Поиск задач
Table of Contents
Заменой устаревшему CTasks::getList считаются:
- Верхнуровневый фасад для legacy-замены
Bitrix\Tasks\Provider\TaskProvider. - Текущий низкоуровневый провайдер
Bitrix\Tasks\Provider\TaskList. - Экспериментальный провайдер возвращающий доменные сущности
Bitrix\Tasks\V2\Public\Provider\TaskProvider.
TaskProvider
Класс-провайдера получения результатов с обратной-совместимостью Bitrix\Tasks\Provider\TaskProvider схематично можно представить его так:
namespace Bitrix\Tasks\Provider;
class TaskProvider
{
/**
* @throws InvalidGroupByException
* @throws CTaskAssertException
* @throws TasksException
*/
public function getList(
mixed $arOrder = [],
mixed $arFilter = [],
mixed $arSelect = [],
mixed $arParams = [],
array $arGroup = []
): CDBResult;
/**
* @throws InvalidGroupByException
* @throws CTaskAssertException
* @throws TasksException
*/
public function getCount(mixed $arFilter = [], mixed $arParams = [], mixed $arGroup = []): CDBResult;
}
Перед началом изучения важно отметить что
TaskProviderэто специализированная надстройка надTaskList, поэтому если вы хотите получить максимальную гибкость и совсем незначительный припрост производительности, то лучше сразу перейти к рассмотрениюTaskListдалее.
Поскольку под капотом TaskProvider::getList и TaskProvider::getCount имеют схожее поведение, давайте заберем ключ arParams и посмотрим на примеры запросов.
В качестве arParams принимаются следующие ключи:
nPageTop(int) - ограничение по количеству выбираемых записей. Если не передан - игнорируется.USER_ID(int) - текущий пользователь. По-умолчанию текущий пользователь, если не указан, но указанTARGET_USER_IDбудет заполнено изTARGET_USER_ID.TARGET_USER_ID(int) - пользователь, от лица которого выполняется действие. Если не указан будет аналогиченUSER_IDNAV_PARAMS(object) - структура описывающая постраничную навигацию: – ЛИБО должно быть заполнено__calculateTotalCount– ЛИБО должно быть заполненоnTopCount– ЛИБО должно быть заполненоnPageSize,iNumPageи не заполненоgetTotalCountMAKE_ACCESS_FILTER(bool|null) указывает на необходимость подключения фильтра по правамCHECK_PERMISSIONS(string: Y|N) - нужно ли проверять праваFILTER_PARAMS(object), структура описывающая дополнительные настройки для проверки прав. –SEARCH_TASK_ONLY(string: Y|N) - указывает на то что необходимо искать только в поисковом индексе задачи и не искать в комментариях
Примечание при передаче
CHECK_PERMISSIONSв arParams и вarFilterбудут учитывать оба. Если хотя бы в одном из массивов он будетNто проверки прав не будет.
Пример подсчета количества задач у которых в названии есть строка “тест” без учета прав текущего пользователя:
use Bitrix\Main\Loader;
use Bitrix\Tasks\Provider\TaskProvider;
use Throwable;
try {
Loader::requireModule('tasks');
$taskProvider = new TaskProvider();
$filter = [
'%TITLE' => 'тест'
];
$resCount = $taskProvider->getCount(
arFilter: $filter,
arParams: ['CHECK_PERMISSIONS' => 'N']
);
if ($arTaskCount = $resCount->fetch()) {
echo sprintf("Task with 'test' count: %d", $arTaskCount['CNT']);
}
} catch (Throwable $e) {
// @todo: log error instead of print error
var_dump($e);
}
Пример получения задач у которы в названии есть строка “тест” без учета прав текущего пользователя:
use Bitrix\Main\Loader;
use Bitrix\Tasks\Provider\TaskProvider;
use Throwable;
try {
Loader::requireModule('tasks');
$taskProvider = new TaskProvider();
$filter = [
'%TITLE' => 'тест'
];
$resCount = $taskProvider->getList(
arSelect: ["ID", "TITLE"],
arFilter: $filter,
arParams: ['CHECK_PERMISSIONS' => 'N']
);
/**
* @var array $arTaskItem
*/
while($arTaskItem = $resCount->fetch()) {
echo "<pre>";
var_dump($arTaskItem);
echo "</pre>";
}
} catch (Throwable $e) {
// @todo: log error instead of print error
var_dump($e);
}
TaskList
Гибкий низкоуровневый поиск по объекту фильтра Bitrix\Tasks\Provider\TaskList:
namespace Bitrix\Tasks\Provider;
use Bitrix\Tasks\Provider\Query\TaskQuery;
class TaskList
{
/**
* @param TaskQuery $query
* @return array
* @throws TaskListException
*/
public function getList(TaskQuery $query): array;
/**
* @param TaskQuery $query
* @return int
* @throws Exception\InvalidSelectException
* @throws Exception\UnexpectedTableException
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException
*/
public function getCount(TaskQuery $query): int;
}
Рассмотрим аналогичный ранее изученным примерам с использованием TaskList и TaskQuery:
use Bitrix\Main\Loader;
use Bitrix\Tasks\Provider\TaskList;
use Bitrix\Tasks\Provider\Query\TaskQuery;
use Throwable;
try {
Loader::requireModule('tasks');
$taskProvider = new TaskList();
$taskQuery = new TaskQuery(userId: 0);
$taskQuery->setSelect([
'ID', 'TITLE'
]);
$taskQuery->setWhere([
'%TITLE' => 'тест'
]);
$taskQuery->skipAccessCheck();
$listElements = $taskProvider->getList($taskQuery);
foreach ($listElements as $element) {
echo "<pre>";
var_dump($element);
echo "</pre>";
}
} catch (Throwable $e) {
// @todo: log error instead of print error
var_dump($e);
}
V2-exp TaskProvider
Экспериментальный провайдер реализует 3 публичных метода getList, getCount и get и схематично его можно представить его как:
namespace Bitrix\Tasks\V2\Public\Provider;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListParams;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskParams;
use Bitrix\Tasks\V2\Internal\Entity\Task;
use Bitrix\Tasks\V2\Internal\Entity\TaskCollection;
class TaskProvider {
public function getList(TaskListParams $taskListParams): TaskCollection;
public function getCount(TaskListParams $taskListParams): int;
public function get(TaskParams $taskParams): ?Task;
}
TaskProvider::get
Это метод отвечающий за получение конкретной задачи, когда вы знаете ее идентификатор.
Поскольку модуль содержит значительное количество бизнес-логики, нельзя просто так взять идентификатор задачи и получить то что нужно без лишнего.
Чтобы не перегружать метод дополнительными параметрами используется инкапсуляция опций в класс-параметр - Bitrix\Tasks\V2\Public\Provider\Params\TaskParams
Как выглядит сигнатура класса:
namespace Bitrix\Tasks\V2\Public\Provider\Params;
class TaskParams
{
public function __construct(
public readonly int $taskId,
public readonly int $userId,
public readonly bool $group = true,
public readonly bool $flow = true,
public readonly bool $stage = true,
public readonly bool $members = true,
public readonly bool $checkLists = true,
public readonly bool $tags = true,
public readonly bool $crm = true,
public readonly bool $email = true,
public readonly bool $subTasks = true,
public readonly bool $relatedTasks = true,
public readonly bool $gantt = true,
public readonly bool $placements = true,
public readonly bool $containsCommentFiles = true,
public readonly bool $favorite = true,
public readonly bool $options = true,
public readonly bool $parameters = true,
public readonly bool $results = true,
public readonly bool $reminders = true,
public readonly bool $userFields = true,
public readonly bool $checkTaskAccess = true,
public readonly bool $checkGroupAccess = true,
public readonly bool $checkFlowAccess = true,
public readonly bool $checkCrmAccess = true,
public readonly bool $checkParentAccess = true,
public readonly bool $view = false,
public readonly bool $scenarios = true,
) {}
}
Давайте рассмотрим основные параметры:
taskId- идентификатор задачи, которую вы хотите получитьuserId- идентификатор пользователя, из-под учетной записи которого вы хотите получить (может быть 0 для системных действий)check*Access- учитывать доступ для указанного (в userId) пользователя –checkTaskAccess- к задаче –checkGroupAccess- к проекту/группе –checkFlowAccess- к потоку –checkCrmAccess- к связанной crm сущности –checkParentAccess- к родительской задачеgroup,flow,stage,members,checkLists,tags,crm,email,subTasks,relatedTasks,gantt,placements,containsCommentFiles,favorite,options,parameters,results,reminders,userFields,view,scenarios- получать ли связанные с задачей сущности.
Если мы хотие получить задачу с ID:1, от лица пользователя ID: 2, при этом нам не нужны дополнительные параметры и пользователь явно никак в задаче не участвует, то код для получения такой задачи выглядит так:
use Bitrix\Tasks\V2\Public\Provider\TaskProvider;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskParams;
$taskProvider = new TaskProvider();
/**
* @var Bitrix\Tasks\V2\Internal\Entity\Task|null
*/
$entityTask = $taskProvider->get(new TaskParams(
taskId: 1,
userId: 2,
// Ignore permissions
checkTaskAccess: false,
checkGroupAccess: false,
checkFlowAccess: false,
checkCrmAccess: false,
checkParentAccess: false,
// Disable unused data
group: false,
flow: false,
stage: false,
members: false,
checkLists: false,
tags: false,
crm: false,
email: false,
subTasks: false,
relatedTasks: false,
gantt: false,
placements: false,
containsCommentFiles: false,
favorite: false,
options: false,
parameters: false,
results: false,
reminders: false,
userFields: false,
scenarios: false,
));
var_dump($entityTask);
На момент написания статьи существует и более короткий синтаксис:
use Bitrix\Tasks\V2\Public\Provider\TaskProvider;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskParams;
$taskProvider = new TaskProvider();
$taskParams = TaskParams::mapFromArray([
"taskId" => 1,
"userId" => 2
]);
$taskParams->checkTaskAccess = false;
$taskParams->checkGroupAccess = false;
$taskParams->checkFlowAccess = false;
$taskParams->checkCrmAccess = false;
$taskParams->checkParentAccess = false;
/**
* @var Bitrix\Tasks\V2\Internal\Entity\Task|null
*/
$entityTask = $taskProvider->get($taskParams);
var_dump($entityTask);
Сам по себе метод
TaskParams::mapFromArrayдостаточно полезный, потому что он позволяет динамически конфигурировать список запрашиваемых параметров.
TaskProvider::getList
Это метод отвечающий за получение неопределеного числа задачи, соответствующий критериям поиска.
Подобно TaskProvider::get он так же имеет множество настроек инкапсулированных в Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListParams, однако в своем исполнении он несколько проще поискольку представляет из себя прокси с стандартизированными интерфейсами.
namespace Bitrix\Tasks\V2\Public\Provider\Params\TaskList;
use Bitrix\Main\Provider\Params\FilterInterface;
use Bitrix\Main\Provider\Params\GridParams;
use Bitrix\Main\Provider\Params\PagerInterface;
use Bitrix\Main\Provider\Params\SelectInterface;
use Bitrix\Main\Provider\Params\SortInterface;
class TaskListParams extends GridParams
{
public function __construct(
public int $userId,
PagerInterface $pagination,
?FilterInterface $filter = null,
?SortInterface $sort = null,
?SelectInterface $select = null,
public bool $skipAccessCheck = false,
) {}
}
Рассмотрим параметры метода:
userId- идентификатор пользователя, от лица которого осуществляется поиск.pagination- параметры постраничной навигации для управления количеством элементов и сдвигом,filter- параметры фильтрации,sort- параметр сортировки,select- параметр выбираемых полейskipAccessCheck- нужно ли проверять права (все)
Поскольку FilterInterface, PagerInterface, SelectInterface, SortInterface являются лишь контрактами, в системе так же присутствует и реализация по-умолчанию которую можно использовать для наших нужд.
| Интерфейс | Реализация |
|---|---|
Bitrix\Main\Provider\Params\PagerInterface |
Bitrix\Main\Provider\Params\Pager |
Bitrix\Main\Provider\Params\FilterInterface |
Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListArrayFilter |
Bitrix\Main\Provider\Params\SortInterface |
Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListSort |
Bitrix\Main\Provider\Params\SelectInterface |
Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListSelect |
Давайте выполним простую задачу: мы получим все названия задач, которые начинаются со слова “тест” и созданы в период между 10 мая 2026 и 13 мая 2026, отсортированные по дате создания (убывание), без учета прав, в количестве 10 штук.
use Bitrix\Main\Loader;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListParams;
use Bitrix\Main\ORM\Query\Filter\ConditionTree;
use Bitrix\Main\Type\DateTime;
use Bitrix\Main\Provider\Params\Pager;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListArrayFilter;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListSort;
use Bitrix\Tasks\V2\Public\Provider\Params\TaskList\TaskListSelect;
use Bitrix\Tasks\V2\Public\Provider\TaskProvider;
use Throwable;
try {
Loader::requireModule('tasks');
// Формируем параметры
$params = new TaskListParams(
userId: 1, // От чьего имени выполняем поиск
pagination: new Pager(limit: 10, offset: 0),
filter: new TaskListArrayFilter([
'logic' => 'and',
['title', 'like', 'тест%'],
['createdDate', '>=', DateTime::createFromTimestamp(strtotime("10.06.2026 00:00:00"))],
['createdDate', '<=', DateTime::createFromTimestamp(strtotime("13.06.2026 00:00:00"))],
]),
sort: new TaskListSort([
'createdDate' => 'desc',
]),
select: new TaskListSelect([
'id', 'title'
]),
skipAccessCheck: true
);
// Выполняем поиск
$provider = new TaskProvider();
$tasks = $provider->getList($params);
foreach ($tasks as $task) {
/**
* @var $task \Bitrix\Tasks\V2\Internal\Entity\Task $task
*/
echo "ID: {$task->getId()}\n";
echo "Название: {$task->getTitle()}\n";
echo "---\n";
}
} catch (Throwable $e) {
// @todo Use error log instead of var_dump
var_dump($e);
}
Доступные поля
Доступность полей уточняйте в классе Bitrix\Tasks\V2\Public\Provider\Params\TaskList\FieldsEnum.