1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
runtime.php
См. документацию.
1<?php
2
8
22{
27
28 public const REST_ACTIVITY_PREFIX = 'rest_';
29
30 public const ACTIVITY_API_VERSION = 1;
31
32 private $isStarted = false;
34 private static $instance;
35 private static $featuresCache = [];
36
37 private $services = [];
38 private $debugServices = [];
39 private $workflows = [];
40
41 private $loadedActivities = [];
42
43 private $activityFolders = [];
44 private $workflowChains = [];
45
46 /********************* SINGLETON PATTERN **************************************************/
47
52 private function __construct()
53 {
54 $this->workflows = array();
55 $this->services = array(
56 "SchedulerService" => null,
57 "StateService" => null,
58 "TrackingService" => null,
59 "TaskService" => null,
60 "HistoryService" => null,
61 "DocumentService" => null,
62 "AnalyticsService" => null,
63 "UserService" => null,
64 );
65 $this->loadedActivities = array();
66 $this->activityFolders = array(
67 $_SERVER["DOCUMENT_ROOT"]."/local/activities",
68 $_SERVER["DOCUMENT_ROOT"]."/local/activities/custom",
69 $_SERVER["DOCUMENT_ROOT"].BX_ROOT."/activities/custom",
70 $_SERVER["DOCUMENT_ROOT"].BX_ROOT."/activities/bitrix",
71 $_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/bizproc/activities",
72 );
73 }
74
80 public static function getRuntime()
81 {
82 if (!isset(self::$instance))
83 {
84 $c = __CLASS__;
85 self::$instance = new $c;
86 self::$instance->startRuntime();
87 }
88
89 return self::$instance;
90 }
91
92 public function __clone()
93 {
94 trigger_error('Clone in not allowed.', E_USER_ERROR);
95 }
96
97 public function __call($name, $arguments)
98 {
99 if (preg_match('|^get([a-z]+)service$|i', $name, $matches))
100 {
101 return $this->GetService($matches[1]. 'Service');
102 }
103
104 throw new Main\SystemException("Unknown method `{$name}`");
105 }
106
112 public static function isFeatureEnabled($featureName = '')
113 {
114 $featureName = (string)$featureName;
115 if ($featureName === '')
116 {
117 $featureName = 'bizproc';
118 }
119
120 if (!isset(static::$featuresCache[$featureName]))
121 {
122 static::$featuresCache[$featureName] = (
123 !Main\Loader::includeModule('bitrix24')
124 || \Bitrix\Bitrix24\Feature::isFeatureEnabled($featureName)
125 );
126 }
127
128 return static::$featuresCache[$featureName];
129 }
130
131 /********************* START / STOP RUNTIME **************************************************/
132
137 public function startRuntime()
138 {
139 if ($this->isStarted)
140 {
141 return;
142 }
143
144 $serviceManager = Bizproc\Service\Manager::getInstance();
145 foreach ($serviceManager->getAllServiceNames() as $serviceName)
146 {
147 $compatibleServiceName = mb_strtoupper($serviceName[0]) . mb_substr($serviceName, 1);
148 if (!$this->services[$compatibleServiceName])
149 {
150 $this->services[$compatibleServiceName] = $serviceManager->getService($serviceName);
151 }
152 if (!isset($this->debugServices[$compatibleServiceName]) && $serviceManager->hasDebugService($serviceName))
153 {
154 $this->debugServices[$compatibleServiceName] = $serviceManager->getDebugService($serviceName);
155 }
156
157 $this->services[$compatibleServiceName]->start($this);
158 }
159
160 $this->isStarted = true;
161 }
162
167 public function stopRuntime()
168 {
169 if (!$this->isStarted)
170 {
171 return;
172 }
173
174 foreach ($this->services as $serviceId => $service)
175 {
176 $service->stop();
177 }
178
179 $this->isStarted = false;
180 }
181
182 /******************* PROCESS WORKFLOWS *********************************************************/
183
197 public function createWorkflow($workflowTemplateId, $documentId, $workflowParameters = array(), $parentWorkflow = null)
198 {
199 $workflowTemplateId = intval($workflowTemplateId);
200 if ($workflowTemplateId <= 0)
201 {
202 throw new Exception("workflowTemplateId");
203 }
204
205 $arDocumentId = CBPHelper::ParseDocumentId($documentId);
206
207 $limit = \Bitrix\Main\Config\Option::get("bizproc", "limit_simultaneous_processes", "0");
208 $ignoreLimits = !empty($workflowParameters[CBPDocument::PARAM_IGNORE_SIMULTANEOUS_PROCESSES_LIMIT]);
209 if (!$ignoreLimits && intval($limit) > 0)
210 {
211 if (CBPStateService::CountDocumentWorkflows($documentId) >= $limit)
212 {
213 throw new Exception(GetMessage("BPCGDOC_LIMIT_SIMULTANEOUS_PROCESSES", ["#NUM#" => $limit]));
214 }
215 }
216 unset($workflowParameters[CBPDocument::PARAM_IGNORE_SIMULTANEOUS_PROCESSES_LIMIT]);
217
218 if (!$this->isStarted)
219 {
220 $this->StartRuntime();
221 }
222
223 $workflowId = $workflowParameters[CBPDocument::PARAM_PRE_GENERATED_WORKFLOW_ID] ?? static::generateWorkflowId();
224
225 if ($parentWorkflow)
226 {
227 $this->addWorkflowToChain($workflowId, $parentWorkflow);
228 if ($this->checkWorkflowRecursion($workflowId, $workflowTemplateId))
229 {
230 throw new Exception(GetMessage("BPCGDOC_WORKFLOW_RECURSION_LOCK"));
231 }
232 }
233
234 $workflow = new CBPWorkflow($workflowId, $this);
235
237
239 [$rootActivity, $workflowVariablesTypes, $workflowParametersTypes] = $loader->LoadWorkflow($workflowTemplateId);
240 foreach ($workflowParametersTypes as $parameterName => $parametersProperty)
241 {
242 if (!array_key_exists($parameterName, $workflowParameters))
243 {
244 $workflowParameters[$parameterName] = $parametersProperty['Default'] ?? null;
245 }
246 }
247
248 if (!$rootActivity)
249 {
250 throw new Exception("EmptyRootActivity");
251 }
252
253 foreach(GetModuleEvents("bizproc", "OnCreateWorkflow", true) as $arEvent)
254 {
255 ExecuteModuleEventEx($arEvent, [$workflowTemplateId, $documentId, &$workflowParameters, $workflowId]);
256 }
257
258 $workflow->initialize($rootActivity, $arDocumentId, $workflowParameters, $workflowVariablesTypes, $workflowParametersTypes, $workflowTemplateId);
259
260 $starterUserId = 0;
261 if (isset($workflowParameters[CBPDocument::PARAM_TAGRET_USER]))
262 {
263 $starterUserId = (int)CBPHelper::stripUserPrefix($workflowParameters[CBPDocument::PARAM_TAGRET_USER]);
264 }
265
266 $this->getStateService()->addWorkflow($workflowId, $workflowTemplateId, $arDocumentId, $starterUserId);
267
268 $this->workflows[$workflowId] = $workflow;
269
270 return $workflow;
271 }
272
273 public function createDebugWorkflow(int $templateId, array $documentId, $workflowParameters = [])
274 {
275 $complexDocumentId = CBPHelper::ParseDocumentId($documentId);
276
277 $workflowId = $workflowParameters[CBPDocument::PARAM_PRE_GENERATED_WORKFLOW_ID] ?? static::generateWorkflowId();
278 $workflow = new DebugWorkflow($workflowId, $this);
279
280 $loader = CBPWorkflowTemplateLoader::GetLoader();
281
282 [$rootActivity, $workflowVariablesTypes, $workflowParametersTypes] = $loader->LoadWorkflow($templateId);
283
284 if (is_null($rootActivity))
285 {
286 throw new Exception('Empty root activity');
287 }
288
289 foreach(GetModuleEvents("bizproc", "OnCreateWorkflow", true) as $arEvent)
290 {
291 ExecuteModuleEventEx($arEvent, [$templateId, $documentId, &$workflowParameters, $workflowId]);
292 }
293
294 $workflow->Initialize(
295 $rootActivity,
296 $complexDocumentId,
297 $workflowParameters,
298 $workflowVariablesTypes,
299 $workflowParametersTypes,
301 );
302
303 $starterUserId = 0;
304 if (isset($workflowParameters[CBPDocument::PARAM_TAGRET_USER]))
305 {
306 $starterUserId = intval(mb_substr($workflowParameters[CBPDocument::PARAM_TAGRET_USER], mb_strlen("user_")));
307 }
308
309 $this
310 ->GetService("StateService")
311 ->AddWorkflow($workflowId, $templateId, $complexDocumentId, $starterUserId)
312 ;
313
314 $this->workflows[$workflowId] = $workflow;
315
316 return $workflow;
317 }
318
327 public function getWorkflow($workflowId, $silent = false)
328 {
329 if ($workflowId == '')
330 throw new Exception("workflowId");
331
332 if (!$this->isStarted)
333 $this->StartRuntime();
334
335 if (array_key_exists($workflowId, $this->workflows))
336 return $this->workflows[$workflowId];
337
338 $workflow = $this->getWorkflowInstance($workflowId);
339 $rootActivity = $workflow->getPersister()->LoadWorkflow($workflowId, $silent);
340
341 if ($rootActivity == null)
342 {
343 throw new Exception("Empty root activity");
344 }
345
346 $workflow->reload($rootActivity);
347
348 $this->workflows[$workflowId] = $workflow;
349 return $workflow;
350 }
351
352 public function hasWorkflow(string $workflowId): bool
353 {
354 if (!$workflowId)
355 {
356 return false;
357 }
358
359 return array_key_exists($workflowId, $this->workflows);
360 }
361
362 public function getWorkflows(): array
363 {
364 return $this->workflows;
365 }
366
367 protected function getWorkflowInstance(string $workflowId): CBPWorkflow
368 {
369 if (WorkflowInstanceTable::isDebugWorkflow($workflowId))
370 {
371 return new DebugWorkflow($workflowId, $this);
372 }
373
374 return new CBPWorkflow($workflowId, $this);
375 }
376
377 public function onWorkflowStatusChanged($workflowId, $status)
378 {
379 if (
383 )
384 {
385 unset($this->workflows[$workflowId]);
386 }
387 }
388
389 public function onDocumentDelete(array $documentId): void
390 {
392 foreach ($this->workflows as $workflow)
393 {
394 if (CBPHelper::isEqualDocument($documentId, $workflow->getDocumentId()))
395 {
396 $workflow->abandon();
397 }
398 }
399 }
400
401 public static function generateWorkflowId(): string
402 {
403 return uniqid("", true);
404 }
405
406 /******************* SERVICES *********************************************************/
407
414 public function getService($name)
415 {
416 if (array_key_exists($name, $this->services))
417 {
418 return $this->services[$name];
419 }
420
421 return null;
422 }
423
424 public function getDebugService($name)
425 {
426 if (array_key_exists($name, $this->debugServices))
427 {
428 return $this->debugServices[$name];
429 }
430
431 return null;
432 }
433
441 {
442 if ($this->isStarted)
443 throw new Exception("Runtime is started");
444
445 $name = trim($name);
446 if ($name == '')
447 throw new Exception("Service code is empty");
448 if (!$service)
449 throw new Exception("Service is null");
450
451 if (array_key_exists($name, $this->services))
452 throw new Exception("Service is already exists");
453
454 $this->services[$name] = $service;
455 }
456
457 /******************* EVENTS ******************************************************************/
458
466 public static function sendExternalEvent($workflowId, $eventName, $arEventParameters = [])
467 {
468 $runtime = CBPRuntime::GetRuntime();
469 $workflow = $runtime->getWorkflow($workflowId);
470 if ($workflow)
471 {
472 //check if state exists
473 $stateExists = CBPStateService::exists($workflowId);
474 $documentExists = false;
475
476 if ($stateExists)
477 {
478 $documentService = $runtime->getDocumentService();
479 $documentExists = $documentService->isDocumentExists($workflow->getDocumentId());
480 }
481
482 if (!$stateExists || !$documentExists)
483 {
484 $workflow->terminate();
485
486 return false;
487 }
488
489 $workflow->sendExternalEvent($eventName, (array)$arEventParameters);
490 }
491 }
492
493 /******************* UTILITIES ***************************************************************/
494
500 public function includeActivityFile($code)
501 {
502 if (in_array($code, $this->loadedActivities))
503 return true;
504
505 if (preg_match("#[^a-zA-Z0-9_]#", $code))
506 return false;
507 if ($code == '')
508 return false;
509
510 $code = mb_strtolower($code);
511 if (mb_substr($code, 0, 3) == "cbp")
512 $code = mb_substr($code, 3);
513 if ($code == '')
514 return false;
515 if (in_array($code, $this->loadedActivities))
516 return true;
517
518 $filePath = "";
519 $fileDir = "";
520 foreach ($this->activityFolders as $folder)
521 {
522 if (file_exists($folder."/".$code."/".$code.".php") && is_file($folder."/".$code."/".$code.".php"))
523 {
524 $filePath = $folder."/".$code."/".$code.".php";
525 $fileDir = $folder."/".$code;
526 break;
527 }
528 }
529
530 if ($filePath <> '')
531 {
532 $this->LoadActivityLocalization($fileDir, $code.".php");
533 include_once($filePath);
534 $this->loadedActivities[] = $code;
535 return true;
536 }
537
538 if (mb_strpos($code, static::REST_ACTIVITY_PREFIX) === 0)
539 {
540 $code = mb_substr($code, mb_strlen(static::REST_ACTIVITY_PREFIX));
541 $result = RestActivityTable::getList(array(
542 'select' => array('ID'),
543 'filter' => array('=INTERNAL_CODE' => $code),
544 ));
545 $activity = $result->fetch();
546 eval('class CBP'.static::REST_ACTIVITY_PREFIX.$code.' extends CBPRestActivity {const REST_ACTIVITY_ID = '.($activity? $activity['ID'] : 0).';}');
547 $this->loadedActivities[] = static::REST_ACTIVITY_PREFIX.$code;
548 return true;
549 }
550
551 return false;
552 }
553
554 public function getActivityDescription($code, $lang = false)
555 {
556 if (preg_match("#[^a-zA-Z0-9_]#", $code))
557 return null;
558 if ($code == '')
559 return null;
560
561 $code = mb_strtolower($code);
562 if (mb_substr($code, 0, 3) == "cbp")
563 $code = mb_substr($code, 3);
564 if ($code == '')
565 return null;
566
567 $filePath = "";
568 $fileDir = "";
569 foreach ($this->activityFolders as $folder)
570 {
571 if (file_exists($folder."/".$code."/".$code.".php") && is_file($folder."/".$code."/".$code.".php"))
572 {
573 $filePath = $folder."/".$code."/.description.php";
574 $fileDir = $folder."/".$code;
575 break;
576 }
577 }
578
579 if ($filePath <> '')
580 {
581 $arActivityDescription = array();
582 if (file_exists($filePath) && is_file($filePath))
583 {
584 $this->LoadActivityLocalization($fileDir, ".description.php");
585 include($filePath);
586 }
587 $arActivityDescription["PATH_TO_ACTIVITY"] = $fileDir;
588
589 return $arActivityDescription;
590 }
591
592 if (mb_strpos($code, static::REST_ACTIVITY_PREFIX) === 0)
593 {
594 $code = mb_substr($code, mb_strlen(static::REST_ACTIVITY_PREFIX));
595 $result = RestActivityTable::getList(array(
596 'filter' => array('=INTERNAL_CODE' => $code),
597 ));
598 $activity = $result->fetch();
599 if ($activity)
600 {
601 return $this->makeRestActivityDescription($activity, $lang);
602 }
603 }
604
605 return null;
606 }
607
608 public function getActivityReturnProperties($code, $lang = false): array
609 {
610 $activity = null;
611 if (is_array($code))
612 {
614 $code = $activity['Type'];
615 }
616
617 $description = $this->GetActivityDescription($code, $lang);
618 $props = [];
619 if (isset($description['RETURN']) && is_array($description['RETURN']))
620 {
621 foreach ($description['RETURN'] as $id => $prop)
622 {
624 }
625 }
626 if (isset($description['ADDITIONAL_RESULT']) && is_array($description['ADDITIONAL_RESULT']))
627 {
628 foreach($description['ADDITIONAL_RESULT'] as $propertyKey)
629 {
630 if (isset($activity['Properties'][$propertyKey]) && is_array($activity['Properties'][$propertyKey]))
631 {
632 foreach ($activity['Properties'][$propertyKey] as $id => $prop)
633 {
635 }
636 }
637 }
638 }
639 return $props;
640 }
641
642 private function loadActivityLocalization($path, $file, $lang = false)
643 {
645 }
646
647 public function getResourceFilePath($activityPath, $filePath)
648 {
649 $path = str_replace("\\", "/", $activityPath);
650 $path = mb_substr($path, 0, mb_strrpos($path, "/") + 1);
651
652 $filePath = str_replace("\\", "/", $filePath);
653 $filePath = ltrim($filePath, "/");
654
655 if (file_exists($path.$filePath) && is_file($path.$filePath))
656 return array($path.$filePath, $path);
657 else
658 return null;
659 }
660
661 public function executeResourceFile($activityPath, $filePath, $arParameters = array())
662 {
663 $result = null;
664 $path = $this->GetResourceFilePath($activityPath, $filePath);
665 if ($path != null)
666 {
667 ob_start();
668
669 foreach ($arParameters as $key => $value)
670 ${$key} = $value;
671
672 $this->LoadActivityLocalization($path[1], $filePath);
673 include($path[0]);
674 $result = ob_get_contents();
675 ob_end_clean();
676 }
677 return $result;
678 }
679
680 public function searchActivitiesByType($type, array $documentType = null)
681 {
682 $type = mb_strtolower(trim($type));
683 if ($type === '')
684 {
685 return false;
686 }
687
688 $arProcessedDirs = [];
689 foreach ($this->activityFolders as $folder)
690 {
691 if (is_dir($folder) && $handle = opendir($folder))
692 {
693 while (false !== ($dir = readdir($handle)))
694 {
695 if ($dir === "." || $dir === "..")
696 {
697 continue;
698 }
699 if (!is_dir($folder."/".$dir))
700 {
701 continue;
702 }
703 $dirKey = mb_strtolower($dir);
704 if (array_key_exists($dirKey, $arProcessedDirs))
705 {
706 continue;
707 }
708 if (!file_exists($folder."/".$dir."/.description.php"))
709 {
710 continue;
711 }
712
713 $arActivityDescription = [];
714 $this->LoadActivityLocalization($folder."/".$dir, ".description.php");
715 include($folder."/".$dir."/.description.php");
716
717 //Support multiple types
718 $activityType = (array)$arActivityDescription['TYPE'];
719 foreach ($activityType as $i => $aType)
720 {
721 $activityType[$i] = mb_strtolower(trim($aType));
722 }
723
724 if (in_array($type, $activityType, true))
725 {
726 $arProcessedDirs[$dirKey] = $arActivityDescription;
727 $arProcessedDirs[$dirKey]["PATH_TO_ACTIVITY"] = $folder."/".$dir;
728 if (
729 isset($arActivityDescription['FILTER']) && is_array($arActivityDescription['FILTER'])
730 && !$this->checkActivityFilter($arActivityDescription['FILTER'], $documentType)
731 )
732 {
733 $arProcessedDirs[$dirKey]['EXCLUDED'] = true;
734 }
735 }
736
737 }
738 closedir($handle);
739 }
740 }
741
742 if ($type == 'activity')
743 {
744 $arProcessedDirs = array_merge($arProcessedDirs, $this->getRestActivities(false, $documentType));
745 }
746
747 if ($type == 'activity' || $type == 'robot_activity')
748 {
749 $arProcessedDirs = array_merge($arProcessedDirs, $this->getRestRobots(false, $documentType));
750 }
751
752 if ($type !== 'condition')
753 {
754 \Bitrix\Main\Type\Collection::sortByColumn($arProcessedDirs, ['SORT' => SORT_ASC, 'NAME' => SORT_ASC]);
755 }
756
757 return $arProcessedDirs;
758 }
759
766 public function getRestActivities($lang = false, $documentType = null)
767 {
768 $result = array();
769 $iterator = RestActivityTable::getList(array(
770 'filter' => array('=IS_ROBOT' => 'N'),
771 ));
772
773 while ($activity = $iterator->fetch())
774 {
775 $result[static::REST_ACTIVITY_PREFIX.$activity['INTERNAL_CODE']] = $this->makeRestActivityDescription($activity, $lang, $documentType);
776 }
777
778 return $result;
779 }
780
787 public function getRestRobots($lang = false, $documentType = null)
788 {
789 $result = array();
790 $iterator = RestActivityTable::getList([
791 'filter' => ['=IS_ROBOT' => 'Y'],
792 'cache' => ['ttl' => 3600],
793 ]);
794
795 while ($activity = $iterator->fetch())
796 {
797 $result[static::REST_ACTIVITY_PREFIX.$activity['INTERNAL_CODE']] = $this->makeRestRobotDescription($activity, $lang, $documentType);
798 }
799
800 return $result;
801 }
802
803 public function unserializeWorkflowStream(string $stream)
804 {
805 $pos = mb_strpos($stream, ";");
806 $usedActivities = mb_substr($stream, 0, $pos);
807 $stream = mb_substr($stream, $pos + 1);
808
809 foreach (explode(',', $usedActivities) as $activityCode)
810 {
811 $this->IncludeActivityFile($activityCode);
812 }
813
814 $classesList = array_map(
815 function ($name)
816 {
817 return 'cbp'.$name;
818 },
819 $this->loadedActivities
820 );
821
823 if (in_array('cbpstateactivity', $classesList))
824 {
825 $classesList[] = CBPStateEventActivitySubscriber::class;
826 }
827 if (in_array('cbplistenactivity', $classesList))
828 {
829 $classesList[] = CBPListenEventActivitySubscriber::class;
830 }
831
832 $classesList[] = \CBPWorkflow::class;
833 $classesList[] = \CBPRuntime::class;
834 $classesList[] = DebugWorkflow::class;
835 $classesList[] = Bizproc\BaseType\Value\Date::class;
836 $classesList[] = Bizproc\BaseType\Value\DateTime::class;
837 $classesList[] = Main\Type\Date::class;
838 $classesList[] = Main\Type\DateTime::class;
839 $classesList[] = Main\Web\Uri::class;
840 $classesList[] = \DateTime::class;
841 $classesList[] = \DateTimeZone::class;
842
843 return unserialize($stream, ['allowed_classes' => $classesList]);
844 }
845
846 private function makeRestActivityDescription($activity, $lang = false, $documentType = null)
847 {
848 if ($lang === false)
849 $lang = LANGUAGE_ID;
850
851 $code = static::REST_ACTIVITY_PREFIX.$activity['INTERNAL_CODE'];
852 $result = array(
853 'NAME' => '['.RestActivityTable::getLocalization($activity['APP_NAME'], $lang).'] '
854 .RestActivityTable::getLocalization($activity['NAME'], $lang),
855 'DESCRIPTION' => RestActivityTable::getLocalization($activity['DESCRIPTION'], $lang),
856 'TYPE' => 'activity',
857 'CLASS' => $code,
858 'JSCLASS' => 'BizProcActivity',
859 'CATEGORY' => array(
860 'ID' => 'rest',
861 ),
862 'RETURN' => array(),
863 //compatibility
864 'PATH_TO_ACTIVITY' => '',
865 );
866
867 if (
868 isset($activity['FILTER']) && is_array($activity['FILTER'])
869 && !$this->checkActivityFilter($activity['FILTER'], $documentType)
870 )
871 $result['EXCLUDED'] = true;
872
873 if (!empty($activity['RETURN_PROPERTIES']))
874 {
875 foreach ($activity['RETURN_PROPERTIES'] as $name => $property)
876 {
877 $result['RETURN'][$name] = array(
878 'NAME' => RestActivityTable::getLocalization($property['NAME'], $lang),
879 'TYPE' => isset($property['TYPE']) ? $property['TYPE'] : \Bitrix\Bizproc\FieldType::STRING,
880 );
881 }
882 }
883 if ($activity['USE_SUBSCRIPTION'] != 'N')
884 $result['RETURN']['IsTimeout'] = array(
885 'NAME' => GetMessage('BPRA_IS_TIMEOUT'),
886 'TYPE' => \Bitrix\Bizproc\FieldType::INT,
887 );
888
889 return $result;
890 }
891
892 private function makeRestRobotDescription($activity, $lang = false, $documentType = null)
893 {
894 if ($lang === false)
895 $lang = LANGUAGE_ID;
896
897 $code = static::REST_ACTIVITY_PREFIX.$activity['INTERNAL_CODE'];
898 $result = array(
899 'NAME' => '['.RestActivityTable::getLocalization($activity['APP_NAME'], $lang).'] '
900 .RestActivityTable::getLocalization($activity['NAME'], $lang),
901 'DESCRIPTION' => RestActivityTable::getLocalization($activity['DESCRIPTION'], $lang),
902 'TYPE' => array('activity', 'robot_activity'),
903 'CLASS' => $code,
904 'JSCLASS' => 'BizProcActivity',
905 'CATEGORY' => [
906 'ID' => 'rest',
907 ],
908 'RETURN' => array(),
909 //compatibility
910 'PATH_TO_ACTIVITY' => '',
911 'ROBOT_SETTINGS' => array(
912 'CATEGORY' => 'other',
913 ),
914 );
915
916 if (
917 isset($activity['FILTER']) && is_array($activity['FILTER'])
918 && !$this->checkActivityFilter($activity['FILTER'], $documentType)
919 )
920 $result['EXCLUDED'] = true;
921
922 if (!empty($activity['RETURN_PROPERTIES']))
923 {
924 foreach ($activity['RETURN_PROPERTIES'] as $name => $property)
925 {
926 $result['RETURN'][$name] = [
927 'NAME' => RestActivityTable::getLocalization($property['NAME'], $lang),
928 'TYPE' => $property['TYPE'] ?? \Bitrix\Bizproc\FieldType::STRING,
929 'OPTIONS' => $property['OPTIONS'] ?? null,
930 ];
931 }
932 }
933 if ($activity['USE_SUBSCRIPTION'] !== 'N')
934 {
935 $result['RETURN']['IsTimeout'] = array(
936 'NAME' => GetMessage('BPRA_IS_TIMEOUT'),
937 'TYPE' => \Bitrix\Bizproc\FieldType::INT,
938 );
939 }
940
941 return $result;
942 }
943
944 public function checkActivityFilter($filter, $documentType)
945 {
946 $distrName = CBPHelper::getDistrName();
947 foreach ($filter as $type => $rules)
948 {
949 if ($type === 'MIN_API_VERSION')
950 {
951 $minApiVersion = (int)$rules;
952 if ($minApiVersion > self::ACTIVITY_API_VERSION)
953 {
954 return false;
955 }
956
957 continue;
958 }
959
960 $found = $this->checkActivityFilterRules($rules, $documentType, $distrName);
961 if (($type === 'INCLUDE' && !$found) || ($type === 'EXCLUDE' && $found))
962 {
963 return false;
964 }
965 }
966
967 return true;
968 }
969
970 private function checkActivityFilterRules($rules, $documentType, $distrName)
971 {
972 if (!is_array($rules) || CBPHelper::IsAssociativeArray($rules))
973 {
974 $rules = [$rules];
975 }
976
977 foreach ($rules as $rule)
978 {
979 $result = false;
980 if (is_array($rule))
981 {
982 if (!$documentType)
983 {
984 $result = true;
985 }
986 else
987 {
988 foreach ($documentType as $key => $value)
989 {
990 if (!isset($rule[$key]))
991 {
992 break;
993 }
994 $result = $rule[$key] == $value;
995 if (!$result)
996 {
997 break;
998 }
999 }
1000 }
1001 }
1002 else
1003 {
1004 $result = (string)$rule == $distrName;
1005 }
1006 if ($result)
1007 {
1008 return true;
1009 }
1010 }
1011
1012 return false;
1013 }
1014
1015 private function addWorkflowToChain($childId, $parent)
1016 {
1017 $this->workflowChains[$childId] = $parent;
1018 return $this;
1019 }
1020
1021 private function checkWorkflowRecursion($workflowId, $currentTemplateId)
1022 {
1023 $templates = array($currentTemplateId);
1024 while (isset($this->workflowChains[$workflowId]))
1025 {
1026 $parent = $this->workflowChains[$workflowId];
1027 if (in_array($parent['templateId'], $templates))
1028 return true;
1029 $templates[] = $parent['templateId'];
1030 $workflowId = $parent['workflowId'];
1031 }
1032 return false;
1033 }
1034}
$path
Определения access_edit.php:21
$type
Определения options.php:106
const BX_ROOT
Определения bx_root.php:3
static normalizeProperty($property)
Определения fieldtype.php:548
static getInstance()
Определения manager.php:26
static includeModule($moduleName)
Определения loader.php:67
static loadLanguageFile($file, $language=null, $normalize=true)
Определения loc.php:225
static sortByColumn(array &$array, $columns, $callbacks='', $defaultValueIfNotSetValue=null, $preserveKeys=false)
Определения collection.php:24
const PARAM_PRE_GENERATED_WORKFLOW_ID
Определения document.php:21
Определения runtime.php:22
stopRuntime()
Определения runtime.php:167
addService($name, CBPRuntimeService $service)
Определения runtime.php:440
includeActivityFile($code)
Определения runtime.php:500
const EXCEPTION_CODE_INSTANCE_LOCKED
Определения runtime.php:25
const ACTIVITY_API_VERSION
Определения runtime.php:30
static sendExternalEvent($workflowId, $eventName, $arEventParameters=[])
Определения runtime.php:466
getService($name)
Определения runtime.php:414
createDebugWorkflow(int $templateId, array $documentId, $workflowParameters=[])
Определения runtime.php:273
__call($name, $arguments)
Определения runtime.php:97
static getRuntime()
Определения runtime.php:80
const REST_ACTIVITY_PREFIX
Определения runtime.php:28
static isFeatureEnabled($featureName='')
Определения runtime.php:112
getActivityReturnProperties($code, $lang=false)
Определения runtime.php:608
const EXCEPTION_CODE_INSTANCE_TARIFF_LIMIT_EXCEED
Определения runtime.php:23
getResourceFilePath($activityPath, $filePath)
Определения runtime.php:647
getRestActivities($lang=false, $documentType=null)
Определения runtime.php:766
startRuntime()
Определения runtime.php:137
onWorkflowStatusChanged($workflowId, $status)
Определения runtime.php:377
hasWorkflow(string $workflowId)
Определения runtime.php:352
getDebugService($name)
Определения runtime.php:424
getRestRobots($lang=false, $documentType=null)
Определения runtime.php:787
getWorkflows()
Определения runtime.php:362
getWorkflow($workflowId, $silent=false)
Определения runtime.php:327
checkActivityFilter($filter, $documentType)
Определения runtime.php:944
searchActivitiesByType($type, array $documentType=null)
Определения runtime.php:680
getActivityDescription($code, $lang=false)
Определения runtime.php:554
getWorkflowInstance(string $workflowId)
Определения runtime.php:367
__clone()
Определения runtime.php:92
static generateWorkflowId()
Определения runtime.php:401
const EXCEPTION_CODE_INSTANCE_NOT_FOUND
Определения runtime.php:24
unserializeWorkflowStream(string $stream)
Определения runtime.php:803
executeResourceFile($activityPath, $filePath, $arParameters=array())
Определения runtime.php:661
const EXCEPTION_CODE_INSTANCE_TERMINATED
Определения runtime.php:26
static exists(string $workflowId)
Определения stateservice.php:399
Определения workflow.php:9
const Suspended
Определения constants.php:84
const Completed
Определения constants.php:83
const Terminated
Определения constants.php:85
$templateId
Определения component_props2.php:51
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$handle
Определения include.php:55
$result
Определения get_property_values.php:14
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
Определения .description.php:24
$activity
Определения options.php:214
$filter
Определения iblock_catalog_list.php:54
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
if(!defined('SITE_ID')) $lang
Определения include.php:91
$status
Определения session.php:10
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
GetMessage($name, $aReplace=null)
Определения tools.php:3397
$name
Определения menu_edit.php:35
$value
Определения Param.php:39
$service
Определения payment.php:18
$dir
Определения quickway.php:303
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
$props
Определения template.php:269
$matches
Определения index.php:22
$iterator
Определения yandex_run.php:610