/protected/components/ezcomponents/Workflow/src/workflow.php

https://github.com/kamarulismail/kamarul-playground · PHP · 425 lines · 204 code · 42 blank · 179 comment · 15 complexity · b173784eafbceac7a85a22bfcd769831 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the ezcWorkflow class.
  4. *
  5. * @package Workflow
  6. * @version 1.4.1
  7. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. */
  10. /**
  11. * Class representing a workflow.
  12. *
  13. * @property ezcWorkflowDefinitonStorage $definitionStorage
  14. * The definition handler used to fetch sub workflows on demand.
  15. * This property is set automatically if you load a workflow using
  16. * a workflow definition storage.
  17. * @property int $id
  18. * Unique ID set automatically by the definition handler when the
  19. * workflow is stored.
  20. * @property string $name
  21. * A unique name (accross the system) for this workflow.
  22. * @property int $version
  23. * The version of the workflow. This must be incremented manually
  24. * whenever you want a new version.
  25. * @property-read ezcWorkflowNodeStart $startNode The unique start node of the workflow.
  26. * @property-read ezcWorkflowNodeEnd $endNode The default end node of the workflow.
  27. * @property-read ezcWorkflowNodeFinally $finallyNode The start of a node
  28. * sequence that is executed when a
  29. * workflow execution is cancelled.
  30. * @property-read array(ezcWorkflowNode) $nodes All the nodes of this workflow.
  31. *
  32. * @package Workflow
  33. * @version 1.4.1
  34. * @mainclass
  35. */
  36. class ezcWorkflow implements Countable, ezcWorkflowVisitable
  37. {
  38. /**
  39. * Container to hold the properties
  40. *
  41. * @var array(string=>mixed)
  42. */
  43. protected $properties = array(
  44. 'definitionStorage' => null,
  45. 'id' => false,
  46. 'name' => '',
  47. 'startNode' => null,
  48. 'endNode' => null,
  49. 'finallyNode' => null,
  50. 'version' => 1
  51. );
  52. /**
  53. * The variable handlers of this workflow.
  54. *
  55. * @var array
  56. */
  57. protected $variableHandlers = array();
  58. /**
  59. * Constructs a new workflow object with the name $name.
  60. *
  61. * Use $startNode and $endNode parameters if you don't want to use the
  62. * default start and end nodes.
  63. *
  64. * $name must uniquely identify the workflow within the system.
  65. *
  66. * @param string $name The name of the workflow.
  67. * @param ezcWorkflowNodeStart $startNode The start node of the workflow.
  68. * @param ezcWorkflowNodeEnd $endNode The default end node of the workflow.
  69. * @param ezcWorkflowNodeFinally $finallyNode The start of a node sequence
  70. * that is executed when a workflow
  71. * execution is cancelled.
  72. */
  73. public function __construct( $name, ezcWorkflowNodeStart $startNode = null, ezcWorkflowNodeEnd $endNode = null, ezcWorkflowNodeFinally $finallyNode = null )
  74. {
  75. $this->name = $name;
  76. // Create a new ezcWorkflowNodeStart object, if necessary.
  77. if ( $startNode === null )
  78. {
  79. $this->properties['startNode'] = new ezcWorkflowNodeStart;
  80. }
  81. else
  82. {
  83. $this->properties['startNode'] = $startNode;
  84. }
  85. // Create a new ezcWorkflowNodeEnd object, if necessary.
  86. if ( $endNode === null )
  87. {
  88. $this->properties['endNode'] = new ezcWorkflowNodeEnd;
  89. }
  90. else
  91. {
  92. $this->properties['endNode'] = $endNode;
  93. }
  94. // Create a new ezcWorkflowNodeFinally object, if necessary.
  95. if ( $finallyNode === null )
  96. {
  97. $this->properties['finallyNode'] = new ezcWorkflowNodeFinally;
  98. }
  99. else
  100. {
  101. $this->properties['finallyNode'] = $finallyNode;
  102. }
  103. }
  104. /**
  105. * Property read access.
  106. *
  107. * @throws ezcBasePropertyNotFoundException
  108. * If the the desired property is not found.
  109. *
  110. * @param string $propertyName Name of the property.
  111. * @return mixed Value of the property or null.
  112. * @ignore
  113. */
  114. public function __get( $propertyName )
  115. {
  116. switch ( $propertyName )
  117. {
  118. case 'definitionStorage':
  119. case 'id':
  120. case 'name':
  121. case 'startNode':
  122. case 'endNode':
  123. case 'finallyNode':
  124. case 'version':
  125. return $this->properties[$propertyName];
  126. case 'nodes':
  127. $visitor = new ezcWorkflowVisitorNodeCollector( $this );
  128. return $visitor->getNodes();
  129. }
  130. throw new ezcBasePropertyNotFoundException( $propertyName );
  131. }
  132. /**
  133. * Property write access.
  134. *
  135. * @param string $propertyName Name of the property.
  136. * @param mixed $val The value for the property.
  137. *
  138. * @throws ezcBaseValueException
  139. * If the value for the property definitionStorage is not an
  140. * instance of ezcWorkflowDefinitionStorage.
  141. * @throws ezcBaseValueException
  142. * If the value for the property id is not an integer.
  143. * @throws ezcBaseValueException
  144. * If the value for the property name is not a string.
  145. * @throws ezcBasePropertyPermissionException
  146. * If there is a write access to startNode.
  147. * @throws ezcBasePropertyPermissionException
  148. * If there is a write access to endNode.
  149. * @throws ezcBasePropertyPermissionException
  150. * If there is a write access to finallyNode.
  151. * @throws ezcBasePropertyPermissionException
  152. * If there is a write access to nodes.
  153. * @throws ezcBaseValueException
  154. * If the value for the property version is not an integer.
  155. * @ignore
  156. */
  157. public function __set( $propertyName, $val )
  158. {
  159. switch ( $propertyName )
  160. {
  161. case 'definitionStorage':
  162. if ( !( $val instanceof ezcWorkflowDefinitionStorage ) )
  163. {
  164. throw new ezcBaseValueException( $propertyName, $val, 'ezcWorkflowDefinitionStorage' );
  165. }
  166. $this->properties['definitionStorage'] = $val;
  167. return;
  168. case 'id':
  169. if ( !( is_int( $val ) ) )
  170. {
  171. throw new ezcBaseValueException( $propertyName, $val, 'integer' );
  172. }
  173. $this->properties['id'] = $val;
  174. return;
  175. case 'name':
  176. if ( !( is_string( $val ) ) )
  177. {
  178. throw new ezcBaseValueException( $propertyName, $val, 'string' );
  179. }
  180. $this->properties['name'] = $val;
  181. return;
  182. case 'startNode':
  183. case 'endNode':
  184. case 'finallyNode':
  185. case 'nodes':
  186. throw new ezcBasePropertyPermissionException(
  187. $propertyName, ezcBasePropertyPermissionException::READ
  188. );
  189. case 'version':
  190. if ( !( is_int( $val ) ) )
  191. {
  192. throw new ezcBaseValueException( $propertyName, $val, 'integer' );
  193. }
  194. $this->properties['version'] = $val;
  195. return;
  196. }
  197. throw new ezcBasePropertyNotFoundException( $propertyName );
  198. }
  199. /**
  200. * Property isset access.
  201. *
  202. * @param string $propertyName Name of the property.
  203. * @return bool True is the property is set, otherwise false.
  204. * @ignore
  205. */
  206. public function __isset( $propertyName )
  207. {
  208. switch ( $propertyName )
  209. {
  210. case 'definitionStorage':
  211. case 'id':
  212. case 'name':
  213. case 'startNode':
  214. case 'endNode':
  215. case 'finallyNode':
  216. case 'nodes':
  217. case 'version':
  218. return true;
  219. }
  220. return false;
  221. }
  222. /**
  223. * Returns the number of nodes of this workflow.
  224. *
  225. * @return integer
  226. */
  227. public function count()
  228. {
  229. $visitor = new ezcWorkflowVisitor;
  230. $this->accept( $visitor );
  231. return count( $visitor );
  232. }
  233. /**
  234. * Returns true when the workflow requires user interaction
  235. * (ie. when it contains ezcWorkflowNodeInput nodes)
  236. * and false otherwise.
  237. *
  238. * @return boolean true when the workflow is interactive, false otherwise.
  239. */
  240. public function isInteractive()
  241. {
  242. foreach ( $this->nodes as $node )
  243. {
  244. if ( $node instanceof ezcWorkflowNodeInput )
  245. {
  246. return true;
  247. }
  248. }
  249. return false;
  250. }
  251. /**
  252. * Returns true when the workflow has sub workflows
  253. * (ie. when it contains ezcWorkflowNodeSubWorkflow nodes)
  254. * and false otherwise.
  255. *
  256. * @return boolean true when the workflow has sub workflows, false otherwise.
  257. */
  258. public function hasSubWorkflows()
  259. {
  260. foreach ( $this->nodes as $node )
  261. {
  262. if ( $node instanceof ezcWorkflowNodeSubWorkflow )
  263. {
  264. return true;
  265. }
  266. }
  267. return false;
  268. }
  269. /**
  270. * Resets the nodes of this workflow.
  271. *
  272. * See the documentation of ezcWorkflowVisitorReset for
  273. * details.
  274. */
  275. public function reset()
  276. {
  277. $this->accept( new ezcWorkflowVisitorReset );
  278. }
  279. /**
  280. * Verifies the specification of this workflow.
  281. *
  282. * See the documentation of ezcWorkflowVisitorVerification for
  283. * details.
  284. *
  285. * @throws ezcWorkflowInvalidWorkflowException if the specification of this workflow is not correct.
  286. */
  287. public function verify()
  288. {
  289. $this->accept( new ezcWorkflowVisitorVerification );
  290. }
  291. /**
  292. * Overridden implementation of accept() calls
  293. * accept on the start node.
  294. *
  295. * @param ezcWorkflowVisitor $visitor
  296. */
  297. public function accept( ezcWorkflowVisitor $visitor )
  298. {
  299. $visitor->visit( $this );
  300. $this->properties['startNode']->accept( $visitor );
  301. }
  302. /**
  303. * Sets the class $className to handle the variable named $variableName.
  304. *
  305. * $className must be the name of a class implementing the
  306. * ezcWorkflowVariableHandler interface.
  307. *
  308. * @param string $variableName
  309. * @param string $className
  310. * @throws ezcWorkflowInvalidWorkflowException if $className does not contain the name of a valid class implementing ezcWorkflowVariableHandler
  311. */
  312. public function addVariableHandler( $variableName, $className )
  313. {
  314. if ( class_exists( $className ) )
  315. {
  316. $class = new ReflectionClass( $className );
  317. if ( $class->implementsInterface( 'ezcWorkflowVariableHandler' ) )
  318. {
  319. $this->variableHandlers[$variableName] = $className;
  320. }
  321. else
  322. {
  323. throw new ezcWorkflowInvalidWorkflowException(
  324. sprintf( 'Class "%s" does not implement the ezcWorkflowVariableHandler interface.', $className )
  325. );
  326. }
  327. }
  328. else
  329. {
  330. throw new ezcWorkflowInvalidWorkflowException(
  331. sprintf( 'Class "%s" not found.', $className )
  332. );
  333. }
  334. }
  335. /**
  336. * Removes the handler for $variableName and returns true
  337. * on success.
  338. *
  339. * Returns false if no handler was set for $variableName.
  340. *
  341. * @param string $variableName
  342. * @return boolean
  343. */
  344. public function removeVariableHandler( $variableName )
  345. {
  346. if ( isset( $this->variableHandlers[$variableName] ) )
  347. {
  348. unset( $this->variableHandlers[$variableName] );
  349. return true;
  350. }
  351. return false;
  352. }
  353. /**
  354. * Sets handlers for multiple variables.
  355. *
  356. * The format of $variableHandlers is
  357. * array( 'variableName' => ezcWorkflowVariableHandler )
  358. *
  359. * @throws ezcWorkflowInvalidWorkflowException if $className does not contain the name of a valid class implementing ezcWorkflowVariableHandler
  360. * @param array $variableHandlers
  361. */
  362. public function setVariableHandlers( array $variableHandlers )
  363. {
  364. $this->variableHandlers = array();
  365. foreach ( $variableHandlers as $variableName => $className )
  366. {
  367. $this->addVariableHandler( $variableName, $className );
  368. }
  369. }
  370. /**
  371. * Returns the variable handlers.
  372. *
  373. * The format of the returned array is
  374. * array( 'variableName' => ezcWorkflowVariableHandler )
  375. *
  376. * @return array
  377. */
  378. public function getVariableHandlers()
  379. {
  380. return $this->variableHandlers;
  381. }
  382. }
  383. ?>