S.Tominoff

Fullstack JavaScript разработчик

Правила URL в модулях Yii1 приложениях

Выносим urlRules из конфигурации в модули.

Зачем?

 

Допустим у нас есть модуль admin. Для этого модуля в конфигурации приложения прописано несколько правил, например:

/* config/main.php, секция components => urlManager */
/* ... */
'rules' => [
    /* Ваши правила */
    /* ... */
    'admin/statistic' => ['admin/statistic/overview'],
    'admin/reports' => ['admin/reportManager/list', ['type' => 'all']],
    'admin/createXLSReport' => ['admin/reportManager/createNewReport', ['type' => 'xls']],
    'admin/createCSVReport' => ['admin/reportManager/createNewReport', ['type' => 'csv']],
    'admin/login' => ['admin/default/login'],
    'admin/logout' => ['admin/default/logout']
]

 

Все выглядит довольно компактно, но, когда мы добавим еще несколько модулей, и пропишем к ним правила могут начаться проблемы.

Во-первых у нас могут появиться трудности в поддержке этого кода и во-вторых возрастает нагрузка на компонент UrlManager, обрабатывающий все эти правила в цикле.

 

Поэтому гораздо логичнее было бы все правила связанные с модулями спрятать в сами модули и загружать по необходимости.

 

Как?

 

У менеджера URL Yii имеется метод addRules, с помощью него мы и будем загружать эти правила. Однако тут есть одно но, addRules нужно вызывать ДО начала разбора приложением URL строки, то есть. До разбора URL, Yii генерирует событие onBeginRequest, в котором мы и будем производить подгрузку url.

 

Давайте создадим класс-хэлпер в котором мы реализуем обработку события onBeginRequest (protected/helpers/CommonHelper.php):

 

<?php
    /*
        Хелпер общего назначения
    */
    class CommonHelper {
        /*
            Обработка события onBeginRequest
        */
        public static function onBeginRequest {
            $route = Yii::app()->getRequest()->getPathInfo();
            $moduleName = substr($route, 0, strpos($route, '/'));
            if(Yii::app()->hasModule($moduleName)) {
                $module = Yii::app()->getModule($moduleName);
                if(isset($module->urlRules)) {
                    $urlManager = Yii::app()->getUrlManager();
                    $urlManager->addRules($module->urlRules, false);
                }
            }
            return true;
        }
    }

 

Метод onBeginRequest вырезает предполагаемое имя модуля из строки запроса и проверяет с помощью hasModule($moduleName) существование зарегистрированного модуля Yii с таким именем.

Если модуль найден, добавляем определенные в нем urlRules в приложение методом addRules.

 

 

Теперь осталось только привязать этот метод к событию, для этого нужно protected/config/main.php должным образом, например:

'import' => [
    /* ... */
   'application.helpers.*'
],
'onBeginRequest' => ['CommonHelper', 'onBeginRequest']

 

Теперь можно определить все правила модуля, в переменной-члене urlRules, внутри модуля, например:

class AdminModule extends CModule {
    public $urlRules = [
        'admin/statistic' => ['admin/statistic/overview'],
        'admin/reports' => ['admin/reportManager/list', ['type' => 'all']],
        'admin/createXLSReport' => ['admin/reportManager/createNewReport', ['type' => 'xls']],
        'admin/createCSVReport' => ['admin/reportManager/createNewReport', ['type' => 'csv']],
        'admin/login' => ['admin/default/login'],
        'admin/logout' => ['admin/default/logout']
    ];
    /* ... */
}

 

Дополнительные материалы по теме: Блог ElisDN Перенос конфигурации в модули Yii