%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/bizproc/classes/general/ |
Current File : /home/bitrix/www/bitrix/modules/bizproc/classes/general/activity.php |
<? IncludeModuleLangFile(__FILE__); abstract class CBPActivity { public $parent = null; public $executionStatus = CBPActivityExecutionStatus::Initialized; public $executionResult = CBPActivityExecutionResult::None; private $arStatusChangeHandlers = array(); const StatusChangedEvent = 0; const ExecutingEvent = 1; const CancelingEvent = 2; const ClosedEvent = 3; const FaultingEvent = 4; const ValuePattern = '#^\s*\{=\s*(?<object>[a-z0-9_]+)\s*\:\s*(?<field>[a-z0-9_\.]+)(\s*>\s*(?<mod1>[a-z0-9_\:]+)(\s*,\s*(?<mod2>[a-z0-9_]+))?)?\s*\}\s*$#i'; const ValueInlinePattern = '#\{=\s*(?<object>[a-z0-9_]+)\s*\:\s*(?<field>[a-z0-9_\.]+)(\s*>\s*(?<mod1>[a-z0-9_\:]+)(\s*,\s*(?<mod2>[a-z0-9_]+))?)?\s*\}#i'; /** Internal pattern used in calc.php */ const ValueInternalPattern = '\{=\s*([a-z0-9_]+)\s*\:\s*([a-z0-9_\.]+)(\s*>\s*([a-z0-9_\:]+)(\s*,\s*([a-z0-9_]+))?)?\s*\}'; const CalcPattern = '#^\s*(=\s*(.*)|\{\{=\s*(.*)\s*\}\})\s*$#is'; const CalcInlinePattern = '#\{\{=\s*(.*?)\s*\}\}([^\}]|$)#is'; protected $arProperties = array(); protected $arPropertiesTypes = array(); protected $name = ""; /** @var CBPWorkflow $workflow */ public $workflow = null; public $arEventsMap = array(); /************************ PROPERTIES ************************************************/ public function GetDocumentId() { $rootActivity = $this->GetRootActivity(); return $rootActivity->GetDocumentId(); } public function SetDocumentId($documentId) { $rootActivity = $this->GetRootActivity(); $rootActivity->SetDocumentId($documentId); } public function GetDocumentType() { $rootActivity = $this->GetRootActivity(); if (!is_array($rootActivity->documentType) || count($rootActivity->documentType) <= 0) { /** @var CBPDocumentService $documentService */ $documentService = $this->workflow->GetService("DocumentService"); $rootActivity->documentType = $documentService->GetDocumentType($rootActivity->documentId); } return $rootActivity->documentType; } public function SetDocumentType($documentType) { $rootActivity = $this->GetRootActivity(); $rootActivity->documentType = $documentType; } public function getDocumentEventType() { $rootActivity = $this->GetRootActivity(); return (int)$rootActivity->getRawProperty(CBPDocument::PARAM_DOCUMENT_EVENT_TYPE); } public function GetWorkflowStatus() { $rootActivity = $this->GetRootActivity(); return $rootActivity->GetWorkflowStatus(); } public function SetWorkflowStatus($status) { $rootActivity = $this->GetRootActivity(); $rootActivity->SetWorkflowStatus($status); } public function SetFieldTypes($arFieldTypes = array()) { if (count($arFieldTypes) > 0) { $rootActivity = $this->GetRootActivity(); foreach ($arFieldTypes as $key => $value) $rootActivity->arFieldTypes[$key] = $value; } } public function GetWorkflowTemplateId() { $rootActivity = $this->GetRootActivity(); //prevent recursion by checking setter if (method_exists($rootActivity, 'SetWorkflowTemplateId')) { return $rootActivity->GetWorkflowTemplateId(); } return 0; } /**********************************************************/ protected function ClearProperties() { $rootActivity = $this->GetRootActivity(); $documentId = $rootActivity->GetDocumentId(); $documentType = $this->GetDocumentType(); /** @var CBPDocumentService $documentService */ $documentService = $this->workflow->GetService("DocumentService"); if (is_array($rootActivity->arPropertiesTypes) && count($rootActivity->arPropertiesTypes) > 0 && is_array($rootActivity->arFieldTypes) && count($rootActivity->arFieldTypes) > 0) { foreach ($rootActivity->arPropertiesTypes as $key => $value) { if ($rootActivity->arFieldTypes[$value["Type"]]["BaseType"] == "file") { foreach ((array) $rootActivity->arProperties[$key] as $v) { if (intval($v) > 0) { $iterator = \CFile::getByID($v); if ($file = $iterator->fetch()) { if ($file['MODULE_ID'] === 'bizproc') CFile::Delete($v); } } } } $fieldType = \Bitrix\Bizproc\FieldType::normalizeProperty($value); if ($fieldTypeObject = $documentService->getFieldTypeObject($documentType, $fieldType)) { $fieldTypeObject->setDocumentId($documentId) ->clearValue($rootActivity->arProperties[$key]); } } } } public function GetPropertyBaseType($propertyName) { $rootActivity = $this->GetRootActivity(); return $rootActivity->arFieldTypes[$rootActivity->arPropertiesTypes[$propertyName]["Type"]]["BaseType"]; } public function getTemplatePropertyType($propertyName) { $rootActivity = $this->GetRootActivity(); return $rootActivity->arPropertiesTypes[$propertyName]; } public function SetProperties($arProperties = array()) { if (count($arProperties) > 0) { foreach ($arProperties as $key => $value) $this->arProperties[$key] = $value; } } public function SetPropertiesTypes($arPropertiesTypes = array()) { if (count($arPropertiesTypes) > 0) { foreach ($arPropertiesTypes as $key => $value) $this->arPropertiesTypes[$key] = $value; } } /**********************************************************/ protected function ClearVariables() { $rootActivity = $this->GetRootActivity(); $documentId = $rootActivity->GetDocumentId(); $documentType = $this->GetDocumentType(); /** @var CBPDocumentService $documentService */ $documentService = $this->workflow->GetService("DocumentService"); if (is_array($rootActivity->arVariablesTypes) && count($rootActivity->arVariablesTypes) > 0 && is_array($rootActivity->arFieldTypes) && count($rootActivity->arFieldTypes) > 0) { foreach ($rootActivity->arVariablesTypes as $key => $value) { if ($rootActivity->arFieldTypes[$value["Type"]]["BaseType"] == "file") { foreach ((array) $rootActivity->arVariables[$key] as $v) { if (intval($v) > 0) { $iterator = \CFile::getByID($v); if ($file = $iterator->fetch()) { if ($file['MODULE_ID'] === 'bizproc') CFile::Delete($v); } } } } $fieldType = \Bitrix\Bizproc\FieldType::normalizeProperty($value); if ($fieldTypeObject = $documentService->getFieldTypeObject($documentType, $fieldType)) { $fieldTypeObject->setDocumentId($documentId) ->clearValue($rootActivity->arVariables[$key]); } } } } public function GetVariableBaseType($variableName) { $rootActivity = $this->GetRootActivity(); return $rootActivity->arFieldTypes[$rootActivity->arVariablesTypes[$variableName]["Type"]]["BaseType"]; } public function SetVariables($arVariables = array()) { if (count($arVariables) > 0) { $rootActivity = $this->GetRootActivity(); foreach ($arVariables as $key => $value) $rootActivity->arVariables[$key] = $value; } } public function SetVariablesTypes($arVariablesTypes = array()) { if (count($arVariablesTypes) > 0) { $rootActivity = $this->GetRootActivity(); foreach ($arVariablesTypes as $key => $value) $rootActivity->arVariablesTypes[$key] = $value; } } public function SetVariable($name, $value) { $rootActivity = $this->GetRootActivity(); $rootActivity->arVariables[$name] = $value; } public function GetVariable($name) { $rootActivity = $this->GetRootActivity(); if (array_key_exists($name, $rootActivity->arVariables)) return $rootActivity->arVariables[$name]; return null; } public function getVariableType($name) { $rootActivity = $this->GetRootActivity(); return isset($rootActivity->arVariablesTypes[$name]) ? $rootActivity->arVariablesTypes[$name] : null; } private function GetConstantTypes() { $rootActivity = $this->GetRootActivity(); if (method_exists($rootActivity, 'GetWorkflowTemplateId')) { $templateId = $rootActivity->GetWorkflowTemplateId(); if ($templateId > 0) { return CBPWorkflowTemplateLoader::getTemplateConstants($templateId); } } return null; } public function GetConstant($name) { $constants = $this->GetConstantTypes(); if (isset($constants[$name]['Default'])) return $constants[$name]['Default']; return null; } public function GetConstantType($name) { $constants = $this->GetConstantTypes(); if (isset($constants[$name])) return $constants[$name]; return array('Type' => null, 'Multiple' => false, 'Required' => false, 'Options' => null); } public function IsVariableExists($name) { $rootActivity = $this->GetRootActivity(); return array_key_exists($name, $rootActivity->arVariables); } /************************************************/ public function GetName() { return $this->name; } public function GetRootActivity() { $p = $this; while ($p->parent != null) $p = $p->parent; return $p; } public function SetWorkflow(CBPWorkflow $workflow) { $this->workflow = $workflow; } public function GetWorkflowInstanceId() { return $this->workflow->GetInstanceId(); } public function SetStatusTitle($title = '') { $rootActivity = $this->GetRootActivity(); $stateService = $this->workflow->GetService("StateService"); if ($rootActivity instanceof CBPStateMachineWorkflowActivity) { $arState = $stateService->GetWorkflowState($this->GetWorkflowInstanceId()); $arActivities = $rootActivity->CollectNestedActivities(); /** @var CBPActivity $activity */ foreach ($arActivities as $activity) if ($activity->GetName() == $arState["STATE_NAME"]) break; $stateService->SetStateTitle( $this->GetWorkflowInstanceId(), $activity->Title.($title != '' ? ": ".$title : '') ); } else { if ($title != '') { $stateService->SetStateTitle( $this->GetWorkflowInstanceId(), $title ); } } } public function AddStatusTitle($title = '') { if ($title == '') return; $stateService = $this->workflow->GetService("StateService"); $mainTitle = $stateService->GetStateTitle($this->GetWorkflowInstanceId()); $mainTitle .= ((strpos($mainTitle, ": ") !== false) ? ", " : ": ").$title; $stateService->SetStateTitle($this->GetWorkflowInstanceId(), $mainTitle); } public function DeleteStatusTitle($title = '') { if ($title == '') return; $stateService = $this->workflow->GetService("StateService"); $mainTitle = $stateService->GetStateTitle($this->GetWorkflowInstanceId()); $ar1 = explode(":", $mainTitle); if (count($ar1) <= 1) return; $newTitle = ""; $ar2 = explode(",", $ar1[1]); foreach ($ar2 as $a) { $a = trim($a); if ($a != $title) { if (strlen($newTitle) > 0) $newTitle .= ", "; $newTitle .= $a; } } $result = $ar1[0].(strlen($newTitle) > 0 ? ": " : "").$newTitle; $stateService->SetStateTitle($this->GetWorkflowInstanceId(), $result); } private function GetPropertyValueRecursive($val, $convertToType = null) { // array(2, 5, array("SequentialWorkflowActivity1", "DocumentApprovers")) // array("Document", "IBLOCK_ID") // array("Workflow", "id") // "Hello, {=SequentialWorkflowActivity1:DocumentApprovers}, {=Document:IBLOCK_ID}!" $parsed = $this->parseValueExpression($val); if ($parsed) { $result = null; if ($convertToType) $parsed['modifiers'][] = $convertToType; $this->GetRealParameterValue($parsed['object'], $parsed['field'], $result, $parsed['modifiers']); return array(1, $result); } elseif (is_array($val)) { $b = true; $r = array(); $keys = array_keys($val); $i = 0; foreach ($keys as $key) { if ($key."!" != $i."!") { $b = false; break; } $i++; } foreach ($keys as $key) { list($t, $a) = $this->GetPropertyValueRecursive($val[$key], $convertToType); if ($b) { if ($t == 1 && is_array($a)) $r = array_merge($r, $a); else $r[] = $a; } else { $r[$key] = $a; } } if (count($r) == 2) { $keys = array_keys($r); if ($keys[0] == 0 && $keys[1] == 1 && is_string($r[0]) && is_string($r[1])) { $result = null; $modifiers = $convertToType ? array($convertToType) : array(); if ($this->GetRealParameterValue($r[0], $r[1], $result, $modifiers)) return array(1, $result); } } return array(2, $r); } else { if (is_string($val)) { $typeClass = null; $fieldTypeObject = null; if ($convertToType) { /** @var CBPDocumentService $documentService */ $documentService = $this->workflow->GetService("DocumentService"); $documentType = $this->GetDocumentType(); $typesMap = $documentService->getTypesMap($documentType); $convertToType = strtolower($convertToType); if (isset($typesMap[$convertToType])) { $typeClass = $typesMap[$convertToType]; $fieldTypeObject = $documentService->getFieldTypeObject( $documentType, array('Type' => \Bitrix\Bizproc\FieldType::STRING) ); } } $calc = new CBPCalc($this); if (preg_match(self::CalcPattern, $val)) { $r = $calc->Calculate($val); if ($r !== null) { if ($typeClass && $fieldTypeObject) { if (is_array($r)) $fieldTypeObject->setMultiple(true); $r = $fieldTypeObject->convertValue($r, $typeClass); } return array(is_array($r)? 1 : 2, $r); } } //parse inline calculator $val = preg_replace_callback( static::CalcInlinePattern, function($matches) use ($calc) { $r = $calc->Calculate($matches[1]); if (is_array($r)) $r = implode(', ', CBPHelper::MakeArrayFlat($r)); return $r !== null? $r.$matches[2] : $matches[0]; }, $val ); //parse properties $val = preg_replace_callback( static::ValueInlinePattern, array($this, "ParseStringParameter"), $val ); //converting... if ($typeClass && $fieldTypeObject) { $val = $fieldTypeObject->convertValue($val, $typeClass); } } return array(2, $val); } } private function GetRealParameterValue($objectName, $fieldName, &$result, array $modifiers = null) { $return = true; $property = null; if ($objectName == "Document") { $rootActivity = $this->GetRootActivity(); $documentId = $rootActivity->GetDocumentId(); /** @var CBPDocumentService $documentService */ $documentService = $this->workflow->GetService("DocumentService"); $documentType = $this->GetDocumentType(); $document = $documentService->GetDocument($documentId, $documentType); $documentFields = $documentService->GetDocumentFields($documentType); //check aliases $documentFieldsAliasesMap = CBPDocument::getDocumentFieldsAliasesMap($documentFields); if (!isset($document[$fieldName]) && strtoupper(substr($fieldName, -strlen('_PRINTABLE'))) == '_PRINTABLE') { $fieldName = substr($fieldName, 0, -strlen('_PRINTABLE')); if (!in_array('printable', $modifiers)) $modifiers[] = 'printable'; } if (!isset($document[$fieldName]) && isset($documentFieldsAliasesMap[$fieldName])) { $fieldName = $documentFieldsAliasesMap[$fieldName]; } $result = ''; if (isset($document[$fieldName])) { $result = $document[$fieldName]; if (is_array($result) && strtoupper(substr($fieldName, -strlen('_PRINTABLE'))) == '_PRINTABLE') $result = implode(", ", CBPHelper::MakeArrayFlat($result)); if (!empty($modifiers)) { $property = isset($documentFields[$fieldName]) ? $documentFields[$fieldName] : null; } } } elseif ($objectName == 'Template' || $objectName == 'Variable' || $objectName == 'Constant') { $rootActivity = $this->GetRootActivity(); if (substr($fieldName, -strlen("_printable")) == "_printable") { $fieldName = substr($fieldName, 0, strlen($fieldName) - strlen("_printable")); $modifiers = array('printable'); } switch ($objectName) { case 'Variable': $result = $rootActivity->GetVariable($fieldName); $property = $rootActivity->getVariableType($fieldName); break; case 'Constant': $result = $rootActivity->GetConstant($fieldName); $property = $rootActivity->GetConstantType($fieldName); break; default: $result = $rootActivity->{$fieldName}; $property = $rootActivity->getTemplatePropertyType($fieldName); } } elseif ($objectName == "Workflow") { $result = $this->GetWorkflowInstanceId(); $property = array('Type' => 'string'); } elseif ($objectName == "User") { $result = 0; if (isset($GLOBALS["USER"]) && is_object($GLOBALS["USER"]) && $GLOBALS["USER"]->isAuthorized()) $result = "user_".$GLOBALS["USER"]->GetID(); $property = array('Type' => 'user'); } elseif ($objectName == "System") { global $DB; $result = null; $property = array('Type' => 'datetime'); $systemField = strtolower($fieldName); if ($systemField === 'now') $result = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL"))); elseif ($systemField === 'nowlocal') { $result = time(); if (CTimeZone::Enabled()) $result += CTimeZone::GetOffset(); $result = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $result); } elseif ($systemField == 'date') { $result = date($DB->DateFormatToPHP(CSite::GetDateFormat("SHORT"))); $property = array('Type' => 'date'); } if ($result === null) $return = false; } elseif ($objectName) { $activity = $this->workflow->GetActivityByName($objectName); if ($activity) { $result = $activity->{$fieldName}; //if mapping is set, we can apply modifiers (type converting & formating like `printable`, `bool` etc.) if (isset($activity->arPropertiesTypes[$fieldName])) { $property = $activity->arPropertiesTypes[$fieldName]; } } else $return = false; } else $return = false; if ($return) $result = $this->applyPropertyValueModifiers($fieldName, $property, $result, $modifiers); return $return; } private function applyPropertyValueModifiers($fieldName, $property, $value, array $modifiers) { if (empty($property) || empty($modifiers) || !is_array($property)) return $value; $typeName = $typeClass = $format = null; $rootActivity = $this->GetRootActivity(); $documentId = $rootActivity->GetDocumentId(); /** @var CBPDocumentService $documentService */ $documentService = $this->workflow->GetService("DocumentService"); $documentType = $this->GetDocumentType(); $typesMap = $documentService->getTypesMap($documentType); foreach ($modifiers as $m) { $m = strtolower($m); if (isset($typesMap[$m])) { $typeName = $m; $typeClass = $typesMap[$m]; } else { $format = $m; } } if ($typeName === \Bitrix\Bizproc\FieldType::STRING && $format === 'printable') { $typeClass = null; } if ($typeClass || $format) { $fieldTypeObject = $documentService->getFieldTypeObject($documentType, $property); if ($fieldTypeObject) { $fieldTypeObject->setDocumentId($documentId); if ($typeClass) $value = $fieldTypeObject->convertValue($value, $typeClass); if ($format) $value = $fieldTypeObject->formatValue($value, $format); } elseif ($format == 'printable') // compatibility: old printable style { $value = $documentService->GetFieldValuePrintable( $documentId, $fieldName, $property['Type'], $value, $property ); if (is_array($value)) $value = implode(", ", CBPHelper::MakeArrayFlat($value)); } } return $value; } private function ParseStringParameter($matches) { $result = ""; $modifiers = array(); if (!empty($matches['mod1'])) $modifiers[] = $matches['mod1']; if (!empty($matches['mod2'])) $modifiers[] = $matches['mod2']; if (empty($modifiers)) $modifiers[] = \Bitrix\Bizproc\FieldType::STRING; if ($this->GetRealParameterValue($matches['object'], $matches['field'], $result, $modifiers)) { if (is_array($result)) $result = implode(", ", CBPHelper::MakeArrayFlat($result)); } else { $result = $matches[0]; } return $result; } /** * @param $text * @return array|bool */ private function parseValueExpression($text) { $matches = null; if (is_string($text) && preg_match(static::ValuePattern, $text, $matches)) { $result = array( 'object' => $matches['object'], 'field' => $matches['field'], 'modifiers' => array() ); if (!empty($matches['mod1'])) $result['modifiers'][] = $matches['mod1']; if (!empty($matches['mod2'])) $result['modifiers'][] = $matches['mod2']; return $result; } return false; } public function ParseValue($value, $convertToType = null) { list($t, $r) = $this->GetPropertyValueRecursive($value, $convertToType); return $r; } protected function getRawProperty($name) { if (isset($this->arProperties[$name])) { return $this->arProperties[$name]; } return null; } function __get($name) { $property = $this->getRawProperty($name); if ($property !== null) { list($t, $r) = $this->GetPropertyValueRecursive($property); return $r; } return null; } function __set($name, $val) { if (array_key_exists($name, $this->arProperties)) $this->arProperties[$name] = $val; //else //throw new Exception(str_replace("#NAME#", htmlspecialcharsbx($name), GetMessage("BPCGACT_NO_PROPERTY"))); } public function IsPropertyExists($name) { return array_key_exists($name, $this->arProperties); } public function CollectNestedActivities() { return null; } /************************ CONSTRUCTORS *****************************************************/ public function __construct($name) { $this->name = $name; } /************************ DEBUG ***********************************************************/ public function ToString() { return $this->name. " [".get_class($this)."] (status=". CBPActivityExecutionStatus::Out($this->executionStatus). ", result=". CBPActivityExecutionResult::Out($this->executionResult). ", count(ClosedEvent)=". count($this->arStatusChangeHandlers[self::ClosedEvent]). ")"; } public function Dump($level = 3) { $result = str_repeat(" ", $level).$this->ToString()."\n"; if (is_subclass_of($this, "CBPCompositeActivity")) { /** @var CBPActivity $activity */ foreach ($this->arActivities as $activity) $result .= $activity->Dump($level + 1); } return $result; } /************************ PROCESS ***********************************************************/ public function Initialize() { } public function Finalize() { } public function Execute() { return CBPActivityExecutionStatus::Closed; } protected function ReInitialize() { $this->executionStatus = CBPActivityExecutionStatus::Initialized; $this->executionResult = CBPActivityExecutionResult::None; } public function Cancel() { return CBPActivityExecutionStatus::Closed; } public function HandleFault(Exception $exception) { return CBPActivityExecutionStatus::Closed; } /************************ LOAD / SAVE *******************************************************/ public function FixUpParentChildRelationship(CBPActivity $nestedActivity) { $nestedActivity->parent = $this; } public static function Load($stream) { if (strlen($stream) <= 0) throw new Exception("stream"); $pos = strpos($stream, ";"); $strUsedActivities = substr($stream, 0, $pos); $stream = substr($stream, $pos + 1); $runtime = CBPRuntime::GetRuntime(); $arUsedActivities = explode(",", $strUsedActivities); foreach ($arUsedActivities as $activityCode) { $runtime->IncludeActivityFile($activityCode); } return unserialize($stream); } protected function GetACNames() { return array(substr(get_class($this), 3)); } private static function SearchUsedActivities(CBPActivity $activity, &$arUsedActivities) { $arT = $activity->GetACNames(); foreach ($arT as $t) { if (!in_array($t, $arUsedActivities)) { $arUsedActivities[] = $t; } } if ($arNestedActivities = $activity->CollectNestedActivities()) { foreach ($arNestedActivities as $nestedActivity) { self::SearchUsedActivities($nestedActivity, $arUsedActivities); } } } public function Save() { $usedActivities = []; self::SearchUsedActivities($this, $usedActivities); $strUsedActivities = implode(",", $usedActivities); return $strUsedActivities.";".serialize($this); } /************************ STATUS CHANGE HANDLERS **********************************************/ public function AddStatusChangeHandler($event, $eventHandler) { if (!is_array($this->arStatusChangeHandlers)) $this->arStatusChangeHandlers = array(); if (!array_key_exists($event, $this->arStatusChangeHandlers)) $this->arStatusChangeHandlers[$event] = array(); $this->arStatusChangeHandlers[$event][] = $eventHandler; } public function RemoveStatusChangeHandler($event, $eventHandler) { if (!is_array($this->arStatusChangeHandlers)) $this->arStatusChangeHandlers = array(); if (!array_key_exists($event, $this->arStatusChangeHandlers)) $this->arStatusChangeHandlers[$event] = array(); $index = array_search($eventHandler, $this->arStatusChangeHandlers[$event], true); if ($index !== false) unset($this->arStatusChangeHandlers[$event][$index]); } /************************ EVENTS **********************************************************************/ private function FireStatusChangedEvents($event, $arEventParameters = array()) { if (array_key_exists($event, $this->arStatusChangeHandlers) && is_array($this->arStatusChangeHandlers[$event])) { foreach ($this->arStatusChangeHandlers[$event] as $eventHandler) call_user_func_array(array($eventHandler, "OnEvent"), array($this, $arEventParameters)); } } public function SetStatus($newStatus, $arEventParameters = array()) { $this->executionStatus = $newStatus; $this->FireStatusChangedEvents(self::StatusChangedEvent, $arEventParameters); switch ($newStatus) { case CBPActivityExecutionStatus::Executing: $this->FireStatusChangedEvents(self::ExecutingEvent, $arEventParameters); break; case CBPActivityExecutionStatus::Canceling: $this->FireStatusChangedEvents(self::CancelingEvent, $arEventParameters); break; case CBPActivityExecutionStatus::Closed: $this->FireStatusChangedEvents(self::ClosedEvent, $arEventParameters); break; case CBPActivityExecutionStatus::Faulting: $this->FireStatusChangedEvents(self::FaultingEvent, $arEventParameters); break; default: return; } } /************************ CREATE *****************************************************************/ public static function IncludeActivityFile($code) { $runtime = CBPRuntime::GetRuntime(); return $runtime->IncludeActivityFile($code); } public static function CreateInstance($code, $data) { if (preg_match("#[^a-zA-Z0-9_]#", $code)) throw new Exception("Activity '".$code."' is not valid"); $classname = 'CBP'.$code; if (class_exists($classname)) return new $classname($data); else return null; } public static function CallStaticMethod($code, $method, $arParameters = array()) { $runtime = CBPRuntime::GetRuntime(); if (!$runtime->IncludeActivityFile($code)) return array(array("code" => "ActivityNotFound", "parameter" => $code, "message" => GetMessage("BPGA_ACTIVITY_NOT_FOUND", array('#ACTIVITY#' => htmlspecialcharsbx($code))))); if (preg_match("#[^a-zA-Z0-9_]#", $code)) throw new Exception("Activity '".$code."' is not valid"); $classname = 'CBP'.$code; if (method_exists($classname,$method)) return call_user_func_array(array($classname, $method), $arParameters); return false; } public function InitializeFromArray($arParams) { if (is_array($arParams)) { foreach ($arParams as $key => $value) { if (array_key_exists($key, $this->arProperties)) $this->arProperties[$key] = $value; } } } /************************ MARK ****************************************************************/ public function MarkCanceled($arEventParameters = array()) { if ($this->executionStatus != CBPActivityExecutionStatus::Closed) { if ($this->executionStatus != CBPActivityExecutionStatus::Canceling) throw new Exception("InvalidCancelActivityState"); $this->executionResult = CBPActivityExecutionResult::Canceled; $this->MarkClosed($arEventParameters); } } public function MarkCompleted($arEventParameters = array()) { $this->executionResult = CBPActivityExecutionResult::Succeeded; $this->MarkClosed($arEventParameters); } public function MarkFaulted($arEventParameters = array()) { $this->executionResult = CBPActivityExecutionResult::Faulted; $this->MarkClosed($arEventParameters); } private function MarkClosed($arEventParameters = array()) { switch ($this->executionStatus) { case CBPActivityExecutionStatus::Executing: case CBPActivityExecutionStatus::Canceling: case CBPActivityExecutionStatus::Faulting: { if (is_subclass_of($this, "CBPCompositeActivity")) { foreach ($this->arActivities as $activity) { if (($activity->executionStatus != CBPActivityExecutionStatus::Initialized) && ($activity->executionStatus != CBPActivityExecutionStatus::Closed)) { throw new Exception("ActiveChildExist"); } } } /** @var CBPTrackingService $trackingService */ $trackingService = $this->workflow->GetService("TrackingService"); $trackingService->Write($this->GetWorkflowInstanceId(), CBPTrackingType::CloseActivity, $this->name, $this->executionStatus, $this->executionResult, ($this->IsPropertyExists("Title") ? $this->Title : "")); $this->SetStatus(CBPActivityExecutionStatus::Closed, $arEventParameters); return; } } throw new Exception("InvalidCloseActivityState"); } protected function WriteToTrackingService($message = "", $modifiedBy = 0, $trackingType = -1) { /** @var CBPTrackingService $trackingService */ $trackingService = $this->workflow->GetService("TrackingService"); if ($trackingType < 0) $trackingType = CBPTrackingType::Custom; $trackingService->Write($this->GetWorkflowInstanceId(), $trackingType, $this->name, $this->executionStatus, $this->executionResult, ($this->IsPropertyExists("Title") ? $this->Title : ""), $message, $modifiedBy); } public static function ValidateProperties($arTestProperties = array(), CBPWorkflowTemplateUser $user = null) { return array(); } public static function ValidateChild($childActivity, $bFirstChild = false) { return array(); } public static function &FindActivityInTemplate(&$arWorkflowTemplate, $activityName) { return CBPWorkflowTemplateLoader::FindActivityByName($arWorkflowTemplate, $activityName); } public static function isExpression($text) { if (is_string($text)) { $text = trim($text); if (preg_match(static::CalcPattern, $text) || preg_match(static::ValuePattern, $text)) return true; } return false; } }