Download the PHP package lexik/workflow-bundle without Composer
On this page you can find all versions of the php package lexik/workflow-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download lexik/workflow-bundle
More information about lexik/workflow-bundle
Files in lexik/workflow-bundle
Package workflow-bundle
Short Description Simple workflow bundle for Symfony2
License MIT
Homepage https://github.com/lexik/LexikWorkflowBundle
Informations about the package workflow-bundle
LexikWorkflowBundle
This bundle is deprecated
This Symfony2 bundle allows to define and manage simple workflows using the event dispatcher for actions and validations.
This bundle was originally a fork of FreeAgentWorkflowBundle. The implementation differs in the way that we use event dispatcher and we store steps history for each model object.
Installation
Installation with composer:
Next, be sure to enable the bundle in your app/AppKernel.php
file:
How it works
First of all, what's a workflow? According to wikipedia definition, "a workflow consists of a sequence of connected steps". You can see below the workflow terms used by the bundle:
- to define your workflow you will have to describe some processes ;
- a process is defined by a series of steps, and you advance through the process step by step ;
- a step contains validations and actions, validations are executed when you try to reach the step, if those validations are successful the step has been reached and actions are executed.
The workflow works on a "model" object, a model is a class that implements Lexik\Bundle\WorkflowBundle\Model\ModelInterface
. Each time a model tries to reach a step, we log it in the database to keep the steps history.
Workflow example
Let's define a simple workflow around a post from its creation to its publication:
- first, we have to create a draft, then an admin must validate this draft before it can be published ;
- once a post is published, any user can unpublish it ;
- if a post is not published, an admin can delete it ;
- if the publication step fails, we go back to the draft step.
Model object
The workflow handles "model" objects. A "model" object is basically an instance of Lexik\Bundle\WorkflowBundle\Model\ModelInterface
. This interface has 3 methods to implement:
getWorkflowIdentifier()
returns an unique identifier used to store a model state in the database ;getWorkflowData()
returns an array of data to store with the model state ;getWorkflowObject()
returns the final object, it will be passed to the security context by the default ProcessHandler.
Here's an example of a PostModel
class we could use in the post_publication
process:
Step validations
As you just read on the bundle introduction, we use the event dispatcher for actions and validations. To validate that a step can be reached, you just need to listen to the <process_name>.<step_name>.validate
event.
The listener will receive an instance of Lexik\Bundle\WorkflowBundle\Event\ValidateStepEvent
, which will allow you to get the step, the model and an object that manages the step violations. You can add violations to block the access to the step.
In the case the step is not reached due to a validation error, a <process_name>.<step_name>.validation_fail
event is dispatched.
Let's see a simple example, here I listen to the events *.validate
and *.validation_fail
for the step published
from the post_publication
process.
Step actions
If you need to execute some logic once a step is successfully reached, you can listen to the <process_name>.<step_name>.reached
event.
The listener will receive a Lexik\Bundle\WorkflowBundle\Event\StepEvent
object with which you can get the step, the model and the last model state.
Let's see a simple example, here I listen to *.reached
event for the step published
from the post_publication
process.
Step Pre-validations
In addition to step validations, you can also process some pre-validations. A pre-validation will be executed just before step validations and only for the current step.
E.g.: let's say we have a post which is currently on step published
and I want to reach the step unpublished
.
When you will try to reach the unpublished
step, the process handler will trigger a pre-validation event named:
post_publication.published.unpublish.pre_validation
So by listening this event you will be able to do some validations before the process handler executes default validations defined on the unpublished
step.
And these pre-validations are only executed when you try to reach unpublished
from published
.
Pre-validation events patterns:
- To process some pre-validations:
<process_name>.<current_step_name>.<next_state_name>.pre_validation
. - To process some code in case pre-validations fail:
<process_name>.<current_step_name>.<next_state_name>.pre_validation_fail
.
Here a simple example for a pre-validation listener:
Conditional next step (OR)
To define a conditional next state, you have to define the target
key as usual, plus the type
key to notify the process handler that this next state is conditional.
Here an example of conditional next state:
Let's say we have a model state currently on the step named my_step_xxx
.
If we try to reach the next state named go_to_next_step
by calling $processHandler->reachNextState($model, 'go_to_next_step')
, the workflow will call each method defined for each target.
The first method that returns true will make the workflow proceed to the related step.
So, if service_id:method_name
returns true
, the next step will be my_step_A
.
If service_id:method_name
returns false
and then service_id:other_method_name
returns true
, the next step will be my_step_B
.
If both service_id:method_name
and service_id:other_method_name
return false
, the next step will be my_step_C
.
Model status update
You can easily assign a status to your model using the model_status
option. The first argument is the method that will be called on the model when the step is reached. The second argument is the value that will be passed to this method. This allows you to automatically update the status at each step of the process.
Step user roles
You can define the roles the current user must have to be able to reach a step. Roles are checked just before step validations.
An event *.bad_credentials
is dispatched when user has not the roles.
Set modelStates on your ModelInterface
If you want to retrieve all modelStates created for your ModelInterface object, you need to implement the ModelStateInterface:
This will allow you to call the method getStates($objects, $processes = array(), $onlySuccess = false)
defined in the lexik_workflow.model_storage
service.
Usage
Here a simple example of how to use the workflow:
Note that the start()
and reachNextState()
methods return an instance of Lexik\Bundle\WorkflowBundle\Entity\ModelState
. This entity represents a state for a given model and process.