%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/activities/bitrix/startworkflowactivity/ |
Current File : //home/bitrix/www/bitrix/activities/bitrix/startworkflowactivity/startworkflowactivity.php |
<? use \Bitrix\Bizproc\FieldType; if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); class CBPStartWorkflowActivity extends CBPActivity implements IBPEventActivity, IBPActivityExternalEventListener { private static $templatesCache = array(); protected $wfId = null; public function __construct($name) { parent::__construct($name); $this->arProperties = array( 'Title' => '', 'DocumentId' => null, 'TemplateId' => 0, 'TemplateParameters' => array(), 'UseSubscription' => 'N', 'WorkflowId' => null ); $this->SetPropertiesTypes(array( 'WorkflowId' => array( 'Type' => 'string' ) )); } protected function ReInitialize() { parent::ReInitialize(); $this->WorkflowId = null; } public function OnExternalEvent($eventParameters = array()) { if ($this->executionStatus == CBPActivityExecutionStatus::Closed || $this->wfId != $eventParameters[0]) return; $this->Unsubscribe($this); $this->workflow->CloseActivity($this); } public function Subscribe(IBPActivityExternalEventListener $eventHandler) { if ($eventHandler == null) throw new Exception('eventHandler'); $schedulerService = $this->workflow->GetService("SchedulerService"); $schedulerService->SubscribeOnEvent($this->workflow->GetInstanceId(), $this->name, 'bizproc', "OnWorkflowComplete", $this->wfId); $this->workflow->AddEventHandler($this->name, $eventHandler); } public function Unsubscribe(IBPActivityExternalEventListener $eventHandler) { if ($eventHandler == null) throw new Exception('eventHandler'); $schedulerService = $this->workflow->GetService("SchedulerService"); $schedulerService->UnSubscribeOnEvent($this->workflow->GetInstanceId(), $this->name, 'bizproc', "OnWorkflowComplete", $this->wfId); $this->wfId = null; $this->workflow->RemoveEventHandler($this->name, $eventHandler); } public function Cancel() { if ($this->UseSubscription == 'Y') $this->Unsubscribe($this); return CBPActivityExecutionStatus::Closed; } public function HandleFault(Exception $exception) { if ($exception == null) throw new Exception("exception"); $status = $this->Cancel(); if ($status == CBPActivityExecutionStatus::Canceling) return CBPActivityExecutionStatus::Faulting; return $status; } public function Execute() { if (!$this->TemplateId) return CBPActivityExecutionStatus::Closed; $rootActivity = $this->GetRootActivity(); $rootDocumentId = $rootActivity->GetDocumentId(); $templateId = 0; if (method_exists($rootActivity, 'GetWorkflowTemplateId')) { $templateId = $rootActivity->GetWorkflowTemplateId(); if ((int) $templateId === (int) $this->TemplateId) { $this->WriteToTrackingService(GetMessage("BPSWFA_SELFSTART_ERROR")); return CBPActivityExecutionStatus::Closed; } } $template = self::getTemplate($this->TemplateId); if (!$template || !$this->DocumentId) return CBPActivityExecutionStatus::Closed; $documentId = $template['DOCUMENT_TYPE']; $documentId[2] = $this->DocumentId; //if Multiple, take only first Id if (is_array($documentId[2])) { reset($documentId[2]); $documentId[2] = current($documentId[2]); } /** @var CBPDocumentService $documentService */ $documentService = CBPRuntime::GetRuntime()->GetService('DocumentService'); $documentId = $documentService->normalizeDocumentId($documentId); $parameters = $this->TemplateParameters; if (!is_array($parameters)) $parameters = array(); if ($template['PARAMETERS']) { foreach ($template['PARAMETERS'] as $key => $parameter) { if ($parameter['Type'] == FieldType::USER && !empty($parameters[$key])) { $userIds = CBPHelper::ExtractUsers($parameters[$key], $rootDocumentId); if (is_array($userIds)) { foreach ($userIds as $i => $uid) $userIds[$i] = 'user_'.$uid; } $parameters[$key] = $userIds; } } } $parameters[CBPDocument::PARAM_TAGRET_USER] = $this->GetRootActivity()->{CBPDocument::PARAM_TAGRET_USER}; $this->wfId = CBPDocument::StartWorkflow( $template['ID'], $documentId, $parameters, $errors, array('workflowId' => $this->GetWorkflowInstanceId(), 'templateId' => $templateId) ); $this->WorkflowId = $this->wfId; $workflowIsCompleted = false; if ($this->wfId && !$errors) { $info = CBPRuntime::GetRuntime()->GetService('StateService')->getWorkflowStateInfo($this->wfId); if ($info['WORKFLOW_STATUS'] === null) { $workflowIsCompleted = true; } } if ($errors) { if ($this->UseSubscription == 'Y') throw new Exception($errors[0]['message']); else $this->WriteToTrackingService(GetMessage("BPSWFA_START_ERROR", array('#MESSAGE#' => $errors[0]['message']))); return CBPActivityExecutionStatus::Closed; } if ($workflowIsCompleted || $this->UseSubscription != 'Y' || !$this->wfId) { return CBPActivityExecutionStatus::Closed; } $this->Subscribe($this); return CBPActivityExecutionStatus::Executing; } public static function GetPropertiesDialog($documentType, $activityName, $arWorkflowTemplate, $arWorkflowParameters, $arWorkflowVariables, $currentValues = null, $formName = "") { $runtime = CBPRuntime::GetRuntime(); /** @var CBPDocumentService $documentService */ $documentService = $runtime->GetService("DocumentService"); $entities = $types = $templates = array(); $currentEntity = $currentType = $currentTemplateId = $templateParametersRender = ''; $entityIterator = CBPWorkflowTemplateLoader::GetList( array('MODULE_ID' => 'ASC'), array(), array('MODULE_ID', 'ENTITY'), false, array('MODULE_ID', 'ENTITY') ); while ($row = $entityIterator->fetch()) { //TODO: tmp if ($row['MODULE_ID'] === 'tasks') { continue; } $entityName = $documentService->getEntityName($row['MODULE_ID'], $row['ENTITY']); if ($entityName) { $entities[$row['MODULE_ID'].'@'.$row['ENTITY']] = $entityName; } } asort($entities); if (!is_array($currentValues)) { $currentActivity = &CBPWorkflowTemplateLoader::FindActivityByName($arWorkflowTemplate, $activityName); if (isset($currentActivity["Properties"]['DocumentId'])) $currentValues['document_id'] = $currentActivity["Properties"]['DocumentId']; if (isset($currentActivity["Properties"]['TemplateId'])) $currentValues['template_id'] = $currentActivity["Properties"]['TemplateId']; if (isset($currentActivity["Properties"]['TemplateParameters'])) $currentValues['template'] = $currentActivity["Properties"]['TemplateParameters']; if (isset($currentActivity["Properties"]['UseSubscription'])) $currentValues['use_subscription'] = $currentActivity["Properties"]['UseSubscription']; } else { $currentValues['template'] = self::extractTemplateParameterValues($documentType, $currentValues['template_id'], $currentValues); } if (!empty($currentValues['template_id'])) { $template = self::getTemplate($currentValues['template_id']); if ($template) { $currentEntity = implode('@', array($template['MODULE_ID'], $template['ENTITY'])); $currentType = implode('@', $template['DOCUMENT_TYPE']); $currentTemplateId = $template['ID']; if (!is_array($currentValues['template'])) $currentValues['template'] = array(); } } if ($currentEntity) $types = self::getTypesList($currentEntity); if ($currentTemplateId) { $templates = self::getTemplatesList($currentType); $templateParametersRender = self::renderTemplateParametersForm($documentType, $currentTemplateId, $formName, $currentValues['template']); } return $runtime->ExecuteResourceFile( __FILE__, "properties_dialog.php", array( 'isAdmin' => static::checkAdminPermissions(), 'documentType' => $documentType, 'entities' => $entities, 'types' => $types, 'templates' => $templates, 'documentId' => !empty($currentValues['document_id']) ? $currentValues['document_id'] : null, 'useSubscription' => $currentValues['use_subscription'], 'currentEntity' => $currentEntity, 'currentType' => $currentType, 'currentTemplateId' => $currentTemplateId, 'templateParametersRender' => $templateParametersRender, "formName" => $formName, ) ); } public static function GetPropertiesDialogValues($documentType, $activityName, &$workflowTemplate, &$arWorkflowParameters, &$arWorkflowVariables, $currentValues, &$errors) { $errors = array(); $properties = array( 'DocumentId' => $currentValues['document_id'], 'TemplateId' => $currentValues['template_id'], 'UseSubscription' => isset($currentValues['use_subscription']) && $currentValues['use_subscription'] == 'Y' ? 'Y' : 'N', 'TemplateParameters' => self::extractTemplateParameterValues($documentType, $currentValues['template_id'], $currentValues, $errors), ); if (count($errors) > 0) return false; $errors = self::ValidateProperties($properties, new CBPWorkflowTemplateUser(CBPWorkflowTemplateUser::CurrentUser)); if (count($errors) > 0) return false; $currentActivity = &CBPWorkflowTemplateLoader::FindActivityByName($workflowTemplate, $activityName); $currentActivity["Properties"] = $properties; return true; } public static function ValidateProperties($testProperties = array(), CBPWorkflowTemplateUser $user = null) { $errors = array(); if (!static::checkAdminPermissions()) { $errors[] = array( "code" => "AccessDenied", "parameter" => "Admin", "message" => GetMessage("BPSWFA_ACCESS_DENIED") ); return array_merge($errors, parent::ValidateProperties($testProperties, $user)); } if (empty($testProperties['DocumentId'])) { $errors[] = array("code" => "NotExist", "parameter" => "DocumentId", "message" => GetMessage("BPSWFA_ERROR_DOCUMENT_ID")); } if (empty($testProperties['TemplateId'])) { $errors[] = array("code" => "NotExist", "parameter" => "TemplateId", "message" => GetMessage("BPSWFA_ERROR_TEMPLATE")); } $template = self::getTemplate($testProperties['TemplateId']); if ($template && $template['PARAMETERS']) { foreach ($template['PARAMETERS'] as $key => $parameter) { $value = isset($testProperties['TemplateParameters'][$key]) ? $testProperties['TemplateParameters'][$key] : null; if (CBPHelper::getBool($parameter['Required']) && CBPHelper::isEmptyValue($value)) { $errors[] = array( "code" => "NotExist", "parameter" => "TemplateParameters_".$key, "message" => GetMessage("BPSWFA_TEMPLATE_PARAMETERS_ERROR", array('#NAME#' => $parameter['Name'])) ); } } } return array_merge($errors, parent::ValidateProperties($testProperties, $user)); } public static function getAjaxResponse($request) { $result = false; if (!static::checkAdminPermissions()) return $result; if (!empty($request['entity'])) { $result = array('types' => self::getTypesList($request['entity'])); } if (!empty($request['document'])) { $result = array('templates' => self::getTemplatesList($request['document'])); } if (!empty($request['template_id']) && !empty($request['form_name'])) { $result = self::renderTemplateParametersForm($request['document_type'], $request['template_id'], $request['form_name']); } return $result; } private static function checkAdminPermissions() { $user = new CBPWorkflowTemplateUser(CBPWorkflowTemplateUser::CurrentUser); return $user->isAdmin(); } private static function getTypesList($entityId) { $runtime = CBPRuntime::GetRuntime(); /** @var CBPDocumentService $documentService */ $documentService = $runtime->GetService("DocumentService"); list($moduleId, $entity) = explode('@', $entityId); $result = array(); $iterator = CBPWorkflowTemplateLoader::GetList( array('MODULE_ID' => 'ASC'), array('MODULE_ID' => $moduleId, 'ENTITY' => $entity), array('MODULE_ID', 'ENTITY', 'DOCUMENT_TYPE'), false, array('MODULE_ID', 'ENTITY', 'DOCUMENT_TYPE') ); while ($row = $iterator->fetch()) { $name = $documentService->getDocumentTypeName($row['DOCUMENT_TYPE']); if ($name) $result[] = array('name' => $name, 'id' => implode('@', $row['DOCUMENT_TYPE'])); } return $result; } private static function getTemplatesList($document) { $result = array(); $iterator = CBPWorkflowTemplateLoader::GetList( array('NAME' => 'ASC'), array( 'DOCUMENT_TYPE' => explode('@', $document), '!AUTO_EXECUTE' => CBPDocumentEventType::Automation ), false, false, array('ID', 'NAME') ); while ($row = $iterator->fetch()) { $result[] = array('name' => $row['NAME'], 'id' => $row['ID']); } return $result; } private static function getTemplate($id) { $id = (int) $id; if (!isset(self::$templatesCache[$id])) { $iterator = CBPWorkflowTemplateLoader::GetList(array(), array("ID" => $id), false, false, array("ID", 'NAME', "MODULE_ID", "ENTITY", "DOCUMENT_TYPE", 'PARAMETERS')); self::$templatesCache[$id] = $iterator->fetch(); } return self::$templatesCache[$id]; } private static function extractTemplateParameterValues($documentType, $templateId, $request, &$errors = array()) { $template = self::getTemplate($templateId); $result = array(); if ($template && $template['PARAMETERS']) { $runtime = CBPRuntime::GetRuntime(); /** @var CBPDocumentService $documentService */ $documentService = $runtime->GetService("DocumentService"); foreach ($template['PARAMETERS'] as $key => $parameter) { $dt = $parameter['Type'] == FieldType::USER ? $documentType : $template['DOCUMENT_TYPE']; $result[$key] = $documentService->GetFieldInputValue( $dt, $parameter, 'bpswfatemplate_'.$key, $request, $errors ); } } return $result; } private static function renderTemplateParametersForm($documentType, $templateId, $formName, array $currentValues = array()) { $result = ''; $template = self::getTemplate($templateId); if ($template) { if (!empty($template['PARAMETERS'])) { $runtime = CBPRuntime::GetRuntime(); /** @var CBPDocumentService $documentService */ $documentService = $runtime->GetService("DocumentService"); $result .= '<tr><td colspan="2" align="center">'.GetMessage('BPSWFA_TEMPLATE_PARAMETERS').':</td></tr>'; foreach ($template['PARAMETERS'] as $key => $parameter) { $parameterKeyExt = 'bpswfatemplate_'.$key; $parameterValue = isset($currentValues[$key]) ? $currentValues[$key] : $parameter['Default']; $dt = $parameter['Type'] == FieldType::USER ? $documentType : $template['DOCUMENT_TYPE']; $result .= '<tr> <td align="right" width="40%" valign="top" class="adm-detail-content-cell-l">' .($parameter['Required'] ? '<span class="adm-required-field">*' : '').htmlspecialcharsbx($parameter['Name']) .($parameter['Required'] ? '</span>' : '').':</td> <td width="60%" valign="top" class="adm-detail-content-cell-r">'.$documentService->GetFieldInputControl( $dt, $parameter, array('Form' => $formName, 'Field' => $parameterKeyExt), $parameterValue, true ) .'</td></tr>'; } } } return $result; } }