• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/provider/taskquerybuilder.php
  • Класс: BitrixTasksProviderTaskQueryBuilder
  • Вызов: TaskQueryBuilder::joinByAlias
private function joinByAlias(string $alias): void
{
	if ($alias === self::ALIAS_TASK)
	{
		return;
	}

	if ($this->query->getEntity()->hasField($alias))
	{
		return;
	}

	switch ($alias)
	{
		case self::ALIAS_TASK_VIEW:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					ViewedTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
						->where('ref.USER_ID', $this->taskQuery->getBehalfUser())
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_FORUM_TOPIC:
			if (!BitrixMainLoader::includeModule('forum'))
			{
				break;
			}
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					TopicTable::getEntity(),
					Join::on('this.FORUM_TOPIC_ID', 'ref.ID')
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_FORUM_MESSAGE:
			if (!BitrixMainLoader::includeModule('forum'))
			{
				break;
			}
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					MessageTable::getEntity(),
					Join::on('this.FORUM_TOPIC_ID', 'ref.TOPIC_ID')
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_TASK_FAVORITE:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					FavoriteTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
						->where('ref.USER_ID', $this->taskQuery->getBehalfUser())
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_TASK_SORT:
			$filter = $this->taskQuery->getWhere();
			$groupId = $filter['GROUP_ID'] ?? null;
			$joinOn = $groupId
				? Join::on('this.ID', 'ref.TASK_ID')->where('ref.GROUP_ID', $groupId)
				: Join::on('this.ID', 'ref.TASK_ID')->where('ref.USER_ID', $this->taskQuery->getBehalfUser());

			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					SortingTable::getEntity(),
					$joinOn
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_USER_CREATE:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					UserTable::getEntity(),
					Join::on('this.CREATED_BY', 'ref.ID')
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_USER_RESPONSIBLE:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					UserTable::getEntity(),
					Join::on('this.RESPONSIBLE_ID', 'ref.ID')
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_TASK_MEMBER_AUDITOR:
		case self::ALIAS_TASK_MEMBER_ACCOMPLICE:
			$memberType = ($alias === self::ALIAS_TASK_MEMBER_ACCOMPLICE)
				? MemberTable::MEMBER_TYPE_ACCOMPLICE
				: MemberTable::MEMBER_TYPE_AUDITOR;

			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					MemberTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
						->where('ref.TYPE', $memberType)
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_TASK_MEMBER:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					MemberTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
						->where('ref.USER_ID', $this->taskQuery->getBehalfUser())
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_TASK_COUNTERS:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					CounterTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
						->where('ref.USER_ID', $this->taskQuery->getBehalfUser())
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_SCRUM_ITEM:
			$this->joinByAlias(TaskQueryBuilder::ALIAS_SCRUM_ENTITY);

			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					ItemTable::getEntity(),
					Join::on('this.ID', 'ref.SOURCE_ID')
						->whereColumn('ref.ENTITY_ID', 'this.' . self::ALIAS_SCRUM_ENTITY . '.ID')
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_SCRUM_ITEM_B:
			$this->joinByAlias(TaskQueryBuilder::ALIAS_SCRUM_ENTITY_B);
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					ItemTable::getEntity(),
					Join::on('this.ID', 'ref.SOURCE_ID')
						->where('ref.ACTIVE', 'Y')
				))->configureJoinType('inner')
			);
			$this->query->whereExpr('%s = %s', [$alias.'.ENTITY_ID', self::ALIAS_SCRUM_ENTITY_B.'.ID']);
			break;

		case self::ALIAS_SCRUM_ENTITY:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					EntityTable::getEntity(),
					Join::on('this.GROUP_ID', 'ref.GROUP_ID')
						->where('ref.STATUS', EntityForm::SPRINT_ACTIVE)
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_SCRUM_ENTITY_B:
			$join = Join::on('this.GROUP_ID', 'ref.GROUP_ID');

			$filter = $this->taskQuery->getWhere();
			if (array_key_exists('SCRUM_ENTITY_IDS', $filter))
			{
				$join->whereIn('ref.ID', $filter['SCRUM_ENTITY_IDS']);
			}

			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					EntityTable::getEntity(),
					$join
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_SCRUM_ENTITY_C:
		case self::ALIAS_SCRUM_ENTITY_D:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					EntityTable::getEntity(),
					Join::on('this.GROUP_ID', 'ref.GROUP_ID')
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_SCRUM_ITEM_C:
			$this->joinByAlias(TaskQueryBuilder::ALIAS_SCRUM_ENTITY_C);
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					ItemTable::getEntity(),
					Join::on('this.ID', 'ref.SOURCE_ID')
				))->configureJoinType('inner')
			);
			$this->query->whereExpr('%s = %s', [$alias.'.ENTITY_ID', self::ALIAS_SCRUM_ENTITY_C.'.ID']);
			break;

		case self::ALIAS_SCRUM_ITEM_D:
			$this->joinByAlias(TaskQueryBuilder::ALIAS_SCRUM_ENTITY_D);

			$epicId = null;
			$filter = $this->taskQuery->getWhere();
			if (array_key_exists('EPIC', $filter))
			{
				$epicId = (int) $filter['EPIC'];
			}
			elseif (isset($filter['::SUBFILTER-EPIC']['EPIC']))
			{
				$epicId = (int) $filter['::SUBFILTER-EPIC']['EPIC'];
			}

			if (!$epicId)
			{
				break;
			}

			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					ItemTable::getEntity(),
					Join::on('this.ID', 'ref.SOURCE_ID')
						->where('ref.EPIC_ID', $epicId)
				))->configureJoinType('inner')
			);
			$this->query->whereExpr('%s = %s', [$alias.'.ENTITY_ID', self::ALIAS_SCRUM_ENTITY_D.'.ID']);
			break;

		case self::ALIAS_TASK_STAGES:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					TaskStageTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_TASK_TAG:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					TaskTagTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_TASK_SCENARIO:
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					ScenarioTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
				))->configureJoinType('left')
			);
			break;

		case self::ALIAS_CHAT_TASK:
			if (!Loader::includeModule('im'))
			{
				break;
			}
			$this->query->registerRuntimeField(
				$alias,
				(new ReferenceField(
					$alias,
					LinkTaskTable::getEntity(),
					Join::on('this.ID', 'ref.TASK_ID')
				))->configureJoinType('inner')
			);
			break;

		case self::ALIAS_SEARCH_FULL:
			break;
	}
}