Роутинг - сброка контроллеров

 

Всем доброго времени суток. Сегодня мы будем разбирать довольно сложную часть реализации роутинга в CMS RS-MINI. Нам предстоит обработать контроллеры для конечной страницы и поместить объекты этих контроллеров в специальный массив. Какие операции входят в понятие «сборка контроллеров»?

Логика метода controllerRun()

Те объекты контроллеров которые имеются у нас сейчас, лишь хранилище информации для роутинга системы. Используя эту информацию наш роутинг должен поднять объекты контроллеров которые будут храниться в папке с модулями. Давайте для удобство дадим термины этим двум видам контроллеров:

  • Хранилище контроллера — так мы будем называть контроллеры класса controller.class.php.
  • Основной контроллер — так мы будем называть контроллеры которые лежат непосредственно в папке с модулями, и объекты этих контроллеров будут подниматься на основе абстрактного класса abstractcontroller.class.php.

Теперь проще будет говорить про какой вид контроллера я говорю Улыбаюсь

Я немного отвлекся... Так в чем конкретная суть метода controllerRun()? Метод должен будет

  • проциклить все имеющиеся страницы (свойство pageList класса map.class.php)
  • взять из этих страниц хранилище контроллера
    • сначала унаследованные
    • потом напрямую подключенные
  • На основе свойства controllerName класса controller.class.php поднять объект основного контроллера
  • Напичкать основной контроллер некоторыми дополнительными параметрами, к таким будут относиться
    • id страницы
    • псевдоним страницы
    • родитель страницы
  • Зарегистрировать динамический псевдоним для динамических страниц.
  • Проверить валидацию основного контроллера (под этими словами я подразумеваю запуск метода validate() класса abstractcontroller.class.php)
  • и в конце, для последней страницы из списка pageList класса map.class.php сохранить поднятые объекты основных контроллеров в специальный массив runList.

Сборка массива runList первостепенная задача на сегодня. На этом логика метода не закончится. Мы как минимум еще две статьи будем работать только с этим методом. Я специально разбил материал на части, для лучшего восприятия кода (надеюсь поэтапная реализация этого метода улучшит его понимание)

Тестовый модуль pub.test

Пожалуй пришло время создать наш первый модуль (пока что тестовый). Заходим в папку /project/modules/pub/ и создаем в нем папку test. В папке /project/modules/pub/test/ нужно создать три каталога:

  • controller
  • model
  • view

Это три основных папки каждого модуля. Будут еще папки, но я пока не определился какие именно.

Теперь заходим в папку /project/modules/pub/test/controller/ и создаем там файл с именем intro.class.php с вот таким кодом внутри:

<?php 
 
/*
 * @package RS-MINI
 * @copyright (c) 2015 Alexey Glumov aka Rio-Shaman (support@rio-shaman.ru)
 * @license GNU General Public License version 2; see LICENSE.txt
 *
 */
 
namespace pub\test\controller;
 
if(!defined('RS-MINI')) die();
 
/*
 * intro v 1.0
 *  
 * контроллер модуля pub.test
 *
 */
 
class intro extends \core\abstractcontroller
{    
     
    /*
     * запуск контроллера
     *  
     * @access - public
     * @return - true или false (404 ошибка)
     *  
     */
      
    public function run()
    {
        return TRUE;
    }
}

Это минимальный код контроллера модуля. Тут пока пояснять нечего, ведь контроллер пуст. Правда есть один нюанс касающийся метода run(). Если Вы помните, в абстрактном классе abstractcontroller.class.php уже существует метод run(). Может возникнуть вопрос, зачем в базовом коде (в минимальном коде) контроллера описывается метод run(), ведь он уже существует? Ответ прост, в абстрактном классе, метод run() возвращает false, что должно будет привести к 404-ой ошибке. В коде основного контроллера метод run() возвращает true, что предотвратит появление ошибки.

Код метода controllerRun()

Ну что же, пора опубликовать код метода. Каждая строчка задокументирована + есть некоторые пояснения в самой статье, по тому считаю, что код должен вызывать минимум вопросов.

Вот код метода: (метод находится в классе application.class.php который лежит в папке /rs-mini/core/)

    /*
     * метод стартует контроллеры
     *
     * @access - private
     *
     */

    private static function controllerRun()
    {
        // массив с контроллерами которые необходимо будет запустить
        $runList = array();

        // листаем страницы
        foreach (self::$map->pageList as $key => $page) {

            // список блоков контроллеров
            $blockList = array(
                'top',
                'center',
                'bottom'
            );

            // если на странице контроллеры
            if ($page->controllerList) {
                // листаем все возможные блоки
                foreach ($blockList as $blockAlias) {
                    // листаем контроллеры страницы
                    foreach ($page->controllerList as $block => $controllerList) {
                        // если листаемый блок совпадает с блоком контроллеров страницы - то разбираем контроллеры данного блока
                        if ($blockAlias == $block) {
                            // сначало проглядываем наследуемые контроллеры (потом подключенные на прямую)
                            for ($inh = 0; $inh <= 1; $inh++) {
                                // листаем контроллеры
                                foreach ($controllerList as $controller) {

                                    // проверка наследия (первая итерация ищет только наследованные контроллры)
                                    // при $inh == 0 запускаются только унаследованные контроллеры
                                    // при $inh == 1 запускаются подключенные на прямую
                                    if ($controller->inheritFlag != ( ($inh == 0) ? TRUE : FALSE ))
                                        continue;

                                    // пропускаем отключенные контроллеры
                                    if ($controller->getParam('active') == 'disable')
                                        continue;

                                    // подставляем в путь допол. папку
                                    // бьем имя контроллера на массив
                                    $controllerClass                                  = explode('.', $controller->controllerName);
                                    // отрезаем два первых элемента массива
                                    $controllerSlice                                  = array_slice($controllerClass, 2);
                                    // во второй элемент массива вставляем слово controller
                                    $controllerClass[2]                               = 'controller';
                                    // вертаем в массив оставшие элементы после отработки функции array_slice
                                    for ($i = 0; isset($controllerSlice[$i]); $i++)
                                        $controllerClass[($i + 3)]                    = $controllerSlice[$i];

                                    // тем самым получаем полный путь к классу
                                    // пример: было pub.test.intro а стало pub\test\controller\intro
                                    $controllerClass                                  = implode('\\', $controllerClass);

                                    // записываем в параметры инфу о странице
                                    $controller
                                        ->setParam('page_id',     $page->pageID)
                                        ->setParam('page_alias',  $page->pageAlias)
                                        ->setParam('page_parent', $page->pageParent)
                                    ;

                                    // создаем объект контроллера
                                    $obj = new $controllerClass(self::$dom, $controller->getParams());
                                    
                                    // регистрируем динамичный алиас и его значение в
                                    // статичном свойстве абстрактного класса контроллера
                                    // если реальный алиас страницы row_id а в адресную строку было вбито
                                    // /123/ то в свойстве dynamicValue абстракного класса abstractcontroller
                                    // будет зарегистрирован ключ row_id с значением 123
                                    // dynamicValue['row_id'] = '123'
                                    if ($page->pageType == 'dynamic')
                                        $obj->setDynamicValue($page->pageDynamicAlias, $page->pageAlias);

                                    // проверяем на валидацию
                                    if (!$obj->validate())
                                        self::notFound();

                                    // если листается последняя страница
                                    if ($key == (count(self::$map->pageList) - 1))
                                        // сохраняем данные для запуска
                                        $runList[] = array(
                                            'obj'           => $obj,
                                            'controller'    => $controller
                                        );

                                }
                            }
                        }
                    }
                }
            }
        }
        
        // тест работы роутинга
        // просматриваем массив объектов для запуска
        ?><xmp><?
        var_dump($runList);
        ?></xmp><?
    }

Вы могли заметить, что в конце метода есть строки для тестирования. Что бы увидеть результат, необходимо вызвать этот метод в методе run() класса application.class.php. (код пишется там же)

    /*
     * главный метод. запуск системы
     *
     * @access  - public
     *
     */
     
    public static function run()
    {
        // поднимаем некоторые классы ядра
        // объект по работе с структурой сайта
        self::$map = new map();
        // объект прослойка между контроллерами и вьюшкой
        self::$dom = new dom();
        
        // стартуем подключение к БД
        sql::setConnect();
        
        // получаем открываемую страницу
        if (!self::$map->getPage())
            self::notFound();
            
        // мероприятия по объеденению унаследованных контроллеров с конечной страницей
        self::unionRun();
        
        // запускаем контроллеры
        self::controllerRun();
    }

Заключение

Если сейчас перейти по адресу http://mini.test.ru/about/ то мы увидим не маленький дамп массива runList. Из всего дампа, на данном этапе, нам важно увидеть вот эту строчку

объект контроллера pub.test.intro

которая говорит нам о том, что на основе хранилище контроллера поднялся объект основного контроллера pub.test.intro.

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

Всего Вам наилучшего, на сегодня все!

Прикрепленные файлы

 

Возможно Вам будут интересны следующие заметки

Комментарии (0)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
К данной статье пока нет комментариев.