%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/bizproc/classes/general/ |
Current File : /home/bitrix/www/bitrix/modules/bizproc/classes/general/document.php |
<? IncludeModuleLangFile(__FILE__); use Bitrix\Bizproc\WorkflowInstanceTable; use Bitrix\Main; /** * Bizproc API Helper for external usage. */ class CBPDocument { const PARAM_TAGRET_USER = 'TargetUser'; const PARAM_MODIFIED_DOCUMENT_FIELDS = 'ModifiedDocumentField'; const PARAM_USE_FORCED_TRACKING = 'UseForcedTracking'; const PARAM_IGNORE_SIMULTANEOUS_PROCESSES_LIMIT = 'IgnoreSimultaneousProcessesLimit'; const PARAM_DOCUMENT_EVENT_TYPE = 'DocumentEventType'; const PARAM_DOCUMENT_TYPE = '__DocumentType'; public static function MigrateDocumentType($oldType, $newType) { $templateIds = array(); $db = CBPWorkflowTemplateLoader::GetList(array(), array("DOCUMENT_TYPE" => $oldType), false, false, array("ID")); while ($ar = $db->Fetch()) $templateIds[] = $ar["ID"]; foreach ($templateIds as $id) CBPWorkflowTemplateLoader::Update($id, array("DOCUMENT_TYPE" => $newType)); if (count($templateIds) > 0) { CBPHistoryService::MigrateDocumentType($oldType, $newType, $templateIds); CBPStateService::MigrateDocumentType($oldType, $newType, $templateIds); WorkflowInstanceTable::migrateDocumentType($oldType, $newType, $templateIds); } } /** * Method returns array of workflow templates and states for specified document. * If document id is set method returns array of running and terminated workflow states and also templates which started on document edit action. * If document id is not set method returns array of templates which started on document add. * Return array example: array( * workflow_id_or_template_id => array( * "ID" => workflow_id, * "TEMPLATE_ID" => template_id, * "TEMPLATE_NAME" => template_name, * "TEMPLATE_DESCRIPTION" => template_description, * "TEMPLATE_PARAMETERS" => template_parameters, * "STATE_NAME" => current_state_name, * "STATE_TITLE" => current_state_title, * "STATE_MODIFIED" => state_modified_datetime, * "STATE_PARAMETERS" => state_parameters, * "STATE_PERMISSIONS" => state_permissions, * "WORKFLOW_STATUS" => workflow_status, * ), * . . . * ) * TEMPLATE_PARAMETERS example: * array( * "param1" => array( * "Name" => "Parameter 1", * "Description" => "", * "Type" => "int", * "Required" => true, * "Multiple" => false, * "Default" => 8, * "Options" => null, * ), * "param2" => array( * "Name" => "Parameter 2", * "Description" => "", * "Type" => "select", * "Required" => false, * "Multiple" => true, * "Default" => "v2", * "Options" => array( * "v1" => "V 1", * "v2" => "V 2", * "v3" => "V 3", * . . . * ), * ), * . . . * ) * STATE_PARAMETERS example: * array( * array( * "NAME" => event_name, * "TITLE" => event_title, * "PERMISSION" => array('user_1') * ), * . . . * ) * STATE_PERMISSIONS example: * array( * operation => users_array, * . . . * ) * * @param array $documentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE) * @param null|array $documentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @return array - Workflow states and templates. */ public static function GetDocumentStates($documentType, $documentId = null) { $arDocumentStates = array(); if ($documentId != null) $arDocumentStates = CBPStateService::GetDocumentStates($documentId); $arTemplateStates = CBPWorkflowTemplateLoader::GetDocumentTypeStates( $documentType, (($documentId != null) ? CBPDocumentEventType::Edit : CBPDocumentEventType::Create) ); return ($arDocumentStates + $arTemplateStates); } /** * Method returns workflow state for specified document. * * @param array $documentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @param string $workflowId - Workflow id. * @return array - Workflow state array. */ public static function GetDocumentState($documentId, $workflowId) { $arDocumentState = CBPStateService::GetDocumentStates($documentId, $workflowId); return $arDocumentState; } public static function MergeDocuments($firstDocumentId, $secondDocumentId) { CBPStateService::MergeStates($firstDocumentId, $secondDocumentId); WorkflowInstanceTable::mergeByDocument($firstDocumentId, $secondDocumentId); CBPHistoryService::MergeHistory($firstDocumentId, $secondDocumentId); } /** * Method returns array of events available for specified user and specified state * * @param int $userId - User id. * @param array $arGroups - User groups. * @param array $arState - Workflow state. * @param bool $appendExtendedGroups - Append extended groups. * @return array - Events array array(array("NAME" => event_name, "TITLE" => event_title), ...). * @throws Exception */ public static function GetAllowableEvents($userId, $arGroups, $arState, $appendExtendedGroups = false) { if (!is_array($arState)) throw new Exception("arState"); if (!is_array($arGroups)) throw new Exception("arGroups"); $arGroups = CBPHelper::convertToExtendedGroups($arGroups); if ($appendExtendedGroups) { $arGroups = array_merge($arGroups, CBPHelper::getUserExtendedGroups($userId)); } if (!in_array("group_u".$userId, $arGroups)) $arGroups[] = "group_u".$userId; $arResult = array(); if (is_array($arState["STATE_PARAMETERS"]) && count($arState["STATE_PARAMETERS"]) > 0) { foreach ($arState["STATE_PARAMETERS"] as $arStateParameter) { $arStateParameter["PERMISSION"] = CBPHelper::convertToExtendedGroups($arStateParameter["PERMISSION"]); if (count($arStateParameter["PERMISSION"]) <= 0 || count(array_intersect($arGroups, $arStateParameter["PERMISSION"])) > 0) { $arResult[] = array( "NAME" => $arStateParameter["NAME"], "TITLE" => ((strlen($arStateParameter["TITLE"]) > 0) ? $arStateParameter["TITLE"] : $arStateParameter["NAME"]), ); } } } return $arResult; } public static function AddDocumentToHistory($parameterDocumentId, $name, $userId) { list($moduleId, $entity, $documentType) = CBPHelper::ParseDocumentId($parameterDocumentId); if (strlen($moduleId) > 0) CModule::IncludeModule($moduleId); if (!class_exists($entity)) return false; $runtime = CBPRuntime::GetRuntime(); $runtime->StartRuntime(); $historyService = $runtime->GetService("HistoryService"); $documentService = $runtime->GetService("DocumentService"); $userId = intval($userId); $historyIndex = $historyService->AddHistory( array( "DOCUMENT_ID" => $parameterDocumentId, "NAME" => "New", "DOCUMENT" => null, "USER_ID" => $userId, ) ); $arDocument = $documentService->GetDocumentForHistory($parameterDocumentId, $historyIndex); if (!is_array($arDocument)) return false; $historyService->UpdateHistory( $historyIndex, array( "NAME" => $name, "DOCUMENT" => $arDocument, ) ); return $historyIndex; } /** * Method returns allowable operations for specified user in specified states. * If specified states are not relevant to state machine returns null. * If user has no access returns array(). * Else returns operations array(operation, ...). * * @param int $userId - User id. * @param array $arGroups - User groups. * @param array $arStates - Workflow states. * @param bool $appendExtendedGroups - Append extended groups. * @return array|null - Allowable operations. * @throws Exception */ public static function GetAllowableOperations($userId, $arGroups, $arStates, $appendExtendedGroups = false) { if (!is_array($arStates)) throw new Exception("arStates"); if (!is_array($arGroups)) throw new Exception("arGroups"); $arGroups = CBPHelper::convertToExtendedGroups($arGroups); if ($appendExtendedGroups) { $arGroups = array_merge($arGroups, CBPHelper::getUserExtendedGroups($userId)); } if (!in_array("group_u".$userId, $arGroups)) $arGroups[] = "group_u".$userId; $result = null; foreach ($arStates as $arState) { if (is_array($arState["STATE_PERMISSIONS"]) && count($arState["STATE_PERMISSIONS"]) > 0) { if ($result == null) $result = array(); foreach ($arState["STATE_PERMISSIONS"] as $operation => $arOperationGroups) { $arOperationGroups = CBPHelper::convertToExtendedGroups($arOperationGroups); if (count(array_intersect($arGroups, $arOperationGroups)) > 0) $result[] = strtolower($operation); } } } return $result; } /** * Method check can operate user specified operation in specified state. * If specified states are not relevant to state machine returns true. * If user can`t do operation return false. * Else returns true. * * @param string $operation - Operation. * @param int $userId - User id. * @param array $arGroups - User groups. * @param array $arStates - Workflows states. * @return bool * @throws Exception */ public static function CanOperate($operation, $userId, $arGroups, $arStates) { $operation = trim($operation); if (strlen($operation) <= 0) throw new Exception("operation"); $operations = self::GetAllowableOperations($userId, $arGroups, $arStates); if ($operations === null) return true; return in_array($operation, $operations); } /** * Method starts workflow. * * @param int $workflowTemplateId - Template id. * @param array $documentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @param array $arParameters - Workflow parameters. * @param array $errors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). * @param array|null $parentWorkflow - Parent workflow information. * @return string - Workflow id. */ public static function StartWorkflow($workflowTemplateId, $documentId, $arParameters, &$errors, $parentWorkflow = null) { $errors = []; $runtime = CBPRuntime::GetRuntime(); if (!is_array($arParameters)) { $arParameters = array($arParameters); } if (!array_key_exists(static::PARAM_TAGRET_USER, $arParameters)) { $arParameters[static::PARAM_TAGRET_USER] = is_object($GLOBALS["USER"]) ? "user_".intval($GLOBALS["USER"]->GetID()) : null; } if (!isset($arParameters[static::PARAM_MODIFIED_DOCUMENT_FIELDS])) { $arParameters[static::PARAM_MODIFIED_DOCUMENT_FIELDS] = false; } if (!isset($arParameters[static::PARAM_DOCUMENT_EVENT_TYPE])) { $arParameters[static::PARAM_DOCUMENT_EVENT_TYPE] = CBPDocumentEventType::None; } try { $wi = $runtime->CreateWorkflow($workflowTemplateId, $documentId, $arParameters, $parentWorkflow); $wi->Start(); return $wi->GetInstanceId(); } catch (Exception $e) { $errors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); } return null; } /** * Method auto starts workflow. * * @param array $documentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @param int $autoExecute - CBPDocumentEventType (1 = CBPDocumentEventType::Create, 2 = CBPDocumentEventType::Edit). * @param array $documentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @param array $arParameters - Workflow parameters. * @param array $arErrors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). */ public static function AutoStartWorkflows($documentType, $autoExecute, $documentId, $arParameters, &$arErrors) { $arErrors = array(); $runtime = CBPRuntime::GetRuntime(); if (!is_array($arParameters)) $arParameters = array($arParameters); if (!isset($arParameters[static::PARAM_TAGRET_USER])) $arParameters[static::PARAM_TAGRET_USER] = is_object($GLOBALS["USER"]) ? "user_".intval($GLOBALS["USER"]->GetID()) : null; if (!isset($arParameters[static::PARAM_MODIFIED_DOCUMENT_FIELDS])) $arParameters[static::PARAM_MODIFIED_DOCUMENT_FIELDS] = false; $arParameters[static::PARAM_DOCUMENT_EVENT_TYPE] = $autoExecute; $arWT = CBPWorkflowTemplateLoader::SearchTemplatesByDocumentType($documentType, $autoExecute); foreach ($arWT as $wt) { try { $wi = $runtime->CreateWorkflow($wt["ID"], $documentId, $arParameters); $wi->Start(); } catch (Exception $e) { $arErrors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); } } } /** * Method sends external event to workflow. * * @param string $workflowId - Workflow id. * @param string $workflowEvent - Event name. * @param array $arParameters - Event parameters. * @param array $arErrors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). */ public static function SendExternalEvent($workflowId, $workflowEvent, $arParameters, &$arErrors) { $arErrors = array(); try { CBPRuntime::SendExternalEvent($workflowId, $workflowEvent, $arParameters); } catch(Exception $e) { $arErrors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); } } /** * Method terminates workflow. * * @param string $workflowId - Workflow id. * @param array $documentId - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @param array $arErrors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). * @param string $stateTitle - State title (workflow status). */ public static function TerminateWorkflow($workflowId, $documentId, &$arErrors, $stateTitle = '') { $arErrors = array(); $runtime = CBPRuntime::GetRuntime(); try { $workflow = $runtime->GetWorkflow($workflowId, true); if ($documentId) { $d = $workflow->GetDocumentId(); if ($d[0] != $documentId[0] || $d[1] != $documentId[1] || strtolower($d[2]) !== strtolower($documentId[2])) throw new Exception(GetMessage("BPCGDOC_INVALID_WF")); } $workflow->Terminate(null, $stateTitle); } catch(Exception $e) { $arErrors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); return false; } return true; } public static function killWorkflow($workflowId, $terminate = true, $documentId = null) { $errors = array(); if ($terminate) static::TerminateWorkflow($workflowId, $documentId, $errors); if (!$errors) { WorkflowInstanceTable::delete($workflowId); CBPTaskService::DeleteByWorkflow($workflowId); CBPTrackingService::DeleteByWorkflow($workflowId); CBPStateService::DeleteWorkflow($workflowId); } return $errors; } /** * Method removes all related document data. * @param array $documentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @param array $errors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). */ public static function OnDocumentDelete($documentId, &$errors) { $errors = []; $instanceIds = WorkflowInstanceTable::getIdsByDocument($documentId); foreach ($instanceIds as $instanceId) { static::TerminateWorkflow($instanceId, $documentId, $errors); } $statesIds = \CBPStateService::getIdsByDocument($documentId); foreach ($statesIds as $stateId) { \CBPTaskService::DeleteByWorkflow($stateId); \CBPTrackingService::DeleteByWorkflow($stateId); } \CBPStateService::deleteCompletedStates($documentId); CBPHistoryService::DeleteByDocument($documentId); } public static function PostTaskForm($arTask, $userId, $arRequest, &$arErrors, $userName = "") { $originalUserId = CBPTaskService::getOriginalTaskUserId($arTask['ID'], $userId); return CBPActivity::CallStaticMethod( $arTask["ACTIVITY"], "PostTaskForm", array( $arTask, $originalUserId, $arRequest, &$arErrors, $userName, $userId ) ); } public static function ShowTaskForm($arTask, $userId, $userName = "", $arRequest = null) { return CBPActivity::CallStaticMethod( $arTask["ACTIVITY"], "ShowTaskForm", array( $arTask, $userId, $userName, $arRequest ) ); } /** * @param int $userId Task User Id. * @param int $status Task user status. * @param int|array $ids Task ids. * @param array $errors Error collection. * @return bool */ public static function setTasksUserStatus($userId, $status, $ids = array(), &$errors = array()) { $filter = array( 'USER_ID' => $userId, 'STATUS' => CBPTaskStatus::Running, 'USER_STATUS' => CBPTaskUserStatus::Waiting, ); if ($ids) { $ids = array_filter(array_map('intval', (array)$ids)); if ($ids) $filter['ID'] = $ids; } $iterator = CBPTaskService::GetList(array('ID'=>'ASC'), $filter, false, false, array('ID', 'NAME', 'WORKFLOW_ID', 'ACTIVITY', 'ACTIVITY_NAME', 'IS_INLINE')); while ($task = $iterator->fetch()) { if ($task['IS_INLINE'] == 'Y') { $taskErrors = array(); self::PostTaskForm($task, $userId, array('INLINE_USER_STATUS' => $status), $taskErrors); if (!empty($taskErrors)) foreach ($taskErrors as $error) $errors[] = GetMessage('BPCGDOC_ERROR_ACTION', array('#NAME#' => $task['NAME'], '#ERROR#' => $error['message'])); } else $errors[] = GetMessage('BPCGDOC_ERROR_TASK_IS_NOT_INLINE', array('#NAME#' => $task['NAME'])); } return true; } /** * @param int $fromUserId Task current user. * @param int $toUserId Task target user. * @param array|int $ids Task ids. * @param array $errors Error collection. * @param null | array $allowedDelegationType * @return bool */ public static function delegateTasks($fromUserId, $toUserId, $ids = array(), &$errors = array(), $allowedDelegationType = null) { $filter = array( 'USER_ID' => $fromUserId, 'STATUS' => CBPTaskStatus::Running, 'USER_STATUS' => CBPTaskUserStatus::Waiting ); if ($ids) { $ids = array_filter(array_map('intval', (array)$ids)); if ($ids) $filter['ID'] = $ids; } $iterator = CBPTaskService::GetList( array('ID'=>'ASC'), $filter, false, false, array('ID', 'NAME', 'WORKFLOW_ID', 'ACTIVITY_NAME', 'DELEGATION_TYPE') ); $found = false; $trackingService = null; $sendImNotify = (CModule::IncludeModule("im")); while ($task = $iterator->fetch()) { if ($allowedDelegationType && !in_array((int)$task['DELEGATION_TYPE'], $allowedDelegationType, true)) { $errors[] = GetMessage('BPCGDOC_ERROR_DELEGATE_'.$task['DELEGATION_TYPE'], array('#NAME#' => $task['NAME'])); } elseif (!CBPTaskService::delegateTask($task['ID'], $fromUserId, $toUserId)) { $errors[] = GetMessage('BPCGDOC_ERROR_DELEGATE', array('#NAME#' => $task['NAME'])); } else { if (!$found) { $runtime = CBPRuntime::GetRuntime(); $runtime->StartRuntime(); /** @var CBPTrackingService $trackingService */ $trackingService = $runtime->GetService('TrackingService'); } $found = true; $trackingService->Write( $task['WORKFLOW_ID'], CBPTrackingType::Custom, $task['ACTIVITY_NAME'], CBPActivityExecutionStatus::Executing, CBPActivityExecutionResult::None, GetMessage('BPCGDOC_DELEGATE_LOG_TITLE'), GetMessage('BPCGDOC_DELEGATE_LOG', array( '#NAME#' => $task['NAME'], '#FROM#' => '{=user:user_'.$fromUserId.'}', '#TO#' => '{=user:user_'.$toUserId.'}' )) ); if ($sendImNotify) { CIMNotify::Add(array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, 'FROM_USER_ID' => $fromUserId, 'TO_USER_ID' => $toUserId, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "bizproc", "NOTIFY_EVENT" => "delegate_task", "NOTIFY_TAG" => "BIZPROC|TASK|".$task['ID'], 'MESSAGE' => GetMessage('BPCGDOC_DELEGATE_NOTIFY_TEXT', array( '#TASK_URL#' => '/company/personal/bizproc/'.(int)$task['ID'].'/', '#TASK_NAME#' => $task['NAME'] )) )); } } } return $found; } public static function getTaskControls($arTask) { return CBPActivity::CallStaticMethod( $arTask["ACTIVITY"], "getTaskControls", array( $arTask ) ); } /** * Method validates parameters values from StartWorkflowParametersShow. * * @param int $templateId - Template id. * @param array $arWorkflowParameters - Workflow parameters. * @param $documentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @param array $arErrors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). * @return array - Valid Parameters values. */ public static function StartWorkflowParametersValidate($templateId, $arWorkflowParameters, $documentType, &$arErrors) { $arErrors = array(); $templateId = intval($templateId); if ($templateId <= 0) { $arErrors[] = array( "code" => "", "message" => GetMessage("BPCGDOC_EMPTY_WD_ID"), ); return array(); } if (!isset($arWorkflowParameters) || !is_array($arWorkflowParameters)) $arWorkflowParameters = array(); $arWorkflowParametersValues = array(); $arRequest = $_REQUEST; foreach ($_FILES as $k => $v) { if (array_key_exists("name", $v)) { if (is_array($v["name"])) { $ks = array_keys($v["name"]); for ($i = 0, $cnt = count($ks); $i < $cnt; $i++) { $ar = array(); foreach ($v as $k1 => $v1) $ar[$k1] = $v1[$ks[$i]]; $arRequest[$k][] = $ar; } } else { $arRequest[$k] = $v; } } } if (count($arWorkflowParameters) > 0) { $arErrorsTmp = array(); $ar = array(); foreach ($arWorkflowParameters as $parameterKey => $arParameter) $ar[$parameterKey] = $arRequest["bizproc".$templateId."_".$parameterKey]; $arWorkflowParametersValues = CBPWorkflowTemplateLoader::CheckWorkflowParameters( $arWorkflowParameters, $ar, $documentType, $arErrors ); } return $arWorkflowParametersValues; } /** * Method shows parameters form. Validates in StartWorkflowParametersValidate. * * @param int $templateId - Template id. * @param array $arWorkflowParameters - Workflow parameters. * @param string $formName - Form name. * @param bool $bVarsFromForm - false on first form open, else - true. * @param null|array $documentType Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). */ public static function StartWorkflowParametersShow($templateId, $arWorkflowParameters, $formName, $bVarsFromForm, $documentType = null) { $templateId = intval($templateId); if ($templateId <= 0) return; if (!isset($arWorkflowParameters) || !is_array($arWorkflowParameters)) $arWorkflowParameters = array(); if (strlen($formName) <= 0) $formName = "start_workflow_form1"; if ($documentType == null) { $dbResult = CBPWorkflowTemplateLoader::GetList(array(), array("ID" => $templateId), false, false, array("ID", "MODULE_ID", "ENTITY", "DOCUMENT_TYPE")); if ($arResult = $dbResult->Fetch()) $documentType = $arResult["DOCUMENT_TYPE"]; } $arParametersValues = array(); $keys = array_keys($arWorkflowParameters); foreach ($keys as $key) { $v = ($bVarsFromForm ? $_REQUEST["bizproc".$templateId."_".$key] : $arWorkflowParameters[$key]["Default"]); if (!is_array($v)) { $arParametersValues[$key] = $v; } else { $keys1 = array_keys($v); foreach ($keys1 as $key1) $arParametersValues[$key][$key1] = $v[$key1]; } } $runtime = CBPRuntime::GetRuntime(); $runtime->StartRuntime(); $documentService = $runtime->GetService("DocumentService"); foreach ($arWorkflowParameters as $parameterKey => $arParameter) { $parameterKeyExt = "bizproc".$templateId."_".$parameterKey; ?><tr> <td align="right" width="40%" valign="top" class="field-name"><?= $arParameter["Required"] ? "<span class=\"required\">*</span> " : ""?><?= htmlspecialcharsbx($arParameter["Name"]) ?>:<?if (strlen($arParameter["Description"]) > 0) echo "<br /><small>".htmlspecialcharsbx($arParameter["Description"])."</small><br />";?></td> <td width="60%" valign="top"><? echo $documentService->GetFieldInputControl( $documentType, $arParameter, array("Form" => $formName, "Field" => $parameterKeyExt), $arParametersValues[$parameterKey], false, true ); ?></td></tr><? } } public static function AddShowParameterInit($module, $type, $document_type, $entity = "", $document_id = '') { $GLOBALS["BP_AddShowParameterInit_".$module."_".$entity."_".$document_type] = 1; CUtil::InitJSCore(array("window", "ajax")); ?> <script src="/bitrix/js/bizproc/bizproc.js"></script> <script> function BPAShowSelector(id, type, mode, arCurValues, arDocumentType) { <?if($type=="only_users"):?> var def_mode = "only_users"; <?else:?> var def_mode = ""; <?endif?> if (!mode) mode = def_mode; var module = '<?=CUtil::JSEscape($module)?>'; var entity = '<?=CUtil::JSEscape($entity)?>'; var documentType = '<?=CUtil::JSEscape($document_type)?>'; var documentId = '<?=CUtil::JSEscape($document_id)?>'; /*if (arDocumentType && arDocumentType.length == 3) { module = arDocumentType[0]; entity = arDocumentType[1]; documentType = arDocumentType[2]; }*/ var loadAccessLib = (typeof BX.Access === 'undefined'); if (mode == "only_users") { if (BX.getClass('BX.Bizproc.UserSelector') && BX.Bizproc.UserSelector.canUse()) { var controlNode = BX(id); if (controlNode.__userSelector) { controlNode.__userSelector.onBindClick(); return; } BX.Bizproc.UserSelector.loadData(function() { controlNode.__userSelector = new BX.Bizproc.UserSelector({ bindTo: controlNode, addCallback: function(user) { var prefix = ''; if (controlNode.value.length > 0 && !/;\s*$/.test(controlNode.value)) { prefix = '; '; } controlNode.value += prefix + user['name'] + ' ['+user['id']+']; '; } }); controlNode.__userSelector.onBindClick(); }); controlNode.__userSelector = true; return; } BX.WindowManager.setStartZIndex(1150); (new BX.CDialog({ 'content_url': '/bitrix/admin/'+module +'_bizproc_selector.php?mode=public&bxpublic=Y&lang=<?=LANGUAGE_ID?>&entity=' +entity +(loadAccessLib? '&load_access_lib=Y':''), 'content_post': { 'document_type': documentType, 'document_id': documentId, 'fieldName': id, 'fieldType': type, 'only_users': 'Y', 'sessid': '<?= bitrix_sessid() ?>' }, 'height': 400, 'width': 485 })).Show(); } else { if (typeof arWorkflowConstants === 'undefined') arWorkflowConstants = {}; var workflowTemplateNameCur = workflowTemplateName; var workflowTemplateDescriptionCur = workflowTemplateDescription; var workflowTemplateAutostartCur = workflowTemplateAutostart; var arWorkflowParametersCur = arWorkflowParameters; var arWorkflowVariablesCur = arWorkflowVariables; var arWorkflowConstantsCur = arWorkflowConstants; var arWorkflowTemplateCur = Array(rootActivity.Serialize()); if (arCurValues) { if (arCurValues['workflowTemplateName']) workflowTemplateNameCur = arCurValues['workflowTemplateName']; if (arCurValues['workflowTemplateDescription']) workflowTemplateDescriptionCur = arCurValues['workflowTemplateDescription']; if (arCurValues['workflowTemplateAutostart']) workflowTemplateAutostartCur = arCurValues['workflowTemplateAutostart']; if (arCurValues['arWorkflowParameters']) arWorkflowParametersCur = arCurValues['arWorkflowParameters']; if (arCurValues['arWorkflowVariables']) arWorkflowVariablesCur = arCurValues['arWorkflowVariables']; if (arCurValues['arWorkflowConstants']) arWorkflowConstantsCur = arCurValues['arWorkflowConstants']; if (arCurValues['arWorkflowTemplate']) arWorkflowTemplateCur = arCurValues['arWorkflowTemplate']; } var p = { 'document_type': documentType, 'document_id': documentId, 'fieldName': id, 'fieldType': type, 'selectorMode': mode, 'workflowTemplateName': workflowTemplateNameCur, 'workflowTemplateDescription': workflowTemplateDescriptionCur, 'workflowTemplateAutostart': workflowTemplateAutostartCur, 'sessid': '<?= bitrix_sessid() ?>' }; JSToPHPHidd(p, arWorkflowParametersCur, 'arWorkflowParameters'); JSToPHPHidd(p, arWorkflowVariablesCur, 'arWorkflowVariables'); JSToPHPHidd(p, arWorkflowConstantsCur, 'arWorkflowConstants'); JSToPHPHidd(p, arWorkflowTemplateCur, 'arWorkflowTemplate'); (new BX.CDialog({ 'content_url': '/bitrix/admin/' +module+'_bizproc_selector.php?mode=public&bxpublic=Y&lang=<?=LANGUAGE_ID?>&entity=' +entity +(loadAccessLib? '&load_access_lib=Y':''), 'content_post': p, 'height': 425, 'width': 485 })).Show(); } } </script> <? } public static function ShowParameterField($type, $name, $values, $arParams = Array()) { if(strlen($arParams['id'])>0) $id = $arParams['id']; else $id = md5(uniqid()); if($type == "text") { $s = '<table cellpadding="0" cellspacing="0" border="0"><tr><td valign="top"><textarea '; $s .= 'rows="'.($arParams['rows']>0?intval($arParams['rows']):5).'" '; $s .= 'cols="'.($arParams['cols']>0?intval($arParams['cols']):50).'" '; if (!empty($arParams['maxlength'])) { $s .= 'maxlength="'.intval($arParams['maxlength']).'" '; } $s .= 'name="'.htmlspecialcharsbx($name).'" '; $s .= 'id="'.htmlspecialcharsbx($id).'" '; $s .= '>'.htmlspecialcharsbx($values); $s .= '</textarea></td>'; $s .= '<td valign="top" style="padding-left:4px">'; $s .= CBPHelper::renderControlSelectorButton($id, $type); $s .= '</td></tr></table>'; } elseif($type == "user") { $s = '<table cellpadding="0" cellspacing="0" border="0"><tr><td valign="top"><textarea onkeydown="if(event.keyCode==45)BPAShowSelector(\''.Cutil::JSEscape(htmlspecialcharsbx($id)).'\', \''.Cutil::JSEscape($type).'\');" '; $s .= 'rows="'.($arParams['rows']>0?intval($arParams['rows']):3).'" '; $s .= 'cols="'.($arParams['cols']>0?intval($arParams['cols']):45).'" '; $s .= 'name="'.htmlspecialcharsbx($name).'" '; $s .= 'id="'.htmlspecialcharsbx($id).'">'.htmlspecialcharsbx($values).'</textarea>'; $s .= '</td><td valign="top" style="padding-left:4px">'; $s .= CBPHelper::renderControlSelectorButton($id, $type, array('title' => GetMessage("BIZPROC_AS_SEL_FIELD_BUTTON").' (Insert)')); $s .= '</td></tr></table>'; } elseif($type == "bool") { $s = '<select name="'.htmlspecialcharsbx($name).'"><option value=""></option><option value="Y"'.($values=='Y'?' selected':'').'>'.GetMessage('MAIN_YES').'</option><option value="N"'.($values=='N'?' selected':'').'>'.GetMessage('MAIN_NO').'</option>'; $s .= '<input type="text" '; $s .= 'size="20" '; $s .= 'name="'.htmlspecialcharsbx($name).'_X" '; $s .= 'id="'.htmlspecialcharsbx($id).'" '; $s .= 'value="'.($values=="Y" || $values=="N"?"":htmlspecialcharsbx($values)).'"> '; $s .= CBPHelper::renderControlSelectorButton($id, $type); } elseif ($type == 'datetime') { $s = '<span style="white-space:nowrap;"><input type="text" '; $s .= 'size="'.($arParams['size']>0?intval($arParams['size']):30).'" '; $s .= 'name="'.htmlspecialcharsbx($name).'" '; $s .= 'id="'.htmlspecialcharsbx($id).'" '; $s .= 'value="'.htmlspecialcharsbx($values).'">'.CAdminCalendar::Calendar(htmlspecialcharsbx($name), "", "", true).'</span> '; $s .= CBPHelper::renderControlSelectorButton($id, $type); } else { $s = '<input type="text" '; $s .= 'size="'.($arParams['size']>0?intval($arParams['size']):70).'" '; if (!empty($arParams['maxlength'])) { $s .= 'maxlength="'.intval($arParams['maxlength']).'" '; } $s .= 'name="'.htmlspecialcharsbx($name).'" '; $s .= 'id="'.htmlspecialcharsbx($id).'" '; $s .= 'value="'.htmlspecialcharsbx($values).'"> '; $s .= CBPHelper::renderControlSelectorButton($id, $type); } return $s; } public static function _ReplaceTaskURL($str, $documentType) { $chttp = new CHTTP(); $baseHref = $chttp->URN2URI(''); return str_replace( Array('#HTTP_HOST#', '#TASK_URL#', '#BASE_HREF#'), Array($_SERVER['HTTP_HOST'], ($documentType[0]=="iblock"?"/bitrix/admin/bizproc_task.php?workflow_id={=Workflow:id}":"/company/personal/bizproc/{=Workflow:id}/"), $baseHref), $str ); } public static function AddDefaultWorkflowTemplates($documentType, $additionalModuleId = null) { if (!empty($additionalModuleId)) { $additionalModuleId = preg_replace("/[^a-z0-9_.]/i", "", $additionalModuleId); $arModule = array($additionalModuleId, $documentType[0], 'bizproc'); } else { $arModule = array($documentType[0], 'bizproc'); } $bIn = false; foreach ($arModule as $sModule) { if (file_exists($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/'.$sModule.'/templates')) { if($handle = opendir($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/'.$sModule.'/templates')) { $bIn = true; while(false !== ($file = readdir($handle))) { if(!is_file($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/'.$sModule.'/templates/'.$file)) continue; $arFields = false; include($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/'.$sModule.'/templates/'.$file); if(is_array($arFields)) { /* * If DOCUMENT_TYPE not defined, use current documentType * Overwise check if DOCUMENT_TYPE equals to current documentType */ if (!array_key_exists("DOCUMENT_TYPE", $arFields)) $arFields["DOCUMENT_TYPE"] = $documentType; elseif($arFields["DOCUMENT_TYPE"] != $documentType) continue; $arFields["SYSTEM_CODE"] = $file; if(is_object($GLOBALS['USER'])) $arFields["USER_ID"] = $GLOBALS['USER']->GetID(); $arFields["MODIFIER_USER"] = new CBPWorkflowTemplateUser(CBPWorkflowTemplateUser::CurrentUser); try { CBPWorkflowTemplateLoader::Add($arFields); } catch (Exception $e) { } } } closedir($handle); } } if ($bIn) break; } } /** * Method returns array of workflow templates for specified document type. * Return array example: * array( * array( * "ID" => workflow_id, * "NAME" => template_name, * "DESCRIPTION" => template_description, * "MODIFIED" => modified datetime, * "USER_ID" => modified by user id, * "USER_NAME" => modified by user name, * "AUTO_EXECUTE" => flag CBPDocumentEventType, * "AUTO_EXECUTE_TEXT" => auto_execute_text, * ), * . . . * ) * * @param array $documentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @return array - Templates array. */ public static function GetWorkflowTemplatesForDocumentType($documentType) { $arResult = array(); $dbWorkflowTemplate = CBPWorkflowTemplateLoader::GetList( array(), array("DOCUMENT_TYPE" => $documentType, "ACTIVE"=>"Y", '!AUTO_EXECUTE' => CBPDocumentEventType::Automation), false, false, array("ID", "NAME", "DESCRIPTION", "MODIFIED", "USER_ID", "AUTO_EXECUTE", "USER_NAME", "USER_LAST_NAME", "USER_LOGIN", "USER_SECOND_NAME", 'PARAMETERS') ); while ($arWorkflowTemplate = $dbWorkflowTemplate->GetNext()) { $arWorkflowTemplate["USER"] = "(".$arWorkflowTemplate["USER_LOGIN"].")".((strlen($arWorkflowTemplate["USER_NAME"]) > 0 || strlen($arWorkflowTemplate["USER_LAST_NAME"]) > 0) ? " " : "").CUser::FormatName(COption::GetOptionString("bizproc", "name_template", CSite::GetNameFormat(false), SITE_ID), array("NAME" => $arWorkflowTemplate["USER_NAME"], "LAST_NAME" => $arWorkflowTemplate["USER_LAST_NAME"], "SECOND_NAME" => $arWorkflowTemplate["USER_SECOND_NAME"]), false, false); $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] = ""; if ($arWorkflowTemplate["AUTO_EXECUTE"] == CBPDocumentEventType::None) $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= GetMessage("BPCGDOC_AUTO_EXECUTE_NONE"); if (($arWorkflowTemplate["AUTO_EXECUTE"] & CBPDocumentEventType::Create) != 0) { if (strlen($arWorkflowTemplate["AUTO_EXECUTE_TEXT"]) > 0) $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= ", "; $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= GetMessage("BPCGDOC_AUTO_EXECUTE_CREATE"); } if (($arWorkflowTemplate["AUTO_EXECUTE"] & CBPDocumentEventType::Edit) != 0) { if (strlen($arWorkflowTemplate["AUTO_EXECUTE_TEXT"]) > 0) $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= ", "; $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= GetMessage("BPCGDOC_AUTO_EXECUTE_EDIT"); } if (($arWorkflowTemplate["AUTO_EXECUTE"] & CBPDocumentEventType::Delete) != 0) { if (strlen($arWorkflowTemplate["AUTO_EXECUTE_TEXT"]) > 0) $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= ", "; $arWorkflowTemplate["AUTO_EXECUTE_TEXT"] .= GetMessage("BPCGDOC_AUTO_EXECUTE_DELETE"); } $arWorkflowTemplate['HAS_PARAMETERS'] = count($arWorkflowTemplate['PARAMETERS']) > 0; $arResult[] = $arWorkflowTemplate; } return $arResult; } public static function GetNumberOfWorkflowTemplatesForDocumentType($documentType) { $n = CBPWorkflowTemplateLoader::GetList( array(), array("DOCUMENT_TYPE" => $documentType, "ACTIVE"=>"Y"), array() ); return $n; } /** * Method deletes workflow template. * * @param int $id - Template id. * @param array $documentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @param array $arErrors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). */ public static function DeleteWorkflowTemplate($id, $documentType, &$arErrors) { $arErrors = array(); $dbTemplates = CBPWorkflowTemplateLoader::GetList( array(), array("ID" => $id, "DOCUMENT_TYPE" => $documentType), false, false, array("ID") ); $arTemplate = $dbTemplates->Fetch(); if (!$arTemplate) { $arErrors[] = array( "code" => 0, "message" => str_replace("#ID#", $id, GetMessage("BPCGDOC_INVALID_WF_ID")), "file" => "" ); return; } try { CBPWorkflowTemplateLoader::Delete($id); } catch (Exception $e) { $arErrors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); } } /** * Method updates workflow template. * * @param int $id - Template id. * @param array $documentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @param array $arFields - Data for update. * @param array $arErrors - Errors array(array("code" => error_code, "message" => message, "file" => file_path), ...). */ public static function UpdateWorkflowTemplate($id, $documentType, $arFields, &$arErrors) { $arErrors = array(); $dbTemplates = CBPWorkflowTemplateLoader::GetList( array(), array("ID" => $id, "DOCUMENT_TYPE" => $documentType), false, false, array("ID") ); $arTemplate = $dbTemplates->Fetch(); if (!$arTemplate) { $arErrors[] = array( "code" => 0, "message" => str_replace("#ID#", $id, GetMessage("BPCGDOC_INVALID_WF_ID")), "file" => "" ); return; } try { CBPWorkflowTemplateLoader::Update($id, $arFields); } catch (Exception $e) { $arErrors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); } } /** * Method checks can user operate specified document with specified operation. * * @param int $operation - operation CBPCanUserOperateOperation. * @param int $userId - User id. * @param array $parameterDocumentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @param array $arParameters - Additional parameters. * @return bool */ public static function CanUserOperateDocument($operation, $userId, $parameterDocumentId, $arParameters = array()) { list($moduleId, $entity, $documentId) = CBPHelper::ParseDocumentId($parameterDocumentId); if (strlen($moduleId) > 0) CModule::IncludeModule($moduleId); if (class_exists($entity)) return call_user_func_array(array($entity, "CanUserOperateDocument"), array($operation, $userId, $documentId, $arParameters)); return false; } /** * Method checks can user operate specified document type with specified operation. * * @param int $operation - operation CBPCanUserOperateOperation. * @param int $userId - User id. * @param array $parameterDocumentType - Document type array(MODULE_ID, ENTITY, DOCUMENT_TYPE). * @param array $arParameters - Additional parameters. * @return bool */ public static function CanUserOperateDocumentType($operation, $userId, $parameterDocumentType, $arParameters = array()) { list($moduleId, $entity, $documentType) = CBPHelper::ParseDocumentId($parameterDocumentType); if (strlen($moduleId) > 0) CModule::IncludeModule($moduleId); if (class_exists($entity)) return call_user_func_array(array($entity, "CanUserOperateDocumentType"), array($operation, $userId, $documentType, $arParameters)); return false; } /** * Get document admin page URL. * * @param array $parameterDocumentId - Document id array(MODULE_ID, ENTITY, DOCUMENT_ID). * @return string - URL. */ public static function GetDocumentAdminPage($parameterDocumentId) { list($moduleId, $entity, $documentId) = CBPHelper::ParseDocumentId($parameterDocumentId); if (strlen($moduleId) > 0) CModule::IncludeModule($moduleId); if (class_exists($entity)) return call_user_func_array(array($entity, "GetDocumentAdminPage"), array($documentId)); return ""; } /** * @param array $parameterDocumentId Document Id. * @return mixed|string * @throws CBPArgumentNullException */ public static function getDocumentName($parameterDocumentId) { list($moduleId, $entity, $documentId) = CBPHelper::ParseDocumentId($parameterDocumentId); if (strlen($moduleId) > 0) CModule::IncludeModule($moduleId); if (class_exists($entity) && method_exists($entity, 'getDocumentName')) return call_user_func_array(array($entity, "getDocumentName"), array($documentId)); return ""; } /** * Method returns task array for specified user and specified workflow state. * Return array example: * array( * array( * "ID" => task_id, * "NAME" => task_name, * "DESCRIPTION" => task_description, * ), * . . . * ) * * @param int $userId - User id. * @param string $workflowId - Workflow id. * @return array - Tasks. */ public static function GetUserTasksForWorkflow($userId, $workflowId) { $userId = intval($userId); if ($userId <= 0) return array(); $workflowId = trim($workflowId); if (strlen($workflowId) <= 0) return array(); $arResult = array(); $dbTask = CBPTaskService::GetList( array(), array("WORKFLOW_ID" => $workflowId, "USER_ID" => $userId, 'STATUS' => CBPTaskStatus::Running), false, false, array("ID", "WORKFLOW_ID", "NAME", "DESCRIPTION") ); while ($arTask = $dbTask->GetNext()) $arResult[] = $arTask; return $arResult; } public static function PrepareFileForHistory($documentId, $fileId, $historyIndex) { return CBPHistoryService::PrepareFileForHistory($documentId, $fileId, $historyIndex); } public static function IsAdmin() { global $APPLICATION; return ($APPLICATION->GetGroupRight("bizproc") >= "W"); } public static function GetDocumentFromHistory($historyId, &$arErrors) { $arErrors = array(); try { $historyId = intval($historyId); if ($historyId <= 0) throw new CBPArgumentNullException("historyId"); return CBPHistoryService::GetById($historyId); } catch (Exception $e) { $arErrors[] = array( "code" => $e->getCode(), "message" => $e->getMessage(), "file" => $e->getFile()." [".$e->getLine()."]" ); } return null; } public static function GetAllowableUserGroups($parameterDocumentType) { list($moduleId, $entity, $documentType) = CBPHelper::ParseDocumentId($parameterDocumentType); if (strlen($moduleId) > 0) CModule::IncludeModule($moduleId); if (class_exists($entity)) { $result = call_user_func_array(array($entity, "GetAllowableUserGroups"), array($documentType)); $result1 = array(); foreach ($result as $key => $value) $result1[strtolower($key)] = $value; return $result1; } return array(); } public static function onAfterTMDayStart($data) { global $DB; if (!CModule::IncludeModule("im")) return; $userId = (int) $data['USER_ID']; $iterator = WorkflowInstanceTable::getList( array( 'select' => array(new \Bitrix\Main\Entity\ExpressionField('CNT', 'COUNT(\'x\')')), 'filter' => array( '=STARTED_BY' => $userId, '<OWNED_UNTIL' => date($DB->DateFormatToPHP(FORMAT_DATETIME), time() - WorkflowInstanceTable::LOCKED_TIME_INTERVAL) ), ) ); $row = $iterator->fetch(); if (!empty($row['CNT'])) { $path = IsModuleInstalled('bitrix24') ? '/bizproc/bizproc/?type=is_locked' : Main\Config\Option::get("bizproc", "locked_wi_path", '/services/bp/instances.php?type=is_locked'); CIMNotify::Add(array( 'FROM_USER_ID' => 0, 'TO_USER_ID' => $userId, "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM, "NOTIFY_MODULE" => "bizproc", "NOTIFY_EVENT" => "wi_locked", 'TITLE' => GetMessage('BPCGDOC_WI_LOCKED_NOTICE_TITLE'), 'MESSAGE' => GetMessage('BPCGDOC_WI_LOCKED_NOTICE_MESSAGE', array( '#PATH#' => $path, '#CNT#' => $row['CNT'] )) )); } } /** * Temporary notification for B24 portal Admins * Ex: CAgent::AddAgent("\CBPDocument::sendB24LimitsNotifyToAdmins();", "bizproc", "N", 43200); * @param int $ts * @return string */ public static function sendB24LimitsNotifyToAdmins($ts = 0) { if (time() > strtotime('2017-05-24')) return ''; if ($ts > 0 && $ts > time()) return '\CBPDocument::sendB24LimitsNotifyToAdmins('.(int)$ts.');'; if (!CModule::IncludeModule('bitrix24') || !CModule::IncludeModule("im")) return ''; $userIds = \CBitrix24::getAllAdminId(); if (!$userIds) return ''; global $DB; $dbResult = $DB->Query('SELECT COUNT(WS.ID) CNT FROM b_bp_workflow_state WS INNER JOIN b_bp_workflow_instance WI ON (WS.ID = WI.ID) INNER JOIN b_bp_workflow_template WT ON (WS.WORKFLOW_TEMPLATE_ID = WT.ID) WHERE WT.AUTO_EXECUTE <> '.(int)CBPDocumentEventType::Automation.' GROUP BY WS.MODULE_ID, WS.ENTITY, WS.DOCUMENT_ID HAVING CNT > 2 LIMIT 1'); $result = $dbResult->Fetch(); if (!empty($result)) { foreach ($userIds as $userId) { CIMNotify::Add(array( 'FROM_USER_ID' => 0, 'TO_USER_ID' => $userId, 'NOTIFY_TYPE' => IM_NOTIFY_SYSTEM, 'NOTIFY_MODULE' => 'bizproc', 'NOTIFY_EVENT' => 'wi_limits', 'TITLE' => GetMessage('BPCGDOC_WI_LOCKED_NOTICE_TITLE'), 'MESSAGE' => GetMessage('BPCGDOC_WI_B24_LIMITS_MESSAGE') )); } } $days = 3600*24*3; return '\CBPDocument::sendB24LimitsNotifyToAdmins('.(time() + $days).');'; } /** * Method returns map of document fields aliases. * @param array $fields Document fields. * @return array Aliases. */ public static function getDocumentFieldsAliasesMap($fields) { if (empty($fields) || !is_array($fields)) return array(); $aliases = array(); foreach ($fields as $key => $property) { if (isset($property['Alias'])) { $aliases[$property['Alias']] = $key; } } return $aliases; } /** * Bizproc expression checker. Required for usage from external modules! * Examples: {=Document:IBLOCK_ID}, {=Document:CREATED_BY>printable}, {=SequentialWorkflowActivity1:DocumentApprovers>user,printable} * @param $value * @return bool */ public static function IsExpression($value) { //go to internal alias return CBPActivity::isExpression($value); } public static function parseExpression($expression) { $matches = null; if (is_string($expression) && preg_match(CBPActivity::ValuePattern, $expression, $matches)) { $result = array( 'object' => $matches['object'], 'field' => $matches['field'], 'modifiers' => array() ); if (!empty($matches['mod1'])) $result['modifiers'][] = $matches['mod1']; if (!empty($matches['mod2'])) $result['modifiers'][] = $matches['mod2']; return $result; } return false; } public static function signParameters(array $parameters) { $signer = new Main\Security\Sign\Signer; $jsonData = Main\Web\Json::encode($parameters); return $signer->sign($jsonData, 'bizproc_wf_params'); } /** * @param string $unsignedData * @return array */ public static function unsignParameters($unsignedData) { $signer = new Main\Security\Sign\Signer; try { $unsigned = $signer->unsign($unsignedData, 'bizproc_wf_params'); $result = Main\Web\Json::decode($unsigned); } catch (\Exception $e) { $result = array(); } return $result; } public static function getTemplatesForStart($userId, $documentType, $documentId = null, array $parameters = array()) { if (!isset($parameters['UserGroups'])) { $parameters['UserGroups'] = CUser::GetUserGroup($userId); } if (!isset($parameters['DocumentStates'])) { $parameters['DocumentStates'] = static::GetDocumentStates($documentType, $documentId); } $op = CBPCanUserOperateOperation::StartWorkflow; $templates = array(); $dbWorkflowTemplate = CBPWorkflowTemplateLoader::GetList( array(), array( "DOCUMENT_TYPE" => $documentType, "ACTIVE" => "Y", '!AUTO_EXECUTE' => CBPDocumentEventType::Automation ), false, false, array("ID", "NAME", "DESCRIPTION", "PARAMETERS") ); while ($arWorkflowTemplate = $dbWorkflowTemplate->fetch()) { $parameters['WorkflowTemplateId'] = $arWorkflowTemplate['ID']; if ($documentId) { if (!CBPDocument::CanUserOperateDocument($op, $userId, $documentId, $parameters)) { continue; } } elseif (!CBPDocument::CanUserOperateDocumentType($op, $userId, $documentType, $parameters)) { continue; } $templates[] = array( 'id' => $arWorkflowTemplate['ID'], 'name' => $arWorkflowTemplate['NAME'], 'description' => $arWorkflowTemplate['DESCRIPTION'], 'hasParameters' => count($arWorkflowTemplate['PARAMETERS']) > 0, 'isConstantsTuned' => CBPWorkflowTemplateLoader::isConstantsTuned($arWorkflowTemplate["ID"]) ); } return $templates; } }