1
2
3
4<?php
5/**
6 * Functions derived from html.php
7 * Modified to generate the dropdown index
8 *
9 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
10 * @author     Andreas Gohr <andi@splitbrain.org>
11 * @author     Modified Paul Minifie
12 */
13
14
15 //#TODO
16 //highlight current page
17 //highlight visitied pages - does a record exist? how does trace work?
18
19
20/**
21 * Display page index
22 *
23 * @author Andreas Gohr <andi@splitbrain.org>
24 * @author Paul Minifie
25 * from html.php
26 */
27
28function html_index_mod ($ns){
29  require_once(DOKU_INC.'inc/search.php');
30  global $conf;
31  global $ID;
32  //added for debug
33  global $ACT;
34  global $debug;
35
36  $dir = $conf['datadir'];
37  $ns  = cleanID($ns);
38  #fixme use appropriate function
39  if(empty($ns)){
40    $ns = dirname(str_replace(':','/',$ID));
41    if($ns == '.') $ns ='';
42  }
43  $ns  = utf8_encodeFN(str_replace(':','/',$ns));
44
45//search_index_title returns an array of arrays, a tree for each of the nodes in the IDX
46//so split the IDX into components, each of which have level 0, and add each tree to them, before building the list
47  $data =array();
48  $data1=array();
49  $pageid=array();
50  search($data,$conf['datadir'],'search_index_title',array('ns' => $ns));
51  $IDdisplay=$ID;
52  //TODO obsolete - modify to hide pages with a given suffix
53  //test to see if pagename is a descriptor of an NS and if so, truncate to NS
54  //only happens if 'nspages' is set in local.php and mod is done and flagged in doku.php
55  //if ($conf['amanuensis']['dokunsmod'] and $conf['amanuensis']['nspages']){
56  //  $IDdisplay=$ID;
57  //  if (test_nsdescriptor(noNS($ID))==true){
58  //    $IDdisplay = getNS($ID);
59  //  }
60  //}
61  //remove pages named the same as the NS
62  //if 'nspages' is set in local.php and mod is done and flagged in doku.php
63  if ($conf['amanuensis']['dokunsmod'] and $conf['amanuensis']['nspages']=='true'){
64      $data =stripNSdescriptors($data);
65  }
66  //$debug['data'] = $data;
67  $data = build_subindex($data,$IDdisplay);
68  $pageid = diceID($IDdisplay);
69  //$debug['iddice']=$pageid;
70  //sets the spacer that appears in the title of the dropdowns
71  $spacer= array ('id' => ".", 'type' => d, 'level' => 0, 'open' => 1);
72  $pageid = index_dicedID ($pageid);
73  $data1 = array_shift ($data);
74  array_unshift($data1, array_shift($pageid));
75  $arrlent = count($pageid);
76  $nn=0;
77  while ($nn < $arrlent){
78      if (($arrlent - $nn) >0){array_push($data1, $spacer);}
79      array_push ($data1, $pageid[$nn] );
80      $data1 = array_merge ($data1, $data[$nn]);
81
82   $nn++;
83  }
84 if ($ACT =='edit'){
85  print html_buildlist_mod($data1,'idx','html_list_index_edit','html_li_index_mod');
86  }else{
87  print html_buildlist_mod($data1,'idx','html_list_index_mod','html_li_index_mod');
88  }
89}
90
91  /**
92   * test to see if name is a namespace descriptor ie, is suffixed with '$conf['amanuensis']['nssuffix']'
93   * FIXME make suffix a variable (set in doku.php??)
94   * @author Paul Minifie
95   */
96 function test_nsdescriptor ($name){
97   global $conf;
98   if (strpos(strrev($name),strrev($conf['amanuensis']['nssuffix']))===0) {
99       $return=true;
100   }else {$return=false;
101   }
102   return $return;
103 }
104
105
106   /**
107   * removes files with the same name as the directory they are in from the dropdown menu
108   *
109   * @author  Paul Minifie
110   */
111function stripNSdescriptors($data){
112  //global $debug;
113  $level = 0;
114  $ret=array();
115  $count=array();
116  $nslist=array();
117     //assumes all directories always come before files at a given level, so only does list once
118     //so names of directories added to array. if filenames match, they are discarded
119     //starts by giving each directory an index
120  while ($data){
121  $item=array_shift($data);
122       $l=$item['level'];
123       if( $l > $level ){
124          $count[$l]++;
125     }
126    //$item['index']=$count[$l];
127    if ($item['type']=='d'){
128      $nslist[$l][$count[$l]][] = noNS($item['id']);
129      array_push($ret,$item);
130     }elseif($item['type']=='f'){
131//$debug['count']=$count;
132//$debug['nslist'] = $nslist;
133       if (is_array ($nslist[$l][$count[$l]])){
134         if (!in_array(noNS($item['id']),$nslist[$l][$count[$l]])){
135         array_push($ret,$item);
136         }
137       }else{
138         array_push($ret,$item);
139       }
140     }
141    //remember current level
142    $level = $l;
143    }
144  return $ret;
145}
146
147  /**
148   * takes an index file, array()as returned by
149   * and the IDX, and creates submenus, corresponding to the namespaces
150   * in form array(array(rootnamespace), array(nextlevelnamespace),....array(deepestnamespace)
151   * and marks the namespaces of the current name
152   *
153   * @author  Paul Minifie
154   */
155function build_subindex($index, $id){
156  $iddice=array();
157  $return[0]=$index;
158  $temp = diceID($id);
159  while ($temp){
160    $iddice[]=noNS(array_shift($temp));
161  }
162  $level=1;
163  $search  = array_shift($iddice).':';
164  while ($iddice){
165    $return[$level]=array();
166    foreach ($return[$level-1] as $item){
167       //set second bit as component of name
168       if ($search == $item['id']){
169           $item['open']=$item['open'] & 2;
170       }
171       //reduce level for submenu items
172       if (0 === strpos( $item['id'],$search)){
173         $item['level']= $item['level']-1;
174         //add item to submenu
175         array_push($return[$level],$item);
176       }
177    }
178  $search .= array_shift($iddice).':';
179  $level++;
180  }
181  return $return;
182}
183
184
185  /**
186   * dices $ID into array of form that can be output by html_buildlist_mod
187   * Function passed to the search function
188   *
189   * @author  Paul Minifie
190   */
191function diceID ($id){
192    $dice = array();
193    while ($id){
194     $dice[]=$id;
195     $id=getNS($id);
196    }
197    return  array_reverse($dice);
198}
199
200
201  /**NOTUSED
202   * dices $ID into array of form that can be output by html_buildlist_mod
203   * Function passed to the search function
204   *
205   * @author  Paul Minifie
206   */
207function diceID_old ($id){
208    $dice = array();
209    $colon = true;
210    while ($colon) {
211      $colon=strpos($id, ':' );
212      if ($colon){
213        $dice[]= substr($id, 0,  strpos($id,':'));
214        $id=substr($id, $colon+1);
215      }else{
216        $dice[]= $id;
217      }
218    }
219    return  $dice;
220}
221
222  /**
223   * formats a diced $ID into a form that can be built into an index
224   *
225   * @author  Paul Minifie
226   */
227function index_dicedID ($dicedID){
228  $return=array();
229  //FIX_ME this identifies a file as a directory when top level (so the menus work)
230  array_unshift ($return, array('id'=>array_pop($dicedID), 'type'=>'d','level'=>0,'open'=>1));
231  while ($dicedID){
232    array_unshift($return, array('id'=>array_pop($dicedID), 'type'=>'d','level'=>0,'open'=>1));
233  }
234  return $return;
235}
236
237
238  /**
239 * Build the browsable index of pages
240 *
241 * $opts['ns'] is the current namespace
242 *
243 * @author  Andreas Gohr <andi@splitbrain.org>
244 * @author  Paul Minifie
245 */
246function search_index_title(&$data,$base,$file,$type,$lvl,$opts){
247  global $conf;
248  $return = true;
249  $item = array();
250
251  if($type == 'd' && !preg_match('#^'.$file.'(/|$)#','/'.$opts['ns'])){
252    //add but don't recurse
253    $return = true;
254  }elseif($type == 'f' && !preg_match('#\.txt$#',$file)){
255    //don't add
256    //modified from andreas' function so return value changed to true in this case, to return the entire index
257    // #FIXME may be possible to do this with the original function if the namespace is not passed
258    return false;
259  }
260  //check ACL
261  $id = pathID($file);
262  if($type=='f' && auth_quickaclcheck($id) < AUTH_READ){
263    return false;
264  }
265  // dont add namespace descriptors to the list
266  //but only if 'nspages' is set in local.php and mod is done and flagged in doku.php                                                                                                       	;
267  if (!($conf['amanuensis']['dokunsmod'] and $conf['amanuensis']['nspages'] and test_nsdescriptor($id))){
268    $data[]=array( 'id'    => $id,
269                   'type'  => $type,
270                   'level' => $lvl,
271                   'open'  => $return );
272  }
273  return $return;
274}
275
276
277
278/**
279 * Build an unordered list
280 *
281 * Build an unordered list from the given $data array
282 * Each item in the array has to have a 'level' property
283 * the item itself gets printed by the given $func user
284 * function. The second and optional function is used to
285 * print the <li> tag. Both user function need to accept
286 * a single item.
287 *
288 * @author Andreas Gohr <andi@splitbrain.org>
289 . @author Paul Minifie
290 */
291function html_buildlist_mod($data,$class,$func,$lifunc='html_li_default',$menuid='menu-h',$menuclass='horizontal'){
292//$level set at -1, changed from 0 -pm
293  $level = -1;
294  $level_init= -1;
295  $opens = 0;
296  $ret   = '';
297  $firstul = 1;
298
299  foreach ($data as $item){
300     if( $item['level'] > $level ){
301      //open new list
302       for($i=0; $i<($item['level'] - $level); $i++){
303          if ($i) $ret .= "<li class=\"clear\">\n";
304          //$changed to set class name to level -pm
305          if ($firstul){
306                       	$ret .= "<ul id=\"$menuid\" class=\"$menuclass\">\n";
307                       	$firstul =NULL;
308          }else{
309          $ret .= "<ul>\n";   //  class=\"lev$level\">\n";
310          }
311       }
312     }
313     elseif( $item['level'] < $level ){
314        //close last item
315        $ret .= "</li>\n";
316        for ($i=0; $i<($level - $item['level']); $i++){
317        //close higher lists
318        $ret .= "</ul>\n</li>\n";
319    }
320    }else{
321      //close last item
322      $ret .= "</li>\n";
323    }
324
325    //remember current level
326    $level = $item['level'];
327
328    //print item
329    $ret .= $lifunc($item); //user function
330    //$ret .= '<span>';// class="li">';
331    $ret .= $func($item); //user function
332    //$ret .= '</span>';
333  }
334
335  //close remaining items and lists
336  for ($i=0; $i < $level; $i++){
337    $ret .= "</li>\n</ul>\n";
338  }
339
340  return $ret;
341}
342
343
344function html_list_index_mod($item){
345  $ret = '';
346  $base = ':'.$item['id'];
347  $base = substr($base,strrpos($base,':')+1);
348  if($item['type']=='d'){
349    $ret .= '<a href="'.wl($ID,'idx='.$item['id']).'" class="subpages">';
350    $ret .= $base;
351    $ret .= '</a>';
352  }else{
353    $ret .= html_wikilink(':'.$item['id']);
354  }
355  return $ret;
356}
357
358/**
359 * In edit mode, builds the links with
360 *
361 * User function for html_buildlist()
362 *
363 * @author Andreas Gohr <andi@splitbrain.org>
364 * @author Paul Minifie
365 */
366
367function html_list_index_edit($item){
368  $ret = '';
369  $base = ':'.$item['id'];
370  $base = substr($base,strrpos($base,':')+1);
371  if($item['type']=='d'){
372    $ret .= '<a href="javascript:insertIntLink(\''.idfilter($item['id']).'\')" class="subpages_edit" >'.noNS($item['id']).'</a>';
373    //$ret .= '<a href="'.wl($ID,'idx='.$item['id']).'" class="subpages">';
374    //$ret .= $base;
375    //$ret .= '</a>';
376  }else{
377    $ret .= '<a href="javascript:insertIntLink(\''.idfilter($item['id']).'\')" class="wikilink1_edit" >'.noNS($item['id']).'</a>';
378
379  }
380  return $ret;
381}
382
383/**
384  * NOT USED
385 * Index item formatter
386 *
387 * User function for html_buildlist()
388 *
389 * @author Andreas Gohr <andi@splitbrain.org>
390 */
391 function html_list_index_mod_old($item){
392  $ret = '';
393  $base = ':'.$item['id'];
394  $base = substr($base,strrpos($base,':')+1);
395  if($item['type']=='d'){
396    $ret .= '<a href="'.wl($ID,'idx='.$item['id']) .'">'; //.'" class="idx_dir">';
397    $ret .= $base;
398    $ret .= '</a>';
399  }else{
400    $ret .= html_wikilink(':'.$item['id']);
401  }
402  return $ret;
403}
404
405
406
407
408/**
409 * NOT USED
410 * Index List item
411 *
412 * This user function is used in html_build_list to build the
413 * <li> tags for namespaces when displaying the page index
414 * it gives different classes to opened or closed "folders"
415 *
416 * @author Andreas Gohr <andi@splitbrain.org>
417 */
418
419function html_li_index_mod($item){
420  if($item['type'] == "f"){
421    return '<li>'; // class="level'.$item['level'].'">';
422  }elseif($item['open']){
423    return '<li>';// class="open">';
424  }else{
425    return '<li>';// class="closed">';
426  }
427}
428
429
430/**
431 * Default List item, modified to insert a link in edit mode
432 *
433 * @author Andreas Gohr <andi@splitbrain.org>
434 * @author Paul Minifie
435 */
436function html_li_edit($item){
437  return '<li class="level'.$item['level'].'">';
438}
439
440
441?>
442