根据数据库结果设置 Yii2 catchAll 路由

Гео*_*ков 5 php routes yii2

<?php

namespace app\modules\site\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use app\models\SiteSettings;

class CommonController extends Controller {

public function init() {
    Yii::$app->language = 'bg-BG';
    Yii::$app->formatter->locale = 'bg-BG';
    Yii::$app->params['siteSettings'] = SiteSettings::find()->one();

    if (Yii::$app->params['siteSettings']->in_maintenance == 1) {
        Yii:$app->catchAll = ['index/maintenance', 'message' => Yii::$app->params['siteSettings']->maintenance_message];
    }
}
Run Code Online (Sandbox Code Playgroud)

}

我尝试从 CommonController init 方法中设置 catchAll 路由,但它引发了一个错误:

从空值创建默认对象

是否可以根据数据库提供的条件设置 catchAll 路由?

Edi*_*gic 5

您需要在处理请求之前设置 catchAll 属性。Init方法是在重新安装控制器后执行的,因此不会有任何影响。您需要使用应用程序 onBeforeRequest 事件来设置 catchAll 路由。

在配置文件中设置如下:

$config = [
    'id' => '...',
     ......

    'on beforeRequest' => function () {
        Yii::$app->params['siteSettings'] = SiteSettings::find()->one();            
        if (Yii::$app->params['siteSettings']->in_maintenance == 1) {
            Yii::$app->catchAll = [
              'index/maintenance', 
              'message' => Yii::$app->params['siteSettings']->maintenance_message
            ];
        }
    },
    ....
    'comonents' = [
        ....
    ]
];
Run Code Online (Sandbox Code Playgroud)

您可以通过缓存 SiteSettings::find()->one(); 对此进行一些改进。以避免为每个请求打开与数据库的连接。

更新: 我不确定 catchAll 是否可用于特定模块,但您可以处理 onBeforeAction 事件并重定向到自定义路由。

'on beforeAction' => function ($event) {

    $actionId = $event->action->id;
    $controllerId = $event->action->controller->id;
    $moduleId = $event->action->controller->module->id;

    //TODO: Check module here
    if (!(($controllerId == "site") && ($actionId == "offline")))
    {
        return Yii::$app->response->redirect(['site/offline']);
    }
},
Run Code Online (Sandbox Code Playgroud)