Комментарии

Поиск пути к категории из пункта меню
( 0 Голосов )

А теперь, когда получен идентификатор пункта меню (Itemid), можно завершить процесс маршрутизации. Напомним, что он был начат в следующей строке кода:

JRoute::_(WeblinksHelperRoute::getCategoryRoute($item->id));

Теперь упомянутая выше ссылка передается в качестве аргумента методу JRoute::_(). В этом методе сначала получается маршрутизатор, который в пользовательской части вебсайта определяется в классе JRouterSite из файла includes/router.php, а затем вызывается метод build () из класса JRouterSite. Если установлена кнопка-переключатель Yes параметра Search Engine Friendly URLs на вкладке SEO диалогового окна Global Configuration, то метод build () принимает в качестве аргумента URL с запросом (например, index.php?option=com_weblinks&Itemid=274) и возвращает удобный для поиска URL (например, index.php/using-joomla/extensions/components/weblinks-component/weblinks-single-category).

Прежде всего в методе build () вызывается другой метод build () из его родительского класса JRouter. Если установлена кнопка-переключатель Yes упомянутого выше параметра Search Engine Friendly URLs, то далее вызывается защищенный метод _buildSefRoute () (снова из класса JRouterSite). В этом методе имеется следующий фрагмент кода:

// использовать  обработчик маршрутизации для  компонента, если таковой имеется
$path = JPATH_SITE . '/components/' . $component . '/router.php';

// использовать специальный обработчик маршрутизации, если таковой имеется (file_exists($path) && !empty($query)) { $path; $function = substr($component, 4).'BuildRoute'; $function = str_replace(array("-", "."), "", $function); $parts = $function($query);

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

<имя компонента (за вычетом части "com_")> + "BuildRoute"

Если такой файл найден, то данная функция вызывается в последней строке приведенного выше фрагмента кода и возвращает массив $parts. Для компонента Weblinks такойфайл имеется и называется components/com_weblinks/router.php, а вызываемая из него функция — WeblinksBuildRoute (). Следует иметь в виду, что в этом файле объявляются только методы build () и parse (), но не класс.

Как пояснялось ранее, если имеется пункт меню единственной категории, указывающий на эту категорию веб-ссылок, маршрутизация осуществляется непосредственно к этому пункту меню. Следовательно, функция WeblinksBuildRoute () возвращает пустой массив, если текущая категория совпадает с категорией, указываемом в пункте меню единственной категории.

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

if ($category) {

// Что сделать: сгенерировать ошибку, если категория не существует или снята с публикации $path = $category->getPath(); $path = array_reverse($path); $array = array(); foreach($path as $id) { if ((int) $id == (int)$menuCatid) { break; } if ($advanced) { list($tmp, $id) = explode(':', $id, 2) ; } $array[] = $id; } $segments = array__merge ($segments,   array_reverse ($array) ) ; }

Этот фрагмент кода требует подробного рассмотрения, поскольку он не так прост. На данный момент уже известно, что имеется категория, для которой отсутствует соответствующий пункт меню. Но у одной из ее родительских категорий, вероятно, такой пункт меню имеется. Это известно из того, что ссылка на такую категорию уже содержит оптимально соответствующий пункт меню.

В переменной $category содержится объект типа JCategoryNode для текущей категории. И в этом случае метод getPath () вызывается, чтобы возвратить всю иерархию для данной категории. Затем порядок следования элементов в массиве изменяется на обратный с помощью функции array_reverse (), как было показано в предыдущем примере.

Далее организуется циклическое обращение к родительским категориям. Ключом к пониманию этой операции служит код, выделенный выше полужирным. Если искомое соответствие не найдено, значение переменной $id вводится в массив $ array и далее цикл повторяется. Когда же соответствие наконец обнаружено, выполнение цикла foreach прерывается по команде break и происходит немедленный выход из него.

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

И наконец, вызывается функция array_merge (), чтобы ввести полученный результат в массив $ segments, который и возвращается в виде значения в конце рассматриваемого здесь метода. Если обратиться к примеру проникновения вглубь меню до категории Other Resources, то массив $ segments будет содержать один приведенный ниже элемент.

0 =>  33:other-resources

В данном примере пункт меню Weblinks Single Category снят с публикации, и поэтому оптимально соответствующим оказывается пункт меню Weblinks Categories. Следовательно, массив $ segments будет содержать два приведенных ниже элемента.

0 => 33:other-resources, 1 => 32:joomla-specific-links

Далее происходит возврат в вызывающий метод, которым в данный момент является метод _buildSefRoute () из класса JRouterSite. В этом методе отдельные части URL собираются вместе и разделяются знаками косой черты (/), а в самом начале к ним добавляется префикс component/. И наконец, по полученному в итоге значению задается путь для объекта типа JURI.

Итак, URL, указывающий на наиболее точно соответствующий пункт меню, создан. По мере надобности в него был также включен путь от категории данного пункта меню вниз по иерархии к текущей категории. В итоге получился логически согласованный и удобный для пользователей URL.


Понравился материал? Пригодилась информация? Плюсани в социалки!


 
Похожие новости