We are unlikely to be sending XHTML, or want to be.
[adorno.git] / inc / MenuClass.php
blob6733a08673723f6ba3212f85989a97648dbb77c5
1 <?php
3 /////////////////////////////////////////////////////////////
4 // C L A S S F O R M E N U T H I N G S //
5 /////////////////////////////////////////////////////////////
6 class MenuOption {
7 var $label; // The label for the menu item
8 var $target; // The target URL for the menu
9 var $title; // The title for the itme when moused over
10 var $active; // Whether the menu option is active
11 var $sortkey; // For sorting menu options
12 var $style; // Style to render it
13 var $submenu_set; // The MenuSet that this menu is a parent of
14 var $rendered; // Once it actually is...
16 // The thing we click
17 function MenuOption( $label, $target, $title="", $style="menu", $sortkey=0 ) {
18 $this->label = $label;
19 $this->target = $target;
20 $this->title = $title;
21 $this->style = $style;
22 $this->attributes = array();
23 $this->active = false;
25 $this->rendered = "";
27 return $this;
30 // Gimme the HTML
31 function Render( ) {
32 $r = sprintf('<span class="%s_left"></span><a href="%s" class="%s" title="%s"%s>%s</a><span class="%s_right"></span>',
33 $this->style, $this->target, $this->style, htmlentities($this->title), "%%attributes%%",
34 htmlentities($this->label), $this->style );
36 // Now process the generic attributes
37 reset( $this->attributes );
38 $attribute_values = "";
39 while( list($k,$v) = each( $this->attributes ) ) {
40 if ( substr($k, 0, 1) == '_' ) continue;
41 $attribute_values .= " $k=\"".htmlentities($v)."\"";
43 $r = str_replace( '%%attributes%%', $attribute_values, $r );
45 $this->rendered = $r;
46 return "$r\n";
49 // Set arbitrary attributes of the menu option
50 function Set( $attribute, $value ) {
51 $this->attributes[$attribute] = $value;
52 return $this;
55 // Mark it as active, with a fancy style to distinguish that
56 function Active( $style ) {
57 $this->active = true;
58 $this->style = $style;
59 return $this;
62 // This menu option is now promoted to the head of a tree
63 function AddSubmenu( &$submenu_set ) {
64 $this->submenu_set = &$submenu_set;
65 return $this;
68 function IsActive( ) {
69 return ( $this->active );
74 // Class implementing a hierarchical
75 class MenuSet {
76 var $div_class; // CSS style to use for the div around the options
77 var $main_class; // CSS style to use for normal menu option
78 var $active_class; // CSS style to use for active menu option
79 var $options; // An array of MenuOption objects
80 var $parent; // Any menu option that happens to parent this set
82 // Constructor
83 function MenuSet( $div_class, $main_class, $active_class ) {
84 $this->options = array();
85 $this->main_class = $main_class;
86 $this->active_class = $active_class;
87 $this->div_class = $div_class;
90 // Add an option, which is a link.
91 function &AddOption( $label, $target, $title="", $active=false, $sortkey=0 ) {
92 $new_option =& new MenuOption( $label, $target, $title, $this->main_class, $sortkey );
93 array_push( $this->options, &$new_option );
94 if ( is_bool($active) && $active == false && $_SERVER['REQUEST_URI'] == $target ) {
95 // If $active is not set, then we look for an exact match to the current URL
96 $new_option->Active( $this->active_class );
98 else if ( is_bool($active) && $active ) {
99 // When active is specified as a boolean, the recognition has been done externally
100 $new_option->Active( $this->active_class );
102 else if ( is_string($active) && preg_match($active,$_SERVER['REQUEST_URI']) ) {
103 // If $active is a string, then we match the current URL to that as a Perl regex
104 $new_option->Active( $this->active_class );
106 return $new_option ;
109 // Add an option, which is a submenu
110 function &AddSubMenu( &$submenu_set, $label, $target, $title="", $active=false, $sortkey=0 ) {
111 $new_option =& $this->AddOption( $label, $target, $title, $active, $sortkey );
112 $submenu_set->parent = &$new_option ;
113 $new_option->AddSubmenu( &$submenu_set );
114 return $new_option ;
117 // This is called to see if a menu has any options that are active,
118 // most likely so that we can then set that menu active, as is done
119 // by LinkActiveSubMenus - should be private.
120 function HasActive( ) {
121 reset($this->options);
122 while( list($k,$v) = each($this->options) ) {
123 if ( $v->IsActive() ) return true;
125 return false;
128 // Currently needs to be called manually before rendering but
129 // really should probably be called as part of the render now,
130 // and then this could be a private routine.
131 function LinkActiveSubMenus( ) {
132 reset($this->options);
133 while( list($k,$v) = each($this->options) ) {
134 if ( isset($v->submenu_set) && $v->submenu_set->HasActive() ) {
135 // Note that we need to do it this way, since $v is a copy, not a reference
136 $this->options[$k]->Active( $this->active_class );
141 // Gimme the HTML. Now.
142 function Render( ) {
143 $render_sub_menus = false;
144 $r = "<div class=\"$this->div_class\">";
145 reset($this->options);
146 while( list($k,$v) = each($this->options) ) {
147 $r .= $v->Render();
148 if ( $v->IsActive() && isset($v->submenu_set) ) {
149 $render_sub_menus = $v->submenu_set;
152 $r .="</div>\n";
153 if ( $render_sub_menus != false ) {
154 $r .= $render_sub_menus->Render();
156 return $r;