%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/sale/lib/compatible/internals/
Upload File :
Create Path :
Current File : //home/bitrix/www/bitrix/modules/sale/lib/compatible/internals/entitycompatibility.php

<?php


namespace Bitrix\Sale\Compatible\Internals;

use Bitrix\Main\Application;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\ArgumentOutOfRangeException;
use Bitrix\Main\Entity;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\NotImplementedException;
use Bitrix\Main\ObjectNotFoundException;
use Bitrix\Main\SystemException;
use Bitrix\Main\Type\Date;
use Bitrix\Main\Type\DateTime;
use Bitrix\Sale\Compatible\Internals;
use Bitrix\Sale\Compatible;
use Bitrix\Sale;

abstract class EntityCompatibility
{
	/** @var Compatible\OrderQuery|null */
	protected $query = null;

	/** @var array */
	protected $filter = array();

	/** @var array */
	protected $select = array();

	/** @var array|null */
	protected $group = null;

	/** @var array */
	protected $sort = array();

	/** @var array|null */
	protected $nav = null;

	/** @var null */
	protected $queryAliasList = null;

	/** @var Sale\Internals\Fields|null  */
	protected $fields = null;

	/** @var array */
	protected $rawFields = array();

	const ENTITY_ORDER = 'ORDER';
	const ENTITY_PAYMENT = 'PAYMENT';

	const ENTITY_ORDER_TABLE = 'b_sale_order';
	const ENTITY_PAYMENT_TABLE = 'b_sale_order_payment';
	protected function __construct(array $fields = array())
	{
		throw new SystemException('not set construct');
	}

	protected static function getRegistryType()
	{
		throw new NotImplementedException();
	}

	protected static function getEntity()
	{
		throw new NotImplementedException();
	}

	/**
	 * @internal
	 * @return array
	 */
	public static function getAliasFields()
	{
		return array();
	}

	/**
	 * @return array
	 */
	protected static function getSelectFields()
	{
		return array();
	}

	/**
	 * @param $id
	 * @return Compatible\CDBResult
	 */
	public static function getById($id)
	{
		/** @var EntityCompatibility $compatibility */
		$compatibility = new static();
		return static::setGetListParameters($compatibility);
	}

	/**
	 * @param $sort
	 * @param $filter
	 * @param null|array $group
	 * @param $nav
	 * @param $select
	 * @param $callback
	 * @return Compatible\CDBResult
	 */
	public static function getList($sort = array(), $filter = array(), $group = null, $nav = array(), $select = array(), $callback = false)
	{
		/** @var EntityCompatibility $compatibility */
		$compatibility = new static();
		return static::setGetListParameters($compatibility, $sort, $filter, $group, $nav, $select, $callback);
	}

	/**
	 * @param EntityCompatibility $compatibility
	 * @param array $sort
	 * @param array $filter
	 * @param null $group
	 * @param array $nav
	 * @param array $select
	 * @param bool $callback
	 *
	 * @return Compatible\CDBResult|int
	 */
	protected static function setGetListParameters(EntityCompatibility $compatibility, $sort = array(), $filter = array(), $group = null, $nav = array(), $select = array(), $callback = false)
	{
		if (empty($select))
		{
			$select = array('*');
		}


		if (!empty($filter))
		{
			$compatibility->setFilter($filter);
		}

		if (!empty($select))
		{
			$compatibility->setSelect($select);
		}

		if ($group !== null)
		{
			$compatibility->setGroup($group);
		}

		if (!empty($sort))
		{
			$compatibility->setSort($sort);
		}

		if (!empty($nav))
		{
			$compatibility->setNav($nav);
		}

		if (!empty($callback))
		{
			$compatibility->setCallback($callback);
		}

		return $compatibility->execute();
	}

	/**
	 * @param array $fields
	 * @throws SystemException
	 */
	public static function add(array $fields)
	{
		throw new SystemException('not set add');
	}

	/**
	 * @param array $filter
	 */
	public function setFilter(array $filter = array())
	{

		$aliasFields = static::getAliasFields();
		foreach($filter as $fieldName => $fieldValue)
		{
			$fieldName = ToUpper($fieldName);
			$filterMatch = $this->query->explodeFilterKey($fieldName);
			$fieldClearName = $filterMatch['alias'];

			if (!in_array($fieldClearName, $this->getQueryAliasList()))
			{
				if (isset($aliasFields[$fieldClearName]))
				{
					$this->addQueryAlias($fieldClearName, $aliasFields[$fieldClearName]);
				}
			}

			if ($propKey = $this->parseField($fieldClearName))
			{
				$this->addFilter($filterMatch['modifier'].$filterMatch['operator'].$propKey, $fieldValue);
			}
			else
			{
				if (!$this->checkWhiteListFields($fieldClearName))
					continue;

				if (!is_array($aliasFields[$fieldClearName]))
				{
					$this->addFilter($fieldName, $fieldValue);
				}
				else
				{
					$this->addFilterForAlias($aliasFields[$fieldClearName], $fieldName, $fieldValue);
					$this->addSelectForAlias($aliasFields[$fieldClearName]);
				}
			}
		}
	}

	/**
	 * @param array $select
	 */
	public function setSelect(array $select = array())
	{
		$aliasFields = static::getAliasFields();
		if (empty($select))
		{
			$select = static::getSelectFields();
		}

		foreach($select as $key => $fieldName)
		{
			if ($fieldName == "*")
			{
				unset($select[$key]);

				$select = array_merge($select, static::getSelectFields());

				break;
			}
		}

		foreach($select as $fieldName)
		{
			$fieldName = ToUpper($fieldName);
			if (!in_array($fieldName, $this->getQueryAliasList()))
			{
				if (isset($aliasFields[$fieldName]))
				{
					$this->addQueryAlias($fieldName, $aliasFields[$fieldName]);
				}
			}

			if ($propKey = $this->parseField($fieldName))
			{
				$this->addSelect($propKey);
			}
			else
			{
				if (!is_array($aliasFields[$fieldName]))
				{
					$this->addSelect($fieldName);
				}
				else
				{
					$this->addSelectForAlias($aliasFields[$fieldName]);
				}
			}
		}
	}

	/**
	 * @param $key
	 *
	 * @return null|string
	 */
	public function parseField($key)
	{
		return null;
	}

	/**
	 * @param array $group
	 */
	public function setGroup($group = null)
	{
		if (is_array($group))
		{
			if (empty($group))
			{
				$this->select = array();
				$this->group = $group;
			}
			else
			{
				foreach($group as $fieldName => $fieldValue)
				{
					if ($propKey = $this->parseField($fieldName))
					{
						$this->group[$propKey] = $fieldValue;
					}
					else
					{
						$this->group[$fieldName] = $fieldValue;
					}
				}
			}
		}
	}

	/**
	 * @param array $sort
	 */
	public function setSort(array $sort = array())
	{
		foreach($sort as $fieldName => $fieldValue)
		{
			$fieldName = strtoupper($fieldName);
			if ($propKey = $this->parseField($fieldName))
			{
				$this->sort[$propKey] = $fieldValue;
			}
			else
			{
				$this->sort[$fieldName] = $fieldValue;
			}
		}
	}

	/**
	 * @param array $nav
	 */
	public function setNav(array $nav = array())
	{
		$this->nav = $nav;
	}

	/**
	 * @param array $callback
	 */
	public function setCallback(array $callback)
	{

		if (($sql = call_user_func_array($callback, array())) && strval(trim($sql)) != '')
		{
			$this->query->registerRuntimeField('',
										 new Entity\ExpressionField(
											 '__CALLBACK',
											 '(CASE WHEN ('.$sql.') THEN 1 ELSE 0 END)'
										 )
			);
			$this->query->addFilter('=__CALLBACK', 1);
		}
	}

	/**
	 * @param $name
	 * @param $value
	 * @return bool
	 */
	protected function addFilter($name, $value)
	{
		if (isset($this->filter[$name]))
			return false;

		$this->filter[$name] = $value;

		return true;
	}

	/**
	 * @param array $aliasList
	 * @param $name
	 * @param $value
	 * @return bool
	 */
	protected function addFilterForAlias(array $aliasList, $name, $value)
	{
		$match = $this->query->explodeFilterKey($name);
		$rule = ($match['modifier']? $match['modifier']:"").($match['operator']? $match['operator']:"");

		$logic = array();
		foreach ($aliasList as $fieldName => $fieldValue)
		{
			$filterName = $rule.$fieldName;
			$logic[] = array($filterName => $value);
		}

		if (!empty($logic))
		{
			$logic['LOGIC'] = 'OR';
			$this->query->addFilter(null, $logic);
		}

		return true;
	}

	/**
	 * @param $name
	 * @return bool
	 */
	protected function addSelect($name)
	{
		if (in_array($name, $this->select))
			return false;

		$this->select[] = $name;

		return true;
	}

	/**
	 * @param array $aliasList
	 * @return bool
	 */
	protected function addSelectForAlias(array $aliasList)
	{
		foreach ($aliasList as $fieldName => $fieldValue)
		{
			$this->addSelect($fieldName);
		}

		return true;
	}

	/**
	 * @param $name
	 * @param null $value
	 * @return bool
	 * @throws \Bitrix\Main\SystemException
	 */
	protected function addQueryAlias($name, $value = null)
	{
		$list = array();

		if ($name == $value)
		{
			$value = null;
		}

		if (!empty($value) && is_array($value))
		{
			$list = $value;
		}
		else
		{
			$list[$name] = $value;
		}

		foreach ($list as $fieldName => $fieldValue)
		{
			if (in_array($fieldName, $this->queryAliasList))
			{
				return false;
			}

			$this->queryAliasList[] = $fieldName;
			$this->query->addAlias($fieldName, $fieldValue);

		}

		return true;
	}

	/**
	 * @return array|null
	 */
	protected function getQueryAliasList()
	{
		if ($this->queryAliasList === null)
		{
			$this->queryAliasList = array_keys($this->query->getAliases());
		}

		return $this->queryAliasList;
	}

	/**
	 * @return Compatible\CDBResult|int
	 */
	public function execute()
	{
		/** @var Compatible\CDBResult $result */
		$result = new Compatible\CDBResult();
		$this->query->prepare($this->sort, $this->filter, $this->group, $this->select);
		if ($this->query->counted())
		{
			return $this->query->exec()->getSelectedRowsCount();
		}

		return $this->query->compatibleExec($result, $this->nav);
	}


	/**
	 * @param $name
	 * @return null|string
	 */
	public function getField($name)
	{
		return $this->fields->get($name);
	}

	/**
	 * @param $name
	 * @param $value
	 */
	public function setField($name, $value)
	{
		$this->fields->set($name, $value);
	}

	/**
	 * @return array
	 */
	public function getFieldValues()
	{
		return $this->fields->getValues();
	}

	/**
	 * @param array $values
	 */
	public function setFields(array $values)
	{
		$this->fields->resetValues($values);
	}


	/**
	 * Remove unnecessary fields
	 *
	 * @param array $fields             An array of fields.
	 * @param array $availableFields    An array of allowed fields.
	 * @return array
	 */
	protected static function clearFields(array $fields, array $availableFields = array())
	{
		if (empty($availableFields))
			$availableFields = static::getAvailableFields();

		foreach ($fields as $fieldName => $fieldValue)
		{
			if (!in_array($fieldName, $availableFields))
			{
				unset($fields[$fieldName]);
			}
		}

		return $fields;
	}


	/**
	 * @internal
	 * Convert an array of dates from a string to an object
	 *
	 * @param array $fields           The array of dates
	 * @param array $dateFields An array describing the fields and types of dates
	 * @return array
	 */
	public static function convertDateFields(array $fields, array $dateFields = array())
	{
		$resultList = array();
		foreach ($fields as $k => $value)
		{
			$resultList[$k] = static::convertDateField($k, $value, $dateFields);
		}
		return $resultList;
	}

	/**
	 * Convert date from string to object
	 *
	 * @param string $name     Field name
	 * @param string $value    Field value
	 * @param array $dateFields
	 *
	 * @return Date|DateTime
	 */
	protected static function convertDateField($name, $value, array $dateFields = array())
	{
		$key = $name;
		if (substr($key,0,1) == '=')
		{
			$key = substr($key, 1);
		}

		if (!array_key_exists($key, $dateFields))
		{
			return $value;
		}

		$nowDate = Application::getConnection()->getSqlHelper()->getCurrentDateTimeFunction();

		if (!($value instanceof DateTime)
			&& !($value instanceof Date))
		{
			if ($value === null)
				return null;

			if (strval($value) == '')
				return false;


			$setValue = null;

			if (ToLower($value) != ToLower($nowDate))
			{
				$setValue = $value;
			}

			if (ToUpper($dateFields[$key]) == "DATE")
			{
				$value = new Date($setValue);
			}
			elseif (ToUpper($dateFields[$key]) == "DATETIME")
			{
				$value = new DateTime($setValue);
			}
		}

		return $value;
	}

	/**
	 * Convert an array of dates from the object to a string
	 *
	 * @param array $fields   The array of dates
	 * @return array
	 */
	public static function convertDateFieldsToOldFormat(array $fields)
	{
		$resultList = array();
		foreach ($fields as $k => $value)
		{
			$valueString = static::convertDateFieldToOldFormat($value);
			$resultList[$k] = $valueString;
		}

		return $resultList;
	}

	/**
	 * Convert date object to a string
	 *
	 * @param string $value    Field value
	 * @return string
	 */
	protected static function convertDateFieldToOldFormat($value)
	{
		$setValue = $value;

		if (($value instanceof DateTime)
			|| ($value instanceof Date))
		{
			$setValue = $value->toString();
		}

		return $setValue;
	}

	/**
	 * @internal
	 * Convert date object to a string to format
	 *
	 * @param string $value    Field value
	 * @param string $format
	 * @return string
	 */
	public static function convertDateFieldToFormat($value, $format)
	{
		$setValue = $value;

		if (($value instanceof DateTime)
			|| ($value instanceof Date))
		{
			$phpFormat = $value->convertFormatToPhp($format);
			$setValue = $value->format($phpFormat);
			$setValue = str_replace(" 00:00:00", "", $setValue);
		}

		return $setValue;
	}


	/**
	 * @param array $fields
	 * @param array $replace
	 *
	 * @return array
	 */
	protected static function replaceFields(array $fields, array $replace = array())
	{
		if (empty($replace))
			return $fields;

		$replacedFields = $fields;

		foreach ($fields as $name => $value)
		{
			if (array_key_exists($name, $replace))
			{
				$replacedFields[$replace[$name]] = $replacedFields[$name];
				unset($replacedFields[$name]);
			}
		}

		return $replacedFields;
	}


	/**
	 * @internal
	 *
	 * @return array
	 */
	public static function getAvailableFields()
	{
		return array();
	}

	/**
	 * @param string $entityName
	 *
	 * @return bool
	 */
	protected static function checkEntityName($entityName)
	{
		return ($entityName == static::ENTITY_ORDER
			|| $entityName == static::ENTITY_PAYMENT
		);
	}

	/**
	 * @param $entityName
	 * @param array $fields
	 * @param array $availableFields
	 *
	 * @return array
	 * @throws ArgumentOutOfRangeException
	 */
	protected function parseRawFields($entityName, array $fields, array $availableFields = array())
	{
		if (!static::checkEntityName($entityName))
		{
			throw new ArgumentOutOfRangeException('entityName');
		}

		if (empty($availableFields))
			$availableFields = static::getAvailableFields();

		foreach ($fields as $name => $value)
		{
			$firstLetter = substr($name, 0, 1);
			if ($firstLetter == "~" || $firstLetter == "=")
			{
				$fieldName = ltrim($name, '=');
				$fieldName = ltrim($fieldName, '~');

				if (!in_array($fieldName, $availableFields))
					continue;

				$this->rawFields[$entityName][$firstLetter.$fieldName] = $value;
				unset($fields[$name]);
			}
		}

		return $fields;
	}


	/**
	 * @param $entity
	 * @param $entityName
	 *
	 * @return Sale\Result
	 * @throws ArgumentNullException
	 * @throws ArgumentOutOfRangeException
	 * @throws ObjectNotFoundException
	 */
	public function saveRawFields($entity, $entityName)
	{
		global $DB;

		if (!static::checkEntityName($entityName))
		{
			throw new ArgumentOutOfRangeException('entityName');
		}

		if (empty($this->rawFields[$entityName]) || !is_array($this->rawFields[$entityName]))
			return new Sale\Result();

		$tableName = null;
		if ($entityName == static::ENTITY_ORDER)
		{
			/** @var Sale\OrderBase $entity */
			if (!$entity instanceof Sale\OrderBase)
			{
				throw new ObjectNotFoundException('Entity "Order" not found');
			}

			$tableName = static::ENTITY_ORDER_TABLE;
		}
		elseif ($entityName == static::ENTITY_PAYMENT)
		{
			/** @var Sale\Payment $entity */
			if (!$entity instanceof Sale\Payment)
			{
				throw new ObjectNotFoundException('Entity "Payment" not found');
			}
			$tableName = static::ENTITY_PAYMENT_TABLE;
		}

		if ($entity->getId() <= 0)
		{
			throw new ArgumentNullException('id');
		}

		if (strval(trim($tableName)) == '')
		{
			throw new ArgumentNullException('tableName');
		}

		$result = new Sale\Result();

		$queryValue = $DB->PrepareUpdate($tableName, $this->rawFields[$entityName]);

		foreach ($this->rawFields[$entityName] as $key => $value)
		{
			if (substr($key, 0, 1) != "=")
				continue;

			if (strval($queryValue) != '')
				$queryValue .= ", ";

			$queryValue .= substr($key, 1)."=".$value." ";
		}

		$sql =
			"UPDATE ".$tableName." SET ".
			"	".$queryValue." WHERE ID = ".$entity->getId()." ";

		if (!($DB->Query($sql, true, "File: ".__FILE__."<br>Line: ".__LINE__)))
		{
			$result->addError(new Sale\ResultError(Loc::getMessage('SALE_COMPATIBLE_'.$entityName.'_RAW_FIELD_UPDATE_ERROR'), 'SALE_'.$entityName.'_COMPATIBLE_RAW_FIELD_UPDATE_ERROR'));
			return $result;
		}

		return $result;
	}

	/**
	 * @param $entityName
	 * @param array $fields
	 * @param string $separator
	 *
	 * @return array
	 * @throws ArgumentOutOfRangeException
	 */
	public static function backRawField($entityName, array $fields, $separator = '=')
	{
		if (!static::checkEntityName($entityName))
		{
			throw new ArgumentOutOfRangeException('entityName');
		}

		if (empty($fields))
			return array();

		foreach($fields as $name => $value)
		{
			$fields[$separator.$name] = $value;
			unset($fields[$name]);
		}

		return $fields;
	}


	protected function getWhiteListFields()
	{
		return array_merge($this->getAvailableFields(), $this->getSelectFields());
	}

	/**
	 * @param $fieldName
	 *
	 * @return bool
	 */
	protected function checkWhiteListFields($fieldName)
	{
		$fields = $this->getWhiteListFields();
		if (!empty($fields))
		{
			if (in_array($fieldName, $fields))
				return true;

			if (strpos($fieldName, 'UF_') === 0)
				return true;
		}

		return false;
	}


}

Zerion Mini Shell 1.0