/modules/mod_mainmenu/helper.php
PHP | 418 lines | 284 code | 52 blank | 82 comment | 61 complexity | 43093e3422b3bc7731f91c0c501fdf3f MD5 | raw file
- <?php
- /**
- * @version $Id: helper.php 14401 2010-01-26 14:10:00Z louis $
- * @package Joomla
- * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
- * @license GNU/GPL, see LICENSE.php
- * Joomla! is free software. This version may have been modified pursuant
- * to the GNU General Public License, and as distributed it includes or
- * is derivative of works licensed under the GNU General Public License or
- * other free or open source software licenses.
- * See COPYRIGHT.php for copyright notices and details.
- */
-
- // no direct access
- defined('_JEXEC') or die('Restricted access');
-
-
- jimport('joomla.base.tree');
- jimport('joomla.utilities.simplexml');
-
- /**
- * mod_mainmenu Helper class
- *
- * @static
- * @package Joomla
- * @subpackage Menus
- * @since 1.5
- */
- class modMainMenuHelper
- {
- function buildXML($params)
- {
- $menu = new JMenuTree($params);
- $items = &JSite::getMenu();
-
- // Get Menu Items
- $rows = $items->getItems('menutype', $params->get('menutype'));
- $maxdepth = $params->get('maxdepth',10);
-
- // Build Menu Tree root down (orphan proof - child might have lower id than parent)
- $user =& JFactory::getUser();
- $ids = array();
- $ids[0] = true;
- $last = null;
- $unresolved = array();
- // pop the first item until the array is empty if there is any item
- if ( is_array($rows)) {
- while (count($rows) && !is_null($row = array_shift($rows)))
- {
- if (array_key_exists($row->parent, $ids)) {
- $row->ionly = $params->get('menu_images_link');
- $menu->addNode($params, $row);
-
- // record loaded parents
- $ids[$row->id] = true;
- } else {
- // no parent yet so push item to back of list
- // SAM: But if the key isn't in the list and we dont _add_ this is infinite, so check the unresolved queue
- if(!array_key_exists($row->id, $unresolved) || $unresolved[$row->id] < $maxdepth) {
- array_push($rows, $row);
- // so let us do max $maxdepth passes
- // TODO: Put a time check in this loop in case we get too close to the PHP timeout
- if(!isset($unresolved[$row->id])) $unresolved[$row->id] = 1;
- else $unresolved[$row->id]++;
- }
- }
- }
- }
- return $menu->toXML();
- }
-
- function &getXML($type, &$params, $decorator)
- {
- static $xmls;
-
- if (!isset($xmls[$type])) {
- $cache =& JFactory::getCache('mod_mainmenu');
- $string = $cache->call(array('modMainMenuHelper', 'buildXML'), $params);
- $xmls[$type] = $string;
- }
-
- // Get document
- $xml = JFactory::getXMLParser('Simple');
- $xml->loadString($xmls[$type]);
- $doc = &$xml->document;
-
- $menu = &JSite::getMenu();
- $active = $menu->getActive();
- $start = $params->get('startLevel');
- $end = $params->get('endLevel');
- $sChild = $params->get('showAllChildren');
- $path = array();
-
- // Get subtree
- if ($start)
- {
- $found = false;
- $root = true;
- if(!isset($active)){
- $doc = false;
- }
- else{
- $path = $active->tree;
- for ($i=0,$n=count($path);$i<$n;$i++)
- {
- foreach ($doc->children() as $child)
- {
- if ($child->attributes('id') == $path[$i]) {
- $doc = &$child->ul[0];
- $root = false;
- break;
- }
- }
-
- if ($i == $start-1) {
- $found = true;
- break;
- }
- }
- if ((!is_a($doc, 'JSimpleXMLElement')) || (!$found) || ($root)) {
- $doc = false;
- }
- }
- }
-
- if ($doc && is_callable($decorator)) {
- $doc->map($decorator, array('end'=>$end, 'children'=>$sChild));
- }
- return $doc;
- }
-
- function render(&$params, $callback)
- {
- switch ( $params->get( 'menu_style', 'list' ) )
- {
- case 'list_flat' :
- // Include the legacy library file
- require_once(dirname(__FILE__).DS.'legacy.php');
- mosShowHFMenu($params, 1);
- break;
-
- case 'horiz_flat' :
- // Include the legacy library file
- require_once(dirname(__FILE__).DS.'legacy.php');
- mosShowHFMenu($params, 0);
- break;
-
- case 'vert_indent' :
- // Include the legacy library file
- require_once(dirname(__FILE__).DS.'legacy.php');
- mosShowVIMenu($params);
- break;
-
- default :
- // Include the new menu class
- $xml = modMainMenuHelper::getXML($params->get('menutype'), $params, $callback);
- if ($xml) {
- $class = $params->get('class_sfx');
- $xml->addAttribute('class', 'menu'.$class);
- if ($tagId = $params->get('tag_id')) {
- $xml->addAttribute('id', $tagId);
- }
-
- $result = JFilterOutput::ampReplace($xml->toString((bool)$params->get('show_whitespace')));
- $result = str_replace(array('<ul/>', '<ul />'), '', $result);
- echo $result;
- }
- break;
- }
- }
- }
-
- /**
- * Main Menu Tree Class.
- *
- * @package Joomla
- * @subpackage Menus
- * @since 1.5
- */
- class JMenuTree extends JTree
- {
- /**
- * Node/Id Hash for quickly handling node additions to the tree.
- */
- var $_nodeHash = array();
-
- /**
- * Menu parameters
- */
- var $_params = null;
-
- /**
- * Menu parameters
- */
- var $_buffer = null;
-
- function __construct(&$params)
- {
- $this->_params =& $params;
- $this->_root = new JMenuNode(0, 'ROOT');
- $this->_nodeHash[0] =& $this->_root;
- $this->_current =& $this->_root;
- }
-
- function addNode(&$params, $item)
- {
- // Get menu item data
- $data = $this->_getItemData($params, $item);
-
- // Create the node and add it
- $node = new JMenuNode($item->id, $item->name, $item->access, $data);
-
- if (isset($item->mid)) {
- $nid = $item->mid;
- } else {
- $nid = $item->id;
- }
- $this->_nodeHash[$nid] =& $node;
- $this->_current =& $this->_nodeHash[$item->parent];
-
- if ($item->type == 'menulink' && !empty($item->query['Itemid'])) {
- $node->mid = $item->query['Itemid'];
- }
-
- if ($this->_current) {
- $this->addChild($node, true);
- } else {
- // sanity check
- JError::raiseError( 500, 'Orphan Error. Could not find parent for Item '.$item->id );
- }
- }
-
- function toXML()
- {
- // Initialize variables
- $this->_current =& $this->_root;
-
- // Recurse through children if they exist
- while ($this->_current->hasChildren())
- {
- $this->_buffer .= '<ul>';
- foreach ($this->_current->getChildren() as $child)
- {
- $this->_current = & $child;
- $this->_getLevelXML(0);
- }
- $this->_buffer .= '</ul>';
- }
- if($this->_buffer == '') { $this->_buffer = '<ul />'; }
- return $this->_buffer;
- }
-
- function _getLevelXML($depth)
- {
- $depth++;
-
- // Start the item
- $rel = (!empty($this->_current->mid)) ? ' rel="'.$this->_current->mid.'"' : '';
- $this->_buffer .= '<li access="'.$this->_current->access.'" level="'.$depth.'" id="'.$this->_current->id.'"'.$rel.'>';
-
- // Append item data
- $this->_buffer .= $this->_current->link;
-
- // Recurse through item's children if they exist
- while ($this->_current->hasChildren())
- {
- $this->_buffer .= '<ul>';
- foreach ($this->_current->getChildren() as $child)
- {
- $this->_current = & $child;
- $this->_getLevelXML($depth);
- }
- $this->_buffer .= '</ul>';
- }
-
- // Finish the item
- $this->_buffer .= '</li>';
- }
-
- function _getItemData(&$params, $item)
- {
- $data = null;
-
- // Menu Link is a special type that is a link to another item
- if ($item->type == 'menulink')
- {
- $menu = &JSite::getMenu();
- if ($newItem = $menu->getItem($item->query['Itemid'])) {
- $tmp = clone($newItem);
- $tmp->name = '<span><![CDATA['.$item->name.']]></span>';
- $tmp->mid = $item->id;
- $tmp->parent = $item->parent;
- } else {
- return false;
- }
- } else {
- $tmp = clone($item);
- $tmp->name = '<span><![CDATA['.$item->name.']]></span>';
- }
-
- $iParams = new JParameter($tmp->params);
- if ($params->get('menu_images') && $iParams->get('menu_image') && $iParams->get('menu_image') != -1) {
- switch ($params->get('menu_images_align', 0)){
- case 0 :
- $imgalign='align="left"';
- break;
-
- case 1 :
- $imgalign='align="right"';
- break;
-
- default :
- $imgalign='';
- break;
- }
-
-
- $image = '<img src="'.JURI::base(true).'/images/stories/'.$iParams->get('menu_image').'" '.$imgalign.' alt="'.$item->alias.'" />';
- if($tmp->ionly){
- $tmp->name = null;
- }
- } else {
- $image = null;
- }
- switch ($tmp->type)
- {
- case 'separator' :
- return '<span class="separator">'.$image.$tmp->name.'</span>';
- break;
-
- case 'url' :
- if ((strpos($tmp->link, 'index.php?') === 0) && (strpos($tmp->link, 'Itemid=') === false)) {
- $tmp->url = $tmp->link.'&Itemid='.$tmp->id;
- } else {
- $tmp->url = $tmp->link;
- }
- break;
-
- default :
- $router = JSite::getRouter();
- $tmp->url = $router->getMode() == JROUTER_MODE_SEF ? 'index.php?Itemid='.$tmp->id : $tmp->link.'&Itemid='.$tmp->id;
- break;
- }
-
- // Print a link if it exists
- if ($tmp->url != null)
- {
- // Handle SSL links
- $iSecure = $iParams->def('secure', 0);
- if ($tmp->home == 1) {
- $tmp->url = JURI::base();
- } elseif (strcasecmp(substr($tmp->url, 0, 4), 'http') && (strpos($tmp->link, 'index.php?') !== false)) {
- $tmp->url = JRoute::_($tmp->url, true, $iSecure);
- } else {
- $tmp->url = str_replace('&', '&', $tmp->url);
- }
-
- switch ($tmp->browserNav)
- {
- default:
- case 0:
- // _top
- $data = '<a href="'.$tmp->url.'">'.$image.$tmp->name.'</a>';
- break;
- case 1:
- // _blank
- $data = '<a href="'.$tmp->url.'" target="_blank">'.$image.$tmp->name.'</a>';
- break;
- case 2:
- // window.open
- $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,'.$this->_params->get('window_open');
-
- // hrm...this is a bit dickey
- $link = str_replace('index.php', 'index2.php', $tmp->url);
- $data = '<a href="'.$link.'" onclick="window.open(this.href,\'targetWindow\',\''.$attribs.'\');return false;">'.$image.$tmp->name.'</a>';
- break;
- }
- } else {
- $data = '<a>'.$image.$tmp->name.'</a>';
- }
-
- return $data;
- }
- }
-
- /**
- * Main Menu Tree Node Class.
- *
- * @package Joomla
- * @subpackage Menus
- * @since 1.5
- */
- class JMenuNode extends JNode
- {
- /**
- * Node Title
- */
- var $title = null;
-
- /**
- * Node Link
- */
- var $link = null;
-
- /**
- * CSS Class for node
- */
- var $class = null;
-
- function __construct($id, $title, $access = null, $link = null, $class = null)
- {
- $this->id = $id;
- $this->title = $title;
- $this->access = $access;
- $this->link = $link;
- $this->class = $class;
- }
- }