%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/main/lib/orm/fields/relations/ |
Current File : //home/bitrix/www/bitrix/modules/main/lib/orm/fields/relations/reference.php |
<?php /** * Bitrix Framework * @package bitrix * @subpackage main * @copyright 2001-2012 Bitrix */ namespace Bitrix\Main\ORM\Fields\Relations; use Bitrix\Main\ArgumentException; use Bitrix\Main\ORM\Entity; use Bitrix\Main\ORM\Fields\FieldTypeMask; use Bitrix\Main\ORM\Query\Filter\ConditionTree as Filter; use Bitrix\Main\ORM\Data\Result; use Bitrix\Main\ORM\Query\Filter\Expressions\ColumnExpression; use Bitrix\Main\Error; use Bitrix\Main\SystemException; /** * Reference field describes relation 1-to-1 or 1-to-many between two entities * @package bitrix * @subpackage main */ class Reference extends Relation { /** @var array|Filter */ protected $reference; protected $join_type = 'LEFT'; const ELEMENTAL_THIS = 1; const ELEMENTAL_REF = 2; const ELEMENTAL_BOTH = 3; /** * @param string $name * @param string|Entity $referenceEntity * @param array|Filter $referenceFilter * @param array $parameters deprecated, use configure* and add* methods instead * * @throws ArgumentException * @throws SystemException */ public function __construct($name, $referenceEntity, $referenceFilter, $parameters = array()) { parent::__construct($name); if ($referenceEntity instanceof Entity) { $this->refEntity = $referenceEntity; $this->refEntityName = $referenceEntity->getFullName(); } else { // this one could be without leading backslash and/or with Table-postfix $this->refEntityName = Entity::normalizeName($referenceEntity); } if (empty($referenceFilter)) { throw new ArgumentException('Reference for `'.$name.'` shouldn\'t be empty'); } $this->reference = $referenceFilter; if (isset($parameters['join_type'])) { $join_type = strtoupper($parameters['join_type']); if (in_array($join_type, array('LEFT', 'INNER', 'RIGHT'), true)) { $this->join_type = $join_type; } } } public function getTypeMask() { return FieldTypeMask::REFERENCE; } /** * @param $type * * @return $this * @throws ArgumentException */ public function configureJoinType($type) { $type = strtoupper($type); if (!in_array($type, ['LEFT', 'INNER', 'RIGHT'], true)) { throw new ArgumentException(sprintf( 'Unknown join type `%s` in reference `%s` of `%s` entity', $type, $this->name, $this->entity->getDataClass() )); } $this->join_type = $type; return $this; } /** * @param $value * @param $primary * @param $row * @param Result $result * * @return Result * @throws ArgumentException * @throws SystemException */ public function validateValue($value, $primary, $row, Result $result) { $remoteObjectClass = $this->getRefEntity()->getObjectClass(); if ($value !== null && !($value instanceof $remoteObjectClass)) { $result->addError(new Error(sprintf( 'Expected instance of `%s`, got `%s` instead', $remoteObjectClass, get_class($value) ))); } return parent::validateValue($value, $primary, $row, $result); } public function getDataType() { return $this->refEntityName; } public function getReference() { return $this->reference; } public function getJoinType() { return $this->join_type; } /** * Returns set of strictly linked fields of this and ref entities [localFieldName => remoteFieldName] * * @return array|bool */ public function getElementals() { if (!($this->reference instanceof Filter)) { return false; } $elemental = []; foreach ($this->reference->getConditions() as $condition) { if (!($condition->getValue() instanceof ColumnExpression) || $condition->getOperator() != '=' ) { continue; } // ok, we have a column filter. one should be `this.` and another one `ref.` $col1 = $condition->getColumn(); $col2 = $condition->getValue()->getDefinition(); $col1Flag = static::getElementalFlag($col1); $col2Flag = static::getElementalFlag($col2); if (($col1Flag + $col2Flag) == static::ELEMENTAL_BOTH) { // we have this and ref link $key = ($col1Flag == static::ELEMENTAL_THIS) ? $col1 : $col2; $value = ($col1Flag == static::ELEMENTAL_REF) ? $col1 : $col2; // cut .this and .ref from the start of definitions $key = substr($key, 5); $value = substr($value, 4); $elemental[$key] = $value; } } return $elemental; } protected static function getElementalFlag($definition) { if (substr_count($definition, '.') == 1) { if (strpos($definition, 'this.') === 0) { return static::ELEMENTAL_THIS; } elseif (strpos($definition, 'ref.') === 0) { return static::ELEMENTAL_REF; } } return 0; } }