* 'IncrementVariable', * 'variables' => array( * 'in' => array( * 'x' => 'y' * ), * 'out' => array( * 'y' => 'z' * ) * ) * ) * ); * ?> * * * @package Workflow * @version 1.4rc1 */ class ezcWorkflowNodeSubWorkflow extends ezcWorkflowNode { /** * Execution ID of the sub workflow, * 0 if it has not been started yet. * * @var integer */ protected $state = 0; /** * Constructs a new sub workflow with the configuration $configuration. * * Configuration format * * * @param mixed $configuration */ public function __construct( $configuration ) { if ( is_string( $configuration ) ) { $configuration = array( 'workflow' => $configuration ); } if ( !isset( $configuration['variables'] ) ) { $configuration['variables'] = array( 'in' => array(), 'out' => array() ); } parent::__construct( $configuration ); } /** * Executes this node. * * @param ezcWorkflowExecution $execution * @return boolean true when the node finished execution, * and false otherwise * @ignore */ public function execute( ezcWorkflowExecution $execution ) { if ( $execution->definitionStorage === null ) { throw new ezcWorkflowExecutionException( 'No ezcWorkflowDefinitionStorage implementation available.' ); } $workflow = $execution->definitionStorage->loadByName( $this->configuration['workflow'] ); // Sub Workflow is not interactive. if ( !$workflow->isInteractive() && !$workflow->hasSubWorkflows() ) { $subExecution = $execution->getSubExecution( null, false ); $subExecution->workflow = $workflow; $this->passVariables( $execution, $subExecution, $this->configuration['variables']['in'] ); $subExecution->start(); } // Sub Workflow is interactive. else { // Sub Workflow is to be started. if ( $this->state == 0 ) { $subExecution = $execution->getSubExecution(); $subExecution->workflow = $workflow; $this->passVariables( $execution, $subExecution, $this->configuration['variables']['in'] ); $subExecution->start( $execution->getId() ); $this->state = $subExecution->getId(); } // Sub Workflow is to be resumed. else { $subExecution = $execution->getSubExecution( $this->state ); $subExecution->workflow = $workflow; $subExecution->resume( $execution->getVariables() ); } } // Execution of Sub Workflow was cancelled. if ( $subExecution->isCancelled() ) { $execution->cancel( $this ); } // Execution of Sub Workflow has ended. if ( $subExecution->hasEnded() ) { $this->passVariables( $subExecution, $execution, $this->configuration['variables']['out'] ); $this->activateNode( $execution, $this->outNodes[0] ); $this->state = 0; return parent::execute( $execution ); } // Execution of Sub Workflow has been suspended. foreach ( $subExecution->getWaitingFor() as $variableName => $data ) { $execution->addWaitingFor( $this, $variableName, $data['condition'] ); } return false; } /** * Generate node configuration from XML representation. * * @param DOMElement $element * @return array * @ignore */ public static function configurationFromXML( DOMElement $element ) { $configuration = array( 'workflow' => $element->getAttribute( 'subWorkflowName' ), 'variables' => array( 'in' => array(), 'out' => array() ) ); $xpath = new DOMXPath( $element->ownerDocument ); $in = $xpath->query( 'in/variable', $element ); $out = $xpath->query( 'out/variable', $element ); foreach ( $in as $variable ) { $configuration['variables']['in'][$variable->getAttribute( 'name' )] = $variable->getAttribute( 'as' ); } foreach ( $out as $variable ) { $configuration['variables']['out'][$variable->getAttribute( 'name' )] = $variable->getAttribute( 'as' ); } return $configuration; } /** * Generate XML representation of this node's configuration. * * @param DOMElement $element * @ignore */ public function configurationToXML( DOMElement $element ) { $element->setAttribute( 'subWorkflowName', $this->configuration['workflow'] ); if ( !empty( $this->configuration['variables']['in'] ) ) { $in = $element->appendChild( $element->ownerDocument->createElement( 'in' ) ); foreach ( $this->configuration['variables']['in'] as $fromName => $toName ) { $variable = $in->appendChild( $in->ownerDocument->createElement( 'variable' ) ); $variable->setAttribute( 'name', $fromName ); $variable->setAttribute( 'as', $toName ); } } if ( !empty( $this->configuration['variables']['out'] ) ) { $out = $element->appendChild( $element->ownerDocument->createElement( 'out' ) ); foreach ( $this->configuration['variables']['out'] as $fromName => $toName ) { $variable = $out->appendChild( $out->ownerDocument->createElement( 'variable' ) ); $variable->setAttribute( 'name', $fromName ); $variable->setAttribute( 'as', $toName ); } } } /** * Returns a textual representation of this node. * * @return string * @ignore */ public function __toString() { return 'Sub Workflow: ' . $this->configuration['workflow']; } /** * Passes variables from one execution context to another. * * @param ezcWorkflowExecution $from The execution context the variables are passed from. * @param ezcWorkflowExecution $to The execution context the variables are passed to. * @param array $variables The names of the variables. * @throws ezcWorkflowExecutionException if a variable that is to be passed does not exist. * @ignore */ protected function passVariables( ezcWorkflowExecution $from, ezcWorkflowExecution $to, array $variables ) { foreach ( $variables as $fromName => $toName ) { $to->setVariable( $toName, $from->getVariable( $fromName ) ); } } } ?>