Создание системного плагина для модификации JRouter
Переопределение JRouter
Маршрутизатор Joomla! может быть изменен с дополнительными правилами, используя методы attatchBuildRules и attatchParseRules. В идеале это можно сделать из системного плагина, так что эти правила будут применяться глобально.
Вот 2 примера модификации JRouter используя правила и системный плагин. Один из них добавит результаты, возвращаемые JRouter, в то время как другой полностью заменит результаты, возвращаемые JRouter.
Добавление.
JRouter возвращает массив переменных, которые затем используются через API JInput для переопределения фактических переменных _GET/_POST/_REQUEST. Если вы просто хотите добавить возвращаемые переменные, то это просто.
class plgSystemMyRouterAugmentor extends JPlugin { /** * @return void */ public function onAfterInitialise() { $app = JFactory::getApplication(); // Получить роутер $router = $app->getRouter(); // Добавить собственное правило: // Создать массив обратного вызова для вызова метода augmentRoute этого объекта $augmentRouteCallback = array($this, 'augmentRoute'); // Прикрепить обратный вызов к роутеру $router->attachBuildRule($augmentRouteCallback); } /** * @param JRouterSite $router The Joomla site Router * @param JURI $uri The URI to parse * * @return array The array of processed URI variables */ public function augmentRoute($router, $uri) { $vars = array(); // Сделать что-нибудь с переменными $vars['augment'] = 'succeeded'; /** * В этом случае теперь любой компонент/модул Joomla! будет выглядеть, как будто параметр * ?augment=succeeded был в URL */ return $vars; } }
Замена.
JRouter возвращает массив переменных, которые затем используются через API JInput для переопределения фактических переменных _GET/_POST/_REQUEST. Если вы хотите полностью заменить эти переменные, это займет немного больше работы. В этом случае вам может потребоваться вызвать метод parse в песочнице, чтобы узнать, каковы были бы результаты. Затем вы можете добавить/удалить/изменить эти результаты. Наконец, прежде чем возвращать эти результаты в JRouter для самого сайта, вам нужно отметить JRouter, чтобы он не продолжал обрабатывать результаты.
define('ROUTER_MODE_SKIP_SEF', 2); define('ROUTER_MODE_SKIP_RAW', -1); class plgSystemMyRouterReplacor extends JPlugin { /** * @return void */ public function onAfterInitialise() { $app = JFactory::getApplication(); // Получить маршрутизатор $router = $app->getRouter(); // Создать массив обратного вызова для вызова метода replaceRoute этого объекта $replaceRouteCallback = array($this, 'replaceRoute'); // Прикрепить обратный вызов к маршрутизатору $router->attachBuildRule($replaceRouteCallback); } /** * @param JRouterSite &$router The Joomla Site Router * @param JURI &$uri URI для разбора * * @return array Массив обработанных переменных URI */ public function replaceRoute($router, $uri) { $app = JFactory::getApplication('site'); $vars = array(); // Get the true router $siteRouter = $app->getRouter(); /** * чтобы избежать рекурсивной ловушки, нам нужно убедиться, * что только маршрутизатор сайта может вызвать это! * Мы могли бы убрать наше собственное правило myRouter * ...но это будет работать только внутри нашего собственного метода! * Если бы кто - то другой тоже делал то же самое, у нас была бы рекурсия, * где они вызывают parse, который вызывает нас, а затем мы * клонируем маршрутизатор и вызываем parse, который вызывает * их туда - обратно! */ if (spl_object_hash($router) != spl_object_hash($siteRouter)) { // Обнаружена рекурсия -> прервать! return $vars; } /** * мы все еще хотим клонировать переданный нам маршрутизатор, * а не настоящий маршрутизатор, так как правила могут быть другими */ $myRouter = clone $router; // Теперь используем возможности Joomla! чтобы разобрать этот uri! $vars = $myRouter->parse($uri); // Есть ли идентификатор меню? Если не - то 0 $menuId = isset($vars['itemId']) ? $vars['itemId'] : 0; // Загрузите меню и проверить конфигурацию... И еще что ни будь... if ($menuId == 67) { // Изменить параметр option на другой компонент. $vars['option'] == 'com_my_custom_component'; } /** * $vars имеет как объединенные значения того, что было бы вычислено, так и наши изменения, * так что заставьте siteRouter пропустить больше обработки - нет причин обрабатывать его дважды! * $router->setMode(JROUTER_MODE_RAW); * если режим маршрутизатора RAW - integer 0, то _parseRawRoute будет вызван JRouter * $router->setMode(JROUTER_MODE_SEF); * если режим маршрутизатора SEF - integer 1, , то _parseSEFRoute будет вызван JRouter, * если мы установим его на что-то, что НЕ является SEF или RAW, ничего не будет сделано с ним * false или null было бы логичным выбором, * но так как сравнение == не === false, null и 0/RAW - это одно и то же, * поэтому мы определили наши собственные константы. * SEF/RAW -это двоичное условие либо положительного целого числа, * либо не положительного целого числа [0], * поэтому мы расширяем его так, что SKIP_SEF будет 2, * так что предложение if потерпит неудачу, * но все остальное, рассчитанное на проверку if mode > 0, будет работать, * а SKIP_RAW будет -1, так что все, что рассчитано на проверку mode <=0, будет работать, * если это не 0 или 1, то мы не меняем его, потому что что-то другое уже вызвало пропуск. */ $mode = $router->getMode(); if ($mode == JROUTER_MODE_RAW) { $router->setMode(ROUTER_MODE_SKIP_RAW); } if ($mode == JROUTER_MODE_SEF) { $router->setMode(ROUTER_MODE_SKIP_SEF); } // Вернуть наши пользовательские переменные return $vars; } }