Your IP : 3.137.172.105


Current Path : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/bizproc/lib/basetype/
Upload File :
Current File : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/bizproc/lib/basetype/base.php

<?php
namespace Bitrix\Bizproc\BaseType;

use Bitrix\Main;
use Bitrix\Main\Localization\Loc;
use Bitrix\Bizproc\FieldType;

Loc::loadMessages(__FILE__);

/**
 * Class Base
 * @package Bitrix\Bizproc\BaseType
 */
class Base
{

	/**
	 * @return string
	 */
	public static function getType()
	{
		return FieldType::STRING;
	}

	/** @var array $formats	 */
	protected static $formats = array(
		'printable' => 	array(
			'callable' =>'formatValuePrintable',
			'separator' => ', ',
		)
	);

	/**
	 * @param string $format
	 * @return callable|null
	 */
	protected static function getFormatCallable($format)
	{
		$format = strtolower($format);
		$formats = static::getFormats();
		if (isset($formats[$format]['callable']))
		{
			$callable = $formats[$format]['callable'];
			if (is_string($callable))
			{
				$callable = array(get_called_class(), $callable);
			}

			return $callable;
		}
		return null;
	}

	/**
	 * @param string $format
	 * @return string
	 */
	protected static function getFormatSeparator($format)
	{
		$format = strtolower($format);
		$separator = ', '; //default - coma
		$formats = static::getFormats();
		if (isset($formats[$format]['separator']))
		{
			$separator = $formats[$format]['separator'];
		}
		return $separator;
	}

	/**
	 * @param string $name Format name.
	 * @param array $options Format options.
	 * @throws Main\ArgumentException
	 * @return void
	 */
	public static function addFormat($name, array $options)
	{
		$name = strtolower($name);
		if (empty($options['callable']))
			throw new Main\ArgumentException('Callable property in format options is not set.');

		static::$formats[$name] = $options;
	}

	/**
	 * Get formats list.
	 * @return array
	 */
	public static function getFormats()
	{
		return static::$formats;
	}

	/**
	 * Normalize single value.
	 *
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @return mixed Normalized value
	 */
	public static function toSingleValue(FieldType $fieldType, $value)
	{
		return $value;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @param string $format Format name.
	 * @return string
	 */
	public static function formatValueMultiple(FieldType $fieldType, $value, $format = 'printable')
	{
		$value = (array) $value;

		foreach ($value as $k => $v)
		{
			$value[$k] = static::formatValueSingle($fieldType, $v, $format);
		}

		return implode(static::getFormatSeparator($format), $value);
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @param string $format Format name.
	 * @return mixed|null
	 */
	public static function formatValueSingle(FieldType $fieldType, $value, $format = 'printable')
	{
		$callable = static::getFormatCallable($format);
		$value = static::toSingleValue($fieldType, $value);

		if (is_callable($callable))
		{
			return call_user_func($callable, $fieldType, $value);
		}
		//return original value if format not found
		return $value;
	}

	/**
	 * @param FieldType $fieldType
	 * @param $value
	 * @return string
	 */
	protected static function formatValuePrintable(FieldType $fieldType, $value)
	{
		return static::convertValueSingle($fieldType, $value, '\Bitrix\Bizproc\BaseType\StringType');
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @param string $toTypeClass Type class name.
	 * @return array
	 */
	public static function convertValueMultiple(FieldType $fieldType, $value, $toTypeClass)
	{
		$value = (array) $value;
		foreach ($value as $k => $v)
		{
			$value[$k] = static::convertValueSingle($fieldType, $v, $toTypeClass);
		}

		return $value;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @param string $toTypeClass Type class name.
	 * @return bool|int|float|string
	 */
	public static function convertValueSingle(FieldType $fieldType, $value, $toTypeClass)
	{
		$value = static::toSingleValue($fieldType, $value);
		/** @var Base $toTypeClass */
		$result = static::convertTo($fieldType, $value, $toTypeClass);
		if ($result === null)
			$result = $toTypeClass::convertFrom($fieldType, $value, get_called_class());

		if ($result !== null)
			$fieldType->setTypeClass($toTypeClass);

		return $result !== null? $result : $value;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @param string $toTypeClass Type class name.
	 * @return null
	 */
	public static function convertTo(FieldType $fieldType, $value, $toTypeClass)
	{
		return null;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @param string $fromTypeClass Type class name.
	 * @return null
	 */
	public static function convertFrom(FieldType $fieldType, $value, $fromTypeClass)
	{
		return null;
	}

	/**
	 * Return conversion map for current type.
	 * @return array Map.
	 */
	public static function getConversionMap()
	{
		return array(
			//to
			array(),
			//from
			array()
		);
	}

	/**
	 * @var array
	 */
	protected static $errors = array();

	/**
	 * @param mixed $error Error description.
	 */
	public static function addError($error)
	{
		static::$errors[] = $error;
	}

	/**
	 * @param array $errors Errors description.
	 * @return void
	 */
	public static function addErrors(array $errors)
	{
		static::$errors = array_merge(static::$errors, $errors);
	}

	/**
	 * @return array
	 */
	public static function getErrors()
	{
		return static::$errors;
	}

	/**
	 * Clean errors
	 */
	protected static function cleanErrors()
	{
		static::$errors = array();
	}

	/**
	 * @param array $field
	 * @return string
	 */
	protected static function generateControlId(array $field)
	{
		$id = 'id_'.$field['Field'];
		$index = isset($field['Index']) ? $field['Index'] : null;
		if ($index !== null)
		{
			$id .= '__n'.$index.'_';
		}
		return $id;
	}

	/**
	 * @param array $field
	 * @return string
	 */
	protected static function generateControlName(array $field)
	{
		$name = $field['Field'];
		$index = isset($field['Index']) ? $field['Index'] : null;
		if ($index !== null)
		{
			$prefix = strpos($index, 'n') === 0 ? '' : 'n';
			$name .= '['.$prefix.$index.']';
		}
		return $name;
	}

	protected static function generateControlClassName(FieldType $fieldType, array $field)
	{
		$prefix = isset($field['ClassNamePrefix']) ? (string)$field['ClassNamePrefix'] : 'bizproc-type-control';
		$classes = array($prefix);
		$classes[] = $prefix.'-'.static::getType();

		if ($fieldType->isMultiple())
		{
			$classes[] = $prefix.'-multiple';
		}
		if ($fieldType->isRequired())
		{
			$classes[] = $prefix.'-required';
		}

		return implode(' ', $classes);
	}

	/**
	 * @param array $controls
	 * @param string $wrapperId
	 * @return string
	 */
	protected static function wrapCloneableControls(array $controls, $wrapperId)
	{
		$wrapperId = (string) $wrapperId;
		$renderResult = '<table width="100%" border="0" cellpadding="2" cellspacing="2" id="BizprocCloneable_'
			.htmlspecialcharsbx($wrapperId).'">';

		foreach ($controls as $control)
		{
			$renderResult .= '<tr><td>'.$control.'</td></tr>';
		}
		$renderResult .= '</table>';
		$renderResult .= '<input type="button" value="'.Loc::getMessage('BPDT_BASE_ADD')
			.'" onclick="BX.Bizproc.cloneTypeControl(\'BizprocCloneable_'
			.htmlspecialcharsbx($wrapperId).'\')"/><br />';

		return $renderResult;
	}

	/**
	 * Low-level control rendering method
	 * @param FieldType $fieldType
	 * @param array $field
	 * @param mixed $value
	 * @param bool $allowSelection
	 * @param int $renderMode
	 * @return string - HTML rendering
	 */
	protected static function renderControl(FieldType $fieldType, array $field, $value, $allowSelection, $renderMode)
	{
		$name = static::generateControlName($field);
		$controlId = static::generateControlId($field);
		$className = static::generateControlClassName($fieldType, $field);
		// example: control rendering
		return '<input type="text" class="'.htmlspecialcharsbx($className).'" size="40" id="'.htmlspecialcharsbx($controlId).'" name="'
			.htmlspecialcharsbx($name).'" value="'.htmlspecialcharsbx((string) $value).'"/>';
	}

	/**
	 * @param int $renderMode Control render mode.
	 * @return bool
	 */
	public static function canRenderControl($renderMode)
	{
		if ($renderMode & FieldType::RENDER_MODE_MOBILE)
			return false;

		return true;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param array $field Form field.
	 * @param mixed $value Field value.
	 * @param bool $allowSelection Allow selection flag.
	 * @param int $renderMode Control render mode.
	 * @return string
	 */
	public static function renderControlSingle(FieldType $fieldType, array $field, $value, $allowSelection, $renderMode)
	{
		$value = static::toSingleValue($fieldType, $value);
		$selectorValue = null;
		if (\CBPActivity::isExpression($value))
		{
			$selectorValue = $value;
			$value = null;
		}

		$renderResult = static::renderControl($fieldType, $field, $value, $allowSelection, $renderMode);

		if ($allowSelection)
		{
			$renderResult .= static::renderControlSelector($field, $selectorValue, true, '', $fieldType);
		}

		return $renderResult;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param array $field Form field.
	 * @param mixed $value Field value.
	 * @param bool $allowSelection Allow selection flag.
	 * @param int $renderMode Control render mode.
	 * @return string
	 */
	public static function renderControlMultiple(FieldType $fieldType, array $field, $value, $allowSelection, $renderMode)
	{
		$selectorValue = null;
		$typeValue = array();
		if (!is_array($value) || is_array($value) && \CBPHelper::isAssociativeArray($value))
			$value = array($value);

		foreach ($value as $v)
		{
			if (\CBPActivity::isExpression($v))
				$selectorValue = $v;
			else
				$typeValue[] = $v;
		}
		// need to show at least one control
		if (empty($typeValue))
			$typeValue[] = null;

		$controls = array();

		foreach ($typeValue as $k => $v)
		{
			$singleField = $field;
			$singleField['Index'] = $k;
			$controls[] = static::renderControl(
				$fieldType,
				$singleField,
				$v,
				$allowSelection,
				$renderMode
			);
		}

		$renderResult = static::wrapCloneableControls($controls, static::generateControlName($field));

		if ($allowSelection)
		{
			$renderResult .= static::renderControlSelector($field, $selectorValue, true, '', $fieldType);
		}

		return $renderResult;
	}

	/**
	 * @param array $field
	 * @param null|string $value
	 * @param bool $showInput
	 * @param string $selectorMode
	 * @param FieldType $fieldType
	 * @return string
	 */
	protected static function renderControlSelector(array $field, $value = null, $showInput = false, $selectorMode = '', FieldType $fieldType = null)
	{
		$html = '';
		$controlId = static::generateControlId($field);
		if ($showInput)
		{
			$controlId = $controlId.'_text';
			$name = static::generateControlName($field).'_text';
			$html = '<input type="text" id="'.htmlspecialcharsbx($controlId).'" name="'
					.htmlspecialcharsbx($name).'" value="'.htmlspecialcharsbx((string)$value).'">';
		}
		$html .= static::renderControlSelectorButton($controlId, $fieldType, $selectorMode);

		return $html;
	}

	protected static function renderControlSelectorButton($controlId, FieldType $fieldType, $selectorMode = '')
	{
		$baseType = $fieldType ? $fieldType->getBaseType() : null;
		$selectorProps = \Bitrix\Main\Web\Json::encode(array(
			'controlId' => $controlId,
			'baseType' => $baseType,
			'type' => $fieldType ? $fieldType->getType() : null,
			'documentType' => $fieldType ? $fieldType->getDocumentType() : null,
			'documentId' => $fieldType ? $fieldType->getDocumentId() : null,
		));

		return '<input type="button" value="..." onclick="BPAShowSelector(\''
			.\CUtil::jsEscape(htmlspecialcharsbx($controlId)).'\', \''.\CUtil::jsEscape(htmlspecialcharsbx($baseType)).'\', '
			.($selectorMode ? '\''.\CUtil::jsEscape(htmlspecialcharsbx($selectorMode)).'\'' : 'null').', null, '
			.htmlspecialcharsbx(\Bitrix\Main\Web\Json::encode($fieldType ? $fieldType->getDocumentType() : null)).');"'
			.' data-role="bp-selector-button" data-bp-selector-props="'.htmlspecialcharsbx($selectorProps).'">';
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param string $callbackFunctionName Client callback function name.
	 * @param mixed $value Field value.
	 * @return string
	 */
	public static function renderControlOptions(FieldType $fieldType, $callbackFunctionName, $value)
	{
		return '';
	}

	/**
	 * @param FieldType $fieldType
	 * @param array $field
	 * @param array $request
	 * @return null|mixed
	 */
	protected static function extractValue(FieldType $fieldType, array $field, array $request)
	{
		$name = $field['Field'];
		$value = isset($request[$name]) ? $request[$name] : null;
		$fieldIndex = isset($field['Index']) ? $field['Index'] : null;
		if (is_array($value) && !\CBPHelper::isAssociativeArray($value))
		{
			if ($fieldIndex !== null)
				$value = isset($value[$fieldIndex]) ? $value[$fieldIndex] : null;
			else
			{
				reset($value);
				$value = current($value);
			}
		}

		return $value;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param array $field Form field.
	 * @param array $request Request data.
	 * @return mixed|null
	 */
	public static function extractValueSingle(FieldType $fieldType, array $field, array $request)
	{
		static::cleanErrors();
		$result = static::extractValue($fieldType, $field, $request);
		if ($result === null || $result === '')
		{
			$nameText = $field['Field'].'_text';
			$text = isset($request[$nameText]) ? $request[$nameText] : null;
			if (\CBPActivity::isExpression($text))
				$result = $text;
		}
		return $result;
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param array $field Form field.
	 * @param array $request Request data.
	 * @return array
	 */
	public static function extractValueMultiple(FieldType $fieldType, array $field, array $request)
	{
		static::cleanErrors();

		$name = $field['Field'];
		$value = isset($request[$name]) ? $request[$name] : array();

		if (!is_array($value) || is_array($value) && \CBPHelper::isAssociativeArray($value))
			$value = array($value);

		foreach ($value as $k => $v)
		{
			$field['Index'] = $k;
			$result = static::extractValue($fieldType, $field, $request);
			if ($result === null || $result === '')
			{
				unset($value[$k]);
			}
			else
				$value[$k] = $result;
		}

		//append selector value
		$nameText = $field['Field'].'_text';
		$text = isset($request[$nameText]) ? $request[$nameText] : null;
		if (\CBPActivity::isExpression($text))
			$value[] = $text;

		return array_values($value);
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @return void
	 */
	public static function clearValueSingle(FieldType $fieldType, $value)
	{
		//Method fires when workflow was complete
	}

	/**
	 * @param FieldType $fieldType Document field type.
	 * @param mixed $value Field value.
	 * @return void
	 */
	public static function clearValueMultiple(FieldType $fieldType, $value)
	{
		if (!is_array($value) || is_array($value) && \CBPHelper::isAssociativeArray($value))
			$value = array($value);

		foreach ($value as $v)
		{
			static::clearValueSingle($fieldType, $v);
		}
	}
}