PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/mod_mainmenu/helper.php

https://github.com/ponlue/abktours
PHP | 418 lines | 284 code | 52 blank | 82 comment | 61 complexity | 43093e3422b3bc7731f91c0c501fdf3f MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: helper.php 14401 2010-01-26 14:10:00Z louis $
  4. * @package Joomla
  5. * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
  6. * @license GNU/GPL, see LICENSE.php
  7. * Joomla! is free software. This version may have been modified pursuant
  8. * to the GNU General Public License, and as distributed it includes or
  9. * is derivative of works licensed under the GNU General Public License or
  10. * other free or open source software licenses.
  11. * See COPYRIGHT.php for copyright notices and details.
  12. */
  13. // no direct access
  14. defined('_JEXEC') or die('Restricted access');
  15. jimport('joomla.base.tree');
  16. jimport('joomla.utilities.simplexml');
  17. /**
  18. * mod_mainmenu Helper class
  19. *
  20. * @static
  21. * @package Joomla
  22. * @subpackage Menus
  23. * @since 1.5
  24. */
  25. class modMainMenuHelper
  26. {
  27. function buildXML($params)
  28. {
  29. $menu = new JMenuTree($params);
  30. $items = &JSite::getMenu();
  31. // Get Menu Items
  32. $rows = $items->getItems('menutype', $params->get('menutype'));
  33. $maxdepth = $params->get('maxdepth',10);
  34. // Build Menu Tree root down (orphan proof - child might have lower id than parent)
  35. $user =& JFactory::getUser();
  36. $ids = array();
  37. $ids[0] = true;
  38. $last = null;
  39. $unresolved = array();
  40. // pop the first item until the array is empty if there is any item
  41. if ( is_array($rows)) {
  42. while (count($rows) && !is_null($row = array_shift($rows)))
  43. {
  44. if (array_key_exists($row->parent, $ids)) {
  45. $row->ionly = $params->get('menu_images_link');
  46. $menu->addNode($params, $row);
  47. // record loaded parents
  48. $ids[$row->id] = true;
  49. } else {
  50. // no parent yet so push item to back of list
  51. // SAM: But if the key isn't in the list and we dont _add_ this is infinite, so check the unresolved queue
  52. if(!array_key_exists($row->id, $unresolved) || $unresolved[$row->id] < $maxdepth) {
  53. array_push($rows, $row);
  54. // so let us do max $maxdepth passes
  55. // TODO: Put a time check in this loop in case we get too close to the PHP timeout
  56. if(!isset($unresolved[$row->id])) $unresolved[$row->id] = 1;
  57. else $unresolved[$row->id]++;
  58. }
  59. }
  60. }
  61. }
  62. return $menu->toXML();
  63. }
  64. function &getXML($type, &$params, $decorator)
  65. {
  66. static $xmls;
  67. if (!isset($xmls[$type])) {
  68. $cache =& JFactory::getCache('mod_mainmenu');
  69. $string = $cache->call(array('modMainMenuHelper', 'buildXML'), $params);
  70. $xmls[$type] = $string;
  71. }
  72. // Get document
  73. $xml = JFactory::getXMLParser('Simple');
  74. $xml->loadString($xmls[$type]);
  75. $doc = &$xml->document;
  76. $menu = &JSite::getMenu();
  77. $active = $menu->getActive();
  78. $start = $params->get('startLevel');
  79. $end = $params->get('endLevel');
  80. $sChild = $params->get('showAllChildren');
  81. $path = array();
  82. // Get subtree
  83. if ($start)
  84. {
  85. $found = false;
  86. $root = true;
  87. if(!isset($active)){
  88. $doc = false;
  89. }
  90. else{
  91. $path = $active->tree;
  92. for ($i=0,$n=count($path);$i<$n;$i++)
  93. {
  94. foreach ($doc->children() as $child)
  95. {
  96. if ($child->attributes('id') == $path[$i]) {
  97. $doc = &$child->ul[0];
  98. $root = false;
  99. break;
  100. }
  101. }
  102. if ($i == $start-1) {
  103. $found = true;
  104. break;
  105. }
  106. }
  107. if ((!is_a($doc, 'JSimpleXMLElement')) || (!$found) || ($root)) {
  108. $doc = false;
  109. }
  110. }
  111. }
  112. if ($doc && is_callable($decorator)) {
  113. $doc->map($decorator, array('end'=>$end, 'children'=>$sChild));
  114. }
  115. return $doc;
  116. }
  117. function render(&$params, $callback)
  118. {
  119. switch ( $params->get( 'menu_style', 'list' ) )
  120. {
  121. case 'list_flat' :
  122. // Include the legacy library file
  123. require_once(dirname(__FILE__).DS.'legacy.php');
  124. mosShowHFMenu($params, 1);
  125. break;
  126. case 'horiz_flat' :
  127. // Include the legacy library file
  128. require_once(dirname(__FILE__).DS.'legacy.php');
  129. mosShowHFMenu($params, 0);
  130. break;
  131. case 'vert_indent' :
  132. // Include the legacy library file
  133. require_once(dirname(__FILE__).DS.'legacy.php');
  134. mosShowVIMenu($params);
  135. break;
  136. default :
  137. // Include the new menu class
  138. $xml = modMainMenuHelper::getXML($params->get('menutype'), $params, $callback);
  139. if ($xml) {
  140. $class = $params->get('class_sfx');
  141. $xml->addAttribute('class', 'menu'.$class);
  142. if ($tagId = $params->get('tag_id')) {
  143. $xml->addAttribute('id', $tagId);
  144. }
  145. $result = JFilterOutput::ampReplace($xml->toString((bool)$params->get('show_whitespace')));
  146. $result = str_replace(array('<ul/>', '<ul />'), '', $result);
  147. echo $result;
  148. }
  149. break;
  150. }
  151. }
  152. }
  153. /**
  154. * Main Menu Tree Class.
  155. *
  156. * @package Joomla
  157. * @subpackage Menus
  158. * @since 1.5
  159. */
  160. class JMenuTree extends JTree
  161. {
  162. /**
  163. * Node/Id Hash for quickly handling node additions to the tree.
  164. */
  165. var $_nodeHash = array();
  166. /**
  167. * Menu parameters
  168. */
  169. var $_params = null;
  170. /**
  171. * Menu parameters
  172. */
  173. var $_buffer = null;
  174. function __construct(&$params)
  175. {
  176. $this->_params =& $params;
  177. $this->_root = new JMenuNode(0, 'ROOT');
  178. $this->_nodeHash[0] =& $this->_root;
  179. $this->_current =& $this->_root;
  180. }
  181. function addNode(&$params, $item)
  182. {
  183. // Get menu item data
  184. $data = $this->_getItemData($params, $item);
  185. // Create the node and add it
  186. $node = new JMenuNode($item->id, $item->name, $item->access, $data);
  187. if (isset($item->mid)) {
  188. $nid = $item->mid;
  189. } else {
  190. $nid = $item->id;
  191. }
  192. $this->_nodeHash[$nid] =& $node;
  193. $this->_current =& $this->_nodeHash[$item->parent];
  194. if ($item->type == 'menulink' && !empty($item->query['Itemid'])) {
  195. $node->mid = $item->query['Itemid'];
  196. }
  197. if ($this->_current) {
  198. $this->addChild($node, true);
  199. } else {
  200. // sanity check
  201. JError::raiseError( 500, 'Orphan Error. Could not find parent for Item '.$item->id );
  202. }
  203. }
  204. function toXML()
  205. {
  206. // Initialize variables
  207. $this->_current =& $this->_root;
  208. // Recurse through children if they exist
  209. while ($this->_current->hasChildren())
  210. {
  211. $this->_buffer .= '<ul>';
  212. foreach ($this->_current->getChildren() as $child)
  213. {
  214. $this->_current = & $child;
  215. $this->_getLevelXML(0);
  216. }
  217. $this->_buffer .= '</ul>';
  218. }
  219. if($this->_buffer == '') { $this->_buffer = '<ul />'; }
  220. return $this->_buffer;
  221. }
  222. function _getLevelXML($depth)
  223. {
  224. $depth++;
  225. // Start the item
  226. $rel = (!empty($this->_current->mid)) ? ' rel="'.$this->_current->mid.'"' : '';
  227. $this->_buffer .= '<li access="'.$this->_current->access.'" level="'.$depth.'" id="'.$this->_current->id.'"'.$rel.'>';
  228. // Append item data
  229. $this->_buffer .= $this->_current->link;
  230. // Recurse through item's children if they exist
  231. while ($this->_current->hasChildren())
  232. {
  233. $this->_buffer .= '<ul>';
  234. foreach ($this->_current->getChildren() as $child)
  235. {
  236. $this->_current = & $child;
  237. $this->_getLevelXML($depth);
  238. }
  239. $this->_buffer .= '</ul>';
  240. }
  241. // Finish the item
  242. $this->_buffer .= '</li>';
  243. }
  244. function _getItemData(&$params, $item)
  245. {
  246. $data = null;
  247. // Menu Link is a special type that is a link to another item
  248. if ($item->type == 'menulink')
  249. {
  250. $menu = &JSite::getMenu();
  251. if ($newItem = $menu->getItem($item->query['Itemid'])) {
  252. $tmp = clone($newItem);
  253. $tmp->name = '<span><![CDATA['.$item->name.']]></span>';
  254. $tmp->mid = $item->id;
  255. $tmp->parent = $item->parent;
  256. } else {
  257. return false;
  258. }
  259. } else {
  260. $tmp = clone($item);
  261. $tmp->name = '<span><![CDATA['.$item->name.']]></span>';
  262. }
  263. $iParams = new JParameter($tmp->params);
  264. if ($params->get('menu_images') && $iParams->get('menu_image') && $iParams->get('menu_image') != -1) {
  265. switch ($params->get('menu_images_align', 0)){
  266. case 0 :
  267. $imgalign='align="left"';
  268. break;
  269. case 1 :
  270. $imgalign='align="right"';
  271. break;
  272. default :
  273. $imgalign='';
  274. break;
  275. }
  276. $image = '<img src="'.JURI::base(true).'/images/stories/'.$iParams->get('menu_image').'" '.$imgalign.' alt="'.$item->alias.'" />';
  277. if($tmp->ionly){
  278. $tmp->name = null;
  279. }
  280. } else {
  281. $image = null;
  282. }
  283. switch ($tmp->type)
  284. {
  285. case 'separator' :
  286. return '<span class="separator">'.$image.$tmp->name.'</span>';
  287. break;
  288. case 'url' :
  289. if ((strpos($tmp->link, 'index.php?') === 0) && (strpos($tmp->link, 'Itemid=') === false)) {
  290. $tmp->url = $tmp->link.'&amp;Itemid='.$tmp->id;
  291. } else {
  292. $tmp->url = $tmp->link;
  293. }
  294. break;
  295. default :
  296. $router = JSite::getRouter();
  297. $tmp->url = $router->getMode() == JROUTER_MODE_SEF ? 'index.php?Itemid='.$tmp->id : $tmp->link.'&Itemid='.$tmp->id;
  298. break;
  299. }
  300. // Print a link if it exists
  301. if ($tmp->url != null)
  302. {
  303. // Handle SSL links
  304. $iSecure = $iParams->def('secure', 0);
  305. if ($tmp->home == 1) {
  306. $tmp->url = JURI::base();
  307. } elseif (strcasecmp(substr($tmp->url, 0, 4), 'http') && (strpos($tmp->link, 'index.php?') !== false)) {
  308. $tmp->url = JRoute::_($tmp->url, true, $iSecure);
  309. } else {
  310. $tmp->url = str_replace('&', '&amp;', $tmp->url);
  311. }
  312. switch ($tmp->browserNav)
  313. {
  314. default:
  315. case 0:
  316. // _top
  317. $data = '<a href="'.$tmp->url.'">'.$image.$tmp->name.'</a>';
  318. break;
  319. case 1:
  320. // _blank
  321. $data = '<a href="'.$tmp->url.'" target="_blank">'.$image.$tmp->name.'</a>';
  322. break;
  323. case 2:
  324. // window.open
  325. $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,'.$this->_params->get('window_open');
  326. // hrm...this is a bit dickey
  327. $link = str_replace('index.php', 'index2.php', $tmp->url);
  328. $data = '<a href="'.$link.'" onclick="window.open(this.href,\'targetWindow\',\''.$attribs.'\');return false;">'.$image.$tmp->name.'</a>';
  329. break;
  330. }
  331. } else {
  332. $data = '<a>'.$image.$tmp->name.'</a>';
  333. }
  334. return $data;
  335. }
  336. }
  337. /**
  338. * Main Menu Tree Node Class.
  339. *
  340. * @package Joomla
  341. * @subpackage Menus
  342. * @since 1.5
  343. */
  344. class JMenuNode extends JNode
  345. {
  346. /**
  347. * Node Title
  348. */
  349. var $title = null;
  350. /**
  351. * Node Link
  352. */
  353. var $link = null;
  354. /**
  355. * CSS Class for node
  356. */
  357. var $class = null;
  358. function __construct($id, $title, $access = null, $link = null, $class = null)
  359. {
  360. $this->id = $id;
  361. $this->title = $title;
  362. $this->access = $access;
  363. $this->link = $link;
  364. $this->class = $class;
  365. }
  366. }