403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/bizproc/lib/Task/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/bizproc/lib/Task/ExternalEventTask.php
<?php

namespace Bitrix\Bizproc\Task;

use Bitrix\Bizproc\Error;
use Bitrix\Bizproc\FieldType;
use Bitrix\Bizproc\Result;
use Bitrix\Bizproc\Task\Data\ExternalEventTask\ExternalEventTaskData;
use Bitrix\Bizproc\Task\Data\ExternalEventTask\UsersByStatus;
use Bitrix\Bizproc\Task\Data\TaskData;
use Bitrix\Bizproc\Task\Dto\AddTaskDto;
use Bitrix\Bizproc\Task\Dto\CompleteTaskDto;
use Bitrix\Bizproc\Task\Dto\DeleteTaskDto;
use Bitrix\Bizproc\Task\Dto\ExternalEventTask\AddCommandDto;
use Bitrix\Bizproc\Task\Dto\ExternalEventTask\RemoveCommandDto;
use Bitrix\Bizproc\Task\Dto\MarkCompletedTaskDto;
use Bitrix\Bizproc\Task\Dto\TaskSettings;
use Bitrix\Bizproc\Task\Dto\UpdateTaskDto;
use Bitrix\Bizproc\Workflow\Entity\WorkflowUserTable;
use Bitrix\Main\Localization\Loc;

final class ExternalEventTask extends BaseTask
{
	/**
	 * @var ExternalEventTaskData $task
	 */
	protected TaskData $task;

	private const BUTTON_NAME = 'execute';
	private const FIELD_NAME = 'command';
	private const USER_STATUS = \CBPTaskUserStatus::Ok;

	public function __construct(TaskData $task, int $userId)
	{
		parent::__construct($task, $userId);

		$this->task = ExternalEventTaskData::createFromArray($task->getData());
	}

	public static function getAssociatedActivity(): string
	{
		return 'HandleExternalEventActivity';
	}

	public static function addToTask(AddCommandDto $command): ?ExternalEventTask
	{
		$runtime = \CBPRuntime::getRuntime();
		if (!$runtime->hasWorkflow($command->workflowId))
		{
			return null;
		}

		$currentTask = self::getCurrentTask($command->workflowId);
		if ($currentTask)
		{
			$externalTask = new self(TaskData::createFromArray($currentTask), 0);

			$users = $externalTask->getTaskUsersByStatus();
			if ($users)
			{
				$intersect = array_intersect($users->completed, $command->userIds);
				if ($intersect)
				{
					$externalTask->markTaskUnCompleted($intersect);
					$externalTask->addUsersToCompletedUsersParameter($intersect);
				}

				$allUsers = array_merge($users->completed, $users->waiting);
				$diff = array_diff($command->userIds, $allUsers);
				if ($diff)
				{
					$newUsers = array_merge($allUsers, $command->userIds);
					$externalTask->update(new UpdateTaskDto(users: $newUsers));
				}
			}

			return $externalTask;
		}

		$workflow = $runtime->getWorkflow($command->workflowId);

		return self::add(new AddTaskDto(
			workflowId: $command->workflowId,
			complexDocumentId: $workflow->getDocumentId(),
			userIds: $command->userIds,
			activityName: $command->id,
		));
	}

	public static function add(Dto\AddTaskDto $task): ?ExternalEventTask
	{
		return parent::add(new AddTaskDto(
			workflowId: $task->workflowId,
			complexDocumentId: $task->complexDocumentId,
			userIds: $task->userIds,
			activityName: $task->activityName,
			settings: new TaskSettings(
				name: Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_NAME') ?? '',
				description: Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_DESCRIPTION') ?? '',
				isInline: false,
				delegationType: \CBPTaskDelegationType::ExactlyNone,
				parameters: ['COMPLETED_USERS' => []],
			),
		));
	}

	public static function getCurrentTask(string $workflowId): bool|array
	{
		if (!$workflowId)
		{
			return false;
		}

		$taskService = self::getTaskService();

		return $taskService::getList(
			[],
			[
				'WORKFLOW_ID' => $workflowId,
				'ACTIVITY' => self::getAssociatedActivity(),
				'STATUS' => \CBPTaskStatus::Running,
			],
			false,
			false,
			['ID', 'WORKFLOW_ID', 'PARAMETERS']
		)->fetch();
	}

	public function markCompleted(MarkCompletedTaskDto $markCompletedData): Result
	{
		if ($this->userId <= 0)
		{
			return Result::createError(new Error('negative userId', 'negative userId'));
		}

		if (!$this->getEvents())
		{
			$this->markTaskCompleted([$this->userId]);
		}
		else
		{
			$this->addUsersToCompletedUsersParameter([$this->userId]);
		}

		return Result::createOk();
	}

	private function addUsersToCompletedUsersParameter(array $userIds): void
	{
		$completedUsers = $this->task->getCompletedUsersParameter();
		if ($completedUsers !== null && $userIds)
		{
			$isAdded = false;
			foreach ($userIds as $userId)
			{
				if (!in_array($userId, $completedUsers, true))
				{
					$isAdded = true;
					$completedUsers[] = $userId;
				}
			}

			if ($isAdded)
			{
				$this->task->setCompletedUsersParameter($completedUsers);
				$this->update(new UpdateTaskDto(parameters: $this->task->getParameters()));
			}
		}
	}

	public function removeFromTask(RemoveCommandDto $command): Result
	{
		$users = $this->getTaskUsersByStatus($command->userIds);
		if (!$users) // no users, no task
		{
			return Result::createOk();
		}

		if (!$users->completed && !$users->waiting && !$users->markCompleted)
		{
			$this->delete(new DeleteTaskDto());

			return Result::createOk();
		}

		if ($users->markCompleted)
		{
			$this->markTaskCompleted($users->markCompleted);
		}

		if (!$users->waiting)
		{
			$this->complete(new CompleteTaskDto());

			return Result::createOk();
		}

		$actualUsers = array_merge($users->completed, $users->waiting, $users->markCompleted);
		$this->update(new UpdateTaskDto(users: $actualUsers));

		return Result::createOk();
	}

	public function complete(CompleteTaskDto $completeData): Result
	{
		return parent::complete(new CompleteTaskDto(status: \CBPTaskStatus::CompleteOk));
	}

	private function getTaskUsersByStatus(array $removeUsers = []): ?UsersByStatus
	{
		$taskService = self::getTaskService();

		$taskUsers = $taskService::getTaskUsers($this->getId())[$this->getId()] ?? [];
		if (!$taskUsers)
		{
			return null;
		}

		$state = $this->getWorkflowState();
		if (!$state)
		{
			return null;
		}

		return new UsersByStatus($taskUsers, $state, $removeUsers, $this->task->getCompletedUsersParameter());
	}

	private function markTaskCompleted(array $userIds): void
	{
		$taskService = self::getTaskService();
		foreach ($userIds as $userId)
		{
			$taskService->markCompleted($this->getId(), $userId, self::USER_STATUS);
		}
	}

	private function markTaskUnCompleted(array $userIds): void
	{
		$taskService = self::getTaskService();
		$taskService->markUnCompleted($this->getId(), $userIds);
	}

	public function getTaskControls(): array
	{
		$field = array_merge(
			$this->getAllowableCommandFieldProperty(),
			[
				'Id' => self::FIELD_NAME,
				'Name' => Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_FIELD_NAME') ?? '',
			]
		);

		return [
			'BUTTONS' => [
				[
					'TYPE' => 'submit',
					'TARGET_USER_STATUS' => self::USER_STATUS,
					'NAME' => self::BUTTON_NAME,
					'VALUE' => 'Y',
					'TEXT' => Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_SEND_BUTTON_NAME') ?? '',
				],
			],
			'FIELDS' => [$field],
		];
	}

	private function getAllowableCommandFieldProperty(): array
	{
		$options = ['' => Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_DEFAULT_OPTION_NAME')];

		$events = $this->getEvents();
		if ($events)
		{
			$options = array_merge($options, $events);
		}

		return [
			'Type' => FieldType::SELECT,
			'Required' => true,
			'Options' => $options,
			'Settings' => ['ShowEmptyValue' => false],
		];
	}

	public function postTaskForm(array $request): Result
	{
		$fields = $request['fields'] ?? $request;

		$command = trim($fields[self::FIELD_NAME] ?? '');
		if (empty($command))
		{
			if (
				!$this->getEvents()
				&& $this->removeFromTask(new RemoveCommandDto(id: $command, userIds: [$this->userId]))->isSuccess()
			)
			{
				WorkflowUserTable::syncOnTaskUpdated($this->task->workflowId);
			}

			return Result::createOk();
		}

		if (!$this->validateCommand($command))
		{
			return Result::createError(new Error(
				Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_ERROR_UNKNOWN_COMMAND') ?? '',
				'unknown_command'
			));
		}

		$eventParameters = ['Groups' => $this->getUserGroups($this->userId), 'User' => $this->userId];

		\CBPRuntime::sendExternalEvent($this->task->workflowId, $command, $eventParameters);

		return Result::createOk();
	}

	private function validateCommand(string $command): bool
	{
		return array_key_exists($command, $this->getEvents());
	}

	private function getEvents(): array
	{
		if ($this->userId > 0)
		{
			$state = $this->getWorkflowState();
			if ($state)
			{
				return $this->getAllowableEventsFromState($this->userId, $state);
			}
		}

		return [];
	}

	private function getWorkflowState(): ?array
	{
		$workflowId = $this->task->workflowId;
		$documentId = $this->task->getDocumentId();

		if ($workflowId !== '' && $documentId)
		{
			$state = \CBPDocument::getDocumentState($documentId, $workflowId)[$workflowId] ?? null;
			if ($state)
			{
				return $state;
			}
		}

		return null;
	}

	private function getAllowableEventsFromState(int $userId, array $state): array
	{
		$allowableEvents = \CBPDocument::getAllowableEvents($userId, $this->getUserGroups($userId), $state, true);
		$events = [];
		foreach ($allowableEvents as $event)
		{
			$events[$event['NAME']] = $event['TITLE'];
		}

		return $events;
	}

	private function getUserGroups(int $userId): array
	{
		$currentUser = \Bitrix\Main\Engine\CurrentUser::get();

		return (int)$currentUser->getId() === $userId ? $currentUser->getUserGroups() : \CUser::GetUserGroup($userId);
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit