xref: /dokuwiki/lib/plugins/info/syntax.php (revision 74981a4e680e4586b25ac0a679add084112cd604)
1<?php
2
3use dokuwiki\Extension\PluginInterface;
4/**
5 * Info Plugin: Displays information about various DokuWiki internals
6 *
7 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
8 * @author     Andreas Gohr <andi@splitbrain.org>
9 * @author     Esther Brunner <wikidesign@gmail.com>
10 */
11class syntax_plugin_info extends DokuWiki_Syntax_Plugin
12{
13
14    /**
15     * What kind of syntax are we?
16     */
17    public function getType()
18    {
19        return 'substition';
20    }
21
22    /**
23     * What about paragraphs?
24     */
25    public function getPType()
26    {
27        return 'block';
28    }
29
30    /**
31     * Where to sort in?
32     */
33    public function getSort()
34    {
35        return 155;
36    }
37
38    /**
39     * Connect pattern to lexer
40     */
41    public function connectTo($mode)
42    {
43        $this->Lexer->addSpecialPattern('~~INFO:\w+~~', $mode, 'plugin_info');
44    }
45
46    /**
47     * Handle the match
48     *
49     * @param string $match The text matched by the patterns
50     * @param int $state The lexer state for the match
51     * @param int $pos The character position of the matched text
52     * @param Doku_Handler $handler The Doku_Handler object
53     * @return  array Return an array with all data you want to use in render
54     */
55    public function handle($match, $state, $pos, Doku_Handler $handler)
56    {
57        $match = substr($match, 7, -2); //strip ~~INFO: from start and ~~ from end
58        return [strtolower($match)];
59    }
60
61    /**
62     * Create output
63     *
64     * @param string $format string     output format being rendered
65     * @param Doku_Renderer $renderer the current renderer object
66     * @param array $data data created by handler()
67     * @return  boolean                 rendered correctly?
68     */
69    public function render($format, Doku_Renderer $renderer, $data)
70    {
71        if ($format == 'xhtml') {
72            /** @var Doku_Renderer_xhtml $renderer */
73            //handle various info stuff
74            switch ($data[0]) {
75                case 'syntaxmodes':
76                    $renderer->doc .= $this->renderSyntaxModes();
77                    break;
78                case 'syntaxtypes':
79                    $renderer->doc .= $this->renderSyntaxTypes();
80                    break;
81                case 'syntaxplugins':
82                    $this->renderPlugins('syntax', $renderer);
83                    break;
84                case 'adminplugins':
85                    $this->renderPlugins('admin', $renderer);
86                    break;
87                case 'actionplugins':
88                    $this->renderPlugins('action', $renderer);
89                    break;
90                case 'rendererplugins':
91                    $this->renderPlugins('renderer', $renderer);
92                    break;
93                case 'helperplugins':
94                    $this->renderPlugins('helper', $renderer);
95                    break;
96                case 'authplugins':
97                    $this->renderPlugins('auth', $renderer);
98                    break;
99                case 'remoteplugins':
100                    $this->renderPlugins('remote', $renderer);
101                    break;
102                case 'helpermethods':
103                    $this->renderHelperMethods($renderer);
104                    break;
105                case 'hooks':
106                    $this->renderHooks($renderer);
107                    break;
108                case 'datetime':
109                    $renderer->doc .= date('r');
110                    break;
111                default:
112                    $renderer->doc .= "no info about " . htmlspecialchars($data[0]);
113            }
114            return true;
115        }
116        return false;
117    }
118
119    /**
120     * list all installed plugins
121     *
122     * uses some of the original renderer methods
123     *
124     * @param string $type
125     * @param Doku_Renderer $renderer
126     */
127    protected function renderPlugins($type, Doku_Renderer $renderer)
128    {
129        global $lang;
130        $plugins = plugin_list($type);
131        $plginfo = [];
132
133        // remove subparts
134        foreach ($plugins as $p) {
135            $po = plugin_load($type, $p);
136            if (! $po instanceof PluginInterface) continue;
137            [$name, ] = explode('_', $p, 2);
138            $plginfo[$name] = $po->getInfo();
139        }
140
141        // list them
142        $renderer->listu_open();
143        foreach ($plginfo as $info) {
144            $renderer->listitem_open(1);
145            $renderer->listcontent_open();
146            $renderer->externallink($info['url'], $info['name']);
147            $renderer->cdata(' ');
148            $renderer->emphasis_open();
149            $renderer->cdata($info['date']);
150            $renderer->emphasis_close();
151            $renderer->cdata(' ' . $lang['by'] . ' ');
152            $renderer->emaillink($info['email'], $info['author']);
153            $renderer->linebreak();
154            $renderer->cdata($info['desc']);
155            $renderer->listcontent_close();
156            $renderer->listitem_close();
157        }
158        $renderer->listu_close();
159    }
160
161    /**
162     * list all installed plugins
163     *
164     * uses some of the original renderer methods
165     *
166     * @param Doku_Renderer_xhtml $renderer
167     */
168    protected function renderHelperMethods(Doku_Renderer_xhtml $renderer)
169    {
170        $plugins = plugin_list('helper');
171        foreach ($plugins as $p) {
172            $po = plugin_load('helper', $p);
173            if (!$po instanceof PluginInterface) continue;
174
175            if (!method_exists($po, 'getMethods')) continue;
176            $methods = $po->getMethods();
177            $info = $po->getInfo();
178
179            $hid = $this->addToToc($info['name'], 2, $renderer);
180            $doc = '<h2><a name="' . $hid . '" id="' . $hid . '">' . hsc($info['name']) . '</a></h2>';
181            $doc .= '<div class="level2">';
182            $doc .= '<p>' . strtr(hsc($info['desc']), ["\n" => "<br />"]) . '</p>';
183            $doc .= '<pre class="code">$' . $p . " = plugin_load('helper', '" . $p . "');</pre>";
184            $doc .= '</div>';
185            foreach ($methods as $method) {
186                $title = '$' . $p . '->' . $method['name'] . '()';
187                $hid = $this->addToToc($title, 3, $renderer);
188                $doc .= '<h3><a name="' . $hid . '" id="' . $hid . '">' . hsc($title) . '</a></h3>';
189                $doc .= '<div class="level3">';
190                $doc .= '<div class="table"><table class="inline"><tbody>';
191                $doc .= '<tr><th>Description</th><td colspan="2">' . $method['desc'] .
192                    '</td></tr>';
193                if ($method['params']) {
194                    $c = count($method['params']);
195                    $doc .= '<tr><th rowspan="' . $c . '">Parameters</th><td>';
196                    $params = [];
197                    foreach ($method['params'] as $desc => $type) {
198                        $params[] = hsc($desc) . '</td><td>' . hsc($type);
199                    }
200                    $doc .= implode('</td></tr><tr><td>', $params) . '</td></tr>';
201                }
202                if ($method['return']) {
203                    $doc .= '<tr><th>Return value</th><td>' . hsc(key($method['return'])) .
204                        '</td><td>' . hsc(current($method['return'])) . '</td></tr>';
205                }
206                $doc .= '</tbody></table></div>';
207                $doc .= '</div>';
208            }
209            unset($po);
210
211            $renderer->doc .= $doc;
212        }
213    }
214
215    /**
216     * lists all known syntax types and their registered modes
217     *
218     * @return string
219     */
220    protected function renderSyntaxTypes()
221    {
222        global $PARSER_MODES;
223        $doc = '';
224
225        $doc .= '<div class="table"><table class="inline"><tbody>';
226        foreach ($PARSER_MODES as $mode => $modes) {
227            $doc .= '<tr>';
228            $doc .= '<td class="leftalign">';
229            $doc .= $mode;
230            $doc .= '</td>';
231            $doc .= '<td class="leftalign">';
232            $doc .= implode(', ', $modes);
233            $doc .= '</td>';
234            $doc .= '</tr>';
235        }
236        $doc .= '</tbody></table></div>';
237        return $doc;
238    }
239
240    /**
241     * lists all known syntax modes and their sorting value
242     *
243     * @return string
244     */
245    protected function renderSyntaxModes()
246    {
247        $modes = p_get_parsermodes();
248
249        $compactmodes = [];
250        foreach ($modes as $mode) {
251            $compactmodes[$mode['sort']][] = $mode['mode'];
252        }
253        $doc = '';
254        $doc .= '<div class="table"><table class="inline"><tbody>';
255
256        foreach ($compactmodes as $sort => $modes) {
257            $rowspan = '';
258            if (count($modes) > 1) {
259                $rowspan = ' rowspan="' . count($modes) . '"';
260            }
261
262            foreach ($modes as $index => $mode) {
263                $doc .= '<tr>';
264                $doc .= '<td class="leftalign">';
265                $doc .= $mode;
266                $doc .= '</td>';
267
268                if ($index === 0) {
269                    $doc .= '<td class="rightalign" ' . $rowspan . '>';
270                    $doc .= $sort;
271                    $doc .= '</td>';
272                }
273                $doc .= '</tr>';
274            }
275        }
276
277        $doc .= '</tbody></table></div>';
278        return $doc;
279    }
280
281    /**
282     * Render all currently registered event handlers
283     *
284     * @param Doku_Renderer $renderer
285     */
286    protected function renderHooks(Doku_Renderer $renderer)
287    {
288        global $EVENT_HANDLER;
289
290        $list = $EVENT_HANDLER->getEventHandlers();
291        ksort($list);
292
293        $renderer->listu_open();
294        foreach ($list as $event => $handlers) {
295            $renderer->listitem_open(1);
296            $renderer->listcontent_open();
297            $renderer->cdata($event);
298            $renderer->listcontent_close();
299
300            $renderer->listo_open();
301            foreach ($handlers as $sequence) {
302                foreach ($sequence as $handler) {
303                    $renderer->listitem_open(2);
304                    $renderer->listcontent_open();
305                    $renderer->cdata(get_class($handler[0]) . '::' . $handler[1] . '()');
306                    $renderer->listcontent_close();
307                    $renderer->listitem_close();
308                }
309            }
310            $renderer->listo_close();
311            $renderer->listitem_close();
312        }
313        $renderer->listu_close();
314    }
315
316    /**
317     * Adds a TOC item
318     *
319     * @param string $text
320     * @param int $level
321     * @param Doku_Renderer_xhtml $renderer
322     * @return string
323     */
324    protected function addToToc($text, $level, Doku_Renderer_xhtml $renderer)
325    {
326        global $conf;
327
328        $hid = '';
329        if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])) {
330            $hid = $renderer->_headerToLink($text, true);
331            $renderer->toc[] = [
332                'hid' => $hid,
333                'title' => $text,
334                'type' => 'ul',
335                'level' => $level - $conf['toptoclevel'] + 1
336            ];
337        }
338        return $hid;
339    }
340}
341