1<?php
2/*
3 * e107 website system
4 *
5 * Copyright (C) 2008-2017 e107 Inc (e107.org)
6 * Released under the terms and conditions of the
7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
8 *
9 */
10
11if (!defined('e107_INIT')) { exit; }
12e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE.'/lan_sitelinks.php');
13
14
15/**
16 * Legacy Navigation class.
17 * Class sitelinks
18 */
19class sitelinks
20{
21	var $eLinkList = array();
22	var $eSubLinkLevel = 0;
23	var $sefList = array();
24
25	const LINK_DISPLAY_FLAT     = 1;
26	const LINK_DISPLAY_MENU     = 2;
27	const LINK_DISPLAY_OTHER    = 3;
28	const LINK_DISPLAY_SLIDER   = 4;
29
30
31	function getlinks($cat=1)
32	{
33
34		$this->eLinkList = array(); // clear the array in case getlinks is called 2x on the same page.
35		$sql = e107::getDb('sqlSiteLinks');
36		$ins = ($cat > 0) ? "link_category = ".intval($cat)." AND " : "";
37		$query = "SELECT * FROM #links WHERE ".$ins."  ((link_class >= 0 AND link_class IN (".USERCLASS_LIST.")) OR (link_class < 0 AND ABS(link_class) NOT IN (".USERCLASS_LIST.")) ) ORDER BY link_order ASC";
38		if($sql->gen($query))
39		{
40			while ($row = $sql->fetch())
41			{
42
43
44				//	if (substr($row['link_name'], 0, 8) == 'submenu.'){
45				//		$tmp=explode('.', $row['link_name'], 3);
46				//		$this->eLinkList[$tmp[1]][]=$row;
47				if (isset($row['link_parent']) && $row['link_parent'] != 0)
48				{
49					$this->eLinkList['sub_'.$row['link_parent']][]=$row;
50
51				}
52				else
53				{
54					$this->eLinkList['head_menu'][] = $row;
55					if(vartrue($row['link_function']))
56					{
57						$parm = false;
58						list($path,$method) = explode("::",$row['link_function']);
59
60						if(strpos($method,"("))
61						{
62							list($method,$prm) = explode("(",$method);
63							$parm = rtrim($prm,")");
64						}
65
66						if(file_exists(e_PLUGIN.$path."/e_sitelink.php") && include_once(e_PLUGIN.$path."/e_sitelink.php"))
67						{
68							$class = $path."_sitelink";
69							$sublinkArray = e107::callMethod($class,$method,$parm); //TODO Cache it.
70							if(vartrue($sublinkArray))
71							{
72								$this->eLinkList['sub_'.$row['link_id']] = $sublinkArray;
73							}
74						}
75
76					}
77				}
78			}
79		}
80
81	}
82
83	function getLinkArray()
84	{
85		return $this->eLinkList;
86	}
87
88	function get($cat = 1, $style = null, $css_class = false)
89	{
90		global $pref, $ns, $e107cache, $linkstyle;
91		$ns = e107::getRender();
92		$pref = e107::getPref();
93		$e107cache = e107::getCache();
94
95		$usecache = ((trim(defset('LINKSTART_HILITE')) != "" || trim(defset('LINKCLASS_HILITE')) != "") ? false : true);
96
97		if($usecache && !strpos(e_SELF, e_ADMIN) && ($data = $e107cache->retrieve('sitelinks_' . $cat . md5($linkstyle . e_PAGE . e_QUERY))))
98		{
99			return $data;
100		}
101
102		if(LINKDISPLAY == self::LINK_DISPLAY_SLIDER)
103		{
104			require_once(e_PLUGIN . 'ypslide_menu/ypslide_menu.php');
105			return null;
106		}
107
108		$this->getlinks($cat);
109
110        if (empty($this->eLinkList))  { return ''; }
111
112		// are these defines used at all ?
113		if(!defined('PRELINKTITLE'))
114		{
115			define('PRELINKTITLE', '');
116		}
117		if(!defined('PRELINKTITLE'))
118		{
119			define('POSTLINKTITLE', '');
120		}
121		// -----------------------------
122
123		// where did link alignment go?
124		if(!defined('LINKALIGN'))
125		{
126			define('LINKALIGN', '');
127		}
128
129		if(empty($style))
130		{
131			$style = array();
132			$style['prelink'] = defined('PRELINK') ? PRELINK : '';
133			$style['postlink'] = defined('POSTLINK') ? POSTLINK : '';
134			$style['linkclass'] = defined('LINKCLASS') ? LINKCLASS : "";
135			$style['linkclass_hilite'] = defined('LINKCLASS_HILITE') ? LINKCLASS_HILITE : "";
136			$style['linkstart_hilite'] = defined('LINKSTART_HILITE') ? LINKSTART_HILITE : "";
137			$style['linkstart'] = defined('LINKSTART') ? LINKSTART : '';
138			$style['linkdisplay'] = defined('LINKDISPLAY') ? LINKDISPLAY : '';
139			$style['linkend'] = defined('LINKEND') ? LINKEND : '';
140			$style['linkseparator'] = defined('LINKSEPARATOR') ? LINKSEPARATOR : '';
141			$style['sublinkstart'] = defined('SUBLINKSTART') ? SUBLINKSTART : '';
142			$style['sublinkend'] = defined('SUBLINKEND') ? SUBLINKEND : '';
143			$style['sublinkclass'] = defined('SUBLINKCLASS') ? SUBLINKCLASS : '';
144		}
145
146		if(!varset($style['linkseparator']))
147		{
148			$style['linkseparator'] = '';
149		}
150
151		// Sublink styles.- replacing the tree-menu.
152		if(isset($style['sublinkdisplay']) || isset($style['subindent']) || isset($style['sublinkclass']) || isset($style['sublinkstart']) || isset($style['sublinkend']) || isset($style['subpostlink']))
153		{
154			foreach($style as $key => $val)
155			{
156				$aSubStyle[$key] = vartrue($style["sub" . $key]) ? $style["sub" . $key] : $style[$key];
157			}
158		}
159		else
160		{
161			$style['subindent'] = "&nbsp;&nbsp;";
162			$aSubStyle = $style;
163		}
164
165		$text = "\n\n\n<!-- Sitelinks ($cat) -->\n\n\n" . $style['prelink'];
166
167		// php warnings
168		if(!vartrue($this->eLinkList['head_menu']))
169		{
170			$this->eLinkList['head_menu'] = array();
171		}
172
173		$render_link = array();
174
175		if($style['linkdisplay'] != self::LINK_DISPLAY_OTHER)
176		{
177
178			foreach($this->eLinkList['head_menu'] as $key => $link)
179			{
180				$main_linkid = "sub_" . $link['link_id'];
181				$link['link_expand'] = ((isset($pref['sitelinks_expandsub']) && $pref['sitelinks_expandsub']) && empty($style['linkmainonly']) && !defined("LINKSRENDERONLYMAIN") && isset($this->eLinkList[$main_linkid]) && is_array($this->eLinkList[$main_linkid])) ? true : false;
182				$render_link[$key] = $this->makeLink($link, '', $style, $css_class);
183
184				if(!defined("LINKSRENDERONLYMAIN") && !isset($style['linkmainonly']))  /* if this is defined in theme.php only main links will be rendered */
185				{
186					$render_link[$key] .= $this->subLink($main_linkid, $aSubStyle, $css_class);
187				}
188			}
189
190			if(!isset($style['linkseparator']))
191			{
192				$style['linkseparator'] = '';
193			}
194
195			$text .= implode($style['linkseparator'], $render_link);
196
197
198			$text .= $style['postlink'];
199
200			if($style['linkdisplay'] == self::LINK_DISPLAY_MENU)
201			{
202				$text = $ns->tablerender(LAN_SITELINKS_183, $text, 'sitelinks', true);
203			}
204		}
205		else // link_DISPLAY_3
206		{
207			foreach($this->eLinkList['head_menu'] as $link)
208			{
209				if(!count($this->eLinkList['sub_' . $link['link_id']]))
210				{
211					$text .= $this->makeLink($link, '', $style, $css_class);
212				}
213				$text .= $style['postlink'];
214			}
215
216			$text = $ns->tablerender(LAN_SITELINKS_183, $text, 'sitelinks_main', true);
217
218			foreach(array_keys($this->eLinkList) as $k)
219			{
220				$mnu = $style['prelink'];
221				foreach($this->eLinkList[$k] as $link)
222				{
223					if($k != 'head_menu')
224					{
225						$mnu .= $this->makeLink($link, true, $style, $css_class);
226					}
227				}
228				$mnu .= $style['postlink'];
229				$text .= $ns->tablerender($k, $mnu, 'sitelinks_sub', true);
230			}
231		}
232
233		$text .= "\n\n\n<!-- end Site Links -->\n\n\n";
234
235
236
237		if($usecache)
238		{
239			$e107cache->set('sitelinks_' . $cat . md5($linkstyle . e_PAGE . e_QUERY), $text);
240		}
241
242		return $text;
243	}
244
245	/**
246	 * Manage Sublink Rendering
247	 * @param string $main_linkid
248	 * @param array $aSubStyle
249	 * @param string $css_class
250	 * @param object $level [optional]
251	 * @return
252	 */
253	function subLink($main_linkid,$aSubStyle=array(),$css_class='',$level=0)
254	{
255		global $pref;
256
257		if(!isset($this->eLinkList[$main_linkid]) || !is_array($this->eLinkList[$main_linkid]))
258		{
259			return null;
260		}
261
262		$sub['link_expand'] = ((isset($pref['sitelinks_expandsub']) && $pref['sitelinks_expandsub']) && empty($style['linkmainonly']) && !defined("LINKSRENDERONLYMAIN") && isset($this->eLinkList[$main_linkid]) && is_array($this->eLinkList[$main_linkid])) ?  TRUE : FALSE;
263
264		foreach($this->eLinkList[$main_linkid] as $val) // check that something in the submenu is actually selected.
265 		{
266			if($this->hilite($val['link_url'],TRUE)== TRUE || $sub['link_expand'] == FALSE)
267         	{
268         		$substyle = "block"; // previously (non-W3C compliant): compact
269          		break;
270        	}
271			else
272			{
273				$substyle = "none";
274			}
275		}
276
277		$text = "";
278		$text .= "\n\n<div id='{$main_linkid}' style='display:$substyle' class='d_sublink'>\n";
279
280		foreach ($this->eLinkList[$main_linkid] as $sub)
281		{
282			$id = (!empty($sub['link_id'])) ? "sub_".$sub['link_id'] : 'sub_0';
283			$sub['link_expand'] = ((isset($pref['sitelinks_expandsub']) && $pref['sitelinks_expandsub']) && empty($style['linkmainonly']) && !defined("LINKSRENDERONLYMAIN") && isset($this->eLinkList[$id]) && is_array($this->eLinkList[$id])) ?  TRUE : FALSE;
284			$class = "sublink-level-".($level+1);
285			$class .= ($css_class) ? " ".$css_class : "";
286			$class .= ($aSubStyle['sublinkclass']) ? " ".$aSubStyle['sublinkclass'] : ""; // backwards compatible
287			$text .= $this->makeLink($sub, TRUE, $aSubStyle,$class );
288			$text .= $this->subLink($id,$aSubStyle,$css_class,($level+1));
289		}
290
291		$text .= "\n</div>\n\n";
292		return $text;
293	}
294
295
296
297	function makeLink($linkInfo=array(), $submenu = FALSE, $style=array(), $css_class = false)
298	{
299		global $pref,$tp;
300
301		// Start with an empty link
302		$linkstart = $indent = $linkadd = $screentip = $href = $link_append = '';
303		$highlighted = FALSE;
304
305		if(!isset($style['linkstart_hilite'])) // Notice removal
306		{
307			$style['linkstart_hilite'] = "";
308		}
309
310		if(!isset($style['linkclass_hilite']))
311		{
312			$style['linkclass_hilite'] = "";
313		}
314
315		if(vartrue($linkInfo['link_sefurl']) && !empty($linkInfo['link_owner']))
316		{
317			$linkInfo['link_url'] = e107::url($linkInfo['link_owner'],$linkInfo['link_sefurl']) ; //  $linkInfo['link_sefurl'];
318		}
319
320
321
322		// If submenu: Fix Name, Add Indentation.
323		if ($submenu == true)
324		{
325			if(substr($linkInfo['link_name'],0,8) == "submenu.")
326			{
327				$tmp = explode('.', $linkInfo['link_name'], 3);
328				$linkInfo['link_name'] = $tmp[2];
329			}
330			$indent = ($style['linkdisplay'] != self::LINK_DISPLAY_OTHER && !empty($style['subindent'])) ? ($style['subindent']) : "";
331		}
332
333		// Convert any {e_XXX} to absolute URLs (relative ones sometimes get broken by adding e_HTTP at the front)
334		$linkInfo['link_url'] = $tp -> replaceConstants($linkInfo['link_url'], TRUE, TRUE); // replace {e_xxxx}
335
336		if(strpos($linkInfo['link_url'],"{") !== false)
337		{
338			$linkInfo['link_url'] = $tp->parseTemplate($linkInfo['link_url'], TRUE); // shortcode in URL support - dynamic urls for multilanguage.
339		}
340		elseif($linkInfo['link_url'][0] != '/' && strpos($linkInfo['link_url'],'http') !== 0)
341		{
342			$linkInfo['link_url'] = e_HTTP.ltrim($linkInfo['link_url'],'/');
343		}
344		// By default links are not highlighted.
345
346		if (isset($linkInfo['link_expand']) && $linkInfo['link_expand'])
347		{
348			// $href = " href=\"javascript:expandit('sub_".$linkInfo['link_id']."')\"";
349			$css_class .= " e-expandit";
350		}
351
352
353		$linkstart = $style['linkstart'];
354		$linkadd = ($style['linkclass']) ? " class='".$style['linkclass']."'" : "";
355		$linkadd = ($css_class) ? " class='".$style['linkclass'].$css_class."'" : $linkadd;
356
357		// Check for screentip regardless of URL.
358		if (isset($pref['linkpage_screentip']) && $pref['linkpage_screentip'] && $linkInfo['link_description'])
359		{
360			$screentip = " title = \"".$tp->toHTML($linkInfo['link_description'],"","value, emotes_off, defs, no_hook")."\"";
361		}
362
363		// Check if its expandable first. It should override its URL.
364		if (isset($linkInfo['link_expand']) && $linkInfo['link_expand'])
365		{
366			// $href = " href=\"javascript:expandit('sub_".$linkInfo['link_id']."')\"";
367			$href = "href='#sub_".$linkInfo['link_id']."'";
368		}
369		elseif ($linkInfo['link_url'])
370		{
371			// Only add the e_BASE if it actually has an URL.
372			$linkInfo['link_url'] = (strpos($linkInfo['link_url'], '://') === FALSE && strpos($linkInfo['link_url'], 'mailto:') !== 0 ? $linkInfo['link_url'] : $linkInfo['link_url']);
373
374			// Only check if its highlighted if it has an URL
375			if ($this->hilite($linkInfo['link_url'], $style['linkstart_hilite'])== TRUE)
376			{
377				$linkstart = (isset($style['linkstart_hilite'])) ? $style['linkstart_hilite'] : "";
378				$highlighted = TRUE;
379			}
380
381
382			if ($this->hilite(varset($linkInfo['link_url']), !empty($style['linkclass_hilite'])))
383			{
384				$linkadd = (isset($style['linkclass_hilite'])) ? " class='".$style['linkclass_hilite']."'" : "";
385				$highlighted = TRUE;
386			}
387
388			if ($linkInfo['link_open'] == 4 || $linkInfo['link_open'] == 5)
389			{
390				$dimen = ($linkInfo['link_open'] == 4) ? "600,400" : "800,600";
391				$href = " href=\"javascript:open_window('".$linkInfo['link_url']."',{$dimen})\"";
392			}
393			else
394			{
395				$href = " href='".$linkInfo['link_url']."'";
396			}
397
398			// Open link in a new window.  (equivalent of target='_blank' )
399			$link_append = ($linkInfo['link_open'] == 1) ? " rel='external'" : "";
400		}
401
402		// Remove default images if its a button and add new image at the start.
403		if ($linkInfo['link_button'])
404		{
405			$linkstart = preg_replace('/\<img.*\>/si', '', $linkstart);
406			$linkstart .= $tp->toIcon($linkInfo['link_button'],array('legacy'=> "{e_IMAGE}icons/"));
407
408		/*	if($linkInfo['link_button'][0]=='{')
409			{
410				$linkstart .= "<img src='".$tp->replaceConstants($linkInfo['link_button'],'abs')."' alt='' style='vertical-align:middle' />";
411			}
412			else
413			{
414
415				$linkstart .= "<img src='".e_IMAGE_ABS."icons/".$linkInfo['link_button']."' alt='' style='vertical-align:middle' />";
416			}*/
417		}
418
419		// mobile phone support.
420		$accesskey = (isset($style['accesskey']) && $style['accesskey']==TRUE) ? " accesskey='".$linkInfo['link_order']."' " : "";
421        $accessdigit = (isset($style['accessdigit'],$style['accesskey']) && $style['accessdigit']==TRUE && $style['accesskey']==TRUE) ? $linkInfo['link_order'].". " : "";
422
423		// If its a link.. make a link
424		$_link = "";
425		$_link .= $accessdigit;
426		if (!empty($href) && ((isset($style['hilite_nolink']) && $highlighted)!=TRUE))
427		{
428			$_link .= "<a".$linkadd.$screentip.$href.$link_append.$accesskey.">".$tp->toHTML($linkInfo['link_name'],"","emotes_off, defs, no_hook")."</a>";
429		}
430		elseif (!empty($linkadd) || !empty($screentip))
431		{	// If its not a link, but has a class or screentip do span:
432			$_link .= "<span".$linkadd.$screentip.">".$tp->toHTML($linkInfo['link_name'],"","emotes_off, defs, no_hook")."</span>";
433		}
434		else
435		{	// Else just the name:
436			$_link .= $tp->toHTML($linkInfo['link_name'],"","emotes_off, defs, no_hook");
437		}
438
439		$_link = $linkstart.$indent.$_link;
440        return $_link.$style['linkend']."\n";
441
442
443		/*
444
445		$search[0] = "/\{LINK\}(.*?)/si";
446		$replace[0] = $_link.$style['linkend']."\n";
447		$search[1] = "/\{LINK_DESCRIPTION\}(.*?)/si";
448		$replace[1] = $tp -> toHTML($linkInfo['link_description'], true);
449
450		$text = preg_replace($search, $replace, $SITELINKSTYLE);
451
452		return $text;*/
453	}
454
455	/**
456	 *	Determine whether link highlighting needs to be active
457	 *
458	 *	@param string $link - the full link as stored in the DB
459	 *	@param boolean $enabled - TRUE if the link is enabled
460	 *
461	 *	@return boolean TRUE if link to be highlighted, FALSE if not
462	 */
463	function hilite($link,$enabled = FALSE)
464	{
465		global $PLUGINS_DIRECTORY;
466		if(!$enabled){ return FALSE; }
467
468		$tp = e107::getParser();
469
470		$link = $tp->replaceConstants($link, '', TRUE);			// The link saved in the DB
471		$tmp = explode('?',$link);
472		$link_qry = (isset($tmp[1])) ? $tmp[1] : '';
473		$link_slf = (isset($tmp[0])) ? $tmp[0] : '';
474		$link_pge = basename($link_slf);
475		$link_match = (empty($tmp[0])) ? "": strpos(e_SELF,$tmp[0]);	// e_SELF is the actual displayed page
476
477		if(e_MENU == "debug" && getperms('0'))
478		{
479			echo "<br />link= ".$link;
480			echo "<br />link_q= ".$link_qry;
481			echo "<br />url= ".e_PAGE;
482			echo "<br />self= ".e_SELF;
483			echo "<br />url_query= ".e_QUERY."<br />";
484		}
485
486		// ----------- highlight overriding - set the link matching in the page itself.
487		if(defined('HILITE'))
488		{
489			if(strpos($link,HILITE))
490			{
491				return TRUE;
492			}
493		}
494
495		// --------------- highlighting for 'HOME'. ----------------
496		// See if we're on whatever is set as 'home' page for this user
497
498		// Although should be just 'index.php', allow for the possibility that there might be a query part
499	//	global $pref;
500		$pref = e107::pref();
501
502		if (($link_slf == e_HTTP."index.php") && count($pref['frontpage']))
503		{	// Only interested if the displayed page is index.php - see whether its the user's home (front) page
504			$full_url = 'news.php';					// Set a default in case
505			$uc_array = explode(',', USERCLASS_LIST);
506			foreach ($pref['frontpage'] as $fk=>$fp)
507			{
508				if (in_array($fk,$uc_array))
509				{
510					$full_url = ((strpos($fp, 'http') === FALSE) ? SITEURL : '').$fp;
511					break;
512				}
513			}
514			list($fp,$fp_q) = explode("?",$full_url."?"); // extra '?' ensure the array is filled
515			if (e_MENU == "debug" && getperms('0'))
516			{
517				echo "\$fp = ".$fp."<br />";
518				echo "\$fp_q = ".$fp_q."<br />";
519			}
520			$tmp = str_replace("../", "", e_SELF);
521			if ((strpos($fp, $tmp) !== FALSE) && ($fp_q == $link_qry))
522			{
523				return TRUE;
524			}
525		}
526
527		// --------------- highlighting for plugins. ----------------
528		if(stristr($link, $PLUGINS_DIRECTORY) !== FALSE && stristr($link, "custompages") === FALSE)
529		{
530			if($link_qry)
531			{	// plugin links with queries
532				return (strpos(e_SELF,$link_slf) && e_QUERY == $link_qry) ? TRUE : FALSE;
533			}
534			else
535			{	// plugin links without queries
536				$link = str_replace("../", "", $link);
537		   		if(stristr(dirname(e_SELF), dirname($link)) !== FALSE)
538				{
539 			 		return TRUE;
540				}
541			}
542            return FALSE;
543		}
544
545		// --------------- highlight for news items.----------------
546		// eg. news.php, news.php?list.1 or news.php?cat.2 etc
547		if(substr(basename($link),0,8) == "news.php")
548		{
549			if (strpos($link, "news.php?") !== FALSE && strpos(e_SELF,"/news.php")!==FALSE)
550			{
551				$lnk = explode(".",$link_qry); // link queries.
552				$qry = explode(".",e_QUERY); // current page queries.
553
554				if($qry[0] == "item")
555				{
556					return ($qry[2] == $lnk[1]) ? TRUE : FALSE;
557				}
558
559				if($qry[0] == "all" && $lnk[0] == "all")
560				{
561					return TRUE;
562				}
563
564				if($lnk[0] == $qry[0] && $lnk[1] == $qry[1])
565				{
566					return TRUE;
567				}
568
569				if($qry[1] == "list" && $lnk[0] == "list" && $lnk[1] == $qry[2])
570				{
571					return TRUE;
572				}
573			}
574			elseif (!e_QUERY && defset('e_PAGE') === "news.php")
575			{
576				return true;
577			}
578			return FALSE;
579		}
580
581		// --------------- highlight for Custom Pages.----------------
582		// eg. page.php?1, or page.php?5.7	[2nd parameter is page # within item]
583
584		//echo "Link: {$link}, link query: {$link_qry}, e_SELF: ".e_SELF.", link_slf: {$link_slf}, link_pge: {$link_pge}, e_PAGE: ".e_PAGE."<br />";
585		if (($link_slf == e_HTTP.'page.php') && (e_PAGE == 'page.php'))
586		{
587            list($custom,$page) = explode('.',$link_qry.'.');
588			list($q_custom,$q_page) = explode('.',e_QUERY.'.');
589			if($custom == $q_custom)
590			{
591            	return TRUE;
592			}
593			else
594			{
595              	return FALSE;
596			}
597		}
598
599		// --------------- highlight default ----------------
600		if(strpos($link, '?') !== FALSE)
601		{
602			$thelink = str_replace("../", "", $link);
603			if(!preg_match("/all|item|cat|list/", e_QUERY) && (empty($link) == false) && (strpos(e_SELF, str_replace("../", "",$link)) !== false))
604			{
605		   		return true;
606			}
607		}
608		if(!preg_match("/all|item|cat|list/", e_QUERY) && (strpos(e_SELF, str_replace("../", "",$link)) !== false))
609		{
610		  	return true;
611		}
612
613		if((!$link_qry && !e_QUERY) && (empty($link) == FALSE) && (strpos(e_SELF,$link) !== FALSE))
614		{
615			return TRUE;
616		}
617
618		if(($link_slf == e_SELF && !link_qry) || (e_QUERY && empty($link) == FALSE && strpos(e_SELF."?".e_QUERY,$link)!== FALSE) )
619		{
620          	return TRUE;
621		}
622
623		if($link_pge == basename($_SERVER['REQUEST_URI'])) // mod_rewrite support
624		{
625			return TRUE;
626		}
627
628	   	return FALSE;
629	}
630}
631
632
633/**
634 * Class for handling all navigation links site-wide. ie. admin links, admin-menu links, admin-plugin links, front-end sitelinks etc.
635 */
636class e_navigation
637{
638	/**
639	 * @var array Admin link structure
640	 */
641	var $admin_cat = array();
642
643	/**
644	 * @var boolean active check main
645	 */
646	public $activeSubFound = false;
647
648	/**
649	 * @var boolean active check sub
650	 */
651	public $activeMainFound = false;
652
653
654	var $iconArray = array();
655
656	function __construct()
657	{
658		if(defined('E_32_MAIN')) // basic check so that it's not loaded on the front-end.
659		{
660			$this->setIconArray();
661		}
662
663
664	}
665
666	function getIconArray()
667	{
668		return $this->iconArray;
669	}
670
671
672
673
674	function setIconArray()
675	{
676		if(!defined('E_32_MAIN'))
677		{
678			e107::getCoreTemplate('admin_icons');
679		}
680
681
682		$this->iconArray = array(
683				'main' 			=> E_32_MAIN,
684				'admin' 		=> E_32_ADMIN,
685				'admin_pass' 	=> E_32_ADPASS,
686				'banlist' 		=> E_32_BANLIST,
687				'cache' 		=> E_32_CACHE,
688				'comment' 		=> E_32_COMMENT,
689				'credits' 		=> E_32_CREDITS,
690				'cron'			=> E_32_CRON,
691				'custom' 		=> E_32_CUST,
692				// 'custom_field' => E_32_CUSTOMFIELD,
693				'database' 		=> E_32_DATAB,
694				'docs' 			=> E_32_DOCS,
695				//'download' => E_32_DOWNL,
696				'emoticon' 		=> E_32_EMOTE,
697				'filemanage' 	=> E_32_FILE,
698				'fileinspector' => E_32_INSPECT,
699				'frontpage' 	=> E_32_FRONT,
700				'image' 		=> E_32_IMAGES,
701				'language' 		=> E_32_LANGUAGE,
702				'links' 		=> E_32_LINKS,
703				'mail' 			=> E_32_MAIL,
704				'maintain' 		=> E_32_MAINTAIN,
705				'menus' 		=> E_32_MENUS,
706				'meta' 			=> E_32_META,
707				'newsfeed' 		=> E_32_NEWSFEED,
708				'news' 			=> E_32_NEWS,
709				'notify' 		=> E_32_NOTIFY,
710				'phpinfo' 		=> E_32_PHP,
711				'plug_manage' 	=> E_32_PLUGMANAGER,
712				'poll' 			=> E_32_POLLS,
713				'prefs' 		=> E_32_PREFS,
714				'search' 		=> E_32_SEARCH,
715				'syslogs' 		=> E_32_ADMINLOG,
716				'theme_manage' 	=> E_32_THEMEMANAGER,
717				'upload' 		=> E_32_UPLOADS,
718				'eurl' 			=> E_32_EURL,
719				'userclass' 	=> E_32_USERCLASS,
720				'user_extended' => E_32_USER_EXTENDED,
721				'users' 		=> E_32_USER,
722				'wmessage' 		=> E_32_WELCOME
723			);
724
725	}
726
727
728	/**
729	 * Structure $this->_md5cache[$category] = md5HASH
730	 * @var md5 hash used for build unique cache string per category and user classes
731	 */
732	protected $_md5cache = array();
733
734	//FIXME array structure - see $this->admin();
735	function adminCats()
736	{
737		$tp = e107::getParser();
738
739		if(count($this->admin_cat))
740		{
741			 return $this->admin_cat;
742		}
743
744		$pref = e107::getPref();
745
746		$this->admin_cat['title'][1] = LAN_SETTINGS;
747		$this->admin_cat['id'][1] = 'setMenu';
748		$this->admin_cat['img'][1] = 'fa-cogs.glyph';
749		$this->admin_cat['lrg_img'][1] = $tp->toGlyph('e-settings-32');
750		$this->admin_cat['sort'][1] = true;
751
752/*
753 * i.e-cat_content-32{ background-position: -370px 0; width: 32px; height: 32px; }
754i.e-cat_files-32{ background-position: -407px 0; width: 32px; height: 32px; }
755i.e-cat_plugins-32{ background-position: -444px 0; width: 32px; height: 32px; }
756i.e-cat_settings-32{ background-position: -481px 0; width: 32px; height: 32px; }
757i.e-cat_tools-32{ background-position: -518px 0; width: 32px; height: 32px; }
758i.e-cat_users-32{ background-position: -555px 0; width: 32px; height: 32px; }
759 * e-manage-32
760 */
761
762
763
764		$this->admin_cat['title'][2] = ADLAN_CL_2;
765		$this->admin_cat['id'][2] = 'userMenu';
766		$this->admin_cat['img'][2] = 'fa-users.glyph'; // $tp->toGlyph('e-cat_users-16');
767		$this->admin_cat['lrg_img'][2] = $tp->toGlyph('e-cat_users-32');
768		$this->admin_cat['sort'][2] = true;
769
770		$this->admin_cat['title'][3] = ADLAN_CL_3;
771		$this->admin_cat['id'][3] = 'contMenu';
772		$this->admin_cat['img'][3] = 'fa-file-text-o.glyph'; // $tp->toGlyph('e-cat_content-16');
773		$this->admin_cat['lrg_img'][3] = $tp->toGlyph('e-cat_content-32');
774		$this->admin_cat['sort'][3] = true;
775
776		$this->admin_cat['title'][4] = ADLAN_CL_6;
777		$this->admin_cat['id'][4] = 'toolMenu';
778		$this->admin_cat['img'][4] = 'fa-wrench.glyph'; // $tp->toGlyph('e-cat_tools-16');
779		$this->admin_cat['lrg_img'][4] = $tp->toGlyph('e-cat_tools-32');
780		$this->admin_cat['sort'][4] = true;
781
782		// Manage
783		$this->admin_cat['title'][5] = LAN_MANAGE;
784		$this->admin_cat['id'][5] = 'managMenu';
785		$this->admin_cat['img'][5] = 'fa-desktop.glyph' ; // $tp->toGlyph('e-manage-16');
786		$this->admin_cat['lrg_img'][5] = $tp->toGlyph('e-manage-32');
787		$this->admin_cat['sort'][5] = TRUE;
788
789		if(vartrue($pref['admin_separate_plugins']))
790		{
791			$this->admin_cat['title'][6] = ADLAN_CL_7;
792			$this->admin_cat['id'][6] = 'plugMenu';
793			$this->admin_cat['img'][6] = 'fa-puzzle-piece.glyph'; // $tp->toGlyph('e-cat_plugins-16');
794			$this->admin_cat['lrg_img'][6] = $tp->toGlyph('e-cat_plugins-32');
795			$this->admin_cat['sort'][6] = false;
796		}
797		else
798		{
799			// Misc.
800			$this->admin_cat['title'][6] = ADLAN_CL_8;
801			$this->admin_cat['id'][6] = 'miscMenu';
802			$this->admin_cat['img'][6] = 'fa-puzzle-piece.glyph'; ; // E_16_CAT_MISC;
803			$this->admin_cat['lrg_img'][6] = ''; // E_32_CAT_MISC;
804			$this->admin_cat['sort'][6] = TRUE;
805		}
806
807		//About menu    - No 20 -  leave space for user-categories.
808		$this->admin_cat['title'][20] = LAN_ABOUT;
809		$this->admin_cat['id'][20] = 'aboutMenu';
810		$this->admin_cat['img'][20] = 'fa-info-circle.glyph'; // E_16_CAT_ABOUT;//E_16_NAV_DOCS
811		$this->admin_cat['lrg_img'][20] = ''; // $tp->toGlyph('e-cat_about-32'); ; // E_32_CAT_ABOUT;
812		$this->admin_cat['sort'][20] = false;
813
814
815		return $this->admin_cat;
816
817	}
818
819	// Previously $array_functions variable.
820	function adminLinks($mode=false)
821	{
822
823        if($mode == 'plugin')
824        {
825             return $this->pluginLinks(E_16_PLUGMANAGER, "array") ;
826        }
827
828		if($mode == 'plugin2')
829        {
830             return $this->pluginLinks(E_16_PLUGMANAGER, "standard") ;
831        }
832
833
834
835		$this->setIconArray();
836
837
838		if($mode=='sub')
839		{
840
841				//FIXME  array structure suitable for e_admin_menu - see shortcodes/admin_navigation.php
842				/*
843				 * Info about sublinks array structure
844				 *
845				 * key = $array_functions key
846				 * attribute 1 = link
847				 * attribute 2 = title
848				 * attribute 3 = description
849				 * attribute 4 = perms
850				 * attribute 5 = category
851				 * attribute 6 = 16 x 16 image
852				 * attribute 7 = 32 x 32 image
853				 *
854				 */
855				$array_sub_functions = array();
856				$array_sub_functions[17][] = array(e_ADMIN.'newspost.php', LAN_MANAGE, ADLAN_3, 'H', 3, E_16_MANAGE, E_32_MANAGE);
857				$array_sub_functions[17][] = array(e_ADMIN.'newspost.php?create', LAN_CREATE, ADLAN_2, 'H', 3, E_16_CREATE, E_32_CREATE);
858				$array_sub_functions[17][] = array(e_ADMIN.'newspost.php?pref', LAN_PREFS, LAN_PREFS, 'H', 3, E_16_SETTINGS, E_32_SETTINGS);
859
860				return $array_sub_functions;
861		}
862
863
864			//FIXME array structure suitable for e_admin_menu (NOW admin() below) - see shortcodes/admin_navigation.php
865			//TODO find out where is used $array_functions elsewhere, refactor it
866
867			//XXX DO NOT EDIT without first checking perms in user_handler.php !!!!
868
869			$array_functions = array(
870			0 => array(e_ADMIN_ABS.'administrator.php', ADLAN_8,	ADLAN_9,	'3', 2, E_16_ADMIN, E_32_ADMIN),
871			1 => array(e_ADMIN_ABS.'updateadmin.php', 	ADLAN_10,	ADLAN_11,	false, 2, E_16_ADPASS, E_32_ADPASS),
872			2 => array(e_ADMIN_ABS.'banlist.php', 		ADLAN_34,	ADLAN_35,	'4', 2, E_16_BANLIST, E_32_BANLIST),
873			4 => array(e_ADMIN_ABS.'cache.php', 		ADLAN_74,	ADLAN_75,	'C', 1, E_16_CACHE, E_32_CACHE),
874			5 => array(e_ADMIN_ABS.'cpage.php', 		ADLAN_42,	ADLAN_43,	'5|J', 3, E_16_CUST, E_32_CUST),
875			6 => array(e_ADMIN_ABS.'db.php', 			ADLAN_44,	ADLAN_45,	'0', 4, E_16_DATAB, E_32_DATAB),
876		//	7 => array(e_ADMIN.'download.php', ADLAN_24, ADLAN_25, 'R', 3, E_16_DOWNL, E_32_DOWNL),
877			8 => array(e_ADMIN_ABS.'emoticon.php', 		ADLAN_58,	ADLAN_59,	'F', 1, E_16_EMOTE, E_32_EMOTE),
878		//	9 => array(e_ADMIN.'filemanager.php', 	ADLAN_30,	ADLAN_31,	'6', 5, E_16_FILE, E_32_FILE), // replaced by media-manager
879			10 => array(e_ADMIN_ABS.'frontpage.php', 	ADLAN_60,	ADLAN_61,	'G', 1, E_16_FRONT, E_32_FRONT),
880			11 => array(e_ADMIN_ABS.'image.php', 		LAN_MEDIAMANAGER, LAN_MEDIAMANAGER, 'A', 5, E_16_IMAGES, E_32_IMAGES),
881			12 => array(e_ADMIN_ABS.'links.php', 		ADLAN_138,	ADLAN_139,	'I', 1, E_16_LINKS, E_32_LINKS),
882			13 => array(e_ADMIN_ABS.'wmessage.php', 	ADLAN_28,	ADLAN_29,	'M', 3, E_16_WELCOME, E_32_WELCOME),
883			14 => array(e_ADMIN_ABS.'ugflag.php', 		ADLAN_40,	ADLAN_41,	'9', 4, E_16_MAINTAIN, E_32_MAINTAIN),
884			15 => array(e_ADMIN_ABS.'menus.php', 		ADLAN_6,	ADLAN_7,	'2', 5, E_16_MENUS, E_32_MENUS),
885			16 => array(e_ADMIN_ABS.'meta.php', 		ADLAN_66,	ADLAN_67,	'T', 1, E_16_META, E_32_META),
886			17 => array(e_ADMIN_ABS.'newspost.php', 	ADLAN_0,	ADLAN_1,	'H|N|7|H0|H1|H2|H3|H4|H5', 3, E_16_NEWS, E_32_NEWS),
887			18 => array(e_ADMIN_ABS.'phpinfo.php', 		ADLAN_68, 	ADLAN_69,	'0', 20, E_16_PHP, E_32_PHP),
888			19 => array(e_ADMIN_ABS.'prefs.php', 		LAN_PREFS, 	ADLAN_5,	'1', 1, E_16_PREFS, E_32_PREFS),
889			20 => array(e_ADMIN_ABS.'search.php', 		LAN_SEARCH,	ADLAN_143,	'X', 1, E_16_SEARCH, E_32_SEARCH),
890			21 => array(e_ADMIN_ABS.'admin_log.php', 	ADLAN_155,	ADLAN_156,	'S', 4, E_16_ADMINLOG, E_32_ADMINLOG),
891			22 => array(e_ADMIN_ABS.'theme.php', 		ADLAN_140,	ADLAN_141,	'1|TMP', 5, E_16_THEMEMANAGER, E_32_THEMEMANAGER),
892			23 => array(e_ADMIN_ABS.'upload.php', 		ADLAN_72,	ADLAN_73,	'V', 3, E_16_UPLOADS, E_32_UPLOADS),
893			24 => array(e_ADMIN_ABS.'users.php', 		ADLAN_36,	ADLAN_37,	'4|U0|U1|U2|U3', 2, E_16_USER, E_32_USER),
894			25 => array(e_ADMIN_ABS.'userclass2.php', 	ADLAN_38,	ADLAN_39,	'4', 2, E_16_USERCLASS, E_32_USERCLASS),
895			26 => array(e_ADMIN_ABS.'language.php', 	ADLAN_132,	ADLAN_133,	'L', 1, E_16_LANGUAGE, E_32_LANGUAGE),
896			27 => array(e_ADMIN_ABS.'mailout.php', 		ADLAN_136,	ADLAN_137,	'W', 2, E_16_MAIL, E_32_MAIL),
897			28 => array(e_ADMIN_ABS.'users_extended.php', ADLAN_78, ADLAN_79,	'4', 2, E_16_USER_EXTENDED, E_32_USER_EXTENDED),
898			29 => array(e_ADMIN_ABS.'fileinspector.php', ADLAN_147, ADLAN_148,	'Y', 4, E_16_INSPECT, E_32_INSPECT),
899			30 => array(e_ADMIN_ABS.'notify.php', 		ADLAN_149,	ADLAN_150,	'O', 4, E_16_NOTIFY, E_32_NOTIFY),
900			31 => array(e_ADMIN_ABS.'cron.php', 		ADLAN_157,	ADLAN_158,	'U', 4, E_16_CRON, E_32_CRON),
901
902			32 => array(e_ADMIN_ABS.'eurl.php', 		ADLAN_159,	ADLAN_160,	'K', 1, E_16_EURL, E_32_EURL),
903			33 => array(e_ADMIN_ABS.'plugin.php', 		ADLAN_98,	ADLAN_99,	'Z', 5 , E_16_PLUGMANAGER, E_32_PLUGMANAGER),
904			34 => array(e_ADMIN_ABS.'docs.php', 		ADLAN_12,	ADLAN_13,	false,	20, E_16_DOCS, E_32_DOCS),
905		// TODO System Info.
906		//	35 => array('#TODO', 'System Info', 'System Information', '', 20, '', ''),
907			36 => array(e_ADMIN_ABS.'credits.php', LAN_CREDITS, LAN_CREDITS, false, 20, E_16_E107, E_32_E107),
908		//	37 => array(e_ADMIN.'custom_field.php', ADLAN_161, ADLAN_162, 'U', 4, E_16_CUSTOMFIELD, E_32_CUSTOMFIELD),
909			38 => array(e_ADMIN_ABS.'comment.php', LAN_COMMENTMAN, LAN_COMMENTMAN, 'B', 5, E_16_COMMENT, E_32_COMMENT),
910		);
911
912
913		if($mode == 'legacy')
914        {
915            return $array_functions; // Old BC format.
916        }
917
918		$newarray = asortbyindex($array_functions, 1);
919    	$array_functions_assoc = $this->convert_core_icons($newarray);
920
921
922
923       if($mode == 'core') // Core links only.
924        {
925            return $array_functions_assoc;
926        }
927
928        $merged = array_merge($array_functions_assoc, $this->pluginLinks(E_16_PLUGMANAGER, "array"));
929        $sorted = multiarray_sort($merged,'title'); // this deleted the e-xxxx and p-xxxxx keys.
930        return $this->restoreKeys($sorted); // we restore the keys with this.
931
932	}
933
934
935
936    private function restoreKeys($newarray)  // Put core button array in the same format as plugin button array.
937    {
938        $array_functions_assoc = array();
939
940        foreach($newarray as $key=>$val)
941        {
942           if(varset($val['key'])) // Plugin Array.
943            {
944                $key = $val['key'];
945
946                $array_functions_assoc[$key] = $val;
947            }
948        }
949
950        return $array_functions_assoc;
951    }
952
953
954	/**
955	 * Return the default array of icon identifiers for the admin "Control Panel". (infopanel and flexpanel)
956	 * @return array
957	 */
958	public function getDefaultAdminPanelArray()
959	{
960		$iconlist = $this->adminLinks();
961
962		$defArray = array();
963
964		$exclude = array (
965				'e-administrator',
966				'e-updateadmin',
967				'e-banlist',
968				'e-cache',
969				'e-comment',
970				'e-credits',
971				'e-db',
972				'e-docs',
973				'e-emoticon',
974				'e-users_extended',
975				'e-fileinspector',
976				'e-language',
977				'e-ugflag',
978				'e-notify',
979				'e-phpinfo',
980				'e-upload',
981				'e-cron',
982				'e-search',
983				'e-admin_log',
984				'e-eurl'
985			);
986
987		foreach($iconlist as $k=>$v)
988		{
989			if(!in_array($k,$exclude))
990			{
991				$defArray[] = $k;
992			}
993		}
994
995		return $defArray;
996	}
997
998
999
1000
1001	private function convert_core_icons($newarray)  // Put core button array in the same format as plugin button array.
1002	{
1003
1004	    $array_functions_assoc = array();
1005
1006	    foreach($newarray as $key=>$val)
1007		{
1008			if(varset($val[0]))
1009			{
1010				$key = "e-".basename($val[0],".php");
1011                $val['key'] = $key;
1012				$val['icon'] = $val[5];
1013				$val['icon_32'] = $val[6];
1014				$val['title'] = $val[1];
1015				$val['link'] = $val[0];
1016				$val['caption'] = $val['2'];
1017                $val['cat'] = $val['4'];
1018				$val['perms'] = $val['3'];
1019				$array_functions_assoc[$key] = $val;
1020			}
1021
1022		}
1023
1024	    return $array_functions_assoc;
1025	}
1026
1027    /**
1028     * Convert from plugin category found in plugin.xml to Navigation Category ID number.
1029     */
1030    function plugCatToCoreCat($cat)
1031    {
1032            $convert = array(
1033                'settings'  => array(1,'setMenu'),
1034                'users'     => array(2,'userMenu'),
1035                'content'   => array(3,'contMenu'),
1036                'tools'     => array(4,'toolMenu'),
1037                'manage'    => array(6,'managMenu'),
1038                'misc'      => array(7,'miscMenu'),
1039                'help'      => array(20,'helpMenu')
1040            );
1041
1042            return (int) vartrue($convert[$cat][0]);
1043    }
1044
1045
1046	/**
1047	 * Get Plugin Links - rewritten for v2.1.5
1048	 * @param string $iconSize
1049	 * @param string $linkStyle standard = new in v2.1.5 | array | adminb
1050	 * @return array|string
1051	 */
1052	function pluginLinks($iconSize = E_16_PLUGMANAGER, $linkStyle = 'adminb')
1053	{
1054		$plug = e107::getPlug();
1055		$data = $plug->getInstalled();
1056
1057		$arr = array();
1058
1059		$pref = e107::getPref();
1060
1061		foreach($data as $path=>$ver)
1062		{
1063
1064			if(!e107::isInstalled($path))
1065			{
1066				continue;
1067			}
1068
1069			if(!empty($pref['lan_global_list']) && !in_array($path, $pref['lan_global_list']))
1070			{
1071				e107::loadLanFiles($path, 'admin');
1072			}
1073
1074			$plug->load($path);
1075
1076
1077			$key = ($linkStyle === 'standard') ? "plugnav-".$path : 'p-'.$path;
1078
1079			$url = $plug->getAdminUrl();
1080			$cat = $plug->getCategory();
1081
1082			if(empty($url) || $cat === 'menu')
1083			{
1084				continue;
1085			}
1086
1087			// Keys compatible with legacy and new admin layouts.
1088			$arr[$key] = array(
1089
1090				'text'          => $plug->getName(),
1091				'description'   => $plug->getDescription(),
1092				'link'          => $url,
1093				'image'         => $plug->getIcon(16),
1094				'image_large'   => $plug->getIcon(32),
1095				'category'      => $cat,
1096				'perm'           => "P".$plug->getId(),
1097				'sort'          => 2,
1098				'sub_class'     => null,
1099
1100
1101				// Legacy Keys.
1102				'key'       => $key,
1103				'title'     => $plug->getName(),
1104				'caption'   => $plug->getAdminCaption(),
1105				'perms'     => "P".$plug->getId(),
1106				'icon'      => $plug->getIcon(16),
1107				'icon_32'   => $plug->getIcon(32),
1108				'cat'       => $this->plugCatToCoreCat($plug->getCategory())
1109
1110			);
1111
1112
1113		}
1114
1115		//ksort($arr, SORT_STRING);
1116
1117		if($linkStyle === "array" || $iconSize === 'assoc' || $linkStyle === 'standard')
1118		{
1119		   	return $arr;
1120		}
1121
1122
1123		$text = '';
1124
1125		foreach ($arr as $plug_key => $plug_value)
1126		{
1127			$the_icon =  ($iconSize == E_16_PLUGMANAGER) ?  $plug_value['icon'] : $plug_value['icon_32'];
1128			$text .= $this->renderAdminButton($plug_value['link'], $plug_value['title'], $plug_value['caption'], $plug_value['perms'], $the_icon, $linkStyle);
1129		}
1130
1131		return $text;
1132
1133	}
1134
1135
1136	// Function renders all the plugin links according to the required icon size and layout style
1137	// - common to the various admin layouts such as infopanel, classis etc.
1138	/**
1139	 * @deprecated
1140	 * @param string $iconSize
1141	 * @param string $linkStyle
1142	 * @return array|string
1143	 */
1144	function pluginLinksOld($iconSize = E_16_PLUGMANAGER, $linkStyle = 'adminb')
1145	{
1146
1147		$sql = e107::getDb();
1148		$tp = e107::getParser();
1149
1150
1151		$plug_id = array();
1152		$plugin_array = array();
1153		e107::getDb()->db_Select("plugin", "*", "plugin_installflag = 1"); // Grab plugin IDs.
1154		while ($row = e107::getDb()->db_Fetch())
1155		{
1156			$pth = $row['plugin_path'];
1157			$plug_id[$pth] = $row['plugin_id'];
1158		}
1159
1160		$pref = e107::getConfig('core')->getPref();
1161
1162		$text = $this->renderAdminButton(e_ADMIN."plugin.php", ADLAN_98, ADLAN_99, "Z", $iconSize, $linkStyle);
1163
1164		$plugs = e107::getObject('e107plugin');
1165
1166
1167
1168		if(!empty($pref['plug_installed']))
1169		{
1170			foreach($pref['plug_installed'] as $plug=>$vers)
1171			{
1172
1173				$plugs->parse_plugin($plug);
1174
1175
1176				$plugin_path = $plug;
1177				$name = $plugs->plug_vars['@attributes']['name'];
1178			/*
1179				echo "<h1>".$name." ($plug)</h1>";
1180				print_a($plugs->plug_vars);
1181                */
1182
1183				if(!varset($plugs->plug_vars['adminLinks']['link']))
1184				{
1185					continue;
1186				}
1187
1188				foreach($plugs->plug_vars['adminLinks']['link'] as $tag)
1189				{
1190					if(varset($tag['@attributes']['primary']) !='true')
1191					{
1192						continue;
1193					}
1194
1195					if(!empty($pref['lan_global_list']) && !in_array($plugin_path, $pref['lan_global_list']))
1196					{
1197						e107::loadLanFiles($plugin_path, 'admin');
1198					}
1199
1200					$att = $tag['@attributes'];
1201
1202
1203					$eplug_name 		= $tp->toHTML($name,FALSE,"defs, emotes_off");
1204					$eplug_conffile 	= $att['url'];
1205					$eplug_icon_small 	= (!empty($att['iconSmall'])) ? $plugin_path.'/'.$att['iconSmall'] : '';
1206					$eplug_icon 		= (!empty($att['icon'])) ? $plugin_path.'/'.$att['icon'] : '';
1207					$eplug_caption 		= str_replace("'", '', $tp->toHTML($att['description'], FALSE, 'defs, emotes_off'));
1208
1209					if (varset($eplug_conffile))
1210					{
1211						$eplug_name = $tp->toHTML($eplug_name,FALSE,"defs, emotes_off");
1212						$plugin_icon = $eplug_icon_small ? "<img class='icon S16' src='".e_PLUGIN_ABS.$eplug_icon_small."' alt=''  />" : E_16_PLUGIN;
1213						$plugin_icon_32 = $eplug_icon ? "<img class='icon S32' src='".e_PLUGIN_ABS.$eplug_icon."' alt=''  />" :  E_32_PLUGIN;
1214						$plugin_array['p-'.$plugin_path] = array(
1215						  'key'      => 'p-'.$plugin_path,
1216						  'link'      => e_PLUGIN.$plugin_path."/".$eplug_conffile,
1217						  'title'     => $eplug_name,
1218						  'caption' => $eplug_caption,
1219						  'perms'     => "P".varset($plug_id[$plugin_path]),
1220						  'icon'      => $plugin_icon,
1221						  'icon_32'   => $plugin_icon_32,
1222						  'cat'       => $this->plugCatToCoreCat($plugs->plug_vars['category'])
1223                        );
1224					}
1225				}
1226			}
1227		}
1228
1229
1230	//	print_a($plugs->plug_vars['adminLinks']['link']);
1231
1232
1233
1234
1235		/*	echo "hello there";
1236
1237		 	$xml = e107::getXml();
1238			$xml->filter = array('@attributes' => FALSE,'description'=>FALSE,'administration' => FALSE);	// .. and they're all going to need the same filter
1239
1240			if ($sql->db_Select("plugin", "*", "plugin_installflag=1"))
1241			{
1242				while ($row = $sql->db_Fetch())
1243				{
1244					extract($row);		//  plugin_id int(10) unsigned NOT NULL auto_increment,
1245										//	plugin_name varchar(100) NOT NULL default '',
1246										//	plugin_version varchar(10) NOT NULL default '',
1247										//	plugin_path varchar(100) NOT NULL default '',
1248										//	plugin_installflag tinyint(1) unsigned NOT NULL default '0',
1249										//	plugin_addons text NOT NULL,
1250
1251					if (is_readable(e_PLUGIN.$plugin_path."/plugin.xml"))
1252					{
1253						$readFile = $xml->loadXMLfile(e_PLUGIN.$plugin_path.'/plugin.xml', true, true);
1254						if ($readFile === FALSE)
1255						{
1256							echo 'Error in file: '.e_PLUGIN.$plugin_path.'/plugin.xml'.'<br />';
1257						}
1258						else
1259						{
1260							loadLanFiles($plugin_path, 'admin');
1261							$eplug_name 		= $tp->toHTML($readFile['@attributes']['name'],FALSE,"defs, emotes_off");
1262							$eplug_conffile 	= $readFile['administration']['configFile'];
1263							$eplug_icon_small 	= $plugin_path.'/'.$readFile['administration']['iconSmall'];
1264							$eplug_icon 		= $plugin_path.'/'.$readFile['administration']['icon'];
1265							$eplug_caption 		= str_replace("'", '', $tp->toHTML($readFile['description'], FALSE, 'defs, emotes_off'));
1266						}
1267					}
1268					elseif (is_readable(e_PLUGIN.$plugin_path."/plugin.php"))
1269					{
1270						include(e_PLUGIN.$plugin_path."/plugin.php");
1271					}
1272					if (varset($eplug_conffile))
1273					{
1274						$eplug_name = $tp->toHTML($eplug_name,FALSE,"defs, emotes_off");
1275						$plugin_icon = $eplug_icon_small ? "<img class='icon S16' src='".e_PLUGIN.$eplug_icon_small."' alt=''  />" : E_16_PLUGIN;
1276						$plugin_icon_32 = $eplug_icon ? "<img class='icon S32' src='".e_PLUGIN.$eplug_icon."' alt=''  />" : E_32_PLUGIN;
1277
1278						$plugin_array['p-'.$plugin_path] = array('link' => e_PLUGIN.$plugin_path."/".$eplug_conffile, 'title' => $eplug_name, 'caption' => $eplug_caption, 'perms' => "P".$plugin_id, 'icon' => $plugin_icon, 'icon_32' => $plugin_icon_32);
1279					}
1280					unset($eplug_conffile, $eplug_name, $eplug_caption, $eplug_icon_small);
1281				}
1282					}
1283					else
1284					{
1285						$plugin_array = array();
1286					}
1287				*/
1288			ksort($plugin_array, SORT_STRING);  // To FIX, without changing the current key format, sort by 'title'
1289
1290			if($linkStyle == "array" || $iconSize == 'assoc')
1291			{
1292		       	return $plugin_array;
1293			}
1294
1295			foreach ($plugin_array as $plug_key => $plug_value)
1296			{
1297				$the_icon =  ($iconSize == E_16_PLUGMANAGER) ?  $plug_value['icon'] : $plug_value['icon_32'];
1298				$text .= $this->renderAdminButton($plug_value['link'], $plug_value['title'], $plug_value['caption'], $plug_value['perms'], $the_icon, $linkStyle);
1299			}
1300			return $text;
1301	}
1302
1303
1304	/**
1305	 * XXX the NEW version of e_admin_menu();
1306	 * Build admin menus - addmin menus are now supporting unlimitted number of submenus
1307	 * TODO - add this to a handler for use on front-end as well (tree, sitelinks.sc replacement)
1308	 *
1309	 * $e107_vars structure:
1310	 * $e107_vars['action']['text'] -> link title
1311	 * $e107_vars['action']['link'] -> if empty '#action' will be added as href attribute
1312	 * $e107_vars['action']['image'] -> (new) image tag
1313	 * $e107_vars['action']['perm'] -> permissions via getperms()
1314	 * $e107_vars['action']['userclass'] -> user class permissions via check_class()
1315	 * $e107_vars['action']['include'] -> additional <a> tag attributes
1316	 * $e107_vars['action']['sub'] -> (new) array, exactly the same as $e107_vars' first level e.g. $e107_vars['action']['sub']['action2']['link']...
1317	 * $e107_vars['action']['sort'] -> (new) used only if found in 'sub' array - passed as last parameter (recursive call)
1318	 * $e107_vars['action']['link_class'] -> (new) additional link class
1319	 * $e107_vars['action']['sub_class'] -> (new) additional class used only when sublinks are being parsed
1320	 *
1321	 * @param string $title
1322	 * @param string $active_page
1323	 * @param array $e107_vars
1324	 * @param array $tmpl
1325	 * @param array $sub_link
1326	 * @param bool $sortlist
1327	 * @return string parsed admin menu (or empty string if title is empty)
1328	 */
1329	function admin($title, $active_page, $e107_vars, $tmpl = array(), $sub_link = false, $sortlist = false)
1330	{
1331
1332		global $E_ADMIN_MENU; //TODO remove me?
1333
1334
1335		$tp = e107::getParser();
1336
1337		if (!$tmpl)
1338			$tmpl = $E_ADMIN_MENU;
1339
1340		/*
1341		 * Search for id
1342		 */
1343		$temp = explode('--id--', $title, 2);
1344		$title = $temp[0];
1345		$id = str_replace(array(' ', '_'), '-', varset($temp[1]));
1346
1347		unset($temp);
1348
1349		/*
1350		 * SORT
1351		 */
1352		if ($sortlist == TRUE)
1353		{
1354			$temp = $e107_vars;
1355			unset($e107_vars);
1356			$func_list = array();
1357			foreach (array_keys($temp) as $key)
1358			{
1359				$func_list[] = $temp[$key]['text'];
1360			}
1361
1362			usort($func_list, 'strcoll');
1363
1364			foreach ($func_list as $func_text)
1365			{
1366				foreach (array_keys($temp) as $key)
1367				{
1368					if ($temp[$key]['text'] == $func_text)
1369					{
1370						$e107_vars[] = $temp[$key];
1371					}
1372				}
1373			}
1374			unset($temp);
1375		}
1376
1377		if(empty($e107_vars))
1378		{
1379			return null;
1380		}
1381
1382
1383
1384		$kpost = '';
1385		$text = '';
1386
1387		if ($sub_link)
1388		{
1389			$kpost = '_sub';
1390		}
1391		else
1392		{
1393			 $text = $tmpl['start'];
1394		}
1395
1396		//FIXME - e_parse::array2sc()
1397/*		$search = array();
1398		$search[0] = '/\{LINK_TEXT\}(.*?)/si';
1399		$search[1] = '/\{LINK_URL\}(.*?)/si';
1400		$search[2] = '/\{ONCLICK\}(.*?)/si';
1401		$search[3] = '/\{SUB_HEAD\}(.*?)/si';
1402		$search[4] = '/\{SUB_MENU\}(.*?)/si';
1403		$search[5] = '/\{ID\}(.*?)/si';
1404		$search[6] = '/\{SUB_ID\}(.*?)/si';
1405		$search[7] = '/\{LINK_CLASS\}(.*?)/si';
1406		$search[8] = '/\{SUB_CLASS\}(.*?)/si';
1407		$search[9] = '/\{LINK_IMAGE\}(.*?)/si';
1408		$search[10] = '/\{LINK_SUB_OVERSIZED\}/si';
1409		$search[11] = '/\{LINK_DATA\}/si';*/
1410
1411
1412
1413		foreach (array_keys($e107_vars) as $act)
1414		{
1415			if (isset($e107_vars[$act]['perm']) && $e107_vars[$act]['perm'] !== false && !getperms($e107_vars[$act]['perm'])) // check perms first.
1416			{
1417				continue;
1418			}
1419
1420
1421
1422			if (isset($e107_vars[$act]['header']))
1423			{
1424			 	$text .= "<li class='nav-header'>".$e107_vars[$act]['header']."</li>";	//TODO add to Template.
1425				continue;
1426			}
1427
1428			if (isset($e107_vars[$act]['divider']))
1429			{
1430			 //	$text .= "<li class='divider'></li>";
1431			 	$text .= $tmpl['divider'];
1432				continue;
1433			}
1434
1435
1436
1437			// check class so that e.g. e_UC_NOBODY will result no permissions granted (even for main admin)
1438			if (isset($e107_vars[$act]['userclass']) && !e107::getUser()->checkClass($e107_vars[$act]['userclass'], false)) // check userclass perms
1439			{
1440				continue;
1441			}
1442
1443			//  print_a($e107_vars[$act]);
1444
1445			$replace = array();
1446
1447
1448
1449
1450			$rid = str_replace(array(' ', '_'), '-', $act).($id ? "-{$id}" : '');
1451
1452			//XXX  && !is_numeric($act) ???
1453			if (($active_page == (string) $act)
1454			|| (str_replace("?", "", e_PAGE.e_QUERY) == str_replace("?", "", $act))
1455            || e_REQUEST_HTTP === $e107_vars[$act]['link']
1456			)
1457			{
1458				$temp = $tmpl['button_active'.$kpost];
1459			}
1460			else
1461			{
1462				$temp = $tmpl['button'.$kpost];
1463			}
1464
1465   //     e107::getDebug()->log($e107_vars[$act]['link']);
1466
1467		//	$temp = $tmpl['button'.$kpost];
1468		//	echo "ap = ".$active_page;
1469		//	echo " act = ".$act."<br /><br />";
1470
1471
1472
1473			if($rid == 'adminhome')
1474			{
1475				$temp = $tmpl['button_other'.$kpost];
1476			}
1477
1478			if(!empty($e107_vars[$act]['template']))
1479			{
1480				$tmplateKey = 'button_'.$e107_vars[$act]['template'].$kpost;
1481				$temp = $tmpl[$tmplateKey];
1482
1483				// e107::getDebug()->log($tmplateKey);
1484			}
1485
1486
1487			$replace['LINK_TEXT'] = str_replace(" ", "&nbsp;", $e107_vars[$act]['text']);
1488
1489			// valid URLs
1490			$replace['LINK_URL'] = str_replace(array('&amp;', '&'), array('&', '&amp;'), vartrue($e107_vars[$act]['link'], "#{$act}"));
1491			$replace['ONCLICK'] = '';
1492
1493			if (vartrue($e107_vars[$act]['include']))
1494			{
1495				$replace['ONCLICK'] = $e107_vars[$act]['include'];
1496				//$replace[2] = $js ? " onclick=\"showhideit('".$act."');\"" : " onclick=\"document.location='".$e107_vars[$act]['link']."'; disabled=true;\"";
1497			}
1498			$replace['SUB_HEAD'] = $title;
1499			$replace['SUB_MENU'] = '';
1500
1501			$replace['ID'] = $id ? " id='eplug-nav-{$rid}'" : '';
1502			$replace['SUB_ID'] = $rid;
1503
1504			$replace['LINK_CLASS'] = varset($e107_vars[$act]['link_class']);
1505			$replace['SUB_CLASS'] = '';
1506
1507			if(vartrue($e107_vars[$act]['image_src']) && strstr($e107_vars[$act]['image_src'],'.glyph'))
1508			{
1509				$replace['LINK_IMAGE'] = $tp->toGlyph($e107_vars[$act]['image_src'], array('space'=>'&nbsp;'));
1510			}
1511			else
1512			{
1513				$replace['LINK_IMAGE'] = varset($e107_vars[$act]['image']);
1514			}
1515
1516			$replace['LINK_SUB_OVERSIZED'] = (isset($e107_vars[$act]['sub']) && count($e107_vars[$act]['sub']) > 20) ? 'oversized' : '';
1517
1518			if(!empty($e107_vars[$act]['link_data']))
1519			{
1520
1521				$dataTmp = array();
1522				foreach($e107_vars[$act]['link_data'] as $k=>$v)
1523				{
1524					$dataTmp[] = $k.'="'.$v.'"';
1525				}
1526
1527				$replace['LINK_DATA'] = implode(" ", $dataTmp); // $e107_vars[$act]['link_data']
1528
1529			}
1530
1531
1532			$replace['LINK_BADGE'] = isset($e107_vars[$act]['badge']['value']) ? $tp->toLabel($e107_vars[$act]['badge']['value'], varset($e107_vars[$act]['badge']['type'])) : '';
1533
1534
1535			if($rid == 'logout' || $rid == 'home' || $rid == 'language')
1536			{
1537				$START_SUB = $tmpl['start_other_sub'];
1538			}
1539			else
1540			{
1541				$START_SUB = $tmpl['start_sub'];
1542			}
1543
1544			if(!empty($e107_vars[$act]['sub']))
1545			{
1546				$replace['SUB_ID'] = $id ? " id='eplug-nav-{$rid}-sub'" : '';
1547				$replace['LINK_CLASS'] = ' '.varset($e107_vars[$act]['link_class'], 'e-expandit');
1548				$replace['SUB_CLASS'] = ' '.varset($e107_vars[$act]['sub_class'], 'e-hideme e-expandme');
1549
1550				$replace['SUB_MENU']  = $tp->parseTemplate($START_SUB, false, $replace);
1551				$replace['SUB_MENU'] .= $this->admin(false, $active_page, $e107_vars[$act]['sub'], $tmpl, true, (isset($e107_vars[$act]['sort']) ? $e107_vars[$act]['sort'] : $sortlist));
1552				$replace['SUB_MENU'] .= $tmpl['end_sub'];
1553			}
1554
1555
1556		//	$text .= preg_replace($search, $replace, $temp);
1557			$text .= $tp->parseTemplate($temp, false, $replace); // ($search, $replace, $temp);
1558		//	echo "<br />".$title." act=".$act;
1559			//print_a($e107_vars[$act]);
1560		}
1561
1562		$text .= (!$sub_link) ? $tmpl['end'] : '';
1563
1564		if ($sub_link || empty($title))
1565		{
1566			return $text;
1567		}
1568
1569		$ns = e107::getRender();
1570		$ns->setUniqueId($id);
1571		$ns->tablerender($title, $text);
1572		$ns->setUniqueId(null);
1573		return '';
1574	}
1575
1576
1577
1578
1579	// Previously admin.php -> render_links();
1580	function renderAdminButton($link, $title, $description, $perms, $icon = FALSE, $mode = FALSE)
1581	{
1582		global $td;
1583		$tp = e107::getParser();
1584		$mes = e107::getMessage();
1585		$cols = defset('ADLINK_COLS',5);
1586
1587
1588		$text = '';
1589		if (getperms($perms))
1590		{
1591			$description = strip_tags($description);
1592			if ($mode == 'adminb')
1593			{
1594				$text = "<tr><td class='forumheader3'>
1595					<div class='td' style='text-align:left; vertical-align:top; width:100%'
1596					onmouseover=\"eover(this, 'forumheader5')\" onmouseout=\"eover(this, 'td')\" onclick=\"document.location.href='".$link."'\">
1597					".$icon." <b>".$title."</b> ".($description ? "[ <span class='field-help'>".$description."</span> ]" : "")."</div></td></tr>";
1598			}
1599			else
1600			{
1601
1602				if($mode != "div" && $mode != 'div-icon-only')
1603				{
1604					if ($td == ($cols +1))
1605					{
1606						$text .= '</tr>';
1607						$td = 1;
1608					}
1609					if ($td == 1)
1610					{
1611						$text .= '<tr>';
1612					}
1613				}
1614
1615
1616				switch ($mode)
1617				{
1618					case 'default':
1619						$text .= "<td class='td' style='text-align:left; vertical-align:top; width:20%; white-space:nowrap'>
1620						 <a class='core-mainpanel-link-icon e-tip' href='".$link."' title='{$description}'>".$icon." ".$tp->toHTML($title,FALSE,"defs, emotes_off")."</a></td>";
1621					break;
1622
1623					case 'classis':
1624						$text .= "<td style='text-align:center; vertical-align:top; width:20%'><a class='core-mainpanel-link-icon' href='".$link."' title='{$description}'>".$icon."</a><br />
1625						<a class='core-mainpanel-link-text' href='".$link."' title='{$description}'><b>".$tp->toHTML($title,FALSE,"defs, emotes_off")."</b></a></td>";
1626					break;
1627
1628					case 'beginner':
1629						 $text .= "<td style='text-align:center; vertical-align:top; width:20%' ><a class='core-mainpanel-link-icon' href='".$link."' >".$icon."</a>
1630						<div style='padding:5px'>
1631						<a class='core-mainpanel-link-text' href='".$link."' title='".$description."'><b>".$tp->toHTML($title,FALSE,"defs, emotes_off")."</b></a></div><br /><br /><br /></td>";
1632					break;
1633
1634					case 'div':
1635						$text .= "<div class='core-mainpanel-block '><a data-toggle='tooltip' class='core-mainpanel-link-icon btn btn-default btn-secondary muted' href='".$link."' title='{$description}'>".$icon."
1636						<small class='core-mainpanel-link-text'>".$tp->toHTML($title,FALSE,"defs, emotes_off")."</small></a>
1637						</div>";
1638					break;
1639
1640					case 'div-icon-only':
1641						$text .= "<div class='core-mainpanel-block  e-tip' title='{$description}'><a class='core-mainpanel-link-icon btn btn-default btn-secondary e-tip' href='".$link."' >".$icon."</a></div>";
1642					break;
1643
1644					default:
1645
1646						break;
1647				}
1648
1649				$td++;
1650			}
1651		}
1652		else
1653		{
1654			// echo "no Perms";
1655		}
1656
1657		return $text;
1658	}
1659
1660
1661	public function cacheString($category, $type = 'sys')
1662	{
1663		if(!isset($this->_md5cache[$category]))
1664		{
1665			$uclist = e107::getUser()->getClassList();
1666			sort($uclist, SORT_NUMERIC);
1667			$this->_md5cache[$category] = md5($category.$uclist);
1668		}
1669		switch ($type)
1670		{
1671			case 'sys':
1672				return $this->cacheBase().$this->_md5cache[$category];
1673			break;
1674
1675			case 'md5':
1676				return $this->_md5cache[$category];
1677			break;
1678		}
1679	}
1680
1681	public function cacheBase()
1682	{
1683		return 'nomd5_sitelinks_';
1684	}
1685
1686
1687	/**
1688	 * TODO Cache
1689	 */
1690	public function render($data, $template, $useCache = true)
1691	{
1692		if(empty($data) || empty($template) || !is_array($template)) return '';
1693
1694		/** @var navigation_shortcodes $sc */
1695		$sc 			= e107::getScBatch('navigation');
1696		$sc->template 	= $template;
1697		$head			= e107::getParser()->parseTemplate($template['start'],true);
1698		$foot 			= e107::getParser()->parseTemplate($template['end'],true);
1699		$ret 			= "";
1700
1701		$sc->counter	= 1;
1702		$this->activeMainFound = false;
1703
1704		foreach ($data as $_data)
1705		{
1706			$active			= ($this->isActive($_data, $this->activeMainFound)) ? "_active" : "";
1707			$sc->setDepth(0);
1708			$sc->setVars($_data); // isActive is allowed to alter data
1709			$itemTmpl 		= count($_data['link_sub']) > 0 ? $template['item_submenu'.$active] : $template['item'.$active];
1710			$ret 			.= e107::getParser()->parseTemplate($itemTmpl, true, $sc);
1711			$sc->active		= ($active) ? true : false;
1712			if($sc->active)
1713			{
1714				$this->activeMainFound = true;
1715			}
1716			$sc->counter++;
1717		}
1718
1719		return ($ret != '') ? $head.$ret.$foot : '';
1720	}
1721
1722
1723	/**
1724	 * --------------- CODE-EFFICIENT APPROACH -------------------------
1725	 * FIXME syscache
1726	 */
1727	public function initData($cat=1, $opt=array())
1728	{
1729		$sql 		= e107::getDb('sqlSiteLinks');
1730
1731		$ins = ($cat > 0) ? " link_category = ".intval($cat)." AND " : "";
1732
1733		$query 		= "SELECT * FROM #links WHERE ".$ins." ((link_class >= 0 AND link_class IN (".USERCLASS_LIST.")) OR (link_class < 0 AND ABS(link_class) NOT IN (".USERCLASS_LIST.")) ) ORDER BY link_order,link_parent ASC";
1734
1735		$outArray 	= array();
1736		$data 		= $sql->retrieve($query,true);
1737
1738
1739		$ret = $this->compile($data, $outArray);
1740
1741		if(!empty($opt['flat']))
1742		{
1743			$newArr = array();
1744			foreach($ret as $row)
1745			{
1746				$ignore = (!empty($opt['noempty']) && (empty($row['link_url']) || $row['link_url'] === '#')) ? true : false;
1747
1748				$tmp = (array) $row['link_sub'];
1749
1750				unset($row['link_sub']);
1751
1752				if($ignore !== true)
1753				{
1754					$newArr[] = $row;
1755				}
1756
1757				if(!empty($tmp))
1758				{
1759					foreach($tmp as $val)
1760					{
1761						$tmp2 = (array) $val['link_sub'];
1762						unset($val['link_sub']);
1763						$newArr[] = $val;
1764						if(!empty($tmp2))
1765						{
1766							foreach($tmp2 as $k=>$v)
1767							{
1768								$tmp3 = (array) $v['link_sub'];
1769								unset($v['link_sub']);
1770								$newArr[] = $v;
1771								foreach($tmp3 as $sub)
1772								{
1773									$newArr[] = $sub;
1774								}
1775							}
1776						}
1777					}
1778				}
1779
1780			}
1781
1782	//e107::getDebug()->log($newArr);
1783
1784			return $newArr;
1785		}
1786
1787		return $ret;
1788	}
1789
1790
1791	/**
1792	 * Compile Array Structure
1793	 */
1794	public function compile(&$inArray, &$outArray, $pid = 0)
1795	{
1796	    if(!is_array($inArray) || !is_array($outArray)){ return null; }
1797
1798	    $frm = e107::getForm();
1799
1800	    foreach($inArray as $key => $val)
1801	    {
1802	        if($val['link_parent'] == $pid)
1803	        {
1804	            $val['link_sub'] = $this->isDynamic($val);
1805
1806	            if(empty($val['link_identifier']) && !empty($val['link_function']))
1807	            {
1808	                $val['link_identifier'] = $frm->name2id($val['link_function']);
1809	            }
1810				// prevent loop of death
1811	            if( $val['link_id'] != $pid) $this->compile($inArray, $val['link_sub'], $val['link_id']);
1812	            $outArray[] = $val;
1813	        }
1814	    }
1815		return $outArray;
1816	}
1817
1818
1819	/**
1820	 * Check for Dynamic Function
1821	 * @example class:method($parm)
1822	 */
1823	protected function isDynamic($row)
1824	{
1825		if(varset($row['link_sub']))
1826		{
1827			return $row['link_sub'];
1828		}
1829
1830		if(!empty($row['link_function']))
1831		{
1832			$parm = false;
1833
1834			list($path,$method) = explode("::",$row['link_function']);
1835
1836			if($path === 'theme')
1837			{
1838				$text = e107::callMethod('theme_shortcodes',$method, $row); // no parms as theme_shortcodes may be added as needed.
1839
1840				if(!empty($text))
1841				{
1842					return '<div class="dropdown-menu">'.$text.'</div>'; // @todo use template?
1843				}
1844
1845				e107::getDebug()->log("Theme shortcode (".$method.") could not be found for use in sitelink");
1846				return array();
1847			}
1848
1849			if(strpos($method,"("))
1850			{
1851				list($method,$prm) = explode("(",$method);
1852				$parm = rtrim($prm,")");
1853			}
1854
1855			if(!file_exists(e_PLUGIN.$path."/e_sitelink.php"))
1856			{
1857
1858			}
1859
1860
1861			if(include_once(e_PLUGIN.$path."/e_sitelink.php"))
1862			{
1863				$class = $path."_sitelink";
1864				if($sublinkArray = e107::callMethod($class,$method,$parm,$row)) //TODO Cache it.
1865				{
1866					return $sublinkArray;
1867				}
1868			}
1869		}
1870
1871		return array();
1872	}
1873
1874	/**
1875	* TODO Extensive Active Link Detection;
1876	*
1877	*/
1878	public function isActive(&$data=array(), $removeOnly = false, $exactMatch = false)
1879	{
1880		if(empty($data)) return null;
1881
1882
1883		### experimental active match added to the URL (and removed after parsing)
1884		### Example of main link: {e_BASE}some/url/#?match/string1^match/string2
1885		### It would match http://your.domain/match/string/ or http://your.domain/match/string2?some=vars
1886		### '#?' is the alternate active check trigger
1887		if(strpos($data['link_url'], '#?') !== false)
1888		{
1889			if($removeOnly)
1890			{
1891			    $arr = explode('#?', $data['link_url'], 2);
1892				$data['link_url'] = array_shift($arr);
1893				return null;
1894			}
1895
1896			$_temp = explode('#?', $data['link_url'], 2);
1897			$data['link_url'] = $_temp[0] ? $_temp[0] : '#';
1898			$matches = explode('^', $_temp[1]);
1899			foreach ($matches as $match)
1900			{
1901				if(strpos(e_REQUEST_URL, $match) !== false)
1902				{
1903					return true;
1904				}
1905			}
1906		}
1907
1908		// No need of further checks
1909		if($removeOnly) return null;
1910
1911		// already checked by compile() or external source
1912		if(isset($data['link_active'])) return $data['link_active'];
1913
1914		$dbLink = e_HTTP. e107::getParser()->replaceConstants($data['link_url'], TRUE, TRUE);
1915	//	$dbLink =  e107::getParser()->replaceConstants($data['link_url'], TRUE, TRUE);
1916
1917		$dbLink = str_replace("//","/",$dbLink); // precaution for e_HTTP inclusion above.
1918
1919		if(!empty($data['link_owner']) && !empty($data['link_sefurl']))
1920		{
1921			$dbLink = e107::url($data['link_owner'],$data['link_sefurl']);
1922		}
1923
1924		if(E107_DBG_PATH)
1925		{
1926		//	e107::getDebug()->log("db=".$dbLink."<br />url=".e_REQUEST_URI."<br /><br />");
1927		}
1928
1929		if($exactMatch)
1930		{
1931			if(e_REQUEST_URI == $dbLink) return true;
1932		}
1933		// XXX this one should go soon - no cotroll at all
1934		elseif(e_REQUEST_HTTP == $dbLink)
1935		{
1936			return true;
1937		}
1938		elseif(e_REQUEST_HTTP."index.php" == $dbLink)
1939		{
1940			return true;
1941		}
1942
1943		if(!empty($data['link_active'])) // Can be used by e_sitelink.php
1944		{
1945			return true;
1946		}
1947
1948
1949		// XXX Temporary Fix - TBD.
1950		// Set the URL matching in the page itself. see: forum_viewforum.php and forum_viewtopic.php
1951		if(defined("NAVIGATION_ACTIVE") && empty($data['link_sub']))
1952		{
1953			if(strpos($data['link_url'], NAVIGATION_ACTIVE)!==false)
1954			{
1955				return true;
1956			}
1957		}
1958
1959
1960		return false;
1961	}
1962}
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974/**
1975 * Navigation Shortcodes
1976 * @todo SEF
1977 */
1978class navigation_shortcodes extends e_shortcode
1979{
1980
1981	public $template;
1982	public $counter;
1983	public $active;
1984	public $depth = 0;
1985
1986
1987	/**
1988	 *
1989	 * @return string 'active' on the active link.
1990	 * @example {LINK_ACTIVE}
1991	 */
1992	function sc_link_active($parm='')
1993	{
1994		if($this->active == true)
1995		{
1996			return 'active';
1997		}
1998
1999		// check if it's the first link.. (eg. anchor mode) and nothing activated.
2000		return ($this->counter ==1) ? 'active' : '';
2001
2002	}
2003
2004	/**
2005	 * Return the primary_id number for the current link
2006	 * @return integer
2007	 */
2008	function sc_link_id($parm=null)
2009	{
2010		return intval($this->var['link_id']);
2011	}
2012
2013	function sc_link_depth($parm=null)
2014	{
2015		unset($parm);
2016		return isset($this->var['link_depth']) ? intval($this->var['link_depth']) : $this->depth;
2017	}
2018
2019
2020	function setDepth($val)
2021	{
2022		$this->depth = intval($val);
2023	}
2024
2025
2026	/**
2027	 * Return the name of the current link
2028	 * @return string
2029	 * @example {LINK_NAME}
2030	 */
2031	function sc_link_name($parm=null)
2032	{
2033		if(empty($this->var['link_name']))
2034		{
2035			return null;
2036		}
2037
2038		if(substr($this->var['link_name'],0,8) == 'submenu.') // BC Fix.
2039		{
2040			list($tmp,$tmp2,$link) = explode('.',$this->var['link_name'],3);
2041			unset($tmp,$tmp2);
2042		}
2043		else
2044		{
2045			$link = $this->var['link_name'];
2046		}
2047
2048		return e107::getParser()->toHTML($link, false,'defs');
2049	}
2050
2051
2052	/**
2053	 * Return the parent of the current link
2054	 * @return integer
2055	 */
2056	function sc_link_parent($parm=null)
2057	{
2058		return intval($this->var['link_parent']);
2059	}
2060
2061
2062	function sc_link_identifier($parm=null)
2063	{
2064		return isset($this->var['link_identifier']) ? $this->var['link_identifier'] : '';
2065	}
2066
2067	/**
2068	 * Return the URL of the current link
2069	 * @return string
2070	 */
2071	function sc_link_url($parm=null)
2072	{
2073		$tp = e107::getParser();
2074
2075		if(!empty($this->var['link_owner']) && !empty($this->var['link_sefurl']))
2076		{
2077			return e107::url($this->var['link_owner'],$this->var['link_sefurl']);
2078		}
2079
2080		if(strpos($this->var['link_url'], e_HTTP) === 0)
2081		{
2082			$url = "{e_BASE}".substr($this->var['link_url'], strlen(e_HTTP));
2083		}
2084		elseif($this->var['link_url'][0] != "{" && strpos($this->var['link_url'],"://")===false)
2085		{
2086			$url = "{e_BASE}".$this->var['link_url']; // Add e_BASE to links like: 'news.php' or 'contact.php'
2087		}
2088		else
2089		{
2090			$url = $this->var['link_url'];
2091		}
2092
2093		$url = $tp->replaceConstants($url, 'full', TRUE);
2094
2095		if(strpos($url,"{") !== false)
2096		{
2097           $url = $tp->parseTemplate($url, TRUE); // BC Fix shortcode in URL support - dynamic urls for multilanguage.
2098        }
2099
2100		return $url;
2101	}
2102
2103/*
2104	function sc_link_sub_oversized($parm='')
2105	{
2106		$count = count($this->var['link_sub']);
2107
2108		if(!empty($parm) && $count > $parm)
2109		{
2110			return 'oversized';
2111		}
2112
2113		return $count;
2114
2115	}
2116*/
2117
2118	/**
2119	 * Returns only the anchor target in the URL if one is found.
2120	 * @param array $parm
2121	 * @return null|string
2122	 */
2123	function sc_link_target($parm=null)
2124	{
2125		if(strpos($this->var['link_url'],'#')!==false)
2126		{
2127			list($tmp,$segment) = explode('#',$this->var['link_url'],2);
2128			return '#'.$segment;
2129
2130		}
2131
2132		return '#';
2133	}
2134
2135
2136
2137	function sc_link_open($parm = '')
2138	{
2139		$type = $this->var['link_open'] ? (int) $this->var['link_open'] : 0;
2140
2141		### 0 - same window, 1 - target blank, 4 - 600x400 popup, 5 - 800x600 popup
2142		### TODO - JS popups (i.e. bootstrap)
2143		switch($type)
2144		{
2145			case 1:
2146				return ' target="_blank"';
2147			break;
2148
2149			case 4:
2150				return " onclick=\"open_window('".$this->var['link_url']."',600,400); return false;\"";
2151			break;
2152
2153			case 5:
2154				return " onclick=\"open_window('".$this->var['link_url']."',800,600); return false;\"";
2155			break;
2156		}
2157		return '';
2158	}
2159
2160	/**
2161	 * @Deprecated - Use {LINK_ICON} instead.
2162	 */
2163	function sc_link_image($parm='')
2164	{
2165		e107::getMessage()->addDebug("Using deprecated shortcode: {LINK_IMAGE} - use {LINK_ICON} instead.");
2166		return $this->sc_link_icon($parm);
2167	}
2168
2169
2170	/**
2171	 * Return the link icon of the current link
2172	 * @return string
2173	 */
2174	function sc_link_icon($parm='')
2175	{
2176		$tp = e107::getParser();
2177
2178		if (empty($this->var['link_button'])) return '';
2179
2180	//	if($icon = $tp->toGlyph($this->var['link_button']))
2181	//	{
2182	//		return $icon;
2183	//	}
2184	//	else
2185		{
2186			//$path = e107::getParser()->replaceConstants($this->var['link_button'], 'full', TRUE);
2187			return $tp->toIcon($this->var['link_button'],array('fw'=>true, 'space'=>' ', 'legacy'=>"{e_IMAGE}icons/"));
2188			// return "<img class='icon' src='".$path."' alt=''  />";
2189		}
2190
2191	}
2192
2193
2194	/**
2195	 * Return the link description of the current link
2196	 * @return string
2197	 */
2198	function sc_link_description($parm='')
2199	{
2200		$toolTipEnabled = e107::pref('core', 'linkpage_screentip', false);
2201
2202		if($toolTipEnabled == false || empty($this->var['link_description']))
2203		{
2204			return null;
2205		}
2206
2207
2208		return e107::getParser()->toAttribute($this->var['link_description']);
2209	}
2210
2211
2212	/**
2213	 * Return the parsed sublinks of the current link
2214	 * @return string
2215	 */
2216	function sc_link_sub($parm='')
2217	{
2218		if(empty($this->var['link_sub']))
2219		{
2220			return false;
2221		}
2222
2223		if(is_string($this->var['link_sub'])) // html override option.
2224		{
2225
2226		//	e107::getDebug()->log($this->var);
2227
2228			return $this->var['link_sub'];
2229		}
2230
2231		$this->depth++;
2232		// Assume it's an array.
2233
2234		$startTemplate = !empty($this->var['link_sub'][0]['link_sub']) && isset($this->template['submenu_lowerstart']) ? $this->template['submenu_lowerstart'] : $this->template['submenu_start'];
2235		$endTemplate = !empty($this->var['link_sub'][0]['link_sub']) && isset($this->template['submenu_lowerstart']) ? $this->template['submenu_lowerend'] :  $this->template['submenu_end'];
2236
2237		$text = e107::getParser()->parseTemplate(str_replace('{LINK_SUB}', '', $startTemplate), true, $this);
2238
2239		foreach($this->var['link_sub'] as $val)
2240		{
2241			$active	= (e107::getNav()->isActive($val, $this->activeSubFound, true)) ? "_active" : "";
2242
2243			$this->setVars($val);	// isActive is allowed to alter data
2244			$tmpl = !empty($val['link_sub']) ? varset($this->template['submenu_loweritem'.$active]) : varset($this->template['submenu_item'.$active]);
2245			$text .= e107::getParser()->parseTemplate($tmpl, TRUE, $this);
2246			if($active) $this->activeSubFound = true;
2247		}
2248
2249		$text .= e107::getParser()->parseTemplate(str_replace('{LINK_SUB}', '', $endTemplate), true, $this);
2250
2251		return $text;
2252	}
2253
2254	/**
2255	 * Return a generated anchor for the current link.
2256	 * @param unused
2257	 * @return	string - a generated anchor for the current link.
2258	 * @example {LINK_ANCHOR}
2259	 */
2260	function sc_link_anchor($parm='')
2261	{
2262		return $this->var['link_name'] ? '#'.e107::getForm()->name2id($this->var['link_name']) : '';
2263	}
2264}
2265