1 <?php
2 /**
3 * @package Joomla.Libraries
4 * @subpackage Menu
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE.txt
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 use Joomla\Registry\Registry;
13
14 /**
15 * JMenu class
16 *
17 * @since 1.5
18 */
19 class JMenu
20 {
21 /**
22 * Array to hold the menu items
23 *
24 * @var JMenuItem[]
25 * @since 1.5
26 * @deprecated 4.0 Will convert to $items
27 */
28 protected $_items = array();
29
30 /**
31 * Identifier of the default menu item
32 *
33 * @var integer
34 * @since 1.5
35 * @deprecated 4.0 Will convert to $default
36 */
37 protected $_default = array();
38
39 /**
40 * Identifier of the active menu item
41 *
42 * @var integer
43 * @since 1.5
44 * @deprecated 4.0 Will convert to $active
45 */
46 protected $_active = 0;
47
48 /**
49 * JMenu instances container.
50 *
51 * @var JMenu[]
52 * @since 1.7
53 */
54 protected static $instances = array();
55
56 /**
57 * User object to check access levels for
58 *
59 * @var JUser
60 * @since 3.5
61 */
62 protected $user;
63
64 /**
65 * Class constructor
66 *
67 * @param array $options An array of configuration options.
68 *
69 * @since 1.5
70 */
71 public function __construct($options = array())
72 {
73 // Load the menu items
74 $this->load();
75
76 foreach ($this->_items as $item)
77 {
78 if ($item->home)
79 {
80 $this->_default[trim($item->language)] = $item->id;
81 }
82 }
83
84 $this->user = isset($options['user']) && $options['user'] instanceof JUser ? $options['user'] : JFactory::getUser();
85 }
86
87 /**
88 * Returns a JMenu object
89 *
90 * @param string $client The name of the client
91 * @param array $options An associative array of options
92 *
93 * @return JMenu A menu object.
94 *
95 * @since 1.5
96 * @throws Exception
97 */
98 public static function getInstance($client, $options = array())
99 {
100 if (empty(self::$instances[$client]))
101 {
102 // Create a JMenu object
103 $classname = 'JMenu' . ucfirst($client);
104
105 if (!class_exists($classname))
106 {
107 // @deprecated 4.0 Everything in this block is deprecated but the warning is only logged after the file_exists
108 // Load the menu object
109 $info = JApplicationHelper::getClientInfo($client, true);
110
111 if (is_object($info))
112 {
113 $path = $info->path . '/includes/menu.php';
114
115 JLoader::register($classname, $path);
116
117 if (class_exists($classname))
118 {
119 JLog::add('Non-autoloadable JMenu subclasses are deprecated, support will be removed in 4.0.', JLog::WARNING, 'deprecated');
120 }
121 }
122 }
123
124 if (!class_exists($classname))
125 {
126 throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_MENU_LOAD', $client), 500);
127 }
128
129 self::$instances[$client] = new $classname($options);
130 }
131
132 return self::$instances[$client];
133 }
134
135 /**
136 * Get menu item by id
137 *
138 * @param integer $id The item id
139 *
140 * @return JMenuItem|null The item object if the ID exists or null if not found
141 *
142 * @since 1.5
143 */
144 public function getItem($id)
145 {
146 $result = null;
147
148 if (isset($this->_items[$id]))
149 {
150 $result = &$this->_items[$id];
151 }
152
153 return $result;
154 }
155
156 /**
157 * Set the default item by id and language code.
158 *
159 * @param integer $id The menu item id.
160 * @param string $language The language code (since 1.6).
161 *
162 * @return boolean True if a menu item with the given ID exists
163 *
164 * @since 1.5
165 */
166 public function setDefault($id, $language = '*')
167 {
168 if (isset($this->_items[$id]))
169 {
170 $this->_default[$language] = $id;
171
172 return true;
173 }
174
175 return false;
176 }
177
178 /**
179 * Get the default item by language code.
180 *
181 * @param string $language The language code, default value of * means all.
182 *
183 * @return JMenuItem|null The item object or null when not found for given language
184 *
185 * @since 1.5
186 */
187 public function getDefault($language = '*')
188 {
189 if (array_key_exists($language, $this->_default))
190 {
191 return $this->_items[$this->_default[$language]];
192 }
193
194 if (array_key_exists('*', $this->_default))
195 {
196 return $this->_items[$this->_default['*']];
197 }
198
199 return;
200 }
201
202 /**
203 * Set the default item by id
204 *
205 * @param integer $id The item id
206 *
207 * @return JMenuItem|null The menu item representing the given ID if present or null otherwise
208 *
209 * @since 1.5
210 */
211 public function setActive($id)
212 {
213 if (isset($this->_items[$id]))
214 {
215 $this->_active = $id;
216
217 return $this->_items[$id];
218 }
219
220 return;
221 }
222
223 /**
224 * Get menu item by id.
225 *
226 * @return JMenuItem|null The item object if an active menu item has been set or null
227 *
228 * @since 1.5
229 */
230 public function getActive()
231 {
232 if ($this->_active)
233 {
234 return $this->_items[$this->_active];
235 }
236
237 return;
238 }
239
240 /**
241 * Gets menu items by attribute
242 *
243 * @param mixed $attributes The field name(s).
244 * @param mixed $values The value(s) of the field. If an array, need to match field names
245 * each attribute may have multiple values to lookup for.
246 * @param boolean $firstonly If true, only returns the first item found
247 *
248 * @return JMenuItem|JMenuItem[] An array of menu item objects or a single object if the $firstonly parameter is true
249 *
250 * @since 1.5
251 */
252 public function getItems($attributes, $values, $firstonly = false)
253 {
254 $items = array();
255 $attributes = (array) $attributes;
256 $values = (array) $values;
257 $count = count($attributes);
258
259 foreach ($this->_items as $item)
260 {
261 if (!is_object($item))
262 {
263 continue;
264 }
265
266 $test = true;
267
268 for ($i = 0; $i < $count; $i++)
269 {
270 if (is_array($values[$i]))
271 {
272 if (!in_array($item->{$attributes[$i]}, $values[$i]))
273 {
274 $test = false;
275 break;
276 }
277 }
278 else
279 {
280 if ($item->{$attributes[$i]} != $values[$i])
281 {
282 $test = false;
283 break;
284 }
285 }
286 }
287
288 if ($test)
289 {
290 if ($firstonly)
291 {
292 return $item;
293 }
294
295 $items[] = $item;
296 }
297 }
298
299 return $items;
300 }
301
302 /**
303 * Gets the parameter object for a certain menu item
304 *
305 * @param integer $id The item id
306 *
307 * @return Registry
308 *
309 * @since 1.5
310 */
311 public function getParams($id)
312 {
313 if ($menu = $this->getItem($id))
314 {
315 return $menu->params;
316 }
317
318 return new Registry;
319 }
320
321 /**
322 * Getter for the menu array
323 *
324 * @return JMenuItem[]
325 *
326 * @since 1.5
327 */
328 public function getMenu()
329 {
330 return $this->_items;
331 }
332
333 /**
334 * Method to check JMenu object authorization against an access control object and optionally an access extension object
335 *
336 * @param integer $id The menu id
337 *
338 * @return boolean
339 *
340 * @since 1.5
341 */
342 public function authorise($id)
343 {
344 $menu = $this->getItem($id);
345
346 if ($menu)
347 {
348 return in_array((int) $menu->access, $this->user->getAuthorisedViewLevels());
349 }
350
351 return true;
352 }
353
354 /**
355 * Loads the menu items
356 *
357 * @return array
358 *
359 * @since 1.5
360 */
361 public function load()
362 {
363 return array();
364 }
365 }
366