Failed Conditions
Pull Request — master (#3198)
by
unknown
03:27
created

Revisions::show()   F

Complexity

Conditions 42
Paths > 20000

Size

Total Lines 270

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 42
nc 290505600
nop 2
dl 0
loc 270
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace dokuwiki\Ui;
4
5
use dokuwiki\ChangeLog\PageChangeLog;
6
use dokuwiki\ChangeLog\MediaChangeLog;
7
use dokuwiki\Extension\Event;
8
use dokuwiki\Form\Form;
9
10
/**
11
 * DokuWiki Revisions Insterface
12
 *
13
 * @package dokuwiki\Ui
14
 */
15
class Revisions extends Ui
16
{
17
    /**
18
     * Display list of old revisions
19
     *
20
     * @author Andreas Gohr <[email protected]>
21
     * @author Ben Coburn <[email protected]>
22
     * @author Kate Arzamastseva <[email protected]>
23
     *
24
     * @triggers HTML_REVISIONSFORM_OUTPUT
25
     * @param int $first skip the first n changelog lines
26
     * @param bool|string $media_id id of media, or false for current page
27
     * @return void
28
     */
29
    public function show($first = 0, $media_id = false)
30
    {
31
        global $ID;
32
        global $INFO;
33
        global $conf;
34
        global $lang;
35
        $id = $ID;
36
        if ($media_id) {
37
            $id = $media_id;
38
            $changelog = new MediaChangeLog($id);
39
        } else {
40
            $changelog = new PageChangeLog($id);
41
        }
42
43
        /* we need to get one additional log entry to be able to
44
         * decide if this is the last page or is there another one.
45
         * see html_recent()
46
         */
47
48
        $revisions = $changelog->getRevisions($first, $conf['recent'] +1);
49
50
        if (count($revisions) == 0 && $first != 0) {
51
            $first = 0;
52
            $revisions = $changelog->getRevisions($first, $conf['recent'] +1);
53
        }
54
        $hasNext = false;
55
        if (count($revisions) > $conf['recent']) {
56
            $hasNext = true;
57
            array_pop($revisions); // remove extra log entry
58
        }
59
60
        // print intro
61
        if (!$media_id) {
62
            print p_locale_xhtml('revisions');
63
            $exists = $INFO['exists'];
64
            $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
65
            if (!$display_name) {
66
                $display_name = $id;
67
            }
68
        } else {
69
            $exists = file_exists(mediaFN($id));
70
            $display_name = $id;
71
        }
72
73
        // create the form
74
        $form = new Form(['id' => 'page__revisions']);
75
        $form->addClass('changes');
76
        if ($media_id) {
77
            $form->attr('action', media_managerURL(array('image' => $media_id), '&'));
0 ignored issues
show
Bug introduced by
It seems like media_managerURL(array('...ge' => $media_id), '&') targeting media_managerURL() can also be of type array; however, dokuwiki\Form\Element::attr() does only seem to accept null|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...
78
        }
79
80
        // start listing
81
        $form->addTagOpen('ul');
82
83
        if ($exists && $first == 0) {
84
            $minor = false;
85
            if ($media_id) {
86
                $date = dformat(@filemtime(mediaFN($id)));
87
                $href = media_managerURL(array('image' => $id, 'tab_details' => 'view'), '&');
88
89
                $changelog->setChunkSize(1024);
90
                $revinfo = $changelog->getRevisionInfo(@filemtime(fullpath(mediaFN($id))));
91
92
                $summary = $revinfo['sum'];
93
                $editor = $revinfo['user'] ?: $revinfo['ip'];
94
                $sizechange = $revinfo['sizechange'];
95
            } else {
96
                $date = dformat($INFO['lastmod']);
97
                if (isset($INFO['meta']) && isset($INFO['meta']['last_change'])) {
98
                    if ($INFO['meta']['last_change']['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
99
                        $minor = true;
100
                    }
101
                    if (isset($INFO['meta']['last_change']['sizechange'])) {
102
                        $sizechange = $INFO['meta']['last_change']['sizechange'];
103
                    } else {
104
                        $sizechange = null;
105
                    }
106
                }
107
                $pagelog = new PageChangeLog($ID);
108
                $latestrev = $pagelog->getRevisions(-1, 1);
109
                $latestrev = array_pop($latestrev);
110
                $href = wl($id, "rev=$latestrev", false, '&');
111
                $summary = $INFO['sum'];
112
                $editor = $INFO['editor'];
113
            }
114
115
            $form->addTagOpen('li')->addClass($minor ? 'minor' : '');
116
            $form->addTagOpen('div')->addClass('li');
117
            $form->addCheckbox('rev2[]')->val('current');
118
119
            $form->addTagOpen('span')->addClass('data');
120
            $form->addHTML($date);
121
            $form->addTagClose('span');
122
123
            $form->addTag('img')->attrs([
124
                'src' => DOKU_BASE.'lib/images/blank.gif',
125
                'width' => 15,
126
                'height' => 11,
127
                'alt' => '',
128
            ]);
129
130
            $form->addTagOPen('a')->attr('href', $href)->addClass('wikilink1');
0 ignored issues
show
Bug introduced by
It seems like $href defined by media_managerURL(array('...tails' => 'view'), '&') on line 87 can also be of type array; however, dokuwiki\Form\Element::attr() does only seem to accept null|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
131
            $form->addHTML($display_name);
132
            $form->addTagClose('a');
133
134
            if ($media_id) $form->addTagOpen('div');
135
136
            if ($summary) {
137
                $form->addTagOpen('span')->addClass('sum');
138
                if (!$media_id) $form->addHTML(' – ');
139
                $form->addHTML('<bdi>' . hsc($summary) . '</bdi>');
140
                $form->addTagClose('span');
141
            }
142
143
            $form->addTagOpen('span')->addClass('user');
144
            $form->addHTML(
145
                (empty($editor)) ? ('('.$lang['external_edit'].')') : '<bdi>'.editorinfo($editor).'</bdi>'
146
            );
147
            $form->addTagClose('span');
148
149
150
            html_sizechange($sizechange, $form);
0 ignored issues
show
Bug introduced by
The variable $sizechange does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Documentation introduced by
$form is of type object<dokuwiki\Form\Form>, but the function expects a object<Form>|object<Doku_Form>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151
152
            $form->addHTML('('.$lang['current'].')');
0 ignored issues
show
Bug introduced by
The method addHTML() does not seem to exist on object<Doku_Form>.

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...
153
154
            if ($media_id) $form->addTagClose('div');
0 ignored issues
show
Bug introduced by
The method addTagClose() does not seem to exist on object<Doku_Form>.

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...
155
156
            $form->addTagClose('div');
0 ignored issues
show
Bug introduced by
The method addTagClose() does not seem to exist on object<Doku_Form>.

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...
157
            $form->addTagClose('li');
0 ignored issues
show
Bug introduced by
The method addTagClose() does not seem to exist on object<Doku_Form>.

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...
158
        }
159
160
        foreach ($revisions as $rev) {
161
            $date = dformat($rev);
162
            $info = $changelog->getRevisionInfo($rev);
163
            if ($media_id) {
164
                $exists = file_exists(mediaFN($id, $rev));
165
            } else {
166
                $exists = page_exists($id, $rev);
167
            }
168
169
            $class = '';
170
            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
171
                $class = 'minor';
172
            }
173
174
            $form->addTagOpen('li')->addClass($class);
0 ignored issues
show
Bug introduced by
The method addTagOpen does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
175
            $form->addTagOpen('div')->addClass('li');
176
177
            if ($exists){
178
                $form->addCheckbox('rev2[]')->val($rev);
0 ignored issues
show
Bug introduced by
The method addCheckbox does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
179
            } else {
180
                $form->addTag('img')->attrs([
0 ignored issues
show
Bug introduced by
The method addTag does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
181
                    'src' => DOKU_BASE.'lib/images/blank.gif',
182
                    'width' => 15,
183
                    'height' => 11,
184
                    'alt' => '',
185
                ]);
186
            }
187
188
            $form->addTagOpen('span')->addClass('date');
189
            $form->addHTML($date);
0 ignored issues
show
Bug introduced by
The method addHTML does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
190
            $form->addTagClose('span');
0 ignored issues
show
Bug introduced by
The method addTagClose does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
191
192
            if ($exists) {
193
                if (!$media_id) {
194
                    $href = wl($id, "rev=$rev,do=diff", false, '&');
195
                } else {
196
                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
197
                }
198
                $form->addTagOpen('a')->attr('href', $href)->addClass('diff_link');
199
                $form->addTag('img')->attrs([
200
                    'src'    => DOKU_BASE.'lib/images/diff.png',
201
                    'width'  => 15,
202
                    'height' => 11,
203
                    'title'  => $lang['diff'],
204
                    'alt'    => $lang['diff'],
205
                ]);
206
                $form->addTagClose('a');
207
208
                if (!$media_id) {
209
                    $href = wl($id, "rev=$rev", false, '&');
210
                } else {
211
                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
212
                }
213
                $form->addTagOpen('a')->attr('href', $href)->addClass('wikilink1');
214
                $form->addHTML($display_name);
215
                $form->addTagClose('a');
216
            } else {
217
                $form->addTag('img')->attrs([
218
                    'src'    => DOKU_BASE.'lib/images/blank.gif',
219
                    'width'  => 15,
220
                    'height' => 11,
221
                    'alt'    => '',
222
                ]);
223
                $form->addHTML($display_name);
224
            }
225
226
            if ($media_id) $form->addTagOpen('div');
227
228
            if ($info['sum']) {
229
                $form->addTagOpen('span')->addClass('sum');
230
                if (!$media_id) $form->addHTML(' – ');
231
                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
232
                $form->addTagClose('span');
233
            }
234
235
            $form->addTagOpen('span')->addClass('user');
236
            if ($info['user']) {
237
                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
238
                if (auth_ismanager()) {
239
                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
240
                }
241
            } else {
242
                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
243
            }
244
            $form->addTagClose('span');
245
246
            html_sizechange($info['sizechange'], $form);
0 ignored issues
show
Bug introduced by
It seems like $form defined by new \dokuwiki\Form\Form(... => 'page__revisions')) on line 74 can also be of type object<dokuwiki\Form\Form>; however, html_sizechange() does only seem to accept object<Form>|object<Doku_Form>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
247
248
            if ($media_id) $form->addTagClose('div');
0 ignored issues
show
Bug introduced by
The method addTagClose() does not seem to exist on object<Doku_Form>.

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...
249
250
            $form->addTagClose('div');
0 ignored issues
show
Bug introduced by
The method addTagClose() does not seem to exist on object<Doku_Form>.

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...
251
            $form->addTagClose('li');
0 ignored issues
show
Bug introduced by
The method addTagClose() does not seem to exist on object<Doku_Form>.

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...
252
        }
253
254
        // end of revision list
255
        $form->addTagClose('ul');
256
257
        // show button for diff view
258
        if (!$media_id) {
259
            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
0 ignored issues
show
Bug introduced by
The method addButton does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
260
        } else {
261
            $form->setHiddenField('mediado', 'diff');
0 ignored issues
show
Bug introduced by
The method setHiddenField does only exist in dokuwiki\Form\Form, but not in Doku_Form.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
262
            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
263
        }
264
265
        $form->addTagClose('div'); // close div class=no
266
267
        // emit HTML_REVISIONSFORM_OUTPUT event, print the form
268
        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, 'html_form_output', false);
269
270
        print DOKU_LF;
271
272
        // provide navigation for pagenated revision list (of pages and/or media files)
273
        print '<div class="pagenav">';
274
        $last = $first + $conf['recent'];
275
        if ($first > 0) {
276
            $first = $first - $conf['recent'];
277
            if ($first < 0) $first = 0;
278
            print '<div class="pagenav-prev">';
279
            if ($media_id) {
280
                print html_btn('newer',$media_id,"p",media_managerURL(array('first' => $first), '&amp;', false, true));
281
            } else {
282
                print html_btn('newer',$id,"p",array('do' => 'revisions', 'first' => $first));
283
            }
284
            print '</div>';
285
        }
286
        if ($hasNext) {
287
            print '<div class="pagenav-next">';
288
            if ($media_id) {
289
                print html_btn('older',$media_id,"n",media_managerURL(array('first' => $last), '&amp;', false, true));
290
            } else {
291
                print html_btn('older',$id,"n",array('do' => 'revisions', 'first' => $last));
292
            }
293
            print '</div>';
294
        }
295
        print '</div>';
296
297
        print DOKU_LF;
298
    }
299
300
}
301