%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/modules/sale/lib/compatible/internals/ |
| 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;
}
}