[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/HTML/Helpers/ -> Menu.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2007 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\HTML\Helpers;
  11  
  12  use Joomla\CMS\Factory;
  13  use Joomla\CMS\HTML\HTMLHelper;
  14  use Joomla\CMS\Language\Text;
  15  use Joomla\Database\ParameterType;
  16  
  17  // phpcs:disable PSR1.Files.SideEffects
  18  \defined('JPATH_PLATFORM') or die;
  19  // phpcs:enable PSR1.Files.SideEffects
  20  
  21  /**
  22   * Utility class working with menu select lists
  23   *
  24   * @since  1.5
  25   */
  26  abstract class Menu
  27  {
  28      /**
  29       * Cached array of the menus.
  30       *
  31       * @var    array
  32       * @since  1.6
  33       */
  34      protected static $menus = array();
  35  
  36      /**
  37       * Cached array of the menus items.
  38       *
  39       * @var    array
  40       * @since  1.6
  41       */
  42      protected static $items = array();
  43  
  44      /**
  45       * Get a list of the available menus.
  46       *
  47       * @param   int  $clientId  The client id
  48       *
  49       * @return  array
  50       *
  51       * @since   1.6
  52       */
  53      public static function menus($clientId = 0)
  54      {
  55          $key = serialize($clientId);
  56  
  57          if (!isset(static::$menus[$key])) {
  58              $db = Factory::getDbo();
  59  
  60              $query = $db->getQuery(true)
  61                  ->select(
  62                      [
  63                          $db->quoteName('id'),
  64                          $db->quoteName('menutype', 'value'),
  65                          $db->quoteName('title', 'text'),
  66                          $db->quoteName('client_id'),
  67                      ]
  68                  )
  69                  ->from($db->quoteName('#__menu_types'))
  70                  ->order(
  71                      [
  72                          $db->quoteName('client_id'),
  73                          $db->quoteName('title'),
  74                      ]
  75                  );
  76  
  77              if (isset($clientId)) {
  78                  $clientId = (int) $clientId;
  79                  $query->where($db->quoteName('client_id') . ' = :client')
  80                      ->bind(':client', $clientId, ParameterType::INTEGER);
  81              }
  82  
  83              static::$menus[$key] = $db->setQuery($query)->loadObjectList();
  84          }
  85  
  86          return static::$menus[$key];
  87      }
  88  
  89      /**
  90       * Returns an array of menu items grouped by menu.
  91       *
  92       * @param   array  $config  An array of configuration options [published, checkacl, clientid].
  93       *
  94       * @return  array
  95       *
  96       * @since   1.6
  97       */
  98      public static function menuItems($config = array())
  99      {
 100          $key = serialize($config);
 101  
 102          if (empty(static::$items[$key])) {
 103              // B/C - not passed  = 0, null can be passed for both clients
 104              $clientId = array_key_exists('clientid', $config) ? $config['clientid'] : 0;
 105              $menus    = static::menus($clientId);
 106  
 107              $db    = Factory::getDbo();
 108              $query = $db->getQuery(true)
 109                  ->select(
 110                      [
 111                          $db->quoteName('a.id', 'value'),
 112                          $db->quoteName('a.title', 'text'),
 113                          $db->quoteName('a.level'),
 114                          $db->quoteName('a.menutype'),
 115                          $db->quoteName('a.client_id'),
 116                      ]
 117                  )
 118                  ->from($db->quoteName('#__menu', 'a'))
 119                  ->where($db->quoteName('a.parent_id') . ' > 0');
 120  
 121              // Filter on the client id
 122              if (isset($clientId)) {
 123                  $query->where($db->quoteName('a.client_id') . ' = :client')
 124                      ->bind(':client', $clientId, ParameterType::INTEGER);
 125              }
 126  
 127              // Filter on the published state
 128              if (isset($config['published'])) {
 129                  if (is_numeric($config['published'])) {
 130                      $query->where($db->quoteName('a.published') . ' = :published')
 131                          ->bind(':published', $config['published'], ParameterType::INTEGER);
 132                  } elseif ($config['published'] === '') {
 133                      $query->where($db->quoteName('a.published') . ' IN (0,1)');
 134                  }
 135              }
 136  
 137              $query->order($db->quoteName('a.lft'));
 138  
 139              $db->setQuery($query);
 140              $items = $db->loadObjectList();
 141  
 142              // Collate menu items based on menutype
 143              $lookup = array();
 144  
 145              foreach ($items as &$item) {
 146                  if (!isset($lookup[$item->menutype])) {
 147                      $lookup[$item->menutype] = array();
 148                  }
 149  
 150                  $lookup[$item->menutype][] = &$item;
 151  
 152                  // Translate the menu item title when client is administrator
 153                  if ($clientId === 1) {
 154                      $item->text = Text::_($item->text);
 155                  }
 156  
 157                  $item->text = str_repeat('- ', $item->level) . $item->text;
 158              }
 159  
 160              static::$items[$key] = array();
 161  
 162              $user = Factory::getUser();
 163  
 164              $aclcheck = !empty($config['checkacl']) ? (int) $config['checkacl'] : 0;
 165  
 166              foreach ($menus as &$menu) {
 167                  if ($aclcheck) {
 168                      $action = $aclcheck == $menu->id ? 'edit' : 'create';
 169  
 170                      if (!$user->authorise('core.' . $action, 'com_menus.menu.' . $menu->id)) {
 171                          continue;
 172                      }
 173                  }
 174  
 175                  // Start group:
 176                  $optGroup = new \stdClass();
 177                  $optGroup->value = '<OPTGROUP>';
 178                  $optGroup->text = $menu->text;
 179                  static::$items[$key][] = $optGroup;
 180  
 181                  // Special "Add to this Menu" option:
 182                  static::$items[$key][] = HTMLHelper::_('select.option', $menu->value . '.1', Text::_('JLIB_HTML_ADD_TO_THIS_MENU'));
 183  
 184                  // Menu items:
 185                  if (isset($lookup[$menu->value])) {
 186                      foreach ($lookup[$menu->value] as &$item) {
 187                          static::$items[$key][] = HTMLHelper::_('select.option', $menu->value . '.' . $item->value, $item->text);
 188                      }
 189                  }
 190  
 191                  // Finish group:
 192                  $closeOptGroup = new \stdClass();
 193                  $closeOptGroup->value = '</OPTGROUP>';
 194                  $closeOptGroup->text = $menu->text;
 195  
 196                  static::$items[$key][] = $closeOptGroup;
 197              }
 198          }
 199  
 200          return static::$items[$key];
 201      }
 202  
 203      /**
 204       * Displays an HTML select list of menu items.
 205       *
 206       * @param   string  $name      The name of the control.
 207       * @param   string  $selected  The value of the selected option.
 208       * @param   string  $attribs   Attributes for the control.
 209       * @param   array   $config    An array of options for the control [id, published, checkacl, clientid].
 210       *
 211       * @return  string
 212       *
 213       * @since   1.6
 214       */
 215      public static function menuItemList($name, $selected = null, $attribs = null, $config = array())
 216      {
 217          static $count;
 218  
 219          $options = static::menuItems($config);
 220  
 221          return HTMLHelper::_(
 222              'select.genericlist',
 223              $options,
 224              $name,
 225              array(
 226                  'id'             => $config['id'] ?? 'assetgroups_' . (++$count),
 227                  'list.attr'      => $attribs ?? 'class="inputbox" size="1"',
 228                  'list.select'    => (int) $selected,
 229                  'list.translate' => false,
 230              )
 231          );
 232      }
 233  
 234      /**
 235       * Build the select list for Menu Ordering
 236       *
 237       * @param   object   $row   The row object
 238       * @param   integer  $id    The id for the row. Must exist to enable menu ordering
 239       *
 240       * @return  string
 241       *
 242       * @since   1.5
 243       */
 244      public static function ordering(&$row, $id)
 245      {
 246          if ($id) {
 247              $db = Factory::getDbo();
 248              $query = $db->getQuery(true)
 249                  ->select(
 250                      [
 251                          $db->quoteName('ordering', 'value'),
 252                          $db->quoteName('title', 'text'),
 253                      ]
 254                  )
 255                  ->from($db->quoteName('#__menu'))
 256                  ->where(
 257                      [
 258                          $db->quoteName('menutype') . ' = :menutype',
 259                          $db->quoteName('parent_id') . ' = :parent',
 260                          $db->quoteName('published') . ' != -2',
 261                      ]
 262                  )
 263                  ->order($db->quoteName('ordering'))
 264                  ->bind(':menutype', $row->menutype)
 265                  ->bind(':parent', $row->parent_id, ParameterType::INTEGER);
 266              $order = HTMLHelper::_('list.genericordering', $query);
 267              $ordering = HTMLHelper::_(
 268                  'select.genericlist',
 269                  $order,
 270                  'ordering',
 271                  array('list.attr' => 'class="inputbox" size="1"', 'list.select' => (int) $row->ordering)
 272              );
 273          } else {
 274              $ordering = '<input type="hidden" name="ordering" value="' . $row->ordering . '">' . Text::_('JGLOBAL_NEWITEMSLAST_DESC');
 275          }
 276  
 277          return $ordering;
 278      }
 279  
 280      /**
 281       * Build the multiple select list for Menu Links/Pages
 282       *
 283       * @param   boolean  $all         True if all can be selected
 284       * @param   boolean  $unassigned  True if unassigned can be selected
 285       * @param   int      $clientId    The client id
 286       *
 287       * @return  string
 288       *
 289       * @since   1.5
 290       */
 291      public static function linkOptions($all = false, $unassigned = false, $clientId = 0)
 292      {
 293          $db = Factory::getDbo();
 294  
 295          // Get a list of the menu items
 296          $query = $db->getQuery(true)
 297              ->select(
 298                  [
 299                      $db->quoteName('m.id'),
 300                      $db->quoteName('m.parent_id'),
 301                      $db->quoteName('m.title'),
 302                      $db->quoteName('m.menutype'),
 303                      $db->quoteName('m.client_id'),
 304                  ]
 305              )
 306              ->from($db->quoteName('#__menu', 'm'))
 307              ->where($db->quoteName('m.published') . ' = 1')
 308              ->order(
 309                  [
 310                      $db->quoteName('m.client_id'),
 311                      $db->quoteName('m.menutype'),
 312                      $db->quoteName('m.parent_id'),
 313                  ]
 314              );
 315  
 316          if (isset($clientId)) {
 317              $clientId = (int) $clientId;
 318              $query->where($db->quoteName('m.client_id') . ' = :client')
 319                  ->bind(':client', $clientId, ParameterType::INTEGER);
 320          }
 321  
 322          $db->setQuery($query);
 323  
 324          $mitems = $db->loadObjectList();
 325  
 326          if (!$mitems) {
 327              $mitems = array();
 328          }
 329  
 330          // Establish the hierarchy of the menu
 331          $children = array();
 332  
 333          // First pass - collect children
 334          foreach ($mitems as $v) {
 335              $pt            = $v->parent_id;
 336              $list          = @$children[$pt] ? $children[$pt] : array();
 337              $list[]        = $v;
 338              $children[$pt] = $list;
 339          }
 340  
 341          // Second pass - get an indent list of the items
 342          $list = static::treerecurse((int) $mitems[0]->parent_id, '', array(), $children, 9999, 0, 0);
 343  
 344          // Code that adds menu name to Display of Page(s)
 345          $mitems = array();
 346  
 347          if ($all | $unassigned) {
 348              $mitems[] = HTMLHelper::_('select.option', '<OPTGROUP>', Text::_('JOPTION_MENUS'));
 349  
 350              if ($all) {
 351                  $mitems[] = HTMLHelper::_('select.option', 0, Text::_('JALL'));
 352              }
 353  
 354              if ($unassigned) {
 355                  $mitems[] = HTMLHelper::_('select.option', -1, Text::_('JOPTION_UNASSIGNED'));
 356              }
 357  
 358              $mitems[] = HTMLHelper::_('select.option', '</OPTGROUP>');
 359          }
 360  
 361          $lastMenuType = null;
 362          $tmpMenuType  = null;
 363  
 364          foreach ($list as $list_a) {
 365              if ($list_a->menutype != $lastMenuType) {
 366                  if ($tmpMenuType) {
 367                      $mitems[] = HTMLHelper::_('select.option', '</OPTGROUP>');
 368                  }
 369  
 370                  $mitems[]     = HTMLHelper::_('select.option', '<OPTGROUP>', $list_a->menutype);
 371                  $lastMenuType = $list_a->menutype;
 372                  $tmpMenuType  = $list_a->menutype;
 373              }
 374  
 375              $mitems[] = HTMLHelper::_('select.option', $list_a->id, $list_a->title);
 376          }
 377  
 378          if ($lastMenuType !== null) {
 379              $mitems[] = HTMLHelper::_('select.option', '</OPTGROUP>');
 380          }
 381  
 382          return $mitems;
 383      }
 384  
 385      /**
 386       * Build the list representing the menu tree
 387       *
 388       * @param   integer  $id         Id of the menu item
 389       * @param   string   $indent     The indentation string
 390       * @param   array    $list       The list to process
 391       * @param   array    $children   The children of the current item
 392       * @param   integer  $maxlevel   The maximum number of levels in the tree
 393       * @param   integer  $level      The starting level
 394       * @param   int      $type       Set the type of spacer to use. Use 1 for |_ or 0 for -
 395       *
 396       * @return  array
 397       *
 398       * @since   1.5
 399       */
 400      public static function treerecurse($id, $indent, $list, &$children, $maxlevel = 9999, $level = 0, $type = 1)
 401      {
 402          if ($level <= $maxlevel && isset($children[$id]) && is_array($children[$id])) {
 403              if ($type) {
 404                  $pre    = '<sup>|_</sup>&#160;';
 405                  $spacer = '.&#160;&#160;&#160;&#160;&#160;&#160;';
 406              } else {
 407                  $pre    = '- ';
 408                  $spacer = '&#160;&#160;';
 409              }
 410  
 411              foreach ($children[$id] as $v) {
 412                  $id = $v->id;
 413  
 414                  if ($v->parent_id == 0) {
 415                      $txt = $v->title;
 416                  } else {
 417                      $txt = $pre . $v->title;
 418                  }
 419  
 420                  $list[$id]           = $v;
 421                  $list[$id]->treename = $indent . $txt;
 422  
 423                  if (isset($children[$id]) && is_array($children[$id])) {
 424                      $list[$id]->children = count($children[$id]);
 425                      $list                = static::treerecurse($id, $indent . $spacer, $list, $children, $maxlevel, $level + 1, $type);
 426                  } else {
 427                      $list[$id]->children = 0;
 428                  }
 429              }
 430          }
 431  
 432          return $list;
 433      }
 434  }


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