Программирование, веб-кодинг

Использование событий контроллера

Иногда вам необходимо доработать чьё-то расширение, которое вы взяли за основу. Вроде как основную вашу задачу оно решает, но надо расширить его функционал, сильно или не очень, добавить вашу логику, специфичную для вашего конкретного приложения.

Для этих целей можно либо заместить контроллер (или модель, или вид - смотря где надо вносить ваши изменения). Я уже писал про такое замещение. Другой же вариант - использовать события. Этот способ хорош, пожалуй, когда не требуется переписывать сильно чужой код, а вставить своё дополнение. И когда разработчик это учёл и навставлял в свой код в разных важных местах заготовки для вызовов событий.

Так сделано, например, в yii2-user. Расширение популярное, но действительно, для гибкости, требуется то редирект свой прописать, то какую-либо проверку свою. Все возможные события здесь вынесены в константы в начало контроллеров. И вы можете в конфиге прописать обработчик события.

Например, вот обработчик события, который будет редиректить пользователя на страницу входа после его успешной регистрации. По умолчанию, разработчик запрограммировал показывать пользователю сообщение на пустой странице. Он так увидел, может такая цель у него была. А мне нужно непременно переадресовывать пользователя на форму входа. Но вот в RegistrationController.php вижу триггер.

...
    if ($model->load(\Yii::$app->request->post()) && $model->register()) {
            $this->trigger(self::EVENT_AFTER_REGISTER, $event);

            return $this->render('/message', [
                'title'  => \Yii::t('user', 'Your account has been created'),
                'module' => $this->module,
            ]);
    }
...

Воспользуюсь заботливо прописанным событием EVENT_AFTER_REGISTER и повешу на него обработчик в конфиге в 'controllerMap'

'user' => [
    'class' => \dektrium\user\Module::className(),
    'controllerMap' => [
        'registration' => [
            'class' => \dektrium\user\controllers\RegistrationController::className(),
            'on ' . \dektrium\user\controllers\RegistrationController::EVENT_AFTER_REGISTER => function ($e) {
                Yii::$app->response->redirect(array('/user/security/login'))->send();
                Yii::$app->end();
            }
        ],
    ],
],
    

Теперь вместо показа message всё заканчивается на событии до этого - редиректом на страницу авторизации.