function &mainMemento() { if (!isset($this->MainMemento)) { $this->MainMemento = eZOperationMemento::fetchMain($this->attribute('main_key')); } return $this->MainMemento; }
if (!is_numeric($offset)) { $offset = 0; } $limitList = array(1 => 10, 2 => 25, 3 => 50, 4 => 100); $limit = 10; $limitId = eZPreferences::value('admin_workflow_processlist_limit'); if ($limitId and isset($limitList[$limitId])) { $limit = $limitList[$limitId]; } $viewParameters = array('offset' => $offset); $plist = eZWorkflowProcess::fetchList($conds, true, $offset, $limit); $plistCount = eZWorkflowProcess::count(eZWorkflowProcess::definition(), $conds); $totalProcessCount = 0; $outList2 = array(); foreach ($plist as $p) { $mementoMain = eZOperationMemento::fetchMain($p->attribute('memento_key')); $mementoChild = eZOperationMemento::fetchChild($p->attribute('memento_key')); if (!$mementoMain or !$mementoChild) { continue; } $mementoMainData = $mementoMain->data(); $mementoChildData = $mementoChild->data(); $triggers = eZTrigger::fetchList(array('module_name' => $mementoChildData['module_name'], 'function_name' => $mementoChildData['operation_name'], 'name' => $mementoChildData['name'])); if (count($triggers) > 0) { $trigger = $triggers[0]; if (is_object($trigger)) { $nkey = $trigger->attribute('module_name') . '/' . $trigger->attribute('function_name') . '/' . $trigger->attribute('name'); if (!isset($outList2[$nkey])) { $outList2[$nkey] = array('trigger' => $trigger, 'process_list' => array()); } $outList2[$nkey]['process_list'][] = $p;
++$processCount; $status = $process->attribute( 'status' ); if ( !isset( $statusMap[$status] ) ) $statusMap[$status] = 0; ++$statusMap[$status]; if ( $process->attribute( 'status' ) != eZWorkflow::STATUS_DONE ) { if ( $process->attribute( 'status' ) == eZWorkflow::STATUS_RESET || $process->attribute( 'status' ) == eZWorkflow::STATUS_FAILED || $process->attribute( 'status' ) == eZWorkflow::STATUS_NONE || $process->attribute( 'status' ) == eZWorkflow::STATUS_CANCELLED || $process->attribute( 'status' ) == eZWorkflow::STATUS_BUSY ) { $bodyMemento = eZOperationMemento::fetchMain( $process->attribute( 'memento_key' ) ); $mementoList = eZOperationMemento::fetchList( $process->attribute( 'memento_key' ) ); $bodyMemento->remove(); foreach( $mementoList as $memento ) { $memento->remove(); } } if ( $process->attribute( 'status' ) == eZWorkflow::STATUS_CANCELLED ) { ++$removedProcessCount; $process->removeThis(); } else {
function runWorkflow() { $workflowProcessList = eZWorkflowProcess::fetchForStatus(eZWorkflow::STATUS_DEFERRED_TO_CRON); foreach ($workflowProcessList as $process) { $workflow = eZWorkflow::fetch($process->attribute("workflow_id")); if ($process->attribute("event_id") != 0) { $workflowEvent = eZWorkflowEvent::fetch($process->attribute("event_id")); } $process->run($workflow, $workflowEvent, $eventLog); // Store changes to process if ($process->attribute('status') != eZWorkflow::STATUS_DONE) { if ($process->attribute('status') == eZWorkflow::STATUS_RESET || $process->attribute('status') == eZWorkflow::STATUS_FAILED || $process->attribute('status') == eZWorkflow::STATUS_NONE || $process->attribute('status') == eZWorkflow::STATUS_CANCELLED || $process->attribute('status') == eZWorkflow::STATUS_BUSY) { $bodyMemento = eZOperationMemento::fetchMain($process->attribute('memento_key')); $mementoList = eZOperationMemento::fetchList($process->attribute('memento_key')); $bodyMemento->remove(); foreach ($mementoList as $memento) { $memento->remove(); } } if ($process->attribute('status') == eZWorkflow::STATUS_CANCELLED) { $process->removeThis(); } else { $process->store(); } } else { //restore memento and run it $bodyMemento = eZOperationMemento::fetchChild($process->attribute('memento_key')); if (is_null($bodyMemento)) { eZDebug::writeError($bodyMemento, "Empty body memento in workflow.php"); continue; } $bodyMementoData = $bodyMemento->data(); $mainMemento = $bodyMemento->attribute('main_memento'); if (!$mainMemento) { continue; } $mementoData = $bodyMemento->data(); $mainMementoData = $mainMemento->data(); $mementoData['main_memento'] = $mainMemento; $mementoData['skip_trigger'] = true; $mementoData['memento_key'] = $process->attribute('memento_key'); $bodyMemento->remove(); $operationParameters = array(); if (isset($mementoData['parameters'])) { $operationParameters = $mementoData['parameters']; } $operationResult = eZOperationHandler::execute($mementoData['module_name'], $mementoData['operation_name'], $operationParameters, $mementoData); $process->removeThis(); } } }
/** * Executes the operation * * @param string $operationName * @param array $operationParameters * @param array $mementoData * @return mixed the operation execution result, or null if an error occured */ function execute($operationName, $operationParameters, $mementoData = null) { $moduleName = $this->ModuleName; if (!isset($this->OperationList[$operationName])) { eZDebug::writeError("No such operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; } $operationDefinition = $this->OperationList[$operationName]; if (!isset($operationDefinition['default_call_method'])) { eZDebug::writeError("No call method defined for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; } if (!isset($operationDefinition['body'])) { eZDebug::writeError("No body for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; } if (!isset($operationDefinition['parameters'])) { eZDebug::writeError("No parameters defined for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; } $callMethod = $operationDefinition['default_call_method']; $resultArray = null; $this->Memento = null; if (isset($callMethod['include_file']) and isset($callMethod['class'])) { $bodyCallCount = array('loop_run' => array()); $operationKeys = null; if (isset($operationDefinition['keys'])) { $operationKeys = $operationDefinition['keys']; } $operationParameterDefinitions = $operationDefinition['parameters']; $this->storeOperationMemento($operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName); // Method callback that must be invoked when the operation gets interrupted (trigger, method...) $onInterrupt = isset($operationDefinition['on-interrupt']) ? $operationDefinition['on-interrupt'] : null; $runOperation = true; if ($mementoData === null) { $keyArray = $this->makeOperationKeyArray($operationDefinition, $operationParameters); $mainMemento = null; if ($this->UseTriggers) { $mainMemento = eZOperationMemento::fetchMain($keyArray); } if ($mainMemento !== null) { $this->Memento = $mainMemento; $mementoOperationData = $this->Memento->data(); if (isset($mementoOperationData['loop_run'])) { $bodyCallCount['loop_run'] = $mementoOperationData['loop_run']; } } $mementoList = null; if ($this->UseTriggers) { $mementoList = eZOperationMemento::fetchList($keyArray); } if (count($mementoList) > 0) { $lastResultArray = array(); $mementoRestoreSuccess = true; // restoring running operation foreach ($mementoList as $memento) { $mementoData = $memento->data(); $memento->remove(); $resultArray = $this->executeBody($callMethod['include_file'], $callMethod['class'], $operationDefinition['body'], $operationKeys, $operationParameterDefinitions, $operationParameters, $mementoData, $bodyCallCount, $operationDefinition['name'], null, $onInterrupt); if (is_array($resultArray)) { $lastResultArray = array_merge($lastResultArray, $resultArray); if (!$resultArray['status']) { $mementoRestoreSuccess = false; } } } $resultArray = $lastResultArray; // $resultArray['status'] = $mementoRestoreSuccess; $runOperation = false; } } if ($runOperation) { // start new operation $resultArray = $this->executeBody($callMethod['include_file'], $callMethod['class'], $operationDefinition['body'], $operationKeys, $operationParameterDefinitions, $operationParameters, $mementoData, $bodyCallCount, $operationDefinition['name'], null, $onInterrupt); } if (is_array($resultArray) and isset($resultArray['status']) and ($resultArray['status'] == eZModuleOperationInfo::STATUS_HALTED or $resultArray['status'] == eZModuleOperationInfo::STATUS_REPEAT)) { if ($this->Memento !== null) { // $bodyCallCount stores an indexed array of each operation method that was executed // it must be store in the memento on HALT/REPEAT so that the operation can be resumed // where it was stopped (same behaviour as triggers) $this->storeOperationMemento($operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName); $data = $this->Memento->data(); $data['loop_run'] = $bodyCallCount['loop_run']; $this->Memento->setData($data); $this->Memento->store(); } } else { if ($this->Memento !== null and $this->Memento->attribute('id') !== null) { // eZDebug::writeDebug( $this->Memento, 'ezmodule operation result not halted' ); $this->Memento->remove(); } } // if ( $resultArray['status'] == eZModuleOperationInfo::STATUS_CANCELLED ) // { // return null; // } /* else if ( isset( $mementoData['memento_key'] ) ) { $memento = eZOperationMemento::fetch( $mementoData['mementoKey'] ); if ( $memento->attribute( 'main_key') != $mementoData['mementoKey'] ) { $mainMemento = eZOperationMemento::fetch( $memento->attribute( 'main_key') ); } $memento->remove(); } */ $this->Memento = null; } else { eZDebug::writeError("No valid call methods found for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; } if (!is_array($resultArray)) { eZDebug::writeError("Operation '{$operationName}' in module '{$moduleName}' did not return a result array", __METHOD__); return null; } if (isset($resultArray['internal_error'])) { switch ($resultArray['internal_error']) { case eZModuleOperationInfo::ERROR_NO_CLASS: $className = $resultArray['internal_error_class_name']; eZDebug::writeError("No class '{$className}' available for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; break; case eZModuleOperationInfo::ERROR_NO_CLASS_METHOD: $className = $resultArray['internal_error_class_name']; $classMethodName = $resultArray['internal_error_class_method_name']; eZDebug::writeError("No method '{$classMethodName}' in class '{$className}' available for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; break; case eZModuleOperationInfo::ERROR_CLASS_INSTANTIATE_FAILED: $className = $resultArray['internal_error_class_name']; eZDebug::writeError("Failed instantiating class '{$className}' which is needed for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; break; case eZModuleOperationInfo::ERROR_MISSING_PARAMETER: $parameterName = $resultArray['internal_error_parameter_name']; eZDebug::writeError("Missing parameter '{$parameterName}' for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; break; default: $internalError = $resultArray['internal_error']; eZDebug::writeError("Unknown internal error '{$internalError}' for operation '{$operationName}' in module '{$moduleName}'", __METHOD__); return null; break; } return null; } else { if (isset($resultArray['error'])) { } else { if (isset($resultArray['status'])) { return $resultArray; } else { eZDebug::writeError("Operation '{$operationName}' in module '{$moduleName}' did not return a result value", __METHOD__); } } } return null; }
/** * Executes the operation * * @param string $operationName * @param array $operationParameters * @param array $mementoData * @return mixed the operation execution result, or null if an error occured */ function execute($operationName, $operationParameters, $mementoData = null) { $moduleName = $this->ModuleName; if (!isset($this->OperationList[$operationName])) { eZDebug::writeError("No such operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; } $operationDefinition = $this->OperationList[$operationName]; if (!isset($operationName['default_call_method'])) { eZDebug::writeError("No call method defined for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; } if (!isset($operationName['body'])) { eZDebug::writeError("No body for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; } if (!isset($operationName['parameters'])) { eZDebug::writeError("No parameters defined for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; } $callMethod = $operationDefinition['default_call_method']; $resultArray = null; $this->Memento = null; if (isset($callMethod['include_file']) and isset($callMethod['class'])) { $bodyCallCount = array('loop_run' => array()); $operationKeys = null; if (isset($operationDefinition['keys'])) { $operationKeys = $operationDefinition['keys']; } $operationParameterDefinitions = $operationDefinition['parameters']; $db = eZDB::instance(); $db->begin(); $this->storeOperationMemento($operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName); $runOperation = true; if ($mementoData === null) { $keyArray = $this->makeOperationKeyArray($operationDefinition, $operationParameters); $http = eZHTTPTool::instance(); $keyArray['session_key'] = $http->getSessionKey(); $mainMemento = null; if ($this->UseTriggers) { $mainMemento = eZOperationMemento::fetchMain($keyArray); } if ($mainMemento !== null) { $this->Memento = $mainMemento; $mementoOperationData = $this->Memento->data(); if (isset($mementoOperationData['loop_run'])) { $bodyCallCount['loop_run'] = $mementoOperationData['loop_run']; } } // else // eZDebug::writeWarning( 'Missing main operation memento for key: ' . $this->Memento->attribute( 'memento_key' ), 'eZModuleOperationInfo::execute' ); $mementoList = null; if ($this->UseTriggers) { $mementoList = eZOperationMemento::fetchList($keyArray); } if (count($mementoList) > 0) { $lastResultArray = array(); $mementoRestoreSuccess = true; // restoring running operation foreach ($mementoList as $memento) { $mementoData = $memento->data(); $memento->remove(); $resultArray = $this->executeBody($callMethod['include_file'], $callMethod['class'], $operationDefinition['body'], $operationKeys, $operationParameterDefinitions, $operationParameters, $mementoData, $bodyCallCount, $operationDefinition['name']); if (is_array($resultArray)) { $lastResultArray = array_merge($lastResultArray, $resultArray); if (!$resultArray['status']) { $mementoRestoreSuccess = false; } } } $resultArray = $lastResultArray; // $resultArray['status'] = $mementoRestoreSuccess; $runOperation = false; } } if ($runOperation) { // start new operation $resultArray = $this->executeBody($callMethod['include_file'], $callMethod['class'], $operationDefinition['body'], $operationKeys, $operationParameterDefinitions, $operationParameters, $mementoData, $bodyCallCount, $operationDefinition['name']); // eZDebug::writeDebug( $resultArray, 'ezmodule operation result array' ); } if (is_array($resultArray) and isset($resultArray['status']) and ($resultArray['status'] == eZModuleOperationInfo::STATUS_HALTED or $resultArray['status'] == eZModuleOperationInfo::STATUS_REPEAT)) { // eZDebug::writeDebug( $this->Memento, 'ezmodule operation result halted' ); if ($this->Memento !== null) { $this->Memento->store(); } } else { if ($this->Memento !== null and $this->Memento->attribute('id') !== null) { // eZDebug::writeDebug( $this->Memento, 'ezmodule operation result not halted' ); $this->Memento->remove(); } } // if ( $resultArray['status'] == eZModuleOperationInfo::STATUS_CANCELLED ) // { // return null; // } /* else if ( isset( $mementoData['memento_key'] ) ) { $memento = eZOperationMemento::fetch( $mementoData['mementoKey'] ); if ( $memento->attribute( 'main_key') != $mementoData['mementoKey'] ) { $mainMemento = eZOperationMemento::fetch( $memento->attribute( 'main_key') ); } $memento->remove(); } */ $this->Memento = null; $db->commit(); } else { eZDebug::writeError("No valid call methods found for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; } if (!is_array($resultArray)) { eZDebug::writeError("Operation '{$operationName}' in module '{$moduleName}' did not return a result array", 'eZOperationHandler::execute'); return null; } if (isset($resultArray['internal_error'])) { switch ($resultArray['internal_error']) { case eZModuleOperationInfo::ERROR_NO_CLASS: $className = $resultArray['internal_error_class_name']; eZDebug::writeError("No class '{$className}' available for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; break; case eZModuleOperationInfo::ERROR_NO_CLASS_METHOD: $className = $resultArray['internal_error_class_name']; $classMethodName = $resultArray['internal_error_class_method_name']; eZDebug::writeError("No method '{$classMethodName}' in class '{$className}' available for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; break; case eZModuleOperationInfo::ERROR_CLASS_INSTANTIATE_FAILED: $className = $resultArray['internal_error_class_name']; eZDebug::writeError("Failed instantiating class '{$className}' which is needed for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; break; case eZModuleOperationInfo::ERROR_MISSING_PARAMETER: $parameterName = $resultArray['internal_error_parameter_name']; eZDebug::writeError("Missing parameter '{$parameterName}' for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; break; default: $internalError = $resultArray['internal_error']; eZDebug::writeError("Unknown internal error '{$internalError}' for operation '{$operationName}' in module '{$moduleName}'", 'eZModuleOperationInfo::execute'); return null; break; } return null; } else { if (isset($resultArray['error'])) { } else { if (isset($resultArray['status'])) { return $resultArray; } else { eZDebug::writeError("Operation '{$operationName}' in module '{$moduleName}' did not return a result value", 'eZOperationHandler::execute'); } } } return null; }