• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/orm/query/query.php
  • Класс: Bitrix\Main\ORM\Query\Query
  • Вызов: Query::collectExprChains
protected function collectExprChains(Chain $chain, $storages = array('hidden'))
{
	$last_elem = $chain->getLastElement();
	$bf_chains = $last_elem->getValue()->getBuildFromChains();

	$pre_chain = clone $chain;
	//$pre_chain->removeLastElement();
	$scopedBuildFrom = [];

	foreach ($bf_chains as $bf_chain)
	{
		// collect hidden chain
		$tmp_chain = clone $pre_chain;

		// exclude init entity
		/** @var ChainElement[] $bf_elements */
		$bf_elements = array_slice($bf_chain->getAllElements(), 1);

		// add elements
		foreach ($bf_elements as $bf_element)
		{
			$tmp_chain->addElement($bf_element);
		}

		//if (!($bf_chain->getLastElement()->getValue() instanceof ExpressionField))
		{
			foreach ($storages as $storage)
			{
				$reg_chain = $this->registerChain($storage, $tmp_chain);
			}

			// replace "build_from" chain end by registered chain end
			// actually it's better and more correctly to replace the whole chain
			$bf_chain->removeLastElement();
			/** @var Chain $reg_chain */
			$bf_chain->addElement($reg_chain->getLastElement());

			// return buildFrom elements with original start of chain for this query
			$scoped_bf_chain = clone $pre_chain;
			$scoped_bf_chain->removeLastElement();

			// copy tail from registered chain
			$tail = array_slice($reg_chain->getAllElements(), $pre_chain->getSize());

			foreach ($tail as $tailElement)
			{
				$scoped_bf_chain->addElement($tailElement);
			}

			$scopedBuildFrom[] = $scoped_bf_chain;
		}

		// check elements to recursive collect hidden chains
		foreach ($bf_elements as $bf_element)
		{
			if ($bf_element->getValue() instanceof ExpressionField)
			{
				$this->collectExprChains($tmp_chain);
			}
		}
	}

	return $scopedBuildFrom;
}