1<?php
2/**
3 * Info Plugin: Displays information about various DokuWiki internals without "start" page
4 * Based on: nslist plugin by Andreas Gohr <andi@splitbrain.org>
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Zaher Dirkey <zaherdirkey@yahoo.com>
8 */
9
10
11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13require_once(DOKU_PLUGIN.'syntax.php');
14require_once(DOKU_INC.'inc/search.php');
15
16/**
17 * All DokuWiki plugins to extend the parser/rendering mechanism
18 * need to inherit from this class
19 */
20class syntax_plugin_pglist extends DokuWiki_Syntax_Plugin {
21
22  function getInfo(){
23        return array(
24            'author' => 'Zaher Dirkey',
25            'email'  => 'zaherdirkey@yahoo.com',
26            'date'   => '2018-11-16',
27            'name'   => 'Page List Plugin',
28            'desc'   => 'List pages of namespace, based on nslist.',
29            'url'    => 'http://dokuwiki.org/plugin:pglist',
30        );
31    }
32/**
33 * What kind of syntax are we?
34 */
35    function getType(){
36        return 'substition';
37    }
38
39/**
40 * What about paragraphs?
41 */
42    function getPType(){
43        return 'block';
44    }
45
46/**
47 * Where to sort in?
48 */
49    function getSort(){
50        return 302;
51    }
52
53
54/**
55 * Connect pattern to lexer
56 */
57    function connectTo($mode) {
58        $this->Lexer->addSpecialPattern('{{pglist>[^}]*}}',$mode,'plugin_pglist');
59    }
60
61
62/**
63 * Handle the match
64 */
65    function handle($match, $state, $pos, Doku_Handler $handler){
66        global $ID;
67        $match = substr($match, 9, -2); //strip {{pglist> from start and }} from end
68
69        $conf = array(
70            'ns'    => getNS($ID),
71            'depth' => 1,
72            'dirs' => 0,
73            'files' => 0,
74            'me' => 0,
75            'sibling' => 0, //todo
76//            'same' => 0, /** If there is a dir have the same name of the file make it as namespace **/
77            'nostart' => 0,
78            'any' => 0,
79            'date'  => 0,
80            'fsort' => 0,
81            'dsort' => 0
82        );
83
84        list($ns, $params) = explode(' ', $match, 2);
85
86        if ($ns) {
87          if ($ns === '*') {
88            $conf['ns'] = cleanID($ID);
89          }
90          else if ($ns[0] === '/')
91            $conf['ns'] = cleanID($ns);
92          else
93            $conf['ns'] = cleanID('/'.getNS($ID).'/'.$ns);
94        }
95
96        if(preg_match('/\bdirs\b/i',$params)) $conf['dirs'] = 1;
97        if(preg_match('/\bfiles\b/i',$params)) $conf['files'] = 1;
98        if(preg_match('/\bme\b/i',$params)) $conf['me'] = 1;
99        if(preg_match('/\bsibling\b/i',$params)) $conf['sibling'] = 1;
100        if(preg_match('/\bsame\b/i',$params)) $conf['same'] = 1;
101        if(preg_match('/\bany\b/i',$params)) $conf['any'] = 1;
102        if(preg_match('/\bnostart\b/i',$params))  $conf['nostart'] = 1;
103        if(preg_match('/\bdate\b/i',$params)) $conf['date'] = 1;
104        if(preg_match('/\bfsort\b/i',$params)) $conf['fsort'] = 1;
105        if(preg_match('/\bdsort\b/i',$params)) $conf['dsort'] = 1;
106        if(preg_match('/\b(\d+)\b/i',$params,$m)) $conf['depth'] = $m[1];
107
108        $conf['dir'] = str_replace(':','/',$conf['ns']);
109
110        // prepare data
111        return $conf;
112    }
113
114/**
115 * Create output
116 */
117    function render($format, Doku_Renderer $renderer, $data) {
118        global $conf;
119        global $lang;
120        global $ID;
121        if($format != 'xhtml')
122          return false;
123
124        $opts = array(
125            'depth'     => $data['depth'],
126            'listfiles' => true,
127            'listdirs'  => false,
128            'pagesonly' => true,
129            'firsthead' => true,
130            'meta'      => true
131        );
132
133        if($data['dirs']) {
134           $opts['listdirs'] = true;
135          if ($data['files'])
136            $opts['listfiles'] = true;
137          else
138            $opts['listfiles'] = false;
139        }
140
141        // read the directory
142        $result = array();
143        search($result, $conf['datadir'], 'search_universal', $opts, $data['dir']);
144
145        if($data['fsort']){
146            usort($result,array($this,'_sort_file'));
147        }elseif($data['dsort']){
148            usort($result,array($this,'_sort_date'));
149        }else{
150            usort($result,array($this,'_sort_page'));
151        }
152
153        $start = cleanID($data['ns'].':'.$conf['start']);
154
155        $renderer->listu_open();
156        foreach($result as $item) {
157          $skip_it = false;
158          if ($data['nostart'] and ($item['file'] == $conf['start'].'.txt'))
159            $skip_it = true;
160          else if (!$data['me'] and ($item['id'] == $ID))
161            $skip_it = true;
162          else if (isHiddenPage($item['id']))
163            $skip_it = true;
164          else if ($item['type']=='d') {
165            $P = resolve_id($item['id'], $conf['start'], false);
166            if (!$data['any'] and !page_exists($P))
167              $skip_it = true;
168          } else
169            $P = ':'.$item['id'];
170
171          if (!$skip_it)
172          {
173            $renderer->listitem_open(1);
174            $renderer->listcontent_open();
175            $renderer->internallink($P);
176            if($data['date'])
177              $renderer->cdata(' '.dformat($item['mtime']));
178            $renderer->listcontent_close();
179            $renderer->listitem_close();
180          }
181        }
182        $renderer->listu_close();
183
184        return true;
185    }
186
187    function _sort_page($a,$b){
188      $r = strcmp($a['type'],$b['type']);
189      if ($r<>0)
190        return $r;
191      else
192        return strcmp($a['id'],$b['id']);
193    }
194
195    function _sort_file($a,$b){
196      $r = strcmp($a['type'],$b['type']);
197      if ($r<>0)
198        return $r;
199      else
200        return strcmp($a['file'],$b['file']);
201    }
202
203    function _sort_date($a,$b) {
204        if ($b['mtime'] < $a['mtime']) {
205            return -1;
206        } elseif($b['mtime'] > $a['mtime']) {
207            return 1;
208        } else {
209            return strcmp($a['id'],$b['id']);
210        }
211    }
212
213}
214