• Модуль: 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;
}