Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
Session.php
1<?php
2
4
8use Bitrix\Bizproc\Service\Entity\EO_Tracking;
13
14class Session extends Entity\EO_DebuggerSession
15{
16 public const ERROR_DOCUMENT_ID_ALREADY_FIXED = 'DOCUMENT ID IS ALREADY FIXED';
17 public const ERROR_UNKNOWN_DOCUMENT_ID = 'FIXING UNKNOWN DOCUMENT ID';
18
19 public function canUserFinish(int $userId): bool
20 {
21 // or admin ?
22 return $this->isStartedByUser($userId);
23 }
24
25 public function canUserDebug(int $userId): bool
26 {
27 // or admin ?
28 return $this->isStartedByUser($userId);
29 }
30
31 public function finish()
32 {
33 if ($this->isBeforeDebuggerStartState())
34 {
35 $this->fillDocuments();
36 $documents = clone($this->getDocuments());
37 if ($documents)
38 {
39 foreach ($documents as $document)
40 {
41 $this->removeFromDocuments($document);
42 }
43 }
44 }
45
46 $this
47 ->setFinishedDate(new \Bitrix\Main\Type\DateTime())
48 ->setActive(false)
49 ;
50
51 //$this->killWorkflows();
52 $this->terminateWorkflows();
53
54 $result = $this->save();
55 if ($result->isSuccess() && $this->isFixed())
56 {
57 $documentService = \CBPRuntime::GetRuntime(true)->getDocumentService();
58
59 $documentService->onDebugSessionDocumentStatusChanged(
60 $this->getFixedDocument()->getParameterDocumentId(),
61 $this->getStartedBy(),
63 );
64 }
65
66 return $result;
67 }
68
69 public function deleteAll(): Result
70 {
71 $result = new Result();
72
73 $this->deleteWorkflows();
74 $result->addErrors($this->deleteDocuments()->getErrors());
75 $result->addErrors($this->delete()->getErrors());
76
77 return $result;
78 }
79
80 public function deleteWorkflows()
81 {
82 $this->killWorkflows();
83 }
84
85 public function deleteDocuments(): Result
86 {
87 $result = new Result();
88
89 foreach ($this->getDocuments() as $document)
90 {
91 $deletionResult = $document->delete();
92
93 if (!$deletionResult->isSuccess())
94 {
95 $result->addErrors($deletionResult->getErrors());
96 }
97 }
98
99 return $result;
100 }
101
102 private function killWorkflows()
103 {
104 $workflowContexts = $this->getWorkflowContexts();
105
106 if ($workflowContexts)
107 {
108 foreach ($workflowContexts as $context)
109 {
110 \CBPDocument::killWorkflow($context->getWorkflowId());
111
112 $shouldSaveTemplateShards = (bool)DebuggerSessionWorkflowContextTable::getList([
113 'filter' => [
114 '!=ID' => $context->getId(),
115 'TEMPLATE_SHARDS_ID' => $context->getTemplateShardsId(),
116 ],
117 'limit' => 1,
118 ])->fetchObject();
119
120 if (!$shouldSaveTemplateShards)
121 {
122 $shards = $context->fillTemplateShards();
123 if ($shards)
124 {
125 $shards->delete();
126 }
127 }
128
129 $context->delete();
130 }
131 }
132 }
133
134 private function terminateWorkflows(): Result
135 {
136 $workflowContexts = $this->getWorkflowContexts();
137 $result = new Result();
138
139 if ($workflowContexts)
140 {
141 foreach ($workflowContexts as $context)
142 {
143 \CBPDocument::TerminateWorkflow($context->getWorkflowId(), null, $errors);
144
145 foreach ($errors as $rawError)
146 {
147 $error = new Error(
148 $rawError['message'],
149 $rawError['code'],
150 ['workflowId' => $context->getWorkflowId()]
151 );
152 $result->addError($error);
153 }
154 }
155 }
156
157 return $result;
158 }
159
160 public function addDocument(string $documentId)
161 {
162 if ($this->isFixed())
163 {
164 $result = new \Bitrix\Main\Result();
165 $error = static::getErrorByCode(self::ERROR_DOCUMENT_ID_ALREADY_FIXED);
166 $result->addError($error);
167
168 return $result;
169 }
170
172 $document
173 ->setSessionId($this->getId())
174 ->setDocumentId($documentId)
175 ;
176
177 if ($this->getMode() === Mode::EXPERIMENTAL)
178 {
179 $document->setDateExpire(null);
180 }
181
182 $this->addToDocuments($document);
183
184 $result = $this->save();
185 if ($result->isSuccess() && $this->getMode() === Mode::INTERCEPTION)
186 {
187 $documentService = \CBPRuntime::GetRuntime(true)->getDocumentService();
188 $parameterDocumentId = $this->getParameterDocumentType();
189 $parameterDocumentId[2] = $documentId;
190
191 $documentService->onDebugSessionDocumentStatusChanged(
192 $parameterDocumentId,
193 $this->getStartedBy(),
195 );
196 }
197
198 return $result;
199 }
200
201 public function removeFromDocuments(\Bitrix\Bizproc\Debugger\Session\Document $debuggerSessionDocument): void
202 {
203 $documentId = $debuggerSessionDocument->getDocumentId();
204 $parameterDocumentId = $this->getParameterDocumentType();
205 $parameterDocumentId[2] = $documentId;
206
207 parent::removeFromDocuments($debuggerSessionDocument);
208 $debuggerSessionDocument->delete();
209
210 $documentService = \CBPRuntime::GetRuntime(true)->getDocumentService();
211
212 $documentService->onDebugSessionDocumentStatusChanged(
213 $parameterDocumentId,
214 $this->getStartedBy(),
216 );
217
219 $target = $documentService->createAutomationTarget($this->getParameterDocumentType());
220 $target->setDocumentId($documentId);
221
222 $target->getRuntime()->runDocumentStatus();
223 }
224
230 public function addWorkflowContext(string $workflowId, $template): \Bitrix\Main\ORM\Data\Result
231 {
232 if ($this->hasWorkflow($workflowId))
233 {
234 $contextRow = DebuggerSessionWorkflowContextTable::getRow([
235 'filter' => ['WORKFLOW_ID' => $workflowId],
236 ]);
237
238 $context = DebuggerSessionWorkflowContextTable::wakeUpObject($contextRow);
239 }
240 else
241 {
242 $context = DebuggerSessionWorkflowContextTable::createObject();
243 $context
244 ->setWorkflowId($workflowId)
245 ->setSessionId($this->getId())
246 ;
247 }
248
249 $context->addTemplateShards($template);
250 $result = $context->save();
251
252 if ($result->isSuccess())
253 {
254 $this->addToWorkflowContexts($context);
255 }
256
257 return $result;
258 }
259
260 public function hasWorkflow(string $workflowId): bool
261 {
262 $ids = $this->getWorkflowContexts()->getWorkflowIdList();
263
264 return in_array($workflowId, $ids);
265 }
266
267 public function fixateDocument(string $documentId)
268 {
269 if (!$this->canAddDocument())
270 {
271 $result = new \Bitrix\Main\Result();
272 $error = static::getErrorByCode(self::ERROR_DOCUMENT_ID_ALREADY_FIXED);
273 $result->addError($error);
274
275 return $result;
276 }
277
278 if ($this->getMode() === Mode::EXPERIMENTAL)
279 {
280 $addDocumentResult = $this->addDocument($documentId);
281 if ($addDocumentResult->isSuccess())
282 {
283 $this->setFixed(true);
284
285 $result = $this->save();
286 if ($result->isSuccess())
287 {
288 $documentService = \CBPRuntime::GetRuntime(true)->getDocumentService();
289
290 $documentService->onDebugSessionDocumentStatusChanged(
291 $this->getFixedDocument()->getParameterDocumentId(),
292 $this->getStartedBy(),
294 );
295 }
296
297 return $result;
298 }
299
300 return $addDocumentResult;
301 }
302
303 $documents = clone($this->getDocuments());
304 $documentIds = $documents ? $documents->getDocumentIdList() : [];
305
306 if (!in_array($documentId, $documentIds, true))
307 {
308 $result = new \Bitrix\Main\Result();
309 $error = static::getErrorByCode(self::ERROR_UNKNOWN_DOCUMENT_ID);
310 $result->addError($error);
311 $result->setData([
312 'session' => $this,
313 'documentId' => $documentId,
314 ]);
315
316 return $result;
317 }
318
319 foreach ($documents as $document)
320 {
321 if ($document->getDocumentId() === $documentId)
322 {
323 $this->setFixed(true);
324
325 continue;
326 }
327
328 $this->removeFromDocuments($document);
329 }
330
331 $result = $this->save();
332 if ($result->isSuccess())
333 {
334 $documentService = \CBPRuntime::GetRuntime(true)->getDocumentService();
335
336 $documentService->onDebugSessionDocumentStatusChanged(
337 $this->getFixedDocument()->getParameterDocumentId(),
338 $this->getStartedBy(),
340 );
341 }
342
343 return $result;
344 }
345
346 public function isActive(): bool
347 {
348 return $this->getActive();
349 }
350
351 public function isFixed(): bool
352 {
353 return $this->getFixed();
354 }
355
356 public function getParameterDocumentType(): array
357 {
358 return [
359 $this->getModuleId(),
360 $this->getEntity(),
361 $this->getDocumentType(),
362 ];
363 }
364
365 public function getFixedDocument(): ?\Bitrix\Bizproc\Debugger\Session\Document
366 {
367 if ($this->isFixed())
368 {
369 $document = $this->getDocuments()->getAll()[0];
370 if ($document)
371 {
372 $document->setSession($this);
373 }
374
375 return $document;
376 }
377
378 return null;
379 }
380
381 public function isStartedByUser(int $userId): bool
382 {
383 return $userId === $this->getStartedBy();
384 }
385
386 public function isStartedInDocumentType(array $parameterDocumentType): bool
387 {
388 [$moduleId, $entity, $documentType] = \CBPHelper::ParseDocumentId($parameterDocumentType);
389
390 return (
391 $moduleId === $this->getModuleId()
392 && $entity === $this->getEntity()
393 && $documentType === $this->getDocumentType()
394 );
395 }
396
397 public function isFixedDocument(array $parameterDocumentId): bool
398 {
399 $documents = $this->getDocuments();
400 if (!$documents)
401 {
402 return false;
403 }
404
405 foreach ($documents as $document)
406 {
407 $document->setSession($this);
408 if ($parameterDocumentId === $document->getParameterDocumentId())
409 {
410 return true;
411 }
412 }
413
414 return false;
415 }
416
417 public function isSessionDocument(array $parameterDocumentId): bool
418 {
419 return $this->isFixedDocument($parameterDocumentId);
420 }
421
422 public function getShortDescription(): ?string
423 {
424 return \Bitrix\Main\Localization\Loc::getMessage(
425 'BIZPROC_DEBUGGER_SESSION_SESSION_SHORT_DESCRIPTION',
426 [
427 '#USER#' => $this->getStartedByPrintable(),
428 '#ENTITY#' => $this->getDocumentTypeCaption(),
429 ]
430 );
431 }
432
433 public function getDescription(): ?string
434 {
435 return \Bitrix\Main\Localization\Loc::getMessage(
436 'BIZPROC_DEBUGGER_SESSION_SESSION_DESCRIPTION',
437 [
438 '#USER#' => $this->getStartedByPrintable(),
439 '#ENTITY#' => $this->getDocumentTypeCaption(),
440 '#DATE#' => $this->getStartedDate()->toUserTime(),
441 ]
442 );
443 }
444
449 public function isExperimentalMode(): bool
450 {
451 return ($this->getMode() === Mode::EXPERIMENTAL);
452 }
453
458 public function isInterceptionMode(): bool
459 {
460 return ($this->getMode() === Mode::INTERCEPTION);
461 }
462
467 public function canAddDocument(): bool
468 {
469 return !$this->isFixed();
470 }
471
475 public function isBeforeDebuggerStartState(): bool
476 {
477 return $this->isInterceptionMode() && $this->canAddDocument();
478 }
479
480 private function getStartedByPrintable(): string
481 {
482 $format = \CSite::GetNameFormat(false);
483 $user = \CUser::GetList(
484 'id',
485 'asc',
486 ['ID' => $this->getStartedBy()],
487 [
488 'FIELDS' => [
489 'TITLE',
490 'NAME',
491 'LAST_NAME',
492 'SECOND_NAME',
493 'NAME_SHORT',
494 'LAST_NAME_SHORT',
495 'SECOND_NAME_SHORT',
496 'EMAIL',
497 'ID'
498 ],
499 ]
500 )->Fetch();
501
502 return $user ? \CUser::FormatName($format, $user, true, false) : '';
503 }
504
505 private function getDocumentTypeCaption()
506 {
507 $runtime = \CBPRuntime::GetRuntime();
508 $runtime->StartRuntime();
509 $documentService = $runtime->GetService('DocumentService');
510
511 return $documentService->getDocumentTypeCaption($this->getParameterDocumentType());
512 }
513
514 public function toArray(): array
515 {
516 $documents = [];
517
518 $this->fillDocuments();
519 $sessionDocuments = $this->getDocuments() ?? [];
520 foreach ($sessionDocuments as $document)
521 {
522 $document->setSession($this);
523 $documents[] = $document->toArray();
524 }
525
526 return [
527 'Id' => $this->getId(),
528 'Mode' => $this->getMode(),
529 'StartedBy' => $this->getStartedBy(),
530 'Active' => $this->getActive(),
531 'Fixed' => $this->getFixed(),
532 'Documents' => $documents,
533 'ShortDescription' => $this->getShortDescription(),
534 'CategoryId' => $this->getDocumentCategoryId(),
535 ];
536 }
537
541 public function getLogs(): array
542 {
543 $workflowIds = [];
544 foreach ($this->getWorkflowContexts() as $context)
545 {
546 $workflowIds[] = $context->getWorkflowId();
547 }
548
550 'filter' => [
551 '@WORKFLOW_ID' => $workflowIds,
552 ],
553 'order' => ['ID'],
554 ])->fetchCollection()->getAll();
555 }
556
557 public function getRobots(): array
558 {
559 $workflowRobots = [];
560 $this->getWorkflowContexts()->fillTemplateShards();
561 foreach ($this->getWorkflowContexts() as $context)
562 {
563 $workflowId = $context->getWorkflowId();
564 $templateShards = $context->getTemplateShards();
565
566 $workflowRobots[$workflowId] = $templateShards ? $templateShards->getRobotData() : [];
567 }
568
569 return $workflowRobots;
570 }
571
572 private static function getErrorByCode(string $code): ?\Bitrix\Main\Error
573 {
574 if ($code === static::ERROR_DOCUMENT_ID_ALREADY_FIXED)
575 {
576 return new \Bitrix\Main\Error(
577 Loc::getMessage('BIZPROC_DEBUGGER_SESSION_ERROR_DOCUMENT_ID_ALREADY_FIXED'),
578 self::ERROR_DOCUMENT_ID_ALREADY_FIXED
579 );
580 }
581
582 if ($code === static::ERROR_UNKNOWN_DOCUMENT_ID)
583 {
584 return new \Bitrix\Main\Error(
585 Loc::getMessage('BIZPROC_DEBUGGER_SESSION_ERROR_UNKNOWN_DOCUMENT_ID_1'),
586 self::ERROR_UNKNOWN_DOCUMENT_ID
587 );
588 }
589
590 return null;
591 }
592}
addWorkflowContext(string $workflowId, $template)
Definition Session.php:230
isFixedDocument(array $parameterDocumentId)
Definition Session.php:397
isStartedInDocumentType(array $parameterDocumentType)
Definition Session.php:386
isSessionDocument(array $parameterDocumentId)
Definition Session.php:417
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getList(array $parameters=array())
static createObject($setDefaultValues=true)