[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Administrator 5 * @subpackage com_menus 6 * 7 * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> 8 * @license GNU General Public License version 2 or later; see LICENSE.txt 9 */ 10 11 namespace Joomla\Component\Menus\Administrator\Model; 12 13 use Joomla\CMS\Helper\ModuleHelper; 14 use Joomla\CMS\Language\LanguageHelper; 15 use Joomla\CMS\MVC\Factory\MVCFactoryInterface; 16 use Joomla\CMS\MVC\Model\ListModel; 17 use Joomla\Database\ParameterType; 18 19 // phpcs:disable PSR1.Files.SideEffects 20 \defined('_JEXEC') or die; 21 // phpcs:enable PSR1.Files.SideEffects 22 23 /** 24 * Menu List Model for Menus. 25 * 26 * @since 1.6 27 */ 28 class MenusModel extends ListModel 29 { 30 /** 31 * Constructor. 32 * 33 * @param array $config An optional associative array of configuration settings. 34 * @param MVCFactoryInterface $factory The factory. 35 * 36 * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel 37 * @since 3.2 38 */ 39 public function __construct($config = array(), MVCFactoryInterface $factory = null) 40 { 41 if (empty($config['filter_fields'])) { 42 $config['filter_fields'] = array( 43 'id', 'a.id', 44 'title', 'a.title', 45 'menutype', 'a.menutype', 46 'client_id', 'a.client_id', 47 ); 48 } 49 50 parent::__construct($config, $factory); 51 } 52 53 /** 54 * Overrides the getItems method to attach additional metrics to the list. 55 * 56 * @return mixed An array of data items on success, false on failure. 57 * 58 * @since 1.6.1 59 */ 60 public function getItems() 61 { 62 // Get a storage key. 63 $store = $this->getStoreId('getItems'); 64 65 // Try to load the data from internal storage. 66 if (!empty($this->cache[$store])) { 67 return $this->cache[$store]; 68 } 69 70 // Load the list items. 71 $items = parent::getItems(); 72 73 // If empty or an error, just return. 74 if (empty($items)) { 75 return array(); 76 } 77 78 // Getting the following metric by joins is WAY TOO SLOW. 79 // Faster to do three queries for very large menu trees. 80 81 // Get the menu types of menus in the list. 82 $db = $this->getDatabase(); 83 $menuTypes = array_column((array) $items, 'menutype'); 84 85 $query = $db->getQuery(true) 86 ->select( 87 [ 88 $db->quoteName('m.menutype'), 89 'COUNT(DISTINCT ' . $db->quoteName('m.id') . ') AS ' . $db->quoteName('count_published'), 90 ] 91 ) 92 ->from($db->quoteName('#__menu', 'm')) 93 ->where($db->quoteName('m.published') . ' = :published') 94 ->whereIn($db->quoteName('m.menutype'), $menuTypes, ParameterType::STRING) 95 ->group($db->quoteName('m.menutype')) 96 ->bind(':published', $published, ParameterType::INTEGER); 97 98 $db->setQuery($query); 99 100 // Get the published menu counts. 101 try { 102 $published = 1; 103 $countPublished = $db->loadAssocList('menutype', 'count_published'); 104 } catch (\RuntimeException $e) { 105 $this->setError($e->getMessage()); 106 107 return false; 108 } 109 110 // Get the unpublished menu counts. 111 try { 112 $published = 0; 113 $countUnpublished = $db->loadAssocList('menutype', 'count_published'); 114 } catch (\RuntimeException $e) { 115 $this->setError($e->getMessage()); 116 117 return false; 118 } 119 120 // Get the trashed menu counts. 121 try { 122 $published = -2; 123 $countTrashed = $db->loadAssocList('menutype', 'count_published'); 124 } catch (\RuntimeException $e) { 125 $this->setError($e->getMessage()); 126 127 return false; 128 } 129 130 // Inject the values back into the array. 131 foreach ($items as $item) { 132 $item->count_published = $countPublished[$item->menutype] ?? 0; 133 $item->count_unpublished = $countUnpublished[$item->menutype] ?? 0; 134 $item->count_trashed = $countTrashed[$item->menutype] ?? 0; 135 } 136 137 // Add the items to the internal cache. 138 $this->cache[$store] = $items; 139 140 return $this->cache[$store]; 141 } 142 143 /** 144 * Method to build an SQL query to load the list data. 145 * 146 * @return string An SQL query 147 * 148 * @since 1.6 149 */ 150 protected function getListQuery() 151 { 152 // Create a new query object. 153 $db = $this->getDatabase(); 154 $query = $db->getQuery(true); 155 $clientId = (int) $this->getState('client_id'); 156 157 // Select all fields from the table. 158 $query->select( 159 $this->getState( 160 'list.select', 161 [ 162 $db->quoteName('a.id'), 163 $db->quoteName('a.menutype'), 164 $db->quoteName('a.title'), 165 $db->quoteName('a.description'), 166 $db->quoteName('a.client_id'), 167 ] 168 ) 169 ) 170 ->from($db->quoteName('#__menu_types', 'a')) 171 ->where( 172 [ 173 $db->quoteName('a.id') . ' > 0', 174 $db->quoteName('a.client_id') . ' = :clientId', 175 ] 176 ) 177 ->bind(':clientId', $clientId, ParameterType::INTEGER); 178 179 // Filter by search in title or menutype 180 if ($search = trim($this->getState('filter.search', ''))) { 181 $search = '%' . str_replace(' ', '%', $search) . '%'; 182 $query->extendWhere( 183 'AND', 184 [ 185 $db->quoteName('a.title') . ' LIKE :search1' , 186 $db->quoteName('a.menutype') . ' LIKE :search2', 187 ], 188 'OR' 189 ) 190 ->bind([':search1', ':search2'], $search); 191 } 192 193 // Add the list ordering clause. 194 $query->order($db->escape($this->getState('list.ordering', 'a.id')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); 195 196 return $query; 197 } 198 199 /** 200 * Method to auto-populate the model state. 201 * 202 * Note. Calling getState in this method will result in recursion. 203 * 204 * @param string $ordering An optional ordering field. 205 * @param string $direction An optional direction (asc|desc). 206 * 207 * @return void 208 * 209 * @since 1.6 210 */ 211 protected function populateState($ordering = 'a.title', $direction = 'asc') 212 { 213 $search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search'); 214 $this->setState('filter.search', $search); 215 216 $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); 217 $this->setState('client_id', $clientId); 218 219 // List state information. 220 parent::populateState($ordering, $direction); 221 } 222 223 /** 224 * Gets the extension id of the core mod_menu module. 225 * 226 * @return integer 227 * 228 * @since 2.5 229 */ 230 public function getModMenuId() 231 { 232 $clientId = (int) $this->getState('client_id'); 233 $db = $this->getDatabase(); 234 $query = $db->getQuery(true) 235 ->select($db->quoteName('e.extension_id')) 236 ->from($db->quoteName('#__extensions', 'e')) 237 ->where( 238 [ 239 $db->quoteName('e.type') . ' = ' . $db->quote('module'), 240 $db->quoteName('e.element') . ' = ' . $db->quote('mod_menu'), 241 $db->quoteName('e.client_id') . ' = :clientId', 242 ] 243 ) 244 ->bind(':clientId', $clientId, ParameterType::INTEGER); 245 $db->setQuery($query); 246 247 return $db->loadResult(); 248 } 249 250 /** 251 * Gets a list of all mod_mainmenu modules and collates them by menutype 252 * 253 * @return array 254 * 255 * @since 1.6 256 */ 257 public function &getModules() 258 { 259 $model = $this->bootComponent('com_menus') 260 ->getMVCFactory()->createModel('Menu', 'Administrator', ['ignore_request' => true]); 261 $result = $model->getModules(); 262 263 return $result; 264 } 265 266 /** 267 * Returns the missing module languages. 268 * 269 * @return array 270 * 271 * @since _DEPLOY_VERSION__ 272 */ 273 public function getMissingModuleLanguages(): array 274 { 275 // Check custom administrator menu modules 276 if (!ModuleHelper::isAdminMultilang()) { 277 return []; 278 } 279 280 $languages = LanguageHelper::getInstalledLanguages(1, true); 281 $langCodes = []; 282 283 foreach ($languages as $language) { 284 if (isset($language->metadata['nativeName'])) { 285 $languageName = $language->metadata['nativeName']; 286 } else { 287 $languageName = $language->metadata['name']; 288 } 289 290 $langCodes[$language->metadata['tag']] = $languageName; 291 } 292 293 $db = $this->getDatabase(); 294 $query = $db->getQuery(true); 295 296 $query->select($db->quoteName('m.language')) 297 ->from($db->quoteName('#__modules', 'm')) 298 ->where( 299 [ 300 $db->quoteName('m.module') . ' = ' . $db->quote('mod_menu'), 301 $db->quoteName('m.published') . ' = 1', 302 $db->quoteName('m.client_id') . ' = 1', 303 ] 304 ) 305 ->group($db->quoteName('m.language')); 306 307 $mLanguages = $db->setQuery($query)->loadColumn(); 308 309 // Check if we have a mod_menu module set to All languages or a mod_menu module for each admin language. 310 if (!in_array('*', $mLanguages) && count($langMissing = array_diff(array_keys($langCodes), $mLanguages))) { 311 return array_intersect_key($langCodes, array_flip($langMissing)); 312 } 313 314 return []; 315 } 316 }
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 |