- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/entity_query.php
- Класс: CEntityQuery
- Вызов: CEntityQuery::buildJoinMap
protected function buildJoinMap()
{
// list of used joins
$done = array();
$talias_count = 0;
foreach ($this->global_chains as $chain)
{
if ($chain->getLastElement()->getParameter('talias'))
{
// already been here
continue;
}
// in NO_DOUBLING mode skip 1:N relations that presented in filter only
if (!$this->data_doubling && $chain->hasBackReference())
{
$alias = $chain->getAlias();
if (isset($this->filter_chains[$alias])
&& !isset($this->select_chains[$alias]) && !isset($this->select_expr_chains[$alias])
&& !isset($this->group_chains[$alias]) && !isset($this->order_chains[$alias])
)
{
continue;
}
}
$prev_entity = $this->init_entity;
$prev_alias = CBaseEntity::camel2snake($this->init_entity->getName());
$map_key = '';
/**
* elemenets after init entity
* @var $elements CEntityQueryChainElement[]
* */
$elements = array_slice($chain->getAllElements(), 1);
foreach ($elements as $element)
{
$table_alias = null;
/**
* define main objects
* @var $src_entity CBaseEntity
* @var $ref_field CReferenceEntityField
* @var $dst_entity CBaseEntity
*/
if ($element->getValue() instanceof CReferenceEntityField)
{
// ref to another entity
$src_entity = $prev_entity;
$ref_field = $element->getValue();
$dst_entity = $ref_field->getRefEntity();
}
elseif (is_array($element->getValue())
)
{
// link from another entity to this
$src_entity = $prev_entity;
list($dst_entity, $ref_field) = $element->getValue();
}
else
{
// scalar field
$element->setParameter('talias', $prev_alias.$this->table_alias_postfix);
continue;
}
// mapping
if (empty($map_key))
{
$map_key = $src_entity->getName();
}
$map_key .= '/' . $ref_field->getName() . '/' . $dst_entity->getName();
if (isset($done[$map_key]))
{
// already connected
$table_alias = $done[$map_key];
}
else
{
// prepare reference
$reference = $ref_field->getReference();
if ($element->getValue() instanceof CReferenceEntityField)
{
// ref to another entity
if (is_null($table_alias))
{
$table_alias = $prev_alias.'_'.strtolower($ref_field->getName());
if (strlen($table_alias.$this->table_alias_postfix) > $this->DB->alias_length)
{
$table_alias = 'TALIAS'.$this->table_alias_postfix.'_' . (++$talias_count);
}
}
$alias_this = $prev_alias;
$alias_ref = $table_alias;
}
elseif (is_array($element->getValue()))
{
if (is_null($table_alias))
{
$table_alias = CBaseEntity::camel2snake($dst_entity->getName()) . '_' . strtolower($ref_field->getName());
$table_alias = $prev_alias.'_'.$table_alias;
if (strlen($table_alias.$this->table_alias_postfix) > $this->DB->alias_length)
{
$table_alias = 'TALIAS'.$this->table_alias_postfix.'_' . (++$talias_count);
}
}
$alias_this = $table_alias;
$alias_ref = $prev_alias;
if ($dst_entity->isUtm())
{
// add to $reference
$reference = array(
$reference,
'=this.FIELD_ID' => array('?i', $element->getParameter('ufield')->getFieldId())
);
}
}
// replace this. and ref. to real definition -- not supported yet
// instead it we set $alias_this and $alias_ref
$csw_reference = $this->prepareJoinReference(
$reference, $alias_this.$this->table_alias_postfix, $alias_ref.$this->table_alias_postfix
);
$join = array(
'type' => $ref_field->getJoinType(),
'table' => $dst_entity->getDbTableName(),
'alias' => $table_alias.$this->table_alias_postfix,
'reference' => $csw_reference
);
$this->join_map[] = $join;
$done[$map_key] = $table_alias;
}
// set alias for each element
$element->setParameter('talias', $table_alias.$this->table_alias_postfix);
$prev_entity = $dst_entity;
$prev_alias = $table_alias;
}
}
}