The simpleWorkflow extension is a set of Yii components that is dedicated to provide an easy way to manage the life cycle of CActiveRecord objects inside a workflow. It provides features to control the behavior of the active record in its associated workflow : transition tasks, status constraints, event model.
Workflows are defined as associative arrays or as classes. They can be created manually, but for your convenience, since version 1.1, a Gii command is provided to automatically convert any workflow created by the yEd Graphical Editor into a simpleWorkflow : check out the video to learn more about it.
Please note that the simpleWorkflow command for Gii is still experimental
Resources ¶
Documentation ¶
Requirements ¶
- Yii 1.1.4 or above
- the Gii command requires domxml PHP extension and since version 1.1.0.8, the DOM extension is also supported
Installation ¶
- Extract the release file under
protected/extensions
- add the SWPhpWorkflowSource component to your configuration
'components'=>array(
// adding the simple Workflow source component
'swSource'=> array(
'class'=>'application.extensions.simpleWorkflow.SWPhpWorkflowSource',
), ...
- add simpleWorkflow extension base folder to your imports
'import'=>array(
...
// Import simpleWorkflow components : validator, helper ...
'application.extensions.simpleWorkflow.*',
),
For more information on how to use the simpleWorkflow extension, please refer to the documentation
Usage ¶
Once installed and correctly configured, the simpleWorkflow extension will handle the workflow for any model. This happens automatically when the model is read/saved from/to database, or programatically by the developer. For instance :
$m=MyModel::model()->findByPk('1');
if( $m->swHasStatus() ){
echo 'status : '.$m->swGetStatus()->toString();
}else {
$m->swInsertToWorkflow();
$m->save();
}
Change Log ¶
May 26, 2013 ¶
- version 1.1.0.8
- gii command : add SWyEdConverterDOM that uses DOM extension. If domxml extension is available, use it in priority otherwise use DOM
- add swSetStatus() to replace swNextStatus() which is still supported, but deprecated
September 19, 2012 ¶
- version 1.1
- change swNextStatus() : it is not permitted anymore to call 'swNextStatus()' with no argument. To insert a model into a workflow, swNextStatus() must be replaced by a call to 'swInsertToWorkflow()'.
- enh : add method 'swRemoveFromWorkflow()'. This method is only successful when the owner model is in a final status (i.e a status with no outgoing transition).
- enh : add swGetWorkflowSource() as public method to return the workflow source component used by the behavior
- Gii command to convert yEd Graph Editor workflows into sW workflows (experimental)
- enh : when loading a workflow, raise exception on duplicate node id
August 15, 2012 ¶
- Version 1.0
- fix : autoinsert into workflow (jmariani)
- enh : replace function is_a() by instanceof (kjharni)
- enh : metadata. It is now possible to add any value to node definition by using the metadata attribute.
- enh : workflow class definition. A workflow can be defined as a class that must implement method getDefinition() which returns the workflow definition in its array format.
- enh : add 'leaveWorkflow' event. This event is fired whenever a component in a workflow reset its status. This must be done from a final status only.
November 27, 2010 ¶
- (RC2)
- fix : replace 'split' with 'explode' (got 2 doodle)
- enh : SWActiveRecordBehavior->swValidate now returns boolean
- enh : Workflow Driven Model Validation. It is now possible to define validators which are only executed upon specific transitions (this is done by defining specific scenario names).
October 3, 2010 ¶
- Initial release (RC1).
Top Notch
Excellent extension - great docs! :)
Just what I need for my issue/bug tracker (Redmine clone).
THanks!
thanks
reply here
Excellent work!
Great extension and excellent documentation. Very timely for a project that I am working on that requires speakers to submit an abstract which then goes back and forth between editors and finally to a publisher.
One thing that was unexpected was the value placed in the field 'status' I expected it would be draft or edited or whatever but mine was (as if it was your post example), 'swPost/draft' and 'swPost/edited' is this the intended result?
Also a small bug in SWNode.php on line 115. PHP5.3 bails flagging keyword 'split' as deprecated. Change 'split' to 'explode' and everything is fine.
doodle
Great documentation
Although I haven't had the chance to use this extension, I want to comment that this is the BEST documentation I've ever seen for a Yii extension, you deserve a badge that says best documentation writer.
warning in log
Thanks for your extension, it's very usefull.
I'm receiving a lot of warnings:
2011/03/07 20:37:54 [warning] [application.simpleWorkflow] events disabled : owner component doesn't inherit from SWActiveRecord
in D:\Inetpub\cultureireland.gov.ie\applications\protected\extensions\simpleWorkflow\SWActiveRecordBehavior.php (200)
Any idea how to fix that?
reply : warning in log
Hi ferllings,
thanks for your comment.
The warning you're receiving is because the Active Record model that uses simpleWorkflow (through the behavior) doesn't inherit from SWActiveRecord and consequently, you'll not be able to use simpleWorkflow events. This is not a problem really, as you can use the extension and just ignore simpleWorkflow events ...so maybe, I should change these log messages level from 'warning' to 'info'.
If you really don't want to see these warning, you can use SWActiveRecord as a base class for your model.
bye
Status not saved on action/update
Hi,
first i love your component, the problem i have, is that i use the following JUIButton to save the form:
<?php echo CHtml::ajaxButton($model->isNewRecord ? 'Create' : 'Save', $model->isNewRecord ? Yii::app()->createUrl('customer/create') : Yii::app()->createUrl('customer/update',array('id'=>$model->customer_id)), array( 'type'=>'POST', 'success'=>'function(responseText,statusText) { $("#customer_save_button").val("saved"); $.fn.yiiGridView.update("ledger-grid"); }', ), array('class'=>'ui-button ui-state-default ui-corner-all','id'=>'customer_save_button')); ?>
and here the update from the controller:
public function actionUpdate($id) { $model=$this->loadModel($id); // Uncomment the following line if AJAX validation is needed $this->performAjaxValidation($model); if(isset($_POST['Customer'])) { $model->attributes=$_POST['Customer']; if($model->save()){ //here comes the logging part $EventLog = new Event(); $EventLog->user_id = Yii::app()->user->id; $EventLog->eve_creationdate = date('Y-m-d H:i:s'); $EventLog->customer_id = $model->customer_id; $EventLog->action_id = 4; //pls take a look into the wiki, to set the correct event id! $EventLog->save(); $this->redirect(array('view','id'=>$model->customer_id)); } } $this->render('update',array( 'model'=>$model, )); }
But the status is not changed:( Pls. help!
Cheers Phil
reply : Status not saved on action/update
hi philippfrenzel,
thanks for your comment.
Regarding your problem, it may be more convient to discuss on the forum
bye
Incredible extension and moreover documentation
Wow Raoul! I reached your page looking for some kind of "visual guide" for interfaces (eguider) and I ended reading ALL the workflow extension documentation, let me give you my congratulations not only for the really difficult extension code, but for the great documentation that let me understand practicaly all the functionality mostly because of the continous comparation with an example!! We will think to implement it in our cloud service, just a question: do we decrease our overall performance using it for a simple pair of models with status? What is the drawback if any? thanks again
reply to aleksdj
Hi aleksdj,
and thanks for your kind comments. I appreciate !
Regarding your question I don't really have production data on performance impact. The only thing I can say is that as workflow definition is stored in a file, it will require disk access each time it is used so unless the server provides some sort of cashing, you'll have to count with that.
Cheers
Question
as you can go from one node to two or more nodes at the same time? to run more than one node at the time, and to save time. thanks for your help
one node at a time
hi williamquitian,
sorry but what you are asking is not possible with this extension : at a certain moment a model is in one and only one node (or status).
thanks
thanks Raoul for your reply, congratulations for your good work on this extension
Save workflow in database
Hello, another question, what workflows can be saved in a database, that is, I have to create different flows for the same model, but different filters I have to choose one among many, please if you can guide me how to do it.
@williamquitian
hi williamquitian,
I'm not sure to understand your problem (if you wnat to describe more in detail, I advice you use the forum thread)
Workflows are not saved in DB, they are just stored as associative array (or class) into a file. That being said, storage is not related to how you assign a workflow to a model instance. This can be done automatically (autoInsert = true) or programatically. In this last case you can assign whatever workflow you want dynamically. Then, when the model instance is assigned a workflow it lives its own life among this workflow.
Again, I'm not sure I understand your question/problem so feel free to elaborate on the forum thread.
ciao
Question About Logging
Although it is mentioned before, but: "Great Extension!"
> The Question:
Does your extension supports status transition logging?
logging
Hi wwwwww,
and thanks for your comment.
The extension doesn't include some built-in logging feature, and actually I removed sometimes ago most of the TRACE that remained for debug purpose.
However, if you want to add status transition logging, what you could do is to write a LoggableStatusBehavior that would handle events triggered by the SWActiveRecordBehavior behavior and in particular the afterTransition event. The SWEvent fired contains the source and destination status, applied to the sender model (check out the SWEvent class).
Hope it helps...
bye
Web GUI to generate sw in browser (tested in FF)
I have used a d3.js svg (http://bl.ocks.org/rkirsling/5001347</a>) to develop a web based app in order to create Simple Workflow as simple as possible. Workflow definition and extra simple workflow model required rules are generated automatically. Here is the link: http://lms.irc.ac.ir/extras/hwts/odg/workflow/update/id/1</a>
Web GUI
Hi wwwww,
I can't acces to the demo url but yes, creating a simpleWorkflow visual builder is an option I had in mind. Sometimes ago I created such a tool based on a Flash component but I was not satisfied with it so I never released it.
Maybe for the next version ...
WEB Gui
Hi Raoul,
I tested the URL again, it works fine!
http://lms.irc.ac.ir/extras/hwts/odg/workflow/update/id/1
Does it suit when the workflow spans over several rows?
Looks like the extension is perfect suit when managing the state transitions of a single object. But in my case, my workflow spans across multiple rows, sometimes multiple rows from different active records ojects and I need to inspect all those object to validate it. Does it work across multiple active record objects?
@seng
hi seng,
I'm not sure to understand what your problem is. For sure the simpleWorkflow extension being provided as a behavior it can only be used for (attached to) aa AR class... but you can attach it to different AR classes.
ciao
Spacing in ID
in ID we cannot put space or something separating the words. for example:
return array( 'initial' => "Waiting Approval", //absolutely will raise error, edit to "WaitingApproval" 'node' => array( array( 'id' => "Waiting Approval", //absolutely will raise error, edit to "WaitingApproval" 'label' => Yii::t('workflow','Waiting Approval'), //But this make it works 'transition' => array( 'Booking', 'Rejected', ), 'metadata' => array( 'background-color' => '#FFCC00', 'color' => '#000000', ), ), array( 'id' => 'Rejected', 'label' => Yii::t('workflow','Rejected'), //'constraint' => '', 'metadata' => array( 'background-color' => '#FFCC00', 'color' => '#000000', ), ),
re: Spacing in ID
@myrazel id should be consistent (without space), for displaying you should use labels (SWNode -> getLabel( ))
get specific label
can we get specific label from an id/status?
something like
$id = 'Archived' SWNode::getLabelFromId($id)
I found nothing about that
@myrazel
Hi myrazel,
if you don't provide a label for node, then the node ID is used as label.
ciao
multi task
Hello friends, my question is, how to declare two tasks in a transition?
@williamquitian
Hi,
Sorry but it is not possible to declare 2 tasks and the only solution I see is declare one task that will invoke your 2 tasks.
Hope it helped
ciao
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.