• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/entity/base.php
  • Класс: BitrixMainEntityBase
  • Вызов: Base::getInstanceByQuery
static function getInstanceByQuery(Query $query, &$entity_name = null)
{
	if ($entity_name === null)
	{
		$entity_name = 'Tmp'.randString();
	}
	elseif (!preg_match('/^[a-z0-9_]+$/i', $entity_name))
	{
		throw new MainArgumentException(sprintf(
			'Invalid entity name `%s`.', $entity_name
		));
	}

	$query_string = '('.$query->getQuery().')';
	$query_chains = $query->getChains();

	$replaced_aliases = array_flip($query->getReplacedAliases());

	// generate fieldsMap
	$fieldsMap = array();

	foreach ($query->getSelect() as $k => $v)
	{
		// convert expressions to regular field, clone in case of regular scalar field
		if (is_array($v))
		{
			// expression
			$fieldsMap[$k] = array('data_type' => $v['data_type']);
		}
		else
		{
			if ($v instanceof ExpressionField)
			{
				$fieldDefinition = $v->getName();

				// better to initialize fields as objects after entity is created
				$dataType = Field::getOldDataTypeByField($query_chains[$fieldDefinition]->getLastElement()->getValue());
				$fieldsMap[$fieldDefinition] = array('data_type' => $dataType);
			}
			else
			{
				$fieldDefinition = is_numeric($k) ? $v : $k;

				/** @var Field $field */
				$field = $query_chains[$fieldDefinition]->getLastElement()->getValue();

				if ($field instanceof ExpressionField)
				{
					$dataType = Field::getOldDataTypeByField($query_chains[$fieldDefinition]->getLastElement()->getValue());
					$fieldsMap[$fieldDefinition] = array('data_type' => $dataType);
				}
				else
				{
					/** @var ScalarField[] $fieldsMap */
					$fieldsMap[$fieldDefinition] = clone $field;
					$fieldsMap[$fieldDefinition]->setName($fieldDefinition);
					$fieldsMap[$fieldDefinition]->setColumnName($fieldDefinition);
					$fieldsMap[$fieldDefinition]->resetEntity();
				}
			}
		}

		if (isset($replaced_aliases[$k]))
		{
			if (is_array($fieldsMap[$k]))
			{
				$fieldsMap[$k]['column_name'] = $replaced_aliases[$k];
			}
			elseif ($fieldsMap[$k] instanceof ScalarField)
			{
				/** @var ScalarField[] $fieldsMap */
				$fieldsMap[$k]->setColumnName($replaced_aliases[$k]);
			}
		}
	}

	// generate class content
	$eval = 'class '.$entity_name.'Table extends '.__NAMESPACE__.'DataManager {'.PHP_EOL;
	$eval .= 'public static function getMap() {'.PHP_EOL;
	$eval .= 'return '.var_export(array('TMP_ID' => array('data_type' => 'integer', 'primary' => true)), true).';'.PHP_EOL;
	$eval .= '}';
	$eval .= 'public static function getTableName() {'.PHP_EOL;
	$eval .= 'return '.var_export($query_string, true).';'.PHP_EOL;
	$eval .= '}';
	$eval .= '}';

	eval($eval);

	$entity = self::getInstance($entity_name);

	foreach ($fieldsMap as $k => $v)
	{
		$entity->addField($v, $k);
	}

	return $entity;
}