%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/bizproc/lib/automation/
Upload File :
Create Path :
Current File : /home/bitrix/www/bitrix/modules/bizproc/lib/automation/helper.php

<?php
namespace Bitrix\Bizproc\Automation;

use Bitrix\Bizproc\Automation\Engine\DelayInterval;
use Bitrix\Disk;
use Bitrix\Main\Loader;

class Helper
{
	const CURRENT_DATE_BASIS = '{=System:Date}';
	const CURRENT_DATETIME_BASIS = '{=System:Now}';

	protected static $maps;
	protected static $documentFields;

	public static function prepareUserSelectorEntities(array $documentType, $users, $config = [])
	{
		$result = [];
		$users = (array)$users;
		$documentUserFields = static::getDocumentFields($documentType, 'user');

		foreach ($users as $user)
		{
			if (!is_scalar($user))
				continue;

			if (substr($user, 0, 5) === "user_")
			{
				$user = intval(substr($user, 5));
				if (($user > 0) && !in_array($user, $result))
				{
					$result[] = array(
						'id'         => 'U'.$user,
						'entityId'   => $user,
						'name'       => htmlspecialcharsBx(self::getFormattedUserName($user)),
						'entityType' => 'users'
					);
				}
			}
			elseif ($user === 'author' &&
				(
					isset($documentUserFields['ASSIGNED_BY_ID']) ||
					isset($documentUserFields['RESPONSIBLE_ID'])
				)
			)
			{
				$responsibleKey = isset($documentUserFields['ASSIGNED_BY_ID']) ? 'ASSIGNED_BY_ID' : 'RESPONSIBLE_ID';

				$result[] = array(
					'id'         => $documentUserFields[$responsibleKey]['Expression'],
					'entityId'   => $documentUserFields[$responsibleKey]['Expression'],
					'name'       => htmlspecialcharsBx($documentUserFields[$responsibleKey]['Name']),
					'entityType' => 'bpuserroles'
				);
			}
			else
			{
				$found = false;
				foreach ($documentUserFields as $field)
				{
					if ($user === $field['Expression'] || $user === $field['SystemExpression'])
					{
						$result[] = array(
							'id'       => $field['Expression'],
							'entityId' => $field['Expression'],
							'name'     => htmlspecialcharsBx($field['Name']),
							'entityType' => 'bpuserroles'
						);
						$found = true;
					}
				}

				if (!$found && isset($config['additionalFields']))
				{
					foreach ($config['additionalFields'] as $field)
					{
						if ($user === $field['entityId'])
						{
							$result[] = array(
								'id'       => $field['id'],
								'entityId' => $field['entityId'],
								'name'     => htmlspecialcharsBx($field['name']),
								'entityType' => 'bpuserroles'
							);
						}
					}
				}
			}
		}
		return $result;
	}

	public static function getResponsibleUserExpression(array $documentType)
	{
		$documentUserFields = static::getDocumentFields($documentType, 'user');
		$result = null;

		if (isset($documentUserFields['ASSIGNED_BY_ID']) || isset($documentUserFields['RESPONSIBLE_ID']))
		{
			$responsibleKey = isset($documentUserFields['ASSIGNED_BY_ID']) ? 'ASSIGNED_BY_ID' : 'RESPONSIBLE_ID';
			$result = '{=Document:'.$responsibleKey.'}';
		}
		return $result;
	}

	/**
	 * Get disk files information by file ids.
	 * @param int|array $attachments
	 * @return array
	 */
	public static function prepareDiskAttachments($attachments)
	{
		$result = array();

		if (!Loader::includeModule('disk'))
			return $result;

		foreach ((array)$attachments as $attachmentId)
		{
			$attachmentId = (int)$attachmentId;
			if ($attachmentId <= 0)
			{
				continue;
			}

			$file = Disk\File::loadById($attachmentId);
			if ($file)
			{
				$result[] = array(
					'id' => $file->getId(),
					'name' => $file->getName(),
					'size' => \CFile::FormatSize($file->getSize()),
					'type' => 'disk'
				);
			}
		}

		return $result;
	}

	/**
	 * Get files information from document fields.
	 * @param array $documentType
	 * @param $files
	 * @return array
	 */
	public static function prepareFileAttachments(array $documentType, $files)
	{
		$result = [];
		$files = (array)$files;
		$documentUserFields = static::getDocumentFields($documentType, 'file');

		foreach ($files as $file)
		{
			if (!is_scalar($file))
				continue;

			foreach ($documentUserFields as $id => $field)
			{
				if ($file !== $field['Expression'])
					continue;

				$result[] = array(
					'id' => $id,
					'expression' => $field['Expression'],
					'name' => $field['Name'],
					'type' => 'file'
				);
			}
		}
		return $result;
	}

	public static function convertExpressions($source, array $documentType)
	{
		$source = (string)$source;
		list($ids, $names) = static::getFieldsMap($documentType);

		$converter = function ($matches) use ($ids, $names)
		{
			$mods = [];
			if ($matches['mod1'])
			{
				$mods[] = $matches['mod1'];
			}
			if ($matches['mod2'])
			{
				$mods[] = $matches['mod2'];
			}

			if ($matches['object'] === 'Document')
			{
				$key = array_search($matches['field'], $ids);
				if ($key !== false)
				{
					$fieldName = $names[$key];
					return '{{'.$fieldName. ($mods? ' > '.implode(',', $mods) : '').'}}';
				}
			}
			elseif (preg_match('/^A[_0-9]+$/', $matches['object']))
			{
				return '{{~'.$matches['object'].':'.$matches['field']. ($mods? ' > '.implode(',', $mods) : '').'}}';
			}

			return $matches[0];
		};

		$source = preg_replace_callback(
			\CBPActivity::ValueInlinePattern,
			$converter,
			$source
		);

		return $source;
	}

	public static function unConvertExpressions($source, array $documentType)
	{
		$source = (string)$source;
		list($ids, $names) = static::getFieldsMap($documentType);

		$converter = function ($matches) use ($ids, $names)
		{
			if (strpos($matches['mixed'], '~') === 0)
			{
				$len = strpos($matches['mixed'], '#');
				$expression = ($len === false)
					? substr($matches['mixed'], 1)
					: substr($matches['mixed'], 1,$len - 1)
				;
				return '{='.trim($expression).'}';
			}

			$pairs = explode('>', $matches['mixed']);
			$fieldName = $fieldId = '';

			while (($pair = array_shift($pairs)) !== null)
			{
				$fieldName .= $fieldName? '>'.$pair : $pair;

				$key = array_search(trim($fieldName), $names);
				if ($key !== false)
				{
					$fieldId = $ids[$key];
					break;
				}
			}

			if ($fieldId)
			{
				$mods = isset($pairs[0]) ? trim($pairs[0]) : '';
				return '{=Document:'.$fieldId.($mods? ' > '.$mods : '').'}';
			}

			return $matches[0];
		};

		$source = preg_replace_callback(
			'/\{\{(?<mixed>.*?)\}\}/is',
			$converter,
			$source
		);

		return $source;
	}

	/**
	 * Get document fields for usage in robots designer.
	 * @param array $documentType Bizproc document type.
	 * @param null|string $typeFilter
	 * @return array
	 */
	public static function getDocumentFields(array $documentType, $typeFilter = null)
	{
		$key = implode('@', $documentType);
		if (!isset(static::$documentFields[$key]))
		{
			$runtime = \CBPRuntime::GetRuntime();
			$runtime->StartRuntime();

			/** @var \CBPDocumentService $documentService */
			$documentService = $runtime->GetService('DocumentService');
			static::$documentFields[$key] = $documentService->GetDocumentFields($documentType);
		}

		$resultFields = array();

		if (is_array(static::$documentFields[$key]))
		{
			foreach (static::$documentFields[$key] as $id => $field)
			{
				if ($field['Type'] === 'UF:boolean')
				{
					//Mark as bizproc boolean type
					$field['Type'] = $field['BaseType'] = 'bool';
				}

				if ($field['Type'] === 'UF:date')
				{
					//Mark as bizproc date type
					$field['Type'] = $field['BaseType'] = 'date';
				}

				if ($typeFilter !== null && $field['Type'] !== $typeFilter)
					continue;

				$resultFields[$id] = array(
					'Id' => $id,
					'Name' => $field['Name'],
					'Type' => $field['Type'],
					'BaseType' => $field['BaseType'],
					'Expression' => '{{'.$field['Name'].'}}',
					'SystemExpression' => '{=Document:'.$id.'}',
					'Options' => $field['Options']
				);
			}
		}
		return $resultFields;
	}

	protected static function getFieldsMap(array $documentType)
	{
		$key = implode('@', $documentType);
		if (!isset(static::$maps[$key]))
		{
			$id = $name = [];

			$fields = static::getDocumentFields($documentType);
			foreach ($fields as $field)
			{
				$id[] = $field['Id'];
				$name[] = $field['Name'];
			}

			static::$maps[$key] = [$id, $name];
		}
		return static::$maps[$key];
	}

	public static function parseDateTimeInterval($interval)
	{
		$interval = (string)$interval;
		$result = array(
			'basis' => null,
			'i' => 0,
			'h' => 0,
			'd' => 0,
			'workTime' => false
		);

		if (strpos($interval, '=dateadd(') === 0 || strpos($interval, '=workdateadd(') === 0)
		{
			if (strpos($interval, '=workdateadd(') === 0)
			{
				$interval = substr($interval, 13, -1); // cut =workdateadd(...)
				$result['workTime'] = true;
			}
			else
			{
				$interval = substr($interval, 9, -1); // cut =dateadd(...)
			}

			$arguments = explode(',', $interval);
			$result['basis'] = trim($arguments[0]);

			$arguments[1] = trim($arguments[1], '"\'');
			$result['type'] = strpos($arguments[1], '-') === 0 ? DelayInterval::TYPE_BEFORE : DelayInterval::TYPE_AFTER;

			preg_match_all('/\s*([\d]+)\s*(i|h|d)\s*/i', $arguments[1], $matches);
			foreach ($matches[0] as $i => $match)
			{
				$result[$matches[2][$i]] = (int)$matches[1][$i];
			}
		}
		elseif (\CBPDocument::IsExpression($interval))
			$result['basis'] = $interval;

		$minutes = $result['i'] + $result['h'] * 60 + $result['d'] * 60 * 24;

		if ($minutes % 1440 === 0)
		{
			$result['value'] = $minutes / 1440;
			$result['valueType'] = 'd';
		}
		elseif ($minutes % 60 === 0)
		{
			$result['value'] = $minutes / 60;
			$result['valueType'] = 'h';
		}
		else
		{
			$result['value'] = $minutes;
			$result['valueType'] = 'i';
		}

		if (
			!$result['value']
			&& $result['basis'] !== static::CURRENT_DATETIME_BASIS
			&& \CBPDocument::IsExpression($result['basis'])
		)
		{
			$result['type'] =  DelayInterval::TYPE_IN;
		}

		return $result;
	}

	public static function getDateTimeIntervalString($interval)
	{
		if (!$interval['basis'] || !\CBPDocument::IsExpression($interval['basis']))
			$interval['basis'] = static::CURRENT_DATE_BASIS;

		$days = isset($interval['d']) ? (int)$interval['d'] : 0;
		$hours = isset($interval['h']) ? (int)$interval['h'] : 0;
		$minutes = isset($interval['i']) ? (int)$interval['i'] : 0;

		if (isset($interval['value']) && isset($interval['valueType']))
		{
			switch ($interval['valueType'])
			{
				case 'i':
					$minutes = (int)$interval['value'];
					break;
				case 'h':
					$hours = (int)$interval['value'];
					break;
				case 'd':
					$days = (int)$interval['value'];
					break;
			}
		}

		$add = '';
		if (isset($interval['type']) && $interval['type'] == DelayInterval::TYPE_BEFORE)
			$add = '-';

		if ($days > 0)
			$add .= $days.'d';
		if ($hours > 0)
			$add .= $hours.'h';
		if ($minutes > 0)
			$add .= $minutes.'i';

		$fn = !empty($interval['workTime']) ? 'workdateadd' : 'dateadd';

		if ($fn === 'workdateadd' && $add === '')
		{
			$add = '0d';
		}

		return '='.$fn.'('.$interval['basis'].',"'.$add.'")';
	}

	public static function parseTimeString($time)
	{
		$pairs = preg_split('#[\s:]+#', $time);
		$pairs[0] = (int)$pairs[0];
		$pairs[1] = (int)$pairs[1];

		if (count($pairs) === 3)
		{
			if ($pairs[2] == 'pm' && $pairs[0] < 12)
				$pairs[0] += 12;
			if ($pairs[2] == 'am' && $pairs[0] == 12)
				$pairs[0] = 0;
		}

		return array('h' => $pairs[0], 'i' => $pairs[1]);
	}

	private static function getFormattedUserName($userID, $format = '', $htmlEncode = false)
	{
		$userID = intval($userID);
		if($userID <= 0)
		{
			return '';
		}

		$format = strval($format);
		if($format === '')
		{
			$format = \CSite::GetNameFormat(false);
		}

		$dbUser = \CUser::GetList(
			($by = 'id'),
			($order = 'asc'),
			array('ID'=> $userID),
			array(
				'FIELDS' => array(
					'ID',
					'NAME', 'SECOND_NAME', 'LAST_NAME',
					'LOGIN', 'TITLE', 'EMAIL'
				)
			)
		);

		$user = $dbUser ? $dbUser->Fetch() : null;
		return is_array($user) ? \CUser::FormatName($format, $user, true, $htmlEncode) : '';
	}
}

Zerion Mini Shell 1.0