Completed
Push — sidebaracl ( 7a112d...7c3e4a )
by Andreas
04:38
created

syntax_plugin_info::_helpermethods_xhtml()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 44
Code Lines 35

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 44
rs 5.3846
cc 8
eloc 35
nc 8
nop 1
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
// must be run within Dokuwiki
10
if(!defined('DOKU_INC')) die();
11
12
/**
13
 * All DokuWiki plugins to extend the parser/rendering mechanism
14
 * need to inherit from this class
15
 */
16
class syntax_plugin_info extends DokuWiki_Syntax_Plugin {
17
18
    /**
19
     * What kind of syntax are we?
20
     */
21
    function getType(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
22
        return 'substition';
23
    }
24
25
    /**
26
     * What about paragraphs?
27
     */
28
    function getPType(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
29
        return 'block';
30
    }
31
32
    /**
33
     * Where to sort in?
34
     */
35
    function getSort(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
36
        return 155;
37
    }
38
39
40
    /**
41
     * Connect pattern to lexer
42
     */
43
    function connectTo($mode) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
44
        $this->Lexer->addSpecialPattern('~~INFO:\w+~~',$mode,'plugin_info');
0 ignored issues
show
Bug introduced by
The property Lexer cannot be accessed from this context as it is declared private in class Doku_Parser_Mode_Plugin.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
45
    }
46
47
    /**
48
     * Handle the match
49
     *
50
     * @param   string       $match   The text matched by the patterns
51
     * @param   int          $state   The lexer state for the match
52
     * @param   int          $pos     The character position of the matched text
53
     * @param   Doku_Handler $handler The Doku_Handler object
54
     * @return  array Return an array with all data you want to use in render
55
     */
56
    function handle($match, $state, $pos, Doku_Handler $handler){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
57
        $match = substr($match,7,-2); //strip ~~INFO: from start and ~~ from end
58
        return array(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
    function render($format, Doku_Renderer $renderer, $data) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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->_syntaxmodes_xhtml();
76
                    break;
77
                case 'syntaxtypes':
78
                    $renderer->doc .= $this->_syntaxtypes_xhtml();
79
                    break;
80
                case 'syntaxplugins':
81
                    $this->_plugins_xhtml('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->_plugins_xhtml('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->_plugins_xhtml('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->_plugins_xhtml('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->_plugins_xhtml('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->_plugins_xhtml('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->_plugins_xhtml('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->_helpermethods_xhtml($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
    function _plugins_xhtml($type, Doku_Renderer_xhtml $renderer){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
121
        global $lang;
122
        $renderer->doc .= '<ul>';
123
124
        $plugins = plugin_list($type);
125
        $plginfo = array();
126
127
        // remove subparts
128
        foreach($plugins as $p){
129
            if (!$po = plugin_load($type,$p)) continue;
130
            list($name,/* $part */) = explode('_',$p,2);
131
            $plginfo[$name] = $po->getInfo();
132
        }
133
134
        // list them
135
        foreach($plginfo as $info){
136
            $renderer->doc .= '<li><div class="li">';
137
            $renderer->externallink($info['url'],$info['name']);
138
            $renderer->doc .= ' ';
139
            $renderer->doc .= '<em>'.$info['date'].'</em>';
140
            $renderer->doc .= ' ';
141
            $renderer->doc .= $lang['by'];
142
            $renderer->doc .= ' ';
143
            $renderer->emaillink($info['email'],$info['author']);
144
            $renderer->doc .= '<br />';
145
            $renderer->doc .= strtr(hsc($info['desc']),array("\n"=>"<br />"));
146
            $renderer->doc .= '</div></li>';
147
            unset($po);
148
        }
149
150
        $renderer->doc .= '</ul>';
151
    }
152
153
    /**
154
     * list all installed plugins
155
     *
156
     * uses some of the original renderer methods
157
     *
158
     * @param Doku_Renderer_xhtml $renderer
159
     */
160
    function _helpermethods_xhtml(Doku_Renderer_xhtml $renderer){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
161
        $plugins = plugin_list('helper');
162
        foreach($plugins as $p){
163
            if (!$po = plugin_load('helper',$p)) continue;
164
165
            if (!method_exists($po, 'getMethods')) continue;
166
            $methods = $po->getMethods();
0 ignored issues
show
Documentation Bug introduced by
The method getMethods does not exist on object<DokuWiki_Plugin>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
167
            $info = $po->getInfo();
168
169
            $hid = $this->_addToTOC($info['name'], 2, $renderer);
170
            $doc = '<h2><a name="'.$hid.'" id="'.$hid.'">'.hsc($info['name']).'</a></h2>';
171
            $doc .= '<div class="level2">';
172
            $doc .= '<p>'.strtr(hsc($info['desc']), array("\n"=>"<br />")).'</p>';
173
            $doc .= '<pre class="code">$'.$p." = plugin_load('helper', '".$p."');</pre>";
174
            $doc .= '</div>';
175
            foreach ($methods as $method){
176
                $title = '$'.$p.'->'.$method['name'].'()';
177
                $hid = $this->_addToTOC($title, 3, $renderer);
178
                $doc .= '<h3><a name="'.$hid.'" id="'.$hid.'">'.hsc($title).'</a></h3>';
179
                $doc .= '<div class="level3">';
180
                $doc .= '<div class="table"><table class="inline"><tbody>';
181
                $doc .= '<tr><th>Description</th><td colspan="2">'.$method['desc'].
182
                    '</td></tr>';
183
                if ($method['params']){
184
                    $c = count($method['params']);
185
                    $doc .= '<tr><th rowspan="'.$c.'">Parameters</th><td>';
186
                    $params = array();
187
                    foreach ($method['params'] as $desc => $type){
188
                        $params[] = hsc($desc).'</td><td>'.hsc($type);
189
                    }
190
                    $doc .= join($params, '</td></tr><tr><td>').'</td></tr>';
191
                }
192
                if ($method['return']){
193
                    $doc .= '<tr><th>Return value</th><td>'.hsc(key($method['return'])).
194
                        '</td><td>'.hsc(current($method['return'])).'</td></tr>';
195
                }
196
                $doc .= '</tbody></table></div>';
197
                $doc .= '</div>';
198
            }
199
            unset($po);
200
201
            $renderer->doc .= $doc;
202
        }
203
    }
204
205
    /**
206
     * lists all known syntax types and their registered modes
207
     *
208
     * @return string
209
     */
210
    function _syntaxtypes_xhtml(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
211
        global $PARSER_MODES;
212
        $doc  = '';
213
214
        $doc .= '<div class="table"><table class="inline"><tbody>';
215
        foreach($PARSER_MODES as $mode => $modes){
216
            $doc .= '<tr>';
217
            $doc .= '<td class="leftalign">';
218
            $doc .= $mode;
219
            $doc .= '</td>';
220
            $doc .= '<td class="leftalign">';
221
            $doc .= join(', ',$modes);
222
            $doc .= '</td>';
223
            $doc .= '</tr>';
224
        }
225
        $doc .= '</tbody></table></div>';
226
        return $doc;
227
    }
228
229
    /**
230
     * lists all known syntax modes and their sorting value
231
     *
232
     * @return string
233
     */
234
    function _syntaxmodes_xhtml(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

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