Custom workflows
One of the most powerful features of Exponential 3 is that you can create custom workflows.
Workflow is a mechanism that makes it possible to customize or add new features to operations in Exponential.
For example: add some additional actions to publish routing or some additional steps to view objects.
Workflows should be connected to defined Exponential operations with triggers (there are only two defined operations
in the content module currently: "Read" and "Publish").
For each defined operation, the Exponential kernel tries to execute two triggers. One is activated before the actual
operation body is executed and another is activated after that. A trigger is just a row stored in the database table
eztrigger.
Table definition:
CREATE TABLE eztrigger (
id int(11) NOT NULL auto_increment,
name varchar(255),
module_name varchar(200) NOT NULL default '',
function_name varchar(200) NOT NULL default '',
workflow_id int(11) default NULL,
PRIMARY KEY (id),
UNIQUE KEY eztrigger_def_id (module_name,function_name,name)
) TYPE=MyISAM;
Field "name" is the name of the trigger, for example, "pre_publish" or "pre_read". The fields module_name and
function_name are the names of module and function that the system will start executing the workflow for.
Understanding Operations
An operation is a sequence of functions and triggers which should be executed to make a full action like read or publish.
For example, simple "read" operation (below) is just a sequence of "pre_read" trigger and "fetch-object" method.
$OperationList['read'] = array( 'name' => 'read',
'default_call_method' => array( 'include_file' => 'kernel/content/ezcontentoperationcollection.php',
'class' => 'eZContentOperationCollection' ),
'parameters' => array( array( 'name' => 'node_id',
'required' => true ),
array( 'name' => 'user_id',
'required' => true ),
array( 'name' => 'language_code',
'default' => '',
'required' => false ) ),
'keys' => array( 'node_id',
'user_id' ),
'body' => array( array( 'type' => 'trigger',
'name' => 'pre_read',
'keys' => array( 'node_id',
'user_id'
) ),
array( 'type' => 'method',
'name' => 'fetch-object',
'frequency' => 'once',
'method' => 'readObject',
) ) );
- name - the name of the operation.
- default_call_method - an array which shows in which file and class methods used in the operation are defined
- parameters - parameters that are passed to each method and trigger in the operation when they are executed
- keys - part of parameters that are used to identify stored interrupted operation (operation memento)
- body - array of arrays that describe methods and triggers of the operation
Types of body elements:
Trigger:
- type - trigger, shows that current body element is trigger
- name - name of the trigger used to fetch trigger from database. To fetch the trigger, the system will use next
conditions - (module name, operation name, trigger name)
- key - part of the parameters used to identify running workflow process
Method:
- type - method
- name - fetch-object, name of method used in internals of operation
- frequency - once, it means that method will be run only once
- method - method of class described with "default_call_method" "class" parameter of operation. That function is
the code which will be executed
Creating workflows
Workflows consist of a sequence of workflow events which will be executed one by one. Therefore, the first step is to
create workflow event types. Alternatively, you can use events that already exist.
Creating new workflow event
Suppose that you want to create a workflow event which will show a "hello user" message to users after the workflow has
run. We use hellouser as the name of the event. To create this new workflow event, you need to complete the
following steps:
- modify site.ini settings to add the new workflow event type. You should add "event_hellouser" to the
AvailableEventTypes parameter
- create directory kernel/classes/workflowtypes/event/hellouser/
- create file in that directory called hellousertype.php
File hellousertype.php
define( "EZ_WORKFLOW_TYPE_HELLO_USER_ID", "hellouser" );
class helloUserType extends eZWorkflowEventType
{
/*!
Constructor
*/
function helloUserType()
{
$this->eZWorkflowEventType( EZ_WORKFLOW_TYPE_HELLO_USER_ID, "Hello User" );
}
function execute( &$process, &$event )
{
return EZ_WORKFLOW_TYPE_STATUS_ACCEPTED;
}
}
eZWorkflowEventType::registerType( EZ_WORKFLOW_TYPE_HELLO_USER_ID, "hellousertype" );
This is a very simple workflow event type. To create a workflow event type we need to create a class inherited from
eZWorkflowEventType and then register it into the system using the method eZWorkflowEventType::registerType().
This class should have at least one method in addition to the class constructor. The method execute is called
when the workflow event is executed. The behaviour of running the workflow depends on the return value of this function.
Possible values
Value | Description |
EZ_WORKFLOW_TYPE_STATUS_ACCEPTED
|
Workflow accepts that event, and run next event in workflow
|
EZ_WORKFLOW_TYPE_STATUS_REJECTED
EZ_WORKFLOW_TYPE_STATUS_WORKFLOW_CANCELLED
|
They have the same meaning currently. The workflow will be canceled.
|
EZ_WORKFLOW_TYPE_STATUS_DEFERRED_TO_CRON
EZ_WORKFLOW_TYPE_STATUS_DEFERRED_TO_CRON_REPEAT
|
This status means that execution of the workflow is deferred to the cron daemon. The difference between the first one
and the second one is that the workflow will be executed from the next event in the first case and from the same event
in the second case after finishing current running process.
|
EZ_WORKFLOW_TYPE_STATUS_FETCH_TEMPLATE
EZ_WORKFLOW_TYPE_STATUS_FETCH_TEMPLATE_REPEAT
|
The workflow engine should interrupt executing workflow and show page to the user. In case of this status, the workflow
event should set up some internal variables. (Will be explaned below). Differences between them is the same as in the
previous case.
|
EZ_WORKFLOW_TYPE_STATUS_REDIRECT
EZ_WORKFLOW_TYPE_STATUS_REDIRECT_REPEAT
|
Workflow engine should interrupt executing the workflow and redirect the user to a specified page. In case of this
status the workflow event should set up some internal variables. (Will be explaned below).
Differences between them is the same as in the previous cases.
|
EZ_WORKFLOW_TYPE_STATUS_NONE
|
Undefined status. The same as EZ_WORKFLOW_TYPE_STATUS_REJECTED temporally.
|
To show a page to the user, you need to use the status EZ_WORKFLOW_TYPE_STATUS_FETCH_TEMPLATE and set up some internal
variables.
function execute( &$process, &$event )
{
$user =& eZUser::currentUser();
$userName =& $user->attribute( 'login' );
$localhostAddr = eZSys::hostname();
$requestUri = eZSys::serverVariable( 'REQUEST_URI' );
$process->Template = array( 'templateName' => 'design:workflow/eventtype/result/' . 'event_hellouser' . '.tpl',
'templateVars' => array( 'return_uri' => $requestUri,
'user_name' => $userName ) );
return EZ_WORKFLOW_TYPE_STATUS_FETCH_TEMPLATE;
}
In addition, you need to create the result template.
<form action={$return_uri|ezurl} method="post" >
<div class="maincontentheader">
<h1>{"Hello"|i18n('workflow/eventtype/result/event_hellouser')} {$user_name}</h1>
</div>
<div class="buttonblock">
<input type="submit" name="Next" value="next" />
</div>
</form>
The workflow event is ready now and it is time to create the workflow. Click on 'Workflows' in the left menu and choose
a defined group or just create a new one.
then click "New workflow" button.
Specify the workflow name first, and then you can add the "Event/Hello User" event to the workflow by selecting it from
the dropdown list and clicking the "New Event" button.
Simply click the store button after you have added the event.
Now the workflow is ready and you need to create a trigger. Go to the "Triggers" list (in the "Set up" menu box) and
select the newly created workflow from the dropdown list on the content - read - before line.
Click the "Store" button. The workflow is connected to the operation now.
Finally the workflow is ready and has been connected to the operation.
|