[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Component/Router/Rules/ -> StandardRules.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Component\Router\Rules;
  11  
  12  use Joomla\CMS\Component\Router\RouterView;
  13  
  14  // phpcs:disable PSR1.Files.SideEffects
  15  \defined('JPATH_PLATFORM') or die;
  16  // phpcs:enable PSR1.Files.SideEffects
  17  
  18  /**
  19   * Rule for the standard handling of component routing
  20   *
  21   * @since  3.4
  22   */
  23  class StandardRules implements RulesInterface
  24  {
  25      /**
  26       * Router this rule belongs to
  27       *
  28       * @var    RouterView
  29       * @since  3.4
  30       */
  31      protected $router;
  32  
  33      /**
  34       * Class constructor.
  35       *
  36       * @param   RouterView  $router  Router this rule belongs to
  37       *
  38       * @since   3.4
  39       */
  40      public function __construct(RouterView $router)
  41      {
  42          $this->router = $router;
  43      }
  44  
  45      /**
  46       * Dummy method to fulfil the interface requirements
  47       *
  48       * @param   array  &$query  The query array to process
  49       *
  50       * @return  void
  51       *
  52       * @since   3.4
  53       */
  54      public function preprocess(&$query)
  55      {
  56      }
  57  
  58      /**
  59       * Parse the URL
  60       *
  61       * @param   array  &$segments  The URL segments to parse
  62       * @param   array  &$vars      The vars that result from the segments
  63       *
  64       * @return  void
  65       *
  66       * @since   3.4
  67       */
  68      public function parse(&$segments, &$vars)
  69      {
  70          // Get the views and the currently active query vars
  71          $views  = $this->router->getViews();
  72          $active = $this->router->menu->getActive();
  73  
  74          if ($active) {
  75              $vars = array_merge($active->query, $vars);
  76          }
  77  
  78          // We don't have a view or its not a view of this component! We stop here
  79          if (!isset($vars['view']) || !isset($views[$vars['view']])) {
  80              return;
  81          }
  82  
  83          // Copy the segments, so that we can iterate over all of them and at the same time modify the original segments
  84          $tempSegments = $segments;
  85  
  86          // Iterate over the segments as long as a segment fits
  87          foreach ($tempSegments as $segment) {
  88              // Our current view is nestable. We need to check first if the segment fits to that
  89              if ($views[$vars['view']]->nestable) {
  90                  if (\is_callable(array($this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'))) {
  91                      $key = \call_user_func_array(array($this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'), array($segment, $vars));
  92  
  93                      // Did we get a proper key? If not, we need to look in the child-views
  94                      if ($key) {
  95                          $vars[$views[$vars['view']]->key] = $key;
  96  
  97                          array_shift($segments);
  98  
  99                          continue;
 100                      }
 101                  } else {
 102                      // The router is not complete. The get<View>Id() method is missing.
 103                      return;
 104                  }
 105              }
 106  
 107              // Lets find the right view that belongs to this segment
 108              $found = false;
 109  
 110              foreach ($views[$vars['view']]->children as $view) {
 111                  if (!$view->key) {
 112                      if ($view->name === $segment) {
 113                          // The segment is a view name
 114                          $parent       = $views[$vars['view']];
 115                          $vars['view'] = $view->name;
 116                          $found        = true;
 117  
 118                          if ($view->parent_key && isset($vars[$parent->key])) {
 119                              $parent_key              = $vars[$parent->key];
 120                              $vars[$view->parent_key] = $parent_key;
 121  
 122                              unset($vars[$parent->key]);
 123                          }
 124  
 125                          break;
 126                      }
 127                  } elseif (\is_callable(array($this->router, 'get' . ucfirst($view->name) . 'Id'))) {
 128                      // Hand the data over to the router specific method and see if there is a content item that fits
 129                      $key = \call_user_func_array(array($this->router, 'get' . ucfirst($view->name) . 'Id'), array($segment, $vars));
 130  
 131                      if ($key) {
 132                          // Found the right view and the right item
 133                          $parent       = $views[$vars['view']];
 134                          $vars['view'] = $view->name;
 135                          $found        = true;
 136  
 137                          if ($view->parent_key && isset($vars[$parent->key])) {
 138                              $parent_key              = $vars[$parent->key];
 139                              $vars[$view->parent_key] = $parent_key;
 140  
 141                              unset($vars[$parent->key]);
 142                          }
 143  
 144                          $vars[$view->key] = $key;
 145  
 146                          break;
 147                      }
 148                  }
 149              }
 150  
 151              if (!$found) {
 152                  return;
 153              }
 154  
 155              array_shift($segments);
 156          }
 157      }
 158  
 159      /**
 160       * Build a standard URL
 161       *
 162       * @param   array  &$query     The vars that should be converted
 163       * @param   array  &$segments  The URL segments to create
 164       *
 165       * @return  void
 166       *
 167       * @since   3.4
 168       */
 169      public function build(&$query, &$segments)
 170      {
 171          if (!isset($query['Itemid'], $query['view'])) {
 172              return;
 173          }
 174  
 175          // Get the menu item belonging to the Itemid that has been found
 176          $item = $this->router->menu->getItem($query['Itemid']);
 177  
 178          if (
 179              $item === null
 180              || $item->component !== 'com_' . $this->router->getName()
 181              || !isset($item->query['view'])
 182          ) {
 183              return;
 184          }
 185  
 186          // Get menu item layout
 187          $mLayout = isset($item->query['layout']) ? $item->query['layout'] : null;
 188  
 189          // Get all views for this component
 190          $views = $this->router->getViews();
 191  
 192          // Return directly when the URL of the Itemid is identical with the URL to build
 193          if ($item->query['view'] === $query['view']) {
 194              $view = $views[$query['view']];
 195  
 196              if (!$view->key) {
 197                  unset($query['view']);
 198  
 199                  if (isset($query['layout']) && $mLayout === $query['layout']) {
 200                      unset($query['layout']);
 201                  }
 202  
 203                  return;
 204              }
 205  
 206              if (isset($query[$view->key]) && $item->query[$view->key] == (int) $query[$view->key]) {
 207                  unset($query[$view->key]);
 208  
 209                  while ($view) {
 210                      unset($query[$view->parent_key]);
 211  
 212                      $view = $view->parent;
 213                  }
 214  
 215                  unset($query['view']);
 216  
 217                  if (isset($query['layout']) && $mLayout === $query['layout']) {
 218                      unset($query['layout']);
 219                  }
 220  
 221                  return;
 222              }
 223          }
 224  
 225          // Get the path from the view of the current URL and parse it to the menu item
 226          $path  = array_reverse($this->router->getPath($query), true);
 227          $found = false;
 228  
 229          foreach ($path as $element => $ids) {
 230              $view = $views[$element];
 231  
 232              if ($found === false && $item->query['view'] === $element) {
 233                  if ($view->nestable) {
 234                      $found = true;
 235                  } elseif ($view->children) {
 236                      $found = true;
 237  
 238                      continue;
 239                  }
 240              }
 241  
 242              if ($found === false) {
 243                  // Jump to the next view
 244                  continue;
 245              }
 246  
 247              if ($ids) {
 248                  if ($view->nestable) {
 249                      $found2 = false;
 250  
 251                      foreach (array_reverse($ids, true) as $id => $segment) {
 252                          if ($found2) {
 253                              $segments[] = str_replace(':', '-', $segment);
 254                          } elseif ((int) $item->query[$view->key] === (int) $id) {
 255                              $found2 = true;
 256                          }
 257                      }
 258                  } elseif ($ids === true) {
 259                      $segments[] = $element;
 260                  } else {
 261                      $segments[] = str_replace(':', '-', current($ids));
 262                  }
 263              }
 264  
 265              if ($view->parent_key) {
 266                  // Remove parent key from query
 267                  unset($query[$view->parent_key]);
 268              }
 269          }
 270  
 271          if ($found) {
 272              unset($query[$views[$query['view']]->key], $query['view']);
 273  
 274              if (isset($query['layout']) && $mLayout === $query['layout']) {
 275                  unset($query['layout']);
 276              }
 277          }
 278      }
 279  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer