1<?php 2/** 3 * DokuWiki Plugin simplenavi (Syntax Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr <gohr@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10if (!defined('DOKU_INC')) die(); 11 12if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); 13if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); 14if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 15 16require_once DOKU_PLUGIN.'syntax.php'; 17require_once DOKU_INC.'inc/search.php'; 18 19class syntax_plugin_simplenavi extends DokuWiki_Syntax_Plugin { 20 function getType() { 21 return 'substition'; 22 } 23 24 function getPType() { 25 return 'block'; 26 } 27 28 function getSort() { 29 return 155; 30 } 31 32 33 function connectTo($mode) { 34 $this->Lexer->addSpecialPattern('{{simplenavi>[^}]*}}',$mode,'plugin_simplenavi'); 35 } 36 37 function handle($match, $state, $pos, Doku_Handler $handler){ 38 $data = array(cleanID(substr($match,13,-2))); 39 40 return $data; 41 } 42 43 function render($mode, Doku_Renderer $R, $pass) { 44 if($mode != 'xhtml') return false; 45 46 global $conf; 47 global $INFO; 48 $R->info['cache'] = false; 49 50 $ns = utf8_encodeFN(str_replace(':','/',$pass[0])); 51 $data = array(); 52 search($data,$conf['datadir'],array($this,'_search'),array('ns' => $INFO['id']),$ns,1,'natural'); 53 if ($this->getConf('sortByTitle') == true) { 54 $this->_sortByTitle($data,"id"); 55 } else { 56 if ($this->getConf('sort') == 'ascii') { 57 uksort($data, array($this, '_cmp')); 58 } 59 } 60 61 $R->doc .= '<div class="plugin__simplenavi">'; 62 $R->doc .= html_buildlist($data,'idx',array($this,'_list'),array($this,'_li')); 63 $R->doc .= '</div>'; 64 65 return true; 66 } 67 68 function _list($item){ 69 global $INFO; 70 71 if(($item['type'] == 'd' && $item['open']) || $INFO['id'] == $item['id']){ 72 return '<strong>'.html_wikilink(':'.$item['id'],$this->_title($item['id'])).'</strong>'; 73 }else{ 74 return html_wikilink(':'.$item['id'],$this->_title($item['id'])); 75 } 76 77 } 78 79 function _li($item){ 80 if($item['type'] == "f"){ 81 return '<li class="level'.$item['level'].'">'; 82 }elseif($item['open']){ 83 return '<li class="open">'; 84 }else{ 85 return '<li class="closed">'; 86 } 87 } 88 89 function _search(&$data,$base,$file,$type,$lvl,$opts){ 90 global $conf; 91 $return = true; 92 93 $item = array(); 94 95 $id = pathID($file); 96 97 if($type == 'd' && !( 98 preg_match('#^'.$id.'(:|$)#',$opts['ns']) || 99 preg_match('#^'.$id.'(:|$)#',getNS($opts['ns'])) 100 101 )){ 102 //add but don't recurse 103 $return = false; 104 }elseif($type == 'f' && (!empty($opts['nofiles']) || substr($file,-4) != '.txt')){ 105 //don't add 106 return false; 107 } 108 109 if($type=='d' && $conf['sneaky_index'] && auth_quickaclcheck($id.':') < AUTH_READ){ 110 return false; 111 } 112 113 if($type == 'd'){ 114 // link directories to their start pages 115 $exists = false; 116 $id = "$id:"; 117 resolve_pageid('',$id,$exists); 118 $this->startpages[$id] = 1; 119 }elseif(!empty($this->startpages[$id])){ 120 // skip already shown start pages 121 return false; 122 }elseif(noNS($id) == $conf['start']){ 123 // skip the main start page 124 return false; 125 } 126 127 //check hidden 128 if(isHiddenPage($id)){ 129 return false; 130 } 131 132 //check ACL 133 if($type=='f' && auth_quickaclcheck($id) < AUTH_READ){ 134 return false; 135 } 136 137 $data[$id]=array( 'id' => $id, 138 'type' => $type, 139 'level' => $lvl, 140 'open' => $return); 141 return $return; 142 } 143 144 function _title($id) { 145 global $conf; 146 147 if(useHeading('navigation')){ 148 $p = p_get_first_heading($id); 149 } 150 if(!empty($p)) return $p; 151 152 $p = noNS($id); 153 if ($p == $conf['start'] || $p == false) { 154 $p = noNS(getNS($id)); 155 if ($p == false) { 156 return $conf['start']; 157 } 158 } 159 return $p; 160 } 161 162 function _cmp($a, $b) { 163 global $conf; 164 $a = preg_replace('/'.preg_quote($conf['start'], '/').'$/', '', $a); 165 $b = preg_replace('/'.preg_quote($conf['start'], '/').'$/', '', $b); 166 $a = str_replace(':', '/', $a); 167 $b = str_replace(':', '/', $b); 168 169 return strcmp($a, $b); 170 } 171 172 function _sortByTitle(&$array, $key) { 173 $sorter = array(); 174 $ret = array(); 175 reset($array); 176 foreach ($array as $ii => $va) { 177 $sorter[$ii] = $this->_title($va[$key]); 178 } 179 if ($this->getConf('sort') == 'ascii') { 180 uksort($sorter, array($this, '_cmp')); 181 } else { 182 natcasesort($sorter); 183 } 184 foreach ($sorter as $ii => $va) { 185 $ret[$ii] = $array[$ii]; 186 } 187 $array = $ret; 188 } 189 190} 191 192// vim:ts=4:sw=4:et: 193