%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/activities/bitrix/startworkflowactivity/
Upload File :
Create Path :
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;
	}
}

Zerion Mini Shell 1.0