Installation Add the bundle via Composer:
composer require 2lenet/bpm-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Lle\BpmBundle\LleBpmBundle::class => ['all' => true],
];
Routing
Import the default routes in config/routes.yaml:
bpm:
resource: "@LleBpmBundle/Resources/config/routing/routes.yaml"
prefix: /admin/bpm
(Note: Adjust prefix to avoid conflicts with existing admin routes.)
First Use Case
Define a simple workflow in a YAML file (e.g., config/bpm/workflows/example_workflow.yaml):
example_workflow:
start: initial_state
states:
initial_state:
transitions:
approve: approved_state
approved_state: {}
Register the workflow in services.yaml:
lle_bpm.workflows:
example_workflow: ~
Basic Usage in Controller
use Lle\BpmBundle\Workflow\WorkflowManager;
public function startWorkflow(WorkflowManager $workflowManager)
{
$workflow = $workflowManager->getWorkflow('example_workflow');
$workflow->start(); // Trigger initial state
}
YAML-Based Workflows
Define workflows in config/bpm/workflows/*.yaml with:
on_enter/on_exit callbacks.approve: next_state).transitions:
approve:
to: approved_state
guard: "@= user.hasPermission('APPROVE')"
Dynamic Workflows Load workflows programmatically:
$workflowManager->loadWorkflowFromYaml(file_get_contents('custom_path.yaml'));
Event Listeners
Hook into workflow events (e.g., WorkflowStateChangedEvent):
use Lle\BpmBundle\Event\WorkflowEvent;
public function onStateChanged(WorkflowEvent $event)
{
if ($event->getNewState() === 'approved') {
$this->mailer->sendApprovalEmail($event->getWorkflow());
}
}
Register in services.yaml:
services:
App\EventListener\WorkflowListener:
tags:
- { name: kernel.event_listener, event: lle_bpm.workflow.state_changed }
Doctrine Entities Attach workflows to entities via annotations or metadata:
use Lle\BpmBundle\Annotation\Workflow;
/**
* @Workflow("example_workflow")
*/
class Order {}
(Note: Bundle may require manual setup for Doctrine integration.)
RESTful Transitions Expose workflow transitions via API:
public function transition(WorkflowManager $workflowManager, string $transition, string $entityId)
{
$workflow = $workflowManager->getWorkflowForEntity($entityId);
$workflow->transition($transition);
return new JsonResponse(['status' => 'transited']);
}
State Validation Validate transitions before execution:
try {
$workflow->canTransition($transition) // Check guard conditions
->transition($transition);
} catch (WorkflowException $e) {
return new JsonResponse(['error' => $e->getMessage()], 403);
}
Routing Conflicts
/admin/bpm) may clash with existing admin panels.prefix in config/routes.yaml or extend the bundle’s routing.YAML Parsing
@=) may fail silently.symfony/var-dumper:
use Symfony\Component\Yaml\Yaml;
$config = Yaml::parse(file_get_contents('workflow.yaml'));
Workflow Caching
php bin/console cache:clear
State Transitions
WorkflowManager::getWorkflowHistory() to audit transitions:
$history = $workflowManager->getWorkflowHistory($workflowId);
$this->logger->info('Transitioned to {$event->getNewState()}', ['workflow' => $event->getWorkflow()->getId()]);
Guard Conditions
config/packages/lle_bpm.yaml:
debug: true
$guard = $workflow->getTransitionGuard('approve');
var_dump($guard->__invoke($workflow)); // Returns bool
Custom States/Transitions
State, Transition) for custom logic:
class CustomState extends \Lle\BpmBundle\Workflow\State
{
public function onEnter(Workflow $workflow)
{
// Custom logic
}
}
services.yaml:
Lle\BpmBundle\Workflow\State: '@App\Workflow\CustomState'
Database Backend
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof WorkflowEntity) {
$workflow = $this->workflowManager->getWorkflowForEntity($entity);
$entity->setCurrentState($workflow->getCurrentState());
}
}
Legacy Code
class LegacyAdapter implements WorkflowInterface
{
public function transition(string $transition)
{
// Call legacy logic
}
}
How can I help you explore Laravel packages today?