Andrew's Web Libraries (AWL)
Loading...
Searching...
No Matches
MenuSet.php
1<?php
14
15require_once("AWLUtilities.php");
16
29 var $label;
30
35 var $target;
36
41 var $title;
42
47 var $active;
48
53 var $sortkey;
54
59 var $style;
60
65 var $submenu_set;
67
72 var $attributes;
73
78 var $self;
79
87 var $rendered;
89
98 function __construct( $label, $target, $title="", $style="menu", $sortkey=1000 ) {
99 $this->label = $label;
100 $this->target = $target;
101 $this->title = $title;
102 $this->style = $style;
103 $this->attributes = array();
104 $this->active = false;
105 $this->sortkey = $sortkey;
106
107 $this->rendered = "";
108 $this->self =& $this;
109 }
110
115 function Render( ) {
116 $r = sprintf('<a href="%s" class="%s" title="%s"%s>%s</a>',
117 $this->target, $this->style, htmlspecialchars($this->title), "%%attributes%%",
118 htmlspecialchars($this->label), $this->style );
119
120 // Now process the generic attributes
121 $attribute_values = "";
122 foreach( $this->attributes AS $k => $v ) {
123 if ( substr($k, 0, 1) == '_' ) continue;
124 $attribute_values .= ' '.$k.'="'.htmlspecialchars($v).'"';
125 }
126 $r = str_replace( '%%attributes%%', $attribute_values, $r );
127
128 $this->rendered = $r;
129 return "$r";
130 }
131
137 function Set( $attribute, $value ) {
138 $this->attributes[$attribute] = $value;
139 }
140
145 function Active( $style=false ) {
146 $this->active = true;
147 if ( $style ) $this->style = $style;
148 }
149
153 function AddSubmenu( &$submenu_set ) {
154 $this->submenu_set = &$submenu_set;
155 }
156
161 function IsActive( ) {
162 return ( $this->active );
163 }
164
169 function MaybeActive( $test_pattern, $active_style ) {
170 if ( is_string($test_pattern) && preg_match($test_pattern,$_SERVER['REQUEST_URI']) ) {
171 $this->Active($active_style);
172 }
173 return ( $this->active );
174 }
175}
176
177
185function _CompareMenuSequence( $a, $b ) {
186 dbg_error_log("MenuSet", ":_CompareMenuSequence: Comparing %d with %d", $a->sortkey, $b->sortkey);
187 return ($a->sortkey - $b->sortkey);
188}
189
190
191
228class MenuSet {
236 var $div_id;
237
242 var $main_class;
243
248 var $active_class;
249
254 var $options;
255
260 var $parent;
261
266 var $last_sortkey;
267
273 var $has_active_options;
275
282 function __construct( $div_id, $main_class = '', $active_class = 'active' ) {
283 $this->options = array();
284 $this->main_class = $main_class;
285 $this->active_class = $active_class;
286 $this->div_id = $div_id;
287 }
288
301 function &AddOption( $label, $target, $title="", $active=false, $sortkey=null, $external=false ) {
302 if ( !isset($sortkey) ) {
303 $sortkey = (isset($this->last_sortkey) ? $this->last_sortkey + 100 : 1000);
304 }
305 $this->last_sortkey = $sortkey;
306 if ( version_compare(phpversion(), '5.0') < 0) {
307 $new_option = new MenuOption( $label, $target, $title, $this->main_class, $sortkey );
308 }
309 else {
310 $new_option = new MenuOption( $label, $target, $title, $this->main_class, $sortkey );
311 }
312 if ( ($old_option = $this->_OptionExists( $label )) === false ) {
313 $this->options[] = &$new_option ;
314 }
315 else {
316 dbg_error_log("MenuSet",":AddOption: Replacing existing option # $old_option ($label)");
317 $this->options[$old_option] = &$new_option; // Overwrite the existing option
318 }
319 if ( is_bool($active) && $active == false && $_SERVER['REQUEST_URI'] == $target ) {
320 // If $active is not set, then we look for an exact match to the current URL
321 $new_option->Active( $this->active_class );
322 }
323 else if ( is_bool($active) && $active ) {
324 // When active is specified as a boolean, the recognition has been done externally
325 $new_option->Active( $this->active_class );
326 }
327 else if ( is_string($active) && preg_match($active,$_SERVER['REQUEST_URI']) ) {
328 // If $active is a string, then we match the current URL to that as a Perl regex
329 $new_option->Active( $this->active_class );
330 }
331
332 if ( $external == true ) $new_option->Set('target', '_blank');
333
334 return $new_option ;
335 }
336
347 function &AddSubMenu( &$submenu_set, $label, $target, $title="", $active=false, $sortkey=2000 ) {
348 $new_option =& $this->AddOption( $label, $target, $title, $active, $sortkey );
349 $submenu_set->parent = &$new_option ;
350 $new_option->AddSubmenu( $submenu_set );
351 return $new_option ;
352 }
353
360 function _HasActive( ) {
361 if ( isset($this->has_active_options) ) {
362 return $this->has_active_options;
363 }
364 foreach( $this->options AS $k => $v ) {
365 if ( $v->IsActive() ) {
366 $rc = true;
367 return $rc;
368 }
369 }
370 $rc = false;
371 return $rc;
372 }
373
378 function Size( ) {
379 return count($this->options);
380 }
381
386 function _OptionExists( $newlabel ) {
387 $rc = false;
388 foreach( $this->options AS $k => $v ) {
389 if ( $newlabel == $v->label ) return $k;
390 }
391 return $rc;
392 }
393
401 function LinkActiveSubMenus( ) {
402 $this->has_active_options = false;
403 foreach( $this->options AS $k => $v ) {
404 if ( isset($v->submenu_set) && $v->submenu_set->_HasActive() ) {
405 // Note that we need to do it this way, since $v is a copy, not a reference
406 $this->options[$k]->Active( $this->active_class );
407 $this->has_active_options = true;
408 }
409 }
410 }
411
419 function MakeSomethingActive( $test_pattern ) {
420 if ( $this->has_active_options ) return; // Already true.
421 foreach( $this->options AS $k => $v ) {
422 if ( isset($v->submenu_set) && $v->submenu_set->_HasActive() ) {
423 // Note that we need to do it this way, since $v is a copy, not a reference
424 $this->options[$k]->Active( $this->active_class );
425 $this->has_active_options = true;
426 return $this->has_active_options;
427 }
428 }
429
430 foreach( $this->options AS $k => $v ) {
431 if ( isset($v->submenu_set) && $v->submenu_set->MakeSomethingActive($test_pattern) ) {
432 // Note that we need to do it this way, since $v is a copy, not a reference
433 $this->options[$k]->Active( $this->active_class );
434 $this->has_active_options = true;
435 return $this->has_active_options;
436 }
437 else {
438 if ( $this->options[$k]->MaybeActive( $test_pattern, $this->active_class ) ) {
439 $this->has_active_options = true;
440 return $this->has_active_options;
441 }
442 }
443 }
444 return false;
445 }
446
454 function _CompareSequence( $a, $b ) {
455 dbg_error_log("MenuSet",":_CompareSequence: Comparing %d with %d", $a->sortkey, $b->sortkey);
456 return ($a->sortkey - $b->sortkey);
457 }
458
459
468 function Render( $submenus_inline = false ) {
469 if ( !isset($this->has_active_options) ) {
470 $this->LinkActiveSubMenus();
471 }
472 $options = $this->options;
473 usort($options,"_CompareMenuSequence");
474 $render_sub_menus = false;
475 $r = "<div id=\"$this->div_id\">\n";
476 foreach( $options AS $k => $v ) {
477 $r .= $v->Render();
478 if ( $v->IsActive() && isset($v->submenu_set) && $v->submenu_set->Size() > 0 ) {
479 $render_sub_menus = $v->submenu_set;
480 if ( $submenus_inline )
481 $r .= $render_sub_menus->Render();
482 }
483 }
484 $r .="</div>\n";
485 if ( !$submenus_inline && $render_sub_menus != false ) {
486 $r .= $render_sub_menus->Render();
487 }
488 return $r;
489 }
490
491
500 function RenderAsCSS( $depth = 0, $skip_empty = true ) {
501 $this->LinkActiveSubMenus();
502
503 if ( $depth > 0 )
504 $class = "submenu" . $depth;
505 else
506 $class = "menu";
507
508 $options = $this->options;
509 usort($options,"_CompareMenuSequence");
510
511 $r = "<div id=\"$this->div_id\" class=\"$class\">\n<ul>\n";
512 foreach( $options AS $k => $v ) {
513 if ( $skip_empty && isset($v->submenu_set) && $v->submenu_set->Size() < 1 ) continue;
514 $r .= "<li>".$v->Render();
515 if ( isset($v->submenu_set) && $v->submenu_set->Size() > 0 ) {
516 $r .= $v->submenu_set->RenderAsCSS($depth+1);
517 }
518 $r .= "</li>\n";
519 }
520 $r .="</ul></div>\n";
521 return $r;
522 }
523}
__construct( $label, $target, $title="", $style="menu", $sortkey=1000)
Definition MenuSet.php:98
MaybeActive( $test_pattern, $active_style)
Definition MenuSet.php:169
AddSubmenu(&$submenu_set)
Definition MenuSet.php:153
Active( $style=false)
Definition MenuSet.php:145
Set( $attribute, $value)
Definition MenuSet.php:137