%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/main/lib/orm/fields/relations/
Upload File :
Create Path :
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;
	}
}



Zerion Mini Shell 1.0