simpleWorkflow
  • Class
  • Tree

Classes

  • SWActiveRecord
  • SWActiveRecordBehavior
  • SWComponent
  • SWEvent
  • SWException
  • SWHelper
  • SWNode
  • SWPhpWorkflowSource
  • SWValidator
  • SWWorkflowSource
  • SWyEdConverter
  • SWyEdConverterDOM
  1 <?php
  2 /**
  3  * This class gives access to workflow and statuses stored as PHP files.
  4  * Following attributes can be initialized when the component is configured:
  5  * <ul>
  6  * <li><b>basePath</b> (string) : the base path alias where all workflow are stored.By default, it is set to
  7  * application.models.workflows (folder  "protected/models/workflows").
  8  * </li>
  9  * <li><b>definitionType</b> (string) :  Defines the type of PHP file to load. A Workflow can be defined in
 10  * a PHP file that contains a simple array definition (definitionType = 'array'), or by a
 11  * class (definitionType = 'class'). By default this attribute is set to 'array'.
 12  * </li>
 13  * </ul>
 14  */
 15 class SWPhpWorkflowSource extends SWWorkflowSource
 16 {
 17     /**
 18      * @var string the base path alias where all workflow are stored.By default, it is set to
 19      * application.models.workflows (folder  "protected/models/workflows").
 20      */
 21     public $basePath = 'application.models.workflows';
 22     /**
 23      * @var string Definition type for workflow. Allowed values are : class, array. Default is 'array'
 24      */
 25     public $definitionType = 'array';
 26     
 27     private $_workflow; // workflow definition collection
 28     private $_workflowBasePath;
 29     /**
 30      * Initialize the component with configured values. To preload workflows, set configuration
 31      * setting 'preload' to an array containing all workflows to preload. If no preload is set
 32      * workflows are loaded on demand.
 33      *
 34      * @see SWWorkflowSource
 35      */
 36     public function init()
 37     {
 38         parent::init();
 39         $this->_workflowBasePath = Yii::getPathOfAlias($this->basePath);
 40         if( is_array($this->preload) and count($this->preload)!=0){
 41             foreach ( $this->preload as $wfId ) {
 42                 $this->_load($wfId,true);
 43             }
 44         }
 45         if( $this->definitionType == 'class'){
 46             Yii::import($this->basePath.'.*');
 47         }
 48     }
 49     
 50     //
 51     ///////////////////////////////////////////////////////////////////////////////////
 52     // private methods
 53         
 54     /**
 55      * Loads a workflow from a php source file into the $this->_workflow
 56      * associative array. A call to reset() will unload all workflows.
 57      */
 58     private function _load($wfId, $forceReload)
 59     {
 60         if( !is_string($wfId) or empty($wfId))
 61         {
 62             throw new SWException('failed to load workflow - invalid workflow Id : '.$wfId,SWException::SW_ERR_WORKFLOW_ID);
 63         }
 64         
 65         if( !isset($this->_workflow[$wfId]) or $forceReload==true)
 66         {
 67             
 68             if($this->definitionType == 'class')
 69             {
 70                 $wo = new $wfId;
 71                 $this->_workflow[$wfId] = $this->_createWorkflow($wo->getDefinition(),$wfId);
 72             }
 73             elseif( $this->definitionType == 'array')
 74             {
 75                 $fname=$this->_workflowBasePath.DIRECTORY_SEPARATOR.$wfId.'.php';
 76                 if( file_exists($fname)==false){
 77                     throw new SWException('workflow definition file not found : '.$fname,SWException::SW_ERR_WORKFLOW_NOT_FOUND);
 78                 }
 79     
 80                 $this->_workflow[$wfId] = $this->_createWorkflow(require($fname),$wfId);
 81             }
 82         }
 83         return $this->_workflow[$wfId];
 84     }
 85     /**
 86      * @param array $wf workflow definition
 87      * @param string $wfId workflow Id
 88      */
 89     private function _createWorkflow($wf,$wfId)
 90     {
 91         if(!is_array($wf) || empty($wfId)){
 92             throw new SWException('invalid argument');
 93         }
 94         $wfDefinition=array();
 95         
 96         if( !isset($wf['initial'])) {
 97             throw new SWException('missing initial status for workflow : '.$wfId,SWException::SW_ERR_IN_WORKFLOW);
 98         }
 99             
100         // load node list
101         $nodeIds = array();
102         foreach($wf['node'] as $rnode)
103         {
104             $node=new SWNode($rnode,$wfId);
105             
106             if(in_array($node->getId(),$nodeIds )){
107                 throw new SWException('duplicate node id : '.$node->getId(),SWException::SW_ERR_IN_WORKFLOW);
108             }else{
109                 $nodeIds[] = $node->getId();
110             }
111             
112             $wfDefinition[$node->getId()]=$node;
113             if( $node->getId()==$wf['initial'] || $node->toString() == $wf['initial']){
114                 $wfDefinition['swInitialNode']= $node;
115             }
116         }
117         // checks that initialnode is set
118          
119         if(!isset($wfDefinition['swInitialNode'])){
120             throw new SWException('missing initial status for workflow : '.$wfId,SWException::SW_ERR_IN_WORKFLOW);
121         }
122         
123         return $wfDefinition;
124     }
125     /**
126      * Returns the SWNode object from the workflow collection.
127      *
128      * @param SWnode swNode node to search for in the node list
129      * @return SWNode the SWNode object retrieved from the workflow collection, or NULL if this
130      * node could not be found in the workflow collection
131      */
132     private function _getNode($swNode)
133     {
134         $wfId=$swNode->getWorkflowId();
135         if($wfId==null)
136         {
137             throw new SWException('workflow not found : '.$wfId,SWException::SW_ERR_WORKFLOW_NOT_FOUND);
138         }
139         
140         $this->_load($wfId,false);
141         $nodeId=$swNode->getId();
142         if(isset($this->_workflow[$wfId][$nodeId])){
143             return $this->_workflow[$wfId][$nodeId];
144         }else {
145             return null;
146         }
147     }
148 
149     //
150     ///////////////////////////////////////////////////////////////////////////////////
151     //  public methods
152     /**
153      * Verify if a workflow has been loaded.
154      *
155      * @param string $workflowId workflow id
156      * @return boolean TRUE if the workflow whose id is $workflowId has already been loaded,
157      * FALSE otherwise
158      */
159     public function isWorkflowLoaded($workflowId)
160     {
161         return isset($this->_workflow[$workflowId]);
162     }
163     /**
164      * Loads the workflow whose id is passed as argument.
165      * By default, if the workflow has already been loaded it is not reloaded unless
166      * $forceReload is TRUE
167      * @param string $workflowId the workflow id
168      * @param boolean $forceReload TRUE to force workflow loading, FALSE otherwise
169      */
170     public function loadWorkflow($workflowId,$forceReload=false)
171     {
172         return $this->_load($workflowId,$forceReload) != null;
173     }
174     /**
175      * This method is used to add a new workflow definition to the current workflow collection.
176      * @param array $definition the workflow definition in its array form
177      * @param string $id the workflow id
178      */
179     public function addWorkflow($definition, $id)
180     {
181         if(!is_array($definition))
182             throw new SWException('array expected');
183             
184         if( ! isset($this->_workflow[$id])){
185             $this->_workflow[$id] = $this->_createWorkflow($definition,$id);
186         }
187     }
188     /**
189      * (non-PHPdoc)
190      * @see SWWorkflowSource::getNodeDefinition()
191      */
192     public function getNodeDefinition($node, $defaultWorkflowId=null)
193     {
194         return $this->_getNode(
195             $this->createSWNode($node,$defaultWorkflowId)
196         );
197     }
198     /**
199      * (non-PHPdoc)
200      * @see SWWorkflowSource::getNextNodes()
201      */
202     public function getNextNodes($sourceNode,$workflowId=null)
203     {
204         $result=array();
205         
206         // convert startStatus into SWNode
207         
208         $startNode=$this->getNodeDefinition(
209             $this->createSWNode($sourceNode,$workflowId)
210         );
211         
212         if($startNode==null){
213             throw new SWException('node could not be found : '.$sourceNode,SWException::SW_ERR_NODE_NOT_FOUND);
214         }else {
215             foreach($startNode->getNext() as $nxtNodeId => $tr){
216                 $result[]=$this->_getNode(new SWNode($nxtNodeId,$workflowId));
217             }
218         }
219         return $result;
220     }
221     /**
222      * (non-PHPdoc)
223      * @see SWWorkflowSource::isNextNode()
224      */
225     public function isNextNode($sourceNode,$targetNode,$workflowId=null)
226     {
227         $startNode=$this->createSWNode($sourceNode,$workflowId);
228         $nextNode=$this->createSWNode(
229             $targetNode,
230             ( $workflowId!=null
231                 ? $workflowId
232                 : $startNode->getWorkflowId()
233             )
234         );
235                 
236         $nxt=$this->getNextNodes($startNode);
237         if( $nxt != null){
238             return in_array($nextNode->toString(),$nxt);
239         }else {
240             return false;
241         }
242     }
243     /**
244      * (non-PHPdoc)
245      * @see SWWorkflowSource::getInitialNode()
246      */
247     public function getInitialNode($workflowId)
248     {
249         $this->_load($workflowId,false);
250         return $this->_workflow[$workflowId]['swInitialNode'];
251     }
252     /**
253      * (non-PHPdoc)
254      * @see SWWorkflowSource::getAllNodes()
255      */
256     public function getAllNodes($workflowId)
257     {
258         $result=array();
259         $wf=$this->_load($workflowId,false);
260         foreach($wf as $key => $value){
261             if($key!='swInitialNode'){
262                 $result[]=$value;
263             }
264         }
265         return $result;
266     }
267 }
268 ?>
269 
simpleWorkflow API documentation generated by ApiGen 2.8.0