dokuwiki-indexmenu-plugin – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 <?php
2 /**
3 * Indexmenu Action Plugin: Indexmenu Component.
4 *
5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author Samuele Tognini <samuele@samuele.netsons.org>
7 */
8  
9 if(!defined('DOKU_INC')) die();
10  
11 class action_plugin_indexmenu extends DokuWiki_Action_Plugin {
12  
13 /**
14 * plugin should use this method to register its handlers with the dokuwiki's event controller
15 *
16 * @param Doku_Event_Handler $controller DokuWiki's event controller object.
17 */
18 function register(Doku_Event_Handler $controller) {
19 if($this->getConf('only_admins')) $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, '_checkperm');
20 if($this->getConf('page_index') != '') $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, '_loadindex');
21 $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, '_extendJSINFO');
22 $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, '_purgecache');
23 if($this->getConf('show_sort')) $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, '_showsort');
24 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_ajax_call');
25 }
26  
27 /**
28 * Check if user has permission to insert indexmenu
29 *
30 * @author Samuele Tognini <samuele@samuele.netsons.org>
31 *
32 * @param Doku_Event $event
33 * @param mixed $param not defined
34 */
35 function _checkperm(&$event, $param) {
36 global $INFO;
37 if(!$INFO['isadmin']) {
38 $event->data[0][1] = preg_replace("/{{indexmenu(|_n)>.+?}}/", "", $event->data[0][1]);
39 }
40 }
41  
42 /**
43 * Add additional info to $JSINFO
44 *
45 * @author Samuele Tognini <samuele@samuele.netsons.org>
46 * @author Gerrit Uitslag <klapinklapin@gmail.com>
47 *
48 * @param Doku_Event $event
49 * @param mixed $param not defined
50 */
51 function _extendJSINFO(&$event, $param) {
52 global $INFO, $JSINFO;
53 $JSINFO['isadmin'] = (int) $INFO['isadmin'];
54 $JSINFO['isauth'] = (int) $INFO['userinfo'];
55 }
56  
57 /**
58 * Check for pages changes and eventually purge cache.
59 *
60 * @author Samuele Tognini <samuele@samuele.netsons.org>
61 *
62 * @param Doku_Event $event
63 * @param mixed $param not defined
64 */
65 function _purgecache(&$event, $param) {
66 global $ID;
67 global $conf;
68 /** @var cache_parser $cache */
69 $cache = &$event->data;
70  
71 if(!isset($cache->page)) return;
72 //purge only xhtml cache
73 if($cache->mode != "xhtml") return;
74 //Check if it is an indexmenu page
75 if(!p_get_metadata($ID, 'indexmenu')) return;
76  
77 $aclcache = $this->getConf('aclcache');
78 if($conf['useacl']) {
79 $newkey = false;
80 if($aclcache == 'user') {
81 //Cache per user
82 if($_SERVER['REMOTE_USER']) $newkey = $_SERVER['REMOTE_USER'];
83 } else if($aclcache == 'groups') {
84 //Cache per groups
85 global $INFO;
86 if($INFO['userinfo']['grps']) $newkey = implode('#', $INFO['userinfo']['grps']);
87 }
88 if($newkey) {
89 $cache->key .= "#".$newkey;
90 $cache->cache = getCacheName($cache->key, $cache->ext);
91 }
92 }
93 //Check if a page is more recent than purgefile.
94 if(@filemtime($cache->cache) < @filemtime($conf['cachedir'].'/purgefile')) {
95 $event->preventDefault();
96 $event->stopPropagation();
97 $event->result = false;
98 }
99 }
100  
101 /**
102 * Render a defined page as index.
103 *
104 * @author Samuele Tognini <samuele@samuele.netsons.org>
105 *
106 * @param Doku_Event $event
107 * @param mixed $param not defined
108 */
109 function _loadindex(&$event, $param) {
110 if('index' != $event->data) return;
111 if(!file_exists(wikiFN($this->getConf('page_index')))) return;
112 global $lang;
113 print '<h1><a id="index" name="index">'.$lang['btn_index']."</a></h1>\n";
114 print p_wiki_xhtml($this->getConf('page_index'));
115 $event->preventDefault();
116 $event->stopPropagation();
117  
118 }
119  
120 /**
121 * Display the indexmenu sort number.
122 *
123 * @author Samuele Tognini <samuele@samuele.netsons.org>
124 *
125 * @param Doku_Event $event
126 * @param mixed $param not defined
127 */
128 function _showsort(&$event, $param) {
129 global $ID, $ACT, $INFO;
130 if($INFO['isadmin'] && $ACT == 'show') {
131 if($n = p_get_metadata($ID, 'indexmenu_n')) {
132 ptln('<div class="info">');
133 ptln($this->getLang('showsort').$n);
134 ptln('</div>');
135 }
136 }
137 }
138  
139 /**
140 * Handles ajax requests for indexmenu
141 *
142 * @param Doku_Event $event
143 * @param mixed $param not defined
144 */
145 function _ajax_call(&$event, $param) {
146 if($event->data !== 'indexmenu') {
147 return;
148 }
149 //no other ajax call handlers needed
150 $event->stopPropagation();
151 $event->preventDefault();
152  
153 switch($_REQUEST['req']) {
154 case 'local':
155 //list themes
156 header('Content-Type: application/json');
157  
158 $data = $this->_getlocalThemes();
159  
160 require_once DOKU_INC.'inc/JSON.php';
161 $json = new JSON();
162 echo ''.$json->encode($data).'';
163 break;
164  
165 case 'toc':
166 //print toc preview
167 if(isset($_REQUEST['id'])) print $this->print_toc($_REQUEST['id']);
168 break;
169  
170 case 'index':
171 //print index
172 if(isset($_REQUEST['idx'])) print $this->print_index($_REQUEST['idx']);
173 break;
174 }
175  
176 }
177  
178 /**
179 * Print a list of local themes
180 *
181 * @author Samuele Tognini <samuele@samuele.netsons.org>
182 * @author Gerrit Uitslag <klapinklapin@gmail.com>
183 */
184 private function _getlocalThemes() {
185 $themebase = 'lib/plugins/indexmenu/images';
186  
187 $handle = @opendir(DOKU_INC.$themebase);
188 $themes = array();
189 while(false !== ($file = readdir($handle))) {
190 if(is_dir(DOKU_INC.$themebase.'/'.$file)
191 && $file != "."
192 && $file != ".."
193 && $file != "repository"
194 && $file != "tmp"
195 && $file != ".svn"
196 ) {
197 $themes[] = $file;
198 }
199 }
200 closedir($handle);
201 sort($themes);
202  
203 return array(
204 'themebase' => $themebase,
205 'themes' => $themes
206 );
207  
208 }
209  
210 /**
211 * Print a toc preview
212 *
213 * @author Samuele Tognini <samuele@samuele.netsons.org>
214 * @author Andreas Gohr <andi@splitbrain.org>
215 */
216 function print_toc($id) {
217 require_once(DOKU_INC.'inc/parser/xhtml.php');
218 $id = cleanID($id);
219 if(auth_quickaclcheck($id) < AUTH_READ) return '';
220  
221 $meta = p_get_metadata($id);
222 $toc = $meta['description']['tableofcontents'];
223  
224 if(count($toc) > 1) {
225 //display ToC of two or more headings
226 $out = $this->render_toc($toc);
227 } else {
228 //display page abstract
229 $out = $this->render_abstract($id, $meta);
230 }
231 return $out;
232 }
233  
234 /**
235 * Return the TOC rendered to XHTML
236 *
237 * @author Andreas Gohr <andi@splitbrain.org>
238 * @author Gerrit Uitslag <klapinklapin@gmail.com>
239 */
240 function render_toc($toc) {
241 global $lang;
242 $out = '<div class="tocheader">'.DOKU_LF;
243 $out .= $lang['toc'];
244 $out .= '</div>'.DOKU_LF;
245 $out .= '<div class="indexmenu_toc_inside">'.DOKU_LF;
246 $out .= html_buildlist($toc, 'toc', array($this, '_indexmenu_list_toc'), 'html_li_default', true);
247 $out .= '</div>'.DOKU_LF;
248 return $out;
249 }
250  
251 /**
252 * Return the page abstract rendered to XHTML
253 */
254 function render_abstract($id, &$meta) {
255 $out = '<div class="tocheader">'.DOKU_LF;
256 $out .= '<a href="'.wl($id).'">';
257 $out .= ($meta['title']) ? htmlspecialchars($meta['title']) : htmlspecialchars(noNS($id));
258 $out .= '</a>'.DOKU_LF;
259 $out .= '</div>'.DOKU_LF;
260 if($meta['description']['abstract']) {
261 $out .= '<div class="indexmenu_toc_inside">'.DOKU_LF;
262 $out .= p_render('xhtml', p_get_instructions($meta['description']['abstract']), $info);
263 $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
264 }
265 return $out;
266 }
267  
268 /**
269 * Callback for html_buildlist
270 */
271 function _indexmenu_list_toc($item) {
272 $id = cleanID($_REQUEST['id']);
273  
274 if(isset($item['hid'])) {
275 $link = '#'.$item['hid'];
276 } else {
277 $link = $item['link'];
278 }
279  
280 //prefix anchers with page id
281 if($link[0] == '#') {
282 $link = wl($id, $link, false, '');
283 }
284 return '<a href="'.$link.'">'.hsc($item['title']).'</a>';
285 }
286  
287 /**
288 * Print index nodes
289 *
290 * @author Samuele Tognini <samuele@samuele.netsons.org>
291 * @author Andreas Gohr <andi@splitbrain.org>
292 * @author Rene Hadler <rene.hadler@iteas.at>
293 */
294 function print_index($ns) {
295 require_once(DOKU_PLUGIN.'indexmenu/syntax/indexmenu.php');
296 global $conf;
297 $idxm = new syntax_plugin_indexmenu_indexmenu();
298 $ns = $idxm->_parse_ns(rawurldecode($ns));
299 $level = -1;
300 $max = 0;
301 $data = array();
302 $skipfile = array();
303 $skipns = array();
304  
305 if($_REQUEST['max'] > 0) {
306 $max = $_REQUEST['max'];
307 $level = $max;
308 }
309 $nss = ($_REQUEST['nss']) ? cleanID($_REQUEST['nss']) : '';
310 $idxm->sort = $_REQUEST['sort'];
311 $idxm->msort = $_REQUEST['msort'];
312 $idxm->rsort = $_REQUEST['rsort'];
313 $idxm->nsort = $_REQUEST['nsort'];
314 $idxm->hsort = $_REQUEST['hsort'];
315 $fsdir = "/".utf8_encodeFN(str_replace(':', '/', $ns));
316  
317 $skipf = utf8_decodeFN($_REQUEST['skipfile']);
318 $skipfile[] = $this->getConf('skip_file');
319 if(isset($skipf)) {
320 $index = 0;
321 if($skipf[1] == '+') {
322 $index = 1;
323 }
324 $skipfile[$index] = substr($skipf, 1);
325 }
326 $skipn = utf8_decodeFN($_REQUEST['skipns']);
327 $skipns[] = $this->getConf('skip_index');
328 if(isset($skipn)) {
329 $index = 0;
330 if($skipn[1] == '+') {
331 $index = 1;
332 }
333 $skipns[$index] = substr($skipn, 1);
334 }
335  
336 $opts = array(
337 'level' => $level,
338 'nons' => $_REQUEST['nons'],
339 'nss' => array(array($nss, 1)),
340 'max' => $max,
341 'js' => false,
342 'nopg' => $_REQUEST['nopg'],
343 'skip_index' => $skipns,
344 'skip_file' => $skipfile,
345 'headpage' => $idxm->getConf('headpage'),
346 'hide_headpage' => $idxm->getConf('hide_headpage')
347 );
348 if($idxm->sort || $idxm->msort || $idxm->rsort || $idxm->hsort) {
349 $idxm->_search($data, $conf['datadir'], array($idxm, '_search_index'), $opts, $fsdir);
350 } else {
351 search($data, $conf['datadir'], array($idxm, '_search_index'), $opts, $fsdir);
352 }
353  
354 $out = '';
355 if($_REQUEST['nojs']) {
356 require_once(DOKU_INC.'inc/html.php');
357 $out_tmp = html_buildlist($data, 'idx', array($idxm, "_html_list_index"), "html_li_index");
358 $out .= preg_replace('/<ul class="idx">(.*)<\/ul>/s', "$1", $out_tmp);
359 } else {
360 $nodes = $idxm->_jsnodes($data, '', 0);
361 $out = "ajxnodes = [";
362 $out .= rtrim($nodes[0], ",");
363 $out .= "];";
364 }
365 return $out;
366 }
367 }