Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
runtime.php
1<?php
2
4
12
13Loc::loadMessages(__FILE__);
14
16{
17 use Bizproc\Debugger\Mixins\WriterDebugTrack;
18
19 protected $target;
20 protected static $startedTemplates = [];
21
22 public function setTarget(BaseTarget $target)
23 {
24 $this->target = $target;
25 return $this;
26 }
27
32 public function getTarget()
33 {
34 if ($this->target === null)
35 {
36 throw new InvalidOperationException('Target must be set by setTarget method.');
37 }
38
39 return $this->target;
40 }
41
42 protected function getWorkflowInstanceIds()
43 {
44 $documentType = $this->getTarget()->getDocumentType();
45 $documentId = $this->getTarget()->getDocumentId();
46 $ids = WorkflowInstanceTable::getList([
47 'select' => ['ID'],
48 'filter' => [
49 '=MODULE_ID' => $documentType[0],
50 '=ENTITY' => $documentType[1],
51 '=DOCUMENT_ID' => $documentId,
52 '@STARTED_EVENT_TYPE' => [\CBPDocumentEventType::Automation, \CBPDocumentEventType::Debug],
53 '=TEMPLATE.DOCUMENT_TYPE' => $documentType[2],
54 ],
55 ])->fetchAll();
56
57 return array_column($ids, 'ID');
58 }
59
60 public function getCurrentWorkflowId(): ?string
61 {
62 $documentType = $this->getTarget()->getDocumentType();
63
64 $template = new Template(
65 $documentType,
66 $this->getTarget()->getDocumentStatus()
67 );
68
69 if ($template->getId() > 0)
70 {
71 $filter = [
72 '=DOCUMENT_ID' => $this->getTarget()->getDocumentId(),
73 '=TEMPLATE.ID' => $template->getId(),
74 ];
75
76 if ($this->isDebug())
77 {
78 $session = Bizproc\Debugger\Session\Manager::getActiveSession();
79 $filter['@ID'] = $session->getWorkflowContexts()->getWorkflowIdList();
80 }
81
82 $row = WorkflowStateTable::getList([
83 'select' => ['ID'],
84 'filter' => $filter,
85 'order' => ['STARTED' => 'DESC'],
86 'limit' => 1,
87 ])->fetch();
88
89 return $row ? $row['ID'] : null;
90 }
91
92 return null;
93 }
94
95 protected function runTemplates($documentStatus, string $preGeneratedWorkflowId = null)
96 {
97 $isDebug = $this->isDebug();
98 $template = new Template($this->getTarget()->getDocumentType(), $documentStatus);
99 $workflowId = null;
100
101 if ($template->getId() > 0)
102 {
103 $errors = [];
104 $trigger = $this->getTarget()->getAppliedTrigger();
105 $this->getTarget()->setAppliedTrigger([]);
106
107 if (
108 !$template->isExternalModified()
109 && !$isDebug
110 && !$trigger
111 && !$template->getRobots()
112 )
113 {
114 return false;
115 }
116
117 $documentType = $this->getTarget()->getDocumentType();
118 $documentId = $this->getTarget()->getDocumentId();
119 $documentComplexId = [$documentType[0], $documentType[1], $documentId];
120
121 $startParameters = [
122 \CBPDocument::PARAM_TAGRET_USER => null, //Started by System
123 \CBPDocument::PARAM_USE_FORCED_TRACKING => $isDebug || !$template->isExternalModified(),
124 \CBPDocument::PARAM_IGNORE_SIMULTANEOUS_PROCESSES_LIMIT => true,
125 \CBPDocument::PARAM_DOCUMENT_TYPE => $documentType,
126 \CBPDocument::PARAM_DOCUMENT_EVENT_TYPE =>
127 $isDebug ? \CBPDocumentEventType::Debug : \CBPDocumentEventType::Automation,
128 \CBPDocument::PARAM_PRE_GENERATED_WORKFLOW_ID => $preGeneratedWorkflowId ?? null,
129 ];
130
131 if (isset($trigger['RETURN']) && is_array($trigger['RETURN']))
132 {
133 $startParameters += $trigger['RETURN'];
134 }
135
136 foreach ($template->getParameters() as $parameterId => $parameter)
137 {
138 if (!isset($startParameters[$parameterId]) && isset($parameter['Default']))
139 {
140 $startParameters[$parameterId] = $parameter['Default'];
141 }
142 }
143
144 $this->setStarted($documentType[2], $documentId, $documentStatus);
145
146 $args = [$template->getId(), $documentComplexId, $startParameters, $errors];
147
148 if ($isDebug && $preGeneratedWorkflowId)
149 {
150 $session = Bizproc\Debugger\Session\Manager::getActiveSession();
151 $session->addWorkflowContext($preGeneratedWorkflowId, $template);
152 }
153
154 $workflowId = $isDebug
155 ? \CBPDocument::startDebugWorkflow(...$args)
156 : \CBPDocument::startWorkflow(...$args)
157 ;
158
159 if (!$errors && $workflowId)
160 {
161 if ($trigger)
162 {
163 $this->writeTriggerTracking($workflowId, $trigger);
164 $this->writeTriggerAnalytics($documentComplexId, $trigger);
165 }
166 }
167 }
168
169 return $workflowId;
170 }
171
172 protected function writeTriggerTracking($workflowId, $trigger)
173 {
174 $trackingService = \CBPRuntime::getRuntime(true)->getTrackingService();
175
176 $trackingService->write(
177 $workflowId,
178 \CBPTrackingType::Trigger,
179 'APPLIED_TRIGGER',
180 \CBPActivityExecutionStatus::Closed,
181 \CBPActivityExecutionResult::Succeeded,
182 '',
183 $trigger['ID']
184 );
185 }
186
187 protected function writeTriggerAnalytics(array $documentId, array $trigger)
188 {
189 $analyticsService = \CBPRuntime::getRuntime(true)->getAnalyticsService();
190 if ($analyticsService->isEnabled())
191 {
192 $analyticsService->write($documentId, 'trigger_run', $trigger['CODE']);
193 }
194 }
195
196 protected function stopTemplates()
197 {
198 $errors = [];
199 $instanceIds = $this->getWorkflowInstanceIds();
200 $documentType = $this->getTarget()->getDocumentType();
201 $documentId = [$documentType[0], $documentType[1], $this->getTarget()->getDocumentId()];
202 foreach ($instanceIds as $instanceId)
203 {
204 \CBPDocument::terminateWorkflow(
205 $instanceId,
206 $documentId,
207 $errors,
208 Loc::getMessage('BIZPROC_AUTOMATION_TEMPLATE_TERMINATED')
209 );
210 }
211 }
212
219 public function onDocumentAdd(?Context $context = null)
220 {
221 $preGeneratedWorkflowId = \CBPRuntime::generateWorkflowId();
222 $isManualAdd = $context && $context->isManualOperation();
223
224 if (!$isManualAdd && $this->isDebug(true))
225 {
226 $debugSession = Bizproc\Debugger\Session\Manager::getActiveSession();
227
228 if ($debugSession->isBeforeDebuggerStartState())
229 {
230 $debugSession->addDocument($this->getTarget()->getDocumentId());
231
232 return;
233 }
234
235 $debugSession->addWorkflowContext($preGeneratedWorkflowId, []);
236
237 $status = $this->getTarget()->getDocumentStatus();
238 $this->writeSessionLegendTrack($preGeneratedWorkflowId);
239 $this->writeStatusTracking($preGeneratedWorkflowId, $status);
240 $this->writeCategoryTracking($preGeneratedWorkflowId);
241 }
242
243 $this->runDocumentStatus($preGeneratedWorkflowId);
244 }
245
252 public function onDocumentStatusChanged()
253 {
254 $preGeneratedWorkflowId = \CBPRuntime::generateWorkflowId();
255 if ($this->isDebug())
256 {
257 $debugSession = Bizproc\Debugger\Session\Manager::getActiveSession();
258
259 if ($debugSession->isBeforeDebuggerStartState())
260 {
261 return;
262 }
263
264 $debugSession->addWorkflowContext($preGeneratedWorkflowId, []);
265
266 $status = $this->getTarget()->getDocumentStatus();
267 $documentType = $this->getTarget()->getDocumentType()[2];
268 $documentId = $this->getTarget()->getDocumentId();
269 if (!$this->isStarted($documentType, $documentId, $status))
270 {
271 $this->onDocumentStatusChangedDebug($preGeneratedWorkflowId, $status);
272 }
273 }
274
275 $this->runDocumentStatus($preGeneratedWorkflowId);
276 }
277
278 public function runDocumentStatus(string $preGeneratedWorkflowId = null): ?string
279 {
280 $status = $this->getTarget()->getDocumentStatus();
281 $documentType = $this->getTarget()->getDocumentType()[2];
282 $documentId = $this->getTarget()->getDocumentId();
283
284 if ($status && !$this->isStarted($documentType, $documentId, $status))
285 {
286 $this->stopTemplates();
287
288 return $this->runTemplates($status, $preGeneratedWorkflowId);
289 }
290
291 return null;
292 }
293
294 protected function isDebug(bool $isOnDocumentAdd = false): bool
295 {
296 $debugSession = Bizproc\Debugger\Session\Manager::getActiveSession();
297 if (!$debugSession)
298 {
299 return false;
300 }
301
302 $documentType = $this->getTarget()->getDocumentType();
303 if (!$debugSession->isStartedInDocumentType($documentType))
304 {
305 return false;
306 }
307
308 $documentId = $this->getTarget()->getComplexDocumentId();
309 if (!$isOnDocumentAdd || $debugSession->isExperimentalMode() || $debugSession->isFixed())
310 {
311 return $debugSession->isSessionDocument($documentId);
312 }
313
314 $documentCategoryId = $this->getTarget()->getDocumentCategory();
315
316 return $documentCategoryId === $debugSession->getDocumentCategoryId();
317 }
318
319 protected function onDocumentStatusChangedDebug(?string $workflowId, string $status)
320 {
321 if ($workflowId)
322 {
323 $trigger = $this->getTarget()->getAppliedTrigger();
324 if ($trigger)
325 {
326 $trigger['APPLIED_RULE_LOG'] = $this->getTarget()->getAppliedTriggerConditionResults();
327 $this->writeAppliedTriggerTrack($workflowId, $trigger);
328 }
329
330 $this->writeStatusTracking($workflowId, $status);
331 }
332
333 Bizproc\Debugger\Listener::getInstance()->onDocumentStatusChanged($status);
334 }
335
341 public function onDocumentMove()
342 {
343 $this->stopTemplates();
344 }
345
346 public function onFieldsChanged(array $changes)
347 {
348 if ($this->isDebug() && $changes)
349 {
350 $debugSession = Bizproc\Debugger\Session\Manager::getActiveSession();
351 if ($debugSession->isBeforeDebuggerStartState())
352 {
353 return;
354 }
355
356 $target = $this->getTarget();
357
358 if ($target->getDocumentCategoryCode() && in_array($target->getDocumentCategoryCode(), $changes))
359 {
360 $session = Bizproc\Debugger\Session\Manager::getActiveSession();
361 $sessionWorkflows = $session->getWorkflowContexts()->getWorkflowIdList();
362 if (!empty($sessionWorkflows))
363 {
364 $lastWorkflowId = $sessionWorkflows[array_key_last($sessionWorkflows)];
365 $this->writeCategoryTracking($lastWorkflowId);
366 }
367 }
368
369 Bizproc\Debugger\Listener::getInstance()->onDocumentUpdated($changes);
370 }
371 }
372
373 private function setStarted($documentType, $documentId, $status)
374 {
375 $key = $documentType . '_' . $documentId;
376 static::$startedTemplates[$key] = (string)$status;
377 return $this;
378 }
379
380 private function isStarted($documentType, $documentId, $status)
381 {
382 $key = $documentType . '_' . $documentId;
383 return (
384 isset(static::$startedTemplates[$key])
385 && (string)$status === static::$startedTemplates[$key]
386 );
387 }
388
389 private function writeStatusTracking($workflowId, string $status): ?int
390 {
391 $statuses = $this->getTarget()->getDocumentStatusList();
392 $status = $statuses[$status] ?? [];
393
394 return $this->writeDocumentStatusTrack($workflowId, $status);
395 }
396
397 private function writeCategoryTracking($workflowId): ?int
398 {
399 $documentService = \CBPRuntime::GetRuntime(true)->getDocumentService();
400 $categories = $documentService->getDocumentCategories($this->target->getDocumentType());
401
402 $categoryName = $categories[$this->target->getDocumentCategory()]['name'];
403
404 return $this->writeDocumentCategoryTrack($workflowId, $categoryName);
405 }
406}
writeTriggerTracking($workflowId, $trigger)
Definition runtime.php:172
onDocumentStatusChangedDebug(?string $workflowId, string $status)
Definition runtime.php:319
runDocumentStatus(string $preGeneratedWorkflowId=null)
Definition runtime.php:278
isDebug(bool $isOnDocumentAdd=false)
Definition runtime.php:294
writeTriggerAnalytics(array $documentId, array $trigger)
Definition runtime.php:187
runTemplates($documentStatus, string $preGeneratedWorkflowId=null)
Definition runtime.php:95
onDocumentAdd(?Context $context=null)
Definition runtime.php:219
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29