Выполните мой код перед любым действием любого контроллера
Я хотел бы проверить, заполнил ли мой пользователь определенные поля в своем профиле, прежде чем он сможет получить доступ к любому действию любого контроллера.
Например
if(empty(field1) && empty(field2))
{
header("Location:/site/error")
}
В yii1 я мог бы сделать это в protected\components\Controller.php в функции init()
Но в yii2 я не уверен, куда поместить мой код. Я не могу изменять основные файлы, но не уверен, что делать в backend моего расширенного приложения, чтобы заставить его работать.
Я знаю, что могу использовать user beforeAction(), но у меня слишком много контроллеров для этого и для отслеживания каждого контроллера.
Ответы
Ответ 1
Если вам нужно выполнить код перед каждым контроллером и действием, вы можете сделать следующее:
1. Добавьте компонент в каталог компонентов, например (MyGlobalClass
):
namespace app\components;
class MyGlobalClass extends \yii\base\Component{
public function init() {
echo "Hi";
parent::init();
}
}
2. Добавьте компонент MyGlobalClass
в свой массив компонентов в файле конфигурации:
'components' => [
'MyGlobalClass'=>[
'class'=>'app\components\MyGlobalClass'
],
//other components
3 - добавьте MyGlobalClass
в массив bootstarp
в файле конфигурации:
'bootstrap' => ['log','MyGlobalClass'],
Теперь вы можете видеть Hi
перед каждым действием.
Обратите внимание, что если вам не нужно использовать Events
и Behaviors
, вы можете использовать \yii\base\Object
вместо \yii\base\Component
Ответ 2
Создайте новый контроллер
namespace backend\components;
class Controller extends \yii\web\Controller {
public function beforeAction($event)
{
..............
return parent::beforeAction($event);
}
}
Все ваши контроллеры должны теперь расширить бэкэнд \components\Controller, а не \yii\web\Controller. с этим вы должны изменить каждый контроллер. Я бы пошел на это решение.
Я считаю, что вы также можете заменить 1 класс другим (поэтому никаких изменений в любом контроллере не требуется), что-то вроде
\Yii::$classMap = array_merge(\Yii::$classMap,[
'\yii\web\Controller'=>'backend\components\Controller',
]);
Подробнее см.: http://www.yiiframework.com/doc-2.0/guide-tutorial-yii-integration.html, и я взял код здесь: https://github.com/mithun12000/adminUI/blob/master/src/AdminUiBootstrap.php
вы можете поместить это в свой файл index.php. Однако убедитесь, что вы очень хорошо документируете это изменение, так как кто-то, кто придет и попытается отладить ваш код, будет полностью смущен этим.
Ответ 3
Просто добавьте конфигурационный файл в $config array:
'on beforeAction' => function ($event) {
echo "Hello";
},
Ответ 4
Или, https://github.com/yiisoft/yii2/blob/master/docs/guide/security-authorization.md использовать RBAC, чтобы ограничить доступ к действиям контроллеров по одному по правилам. Почему вы хотите ограничить доступ к действиям контроллера, основанным на пользовательских полях, вне меня. Вы не сможете получить доступ к чему-либо (включая регистрационную форму), если вы разместите там ограничение.