PageRenderTime 21ms CodeModel.GetById 13ms app.highlight 6ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/modules/mod_menu/menu.php

https://bitbucket.org/eternaware/joomus
PHP | 395 lines | 194 code | 47 blank | 154 comment | 36 complexity | 203ca6e9d895872932afabddfb0b2b42 MD5 | raw file
Possible License(s): LGPL-2.1
  1<?php
  2/**
  3 * @package     Joomla.Administrator
  4 * @subpackage  mod_menu
  5 *
  6 * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7 * @license     GNU General Public License version 2 or later; see LICENSE.txt
  8 */
  9
 10defined('_JEXEC') or die;
 11
 12/**
 13 * Tree based class to render the admin menu
 14 *
 15 * @package     Joomla.Administrator
 16 * @subpackage  mod_menu
 17 * @since       1.5
 18 */
 19class JAdminCssMenu extends JObject
 20{
 21	/**
 22	 * CSS string to add to document head
 23	 * @var string
 24	 */
 25	protected $_css = null;
 26
 27	/**
 28	 * Root node
 29	 *
 30	 * @var    object
 31	 */
 32	protected $_root = null;
 33
 34	/**
 35	 * Current working node
 36	 *
 37	 * @var    object
 38	 */
 39	protected $_current = null;
 40
 41	/**
 42	 * Constructor
 43	 */
 44	public function __construct()
 45	{
 46		$this->_root = new JMenuNode('ROOT');
 47		$this->_current = & $this->_root;
 48	}
 49
 50	/**
 51	 * Method to add a child
 52	 *
 53	 * @param   JMenuNode  &$node       The node to process
 54	 * @param   boolean    $setCurrent  True to set as current working node
 55	 *
 56	 * @return  void
 57	 */
 58	public function addChild(JMenuNode &$node, $setCurrent = false)
 59	{
 60		$this->_current->addChild($node);
 61		if ($setCurrent)
 62		{
 63			$this->_current = &$node;
 64		}
 65	}
 66
 67	/**
 68	 * Method to get the parent
 69	 *
 70	 * @return  void
 71	 */
 72	public function getParent()
 73	{
 74		$this->_current = &$this->_current->getParent();
 75	}
 76
 77	/**
 78	 * Method to get the parent
 79	 *
 80	 * @return  void
 81	 */
 82	public function reset()
 83	{
 84		$this->_current = &$this->_root;
 85	}
 86
 87	public function addSeparator()
 88	{
 89		$this->addChild(new JMenuNode(null, null, 'separator', false));
 90	}
 91
 92	public function renderMenu($id = 'menu', $class = '')
 93	{
 94		$depth = 1;
 95
 96		if (!empty($id)) {
 97			$id = 'id="' . $id . '"';
 98		}
 99
100		if (!empty($class)) {
101			$class = 'class="' . $class . '"';
102		}
103
104		/*
105		 * Recurse through children if they exist
106		 */
107		while ($this->_current->hasChildren())
108		{
109			echo "<ul ".$id." ".$class.">\n";
110			foreach ($this->_current->getChildren() as $child)
111			{
112				$this->_current = & $child;
113				$this->renderLevel($depth++);
114			}
115			echo "</ul>\n";
116		}
117
118		if ($this->_css) {
119			// Add style to document head
120			$doc = JFactory::getDocument();
121			$doc->addStyleDeclaration($this->_css);
122		}
123	}
124
125	public function renderLevel($depth)
126	{
127		/*
128		 * Build the CSS class suffix
129		 */
130		$class = '';
131		if ($this->_current->hasChildren()) {
132			$class = ' class="dropdown"';
133		}
134
135		if ($this->_current->class == 'separator') {
136			$class = ' class="divider"';
137		}
138
139		if ($this->_current->class == 'disabled') {
140			$class = ' class="disabled"';
141		}
142
143		/*
144		 * Print the item
145		 */
146		echo "<li".$class.">";
147
148		/*
149		 * Print a link if it exists
150		 */
151
152		$linkClass = '';
153		$dataToggle = '';
154		$dropdownCaret = '';
155
156		if ($this->_current->hasChildren()) {
157				$linkClass = ' class="dropdown-toggle"';
158				$dataToggle = ' data-toggle="dropdown"';
159				$dropdownCaret = ' <span class="caret"></span>';
160		}
161
162		if ($this->_current->link != null && $this->_current->target != null) {
163			echo "<a".$linkClass." ".$dataToggle." href=\"".$this->_current->link."\" target=\"".$this->_current->target."\" >".$this->_current->title.$dropdownCaret."</a>";
164		} elseif ($this->_current->link != null && $this->_current->target == null) {
165			echo "<a".$linkClass." ".$dataToggle." href=\"".$this->_current->link."\">".$this->_current->title.$dropdownCaret."</a>";
166		} elseif ($this->_current->title != null) {
167			echo "<a".$linkClass." ".$dataToggle.">".$this->_current->title.$dropdownCaret."</a>";
168		} else {
169			echo "<span></span>";
170		}
171
172		/*
173		 * Recurse through children if they exist
174		 */
175		while ($this->_current->hasChildren())
176		{
177			if ($this->_current->class) {
178				$id = '';
179				if (!empty($this->_current->id)) {
180					$id = ' id="menu-'.strtolower($this->_current->id).'"';
181				}
182				echo '<ul'.$id.' class="dropdown-menu menu-component">'."\n";
183			} else {
184				echo '<ul class="dropdown-menu">'."\n";
185			}
186			foreach ($this->_current->getChildren() as $child)
187			{
188				$this->_current = & $child;
189				$this->renderLevel($depth++);
190			}
191			echo "</ul>\n";
192		}
193		echo "</li>\n";
194	}
195
196	/**
197	 * Method to get the CSS class name for an icon identifier or create one if
198	 * a custom image path is passed as the identifier
199	 *
200	 * @access	public
201	 * @param	string	$identifier	Icon identification string
202	 * @return	string	CSS class name
203	 * @since	1.5
204	 */
205	public function getIconClass($identifier)
206	{
207		static $classes;
208
209		// Initialise the known classes array if it does not exist
210		if (!is_array($classes)) {
211			$classes = array();
212		}
213
214		/*
215		 * If we don't already know about the class... build it and mark it
216		 * known so we don't have to build it again
217		 */
218		if (!isset($classes[$identifier])) {
219			if (substr($identifier, 0, 6) == 'class:') {
220				// We were passed a class name
221				$class = substr($identifier, 6);
222				$classes[$identifier] = "icon-16-$class";
223			} else {
224				if ($identifier == null) {
225					return null;
226				}
227				// Build the CSS class for the icon
228				$class = preg_replace('#\.[^.]*$#', '', basename($identifier));
229				$class = preg_replace('#\.\.[^A-Za-z0-9\.\_\- ]#', '', $class);
230
231				$this->_css  .= "\n.icon-16-$class {\n" .
232						"\tbackground: url($identifier) no-repeat;\n" .
233						"}\n";
234
235				$classes[$identifier] = "icon-16-$class";
236			}
237		}
238		return $classes[$identifier];
239	}
240}
241
242/**
243 * A Node for JAdminCssMenu
244 *
245 * @package     Joomla.Administrator
246 * @subpackage  mod_menu
247 * @since       1.5
248 * @see         JAdminCssMenu
249 */
250class JMenuNode extends JObject
251{
252	/**
253	 * Node Title
254	 */
255	public $title = null;
256
257	/**
258	 * Node Id
259	 */
260	public $id = null;
261
262	/**
263	 * Node Link
264	 */
265	public $link = null;
266
267	/**
268	 * Link Target
269	 */
270	public $target = null;
271
272	/**
273	 * CSS Class for node
274	 */
275	public $class = null;
276
277	/**
278	 * Active Node?
279	 */
280	public $active = false;
281
282	/**
283	 * Parent node
284	 * @var    object
285	 */
286	protected $_parent = null;
287
288	/**
289	 * Array of Children
290	 *
291	 * @var    array
292	 */
293	protected $_children = array();
294
295	public function __construct($title, $link = null, $class = null, $active = false, $target = null, $titleicon = null)
296	{
297		$this->title	= $titleicon ? $title.$titleicon : $title;
298		$this->link		= JFilterOutput::ampReplace($link);
299		$this->class	= $class;
300		$this->active	= $active;
301
302		$this->id = null;
303		if (!empty($link) && $link !== '#') {
304			$uri = new JURI($link);
305			$params = $uri->getQuery(true);
306			$parts = array();
307
308			foreach ($params as $name => $value)
309			{
310				$parts[] = str_replace(array('.', '_'), '-', $value);
311			}
312
313			$this->id = implode('-', $parts);
314		}
315
316		$this->target	= $target;
317	}
318
319	/**
320	 * Add child to this node
321	 *
322	 * If the child already has a parent, the link is unset
323	 *
324	 * @param   JMenuNode  &$child  The child to be added
325	 *
326	 * @return  void
327	 */
328	public function addChild(JMenuNode &$child)
329	{
330		$child->setParent($this);
331	}
332
333	/**
334	 * Set the parent of a this node
335	 *
336	 * If the node already has a parent, the link is unset
337	 *
338	 * @param   JMenuNode   &$parent  The JMenuNode for parent to be set or null
339	 *
340	 * @return  void
341	 */
342	public function setParent(JMenuNode &$parent = null)
343	{
344		$hash = spl_object_hash($this);
345		if (!is_null($this->_parent))
346		{
347			unset($this->_parent->children[$hash]);
348		}
349		if (!is_null($parent))
350		{
351			$parent->_children[$hash] = & $this;
352		}
353		$this->_parent = & $parent;
354	}
355
356	/**
357	 * Get the children of this node
358	 *
359	 * @return  array    The children
360	 */
361	public function &getChildren()
362	{
363		return $this->_children;
364	}
365
366	/**
367	 * Get the parent of this node
368	 *
369	 * @return  mixed   JMenuNode object with the parent or null for no parent
370	 */
371	public function &getParent()
372	{
373		return $this->_parent;
374	}
375
376	/**
377	 * Test if this node has children
378	 *
379	 * @return   boolean  True if there are children
380	 */
381	public function hasChildren()
382	{
383		return (bool) count($this->_children);
384	}
385
386	/**
387	 * Test if this node has a parent
388	 *
389	 * @return  boolean  True if there is a parent
390	 */
391	public function hasParent()
392	{
393		return $this->getParent() != null;
394	}
395}