10 private bool $isNew =
false;
11 private bool $isAbandoned =
false;
12 private string $instanceId;
22 private array $activitiesNamesMap = [];
28 return $this->instanceId;
44 private function getWorkflowStatus()
51 $this->rootActivity->setWorkflowStatus($newStatus);
53 $this->syncStatus($newStatus);
58 return $this->runtime->getService(
$name);
63 return $this->rootActivity->getDocumentId();
68 return $this->rootActivity->getDocumentType();
73 return (
int)$this->rootActivity->getWorkflowTemplateId();
78 $startedBy = (int)CBPHelper::stripUserPrefix($this->rootActivity->{\CBPDocument::PARAM_TAGRET_USER});
80 return $startedBy ?:
null;
85 return $this->persister;
100 throw new Exception(
"instanceId");
103 $this->instanceId = $instanceId;
122 $workflowParameters = [],
123 $workflowVariablesTypes = [],
124 $workflowParametersTypes = [],
125 $workflowTemplateId = 0
138 CBPWorkflowTemplateLoader::getTemplateUserId($workflowTemplateId)
142 $arDocumentId = CBPHelper::parseDocumentId($documentId);
146 $documentService = $this->
getService(
"DocumentService");
147 $documentType = $workflowParameters[CBPDocument::PARAM_DOCUMENT_TYPE]
148 ?? $documentService->getDocumentType($arDocumentId)
151 unset($workflowParameters[CBPDocument::PARAM_DOCUMENT_TYPE]);
153 if ($documentType !==
null)
156 $rootActivity->setFieldTypes($documentService->getDocumentFieldTypes($documentType));
162 if (is_array($workflowVariablesTypes))
164 foreach ($workflowVariablesTypes as
$k => $v)
166 $variableValue = $v[
"Default"] ??
null;
167 if ($documentType && $fieldTypeObject = $documentService->getFieldTypeObject($documentType, $v))
169 $fieldTypeObject->setDocumentId($arDocumentId);
170 $variableValue = $fieldTypeObject->internalizeValue(
'Variable', $variableValue);
186 switch ($this->getWorkflowStatus())
190 throw new Exception(
"InvalidAttemptToLoad");
204 throw new Exception(
"CanNotStartInstanceTwice");
219 throw new Exception(
"CanNotResumeInstance");
225 private function run(): void
232 $this->rootActivity->setReadOnlyData(
233 $this->rootActivity->pullProperties()
236 $this->initializeActivity($this->rootActivity);
237 $this->executeActivity($this->rootActivity);
244 $this->terminate($e);
258 $this->persister->saveWorkflow($this->rootActivity,
true);
273 return $this->isAbandoned;
296 $this->addEventToQueue($eventName, $eventParameters);
312 $arSubActivities =
$activity->collectNestedActivities();
313 foreach ($arSubActivities as $subActivity)
315 $this->fillNameActivityMapInternal($subActivity);
320 private function fillNameActivityMap()
322 if (!is_array($this->activitiesNamesMap))
324 $this->activitiesNamesMap = [];
327 if (
count($this->activitiesNamesMap) > 0)
332 $this->fillNameActivityMapInternal($this->rootActivity);
343 if ($activityName ==
'')
345 throw new Exception(
'activityName');
350 $this->fillNameActivityMap();
352 if (array_key_exists($activityName, $this->activitiesNamesMap))
354 $activity = $this->activitiesNamesMap[$activityName];
371 throw new Exception(
"InvalidInitializingState");
387 throw new Exception(
"InvalidExecutionState");
391 $this->addItemToQueue([
$activity, CBPActivityExecutorOperationType::Execute]);
405 $activity->markCompleted($arEventParameters);
409 $activity->markCanceled($arEventParameters);
416 $activity->markFaulted($arEventParameters);
420 throw new Exception(
"InvalidClosingState");
433 throw new Exception(
"InvalidCancelingState");
437 $this->addItemToQueue(
array(
$activity, CBPActivityExecutorOperationType::Cancel));
446 $this->Terminate($e);
450 $this->FaultActivity(
$activity->parent, $e, $arEventParameters);
456 $this->addItemToQueue(
array(
$activity, CBPActivityExecutorOperationType::HandleFault, $e));
462 private function addItemToQueue($item)
464 $this->activitiesQueue[] = $item;
479 if (empty($this->activitiesQueue))
481 $this->ProcessQueuedEvents();
484 $item = array_shift($this->activitiesQueue);
492 $this->runQueuedItem($item[0], $item[1], (
count($item) > 2 ? $item[2] :
null));
510 private function runQueuedItem(
CBPActivity $activity, $activityOperation, Exception $exception =
null): void
512 match ($activityOperation)
514 CBPActivityExecutorOperationType::Execute => $this->runExecuteActivityOperation(
$activity),
515 CBPActivityExecutorOperationType::Cancel => $this->runCancelActivityOperation(
$activity),
516 CBPActivityExecutorOperationType::HandleFault => $this->runHandleFaultActivityOperation(
$activity, $exception),
536 $trackingService = $this->getService(
'TrackingService');
537 $trackingService->write(
538 $this->getInstanceId(),
555 throw new Exception(
'InvalidExecutionStatus');
572 $trackingService = $this->getService(
"TrackingService");
573 $trackingService->write(
574 $this->getInstanceId(),
590 throw new Exception(
"InvalidExecutionStatus");
600 private function runHandleFaultActivityOperation(
CBPActivity $activity, ?Exception $exception): void
608 $trackingService = $this->getService(
"TrackingService");
609 $trackingService->write(
610 $this->getInstanceId(),
616 ($exception ? ($exception->getCode() ?
"[" . $exception->getCode() .
"] " :
'') . $exception->getMessage() :
"")
619 $newStatus =
$activity->handleFault($exception);
627 throw new Exception(
"InvalidExecutionStatus");
631 public function terminate(Exception $e =
null, $stateTitle =
'')
637 $this->persister->SaveWorkflow($this->rootActivity,
true);
640 $stateService = $this->GetService(
"StateService");
641 $stateService->SetState(
644 "STATE" =>
"Terminated",
645 "TITLE" => $stateTitle ?:
GetMessage(
"BPCGWF_TERMINATED_MSGVER_1"),
654 $trackingService = $this->getService(
"TrackingService");
655 $trackingService->write(
662 ($e->getCode() ?
"[" . $e->getCode() .
"] " :
'') . $e->getMessage()
679 private function addEventToQueue($eventName, $arEventParameters =
array())
681 $this->eventsQueue[] = [$eventName, $arEventParameters];
684 private function processQueuedEvents()
688 $event = array_shift($this->eventsQueue);
694 [$eventName, $eventParameters] =
$event;
696 $this->processQueuedEvent($eventName, $eventParameters);
700 private function processQueuedEvent($eventName, $eventParameters = [])
702 if (!array_key_exists($eventName, $this->rootActivity->arEventsMap))
707 foreach ($this->rootActivity->arEventsMap[$eventName] as $eventHandler)
711 $eventHandler->onDebugEvent($eventParameters);
716 if ($eventHandler instanceof IBPActivityExternalEventListener)
718 $eventHandler->onExternalEvent($eventParameters);
723 private function syncStatus(
int $status): void
730 WorkflowUserTable::syncOnWorkflowUpdated($this,
$status);
741 if (!is_array($this->rootActivity->arEventsMap))
743 $this->rootActivity->arEventsMap = [];
746 if (!array_key_exists($eventName, $this->rootActivity->arEventsMap))
748 $this->rootActivity->arEventsMap[$eventName] = [];
751 $this->rootActivity->arEventsMap[$eventName][] = $eventHandler;
756 return is_array($this->rootActivity->arEventsMap) ? $this->rootActivity->arEventsMap : [];
767 if (!is_array($this->rootActivity->arEventsMap))
769 $this->rootActivity->arEventsMap = [];
772 if (!array_key_exists($eventName, $this->rootActivity->arEventsMap))
774 $this->rootActivity->arEventsMap[$eventName] = [];
777 $idx = array_search($eventHandler, $this->rootActivity->arEventsMap[$eventName],
true);
780 unset($this->rootActivity->arEventsMap[$eventName][$idx]);
783 if (
count($this->rootActivity->arEventsMap[$eventName]) <= 0)
785 unset($this->rootActivity->arEventsMap[$eventName]);
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)