Failed Conditions
Push — psr2 ( 29fc53...957f36 )
by Andreas
07:13 queued 03:02
created

syntax_plugin_info::addToToc()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 2
nop 3
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Info Plugin: Displays information about various DokuWiki internals
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 * @author     Andreas Gohr <[email protected]>
7
 * @author     Esther Brunner <[email protected]>
8
 */
9
class syntax_plugin_info extends DokuWiki_Syntax_Plugin
10
{
11
12
    /**
13
     * What kind of syntax are we?
14
     */
15
    public function getType()
16
    {
17
        return 'substition';
18
    }
19
20
    /**
21
     * What about paragraphs?
22
     */
23
    public function getPType()
24
    {
25
        return 'block';
26
    }
27
28
    /**
29
     * Where to sort in?
30
     */
31
    public function getSort()
32
    {
33
        return 155;
34
    }
35
36
37
    /**
38
     * Connect pattern to lexer
39
     */
40
    public function connectTo($mode)
41
    {
42
        $this->Lexer->addSpecialPattern('~~INFO:\w+~~', $mode, 'plugin_info');
43
    }
44
45
    /**
46
     * Handle the match
47
     *
48
     * @param   string       $match   The text matched by the patterns
49
     * @param   int          $state   The lexer state for the match
50
     * @param   int          $pos     The character position of the matched text
51
     * @param   Doku_Handler $handler The Doku_Handler object
52
     * @return  array Return an array with all data you want to use in render
53
     */
54
    public function handle($match, $state, $pos, Doku_Handler $handler)
55
    {
56
        $match = substr($match, 7, -2); //strip ~~INFO: from start and ~~ from end
57
        return array(strtolower($match));
58
    }
59
60
    /**
61
     * Create output
62
     *
63
     * @param string $format   string     output format being rendered
64
     * @param Doku_Renderer    $renderer  the current renderer object
65
     * @param array            $data      data created by handler()
66
     * @return  boolean                 rendered correctly?
67
     */
68
    public function render($format, Doku_Renderer $renderer, $data)
69
    {
70
        if ($format == 'xhtml') {
71
            /** @var Doku_Renderer_xhtml $renderer */
72
            //handle various info stuff
73
            switch ($data[0]) {
74
                case 'syntaxmodes':
75
                    $renderer->doc .= $this->renderSyntaxModes();
76
                    break;
77
                case 'syntaxtypes':
78
                    $renderer->doc .= $this->renderSyntaxTypes();
79
                    break;
80
                case 'syntaxplugins':
81
                    $this->renderPlugins('syntax', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
82
                    break;
83
                case 'adminplugins':
84
                    $this->renderPlugins('admin', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
85
                    break;
86
                case 'actionplugins':
87
                    $this->renderPlugins('action', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
88
                    break;
89
                case 'rendererplugins':
90
                    $this->renderPlugins('renderer', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
91
                    break;
92
                case 'helperplugins':
93
                    $this->renderPlugins('helper', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
94
                    break;
95
                case 'authplugins':
96
                    $this->renderPlugins('auth', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
97
                    break;
98
                case 'remoteplugins':
99
                    $this->renderPlugins('remote', $renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
100
                    break;
101
                case 'helpermethods':
102
                    $this->renderHelperMethods($renderer);
0 ignored issues
show
Compatibility introduced by
$renderer of type object<Doku_Renderer> is not a sub-type of object<Doku_Renderer_xhtml>. It seems like you assume a child class of the class Doku_Renderer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
103
                    break;
104
                default:
105
                    $renderer->doc .= "no info about ".htmlspecialchars($data[0]);
106
            }
107
            return true;
108
        }
109
        return false;
110
    }
111
112
    /**
113
     * list all installed plugins
114
     *
115
     * uses some of the original renderer methods
116
     *
117
     * @param string $type
118
     * @param Doku_Renderer_xhtml $renderer
119
     */
120
    protected function renderPlugins($type, Doku_Renderer_xhtml $renderer)
121
    {
122
        global $lang;
123
        $renderer->doc .= '<ul>';
124
125
        $plugins = plugin_list($type);
126
        $plginfo = array();
127
128
        // remove subparts
129
        foreach ($plugins as $p) {
130
            if (!$po = plugin_load($type, $p)) continue;
131
            list($name,/* $part */) = explode('_', $p, 2);
132
            $plginfo[$name] = $po->getInfo();
133
        }
134
135
        // list them
136
        foreach ($plginfo as $info) {
137
            $renderer->doc .= '<li><div class="li">';
138
            $renderer->externallink($info['url'], $info['name']);
139
            $renderer->doc .= ' ';
140
            $renderer->doc .= '<em>'.$info['date'].'</em>';
141
            $renderer->doc .= ' ';
142
            $renderer->doc .= $lang['by'];
143
            $renderer->doc .= ' ';
144
            $renderer->emaillink($info['email'], $info['author']);
145
            $renderer->doc .= '<br />';
146
            $renderer->doc .= strtr(hsc($info['desc']), array("\n"=>"<br />"));
147
            $renderer->doc .= '</div></li>';
148
            unset($po);
149
        }
150
151
        $renderer->doc .= '</ul>';
152
    }
153
154
    /**
155
     * list all installed plugins
156
     *
157
     * uses some of the original renderer methods
158
     *
159
     * @param Doku_Renderer_xhtml $renderer
160
     */
161
    protected function renderHelperMethods(Doku_Renderer_xhtml $renderer)
162
    {
163
        $plugins = plugin_list('helper');
164
        foreach ($plugins as $p) {
165
            if (!$po = plugin_load('helper', $p)) continue;
166
167
            if (!method_exists($po, 'getMethods')) continue;
168
            $methods = $po->getMethods();
0 ignored issues
show
Bug introduced by
The method getMethods() does not seem to exist on object<DokuWiki_PluginInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
169
            $info = $po->getInfo();
170
171
            $hid = $this->addToToc($info['name'], 2, $renderer);
172
            $doc = '<h2><a name="'.$hid.'" id="'.$hid.'">'.hsc($info['name']).'</a></h2>';
173
            $doc .= '<div class="level2">';
174
            $doc .= '<p>'.strtr(hsc($info['desc']), array("\n"=>"<br />")).'</p>';
175
            $doc .= '<pre class="code">$'.$p." = plugin_load('helper', '".$p."');</pre>";
176
            $doc .= '</div>';
177
            foreach ($methods as $method) {
178
                $title = '$'.$p.'->'.$method['name'].'()';
179
                $hid = $this->addToToc($title, 3, $renderer);
180
                $doc .= '<h3><a name="'.$hid.'" id="'.$hid.'">'.hsc($title).'</a></h3>';
181
                $doc .= '<div class="level3">';
182
                $doc .= '<div class="table"><table class="inline"><tbody>';
183
                $doc .= '<tr><th>Description</th><td colspan="2">'.$method['desc'].
184
                    '</td></tr>';
185
                if ($method['params']) {
186
                    $c = count($method['params']);
187
                    $doc .= '<tr><th rowspan="'.$c.'">Parameters</th><td>';
188
                    $params = array();
189
                    foreach ($method['params'] as $desc => $type) {
190
                        $params[] = hsc($desc).'</td><td>'.hsc($type);
191
                    }
192
                    $doc .= join($params, '</td></tr><tr><td>').'</td></tr>';
193
                }
194
                if ($method['return']) {
195
                    $doc .= '<tr><th>Return value</th><td>'.hsc(key($method['return'])).
196
                        '</td><td>'.hsc(current($method['return'])).'</td></tr>';
197
                }
198
                $doc .= '</tbody></table></div>';
199
                $doc .= '</div>';
200
            }
201
            unset($po);
202
203
            $renderer->doc .= $doc;
204
        }
205
    }
206
207
    /**
208
     * lists all known syntax types and their registered modes
209
     *
210
     * @return string
211
     */
212
    protected function renderSyntaxTypes()
213
    {
214
        global $PARSER_MODES;
215
        $doc  = '';
216
217
        $doc .= '<div class="table"><table class="inline"><tbody>';
218
        foreach ($PARSER_MODES as $mode => $modes) {
219
            $doc .= '<tr>';
220
            $doc .= '<td class="leftalign">';
221
            $doc .= $mode;
222
            $doc .= '</td>';
223
            $doc .= '<td class="leftalign">';
224
            $doc .= join(', ', $modes);
225
            $doc .= '</td>';
226
            $doc .= '</tr>';
227
        }
228
        $doc .= '</tbody></table></div>';
229
        return $doc;
230
    }
231
232
    /**
233
     * lists all known syntax modes and their sorting value
234
     *
235
     * @return string
236
     */
237
    protected function renderSyntaxModes()
238
    {
239
        $modes = p_get_parsermodes();
240
241
        $compactmodes = array();
242
        foreach ($modes as $mode) {
0 ignored issues
show
Bug introduced by
The expression $modes of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
243
            $compactmodes[$mode['sort']][] = $mode['mode'];
244
        }
245
        $doc  = '';
246
        $doc .= '<div class="table"><table class="inline"><tbody>';
247
248
        foreach ($compactmodes as $sort => $modes) {
249
            $rowspan = '';
250
            if (count($modes) > 1) {
251
                $rowspan = ' rowspan="'.count($modes).'"';
252
            }
253
254
            foreach ($modes as $index => $mode) {
255
                $doc .= '<tr>';
256
                $doc .= '<td class="leftalign">';
257
                $doc .= $mode;
258
                $doc .= '</td>';
259
260
                if ($index === 0) {
261
                    $doc .= '<td class="rightalign" '.$rowspan.'>';
262
                    $doc .= $sort;
263
                    $doc .= '</td>';
264
                }
265
                $doc .= '</tr>';
266
            }
267
        }
268
269
        $doc .= '</tbody></table></div>';
270
        return $doc;
271
    }
272
273
    /**
274
     * Adds a TOC item
275
     *
276
     * @param string $text
277
     * @param int $level
278
     * @param Doku_Renderer_xhtml $renderer
279
     * @return string
280
     */
281
    protected function addToToc($text, $level, Doku_Renderer_xhtml $renderer)
282
    {
283
        global $conf;
284
285
        $hid = '';
286
        if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])) {
287
            $hid  = $renderer->_headerToLink($text, true);
288
            $renderer->toc[] = array(
289
                'hid'   => $hid,
290
                'title' => $text,
291
                'type'  => 'ul',
292
                'level' => $level - $conf['toptoclevel'] + 1
293
            );
294
        }
295
        return $hid;
296
    }
297
}
298
299
//Setup VIM: ex: et ts=4 :
300