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/ilovecveti.ru/bitrix/modules/bizproc/lib/workflow/entity/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/ilovecveti.ru/bitrix/modules/bizproc/lib/workflow/entity/workflowusertable.php
<?php

namespace Bitrix\Bizproc\Workflow\Entity;

use Bitrix\Main\Application;
use Bitrix\Main\ORM\Data\DataManager;
use Bitrix\Main\ORM\Fields\IntegerField;
use Bitrix\Main\ORM\Fields\StringField;
use Bitrix\Main\ORM\Fields\DatetimeField;
use Bitrix\Main\ORM\Fields\Relations\Reference;
use Bitrix\Main\ORM\Query\Join;
use Bitrix\Main\Type\DateTime;
use Bitrix\Bizproc\Integration\Push\WorkflowPush;

/**
 * Class WorkflowUserTable
 *
 * DO NOT WRITE ANYTHING BELOW THIS
 *
 * <<< ORMENTITYANNOTATION
 * @method static EO_WorkflowUser_Query query()
 * @method static EO_WorkflowUser_Result getByPrimary($primary, array $parameters = [])
 * @method static EO_WorkflowUser_Result getById($id)
 * @method static EO_WorkflowUser_Result getList(array $parameters = [])
 * @method static EO_WorkflowUser_Entity getEntity()
 * @method static \Bitrix\Bizproc\Workflow\Entity\EO_WorkflowUser createObject($setDefaultValues = true)
 * @method static \Bitrix\Bizproc\Workflow\Entity\EO_WorkflowUser_Collection createCollection()
 * @method static \Bitrix\Bizproc\Workflow\Entity\EO_WorkflowUser wakeUpObject($row)
 * @method static \Bitrix\Bizproc\Workflow\Entity\EO_WorkflowUser_Collection wakeUpCollection($rows)
 */
class WorkflowUserTable extends DataManager
{
	public const WORKFLOW_STATUS_ACTIVE = 0;
	public const WORKFLOW_STATUS_COMPLETED = 1;

	public const TASK_STATUS_NONE = 0;
	public const TASK_STATUS_COMPLETED = 1;
	public const TASK_STATUS_ACTIVE = 2;


	public static function getTableName()
	{
		return 'b_bp_workflow_user';
	}

	public static function getMap()
	{
		return [
			(new IntegerField('USER_ID'))
				->configurePrimary()
			,
			(new StringField('WORKFLOW_ID'))
				->configureSize(32)
				->configurePrimary()
			,
			(new IntegerField('IS_AUTHOR'))
				->configureNullable(false)
			,
			(new IntegerField('WORKFLOW_STATUS'))
				->configureNullable(false)
			,
			(new IntegerField('TASK_STATUS'))
				->configureNullable(false)
			,
			(new DatetimeField('MODIFIED'))
				->configureNullable(false)
			,
			(new Reference(
				'FILTER',
				WorkflowFilterTable::class,
				Join::on('this.WORKFLOW_ID', 'ref.WORKFLOW_ID')
			))
				->configureJoinType(Join::TYPE_INNER)
			,
			(new Reference(
				'COMMENTS',
				WorkflowUserCommentTable::class,
				Join::on('this.WORKFLOW_ID', 'ref.WORKFLOW_ID')
					->whereColumn('this.USER_ID', 'ref.USER_ID')
			)),
		];
	}

	public static function syncOnWorkflowUpdated(\CBPWorkflow $workflow, int $status): void
	{
		$workflowId = $workflow->getInstanceId();
		$users = static::getTaskUsers($workflowId);
		$hasUsers = !empty($users) || static::hasStoredUsers($workflowId);

		if (!$hasUsers && !static::isLiveFeedProcess($workflow->getDocumentId()))
		{
			return;
		}

		$authorId = $workflow->getStartedBy();
		$workflowStatus = \CBPWorkflowStatus::isFinished($status)
			? static::WORKFLOW_STATUS_COMPLETED
			: static::WORKFLOW_STATUS_ACTIVE
		;

		if ($authorId)
		{
			$users[$authorId]['IS_AUTHOR'] ??= 1;
		}

		foreach ($users as $id => $user)
		{
			$users[$id]['WORKFLOW_STATUS'] = $workflowStatus;
			$users[$id]['IS_AUTHOR'] ??= 0;
		}

		static::syncUsers($workflowId, $users);
	}

	public static function syncOnTaskUpdated(string $workflowId): array
	{
		$users = static::getTaskUsers($workflowId);

		return static::syncUsers($workflowId, $users);
	}

	public static function getUserIdsByWorkflowId(string $workflowId): array
	{
		$result = static::getList([
			'select' => ['USER_ID'],
			'filter' => ['=WORKFLOW_ID' => $workflowId],
		])->fetchAll();

		$ids = array_column($result, 'USER_ID');
		return array_map(
			static fn($id) => (int)$id,
			$ids,
		);
	}

	public static function touchWorkflowUsers(string $workflowId, array $userIds): void
	{
		static::updateOnSync(
			$workflowId,
			array_fill_keys($userIds, [/* MODIFIED = new DateTime() */])
		);
	}

	private static function isLiveFeedProcess(array $documentId): bool
	{
		return ($documentId[0] ?? '') === 'lists' && ($documentId[1] ?? '') === 'BizprocDocument';
	}

	private static function getTaskUsers(string $workflowId): array
	{
		$taskUsers = \CBPTaskService::getWorkflowUsers($workflowId);
		$users = [];

		foreach ($taskUsers as $id => $taskStatus)
		{
			$users[$id] = [
				'TASK_STATUS' => $taskStatus === \CBPTaskUserStatus::Waiting
					? static::TASK_STATUS_ACTIVE
					: static::TASK_STATUS_COMPLETED
				,
			];
		}

		$authorId = static::getAuthorId($workflowId);
		if ($authorId && !isset($users[$authorId]))
		{
			$users[$authorId] = [
				'TASK_STATUS' => static::TASK_STATUS_NONE,
			];
		}

		return $users;
	}

	private static function syncUsers(string $workflowId, array $users): array
	{
		$stored = static::getStoredUsers($workflowId);

		$toDelete = array_diff_key($stored, $users);
		$toAdd = array_diff_key($users, $stored);
		$toUpdate = array_intersect_key($users, $stored);

		self::deleteOnSync($workflowId, $toDelete);
		self::addOnSync($workflowId, $toAdd);
		self::updateOnSync($workflowId, $toUpdate, $stored);

		return [array_keys($toAdd), array_keys($toUpdate), array_keys($toDelete)];
	}

	private static function getAuthorId(string $workflowId): int
	{
		$result = static::getList([
			'select' => ['USER_ID'],
			'filter' => [
				'=WORKFLOW_ID' => $workflowId,
				'=IS_AUTHOR' => 1,
			],
		])->fetch();

		return (int)($result['USER_ID'] ?? 0);
	}

	private static function deleteOnSync(string $workflowId, array $toDelete): void
	{
		if (!$toDelete)
		{
			return;
		}

		$deleted = array_keys($toDelete);
		foreach ($deleted as $userId)
		{
			static::delete([
				'USER_ID' => $userId,
				'WORKFLOW_ID' => $workflowId,
			]);
		}

		WorkflowUserCommentTable::deleteUsersByWorkflow($deleted, $workflowId);
		WorkflowPush::pushDeleted($workflowId, $deleted);
	}

	private static function addOnSync(string $workflowId, array $toAdd): void
	{
		if (!$toAdd)
		{
			return;
		}

		foreach ($toAdd as $userId => $user)
		{
			static::add([
				'USER_ID' => $userId,
				'WORKFLOW_ID' => $workflowId,
				'IS_AUTHOR' => $user['IS_AUTHOR'] ?? 0,
				'WORKFLOW_STATUS' => $user['WORKFLOW_STATUS'] ?? static::WORKFLOW_STATUS_ACTIVE,
				'TASK_STATUS' => $user['TASK_STATUS'] ?? static::TASK_STATUS_NONE,
				'MODIFIED' => new DateTime(),
			]);
		}

		WorkflowPush::pushAdded($workflowId, array_keys($toAdd));
	}

	private static function updateOnSync(string $workflowId, array $toUpdate, ?array $stored = null): void
	{
		if (!$toUpdate)
		{
			return;
		}

		$modified = new DateTime();

		foreach ($toUpdate as $userId => $user)
		{
			if (
				isset($stored[$userId])
				&& $user['TASK_STATUS'] !== static::TASK_STATUS_ACTIVE
				&& static::isEqualUser($user, $stored[$userId])
			)
			{
				unset($toUpdate[$userId]);
				continue;
			}

			$user['MODIFIED'] ??= $modified;

			static::update(
				[
					'USER_ID' => $userId,
					'WORKFLOW_ID' => $workflowId,
				],
				$user
			);
		}

		WorkflowPush::pushUpdated($workflowId, array_keys($toUpdate));
	}

	private static function isEqualUser(array $userA, array $userB): bool
	{
		return (
			($userA['IS_AUTHOR'] ?? null) === ($userB['IS_AUTHOR'] ?? null)
			&& ($userA['WORKFLOW_STATUS'] ?? null) === ($userB['WORKFLOW_STATUS'] ?? null)
			&& ($userA['TASK_STATUS'] ?? null) === ($userB['TASK_STATUS'] ?? null)
		);
	}

	private static function getStoredUsers(string $workflowId): array
	{
		$result = static::getList([
			'select' => ['USER_ID', 'IS_AUTHOR', 'WORKFLOW_STATUS', 'TASK_STATUS'],
			'filter' => ['=WORKFLOW_ID' => $workflowId],
		]);

		$users = [];

		while ($row = $result->fetch())
		{
			$users[(int)$row['USER_ID']] = [
				'IS_AUTHOR' => (int)$row['IS_AUTHOR'],
				'WORKFLOW_STATUS' => (int)$row['WORKFLOW_STATUS'],
				'TASK_STATUS' => (int)$row['TASK_STATUS'],
			];
		}

		return $users;
	}

	private static function hasStoredUsers(string $workflowId): bool
	{
		return static::getCount(['=WORKFLOW_ID' => $workflowId]) > 0;
	}

	public static function deleteByWorkflow(string $workflowId): array
	{
		$stored = static::getStoredUsers($workflowId);
		self::deleteOnSync($workflowId, $stored);

		return array_keys($stored);
	}

	public static function onDocumentDelete(array $docId): void
	{
		$stateIds = WorkflowStateTable::getIdsByDocument($docId, 1000);

		if (!$stateIds)
		{
			return;
		}

		$connection = Application::getConnection();
		$sqlHelper = $connection->getSqlHelper();
		$tableName = $sqlHelper->forSql(static::getTableName());
		$sqlQuery = sprintf(
			'DELETE from %s WHERE WORKFLOW_ID IN(%s)',
			$tableName,
			implode(',', array_map(fn($id) => "'{$id}'", $stateIds))
		);

		$connection->queryExecute($sqlQuery);
	}

	public static function convertUserProcesses(int $userId): void
	{
		$connection = Application::getConnection();

		if ($connection->getType() !== 'mysql')
		{
			return;
		}

		//truncate first
		$connection->query(
			<<<SQL
				DELETE FROM b_bp_workflow_user WHERE USER_ID = {$userId}
			SQL
		);

		// convert user "Live Feed" workflows (lists + BizprocDocument)
		$connection->query(
			<<<SQL
				INSERT INTO b_bp_workflow_user
				(USER_ID, WORKFLOW_ID, IS_AUTHOR, WORKFLOW_STATUS, MODIFIED)
			 	(
					 select wt.STARTED_BY, wt.ID, 1, case when wi.id is null then 1 else 0 end, wt.MODIFIED
					 from b_bp_workflow_state wt
					 left join b_bp_workflow_instance wi on (wt.id = wi.id)
					 where wt.STARTED_BY = {$userId} and wt.MODULE_ID = 'lists' and wt.ENTITY = 'BizprocDocument'
				)
				ON DUPLICATE KEY UPDATE IS_AUTHOR = 1, WORKFLOW_STATUS = VALUES(WORKFLOW_STATUS), MODIFIED = VALUES(MODIFIED)
			SQL
		);

		// convert my active tasks
		$connection->query(
			<<<SQL
				INSERT INTO b_bp_workflow_user
				(USER_ID, WORKFLOW_ID, IS_AUTHOR, WORKFLOW_STATUS, TASK_STATUS, MODIFIED)
				(
					select tu.USER_ID, t.WORKFLOW_ID, 0, 0, 2,
						case when tu.DATE_UPDATE is null then now() else tu.DATE_UPDATE end
					from b_bp_task_user tu
					inner join b_bp_task t on (t.ID = tu.TASK_ID)
					where tu.USER_ID = {$userId} and tu.STATUS = '0'
				)
				ON DUPLICATE KEY UPDATE TASK_STATUS = VALUES(TASK_STATUS), MODIFIED = VALUES(MODIFIED)
			SQL
		);

		//convert other tasks
		\Bitrix\Bizproc\Worker\Task\UserToWorkflowStepper::bindUser($userId);
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit