f5a524ac9252f356e4d234cf8c9968fadbca4d6e
[atutor.git] / mods / wiki / plugins / lib / navbar.php
1 <?php
2
3 /* 
4 Ewiki nav bar plugin - by AndyFundinger
5
6 this plugin will create a navigation bar from a site map on a page.  The site 
7 map should be a list with wiki words or [] style wiki links.  You must select 
8 two functions to control the operation of your navigation bar.  
9 $ewiki_plugins['select_navbar_buttons'][0] will be run to determine which 
10 buttons are invisible($NavBar[$id][2] = 0), visible($NavBar[$id][2] = 1), or 
11 active ($NavBar[$id][2] = 2).  $ewiki_plugins['render_navbar_section'][0] will 
12 control the actual rendering and is designed to support recursive calls.  Two 
13 versions of each are supported.  You can also create your own site specific 
14 selector or renderer.  I use a function that calls 
15 ewiki_navbar_selectall_buttons() to select the level 1 pages and then 
16 ewiki_navbar_select_psuc() to select parents, siblings, uncles, and children if 
17 possible.
18
19 The effect of this NavBar relies on stylesheets.  You must add several classes
20 to make the NavBar appear properly.  An example style sheet is 
21 WikiNavBarStyle.css.  The following tag will add this example style sheet to your
22 code:
23
24 <link rel='stylesheet' href='./fragments/WikiNavBarStyle.css' type='text/css' media='all' />
25
26 The NavBar array is composed of one line per button as follows:
27 $NavBar[]=array( line text, depth, activation,target page);
28
29 Call mkLiveWebNavBar() from within your page to create a NavBar.
30 */
31
32 define("EWIKI_NAVBAR_SELECTALL_DEPTH",99);
33 define("EWIKI_NAVBAR_ACTIVATEPARENTS",1);
34 define("EWIKI_NAVBAR_ACTIVATECHILDREN",1);
35 define('EWIKI_NAVBAR_ACTION','view');
36
37 //Select only Parents, Siblings, Uncles, and Children
38 $ewiki_plugins['select_navbar_buttons'][]="ewiki_navbar_select_psuc";
39 //Select entire menu, highlight current page, selects to depth of 
40 // EWIKI_NAVBAR_SELECTALL_DEPTH
41 $ewiki_plugins['select_navbar_buttons'][]="ewiki_navbar_selectall_buttons";
42 //Renders NavBar as a set of nested lists 
43 $ewiki_plugins['render_navbar_section'][]='ewiki_render_navbar_list';
44 //Alternate render routine that puts sub bars below the major categories.
45 $ewiki_plugins['render_navbar_section'][]='ewiki_render_navbar_fixedtop_list';
46
47 //Create a navBar, call with a page to be turned into the bar and a page to be 
48 // selected, uses $ewiki_plugins['select_navbar_buttons'][0] and 
49 // $ewiki_plugins['render_navbar_section'][0].  Returns nothing if no bar is 
50 // created.
51 function mkLiveWebNavBar($navBarPage, $activePage){
52     #-- fetch from db
53     $data = ewiki_db::GET($navBarPage);
54     
55     #-- Authenticate, return nothing if authentication fails
56     if (ewiki_auth($navBarPage, $data, EWIKI_NAVBAR_ACTION, $ring=3, $force=0)) {
57          return("");
58     }
59
60     #-- escape if navBarPage does not exist or was not retrieved.  
61     if(empty($data["content"])){
62         return("");
63     }
64     //echo(":".$data["content"].":");
65     
66     $o .= ewiki_navbar_format ( $data["content"], 1,urlencode($activePage) );
67
68     //Apply class only if we have a bar at all
69     if($o)
70         return(" <div class='wikiNavBar' >\n".$o."\n</div>\n");
71     return("");
72 }
73
74 //An adaptation of ewiki_format to format navigation bars
75 function ewiki_navbar_format ($wiki_source, $scan_links=1,
76     $currpage=EWIKI_PAGE_INDEX)
77 {
78     global $ewiki_links, $ewiki_plugins;
79     
80     //echo("navbar function run");
81     // pre-scan WikiLinks
82     if ($scan_links) {
83         ewiki_scan_wikiwords($wiki_source, $ewiki_links);
84     }
85     
86     // formatted output
87     $o = "\n";
88     
89     // plugins only format finals are respected
90     $pf_final = @$ewiki_plugins["format_final"];
91     
92     $table_defaults = 'cellpadding="2" border="1" cellspacing="0"';
93     $syn_htmlentities = array(
94         "&" => "&amp;",
95         ">" => "&gt;",
96         "<" => "&lt;",
97         "%%%" => "<br />"
98     );
99     $wm_list = array(
100         "-" => array('ul type="square"', "", "li"),
101         "*" => array('ul type="circle"', "", "li"),
102         "#" => array("ol", "", "li"),
103         ":" => array("dl", "dt", "dd"),
104         ";" => array("dl", "dt", "dd"),
105     );
106
107    // eleminate html
108     foreach ($syn_htmlentities as $find=>$replace) {
109         $wiki_source = str_replace($find, $replace, $wiki_source);
110     }
111     array_pop($syn_htmlentities);   // strips "&amp;"
112     
113     // add a last empty line to get opened tables/lists closed correctly
114     $wiki_source = trim($wiki_source) . "\n";
115     
116     
117     #-- finally the link-detection-regex
118     #   (impossible to do with the simple string functions)
119     ewiki_render_wiki_links($wiki_source);
120         
121     $NavBar = array();
122     
123                 //return($wiki_source);
124     foreach (explode("\n", $wiki_source) as $line) {
125
126         $line = rtrim($line);
127         $lineout="";
128
129         #-- wiki list markup
130         if ( strlen($line) && isset($wm_list[@$line[0]]) ) {
131             $n = 0;
132             $li = "";
133             #-- count depth of list
134             #   line has length         first character in the line is in wm_list
135             while (strlen($line) && ('*'==$line[0]) ) {
136                 $li .= '*';     //add new list delim to list count
137                 $n++;                   //count depth
138                 $line = substr($line, 1);       //remove first character 
139             }
140             $line = ltrim($line);
141             
142             $regex='#<a href=["\'](.*)'.preg_quote(EWIKI_SCRIPT) .'(.*?)["\'&?^](.*)#i';
143             preg_match($regex,$line,$matches=array());
144
145             $href=$matches[2];
146             //echo($regex.$line."HREF'".$href."'");
147
148             $NavBar[]=array($line,$n,0,$href);
149             //echo($line.$n.count($NavBar));
150
151         }
152    }
153    
154     //$NavBar now contains all elements in the navigation bar.
155       
156     //return("");
157
158     $NavBar=$ewiki_plugins['select_navbar_buttons'][0]($NavBar,$currpage);
159     
160     reset($NavBar);
161     $pre='';
162     $post='';
163     $barText=$ewiki_plugins['render_navbar_section'][0]($pre,$post,$NavBar);
164     $barText=$pre.$barText.$post;
165       
166     //Cut out if we have no navigation bar
167     if(!$barText)
168         return("");    
169     
170     #-- close last line
171     $o .= $barText."\n";
172     
173     #-- international characters
174     if (EWIKI_HTML_CHARS) {
175         $o = str_replace("&amp;#", "&#", $o);
176     }
177     
178     
179     #-- call post processing plugins
180     if ($pf_final) {
181         foreach ($pf_final as $pf) $pf($o);
182     }
183     
184     return($o);
185 }
186
187
188 //Select entire menu, highlight current page, selects to depth of 
189 // EWIKI_NAVBAR_SELECTALL_DEPTH, or can be called with a specified depth.
190 function ewiki_navbar_selectall_buttons( $NavBar,$currpage,$maxlevel=EWIKI_NAVBAR_SELECTALL_DEPTH){
191     foreach($NavBar as $id=>$row){
192         //echo("($id,$currpage)");
193         if($row[1]>$maxlevel){
194             next;
195         }elseif($row[3]==$currpage){
196             $NavBar[$id][2]=2;
197         }else{
198             $NavBar[$id][2]=1;            
199         }
200         //echo("($id,$row[0],".$NavBar[$id][2].")");
201     }
202     return($NavBar);
203 }
204
205 //Selects parents, siblings, uncles and children
206 function ewiki_navbar_select_psuc( $NavBar,$currpage){
207     foreach($NavBar as $id=>$row){
208         //echo("($row[3],$currpage)");
209         if($row[3]==$currpage){
210             $NavBar[$id][2]=2;
211             $selLev=$row[1];
212             
213             for($index=$id-1;$index>=0;$index--){
214                 if($NavBar[$index][1]<=$selLev){
215                     //set to displayed or active depending on ACTIVATEPARENTS
216                     $NavBar[$index][2]=
217                        ((($NavBar[$index][1]==$selLev)||
218                            (!EWIKI_NAVBAR_ACTIVATEPARENTS))? 1 : 2);  
219                     $selLev=$NavBar[$index][1];    //reduce selected level
220                 }
221             }
222             
223             $selLev=$row[1]+1;  
224             for($index=$id+1;$index<count($NavBar);$index++){ 
225                 //echo(":".$selLev.":(".$index.$NavBar[$index][0].$NavBar[$index][1].")");
226                 
227                 if($NavBar[$index][1]<=$selLev){
228                     if(!EWIKI_NAVBAR_ACTIVATECHILDREN){
229                         $NavBar[$index][2]=1;  //set to displayed
230                     }elseif($NavBar[$index][1]==$row[1]+1){
231                         $NavBar[$index][2]=2;  //set to active
232                     }else{
233                         $NavBar[$index][2]=1;  //set to displayed                    
234                     }
235                     $selLev=$NavBar[$index][1];    //reduce selected level
236                 }
237             } //*/
238         }
239         //echo($id.$NavBar[$id][2]);
240     }
241     return($NavBar);
242 }
243
244 //Render nav bar with sub menus appearing below entire bar
245 function ewiki_render_navbar_fixedtop_list($pre,$post,&$NavBar){
246
247     $element=current($NavBar);
248     $currLevel=$element[1];
249     //echo("processing".$currLevel.$uu[0]);
250     $myPre="<ul class='wikiNavBarDepth".$currLevel."'>";
251     $myPost="</ul>";
252     do{        
253         if(($element[1]>$currLevel)){
254             $myPost.=ewiki_render_navbar_fixedtop_list($myPre,$myPost,$NavBar);
255             $element=current($NavBar);
256             continue;
257         }elseif($element[2]>=2){
258             $mySection.="<li class='activebutton'>".$element[0]."</li>";
259         }elseif($element[2]>=1){
260             $mySection.="<li class='inactivebutton'>".$element[0]."</li>";        
261         }else{
262             //$mySection.=$element[0]            ."($element[1],$element[2])";        
263         }
264         $element=next($NavBar);
265     }while(($element[1]>=$currLevel));
266     
267     //Return list if there are elements
268     if($mySection)
269         return($myPre.$mySection.$myPost);
270     return("");
271 }
272
273 //Render nav bar as a simple list
274 function ewiki_render_navbar_list($pre,$post,&$NavBar){
275
276     $element=current($NavBar);
277     $currLevel=$element[1];
278     //echo("processing".$currLevel.$uu[0]);
279     $myPre="<ul class='wikiNavBarDepth".$currLevel."'>";
280     $myPost="</ul>\n";
281     do{        
282         if(($element[1]>$currLevel)){
283             $mySection.=ewiki_render_navbar_list($myPre,$myPost,$NavBar);
284             $element=current($NavBar);
285             continue;
286         }elseif($element[2]>=2){
287             $mySection.="<li class='activebutton'>".$element[0]."</li>";
288         }elseif($element[2]>=1){
289             $mySection.="<li class='inactivebutton'>".$element[0]."</li>";        
290         }else{
291             //$mySection.=$element[0]            ."($element[1],$element[2])";        
292             
293         }
294         $element=next($NavBar);
295     }while(($element[1]>=$currLevel));
296     
297     //Return list if there are elements
298     if($mySection)
299         return($myPre.$mySection.$myPost);   
300     return("");
301 }
302
303
304
305 ?>