PageRenderTime 117ms CodeModel.GetById 60ms app.highlight 30ms RepoModel.GetById 20ms app.codeStats 1ms

/lib/webgets/menu.php

https://bitbucket.org/navigatecms/navigatecms
PHP | 637 lines | 460 code | 108 blank | 69 comment | 97 complexity | 63117a5ff5f65c50221f077d4608714b MD5 | raw file
  1<?php
  2nvweb_webget_load('properties');
  3
  4function nvweb_menu($vars=array())
  5{
  6	global $website;
  7	global $DB;
  8	global $structure;
  9	global $current;
 10
 11	$out = '';
 12
 13	nvweb_menu_load_dictionary();
 14	nvweb_menu_load_routes();	
 15	nvweb_menu_load_structure();
 16	nvweb_menu_load_actions();
 17	
 18	$parent = intval(@$vars['parent']) + 0;
 19	$from = intval(@$vars['from']) + 0;
 20	$of	= intval(@$vars['of']) + 0;
 21
 22    if(isset($vars['parent']) && !is_numeric($vars['parent']))
 23    {
 24        // assume parent attribute contains a property_id which has the category value
 25        $parent_property = nvweb_properties(array(
 26            'property' => $vars['parent']
 27        ));
 28        if(!empty($parent_property))
 29            $parent = $parent_property;
 30    }
 31
 32	if($of > 0)
 33	{
 34		// get options of the parent x in the order of the structure
 35		// example:
 36		//	Home [5]	Products [6]	Contact [7]
 37		//					|
 38		//					-- Computers [8]	Mobile Phones [9]
 39		//							|
 40		//							-- Apple [10]	Dell [11]
 41		//
 42		//	we want the categories under Products [6]: "Computers" [8] and "Mobile Phones" [9]
 43		//	of: 2 (second item in the main structure)
 44		//  <nv object="nvweb" name="menu" of="2" />
 45		$parent = $structure['cat-0'][intval($of)-1]->id;
 46	}
 47
 48    if(empty($current['hierarchy']))	// calculate
 49    {
 50        $inverse_hierarchy = array();
 51        // discover the parent from which get the menu
 52        if(!empty($current['category']))
 53        {
 54            $inverse_hierarchy[] = $current['category'];
 55            $last = $current['category'];
 56        }
 57        else
 58        {
 59            $inverse_hierarchy[] = $current['object']->category;
 60            $last = $current['object']->category;
 61        }
 62
 63        // get category parents until root (to know how many levels count from)
 64        while($last > 0)
 65        {
 66            $last = $DB->query_single('parent', 'nv_structure', ' id = '.protect($last));
 67            $inverse_hierarchy[] = $last;
 68        }
 69        $current['hierarchy'] = array_reverse($inverse_hierarchy);
 70    }
 71
 72	if($from > 0)
 73	{
 74		// get a certain level of the menu based on the path to current item category with offset 
 75		// example:
 76		//	Home [5]	Products [6]	Contact [7]
 77		//					|
 78		//					-- Computers [8]	Mobile Phones [9]
 79		//							|
 80		//							-- Apple [10]	Dell [11]
 81		//
 82		//	current item is a Dell computer (category = 11)
 83		//  we want the menu from level 1
 84		//	from: 1	--> 8, 9		
 85		$parent = $current['hierarchy'][$from];
 86
 87		if(is_null($parent)) return '';	// the requested level of menu does not exist under the current category
 88	}
 89
 90	$option = -1;	
 91	if(isset($vars['option']))
 92		$option = intval($vars['option']);
 93
 94    if($vars['mode']=='next' || $vars['mode']=='previous')
 95        $out = nvweb_menu_render_arrow($vars);
 96    else
 97    {
 98        $out = nvweb_menu_generate($vars['mode'], $vars['levels'], $parent, 0, $option, $vars['class']);
 99
100        if($vars['mode'] == 'select')
101        {
102            nvweb_after_body('js', '
103                // jQuery required
104                $("select.menu_level_0").off("change").on("change", function()
105                {
106                    var option = $(this).find("option[value=" + $(this).val() + "]");
107                    if($(option).attr("target") == "_blank")
108                        window.open($(option).attr("href"));
109                    else
110                    {
111                        if($(option).attr("href")=="#")
112                            window.location.replace($(option).attr("href") + "sid_" + $(option).attr("value"));
113                        else
114                            window.location.replace($(option).attr("href"));
115                    }
116                });
117            ');
118        }
119    }
120
121	return $out;
122}
123
124function nvweb_menu_generate($mode='ul', $levels=0, $parent=0, $level=0, $option=-1, $class='')
125{
126	global $structure;
127	global $current;
128
129	$out = '';
130
131	if($level >= $levels && $levels > 0)
132        return '';
133	
134	nvweb_menu_load_structure($parent);
135
136	if(!empty($structure['cat-'.$parent]))
137	{	
138		switch($mode)
139		{
140            case 'category_title':
141			case 'current_title':
142                if($current['type']=='structure')
143				    $out = $structure['dictionary'][$current['category']];
144                else if($current['type']=='item')
145                    $out = $structure['dictionary'][$current['object']->category];
146				break;
147
148            case 'category_link':
149            case 'category_url':
150                if($current['type']=='structure')
151                    $out = nvweb_source_url('structure', $current['category']);
152                else if($current['type']=='item')
153                    $out = nvweb_source_url('structure', $current['object']->category);
154                else
155                    $out = '#';
156                break;
157			
158			case 'a':
159				$out[] = '<div class="menu_level_'.$level.' '.$class.'">';	
160				for($m=0; $m < count($structure['cat-'.$parent]); $m++)
161				{
162					if(!nvweb_object_enabled($structure['cat-'.$parent][$m]))
163                        continue;
164
165					if($structure['cat-'.$parent][$m]->visible == 0)
166                        continue;
167
168					$mid = $structure['cat-'.$parent][$m]->id;
169
170                    // hide menu items without a title
171                    if(empty($structure['dictionary'][$mid]))
172                        continue;
173
174					$aclass = '';
175                    if(in_array($mid, $current['hierarchy']))
176						$aclass = ' class="menu_option_active"';
177					$out[] = '<a'.$aclass.' '.nvweb_menu_action($mid).'>'.$structure['dictionary'][$mid].'</a>';
178					if($option==$m)
179						return array_pop($out);
180
181                    $out[] = nvweb_menu_generate($mode, $levels, $mid, $level+1);
182				}
183				$out[] = '</div>';		
184				$out = implode("\n", $out);	
185				break;
186
187            case 'select':
188                $out[] = '<select class="menu_level_'.$level.' '.$class.'">';
189                for($m=0; $m < count($structure['cat-'.$parent]); $m++)
190                {
191                    if(!nvweb_object_enabled($structure['cat-'.$parent][$m]))
192                        continue;
193
194                    if($structure['cat-'.$parent][$m]->visible == 0)
195                        continue;
196
197                    $mid = $structure['cat-'.$parent][$m]->id;
198
199                    // hide menu items without a title
200                    if(empty($structure['dictionary'][$mid]))
201                        continue;
202
203                    $aclass = '';
204                    if(in_array($mid, $current['hierarchy']))
205                        $aclass = ' class="menu_option_active" selected="selected"';
206
207                    $target = '';
208                    $act = nvweb_menu_action($mid, NULL, false, false);
209                    if(strpos($act, 'target="_blank"')!==false)
210                        $target = 'target="_blank"';
211                    if(strpos($act, 'onclick')!==false)
212                        $act = '#';
213
214                    $act = str_replace('target="_blank"', '', $act);
215                    $act = str_replace('data-sid', 'data_sid', $act);
216                    $act = str_replace('href="', '', $act);
217                    $act = str_replace('"', '', $act);
218                    $act = trim($act);
219
220                    $out[] = '<option'.$aclass.' value="'.$mid.'" href="'.$act.'" '.$target.'>'
221                             .$structure['dictionary'][$mid]
222                             .'</option>';
223
224                    if($option==$m)
225                        return array_pop($out);
226
227                    $submenu = nvweb_menu_generate($mode, $levels, $mid, $level+1);
228                    $submenu = strip_tags($submenu, '<option>');
229
230                    $parts = explode('>', $submenu);
231                    $submenu = '';
232                    for($p=0; $p < count($parts); $p++)
233                    {
234                        if(strpos($parts[$p], '</option')!==false)
235                            $parts[$p] = '&ndash;&nbsp;'.$parts[$p];
236                    }
237                    $submenu = implode('>', $parts);
238
239                    $out[] = $submenu;
240                }
241                $out[] = '</select>';
242                $out = implode("\n", $out);
243                break;
244	
245			default:
246			case 'ul':
247                $ul_items = 0;
248				$out[] = '<ul class="menu_level_'.$level.' '.$class.'">';
249
250				for($m=0; $m < count($structure['cat-'.$parent]); $m++)
251				{
252					if(!nvweb_object_enabled($structure['cat-'.$parent][$m]))
253                        continue;
254
255                    if($structure['cat-'.$parent][$m]->visible == 0)
256                        continue;
257
258					$mid = $structure['cat-'.$parent][$m]->id;
259
260                    // hide menu items without a title
261                    if(empty($structure['dictionary'][$mid]))
262                        continue;
263
264                    $aclass = '';
265					if(in_array($mid, $current['hierarchy']))
266						$aclass = ' class="menu_option_active"';
267
268					$out[] = '<li'.$aclass.'>';
269					$out[] = '<a'.$aclass.' '.nvweb_menu_action($mid).'>'.$structure['dictionary'][$mid].'</a>';
270					if($option==$m)
271						return array_pop($out);					
272					$out[] = nvweb_menu_generate($mode, $levels, $mid, $level+1);
273					$out[] = '</li>';
274                    $ul_items++;
275				}
276                $out[] = '</ul>';
277                if($ul_items==0) // no option found, remove the last two lines (<ul> and </ul>)
278                {
279                    array_pop($out);
280                    array_pop($out);
281                }
282				$out = implode("\n", $out);			
283				break;
284		}
285	}
286
287	return $out;
288	
289}
290
291function nvweb_menu_action($id, $force_type=NULL, $use_javascript=true, $include_datasid=true)
292{
293	global $structure; 
294	global $current;
295	
296	$type = $structure['actions'][$id]['action-type'];
297		
298	if(!empty($force_type))
299		$type = $force_type;
300	
301	switch($type)
302	{
303		case 'url':
304			$url = $structure['routes'][$id];
305			if(empty($url))
306            {
307                if($use_javascript)
308				    $url = 'javascript: return false;';
309                else
310                    $url = '#';
311            }
312            else
313                $url = nvweb_prepare_link($url);
314
315			$action = ' href="'.$url.'" ';
316            if($include_datasid)
317                $action.= ' data-sid="'.$id.'" ';
318			break;
319			
320		case 'jump-branch':
321			// we force only one jump to avoid infinite loops (caused by user mistake)
322			$action = nvweb_menu_action($structure['actions'][$id]['action-jump-branch'], 'url');
323			break;
324			
325		case 'jump-item':
326			$url = nvweb_source_url('item', $structure['actions'][$id]['action-jump-item'], $current['lang']);
327			if(empty($url))
328            {
329                if($use_javascript)
330                    $url = 'javascript: return false;';
331                else
332                    $url = '#';
333            }
334			else
335                $url = nvweb_prepare_link($url);
336			$action = ' href="'.$url.'" ';
337            if($include_datasid)
338                $action.= ' data-sid="'.$id.'" ';
339			break;
340			
341		case 'do-nothing':
342			$action = ' href="#" onclick="javascript: return false;" ';
343            if($include_datasid)
344                $action.= ' data-sid="'.$id.'" ';
345			break;
346			
347		default:
348			// Navigate CMS < 1.6.5 compatibility [deprecated]
349            // will be removed by 1.7
350			$url = $structure['routes'][$id];
351			if(substr($url, 0, 7)=='http://' || substr($url, 0, 7)=='https://')
352            {
353                $action = ' href="'.$url.'" target="_blank" ';
354                if($include_datasid)
355                    $action.= ' data-sid="'.$id.'" ';
356				return $action; // ;)
357            }
358			else if(empty($url))
359            {
360                $action = ' href="#" onclick="return false;" ';
361                if($include_datasid)
362                    $action.= ' data-sid="'.$id.'" ';
363				return $action;
364            }
365			else
366            {
367                $action = ' href="'.NVWEB_ABSOLUTE.$url.'"';
368                if($include_datasid)
369                    $action.= ' data-sid="'.$id.'" ';
370				return $action;
371            }
372			break;	
373	}
374	
375	if($structure['actions'][$id]['action-new-window']=='1' && $type!='do-nothing')
376		$action .= ' target="_blank"';
377	
378	return $action;	
379}
380
381function nvweb_menu_load_dictionary()
382{
383	global $DB;	
384	global $structure;
385	global $current;
386	global $website;
387			
388	if(empty($structure['dictionary']))
389	{
390		$structure['dictionary'] = array();
391
392		$DB->query('SELECT node_id, text
393					  FROM nv_webdictionary 
394					 WHERE node_type = "structure"
395					   AND subtype = "title" 
396					   AND lang = '.protect($current['lang']).'
397					   AND website = '.$website->id);		
398					
399		$data = $DB->result();
400		
401		if(!is_array($data)) $data = array();
402		$dictionary = array();
403		
404		foreach($data as $item)
405		{
406			$structure['dictionary'][$item->node_id] = $item->text;
407		}
408	}
409}
410
411function nvweb_menu_load_routes()
412{
413	global $DB;	
414	global $structure;
415	global $current;
416	global $website;
417			
418	if(empty($structure['routes']))
419	{
420		$structure['routes'] = array();
421
422		$DB->query('SELECT object_id, path
423					  FROM nv_paths 
424					 WHERE type = "structure"
425					   AND lang = '.protect($current['lang']).'
426					   AND website = '.$website->id);		
427					
428		$data = $DB->result();
429		
430		if(!is_array($data)) $data = array();
431		$dictionary = array();
432		
433		foreach($data as $item)
434		{
435			$structure['routes'][$item->object_id] = $item->path;
436		}			
437	}
438}
439
440function nvweb_menu_load_actions()
441{
442	global $DB;	
443	global $structure;
444	global $current;
445	global $website;
446			
447	if(empty($structure['actions']))
448	{
449		$structure['actions'] = array();
450		
451
452		$DB->query('SELECT node_id, subtype, text
453					  FROM nv_webdictionary 
454					 WHERE node_type = "structure"
455					   AND lang = '.protect($current['lang']).'
456					   AND subtype IN("action-type", "action-jump-item", "action-jump-branch", "action-new-window")
457					   AND website = '.$website->id);		
458					
459		$data = $DB->result();
460		
461		if(!is_array($data)) $data = array();
462		$dictionary = array();
463		
464		foreach($data as $row)
465		{
466			$structure['actions'][$row->node_id][$row->subtype] = $row->text;
467		}			
468	}
469}
470
471function nvweb_menu_load_structure($parent=0)
472{
473	global $DB;	
474	global $structure;
475	global $website;
476
477	if(!isset($structure['cat-'.$parent]))
478	{
479		$structure['cat-'.$parent] = array();
480		
481		$DB->query('SELECT * 
482					  FROM nv_structure
483					 WHERE parent = '.protect($parent).' 
484					   AND website = '.$website->id.' 
485					  ORDER BY position ASC');
486				  
487		$structure['cat-'.$parent] = $DB->result();
488
489        // parse some result values
490        foreach($structure['cat-'.$parent] as $key => $value)
491        {
492            $value->groups = str_replace('g', '', $value->groups);
493            $value->groups = array_filter(explode(',', $value->groups));
494            $structure[$key] = clone $value;
495        }
496	}
497}
498
499function nvweb_menu_get_children($categories=array(), $sublevels=NULL)
500{
501	global $structure;
502
503	// get all leafs from all categories that are child of the selected ones
504	$categories_count = count($categories);
505
506    $depth = array();
507
508	for($c=0; $c < $categories_count; $c++)
509	{
510		$categories[$c] = trim($categories[$c]);
511		if(empty($categories[$c]) && $categories[$c]!='0') 
512            continue;
513        
514        if(!isset($depth[$categories[$c]]))
515            $depth[$categories[$c]] = 0;
516
517		nvweb_menu_load_structure($categories[$c]);
518
519		for($s=0; $s < count($structure['cat-'.$categories[$c]]); $s++)
520		{
521            $depth[$structure['cat-'.$categories[$c]][$s]->id] = $depth[$categories[$c]] + 1;
522
523            // the current category is beyond the allowed number of sublevels on hierarchy?
524            if(isset($sublevels) && $depth[$structure['cat-'.$categories[$c]][$s]->id] > $sublevels)
525                continue;
526
527			array_push($categories, $structure['cat-'.$categories[$c]][$s]->id);
528		}
529
530		$categories = array_unique($categories); // remove duplicates
531		$categories_count = count($categories);	 // recount elements
532	}
533
534	return $categories;		
535}
536
537function nvweb_menu_render_arrow($vars=array())
538{
539    global $DB;
540    global $structure;
541    global $current;
542    global $website;
543
544    $out = '';
545    $char = $vars['character'];
546    $link = '';
547    $title = '';
548    $previous = null;
549    $next = null;
550    $parent = null;
551
552    // look for the category before and after the current one
553
554    if($current['type']=='structure')
555        $parent = $current['object']->parent;
556    else if($current['category'] > 0)
557        $parent = $current['hierarchy'][count($current['category'])-1];
558
559    // if we have found the parent
560    // AND
561    // if the "from" option is not empty AND the number of levels until the current category is greater than "from"
562    if( $parent >= 0 &&
563        (!empty($vars['from']) && count($current['hierarchy']) >= $vars['from']))
564    {
565        nvweb_menu_load_structure($parent);
566
567        for($c=0; $c < count($structure['cat-'.$parent]); $c++)
568        {
569            if($structure['cat-'.$parent][$c]->id == $current['category'])
570            {
571                if(isset($structure['cat-'.$parent][$c-1]))
572                    $previous = $structure['cat-'.$parent][$c-1]->id;
573
574                if(isset($structure['cat-'.$parent][$c+1]))
575                    $next = $structure['cat-'.$parent][$c+1]->id;
576
577                break;
578            }
579        }
580
581        // TO DO: look for previous and next categories from the parent's brothers
582        /*
583        if(empty($previous))
584        {
585            // we have not found a PREVIOUS structure entry in the same level of the current category
586            // we may look for the last child of the parent brother... example
587            /*
588             *  ROOT
589             *      1
590             *      2
591             *        2.1
592             *          2.1.1
593             *          2.1.2
594             *        2.2
595             *          2.2.1 <- current category
596             *          2.2.2
597             *        2.3
598             *          2.3.1
599             *      3
600             *
601             *  in this example, the previous category of 2.2.1 is 2.1.2
602             *  if the current category is 2.2.2, the next one will be the children of the next parent, so, 2.3.1
603             */
604        /*
605        }
606        /*
607        if(empty($next))
608        {
609
610        }
611        */
612
613        if($vars['mode']=='next' && !empty($next))
614        {
615            if(empty($char))
616                $char = '&gt;';
617
618            $link = $structure['routes'][$next];
619            $title = $structure['dictionary'][$next];
620        }
621        else if($vars['mode']=='previous' && !empty($previous))
622        {
623            if(empty($char))
624                $char = '&lt;';
625
626            $link = $structure['routes'][$previous];
627            $title = $structure['dictionary'][$previous];
628        }
629
630        if(!empty($link))
631            $out = '<a href="'.$link.'" title="'.$title.'">'.$char.'</a>';
632    }
633
634    return $out;
635}
636
637?>