[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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> '; 405 $spacer = '.      '; 406 } else { 407 $pre = '- '; 408 $spacer = '  '; 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |