ezcWorkflowExecution provides all functionality necessary to execute
a workflow. However, it does not provide functionality to make the
execution of a workflow persistent and hence usuable over more than
one PHP run.
Implementations must implement the do* methods and provide the means
to store the execution data to a persistent medium.
public function execute(ezcWorkflowExecution $execution) { $qa_results_dir = "/var/qa"; // value will be the latest score of the package $value = $execution->getVariable('distilled_review'); // an integer // dump this value to a file in the filesystem $storage = new midgard_query_storage('com_meego_package_details'); // get the detailed package object $q = new midgard_query_select($storage); $q->set_constraint(new midgard_query_constraint(new midgard_query_property('packageguid'), '=', new midgard_query_value($execution->getVariable('package_instance')))); $q->execute(); $package = $q->list_objects(); if (count($package) && $value) { $project_name = $package[0]->repoprojectname; $package_name = $package[0]->packageparent; $qa_results_dir = $qa_results_dir . '/' . $project_name; if (!is_dir($qa_results_dir)) { $ret = mkdir($qa_results_dir, 0755, true); if (!$ret) { // do something return; } } $handle = fopen($qa_results_dir . '/' . $package_name . '.txt', "wb"); if ($handle) { $ret = fwrite($handle, $value); if (!$ret) { // do something } } fclose($handle); } return; }
/** * Executes this node and returns true. * * Expects the configuration parameters 'name' the name of the workflow * variable to work on and the parameter 'value' the value to operate with * or the name of the workflow variable containing the value. * * @param ezcWorkflowExecution $execution * @return boolean * @ignore */ public function execute(ezcWorkflowExecution $execution) { if (is_array($this->configuration)) { $variableName = $this->configuration['name']; } else { $variableName = $this->configuration; } $this->variable = $execution->getVariable($variableName); if (!is_numeric($this->variable)) { throw new ezcWorkflowExecutionException(sprintf('Variable "%s" is not a number.', $variableName)); } if (is_numeric($this->configuration['operand'])) { $this->operand = $this->configuration['operand']; } else { if (is_string($this->configuration['operand'])) { try { $operand = $execution->getVariable($this->configuration['operand']); if (is_numeric($operand)) { $this->operand = $operand; } } catch (ezcWorkflowExecutionException $e) { } } } if ($this->operand === null) { throw new ezcWorkflowExecutionException('Illegal operand.'); } $this->doExecute(); $execution->setVariable($variableName, $this->variable); $this->activateNode($execution, $this->outNodes[0]); return parent::execute($execution); }
/** * Activate this node. * * @param ezcWorkflowExecution $execution * @param ezcWorkflowNode $activatedFrom * @param int $threadId * @ignore */ public function activate(ezcWorkflowExecution $execution, ezcWorkflowNode $activatedFrom = null, $threadId = 0) { $parentThreadId = $execution->getParentThreadId($threadId); if (empty($this->state['threads'])) { $this->state['threads'][] = $threadId; parent::activate($execution, $activatedFrom, $parentThreadId); } }
/** * Executes this by setting all the variables specified by the * configuration. * * @param ezcWorkflowExecution $execution * @return boolean true when the node finished execution, * and false otherwise * @ignore */ public function execute(ezcWorkflowExecution $execution) { foreach ($this->configuration as $variable => $value) { $execution->setVariable($variable, $value); } $this->activateNode($execution, $this->outNodes[0]); return parent::execute($execution); }
/** * Performs the merge by ending the incoming threads and * activating the outgoing node. * * @param ezcWorkflowExecution $execution * @return boolean true when the node finished execution, * and false otherwise */ protected function doMerge(ezcWorkflowExecution $execution) { foreach ($this->state['threads'] as $threadId) { $execution->endThread($threadId); } $this->activateNode($execution, $this->outNodes[0]); $this->initState(); return parent::execute($execution); }
public function execute(ezcWorkflowExecution $execution) { $package_instance = new com_meego_package($execution->getVariable('package_instance')); // We load the form from the package's repository $repository = new com_meego_repository($package_instance->repository); $list_of_forms = midgardmvc_ui_forms_generator::list_for_object($repository); if (empty($list_of_forms)) { return; } $execution->setVariable('review_form', $list_of_forms[0]->name); }
/** * Property write access. * * @param string $propertyName Name of the property. * @param mixed $val The value for the property. * * @throws ezcBaseValueException * If a the value for the property definitionStorage is not an * instance of ezcWorkflowDefinitionStorage. * @throws ezcBaseValueException * If a the value for the property workflow is not an instance of * ezcWorkflow. * @ignore */ public function __set($propertyName, $val) { if ($val instanceof ezcWorkflow && ($val->isInteractive() || $val->hasSubWorkflows())) { throw new ezcWorkflowExecutionException('This executer can only execute workflows that have no Input and SubWorkflow nodes.'); } return parent::__set($propertyName, $val); }
/** * @todo: docs */ public function execute(ezcWorkflowExecution $execution) { $form = midgardmvc_ui_forms_generator::get_by_guid($execution->getVariable('review_form')); $instance = new midgardmvc_ui_forms_form_instance($execution->getVariable('review')); $review = midgardmvc_ui_forms_store::load_form($form, $instance); $items = $form->items; $boolean_count = 0; $positive = 0; $package = new com_meego_package($instance->relatedobject); foreach ($items as $key => $item) { if ($key == "redirect_link" || $key == "execution") { continue; } try { $field = new midgardmvc_ui_forms_form_field($key); } catch (Exception $e) { midgardmvc_core::get_instance()->log('Invalid field detected in distill review: ' . $key . ', value: ' . $item, 'warning'); } // todo: ugly hardcoded check, but what can we do.. if ($field->title == "Should the application be in this application catalog?") { // if the answer belongs to a certain field then we process // this field must be a boolean too if ($item instanceof midgardmvc_helper_forms_field_boolean) { if ($item->get_value()) { // add +1 to the package score $package->metadata->score++; } else { // oh yes, we do give -1 points too ;) $package->metadata->score--; } $res = $package->update(); if (!$res) { //update failed; do what? } } } else { // otherwise continue; } } // pass on the score $execution->setVariable('distilled_review', $package->metadata->score); }
/** * Visualizes the current state of the workflow execution. * * @param ezcWorkflowExecution $execution */ protected function visualize(ezcWorkflowExecution $execution) { $activatedNodes = array(); foreach ($execution->getActivatedNodes() as $node) { $activatedNodes[] = $node->getId(); } if ($this->options['includeVariables']) { $variables = $execution->getVariables(); } else { $variables = array(); } $visitor = new ezcWorkflowVisitorVisualization(); $visitor->options['highlightedNodes'] = $activatedNodes; $visitor->options['workflowVariables'] = $variables; $execution->workflow->accept($visitor); file_put_contents(sprintf('%s%s%s_%03d_%03d.dot', $this->options['directory'], DIRECTORY_SEPARATOR, $execution->workflow->name, $execution->getId(), ++$this->fileCounter), $visitor); }
/** * 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)); } }
/** * Executes this node. * * @param ezcWorkflowExecution $execution * @return boolean true when the node finished execution, * and false otherwise * @ignore */ public function execute(ezcWorkflowExecution $execution) { $variables = $execution->getVariables(); $canExecute = true; $errors = array(); foreach ($this->configuration as $variable => $condition) { if (!isset($variables[$variable])) { $execution->addWaitingFor($this, $variable, $condition); $canExecute = false; } else { if (!$condition->evaluate($variables[$variable])) { $errors[$variable] = (string) $condition; } } } if (!empty($errors)) { throw new ezcWorkflowInvalidInputException($errors); } if ($canExecute) { $this->activateNode($execution, $this->outNodes[0]); return parent::execute($execution); } else { return false; } }
/** * Ends the execution of this workflow. * * @param ezcWorkflowExecution $execution * @return boolean true when the node finished execution, * and false otherwise * @ignore */ public function execute(ezcWorkflowExecution $execution) { $execution->end($this); return parent::execute($execution); }
/** * Property set access. * * @param string $propertyName * @param string $propertyValue * @throws ezcBasePropertyNotFoundException * If the given property could not be found. * @throws ezcBaseValueException * If the value for the property options is not an ezcWorkflowDatabaseOptions object. * @ignore */ public function __set($propertyName, $propertyValue) { switch ($propertyName) { case 'definitionStorage': case 'workflow': return parent::__set($propertyName, $propertyValue); case 'options': if (!$propertyValue instanceof ezcWorkflowDatabaseOptions) { throw new ezcBaseValueException($propertyName, $propertyValue, 'ezcWorkflowDatabaseOptions'); } break; default: throw new ezcBasePropertyNotFoundException($propertyName); } $this->properties[$propertyName] = $propertyValue; }
/** * Called after a variable has been unset. * * @param ezcWorkflowExecution $execution * @param string $variableName */ public function afterVariableUnset(ezcWorkflowExecution $execution, $variableName) { $this->notifyListeners(sprintf('Unset variable "%s" for execution #%d of workflow "%s" (version %d).', $variableName, $execution->getId(), $execution->workflow->name, $execution->workflow->version), ezcWorkflowExecutionListener::DEBUG); }
/** * Evaluates all the conditions, checks the constraints and activates any nodes that have * passed through both checks and condition evaluation. * * @param ezcWorkflowExecution $execution * @return boolean true when the node finished execution, * and false otherwise * @ignore */ public function execute(ezcWorkflowExecution $execution) { $keys = array_keys($this->outNodes); $numKeys = count($keys); $nodesToStart = array(); $numActivatedConditionalOutNodes = 0; if ($this->maxActivatedConditionalOutNodes !== false) { $maxActivatedConditionalOutNodes = $this->maxActivatedConditionalOutNodes; } else { $maxActivatedConditionalOutNodes = $numKeys; } for ($i = 0; $i < $numKeys && $numActivatedConditionalOutNodes <= $maxActivatedConditionalOutNodes; $i++) { if (isset($this->configuration['condition'][$keys[$i]])) { // Conditional outgoing node. if ($this->configuration['condition'][$keys[$i]]->evaluate($execution->getVariables())) { $nodesToStart[] = $this->outNodes[$keys[$i]]; $numActivatedConditionalOutNodes++; } } else { // Unconditional outgoing node. $nodesToStart[] = $this->outNodes[$keys[$i]]; } } if ($this->minActivatedConditionalOutNodes !== false && $numActivatedConditionalOutNodes < $this->minActivatedConditionalOutNodes) { throw new ezcWorkflowExecutionException('Node activates less conditional outgoing nodes than required.'); } return $this->activateOutgoingNodes($execution, $nodesToStart); }
/** * Activate this node in the execution environment $execution. * * $activatedFrom is the node that activated this node and $threadId is * threadId of the thread the node should be activated in. * * This method is called by other nodes and/or the execution environment * depending on the workflow. * * @param ezcWorkflowExecution $execution * @param ezcWorkflowNode $activatedFrom * @param int $threadId * @ignore */ public function activate(ezcWorkflowExecution $execution, ezcWorkflowNode $activatedFrom = null, $threadId = 0) { if ($this->activationState === self::WAITING_FOR_ACTIVATION) { $this->activationState = self::WAITING_FOR_EXECUTION; $this->setThreadId($threadId); if ($activatedFrom !== null) { $this->activatedFrom[] = get_class($activatedFrom); } $execution->activate($this); } }
/** * Cancels the execution of this workflow. * * @param ezcWorkflowExecution $execution * @param ezcWorkflowNode $activatedFrom * @param int $threadId * @ignore */ public function activate(ezcWorkflowExecution $execution, ezcWorkflowNode $activatedFrom = null, $threadId = 0) { $execution->cancel($this); }
/** * Gets a rendered HTML form */ public function get_form(ezcWorkflowExecution $execution) { $list_of_variables = $execution->getVariables(); if (array_key_exists('review_form', $list_of_variables)) { $db_form = new midgardmvc_ui_forms_form($list_of_variables['review_form']); $form = midgardmvc_ui_forms_generator::get_by_form($db_form, false); $form->set_readonly(false); if ($this->request->isset_data_item('redirect_link')) { $redirect_link = $this->request->get_data_item('redirect_link'); } else { if (array_key_exists('HTTP_REFERER', $_SERVER)) { $redirect_link = $_SERVER['HTTP_REFERER']; } else { $redirect_link = ''; } } $form->set_cancel(null, $this->mvc->i18n->get('cancel', 'midgardmvc_helper_forms'), $redirect_link); // add a hidden input with the recirect link // where we go upon successful submit $field = $form->add_field('redirect_link', 'text'); $field->set_value($redirect_link); $widget = $field->set_widget('hidden'); // add a hidden input with the execution guid $field = $form->add_field('execution', 'text'); $field->set_value($execution->guid); $widget = $field->set_widget('hidden'); return array('db_form' => $db_form, 'form' => $form); } return null; }