chelishchev / bitrix-talks-2022

Demo code
18 stars 6 forks source link

Controller::configureActions() #1

Closed extdesign closed 2 years ago

extdesign commented 2 years ago

Извините, не успел задать вопрос во время передачи. Решил сюда написать. Если что, то просто удалите.

Использую контроллеры. Может что изменилось в последних версиях (полгода, как новый контроллер не создавал), но вот раньше не мог в configureActions() прописать какой-то универсальный код проверок в prefilters, чтобы для всех Actions действовал или комбинацию (допустим для getAction и fetchAction один prefilters, а для setId другой. Приходится для каждого Action свой prefilters указывать. Если возвращать в configureActions массив с prefilters, то не срабатывает, а как объединить несколько "действий" и применить к ним правила, то же не понятно.

<?php

namespace MyModule\Main\Inter\Controller;

use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Engine\ActionFilter;

class Order extends Controller
{
    public function configureActions()
    {
        return [
            'fetchOrders' => [
                'prefilters' => [
                    new ActionFilter\Authentication(),
                    new ActionFilter\HttpMethod(
                        [
                            ActionFilter\HttpMethod::METHOD_GET,
                            ActionFilter\HttpMethod::METHOD_POST,
                        ]
                    ),
                    //new ActionFilter\Csrf(),
                ],
                'postfilters' => []
            ],
            'fetchStatuses' => [
                'prefilters' => [
                    new ActionFilter\Authentication(),
                    new ActionFilter\HttpMethod(
                        [
                            ActionFilter\HttpMethod::METHOD_GET,
                            ActionFilter\HttpMethod::METHOD_POST,
                        ]
                    ),
                ],
                'postfilters' => []
            ],
     ... и т.д.
    }

    public function fetchOrdersAction(array $params): array
    public function fetchStatusesAction(): array
}
chelishchev commented 2 years ago

Если я вас правильно понял, то можно организовать код так:

<?php

namespace MyModule\Main\Inter\Controller;

use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Engine\ActionFilter;

class Order extends Controller
{
    protected function getDefaultPreFilters()
    {
        return [
            new ActionFilter\Authentication(),
            new ActionFilter\HttpMethod(
                [
                    ActionFilter\HttpMethod::METHOD_GET,
                    ActionFilter\HttpMethod::METHOD_POST,
                ]
            ),
        ];
    }

    public function fetchOrdersAction(array $params): array
    {}
    public function fetchStatusesAction(): array
    {}
}

Внимание на getDefaultPreFilters. Этот метод говорит какие префильтры по умолчанию будут применены ко всем действия данного контроллера.

Если вам, надо в конкретном действии что-то добавить к дефолтным, то можно использовать "арифметику" префильтров. :

<?php

namespace MyModule\Main\Inter\Controller;

use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Engine\ActionFilter;

class Order extends Controller
{
    public function configureActions()
    {
        return [
                         //это равносильно array_merge($this->getDefaultPreFilters(), [new ActionFilter\Csrf()]
            'fetchStatuses' => [
                '+prefilters' => [
                    new ActionFilter\Csrf(),
                ]   
            ],
        ];
    }
        //...
}

Либо, если надо что-то убрать из дефолтных, то есть вариант "вычесть" все фильтры определенного типа

    public function configureActions()
    {
        return [
            'fetchStatuses' => [
                '-prefilters' => [
                    ActionFilter\HttpMethod::class,
                ]
            ],
        ];
    }

И конечно, можно описать сразу и "+" & "-".

extdesign commented 2 years ago

Класс! Спасибо! В документации нет ничего про getDefaultPreFilters, а когда изучал тему, в коде не нашел (или проглядел) данного метода. Про "+" & "-" знал, но не видел преимуществ, теперь с дефолтными префильтрами и механизмом "+" & "-" все становится намного проще.

p.s. про getDefaultPreFilters все же надо добавить в документацию...