PageRenderTime 50ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/bizproc/lib/controller/script.php

https://gitlab.com/alexprowars/bitrix
PHP | 338 lines | 278 code | 56 blank | 4 comment | 23 complexity | c84589f709d27f79ef2a289aaeaf9a7b MD5 | raw file
  1. <?php
  2. namespace Bitrix\Bizproc\Controller;
  3. use Bitrix\Bizproc\FieldType;
  4. use Bitrix\Bizproc\Script\Entity\ScriptTable;
  5. use Bitrix\Bizproc\Script\Entity\ScriptQueueDocumentTable;
  6. use Bitrix\Bizproc\Script\Entity\ScriptQueueTable;
  7. use Bitrix\Bizproc\Script\Queue;
  8. use Bitrix\Main;
  9. use Bitrix\Main\Localization\Loc;
  10. use Bitrix\Bizproc\Script\Manager;
  11. class Script extends Base
  12. {
  13. public const START_STATUS_NOT_PERMITTED = 'NOT_PERMITTED';
  14. public const START_STATUS_NOT_EXISTS = 'NOT_EXISTS';
  15. public const START_STATUS_NO_DOCUMENTS = 'NO_DOCUMENTS';
  16. public const START_STATUS_FILL_PARAMETERS = 'FILL_PARAMETERS';
  17. public const START_STATUS_INVALID_PARAMETERS = 'INVALID_PARAMETERS';
  18. public const START_STATUS_QUEUED = 'QUEUED';
  19. //TODO: use dynamic rules such as b24 limitation api
  20. private const LIMIT_DOCUMENT_ID = 1000;
  21. private const LIMIT_QUEUES = 1;
  22. public function startAction($scriptId, array $documentIds, array $parameters = [])
  23. {
  24. $userId = $this->getCurrentUser()->getId();
  25. if (!Manager::canUserStartScript($scriptId, $userId))
  26. {
  27. return [
  28. 'status' => static::START_STATUS_NOT_PERMITTED,
  29. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_START')
  30. ];
  31. }
  32. $documentIds = array_unique($documentIds);
  33. if (count($documentIds) > $this->getDocumentIdLimit())
  34. {
  35. return [
  36. 'status' => static::START_STATUS_NOT_PERMITTED,
  37. 'error' => Loc::getMessage(
  38. 'BIZPROC_CONTROLLER_SCRIPT_ERROR_DOCUMENT_ID_LIMIT',
  39. [
  40. '#LIMIT#' => $this->getDocumentIdLimit(),
  41. '#SELECTED#' => count($documentIds),
  42. ]
  43. )
  44. ];
  45. }
  46. $script = Manager::getById($scriptId);
  47. if (!$script)
  48. {
  49. return [
  50. 'status' => static::START_STATUS_NOT_EXISTS,
  51. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  52. ];
  53. }
  54. if (!$script->getActive())
  55. {
  56. return [
  57. 'status' => static::START_STATUS_NOT_PERMITTED,
  58. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_START_INACTIVE')
  59. ];
  60. }
  61. $queuesCnt = ScriptTable::getActiveQueueCount($scriptId);
  62. if ($queuesCnt >= $this->getQueuesLimit())
  63. {
  64. return [
  65. 'status' => static::START_STATUS_NOT_PERMITTED,
  66. 'error' => Loc::getMessage(
  67. 'BIZPROC_CONTROLLER_SCRIPT_ERROR_QUEUES_LIMIT',
  68. [
  69. '#LIMIT#' => $this->getQueuesLimit(),
  70. '#CNT#' => $queuesCnt,
  71. ]
  72. )
  73. ];
  74. }
  75. $script->fill('WORKFLOW_TEMPLATE');
  76. /** @var \Bitrix\Bizproc\Workflow\Template\Tpl $tpl */
  77. $tpl = $script->getWorkflowTemplate();
  78. $templateParameters = $tpl->getParameters();
  79. if ($templateParameters)
  80. {
  81. if (empty($parameters))
  82. {
  83. return [
  84. 'status' => static::START_STATUS_FILL_PARAMETERS,
  85. 'parameters' => self::convertTemplateParameters($templateParameters, $tpl->getDocumentComplexType()),
  86. 'documentType' => $tpl->getDocumentComplexType(),
  87. 'scriptName' => $script->getName(),
  88. ];
  89. }
  90. $parameters = \CBPWorkflowTemplateLoader::CheckWorkflowParameters(
  91. $templateParameters,
  92. $parameters,
  93. $tpl->getDocumentComplexType(),
  94. $errors
  95. );
  96. if (!empty($errors))
  97. {
  98. return [
  99. 'status' => static::START_STATUS_INVALID_PARAMETERS,
  100. 'error' => reset($errors)['message']
  101. ];
  102. }
  103. }
  104. //TODO: move logic to Manager
  105. $addResult = ScriptQueueTable::add([
  106. 'SCRIPT_ID' => $scriptId,
  107. 'STARTED_DATE' => new Main\Type\DateTime(),
  108. 'STARTED_BY' => $userId,
  109. 'STATUS' => Queue\Status::QUEUED,
  110. 'MODIFIED_DATE' => new Main\Type\DateTime(),
  111. 'WORKFLOW_PARAMETERS' => $parameters,
  112. ]);
  113. $queueId = null;
  114. if ($addResult->isSuccess())
  115. {
  116. $queueId = $addResult->getId();
  117. $documentRows = array_map(
  118. function ($id) use ($queueId)
  119. {
  120. return [
  121. 'QUEUE_ID' => $queueId,
  122. 'DOCUMENT_ID' => $id,
  123. 'STATUS' => Queue\Status::QUEUED,
  124. ];
  125. },
  126. $documentIds
  127. );
  128. ScriptQueueDocumentTable::addMulti($documentRows, true);
  129. }
  130. Queue\Stepper::bind(1, [$queueId, $scriptId]);
  131. return [
  132. 'status' => static::START_STATUS_QUEUED,
  133. 'queueId' => $queueId,
  134. ];
  135. }
  136. public function deleteAction($scriptId)
  137. {
  138. $userId = $this->getCurrentUser()->getId();
  139. $script = Manager::getById($scriptId);
  140. if (!$script)
  141. {
  142. return [
  143. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  144. ];
  145. }
  146. if (!Manager::canUserEditScript($script->getId(), $userId))
  147. {
  148. return [
  149. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_DELETE_SCRIPT')
  150. ];
  151. }
  152. $result = Manager::deleteScript($scriptId);
  153. if (!$result->isSuccess())
  154. {
  155. return ['error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_DELETE_RUNNING_SCRIPT')];
  156. }
  157. return ['status' => 'success'];
  158. }
  159. public function activateAction(int $scriptId)
  160. {
  161. $script = Manager::getById($scriptId);
  162. if (!$script)
  163. {
  164. return [
  165. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  166. ];
  167. }
  168. $userId = $this->getCurrentUser()->getId();
  169. if (!Manager::canUserEditScript($script->getId(), $userId))
  170. {
  171. return [
  172. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_UPDATE_SCRIPT')
  173. ];
  174. }
  175. Manager::activateScript($scriptId);
  176. return ['status' => 'success'];
  177. }
  178. public function deactivateAction(int $scriptId)
  179. {
  180. $script = Manager::getById($scriptId);
  181. if (!$script)
  182. {
  183. return [
  184. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  185. ];
  186. }
  187. $userId = $this->getCurrentUser()->getId();
  188. if (!Manager::canUserEditScript($script->getId(), $userId))
  189. {
  190. return [
  191. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_UPDATE_SCRIPT')
  192. ];
  193. }
  194. Manager::deactivateScript($scriptId);
  195. return ['status' => 'success'];
  196. }
  197. public function terminateQueueAction(int $queueId)
  198. {
  199. $userId = $this->getCurrentUser()->getId();
  200. $queue = Manager::getQueueById($queueId);
  201. if (!$queue)
  202. {
  203. return [
  204. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  205. ];
  206. }
  207. if (!Manager::canUserStartScript($queue->getScriptId(), $userId))
  208. {
  209. return [
  210. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_TERMINATE')
  211. ];
  212. }
  213. if ($queue->getStatus() > Queue\Status::EXECUTING)
  214. {
  215. return [
  216. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_TERMINATE_FINISHED')
  217. ];
  218. }
  219. Manager::terminateQueue($queueId, $userId);
  220. return ['status' => 'success'];
  221. }
  222. public function execQueueAction(int $queueId)
  223. {
  224. $queue = Manager::getQueueById($queueId);
  225. if (!$queue)
  226. {
  227. return [
  228. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  229. ];
  230. }
  231. //emulate Stepper step
  232. $stepper = Queue\Stepper::createInstance();
  233. $option = [];
  234. $stepper->setOuterParams([$queueId, $queue->getScriptId()]);
  235. $result = $stepper->execute($option);
  236. return ['status' => 'success', 'finished' => ($result === $stepper::FINISH_EXECUTION)];
  237. }
  238. public function deleteQueueAction(int $queueId)
  239. {
  240. $userId = $this->getCurrentUser()->getId();
  241. $queue = Manager::getQueueById($queueId);
  242. if (!$queue)
  243. {
  244. return [
  245. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_NOT_EXISTS')
  246. ];
  247. }
  248. if (!Manager::canUserStartScript($queue->getScriptId(), $userId))
  249. {
  250. return [
  251. 'error' => Loc::getMessage('BIZPROC_CONTROLLER_SCRIPT_CANT_DELETE_QUEUE')
  252. ];
  253. }
  254. Manager::deleteQueue($queueId, $userId);
  255. return ['status' => 'success'];
  256. }
  257. private function getDocumentIdLimit(): int
  258. {
  259. return self::LIMIT_DOCUMENT_ID;
  260. }
  261. private function getQueuesLimit(): int
  262. {
  263. return self::LIMIT_QUEUES;
  264. }
  265. private static function convertTemplateParameters(array $parameters, array $documentType): array
  266. {
  267. $result = [];
  268. foreach ($parameters as $id => $parameter)
  269. {
  270. $parameter = FieldType::normalizeProperty($parameter);
  271. $parameter['Id'] = $id;
  272. if ($parameter['Type'] === 'user')
  273. {
  274. $parameter['Default'] = \CBPHelper::UsersArrayToString(
  275. $parameter['Default'], [], $documentType
  276. );
  277. }
  278. $result[] = $parameter;
  279. }
  280. return $result;
  281. }
  282. }