Workflows are a useful tool to help manage business processes. In this post I take a look at the workflow engine of eZ components, which was developed by Sebastian Bergmann. In this post, I introduce the basics of the workflow engine, and will expand on it’s usage in future posts.
The first step is to download eZ components. At time of writing, the latest version is 2009.1.1 – eZ components can be downloaded from: http://www.ezcomponents.org/download
$ mkdir workflow
$ cd workflow/
$ wget http://www.ezcomponents.org/files/downloads/ezcomponents-2009.1.1.tar.bz2
$ tar -xjf
$ tar -xjf ezcomponents-2009.1.1.tar.bz2
$ cd ezcomponents-2009.1.1
A workflow flows from node to node, sometimes branching conditionally, or splitting to parallel tasks. It flows from the startNode, to the endNode, unless the process is canceled at some point during execution. We start with a really basic workflow, which when started will simply write ‘Hello world’ to the screen.
'myServiceObject'));
$workflow->startNode->addoutNode($step1);
$step1->addOutNode($workflow->endNode);
$execution = new ezcWorkflowExecutionNonInteractive();
$execution->workflow = $workflow;
$execution->start();
if ($execution->hasEnded())
echo "Execution has ended.n";
else
echo "Execution has NOT ended?n";
- lines 1-8
- These lines just setup the autoloader
- line 10
- Creates a workflow with a name ‘Example 1’
- lines 12-23
- The ezcWorkflowServiceObject interface can be implemented to provide custom code that can be executed by a ezcWorkflowNodeAction once it is reached in the workflow. If execute() returns true, the workflow proceeds, else it is stalled.
- line 25
- Creates a action node, which will instance and execute the myServiceObject class when reached.
- line 27-28
- Defines step1 as the action node, linking it to the outNode of the workflows start, and linking it’s own outNode to the endNode of the workflow.
- line 30-32
- An execution object is created, the workflow assigned, and the execution is started.
- line 34-38
- Checks that the workflow is complete as we’d expect it to be
The output of this script is as follows:
$ php ./eg1.php
Hello world!
Execution has ended.
We will now modify this example to be a little more personal. We will introduce an input node, which will stall the workflow execution until required input is acquired, and provided to the workflow. Once the input is provided, execution continues to an action node which instances a slightly modified service object, which says hello.
# cat ./eg2.php
getVariable('name');
echo "Hello {$name}!n";
}
public function __toString()
{
return __CLASS__;
}
}
$getName = new ezcWorkflowNodeInput(array(
'name' => new ezcWorkflowConditionIsString()
));
$sayHello = new ezcWorkflowNodeAction(array('class' => 'myServiceObject'));
$workflow->startNode->addoutNode($getName);
$getName->addOutNode($sayHello);
$sayHello->addoutNode($workflow->endNode);
$db = ezcDbFactory::create('sqlite://:memory:');
$schema = ezcDbSchema::createFromFile('array', './WorkflowDatabaseTiein/tests/workflow.dba');
$schema->writeToDb($db);
$execution = new ezcWorkflowDatabaseExecution($db);
$execution->workflow = $workflow;
$execution->start();
if ($execution->hasEnded())
echo "Execution has ended.n";
else
echo "Execution has NOT ended?n";
$execution->resume(array('name' => 'Fred'));
if ($execution->hasEnded())
echo "Execution has ended.n";
else
echo "Execution has NOT ended?n";
The code is very similar to the first example, so I’ll cover just the main differences below:
- line 17
- Accesses a variable called ‘name’ of the workflow
- line 27-29
- Creates an input node, which will take input from the application. In this instance it’s requiring a ‘name’ of type string.
- line 33-35
- Configuring the work flow
- line 37-39
- The details of this will be covered in my next post on the workflow component
Execution of the workflow is started in this example in much the same was as the previous example – however execution does not finish on the first call to $execution->start(). This is because of the input node requiring a ‘name’ before it can continue. In line 50, we ask the exeuction to resume, providing the name , at which point execution continues, prints hello, and then finishes. The output is as follows:
$ php ./eg2.php
Execution has NOT ended?
Hello Fred!
Execution has ended.
In a follow up post, I will show a more realistic use of workflows, and show a few more of the workflow components in action.
Good article, thanks
Do you know how to integrate ezComponents
with Zend Framework ?
easy components is not at al easy….
Well, I guess it depends what you’re trying to integrate exactly 🙂
I don’t though – because I’ve not really spend much time looking at Zend yet. What is it you’re trying to do out of interest?
Hi Lula,
Try this article on EZC and ZF integration.
http://devzone.zend.com/article/156
Ian, i live in Santa Fe, Argentina and actually i’m working as project leader in software development. I’ve seen your article (very interesting), but i’d like to have, as you’ve said, “more realistic use of workflow”.
Thanks a lot for your time! (and apologise me for my bad english).
The workflow is excellent tool.The code is providing me better idea about how eZcomponents deals with the workflows.
I’ve managed to integrate it with Zend Framework 1.10+ like this way:
1) put it in the libraryezc directory
2) In Bootstrap.php
protected function _initAutoload()
{
require_once ‘../library/ezc/Base/src/base.php’;
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader(array(‘ezcBase’, ‘autoload’), ‘ezc’);
return $autoloader;
}
Hello,
Do you know if with WorkflowParallelSplit you can use thread, and therefore workflows in two branch whitch are executed in parallel ?
When I try, scripts were always linear and not parallel. For exemple http://www.hostingpics.net/viewer.php?id=474745Test_041_012.jpg
if MyServiceObject1 was executing a task, MyServiceObject2 was waiting the end of MyServiceObject1.
Thank you
Hello,
I have two general problems with the understanding of the workflow-functionality:
1.) If I have defined a general workflow (for example for publish an article after a review) – each posted article has actually start a new “instance” of my general publish-workflow. Is this right? Or how does I handle it when the same workflow is used for many different articles/data-sets? And how can I generate a “instance” of a general workflow?
2.) How does the basis-application have to work with the workflow-component? If in the publish-process an email has to send to the person who has to review the article – where has the code to be placed for sending this email? Is it the right approach to send the email directly in the workflow, for example in the execute-method in a WorkflowServiceObject? Or does the sending of the email just placed in the application-code (after save an article or set the state of an article) and the status of the workflow has to set to the next node/level after sending the email?
Thanks for an answer (and sorry for my bad english ;-))!
Timo
@Lula. Here is an easier way to integrate with ZF if you are using teh ZF Bootstrapper. This illustration assumes that the EZC lib is already off of one of your include paths. (I used the PEAR installer so /usr/share/pear is already in php include path.)
Inside your bootstrap class, put the following;
/**
* Load the EZ Components library
* Cannot be done via the autoloader application.ini config
*
*/
public function _initLoadEZC() {
require_once ‘ezc/Base/base.php’;
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader(array(‘ezcBase’, ‘autoload’), ‘ezc’);
}
That’s it.
Good article, thanks
Do you know how to integrate ezComponents
with symfony Framework ?
Did the follow up article ever get published? I’m very interested. Thanks.
Very good article!
I’m a cuban student at the University of the Informatics Sciences. I would like to know how can I integrate ezComponents with CodeIgniter framework. Thanks.