В деятельности разработчиков на Bitrix Framework рано или поздно возникает необходимость использования контроллера. Встретиться с ним придётся в компонентах, модулях и при работе с собственным роутингом. Однако документации на эту тему не хватает, она крайне ограничена, не предоставляет ясности относительно уже реализованных методов и их правильного применения. Из-за этого требуется постоянно изучать исходники. В статье рассмотрим лишь небольшой, но важный аспект этого вопроса на примере собственного роутинга
https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&CHAPTER_ID=013764&LESSON_PATH=3913.3516.5062.13764
Итак, у нас есть собственный контроллер, унаследованный от \Bitrix\Main\Engine\Controller.
Полезные методы, доступные в нём:
Метод processBeforeAction предоставляет возможность выполнения дополнительных проверок или предварительной обработки данных перед тем, как будет вызван конкретный метод-действие контроллера. Если метод processBeforeAction возвращает false, выполнение действия контроллера и всех последующих этапов обработки запроса прекращается.
Пример логгирования внутри метода processBeforeAction
protected function processBeforeAction($action)
{
logger(static::class)->info(
print_r([
"fields" => $this->getFields(),
"files" => $this->getFiles(),
"page" => $this->getRequest()->getRequestUri(),
"method" => $this->getRequest()->getRequestMethod()
], true)
);
return true;
}
Метод finalizeResponse может быть использован для выполнения определенных действий после завершения обработки запроса, независимо от того, было ли выполнено действие контроллера или возникли какие-либо ошибки. Этот метод вызывается после завершения всех этапов обработки запроса и готовности отправить ответ клиенту. Метод можно использовать для логгирования, сбора статистики, манипуляции с кэшем, запуска выполнения backgroundJob.
Метод processAfterAction похож, на finalizeResponse, но может быть не вызван, в случае выбрасывания Exception.
В мире веб-разработки неотъемлемой частью становится использование инструментов, которые помогают эффективно управлять запросами и обрабатывать данные. Одним из интересных аспектов Bitrix Framework являются пре- и пост-фильтры, которые регулируют поток информации ещё до того, как он достигнет контроллера, и после того, как контроллер завершил свою работу.
- Пре фильтры срабатывают до вызова Action у контроллера. Пре-фильтры в Битриксе можно рассматривать как middleware, предназначенные для выполнения проверок и предварительной обработки данных перед тем, как запрос достигнет контроллера. Это мощный инструмент, позволяющий осуществлять валидацию, авторизацию, а также производить другие манипуляции с запросом до того, как он начнет свое воздействие на логику приложения.
- Пост фильтры срабатывают после выполнения контроллера. Они предоставляют возможность воздействовать на уже готовые данные перед тем, как они будут отправлены. Пост фильтры позволяют осуществлять финальную обработку, модификацию ответа и другие операции, завершая жизненный цикл запроса.
Вместе пре- и пост-фильтры предоставляют разработчикам Битрикса мощный инструментарий для управления потоком данных и обеспечивают более гибкий и контролируемый процесс обработки запросов.
Пре-фильтры, которые использует контроллер по умолчанию:
- Authentication проверяет авторизован ли пользователь
- HttpMethod ограничивает метод запроса
- Csrf. CSRF-токен используется для защиты от атак, связанных с подделкой межсайтовых запросов. Фильтр проверяет наличие и валидность CSRF-токена
use Bitrix\Main\Engine\ActionFilter;
protected function getDefaultPreFilters()
{
return [
new ActionFilter\Authentication(),
new ActionFilter\HttpMethod(
[ActionFilter\HttpMethod::METHOD_GET, ActionFilter\HttpMethod::METHOD_POST]
),
new ActionFilter\Csrf(),
];
}
Если требуется изменить пре фильтры по умолчанию, достаточно переопределить метод getDefaultPreFilters. В котором нужно вернуть массив с объектами.
Так же пре- и пост-фильтры можно указывать для каждого конкретного Action у контроллера.
Для этого требуется переопределить метод configureActions, в котором вернуть массив, где первым ключом передаётся Action name, без префикса Action, а в дальнейшей вложенности с помощью + или – можно указывать пре- или пост-фильтры, которые необходимо добавить или удалить.
public function configureActions()
{
return [
'registerUser' => [
'-prefilters' => [
ActionFilter\Csrf::class,
ActionFilter\Authentication::class
],
'+prefilters' => [
new ApiKey,
],
'+postfilters' => [
new FormatData
]
]
];
}
Либо просто передать массив используемых пре/пост фильтров
public function configureActions()
{
return [
'registerUser' => [
'prefilters' => [
ActionFilter\Csrf::class,
ActionFilter\Authentication::class
],
'postfilters' => [
new FormatData
]
]
];
}
Удобный пре-фильтр для работы с json. По умолчанию для работы с json требовалось получить payload и разбирать его содержимое.
$jsonPayload = new \Bitrix\Main\Engine\JsonPayload(); $jsonPayload->getData();
Если применить пре-фильтр ContentType с параметром application/json, то в наш контроллер придут отдельные переменные, каждая со своим типом.
use Bitrix\Main\Engine\ActionFilter\ContentType;
public function getDefaultPreFilters(): array
{
return [
new ContentType([ContentType::JSON])
];
}
public function jsonExampleAction(bool $test, array $test2)
{
}
Реализация собственных пре-фильтров. Чтобы реализовать свой пре/пост фильтр, нужно унаследовать свой класс от Bitrix\Main\Engine\ActionFilter\Base.
Для пре-фильтра нужно переопределить метод onBeforeAction, в который передаётся экземпляр класса Event. Для того, чтобы выбросить ошибку и прервать дальнейшее выполнение методов контроллера, достаточно вызвать addError и вернуть в методе EventResult, передав параметры как в примере.
Пример пре-фильтра, который проверяет заголовок на наличие API-KEY и запрещает дальнейшие действия, если он не совпадает с заданным значением.
use Bitrix\Main\EventResult;
use Bitrix\Main\Engine\ActionFilter\Base;
class ApiKey extends Base
{
public function onBeforeAction(Event $event)
{
$apiKey = Context::getCurrent()->getRequest()->getHeader('API-KEY');
if ($apiKey !== 'TESTKEY')
{
$this->addError(new Error('Wrong API key'));
return new EventResult(EventResult::ERROR, null, null, $this);
}
return null;
}
}
Параметры для вызова EventResult
__Bitrix\Main\EventResult::construct
public function __construct(
$type,
$parameters = null,
$moduleId = null,
$handler = null
) { }
Для создания пост-фильтра требуется переопределить метод onAfterAction
Пример пост-фильтра
use Bitrix\Main\Engine\ActionFilter\Base;
class FormatData extends Base
{
public function onAfterAction(Event $event)
{
$result = $event->getParameter('result');
$event->setParameter('result', [
'level' => 'one',
'result' => $result
]);
}
}
Важно помнить, требуется не только знать документацию, но и постоянно следить за изменениями и улучшениями в продукте. Разработчики регулярно выпускают обновления и доработки, поэтому периодический анализ исходного кода может принести дополнительные возможности и оптимизации, не всегда описанные в документации.
Появление контроллеров в Bitrix стало настоящим прорывом, освободив разработчиков от необходимости размещать PHP-скрипты по всему сайту для работы с AJAX. Теперь задачи, связанные с обработкой запросов и управлением данными, решаются удобно и эффективно с помощью контроллеров.
Контроллеры предлагают элегантное решение для многих типовых задач, облегчая процесс разработки веб-приложений на платформе Bitrix. Их использование позволяет создавать более надежные и масштабируемые приложения, обеспечивая высокую производительность и удобство в обслуживании.