File manager - Edit - /home/ferretapmx/public_html/Router.tar
Back
RouterViewConfiguration.php 0000644 00000011527 15231072377 0012135 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2015 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * View-configuration class for the view-based component router * * @since 3.5 */ class RouterViewConfiguration { /** * Name of the view * * @var string * @since 3.5 */ public $name; /** * Key of the view * * @var string * @since 3.5 */ public $key = false; /** * Parentview of this one * * @var RouterViewConfiguration * @since 3.5 */ public $parent = false; /** * Key of the parent view * * @var string * @since 3.5 */ public $parent_key = false; /** * Is this view nestable? * * @var bool * @since 3.5 */ public $nestable = false; /** * Layouts that are supported by this view * * @var array * @since 3.5 */ public $layouts = ['default']; /** * Child-views of this view * * @var RouterViewConfiguration[] * @since 3.5 */ public $children = []; /** * Keys used for this parent view by the child views * * @var array * @since 3.5 */ public $child_keys = []; /** * Path of views from this one to the root view * * @var array * @since 3.5 */ public $path = []; /** * Constructor for the View-configuration class * * @param string $name Name of the view * * @since 3.5 */ public function __construct($name) { $this->name = $name; $this->path[] = $name; } /** * Set the name of the view * * @param string $name Name of the view * * @return RouterViewConfiguration This object for chaining * * @since 3.5 */ public function setName($name) { $this->name = $name; array_pop($this->path); $this->path[] = $name; return $this; } /** * Set the key-identifier for the view * * @param string $key Key of the view * * @return RouterViewConfiguration This object for chaining * * @since 3.5 */ public function setKey($key) { $this->key = $key; return $this; } /** * Set the parent view of this view * * @param RouterViewConfiguration $parent Parent view object * @param string $parentKey Key of the parent view in this context * * @return RouterViewConfiguration This object for chaining * * @since 3.5 */ public function setParent(RouterViewConfiguration $parent, $parentKey = null) { if ($this->parent) { $key = array_search($this, $this->parent->children); if ($key !== false) { unset($this->parent->children[$key]); } if ($this->parent_key) { $child_key = array_search($this->parent_key, $this->parent->child_keys); unset($this->parent->child_keys[$child_key]); } } $this->parent = $parent; $parent->children[] = $this; $this->path = $parent->path; $this->path[] = $this->name; $this->parent_key = $parentKey ?? false; if ($parentKey) { $parent->child_keys[] = $parentKey; } return $this; } /** * Set if this view is nestable or not * * @param bool $isNestable If set to true, the view is nestable * * @return RouterViewConfiguration This object for chaining * * @since 3.5 */ public function setNestable($isNestable = true) { $this->nestable = (bool) $isNestable; return $this; } /** * Add a layout to this view * * @param string $layout Layouts that this view supports * * @return RouterViewConfiguration This object for chaining * * @since 3.5 */ public function addLayout($layout) { $this->layouts[] = $layout; $this->layouts = array_unique($this->layouts); return $this; } /** * Remove a layout from this view * * @param string $layout Layouts that this view supports * * @return RouterViewConfiguration This object for chaining * * @since 3.5 */ public function removeLayout($layout) { $key = array_search($layout, $this->layouts); if ($key !== false) { unset($this->layouts[$key]); } return $this; } } RouterInterface.php 0000644 00000003373 15231072377 0010373 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Component routing interface * * @since 3.3 */ interface RouterInterface { /** * Prepare-method for URLs * This method is meant to validate and complete the URL parameters. * For example it can add the Itemid or set a language parameter. * This method is executed on each URL, regardless of SEF mode switched * on or not. * * @param array $query An associative array of URL arguments * * @return array The URL arguments to use to assemble the subsequent URL. * * @since 3.3 */ public function preprocess($query); /** * Build method for URLs * This method is meant to transform the query parameters into a more human * readable form. It is only executed when SEF mode is switched on. * * @param array &$query An array of URL arguments * * @return array The URL arguments to use to assemble the subsequent URL. * * @since 3.3 */ public function build(&$query); /** * Parse method for URLs * This method is meant to transform the human readable URL back into * query parameters. It is only executed when SEF mode is switched on. * * @param array &$segments The segments of the URL to parse. * * @return array The URL attributes to be used by the application. * * @since 3.3 */ public function parse(&$segments); } RouterServiceInterface.php 0000644 00000001641 15231072377 0011710 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Menu\AbstractMenu; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * The component router service. * * @since 4.0.0 */ interface RouterServiceInterface { /** * Returns the router. * * @param CMSApplicationInterface $application The application object * @param AbstractMenu $menu The menu object to work with * * @return RouterInterface * * @since 4.0.0 */ public function createRouter(CMSApplicationInterface $application, AbstractMenu $menu): RouterInterface; } RouterServiceTrait.php 0000644 00000002717 15231072377 0011100 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Menu\AbstractMenu; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Trait to implement AssociationServiceInterface * * @since 4.0.0 */ trait RouterServiceTrait { /** * The router factory. * * @var RouterFactoryInterface * * @since 4.0.0 */ private $routerFactory = null; /** * Returns the router. * * @param CMSApplicationInterface $application The application object * @param AbstractMenu $menu The menu object to work with * * @return RouterInterface * * @since 4.0.0 */ public function createRouter(CMSApplicationInterface $application, AbstractMenu $menu): RouterInterface { return $this->routerFactory->createRouter($application, $menu); } /** * The router factory. * * @param RouterFactoryInterface $routerFactory The router factory * * @return void * * @since 4.0.0 */ public function setRouterFactory(RouterFactoryInterface $routerFactory) { $this->routerFactory = $routerFactory; } } RouterFactory.php 0000644 00000004553 15231072377 0010103 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Categories\CategoryFactoryInterface; use Joomla\CMS\Menu\AbstractMenu; use Joomla\Database\DatabaseInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Default router factory. * * @since 4.0.0 */ class RouterFactory implements RouterFactoryInterface { /** * The namespace to create the categories from. * * @var string * @since 4.0.0 */ private $namespace; /** * The category factory * * @var CategoryFactoryInterface * * @since 4.0.0 */ private $categoryFactory; /** * The db * * @var DatabaseInterface * * @since 4.0.0 */ private $db; /** * The namespace must be like: * Joomla\Component\Content * * @param string $namespace The namespace * @param ?CategoryFactoryInterface $categoryFactory The category object * @param ?DatabaseInterface $db The database object * * @since 4.0.0 */ public function __construct($namespace, ?CategoryFactoryInterface $categoryFactory = null, ?DatabaseInterface $db = null) { $this->namespace = $namespace; $this->categoryFactory = $categoryFactory; $this->db = $db; } /** * Creates a router. * * @param CMSApplicationInterface $application The application * @param AbstractMenu $menu The menu object to work with * * @return RouterInterface * * @since 4.0.0 */ public function createRouter(CMSApplicationInterface $application, AbstractMenu $menu): RouterInterface { $className = trim($this->namespace, '\\') . '\\' . ucfirst($application->getName()) . '\\Service\\Router'; if (!class_exists($className)) { throw new \RuntimeException('No router available for this application.'); } return new $className($application, $menu, $this->categoryFactory, $this->db); } } RouterLegacy.php 0000644 00000005147 15231072377 0007700 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Default routing class for missing or legacy component routers * * @since 3.3 * @deprecated 5.1 will be removed in 7.0 * Will be removed without replacement. Use the class based router * implementing the RouterInterface */ class RouterLegacy implements RouterInterface { /** * Name of the component * * @var string * @since 3.3 */ protected $component; /** * Constructor * * @param string $component Component name without the com_ prefix this router should react upon * * @since 3.3 */ public function __construct($component) { $this->component = $component; } /** * Generic preprocess function for missing or legacy component router * * @param array $query An associative array of URL arguments * * @return array The URL arguments to use to assemble the subsequent URL. * * @since 3.3 */ public function preprocess($query) { return $query; } /** * Generic build function for missing or legacy component router * * @param array &$query An array of URL arguments * * @return array The URL arguments to use to assemble the subsequent URL. * * @since 3.3 */ public function build(&$query) { $function = $this->component . 'BuildRoute'; if (\function_exists($function)) { $segments = $function($query); foreach ($segments as &$segment) { $segment = str_replace(':', '-', $segment); } return $segments; } return []; } /** * Generic parse function for missing or legacy component router * * @param array &$segments The segments of the URL to parse. * * @return array The URL attributes to be used by the application. * * @since 3.3 */ public function parse(&$segments) { $function = $this->component . 'ParseRoute'; if (\function_exists($function)) { foreach ($segments as &$segment) { $segment = preg_replace('/-/', ':', $segment, 1); } return $function($segments); } return []; } } Rules/NomenuRules.php 0000644 00000012433 15231072377 0010635 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router\Rules; use Joomla\CMS\Component\Router\RouterView; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Rule to process URLs without a menu item * * @since 3.4 */ class NomenuRules implements RulesInterface { /** * Router this rule belongs to * * @var RouterView * @since 3.4 */ protected $router; /** * Class constructor. * * @param RouterView $router Router this rule belongs to * * @since 3.4 */ public function __construct(RouterView $router) { $this->router = $router; } /** * Dummy method to fulfil the interface requirements * * @param array &$query The query array to process * * @return void * * @since 3.4 * @codeCoverageIgnore */ public function preprocess(&$query) { } /** * Parse a menu-less URL * * @param array &$segments The URL segments to parse * @param array &$vars The vars that result from the segments * * @return void * * @since 3.4 */ public function parse(&$segments, &$vars) { $active = $this->router->menu->getActive(); if (!\is_object($active)) { $views = $this->router->getViews(); if (isset($views[$segments[0]])) { $vars['view'] = array_shift($segments); $view = $views[$vars['view']]; if (isset($view->key, $segments[0])) { if (\is_callable([$this->router, 'get' . ucfirst($view->name) . 'Id'])) { $input = $this->router->app->getInput(); if ($view->parent_key && $input->get($view->parent_key)) { $vars[$view->parent->key] = $input->get($view->parent_key); $vars[$view->parent_key] = $input->get($view->parent_key); } if ($view->nestable) { $vars[$view->key] = 0; while (\count($segments)) { $segment = array_shift($segments); $result = \call_user_func_array([$this->router, 'get' . ucfirst($view->name) . 'Id'], [$segment, $vars]); if (!$result) { array_unshift($segments, $segment); break; } $vars[$view->key] = preg_replace('/-/', ':', $result, 1); } } else { $segment = array_shift($segments); $result = \call_user_func_array([$this->router, 'get' . ucfirst($view->name) . 'Id'], [$segment, $vars]); $vars[$view->key] = preg_replace('/-/', ':', $result, 1); } } else { $vars[$view->key] = preg_replace('/-/', ':', array_shift($segments), 1); } } } } } /** * Build a menu-less URL * * @param array &$query The vars that should be converted * @param array &$segments The URL segments to create * * @return void * * @since 3.4 */ public function build(&$query, &$segments) { $menu_found = false; if (isset($query['Itemid'])) { $item = $this->router->menu->getItem($query['Itemid']); if ( !isset($query['option']) || ($item && isset($item->query['option']) && $item->query['option'] === $query['option']) ) { $menu_found = true; } } if (!$menu_found && isset($query['view'])) { $views = $this->router->getViews(); if (isset($views[$query['view']])) { $view = $views[$query['view']]; $segments[] = $query['view']; if ($view->key && isset($query[$view->key])) { if (\is_callable([$this->router, 'get' . ucfirst($view->name) . 'Segment'])) { $result = \call_user_func_array([$this->router, 'get' . ucfirst($view->name) . 'Segment'], [$query[$view->key], $query]); if ($view->nestable) { array_pop($result); while (\count($result)) { $segments[] = str_replace(':', '-', array_pop($result)); } } else { $segments[] = str_replace(':', '-', array_pop($result)); } } else { $segments[] = str_replace(':', '-', $query[$view->key]); } unset($query[$views[$query['view']]->key]); } unset($query['view']); } } } } Rules/StandardRules.php 0000644 00000021711 15231072377 0011133 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router\Rules; use Joomla\CMS\Component\Router\RouterView; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Rule for the standard handling of component routing * * @since 3.4 */ class StandardRules implements RulesInterface { /** * Router this rule belongs to * * @var RouterView * @since 3.4 */ protected $router; /** * Class constructor. * * @param RouterView $router Router this rule belongs to * * @since 3.4 */ public function __construct(RouterView $router) { $this->router = $router; } /** * Dummy method to fulfil the interface requirements * * @param array &$query The query array to process * * @return void * * @since 3.4 */ public function preprocess(&$query) { } /** * Parse the URL * * @param array &$segments The URL segments to parse * @param array &$vars The vars that result from the segments * * @return void * * @since 3.4 */ public function parse(&$segments, &$vars) { // Get the views and the currently active query vars $views = $this->router->getViews(); $active = $this->router->menu->getActive(); if ($active) { $vars = array_merge($active->query, $vars); } // We don't have a view or its not a view of this component! We stop here if (!isset($vars['view']) || !isset($views[$vars['view']])) { return; } // Copy the segments, so that we can iterate over all of them and at the same time modify the original segments $tempSegments = $segments; // Iterate over the segments as long as a segment fits foreach ($tempSegments as $segment) { // Our current view is nestable. We need to check first if the segment fits to that if ($views[$vars['view']]->nestable) { if (\is_callable([$this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'])) { $key = \call_user_func_array([$this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'], [$segment, $vars]); // Did we get a proper key? If not, we need to look in the child-views if ($key) { $vars[$views[$vars['view']]->key] = $key; array_shift($segments); continue; } } else { // The router is not complete. The get<View>Id() method is missing. return; } } // Lets find the right view that belongs to this segment $found = false; foreach ($views[$vars['view']]->children as $view) { if (!$view->key) { if ($view->name === $segment) { // The segment is a view name $parent = $views[$vars['view']]; $vars['view'] = $view->name; $found = true; if ($view->parent_key && isset($vars[$parent->key])) { $parent_key = $vars[$parent->key]; $vars[$view->parent_key] = $parent_key; unset($vars[$parent->key]); } break; } } elseif (\is_callable([$this->router, 'get' . ucfirst($view->name) . 'Id'])) { // Hand the data over to the router specific method and see if there is a content item that fits $key = \call_user_func_array([$this->router, 'get' . ucfirst($view->name) . 'Id'], [$segment, $vars]); if ($key) { // Found the right view and the right item $parent = $views[$vars['view']]; $vars['view'] = $view->name; $found = true; if ($view->parent_key && isset($vars[$parent->key])) { $parent_key = $vars[$parent->key]; $vars[$view->parent_key] = $parent_key; unset($vars[$parent->key]); } $vars[$view->key] = $key; break; } } } if (!$found) { return; } array_shift($segments); } } /** * Build a standard URL * * @param array &$query The vars that should be converted * @param array &$segments The URL segments to create * * @return void * * @since 3.4 */ public function build(&$query, &$segments) { if (!isset($query['Itemid'], $query['view'])) { return; } // Get the menu item belonging to the Itemid that has been found $item = $this->router->menu->getItem($query['Itemid']); if ( $item === null || $item->component !== 'com_' . $this->router->getName() || !isset($item->query['view']) ) { return; } // Get menu item layout $mLayout = $item->query['layout'] ?? null; // Get menu item filter_tag $mFilterTag = $item->query['filter_tag'] ?? null; // Get all views for this component $views = $this->router->getViews(); // Return directly when the URL of the Itemid is identical with the URL to build if ($item->query['view'] === $query['view']) { $view = $views[$query['view']]; if (!$view->key) { unset($query['view']); if (isset($query['layout']) && $mLayout === $query['layout']) { unset($query['layout']); } if (isset($query['filter_tag']) && $mFilterTag === $query['filter_tag']) { unset($query['filter_tag']); } return; } if (isset($query[$view->key]) && $item->query[$view->key] == (int) $query[$view->key]) { unset($query[$view->key]); while ($view) { unset($query[$view->parent_key]); $view = $view->parent; } unset($query['view']); if (isset($query['layout']) && $mLayout === $query['layout']) { unset($query['layout']); } if (isset($query['filter_tag']) && $mFilterTag === $query['filter_tag']) { unset($query['filter_tag']); } return; } } // Get the path from the view of the current URL and parse it to the menu item $path = array_reverse($this->router->getPath($query), true); $found = false; foreach ($path as $element => $ids) { $view = $views[$element]; if ($found === false && $item->query['view'] === $element) { if ($view->nestable) { $found = true; } elseif ($view->children) { $found = true; continue; } } if ($found === false) { // Jump to the next view continue; } if ($ids) { if ($view->nestable) { $found2 = false; foreach (array_reverse($ids, true) as $id => $segment) { if ($found2) { $segments[] = str_replace(':', '-', $segment); } elseif ((int) $item->query[$view->key] === (int) $id) { $found2 = true; } } } elseif ($ids === true) { $segments[] = $element; } else { $segments[] = str_replace(':', '-', current($ids)); } } if ($view->parent_key) { // Remove parent key from query unset($query[$view->parent_key]); } } if ($found) { unset($query[$views[$query['view']]->key], $query['view']); if (isset($query['layout']) && $mLayout === $query['layout']) { unset($query['layout']); } if (isset($query['filter_tag']) && $mFilterTag === $query['filter_tag']) { unset($query['filter_tag']); } } } } Rules/MenuRules.php 0000644 00000022336 15231072377 0010303 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router\Rules; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Component\Router\RouterView; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Rule to identify the right Itemid for a view in a component * * @since 3.4 */ class MenuRules implements RulesInterface { /** * Router this rule belongs to * * @var RouterView * @since 3.4 */ protected $router; /** * Lookup array of the menu items * * @var array * @since 3.4 */ protected $lookup = []; /** * System - SEF Plugin parameters * * @var Registry * @since 5.2.0 * @deprecated 5.2.0 will be removed in 6.0 * without replacement */ private $sefparams; /** * Class constructor. * * @param RouterView $router Router this rule belongs to * * @since 3.4 */ public function __construct(RouterView $router) { $this->router = $router; $sefPlugin = PluginHelper::getPlugin('system', 'sef'); if ($sefPlugin) { $this->sefparams = new Registry($sefPlugin->params); } else { $this->sefparams = new Registry(); } $this->buildLookup(); } /** * Finds the right Itemid for this query * * @param array &$query The query array to process * * @return void * * @since 3.4 */ public function preprocess(&$query) { $active = $this->router->menu->getActive(); /** * If the active item id is not the same as the supplied item id or we have a supplied item id and no active * menu item then we just use the supplied menu item and continue */ if (isset($query['Itemid']) && ($active === null || $query['Itemid'] != $active->id)) { return; } // Get query language $language = $query['lang'] ?? '*'; // Set the language to the current one when multilang is enabled and item is tagged to ALL if (Multilanguage::isEnabled() && $language === '*') { $language = $this->router->app->get('language'); } if (!isset($this->lookup[$language])) { $this->buildLookup($language); } // Check if the active menu item matches the requested query if ($active !== null && isset($query['Itemid'])) { // Check if active->query and supplied query are the same $match = true; foreach ($active->query as $k => $v) { if (isset($query[$k]) && $v !== $query[$k]) { // Compare again without alias if (\is_string($v) && $v == current(explode(':', $query[$k], 2))) { continue; } $match = false; break; } } if ($match) { // Just use the supplied menu item return; } } $needles = $this->router->getPath($query); $layout = isset($query['layout']) && $query['layout'] !== 'default' ? ':' . $query['layout'] : ''; if ($needles) { foreach ($needles as $view => $ids) { $viewLayout = $view . $layout; if ($layout && isset($this->lookup[$language][$viewLayout])) { if (\is_bool($ids)) { $query['Itemid'] = $this->lookup[$language][$viewLayout]; return; } foreach ($ids as $id => $segment) { if (isset($this->lookup[$language][$viewLayout][(int) $id])) { $query['Itemid'] = $this->lookup[$language][$viewLayout][(int) $id]; return; } } } if (isset($this->lookup[$language][$view])) { if (\is_bool($ids)) { $query['Itemid'] = $this->lookup[$language][$view]; return; } foreach ($ids as $id => $segment) { if (isset($this->lookup[$language][$view][(int) $id])) { $query['Itemid'] = $this->lookup[$language][$view][(int) $id]; return; } } } } } // TODO: Remove this whole block in 6.0 as it is a bug if (!$this->sefparams->get('strictrouting', 0)) { // Check if the active menuitem matches the requested language if ( $active && $active->component === 'com_' . $this->router->getName() && ($language === '*' || \in_array($active->language, ['*', $language]) || !Multilanguage::isEnabled()) ) { $query['Itemid'] = $active->id; return; } // If not found, return language specific home link $default = $this->router->menu->getDefault($language); if (!empty($default->id)) { $query['Itemid'] = $default->id; } } } /** * Method to build the lookup array * * @param string $language The language that the lookup should be built up for * * @return void * * @since 3.4 */ protected function buildLookup($language = '*') { // Prepare the reverse lookup array. if (!isset($this->lookup[$language])) { $this->lookup[$language] = []; $component = ComponentHelper::getComponent('com_' . $this->router->getName()); $views = $this->router->getViews(); $attributes = ['component_id']; $values = [(int) $component->id]; $attributes[] = 'language'; $values[] = [$language, '*']; $items = $this->router->menu->getItems($attributes, $values); foreach ($items as $item) { if (isset($item->query['view'], $views[$item->query['view']])) { $view = $item->query['view']; $layout = ''; if (isset($item->query['layout'])) { $layout = ':' . $item->query['layout']; } if ($views[$view]->key) { if (!isset($this->lookup[$language][$view . $layout])) { $this->lookup[$language][$view . $layout] = []; } if (!isset($this->lookup[$language][$view])) { $this->lookup[$language][$view] = []; } // If menuitem has no key set, we assume 0. if (!isset($item->query[$views[$view]->key])) { $item->query[$views[$view]->key] = 0; } /** * Here it will become a bit tricky * language != * can override existing entries * language == * cannot override existing entries */ if (!isset($this->lookup[$language][$view . $layout][$item->query[$views[$view]->key]]) || $item->language !== '*') { $this->lookup[$language][$view . $layout][$item->query[$views[$view]->key]] = $item->id; $this->lookup[$language][$view][$item->query[$views[$view]->key]] = $item->id; } } else { /** * Here it will become a bit tricky * language != * can override existing entries * language == * cannot override existing entries */ if (!isset($this->lookup[$language][$view . $layout]) || $item->language !== '*') { $this->lookup[$language][$view . $layout] = $item->id; } } } } } } /** * Dummy method to fulfil the interface requirements * * @param array &$segments The URL segments to parse * @param array &$vars The vars that result from the segments * * @return void * * @since 3.4 * @codeCoverageIgnore */ public function parse(&$segments, &$vars) { } /** * Dummy method to fulfil the interface requirements * * @param array &$query The vars that should be converted * @param array &$segments The URL segments to create * * @return void * * @since 3.4 * @codeCoverageIgnore */ public function build(&$query, &$segments) { } } Rules/RulesInterface.php 0000644 00000003420 15231072377 0011270 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Component\Router\Rules; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * RouterRules interface for Joomla * * @since 3.4 */ interface RulesInterface { /** * Prepares a query set to be handed over to the build() method. * This should complete a partial query set to work as a complete non-SEFed * URL and in general make sure that all information is present and properly * formatted. For example, the Itemid should be retrieved and set here. * * @param array &$query The query array to process * * @return void * * @since 3.4 */ public function preprocess(&$query); /** * Parses a URI to retrieve information for the right route through the component. * This method should retrieve all its input from its method arguments. * * @param array &$segments The URL segments to parse * @param array &$vars The vars that result from the segments * * @return void * * @since 3.4 */ public function parse(&$segments, &$vars); /** * Builds URI segments from a query to encode the necessary information for a route in a human-readable URL. * This method should retrieve all its input from its method arguments. * * @param array &$query The vars that should be converted * @param array &$segments The URL segments to create * * @return void * * @since 3.4 */ public function build(&$query, &$segments); } Rules/.htaccess 0000555 00000000355 15231072377 0007447 0 ustar 00 <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>