Всем доброго времени суток. Сегодня мы немного отступимся от реализации роутинга в CMS RS-MINI, и реализуем очень полезную, и важную вещь — хлебные крошки. Под хлебными крошками, на данном этапе разработки, я имею ввиду не выведенные подряд ссылки на странице сайта, а лишь данные которые нам понадобятся для реализации этих самых ссылок в будущем.
При сборке и запуске контроллеров у нас имеется прямой доступ к данным страниц, по которым строятся хлебные крошки, поэтому реализовать их сейчас самое то.
Если вы помните, первый цикл, в методе controllerRun() класса application.class.php, перебирает все найденные страницы, то бишь объекты класса page.class.php. В объектах этого класса имеется свойство pageAlias содержащие псевдоним и свойство pageName содержащие название страницы. Это именно то что нам нужно.
Но тут есть один маленький нюанс. У наших основных контроллеров имеется метод getCaption() который позволяет переназначить имя страницы, и нам необходимо будет учитывать то, что название страницы которое храниться в базе данных, может не совпадать с реальным названием.
Для этих целей у нас есть очень хороший класс-прослойка между контроллером и представлением. Название этому классу dom.class.php. Именно там мы создадим узел (breadcrumbs) хлебных крошек и наполним этот узел данными (узлами page с атрибутами caption (заголовок) и path (путь)).
Вот новый код метода (файл application.class.php в папке /rs-mini/core/)
/*
* метод стартует контроллеры
*
* @access - private
*
*/
private static function controllerRun()
{
// создаем узел хлебных крошек
$breadCrumbs = self::$dom->addNode('breadcrumbs');
// массив с псевдонимами страниц для формирования пути
$path = array();
// массив с контроллерами которые необходимо будет запустить
$runList = array();
// листаем страницы
foreach (self::$map->pageList as $key => $page) {
// список блоков контроллеров
$blockList = array(
'top',
'center',
'bottom'
);
// создаем узел в хлебных крошках
$pageNode = $breadCrumbs->addNode('page');
// созраняем название страницы
$caption = $page->pageName;
// сохраняем псевдоним в массиве пути
$path[] = $page->pageAlias;
// если на странице контроллеры
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();
// получаем заголовок
$caption = $obj->getCaption($caption);
// если листается последняя страница
if ($key == (count(self::$map->pageList) - 1))
// сохраняем данные для запуска (запуск ниже)
$runList[] = array(
'obj' => $obj,
'controller' => $controller
);
}
}
}
}
}
}
// атрибуты хлебных крошек
$pageNode->addAttr('caption', $caption);
$pageNode->addAttr('path', (count($path) > 1) ? implode('/', $path) . '/' : '/');
}
// тест хлебных крошек
?><xmp><?
var_dump(self::$dom->getDom());
?></xmp><?
}
Давайте я немного прокомментирую добавленные строчки.
// создаем узел хлебных крошек
$breadCrumbs = self::$dom->addNode('breadcrumbs');
// массив с псевдонимами страниц для формирования пути
$path = array();
Начал я с создания узла крошек и массива для хранения псевдонимов страниц.
// создаем узел в хлебных крошках
$pageNode = $breadCrumbs->addNode('page');
// созраняем название страницы
$caption = $page->pageName;
// сохраняем псевдоним в массиве пути
$path[] = $page->pageAlias;
Далее, для каждой страницы из массива self::$map->pageList, создается узел page, сохраняется псевдоним страницы в массиве path, и запоминается имя страницы. Я специально сохранил имя в отдельную переменную, так как чуть ниже будет попытка перезаписать значение этой переменной.
// получаем заголовок
$caption = $obj->getCaption($caption);
Теперь сразу после проверки на валидацию я запускаю метод getCaption() у основного объекта контроллера. Если помните этот метод по умолчанию возвращает то, что было прислано в его параметры. У нас как у разработчиков будет возможность через этот метод поменять имя страницы, на любое какое нам захочется.
// атрибуты хлебных крошек
$pageNode->addAttr('caption', $caption);
$pageNode->addAttr('path', (count($path) > 1) ? implode('/', $path) . '/' : '/');
Ну и последнее, что нам понадобится сделать, это создать два атрибута. Первый это имя страницы, а второй путь до страницы. Путь как видите это склеенный с помощью слэша массив с псевдонимами.
В конце метода есть код для проверки вставленных нами узлов. Если сейчас перейти вот на такую страницу http://mini.test.ru/about/ то мы должны увидеть вот такой массив:
Как видите, у нас теперь в доме есть узел с хлебными крошками. Останется его лишь разобрать в шаблон, но это мы будем делать потом, а не сейчас
Если у Вас есть какие либо вопросы, то задавайте их в комментариях. Архив с движком на данном этапе разработки, можно скачать в конце статьи.
Всего Вам наилучшего, на сегодня у меня все!