Failed Conditions
Push — psr2 ( 64159a )
by Andreas
07:54 queued 04:15
created

helper_plugin_extension_list   D

Complexity

Total Complexity 97

Size/Duplication

Total Lines 591
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 591
rs 4.8717
c 0
b 0
f 0
wmc 97
lcom 1
cbo 3

25 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A start_form() 0 10 1
A add_row() 0 6 1
A add_header() 0 3 1
A add_p() 0 3 1
A add_hidden() 0 7 2
A end_form() 0 4 1
A nothing_found() 0 4 1
A render() 0 3 1
A start_row() 0 4 1
A populate_column() 0 3 1
A end_row() 0 3 1
A make_homepagelink() 0 5 1
B make_class() 0 12 7
A make_author() 0 18 3
A make_screenshot() 0 23 3
B make_legend() 0 47 6
B make_linkbar() 0 25 5
C make_noticearea() 0 46 7
A shortlink() 0 12 3
F make_info() 0 85 19
A make_linklist() 0 8 2
D make_actions() 0 60 18
A make_action() 0 16 3
B make_status() 0 21 7

How to fix   Complexity   

Complex Class

Complex classes like helper_plugin_extension_list often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use helper_plugin_extension_list, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * DokuWiki Plugin extension (Helper Component)
4
 *
5
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6
 * @author  Michael Hamann <[email protected]>
7
 */
8
9
/**
10
 * Class helper_plugin_extension_list takes care of creating a HTML list of extensions
11
 */
12
class helper_plugin_extension_list extends DokuWiki_Plugin {
13
    protected $form = '';
14
    /** @var  helper_plugin_extension_gui */
15
    protected $gui;
16
17
    /**
18
     * Constructor
19
     *
20
     * loads additional helpers
21
     */
22
    public function __construct(){
23
        $this->gui = plugin_load('helper', 'extension_gui');
0 ignored issues
show
Documentation Bug introduced by
It seems like plugin_load('helper', 'extension_gui') can also be of type object<DokuWiki_PluginInterface>. However, the property $gui is declared as type object<helper_plugin_extension_gui>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
24
    }
25
26
    function start_form() {
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...
27
        $this->form .= '<form id="extension__list" accept-charset="utf-8" method="post" action="">';
28
        $hidden = array(
29
            'do'=>'admin',
30
            'page'=>'extension',
31
            'sectok'=>getSecurityToken()
32
        );
33
        $this->add_hidden($hidden);
34
        $this->form .= '<ul class="extensionList">';
35
    }
36
    /**
37
     * Build single row of extension table
38
     * @param helper_plugin_extension_extension  $extension The extension that shall be added
39
     * @param bool                               $showinfo  Show the info area
40
     */
41
    function add_row(helper_plugin_extension_extension $extension, $showinfo = false) {
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...
42
        $this->start_row($extension);
43
        $this->populate_column('legend', $this->make_legend($extension, $showinfo));
44
        $this->populate_column('actions', $this->make_actions($extension));
45
        $this->end_row();
46
    }
47
48
    /**
49
     * Adds a header to the form
50
     *
51
     * @param string $id     The id of the header
52
     * @param string $header The content of the header
53
     * @param int    $level  The level of the header
54
     */
55
    function add_header($id, $header, $level = 2) {
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...
56
        $this->form .='<h'.$level.' id="'.$id.'">'.hsc($header).'</h'.$level.'>'.DOKU_LF;
57
    }
58
59
    /**
60
     * Adds a paragraph to the form
61
     *
62
     * @param string $data The content
63
     */
64
    function add_p($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...
65
        $this->form .= '<p>'.hsc($data).'</p>'.DOKU_LF;
66
    }
67
68
    /**
69
     * Add hidden fields to the form with the given data
70
     * @param array $array
71
     */
72
    function add_hidden(array $array) {
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...
73
        $this->form .= '<div class="no">';
74
        foreach ($array as $key => $value) {
75
            $this->form .= '<input type="hidden" name="'.hsc($key).'" value="'.hsc($value).'" />';
76
        }
77
        $this->form .= '</div>'.DOKU_LF;
78
    }
79
80
    /**
81
     * Add closing tags
82
     */
83
    function end_form() {
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...
84
        $this->form .= '</ul>';
85
        $this->form .= '</form>'.DOKU_LF;
86
    }
87
88
    /**
89
     * Show message when no results are found
90
     */
91
    function nothing_found() {
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...
92
        global $lang;
93
        $this->form .= '<li class="notfound">'.$lang['nothingfound'].'</li>';
94
    }
95
96
    /**
97
     * Print the form
98
     */
99
    function render() {
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...
100
        echo $this->form;
101
    }
102
103
    /**
104
     * Start the HTML for the row for the extension
105
     *
106
     * @param helper_plugin_extension_extension $extension The extension
107
     */
108
    private function start_row(helper_plugin_extension_extension $extension) {
109
        $this->form .= '<li id="extensionplugin__'.hsc($extension->getID()).
110
            '" class="'.$this->make_class($extension).'">';
111
    }
112
113
    /**
114
     * Add a column with the given class and content
115
     * @param string $class The class name
116
     * @param string $html  The content
117
     */
118
    private function populate_column($class, $html) {
119
        $this->form .= '<div class="'.$class.' col">'.$html.'</div>'.DOKU_LF;
120
    }
121
122
    /**
123
     * End the row
124
     */
125
    private function end_row() {
126
        $this->form .= '</li>'.DOKU_LF;
127
    }
128
129
    /**
130
     * Generate the link to the plugin homepage
131
     *
132
     * @param helper_plugin_extension_extension $extension The extension
133
     * @return string The HTML code
134
     */
135
    function make_homepagelink(helper_plugin_extension_extension $extension) {
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...
136
        $text = $this->getLang('homepage_link');
137
        $url = hsc($extension->getURL());
138
        return '<a href="'.$url.'" title="'.$url.'" class ="urlextern">'.$text.'</a> ';
139
    }
140
141
    /**
142
     * Generate the class name for the row of the extensio
143
     *
144
     * @param helper_plugin_extension_extension $extension The extension object
145
     * @return string The class name
146
     */
147
    function make_class(helper_plugin_extension_extension $extension) {
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...
148
        $class = ($extension->isTemplate()) ? 'template' : 'plugin';
149
        if($extension->isInstalled()) {
150
            $class.=' installed';
151
            $class.= ($extension->isEnabled()) ? ' enabled':' disabled';
152
            if($extension->updateAvailable()) $class .= ' updatable';
153
        }
154
        if(!$extension->canModify()) $class.= ' notselect';
155
        if($extension->isProtected()) $class.=  ' protected';
156
        //if($this->showinfo) $class.= ' showinfo';
157
        return $class;
158
    }
159
160
    /**
161
     * Generate a link to the author of the extension
162
     *
163
     * @param helper_plugin_extension_extension $extension The extension object
164
     * @return string The HTML code of the link
165
     */
166
    function make_author(helper_plugin_extension_extension $extension) {
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...
167
        global $ID;
168
169
        if($extension->getAuthor()) {
170
171
            $mailid = $extension->getEmailID();
172
            if($mailid){
173
                $url = $this->gui->tabURL('search', array('q' => 'authorid:'.$mailid));
174
                return '<bdi><a href="'.$url.'" class="author" title="'.$this->getLang('author_hint').'" >'.
175
                    '<img src="//www.gravatar.com/avatar/'.$mailid.'?s=20&amp;d=mm" width="20" height="20" alt="" /> '.
176
                    hsc($extension->getAuthor()).'</a></bdi>';
0 ignored issues
show
Bug introduced by
It seems like $extension->getAuthor() targeting helper_plugin_extension_extension::getAuthor() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
177
178
            }else{
179
                return '<bdi><span class="author">'.hsc($extension->getAuthor()).'</span></bdi>';
0 ignored issues
show
Bug introduced by
It seems like $extension->getAuthor() targeting helper_plugin_extension_extension::getAuthor() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
180
            }
181
        }
182
        return "<em class=\"author\">".$this->getLang('unknown_author')."</em>".DOKU_LF;
183
    }
184
185
    /**
186
     * Get the link and image tag for the screenshot/thumbnail
187
     *
188
     * @param helper_plugin_extension_extension $extension The extension object
189
     * @return string The HTML code
190
     */
191
    function make_screenshot(helper_plugin_extension_extension $extension) {
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...
192
        $screen = $extension->getScreenshotURL();
193
        $thumb = $extension->getThumbnailURL();
194
195
        if($screen) {
196
            // use protocol independent URLs for images coming from us #595
197
            $screen = str_replace('http://www.dokuwiki.org', '//www.dokuwiki.org', $screen);
198
            $thumb = str_replace('http://www.dokuwiki.org', '//www.dokuwiki.org', $thumb);
199
200
            $title = sprintf($this->getLang('screenshot'), hsc($extension->getDisplayName()));
201
            $img = '<a href="'.hsc($screen).'" target="_blank" class="extension_screenshot">'.
202
                '<img alt="'.$title.'" width="120" height="70" src="'.hsc($thumb).'" />'.
203
                '</a>';
204
        } elseif($extension->isTemplate()) {
205
            $img = '<img alt="" width="120" height="70" src="'.DOKU_BASE.
206
                'lib/plugins/extension/images/template.png" />';
207
208
        } else {
209
            $img = '<img alt="" width="120" height="70" src="'.DOKU_BASE.
210
                'lib/plugins/extension/images/plugin.png" />';
211
        }
212
        return '<div class="screenshot" >'.$img.'<span></span></div>'.DOKU_LF;
213
    }
214
215
    /**
216
     * Extension main description
217
     *
218
     * @param helper_plugin_extension_extension $extension The extension object
219
     * @param bool                              $showinfo  Show the info section
220
     * @return string The HTML code
221
     */
222
    function make_legend(helper_plugin_extension_extension $extension, $showinfo = false) {
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...
223
        $return  = '<div>';
224
        $return .= '<h2>';
225
        $return .= sprintf(
226
            $this->getLang('extensionby'),
227
            '<bdi>'.hsc($extension->getDisplayName()).'</bdi>',
228
            $this->make_author($extension)
229
        );
230
        $return .= '</h2>'.DOKU_LF;
231
232
        $return .= $this->make_screenshot($extension);
233
234
        $popularity = $extension->getPopularity();
235
        if ($popularity !== false && !$extension->isBundled()) {
236
            $popularityText = sprintf($this->getLang('popularity'), round($popularity*100, 2));
237
            $return .= '<div class="popularity" title="'.$popularityText.'">'.
238
                '<div style="width: '.($popularity * 100).'%;">'.
239
                '<span class="a11y">'.$popularityText.'</span>'.
240
                '</div></div>'.DOKU_LF;
241
        }
242
243
        if($extension->getDescription()) {
244
            $return .= '<p><bdi>';
245
            $return .=  hsc($extension->getDescription()).' ';
246
            $return .= '</bdi></p>'.DOKU_LF;
247
        }
248
249
        $return .= $this->make_linkbar($extension);
250
251
        if($showinfo){
252
            $url = $this->gui->tabURL('');
253
            $class = 'close';
254
        }else{
255
            $url = $this->gui->tabURL('', array('info' => $extension->getID()));
256
            $class = '';
257
        }
258
        $return .= ' <a href="'.$url.'#extensionplugin__'.$extension->getID().
259
            '" class="info '.$class.'" title="'.$this->getLang('btn_info').
260
            '" data-extid="'.$extension->getID().'">'.$this->getLang('btn_info').'</a>';
261
262
        if ($showinfo) {
263
            $return .= $this->make_info($extension);
264
        }
265
        $return .= $this->make_noticearea($extension);
266
        $return .= '</div>'.DOKU_LF;
267
        return $return;
268
    }
269
270
    /**
271
     * Generate the link bar HTML code
272
     *
273
     * @param helper_plugin_extension_extension $extension The extension instance
274
     * @return string The HTML code
275
     */
276
    function make_linkbar(helper_plugin_extension_extension $extension) {
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...
277
        $return  = '<div class="linkbar">';
278
        $return .= $this->make_homepagelink($extension);
279
        if ($extension->getBugtrackerURL()) {
280
            $return .= ' <a href="'.hsc($extension->getBugtrackerURL()).
0 ignored issues
show
Bug introduced by
It seems like $extension->getBugtrackerURL() targeting helper_plugin_extension_...ion::getBugtrackerURL() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
281
                '" title="'.hsc($extension->getBugtrackerURL()).'" class ="bugs">'.
0 ignored issues
show
Bug introduced by
It seems like $extension->getBugtrackerURL() targeting helper_plugin_extension_...ion::getBugtrackerURL() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
282
                $this->getLang('bugs_features').'</a> ';
283
        }
284
        if ($extension->getTags()){
285
            $first = true;
286
            $return .= '<span class="tags">'.$this->getLang('tags').' ';
287
            foreach ($extension->getTags() as $tag) {
288
                if (!$first){
289
                    $return .= ', ';
290
                } else {
291
                    $first = false;
292
                }
293
                $url = $this->gui->tabURL('search', array('q' => 'tag:'.$tag));
294
                $return .= '<bdi><a href="'.$url.'">'.hsc($tag).'</a></bdi>';
295
            }
296
            $return .= '</span>';
297
        }
298
        $return .= '</div>'.DOKU_LF;
299
        return $return;
300
    }
301
302
    /**
303
     * Notice area
304
     *
305
     * @param helper_plugin_extension_extension $extension The extension
306
     * @return string The HTML code
307
     */
308
    function make_noticearea(helper_plugin_extension_extension $extension) {
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...
309
        $return = '';
310
        $missing_dependencies = $extension->getMissingDependencies();
311
        if(!empty($missing_dependencies)) {
312
            $return .= '<div class="msg error">' .
313
                sprintf(
314
                    $this->getLang('missing_dependency'),
315
                    '<bdi>' . implode(', ', $missing_dependencies) . '</bdi>'
316
                ) .
317
                '</div>';
318
        }
319
        if($extension->isInWrongFolder()) {
320
            $return .= '<div class="msg error">' .
321
                sprintf(
322
                    $this->getLang('wrong_folder'),
323
                    '<bdi>' . hsc($extension->getInstallName()) . '</bdi>',
324
                    '<bdi>' . hsc($extension->getBase()) . '</bdi>'
325
                ) .
326
                '</div>';
327
        }
328
        if(($securityissue = $extension->getSecurityIssue()) !== false) {
329
            $return .= '<div class="msg error">'.
330
                sprintf($this->getLang('security_issue'), '<bdi>'.hsc($securityissue).'</bdi>').
331
                '</div>';
332
        }
333
        if(($securitywarning = $extension->getSecurityWarning()) !== false) {
334
            $return .= '<div class="msg notify">'.
335
                sprintf($this->getLang('security_warning'), '<bdi>'.hsc($securitywarning).'</bdi>').
336
                '</div>';
337
        }
338
        if($extension->updateAvailable()) {
339
            $return .=  '<div class="msg notify">'.
340
                sprintf($this->getLang('update_available'), hsc($extension->getLastUpdate())).
0 ignored issues
show
Bug introduced by
It seems like $extension->getLastUpdate() targeting helper_plugin_extension_extension::getLastUpdate() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
341
                '</div>';
342
        }
343
        if($extension->hasDownloadURLChanged()) {
344
            $return .= '<div class="msg notify">' .
345
                sprintf(
346
                    $this->getLang('url_change'),
347
                    '<bdi>' . hsc($extension->getDownloadURL()) . '</bdi>',
0 ignored issues
show
Bug introduced by
It seems like $extension->getDownloadURL() targeting helper_plugin_extension_...nsion::getDownloadURL() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
348
                    '<bdi>' . hsc($extension->getLastDownloadURL()) . '</bdi>'
0 ignored issues
show
Bug introduced by
It seems like $extension->getLastDownloadURL() targeting helper_plugin_extension_...n::getLastDownloadURL() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
349
                ) .
350
                '</div>';
351
        }
352
        return $return.DOKU_LF;
353
    }
354
355
    /**
356
     * Create a link from the given URL
357
     *
358
     * Shortens the URL for display
359
     *
360
     * @param string $url
361
     * @return string  HTML link
362
     */
363
    function shortlink($url){
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...
364
        $link = parse_url($url);
365
366
        $base = $link['host'];
367
        if(!empty($link['port'])) $base .= $base.':'.$link['port'];
368
        $long = $link['path'];
369
        if(!empty($link['query'])) $long .= $link['query'];
370
371
        $name = shorten($base, $long, 55);
372
373
        return '<a href="'.hsc($url).'" class="urlextern">'.hsc($name).'</a>';
374
    }
375
376
    /**
377
     * Plugin/template details
378
     *
379
     * @param helper_plugin_extension_extension $extension The extension
380
     * @return string The HTML code
381
     */
382
    function make_info(helper_plugin_extension_extension $extension) {
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...
383
        $default = $this->getLang('unknown');
384
        $return = '<dl class="details">';
385
386
        $return .= '<dt>'.$this->getLang('status').'</dt>';
387
        $return .= '<dd>'.$this->make_status($extension).'</dd>';
388
389
        if ($extension->getDonationURL()) {
390
            $return .= '<dt>'.$this->getLang('donate').'</dt>';
391
            $return .= '<dd>';
392
            $return .= '<a href="'.$extension->getDonationURL().'" class="donate">'.
393
                $this->getLang('donate_action').'</a>';
394
            $return .= '</dd>';
395
        }
396
397
        if (!$extension->isBundled()) {
398
            $return .= '<dt>'.$this->getLang('downloadurl').'</dt>';
399
            $return .= '<dd><bdi>';
400
            $return .= ($extension->getDownloadURL() ? $this->shortlink($extension->getDownloadURL()) : $default);
0 ignored issues
show
Bug introduced by
It seems like $extension->getDownloadURL() targeting helper_plugin_extension_...nsion::getDownloadURL() can also be of type boolean; however, helper_plugin_extension_list::shortlink() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
401
            $return .= '</bdi></dd>';
402
403
            $return .= '<dt>'.$this->getLang('repository').'</dt>';
404
            $return .= '<dd><bdi>';
405
            $return .= ($extension->getSourcerepoURL() ? $this->shortlink($extension->getSourcerepoURL()) : $default);
0 ignored issues
show
Bug introduced by
It seems like $extension->getSourcerepoURL() targeting helper_plugin_extension_...ion::getSourcerepoURL() can also be of type boolean; however, helper_plugin_extension_list::shortlink() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
406
            $return .= '</bdi></dd>';
407
        }
408
409
        if ($extension->isInstalled()) {
410
            if ($extension->getInstalledVersion()) {
411
                $return .= '<dt>'.$this->getLang('installed_version').'</dt>';
412
                $return .= '<dd>';
413
                $return .= hsc($extension->getInstalledVersion());
0 ignored issues
show
Bug introduced by
It seems like $extension->getInstalledVersion() targeting helper_plugin_extension_...::getInstalledVersion() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
414
                $return .= '</dd>';
415
            }
416
            if (!$extension->isBundled()) {
417
                $return .= '<dt>'.$this->getLang('install_date').'</dt>';
418
                $return .= '<dd>';
419
                $return .= ($extension->getUpdateDate() ? hsc($extension->getUpdateDate()) : $this->getLang('unknown'));
0 ignored issues
show
Bug introduced by
It seems like $extension->getUpdateDate() targeting helper_plugin_extension_extension::getUpdateDate() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
420
                $return .= '</dd>';
421
            }
422
        }
423
        if (!$extension->isInstalled() || $extension->updateAvailable()) {
424
            $return .= '<dt>'.$this->getLang('available_version').'</dt>';
425
            $return .= '<dd>';
426
            $return .= ($extension->getLastUpdate() ? hsc($extension->getLastUpdate()) : $this->getLang('unknown'));
0 ignored issues
show
Bug introduced by
It seems like $extension->getLastUpdate() targeting helper_plugin_extension_extension::getLastUpdate() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
427
            $return .= '</dd>';
428
        }
429
430
        $return .= '<dt>'.$this->getLang('provides').'</dt>';
431
        $return .= '<dd><bdi>';
432
        $return .= ($extension->getTypes() ? hsc(implode(', ', $extension->getTypes())) : $default);
433
        $return .= '</bdi></dd>';
434
435
        if(!$extension->isBundled() && $extension->getCompatibleVersions()) {
436
            $return .= '<dt>'.$this->getLang('compatible').'</dt>';
437
            $return .= '<dd>';
438
            foreach ($extension->getCompatibleVersions() as $date => $version) {
439
                $return .= '<bdi>'.$version['label'].' ('.$date.')</bdi>, ';
440
            }
441
            $return = rtrim($return, ', ');
442
            $return .= '</dd>';
443
        }
444
        if($extension->getDependencies()) {
445
            $return .= '<dt>'.$this->getLang('depends').'</dt>';
446
            $return .= '<dd>';
447
            $return .= $this->make_linklist($extension->getDependencies());
448
            $return .= '</dd>';
449
        }
450
451
        if($extension->getSimilarExtensions()) {
452
            $return .= '<dt>'.$this->getLang('similar').'</dt>';
453
            $return .= '<dd>';
454
            $return .= $this->make_linklist($extension->getSimilarExtensions());
455
            $return .= '</dd>';
456
        }
457
458
        if($extension->getConflicts()) {
459
            $return .= '<dt>'.$this->getLang('conflicts').'</dt>';
460
            $return .= '<dd>';
461
            $return .= $this->make_linklist($extension->getConflicts());
462
            $return .= '</dd>';
463
        }
464
        $return .= '</dl>'.DOKU_LF;
465
        return $return;
466
    }
467
468
    /**
469
     * Generate a list of links for extensions
470
     *
471
     * @param array $ext The extensions
472
     * @return string The HTML code
473
     */
474
    function make_linklist($ext) {
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...
475
        $return = '';
476
        foreach ($ext as $link) {
477
            $return .= '<bdi><a href="'.
478
                $this->gui->tabURL('search', array('q'=>'ext:'.$link)).'">'.hsc($link).'</a></bdi>, ';
479
        }
480
        return rtrim($return, ', ');
481
    }
482
483
    /**
484
     * Display the action buttons if they are possible
485
     *
486
     * @param helper_plugin_extension_extension $extension The extension
487
     * @return string The HTML code
488
     */
489
    function make_actions(helper_plugin_extension_extension $extension) {
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...
490
        global $conf;
491
        $return = '';
492
        $errors = '';
493
494
        if ($extension->isInstalled()) {
495
            if (($canmod = $extension->canModify()) === true) {
496
                if (!$extension->isProtected()) {
497
                    $return .= $this->make_action('uninstall', $extension);
498
                }
499
                if ($extension->getDownloadURL()) {
500
                    if ($extension->updateAvailable()) {
501
                        $return .= $this->make_action('update', $extension);
502
                    } else {
503
                        $return .= $this->make_action('reinstall', $extension);
504
                    }
505
                }
506
            }else{
507
                $errors .= '<p class="permerror">'.$this->getLang($canmod).'</p>';
508
            }
509
510
            if (!$extension->isProtected() && !$extension->isTemplate()) { // no enable/disable for templates
511
                if ($extension->isEnabled()) {
512
                    $return .= $this->make_action('disable', $extension);
513
                } else {
514
                    $return .= $this->make_action('enable', $extension);
515
                }
516
            }
517
518
            if ($extension->isGitControlled()){
519
                $errors .= '<p class="permerror">'.$this->getLang('git').'</p>';
520
            }
521
522
            if (
523
                $extension->isEnabled() &&
524
                in_array('Auth', $extension->getTypes()) &&
525
                $conf['authtype'] != $extension->getID()
526
            ) {
527
                $errors .= '<p class="permerror">'.$this->getLang('auth').'</p>';
528
            }
529
530
        }else{
531
            if (($canmod = $extension->canModify()) === true) {
532
                if ($extension->getDownloadURL()) {
533
                    $return .= $this->make_action('install', $extension);
534
                }
535
            }else{
536
                $errors .= '<div class="permerror">'.$this->getLang($canmod).'</div>';
537
            }
538
        }
539
540
        if (!$extension->isInstalled() && $extension->getDownloadURL()) {
541
            $return .= ' <span class="version">'.$this->getLang('available_version').' ';
542
            $return .= ($extension->getLastUpdate()
543
                    ? hsc($extension->getLastUpdate())
0 ignored issues
show
Bug introduced by
It seems like $extension->getLastUpdate() targeting helper_plugin_extension_extension::getLastUpdate() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
544
                    : $this->getLang('unknown')).'</span>';
545
        }
546
547
        return $return.' '.$errors.DOKU_LF;
548
    }
549
550
    /**
551
     * Display an action button for an extension
552
     *
553
     * @param string                            $action    The action
554
     * @param helper_plugin_extension_extension $extension The extension
555
     * @return string The HTML code
556
     */
557
    function make_action($action, $extension) {
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...
558
        $title = '';
559
560
        switch ($action) {
561
            case 'install':
562
            case 'reinstall':
563
                $title = 'title="'.hsc($extension->getDownloadURL()).'"';
0 ignored issues
show
Bug introduced by
It seems like $extension->getDownloadURL() targeting helper_plugin_extension_...nsion::getDownloadURL() can also be of type boolean; however, hsc() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
564
                break;
565
        }
566
567
        $classes = 'button '.$action;
568
        $name    = 'fn['.$action.']['.hsc($extension->getID()).']';
569
570
        return '<button class="'.$classes.'" name="'.$name.'" type="submit" '.$title.'>'.
571
            $this->getLang('btn_'.$action).'</button> ';
572
    }
573
574
    /**
575
     * Plugin/template status
576
     *
577
     * @param helper_plugin_extension_extension $extension The extension
578
     * @return string The description of all relevant statusses
579
     */
580
    function make_status(helper_plugin_extension_extension $extension) {
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...
581
        $status = array();
582
583
584
        if ($extension->isInstalled()) {
585
            $status[] = $this->getLang('status_installed');
586
            if ($extension->isProtected()) {
587
                $status[] = $this->getLang('status_protected');
588
            } else {
589
                $status[] = $extension->isEnabled()
590
                    ? $this->getLang('status_enabled')
591
                    : $this->getLang('status_disabled');
592
            }
593
        } else {
594
            $status[] = $this->getLang('status_not_installed');
595
        }
596
        if(!$extension->canModify()) $status[] = $this->getLang('status_unmodifiable');
597
        if($extension->isBundled()) $status[] = $this->getLang('status_bundled');
598
        $status[] = $extension->isTemplate() ? $this->getLang('status_template') : $this->getLang('status_plugin');
599
        return join(', ', $status);
600
    }
601
602
}
603