• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/provider/taskfilterbuilder.php
  • Класс: BitrixTasksProviderTaskFilterBuilder
  • Вызов: TaskFilterBuilder::optimizeFilter
private function optimizeFilter(array $filter): self
{
	// get rid of ::SUBFILTER-ROOT if can
	if (
		array_key_exists('::SUBFILTER-ROOT', $filter)
		&& count($filter) === 1
	)
	{
		if ($filter['::LOGIC'] != 'OR')
		{
			// we have only one element in the root, and logic is not "OR". then we could remove subfilter-root
			$filter = $filter['::SUBFILTER-ROOT'];
		}
	}

	// we can optimize only if there is no "or-logic"
	if (
		(
			isset($filter['::LOGIC'])
			&& $filter['::LOGIC'] === 'OR'
		) || (
			isset($filter['LOGIC'])
			&& $filter['LOGIC'] === 'OR'
		)
	)
	{
		return $this;
	}

	$join = Join::on('this.ID', 'ref.TASK_ID');

	// MEMBER
	if (
		array_key_exists('MEMBER', $filter)
		||
		(
			isset($filter[self::FILTER_ROLE_KEY])
			&& array_key_exists('MEMBER', $filter[self::FILTER_ROLE_KEY])
		)
	)
	{
		if (array_key_exists('MEMBER', $filter))
		{
			$member = intval($filter['MEMBER']);
			unset($filter['MEMBER']);
		}
		else
		{
			$member = intval($filter[self::FILTER_ROLE_KEY]['MEMBER']);
			unset($filter[self::FILTER_ROLE_KEY]);
		}

		$join->where('ref.USER_ID', $member);
	}
	// DOER
	elseif (array_key_exists('DOER', $filter))
	{
		$doer = intval($filter['DOER']);
		unset($filter['DOER']);

		$join
			->where('ref.USER_ID', $doer)
			->whereIn('ref.TYPE', [MemberTable::MEMBER_TYPE_RESPONSIBLE, MemberTable::MEMBER_TYPE_ACCOMPLICE]);
	}
	// RESPONSIBLE
	elseif (
		isset($filter[self::FILTER_ROLE_KEY])
		&& array_key_exists('=RESPONSIBLE_ID', $filter[self::FILTER_ROLE_KEY])
	)
	{
		$responsible = (int)$filter[self::FILTER_ROLE_KEY]['=RESPONSIBLE_ID'];
		unset($filter[self::FILTER_ROLE_KEY]);

		$join
			->where('ref.USER_ID', $responsible)
			->where('ref.TYPE', MemberTable::MEMBER_TYPE_RESPONSIBLE);
	}
	// CREATOR
	elseif (
		isset($filter[self::FILTER_ROLE_KEY])
		&& array_key_exists('=CREATED_BY', $filter[self::FILTER_ROLE_KEY])
	)
	{
		$creator = (int)$filter[self::FILTER_ROLE_KEY]['=CREATED_BY'];
		unset($filter[self::FILTER_ROLE_KEY]['=CREATED_BY']);

		if (!empty($filter[self::FILTER_ROLE_KEY]))
		{
			$filter += $filter[self::FILTER_ROLE_KEY];
		}
		unset($filter[self::FILTER_ROLE_KEY]);

		$join
			->where('ref.USER_ID', $creator)
			->where('ref.TYPE', MemberTable::MEMBER_TYPE_ORIGINATOR);
	}
	// ACCOMPLICE
	elseif (
		array_key_exists('ACCOMPLICE', $filter)
		||
		(
			isset($filter[self::FILTER_ROLE_KEY])
			&& array_key_exists('=ACCOMPLICE', $filter[self::FILTER_ROLE_KEY])
		)
	)
	{
		if (array_key_exists('ACCOMPLICE', $filter))
		{
			if (!is_array($filter['ACCOMPLICE'])) // we have single value, not array which will cause "in ()" instead of =
			{
				$accomplice = intval($filter['ACCOMPLICE']);
				unset($filter['ACCOMPLICE']);

				$join
					->where('ref.USER_ID', $accomplice)
					->where('ref.TYPE', MemberTable::MEMBER_TYPE_ACCOMPLICE);
			}
		}
		elseif (!is_array($filter[self::FILTER_ROLE_KEY]['=ACCOMPLICE']))
		{
			$accomplice = intval($filter[self::FILTER_ROLE_KEY]['=ACCOMPLICE']);
			unset($filter[self::FILTER_ROLE_KEY]);

			$join
				->where('ref.USER_ID', $accomplice)
				->where('ref.TYPE', MemberTable::MEMBER_TYPE_ACCOMPLICE);
		}
	}
	// AUDITOR
	elseif (
		array_key_exists('AUDITOR', $filter)
		||
		(
			isset($filter[self::FILTER_ROLE_KEY])
			&& array_key_exists('=AUDITOR', $filter[self::FILTER_ROLE_KEY])
		)
	)
	{
		if (array_key_exists('AUDITOR', $filter))
		{
			if (!is_array($filter['AUDITOR'])) // we have single value, not array which will cause "in ()" instead of =
			{
				$auditor = intval($filter['AUDITOR']);
				unset($filter['AUDITOR']);

				$join
					->where('ref.USER_ID', $auditor)
					->where('ref.TYPE', MemberTable::MEMBER_TYPE_AUDITOR);
			}
		}
		elseif (!is_array($filter[self::FILTER_ROLE_KEY]['=AUDITOR']))
		{
			$auditor = intval($filter[self::FILTER_ROLE_KEY]['=AUDITOR']);
			unset($filter[self::FILTER_ROLE_KEY]);

			$join
				->where('ref.USER_ID', $auditor)
				->where('ref.TYPE', MemberTable::MEMBER_TYPE_AUDITOR);
		}
	}
	else
	{
		return $this;
	}

	$this->registerRuntimeField(
		TaskQueryBuilder::ALIAS_TASK_MEMBER,
		(new ReferenceField(
			TaskQueryBuilder::ALIAS_TASK_MEMBER,
			MemberTable::getEntity(),
			$join
		))->configureJoinType('inner')
	);

	return $this;
}