- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/lib/orm/fields/relations/manytomany.php
- Класс: BitrixMainORMFieldsRelationsManyToMany
- Вызов: ManyToMany::getMediatorEntity
public function getMediatorEntity()
{
if ($this->mediatorEntity === null)
{
if (!empty($this->mediatorEntityName) && Entity::has($this->mediatorEntityName))
{
$this->mediatorEntity = Entity::getInstance($this->mediatorEntityName);
}
else
{
// there is no described mediator entity
// check table_name first, entity can not exist without it
if (empty($this->mediatorTableName))
{
throw new ArgumentException(sprintf(
'Table Name for mediator entity of relation `%s` between %s and %s was not found',
$this->name, $this->getEntity()->getObjectClass(), $this->getRefEntity()->getObjectClass()
));
}
// generate mediator entity runtime
if (empty($this->mediatorEntityName))
{
$localEntityName = $this->getEntity()->getName();
$remoteEntityName = $this->getRefEntity()->getName();
$fieldToClassName = StringHelper::snake2camel($this->name);
// each field has its own entity in case of ManyToMany definitions will be different
$this->mediatorEntityName = "MediatorFrom{$localEntityName}To{$remoteEntityName}Via{$fieldToClassName}Table";
}
// fields of mediator entity
$fields = [];
// local entity primary
$localReferenceConditions = Query::filter();
foreach ($this->getEntity()->getPrimaryArray() as $primaryName)
{
$mediatorPrimaryName = $this->localPrimaryNames[$primaryName] ?? $this->getLocalReferenceName().'_'.$primaryName;
$fieldType = get_class($this->getEntity()->getField($primaryName));
/** @var BitrixMainORMFieldsScalarField $mediatorPrimary */
$mediatorPrimary = new $fieldType($mediatorPrimaryName);
$mediatorPrimary->configurePrimary(true);
$fields[] = $mediatorPrimary;
// save join condition for reference
$localReferenceConditions->whereColumn('this.'.$mediatorPrimaryName, 'ref.'.$primaryName);
}
// local reference
$localReference = (new Reference($this->getLocalReferenceName(), $this->getEntity(), $localReferenceConditions))
->configureJoinType($this->joinType);
$fields[] = $localReference;
// remote entity primary
$remoteReferenceConditions = Query::filter();
foreach ($this->getRefEntity()->getPrimaryArray() as $primaryName)
{
$mediatorPrimaryName = $this->remotePrimaryNames[$primaryName] ?? $this->getRemoteReferenceName().'_'.$primaryName;
$fieldType = get_class($this->getRefEntity()->getField($primaryName));
/** @var BitrixMainORMFieldsScalarField $mediatorPrimary */
$mediatorPrimary = new $fieldType($mediatorPrimaryName);
$mediatorPrimary->configurePrimary(true);
$fields[] = $mediatorPrimary;
// save join condition for reference
$remoteReferenceConditions->whereColumn('this.'.$mediatorPrimaryName, 'ref.'.$primaryName);
}
// remote reference
$remoteReference = (new Reference($this->getRemoteReferenceName(), $this->getRefEntity(), $remoteReferenceConditions))
->configureJoinType($this->joinType);
$fields[] = $remoteReference;
// set table name
$parameters = ['table_name' => $this->mediatorTableName];
// finalize
$this->mediatorEntity = Entity::compileEntity($this->mediatorEntityName, $fields, $parameters);
}
}
return $this->mediatorEntity;
}