13define(
"BP_EI_DIRECTION_EXPORT", 0);
14define(
"BP_EI_DIRECTION_IMPORT", 1);
27 private static $instance;
33 private function __construct()
40 trigger_error(
'Clone in not allowed.', E_USER_ERROR);
50 if (!isset(self::$instance))
53 self::$instance =
new $c;
56 return self::$instance;
62 return $loader->GetTemplatesList($arOrder,
$arFilter, $arGroupBy, $arNavStartParams, $arSelectFields);
69 if (!CBPActivity::IncludeActivityFile(
$activity[
'Type']))
73 $childResult = static::checkTemplateActivities(
$activity[
'Children']);
87 [$arActivity[
'Properties'], $user]
91 if (isset($arActivity[
'Properties'][
'Title']))
94 Loc::getMessage(
'BPWTL_ERROR_MESSAGE_PREFIX', [
'#TITLE#' => $arActivity[
'Properties'][
'Title']])
101 $errors[
$i][
'message'] = $pref . $e[
'message'];
102 $errors[
$i][
'activityName'] = $arActivity[
'Name'];
105 if (array_key_exists(
'Children', $arActivity) &&
count($arActivity[
'Children']) > 0)
109 $childrenErrors = [];
110 foreach ($arActivity[
'Children'] as $arChildActivity)
112 if (!isset($arChildActivity[
'Activated']) || $arChildActivity[
'Activated'] !==
'N')
117 [$arChildActivity[
'Type'], $bFirst]
120 foreach ($childErrors as
$i => $e)
122 $childErrors[
$i][
'message'] = $pref . $e[
'message'];
123 $childErrors[
$i][
'activityName'] = $arActivity[
'Name'];
128 $childrenErrors[] = $childErrors;
135 $childrenErrors[] = $validateErrors;
149 $updateMode = ($id > 0 ? true :
false);
150 $addMode = !$updateMode;
152 if ($addMode && !isset(
$arFields[
"DOCUMENT_TYPE"]))
157 $arDocumentType = CBPHelper::ParseDocumentId(
$arFields[
"DOCUMENT_TYPE"]);
159 $arFields[
"MODULE_ID"] = $arDocumentType[0];
160 $arFields[
"ENTITY"] = $arDocumentType[1];
161 $arFields[
"DOCUMENT_TYPE"] = $arDocumentType[2];
170 if (isset(
$arFields[
"NAME"]) || $addMode)
177 if ($addMode && !isset(
$arFields[
'TEMPLATE']))
182 if (array_key_exists(
'TEMPLATE',
$arFields))
194 if (array_key_exists(
"MODIFIER_USER",
$arFields))
196 if (is_object(
$arFields[
"MODIFIER_USER"]) && is_a(
$arFields[
"MODIFIER_USER"],
"CBPWorkflowTemplateUser"))
207 if ($validationRequired)
209 foreach (
$arFields[
'TEMPLATE'] as $rawTemplate)
211 array_push(
$errors, ...$this->ValidateTemplate($rawTemplate, $userTmp));
228 $enumValues = array_column(WorkflowTemplateType::cases(),
'value');
231 $arFields[
'TYPE'] = WorkflowTemplateType::Default->value;
249 $loader->getTemplateType(
$fields);
250 $loader->setShowInTimelineBeforeAdd(
$fields);
251 $loader->setTemplateType(
$fields);
253 $id = $loader->AddTemplate(
$fields, $systemImport);
254 $loader->addTemplateSettings($id,
$fields);
262 isset($templateFields[
'DOCUMENT_TYPE'])
263 && !empty($templateFields[
'TEMPLATE_SETTINGS'])
267 foreach ($templateFields[
'TEMPLATE_SETTINGS'] as
$option => $value)
276 WorkflowTemplateSettingsTable::addMultiSettings(
$rows);
280 private function deleteTemplateSettings(
int $templateId)
282 WorkflowTemplateSettingsTable::deleteSettingsByFilter([
'=TEMPLATE_ID' =>
$templateId]);
285 public static function update($id,
$fields, $systemImport =
false, $validationRequired =
true)
288 $loader->getTemplateType(
$fields, $id);
289 $loader->setShowInTimelineBeforeUpdate(
$fields);
290 $loader->setTemplateType(
$fields);
292 if (isset(
$fields[
'TEMPLATE']) && !$systemImport)
297 $returnId = $loader->UpdateTemplate($id,
$fields, $systemImport, $validationRequired);
298 $loader->updateTemplateSettings($id,
$fields);
299 self::cleanTemplateCache($returnId);
306 $fields[
'TYPE'] = $this->templateType;
314 private function updateTemplateSettings(
int $templateId,
array $templateFields)
317 isset($templateFields[
'DOCUMENT_TYPE'])
318 && !empty($templateFields[
'TEMPLATE_SETTINGS'])
323 foreach ($templateFields[
'TEMPLATE_SETTINGS'] as
$option => $value)
329 $result = WorkflowTemplateSettingsTable::getList([
331 'select' => [
'ID',
'NAME']
333 while ($row =
$result->fetch())
335 $existSettings[$row[
'NAME']] = $row[
'ID'];
338 foreach ($templateFields[
'TEMPLATE_SETTINGS'] as
$option => $value)
340 if (isset($existSettings[
$option]))
342 WorkflowTemplateSettingsTable::update($existSettings[
$option], [
'VALUE' => $value]);
346 WorkflowTemplateSettingsTable::add([
359 empty(
$fields[
'DOCUMENT_TYPE'])
361 || !array_key_exists(
'AUTO_EXECUTE',
$fields)
367 arFilter: [
'ID' => $id],
368 arSelectFields: [
'DOCUMENT_TYPE',
'TEMPLATE',
'AUTO_EXECUTE']
372 $fields[
'DOCUMENT_TYPE'] = $row[
'DOCUMENT_TYPE'];
373 $fields[
'TEMPLATE'] = $row[
'TEMPLATE'];
374 $fields[
'AUTO_EXECUTE'] = $row[
'AUTO_EXECUTE'];
379 $this->templateType = WorkflowTemplateType::Default->value;
385 $this->templateType = WorkflowTemplateType::Default->value;
386 if ($this->isRobot((
int)
$fields[
'AUTO_EXECUTE']))
388 $this->templateType = WorkflowTemplateType::Robots->value;
389 if ($this->isExternalModified(
$fields))
391 $this->templateType = WorkflowTemplateType::CustomRobots->value;
398 $isCrm = array_key_exists(
'DOCUMENT_TYPE',
$fields) &&
$fields[
'DOCUMENT_TYPE'][0] ===
'crm';
400 $customRobotToRobot =
401 array_key_exists(
'TYPE',
$fields)
402 &&
$fields[
'TYPE'] !== WorkflowTemplateType::Robots->value
403 && $this->templateType === WorkflowTemplateType::Robots->value
406 if ($isCrm && $customRobotToRobot)
408 $fields[
'TEMPLATE_SETTINGS'][
'SHOW_IN_TIMELINE'] =
'N';
412 private function isRobot(
int $autoExecute): bool
419 $isCrm = array_key_exists(
'DOCUMENT_TYPE',
$fields) &&
$fields[
'DOCUMENT_TYPE'][0] ===
'crm';
421 if ($isCrm && empty(
$fields[
'TEMPLATE_SETTINGS'][
'SHOW_IN_TIMELINE']))
423 $fields[
'TEMPLATE_SETTINGS'][
'SHOW_IN_TIMELINE'] =
'N';
429 return WorkflowTemplateTable::toSerializedForm(
$arTemplate);
432 private function getSerializedSettings(
$arTemplate)
434 return WorkflowTemplateTable::encodeJson(
$arTemplate);
437 public static function delete($id)
440 $loader->DeleteTemplate($id);
441 $loader->deleteTemplateSettings($id);
442 self::cleanTemplateCache($id);
450 $cache->clean(self::CONSTANTS_CACHE_TAG_PREFIX . $id);
451 unset(self::$workflowConstants[$id]);
459 throw new Exception(
"id");
462 $hasInstance = (bool)WorkflowInstanceTable::getRow([
464 'filter' => [
'=WORKFLOW_TEMPLATE_ID' => $id],
465 'order' => [
'DOCUMENT_ID' =>
'DESC'],
470 WorkflowTemplateTable::delete($id);
474 'onAfterWorkflowTemplateDelete',
479 EventManager::getInstance()->send(
$event);
481 WorkflowDurationStatTable::deleteAllByTemplateId($id);
492 $workflowTemplateId = intval($workflowTemplateId);
493 if ($workflowTemplateId <= 0)
500 [
'ID' => $workflowTemplateId],
503 [
'TEMPLATE',
'VARIABLES',
'PARAMETERS']
505 $arTemplatesListItem = $dbTemplatesList->Fetch();
507 if (!$arTemplatesListItem)
509 throw new Exception(str_replace(
'#ID#', $workflowTemplateId,
GetMessage(
'BPCGWTL_INVALID_WF_ID')));
512 $arTemplatesListItem[
'ID'] = $workflowTemplateId;
519 $wfId = $templatesListItem[
'ID'];
520 $wfTemplate = $templatesListItem[
'TEMPLATE'];
521 $wfVariablesTypes = $templatesListItem[
'VARIABLES'];
522 $wfParametersTypes = $templatesListItem[
'PARAMETERS'];
524 if (!is_array($wfTemplate) ||
count($wfTemplate) <= 0)
526 throw new Exception(str_replace(
'#ID#', $wfId,
GetMessage(
'BPCGWTL_EMPTY_TEMPLATE')));
530 $rootActivity = $this->parseWorkflowTemplate($wfTemplate, $activityNames);
532 return [$rootActivity, $wfVariablesTypes, $wfParametersTypes];
535 private function parseWorkflowTemplate($arWorkflowTemplate, &$arActivityNames,
CBPActivity $parentActivity =
null)
537 if (!is_array($arWorkflowTemplate))
542 foreach ($arWorkflowTemplate as $activityFormatted)
544 if (in_array($activityFormatted[
'Name'], $arActivityNames))
546 throw new Exception(
'DuplicateActivityName');
549 $arActivityNames[] = $activityFormatted[
'Name'];
550 $activity = $this->createActivity($activityFormatted);
553 throw new Exception(
'Activity is not found.');
556 $activity->initializeFromArray($activityFormatted[
'Properties']);
559 $parentActivity->fixUpParentChildRelationship(
$activity);
562 if (!empty($activityFormatted[
'Children']))
564 $this->parseWorkflowTemplate($activityFormatted[
'Children'], $arActivityNames,
$activity);
571 private function createActivity(
array $activityFormatted): ?CBPActivity
573 $code = $activityFormatted[
'Type'];
574 $name = $activityFormatted[
'Name'];
575 $activated = !isset($activityFormatted[
'Activated']) || $activityFormatted[
'Activated'] ===
'Y';
589 throw new Exception(
'Activity is not found.');
595 if (!is_array($arWorkflowTemplate))
598 if (!is_array($arWorkflowTemplate[0]))
602 foreach ($arWorkflowTemplate[0][
"Children"] as $state)
603 $arStates[$state[
"Name"]] = ($state[
"Properties"][
"Title"] <>
'' ? $state[
"Properties"][
"Title"] : $state[
"Name"]);
608 private static function findSetStateActivities($arWorkflowTemplate)
612 if ($arWorkflowTemplate[
"Type"] ==
"SetStateActivity")
613 $arResult[] = $arWorkflowTemplate[
"Properties"][
"TargetStateName"];
615 if (is_array($arWorkflowTemplate[
"Children"]))
617 foreach ($arWorkflowTemplate[
"Children"] as
$key => $value)
626 if (!is_array($arWorkflowTemplate))
629 if (!is_array($arWorkflowTemplate[0]))
632 $stateName = trim($stateName);
633 if ($stateName ==
'')
636 $arTransfers =
array();
637 foreach ($arWorkflowTemplate[0][
"Children"] as $state)
639 if ($stateName == $state[
"Name"])
641 foreach ($state[
"Children"] as
$event)
642 $arTransfers[
$event[
"Name"]] = self::FindSetStateActivities(
$event);
651 private static function parseDocumentTypeStates($arTemplatesListItem)
653 $arWorkflowTemplate = $arTemplatesListItem[
"TEMPLATE"];
654 if (!is_array($arWorkflowTemplate))
659 "TEMPLATE_ID" => $arTemplatesListItem[
"ID"],
660 "TEMPLATE_NAME" => $arTemplatesListItem[
"NAME"],
661 "TEMPLATE_DESCRIPTION" => $arTemplatesListItem[
"DESCRIPTION"],
664 "TEMPLATE_PARAMETERS" => $arTemplatesListItem[
"PARAMETERS"],
665 "STATE_PARAMETERS" =>
array(),
666 "STATE_PERMISSIONS" =>
array(),
667 "WORKFLOW_STATUS" => -1,
670 $type =
"CBP".$arWorkflowTemplate[0][
"Type"];
672 $type === CBPStateMachineWorkflowActivity::class
675 && is_subclass_of(
$type, CBPStateMachineWorkflowActivity::class)
682 $stateName = $arWorkflowTemplate[0][
"Properties"][
"InitialStateName"];
684 if (is_array($arWorkflowTemplate[0][
"Children"]))
686 foreach ($arWorkflowTemplate[0][
"Children"] as $state)
688 if ($stateName == $state[
"Name"])
690 $result[
"STATE_NAME"] = $stateName;
691 $result[
"STATE_TITLE"] = $state[
"Properties"][
"Title"];
693 $result[
"STATE_PERMISSIONS"] = $state[
"Properties"][
"Permission"];
695 if (is_array($state[
"Children"]))
697 foreach ($state[
"Children"] as
$event)
699 if (
$event[
"Type"] ==
"EventDrivenActivity")
701 if (
$event[
"Children"][0][
"Type"] ==
"HandleExternalEventActivity")
704 "NAME" =>
$event[
"Children"][0][
"Name"],
705 "TITLE" =>
$event[
"Children"][0][
"Properties"][
"Title"],
706 "PERMISSION" =>
$event[
"Children"][0][
"Properties"][
"Permission"],
720 $result[
"STATE_PERMISSIONS"] = $arWorkflowTemplate[0][
"Properties"][
"Permission"] ??
null;
723 if (is_array(
$result[
"STATE_PERMISSIONS"]))
725 $arKeys = array_keys(
$result[
"STATE_PERMISSIONS"]);
726 foreach ($arKeys as
$key)
728 $ar = self::ExtractValuesFromVariables(
$result[
"STATE_PERMISSIONS"][
$key], $arTemplatesListItem[
"VARIABLES"], $arTemplatesListItem[
"CONSTANTS"]);
729 $result[
"STATE_PERMISSIONS"][
$key] = CBPHelper::MakeArrayFlat(
$ar);
736 private static function extractValuesFromVariables(
$ar, $variables, $constants =
array())
739 $ar =
array($arMatches[
'object'], $arMatches[
'field']);
743 if (!CBPHelper::IsAssociativeArray(
$ar))
745 if (
count(
$ar) == 2 && (
$ar[0] ==
'Variable' ||
$ar[0] ==
'Constant' ||
$ar[0] ==
'Template'))
747 if (
$ar[0] ==
'Variable' && is_array($variables) && array_key_exists(
$ar[1], $variables))
748 return array($variables[
$ar[1]][
"Default"]);
749 if (
$ar[0] ==
'Constant' && is_array($constants) && array_key_exists(
$ar[1], $constants))
750 return array($constants[
$ar[1]][
"Default"]);
756 foreach (
$ar as $ar1)
757 $arResult[] = self::ExtractValuesFromVariables($ar1, $variables, $constants);
769 $autoExecute = intval($autoExecute);
771 $cacheKey = implode(
'@', $documentType).
'@'.$autoExecute;
773 if (!isset(static::$typesStates[$cacheKey]))
776 if ($autoExecute >= 0)
777 $arFilter[
"AUTO_EXECUTE"] = $autoExecute;
780 $dbTemplatesList = self::GetList(
785 array(
'ID',
'NAME',
'DESCRIPTION',
'TEMPLATE',
'PARAMETERS',
'VARIABLES',
'CONSTANTS')
787 while ($arTemplatesListItem = $dbTemplatesList->Fetch())
788 $result[$arTemplatesListItem[
"ID"]] = self::ParseDocumentTypeStates($arTemplatesListItem);
790 static::$typesStates[$cacheKey] =
$result;
792 return static::$typesStates[$cacheKey];
797 $workflowTemplateId = intval($workflowTemplateId);
798 if ($workflowTemplateId <= 0)
803 $dbTemplatesList = self::GetList(
805 array(
'ID' => $workflowTemplateId),
808 array(
'ID',
'NAME',
'DESCRIPTION',
'TEMPLATE',
'PARAMETERS',
'VARIABLES',
'CONSTANTS')
810 if ($arTemplatesListItem = $dbTemplatesList->Fetch())
811 $result = self::ParseDocumentTypeStates($arTemplatesListItem);
813 throw new Exception(str_replace(
"#ID#", $workflowTemplateId,
GetMessage(
"BPCGWTL_INVALID_WF_ID")));
821 $dbTemplatesList = self::GetList(
823 [
'ID' => (
int) $workflowTemplateId],
false,
false, [
'USER_ID']
825 if ($row = $dbTemplatesList->Fetch())
827 $userId = (int) $row[
'USER_ID'];
835 $workflowTemplateId = (int) $workflowTemplateId;
836 if ($workflowTemplateId <= 0)
839 if (!isset(self::$workflowConstants[$workflowTemplateId]))
842 $cacheTag = self::CONSTANTS_CACHE_TAG_PREFIX.$workflowTemplateId;
843 if ($cache->read(3600*24*7, $cacheTag))
845 self::$workflowConstants[$workflowTemplateId] = (
array) $cache->get($cacheTag);
851 array(
'ID' => $workflowTemplateId),
858 self::$workflowConstants[$workflowTemplateId] = (
array) $row[
'CONSTANTS'];
859 $cache->set($cacheTag, self::$workflowConstants[$workflowTemplateId]);
862 self::$workflowConstants[$workflowTemplateId] =
array();
867 return self::$workflowConstants[$workflowTemplateId];
878 $constants = self::getTemplateConstants($workflowTemplateId);
879 if (!empty($constants) && is_array($constants))
881 foreach ($constants as
$key => $const)
883 $value = isset($const[
'Default']) ? $const[
'Default'] :
null;
884 if (CBPHelper::getBool($const[
'Required']) && CBPHelper::isEmptyValue($value))
897 $arWorkflowParameters =
array();
899 if (
count($arTemplateParameters) <= 0)
902 $runtime = CBPRuntime::GetRuntime();
903 $runtime->StartRuntime();
904 $documentService = $runtime->GetService(
"DocumentService");
906 foreach ($arTemplateParameters as $parameterKey => $arParameter)
908 $arErrorsTmp =
array();
910 $arWorkflowParameters[$parameterKey] = $documentService->GetFieldInputValue(
918 if (CBPHelper::getBool($arParameter[
'Required']) && CBPHelper::isEmptyValue($arWorkflowParameters[$parameterKey]))
920 $arErrorsTmp[] =
array(
921 "code" =>
"RequiredValue",
922 "message" => str_replace(
"#NAME#", $arParameter[
"Name"],
GetMessage(
"BPCGWTL_INVALID8")),
923 "parameter" => $parameterKey,
927 $arErrors = array_merge($arErrors, $arErrorsTmp);
930 return $arWorkflowParameters;
937 $arFilter = [
'DOCUMENT_TYPE' => $documentType];
938 $autoExecute = intval($autoExecute);
939 if ($autoExecute >= 0)
941 $arFilter[
'AUTO_EXECUTE'] = $autoExecute;
944 $dbTemplatesList = self::GetList(
949 [
'ID',
'NAME',
'DESCRIPTION',
'AUTO_EXECUTE']
951 while ($arTemplatesListItem = $dbTemplatesList->Fetch())
954 'ID' => $arTemplatesListItem[
'ID'],
955 'NAME' => $arTemplatesListItem[
'NAME'],
956 'DESCRIPTION' => $arTemplatesListItem[
'DESCRIPTION'],
957 'AUTO_EXECUTE' => $arTemplatesListItem[
'AUTO_EXECUTE'],
973 foreach ($arWorkflowTemplate as
$key => $value)
975 $valueName = $value[
'Name'] ??
null;
976 if ($valueName == $activityName)
978 return $arWorkflowTemplate[
$key];
981 if (is_array($value[
"Children"] ??
null))
983 if (
$res = &self::FindActivityByName($arWorkflowTemplate[
$key][
"Children"], $activityName))
995 foreach ($arWorkflowTemplate as
$key => $value)
997 if (is_array($value[
"Children"]))
999 for (
$i = 0, $s =
sizeof($value[
'Children']);
$i < $s;
$i++)
1001 if ($value[
"Children"][
$i][
"Name"] == $activityName)
1002 return $arWorkflowTemplate[
$key];
1005 if (
$res = &self::FindParentActivityByName($arWorkflowTemplate[
$key][
"Children"], $activityName))
1014 $tpl = WorkflowTemplateTable::getById($id)->fetchObject();
1020 $packer = new \Bitrix\Bizproc\Workflow\Template\Packer\Bpt();
1023 $packer->disableCompression();
1026 return $packer->pack($tpl)->getPackage();
1029 private static function walkThroughWorkflowTemplate(&$arWorkflowTemplate, $callback, $user)
1031 foreach ($arWorkflowTemplate as
$key => $value)
1033 if (!call_user_func_array($callback,
array($value, $user)))
1036 if (isset($value[
'Children']) && is_array($value[
'Children']))
1039 !self::WalkThroughWorkflowTemplate(
1040 $arWorkflowTemplate[
$key][
'Children'],
1053 private static function importTemplateChecker($arActivity, $user)
1055 $arErrors = CBPActivity::CallStaticMethod($arActivity[
"Type"],
"ValidateProperties",
array($arActivity[
"Properties"], $user));
1056 if (
count($arErrors) > 0)
1059 foreach ($arErrors as $er)
1060 $m .= $er[
"message"].
". ";
1062 throw new Exception($m);
1073 $packer = new \Bitrix\Bizproc\Workflow\Template\Packer\Bpt();
1074 $unpackResult = $packer->unpack($datum);
1076 if (!$unpackResult->isSuccess())
1078 throw new \Bitrix\Main\ArgumentException(reset($unpackResult->getErrorMessages()));
1081 $templateFields = $unpackResult->getTpl()->collectValues();
1082 $templateFields[
'DOCUMENT_FIELDS'] = $unpackResult->getDocumentFields();
1084 return self::importTemplateFromArray($id, $documentType, $autoExecute,
$name,
$description, $templateFields, $systemCode, $systemImport);
1098 elseif ($id > 0 && !empty($templateFields[
"CONSTANTS"]))
1100 $userConstants = self::getTemplateConstants($id);
1101 if (!empty($userConstants))
1103 foreach ($userConstants as $constantName => $constantData)
1105 if (isset($templateFields[
"CONSTANTS"][$constantName]))
1107 $templateFields[
"CONSTANTS"][$constantName][
'Default'] = $constantData[
'Default'];
1113 $templateData =
array(
1114 "DOCUMENT_TYPE" => $documentType,
1115 "AUTO_EXECUTE" => $autoExecute,
1118 "TEMPLATE" => $templateFields[
"TEMPLATE"],
1119 "PARAMETERS" => $templateFields[
"PARAMETERS"],
1120 "VARIABLES" => $templateFields[
"VARIABLES"],
1121 "CONSTANTS" => $templateFields[
"CONSTANTS"],
1122 "USER_ID" => $systemImport ? 1 :
$GLOBALS[
"USER"]->GetID(),
1125 if (!is_null($systemCode))
1126 $templateData[
"SYSTEM_CODE"] = $systemCode;
1128 $templateData[
'ACTIVE'] =
'Y';
1131 self::Update($id, $templateData, $systemImport);
1133 $id = self::Add($templateData, $systemImport);
1135 if ($templateFields[
'DOCUMENT_FIELDS'] && is_array($templateFields[
'DOCUMENT_FIELDS']))
1137 static::importDocumentFields($documentType, $templateFields[
'DOCUMENT_FIELDS']);
1145 $documentService = CBPRuntime::GetRuntime(
true)->getDocumentService();
1146 $currentDocumentFields = $documentService->GetDocumentFields($documentType,
true);
1149 $len = mb_strlen(
"_PRINTABLE");
1154 if (mb_strtoupper(mb_substr(
$code, -$len)) ==
"_PRINTABLE")
1160 if (mb_strpos(
$code,
'.') !==
false)
1166 "name" => $field[
"Name"],
1168 "type" => $field[
"Type"],
1169 "multiple" => $field[
"Multiple"] ??
null,
1170 "required" => $field[
"Required"] ??
null,
1173 if (isset($field[
'Options']) && is_array($field[
"Options"]) &&
count($field[
"Options"]) > 0)
1175 $documentField[
'options'] =
'';
1176 foreach ($field[
"Options"] as
$k => $v)
1183 $documentField[
"options"] .=
"[".$k.
"]".$v.
"\n";
1187 unset($field[
"Name"], $field[
"Type"], $field[
"Multiple"], $field[
"Required"], $field[
"Options"]);
1188 $documentField = array_merge($documentField, $field);
1190 if ($currentDocumentFields && !array_key_exists(
$code, $currentDocumentFields))
1192 $documentService->AddDocumentField($documentType, $documentField);
1196 $documentService->UpdateDocumentField($documentType, $documentField);
1205 $navStartParams =
false,
1212 if (is_array($group) && empty($group))
1215 WorkflowTemplateTable::query()
1216 ->addSelect(
new \
Bitrix\Main\Entity\ExpressionField(
'CNT',
'COUNT(*)'))
1219 $countResult = $countQuery->fetch();
1221 return $countResult ? $countResult[
'CNT'] :
false;
1224 $query = WorkflowTemplateTable::query()
1230 if (is_array($group) && !empty($group))
1232 $query->setSelect($group);
1233 $query->addSelect(
new \
Bitrix\Main\Entity\ExpressionField(
'CNT',
'COUNT(*)'));
1234 $query->setGroup($group);
1238 $hasNavStartParams = (is_array($navStartParams) && !empty($navStartParams));
1239 if ($hasNavStartParams && isset($navStartParams[
'nTopCount']))
1241 $topCount = (int)$navStartParams[
'nTopCount'];
1244 if ($hasNavStartParams && $topCount > 0)
1246 $query->setLimit($topCount);
1248 elseif ($hasNavStartParams && isset($navStartParams[
'iNumPage']) && isset($navStartParams[
'nPageSize']))
1250 $query->setOffset(((
int)$navStartParams[
'iNumPage'] - 1) * (
int)$navStartParams[
'nPageSize']);
1251 $query->setLimit((
int)$navStartParams[
'nPageSize']);
1261 if (array_key_exists(
'DOCUMENT_TYPE',
$filter) && is_array(
$filter[
'DOCUMENT_TYPE']))
1266 $filter[
'=DOCUMENT_TYPE'] = $documentId;
1268 unset(
$filter[
'DOCUMENT_TYPE']);
1271 $entity = WorkflowTemplateTable::getEntity();
1272 $strictMatchFields = [];
1274 foreach (
$entity->getFields() as $field)
1276 if ($field->getDataType() ===
'string' || $field->getDataType() ===
'boolean')
1278 $strictMatchFields[] = $field->getName();
1282 foreach ($strictMatchFields as $fieldName)
1284 if (isset(
$filter[$fieldName]) && is_string(
$filter[$fieldName]))
1291 if (array_key_exists(
'AUTO_EXECUTE',
$filter))
1311 'ID',
'MODULE_ID',
'ENTITY',
'DOCUMENT_TYPE',
'DOCUMENT_STATUS',
'AUTO_EXECUTE',
1312 'NAME',
'DESCRIPTION',
'TEMPLATE',
'PARAMETERS',
'VARIABLES',
'CONSTANTS',
1313 'MODIFIED',
'USER_ID',
'ACTIVE',
'IS_MODIFIED',
'IS_SYSTEM',
'SORT',
'TYPE'
1319 $select = array_merge(
$select, [
'USER_NAME',
'USER_LAST_NAME',
'USER_SECOND_NAME',
'USER_LOGIN']);
1322 if (
count(array_intersect(
$select, [
'MODULE_ID',
'ENTITY',
'DOCUMENT_TYPE'])) > 0)
1324 foreach ([
'MODULE_ID',
'ENTITY',
'DOCUMENT_TYPE'] as $field)
1326 if (!in_array($field,
$select,
true))
1333 $userFields = [
'USER_NAME',
'USER_LAST_NAME',
'USER_SECOND_NAME',
'USER_LOGIN'];
1334 if (array_intersect(
$select, $userFields))
1336 foreach ($userFields as $userField)
1338 if (in_array($userField,
$select,
true))
1340 $select[$userField] = str_replace(
'USER_',
'USER.', $userField);
1342 $index = array_search($userField,
$select,
true);
1359 self::ParseFields(
$fields, 0, $isSystemImport);
1363 $tplFields = $this->prepareTplFields(
$fields);
1364 $result = WorkflowTemplateTable::add($tplFields);
1373 'onAfterWorkflowTemplateAdd',
1378 EventManager::getInstance()->send(
$event);
1404 self::ParseFields(
$fields, $id, $systemImport, $validationRequired);
1406 $tplFields = $this->prepareTplFields(
$fields);
1407 $result = WorkflowTemplateTable::update($id, $tplFields);
1413 'onAfterWorkflowTemplateUpdate',
1419 EventManager::getInstance()->send(
$event);
1429 $fields[
'MODIFIED'] = new \Bitrix\Main\Type\DateTime();
1430 unset(
$fields[
'TEMPLATE_SETTINGS']);
1438 if ($useGZipCompressionOption ===
"Y")
1442 elseif ($useGZipCompressionOption ===
"N")
1448 $result = function_exists(
"gzcompress");
1456 if (self::useGZipCompression())
1458 return mb_strlen(gzcompress(serialize($field), 9));
1461 return mb_strlen(serialize($field));
1466 unset(
$fields[
'MODIFIER_USER']);
1470 $fields[
'DOCUMENT_TYPE'] = $documentType;
1477 if (array_key_exists(
'DOCUMENT_TYPE',
$fields) && !is_array(
$fields[
'DOCUMENT_TYPE']))
1489 if (array_key_exists(
'TEMPLATE_SETTINGS',
$fields))
1492 $settingsValues =
$fields[
'TEMPLATE_SETTINGS']?->getAll();
1494 if (!empty($settingsValues))
1496 foreach ($settingsValues as $setting)
1498 $newValues[$setting->getName()] = $setting->getValue();
1502 $fields[
'TEMPLATE_SETTINGS'] = $newValues;
1506 private function isExternalModified(
array $fields): ?bool
1508 $template = new \Bitrix\Bizproc\Automation\Engine\Template(
$fields[
'DOCUMENT_TYPE']);
1518 private $useGZipCompression =
false;
1522 $this->useGZipCompression = $useGZipCompression;
1523 parent::__construct(
$res);
1526 private function getFromSerializedForm($value)
1528 return WorkflowTemplateTable::getFromSerializedForm($value);
1531 private function getFromSerializedSettings($value)
1533 return WorkflowTemplateTable::decodeJson($value);
1538 $res = parent::Fetch();
1542 if (array_key_exists(
"DOCUMENT_TYPE",
$res) && !is_array(
$res[
"DOCUMENT_TYPE"]))
1547 if (array_key_exists(
"TEMPLATE",
$res) && !is_array(
$res[
"TEMPLATE"]))
1549 $res[
"TEMPLATE"] = $this->GetFromSerializedForm(
$res[
"TEMPLATE"]);
1552 if (array_key_exists(
"VARIABLES",
$res) && !is_array(
$res[
"VARIABLES"]))
1554 $res[
"VARIABLES"] = $this->GetFromSerializedForm(
$res[
"VARIABLES"]);
1557 if (array_key_exists(
"CONSTANTS",
$res) && !is_array(
$res[
"CONSTANTS"]))
1559 $res[
"CONSTANTS"] = $this->GetFromSerializedForm(
$res[
"CONSTANTS"]);
1562 if (array_key_exists(
"PARAMETERS",
$res) && !is_array(
$res[
"PARAMETERS"]))
1564 $res[
"PARAMETERS"] = $this->GetFromSerializedForm(
$res[
"PARAMETERS"]);
1567 if (array_key_exists(
'TEMPLATE_SETTINGS',
$res) && !is_array(
$res[
'TEMPLATE_SETTINGS']))
1569 $res[
'TEMPLATE_SETTINGS'] = $this->getFromSerializedSettings(
$res[
'TEMPLATE_SETTINGS']);
1572 if (array_key_exists(
'MODIFIED',
$res) &&
$res[
'MODIFIED'] instanceof \
Bitrix\Main\Type\DateTime)
1588 private $userId = 0;
1589 private $isAdmin =
false;
1590 private $fullName =
'';
1596 $this->fullName =
'';
1598 if (is_int($userId))
1600 $userGroups = CUser::GetUserGroup($userId);
1601 $this->userId = (int)$userId;
1602 $this->
isAdmin = in_array(1, $userGroups);
1604 elseif ($userId === self::CurrentUser)
1607 if (is_object(
$USER) &&
$USER->IsAuthorized())
1609 $this->userId = (int)
$USER->GetID();
1612 || CModule::IncludeModule(
'bitrix24') && CBitrix24::IsPortalAdmin(
$USER->GetID())
1614 $this->fullName =
$USER->GetFullName();
1626 return $this->userId > 0 ?
'user_'.$this->userId :
null;
1631 return ($this->
isAdmin || self::isBpAdmin($this->userId));
1636 return $this->fullName;
1639 private static function isBpAdmin(
int $userId): bool
1645 $ids = array_map(
'intval', explode(
',', $idsString));
1647 return $userId && in_array($userId, $ids,
true);
1656 parent::__construct(
$message, 10010);
1657 $this->errors = $errors;
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static delete($moduleId, array $filter=array())
static get($moduleId, $name, $default="", $siteId=false)
static sortByColumn(array &$array, $columns, $callbacks='', $defaultValueIfNotSetValue=null, $preserveKeys=false)
static includeActivityFile($code)
static createInstance($code, $name)
static callStaticMethod($code, $method, $arParameters=array())
const CONSTANTS_CACHE_TAG_PREFIX
const MAX_CONSTANTS_LENGTH
static prepareDocumentType(array &$fields)
static getDocumentTypeStates($documentType, $autoExecute=-1, $stateName="")
static isConstantsTuned($workflowTemplateId)
static getCompressedFieldLength($field)
parseFields(&$arFields, $id=0, $systemImport=false, $validationRequired=true)
static & FindActivityByName(&$arWorkflowTemplate, $activityName)
setTemplateType(array &$fields, ?string $templateType=null)
const MAX_PARAMETERS_LENGTH
static importTemplateFromArray($id, $documentType, $autoExecute, $name, $description, $templateFields, $systemCode=null, $systemImport=false)
const MAX_VARIABLES_LENGTH
static & FindParentActivityByName(&$arWorkflowTemplate, $activityName)
setShowInTimelineBeforeAdd(array &$fields)
prepareTemplatesSelect(array &$select)
static getTemplateState($workflowTemplateId, $stateName="")
updateTemplate($id, array $fields, bool $systemImport=false, bool $validationRequired=true)
static getTemplateUserId($workflowTemplateId)
setShowInTimelineBeforeUpdate(array &$fields)
loadWorkflow($workflowTemplateId)
getTemplateType(array $fields, int $id=0)
getTemplatesList(array $order=['ID'=> 'DESC'], array $filter=[], $group=false, $navStartParams=false, array $select=[])
static update($id, $fields, $systemImport=false, $validationRequired=true)
prepareTemplatesFilter(array &$filter)
static importDocumentFields(array $documentType, array $fields)
static getTemplateConstants($workflowTemplateId)
static checkWorkflowParameters($arTemplateParameters, $arPossibleValues, $documentType, &$arErrors)
static add($fields, $systemImport=false)
static getList($arOrder=array("ID"=> "DESC"), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
loadWorkflowFromArray($templatesListItem)
static exportTemplate($id, $bCompress=true)
addTemplate(array $fields, bool $isSystemImport=false)
static cleanTemplateCache($id)
static $workflowConstants
addTemplateSettings(int $templateId, array $templateFields)
static useGZipCompression()
static prepareSettingsCollection(array &$fields)
static checkTemplateActivities(array $template)
static getStatesOfTemplate($arWorkflowTemplate)
static importTemplate($id, $documentType, $autoExecute, $name, $description, $datum, $systemCode=null, $systemImport=false)
validateTemplate($arActivity, $user)
static searchTemplatesByDocumentType($documentType, $autoExecute=-1)
GetTemplatesList($arOrder=array("ID"=> "DESC"), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
static getTransfersOfState($arWorkflowTemplate, $stateName)
__construct($res, $useGZipCompression)
__construct($userId=null)
__construct($message="", array $errors=array())
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
GetMessage($name, $aReplace=null)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
$GLOBALS['_____370096793']