Failed Conditions
Pull Request — master (#3198)
by
unknown
11:20
created

Revisions::show()   F

Complexity

Conditions 42
Paths > 20000

Size

Total Lines 273

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 42
nc 290505600
nop 0
dl 0
loc 273
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 Interface
12
 *
13
 * @package dokuwiki\Ui
14
 */
15
class Revisions extends Ui
16
{
17
    protected $first;
18
    protected $media_id;
19
20
    /** 
21
     * Revisions Ui constructor
22
     *
23
     * @param int $first  skip the first n changelog lines
24
     * @param bool|string $media_id  id of media, or false for current page
25
     */
26
    public function __construct($first = 0, $media_id = false)
27
    {
28
        $this->first    = $first;
29
        $this->media_id = $media_id;
30
    }
31
32
    /**
33
     * Display list of old revisions
34
     *
35
     * @author Andreas Gohr <[email protected]>
36
     * @author Ben Coburn <[email protected]>
37
     * @author Kate Arzamastseva <[email protected]>
38
     *
39
     * @triggers HTML_REVISIONSFORM_OUTPUT
40
     * @return void
41
     */
42
    public function show()
43
    {
44
        global $ID;
45
        global $INFO;
46
        global $conf;
47
        global $lang;
48
49
        $first    = $this->first;
50
        $media_id = $this->media_id;
51
52
        $id = $ID;
53
        if ($media_id) {
54
            $id = $media_id;
55
            $changelog = new MediaChangeLog($id);
56
        } else {
57
            $changelog = new PageChangeLog($id);
58
        }
59
60
        /* we need to get one additional log entry to be able to
61
         * decide if this is the last page or is there another one.
62
         * see html_recent()
63
         */
64
65
        $revisions = $changelog->getRevisions($first, $conf['recent'] +1);
66
67
        if (count($revisions) == 0 && $first != 0) {
68
            $first = 0;
69
            $revisions = $changelog->getRevisions($first, $conf['recent'] +1);
70
        }
71
        $hasNext = false;
72
        if (count($revisions) > $conf['recent']) {
73
            $hasNext = true;
74
            array_pop($revisions); // remove extra log entry
75
        }
76
77
        // print intro
78
        if (!$media_id) {
79
            print p_locale_xhtml('revisions');
80
            $exists = $INFO['exists'];
81
            $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
82
            if (!$display_name) {
83
                $display_name = $id;
84
            }
85
        } else {
86
            $exists = file_exists(mediaFN($id));
87
            $display_name = $id;
88
        }
89
90
        // create the form
91
        $form = new Form(['id' => 'page__revisions']);
92
        $form->addClass('changes');
93
        if ($media_id) {
94
            $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...
95
        }
96
97
        // start listing
98
        $form->addTagOpen('ul');
99
100
        if ($exists && $first == 0) {
101
            $minor = false;
102
            if ($media_id) {
103
                $date = dformat(@filemtime(mediaFN($id)));
104
                $href = media_managerURL(array('image' => $id, 'tab_details' => 'view'), '&');
105
106
                $changelog->setChunkSize(1024);
107
                $revinfo = $changelog->getRevisionInfo(@filemtime(fullpath(mediaFN($id))));
108
109
                $summary = $revinfo['sum'];
110
                $editor = $revinfo['user'] ?: $revinfo['ip'];
111
                $sizechange = $revinfo['sizechange'];
112
            } else {
113
                $date = dformat($INFO['lastmod']);
114
                $sizechange = null;
115
                if (isset($INFO['meta']) && isset($INFO['meta']['last_change'])) {
116
                    if ($INFO['meta']['last_change']['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
117
                        $minor = true;
118
                    }
119
                    if (isset($INFO['meta']['last_change']['sizechange'])) {
120
                        $sizechange = $INFO['meta']['last_change']['sizechange'];
121
                    }
122
                }
123
                $pagelog = new PageChangeLog($ID);
124
                $latestrev = $pagelog->getRevisions(-1, 1);
125
                $latestrev = array_pop($latestrev);
126
                $href = wl($id, "rev=$latestrev", false, '&');
127
                $summary = $INFO['sum'];
128
                $editor = $INFO['editor'];
129
            }
130
131
            $form->addTagOpen('li')->addClass($minor ? 'minor' : '');
132
            $form->addTagOpen('div')->addClass('li');
133
            $form->addCheckbox('rev2[]')->val('current');
134
135
            $form->addTagOpen('span')->addClass('data');
136
            $form->addHTML($date);
137
            $form->addTagClose('span');
138
139
            $form->addTag('img')->attrs([
140
                'src' => DOKU_BASE.'lib/images/blank.gif',
141
                'width' => 15,
142
                'height' => 11,
143
                'alt' => '',
144
            ]);
145
146
            $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 104 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...
147
            $form->addHTML($display_name);
148
            $form->addTagClose('a');
149
150
            if ($media_id) $form->addTagOpen('div');
151
152
            if ($summary) {
153
                $form->addTagOpen('span')->addClass('sum');
154
                if (!$media_id) $form->addHTML(' – ');
155
                $form->addHTML('<bdi>' . hsc($summary) . '</bdi>');
156
                $form->addTagClose('span');
157
            }
158
159
            $form->addTagOpen('span')->addClass('user');
160
            $form->addHTML(
161
                (empty($editor)) ? ('('.$lang['external_edit'].')') : '<bdi>'.editorinfo($editor).'</bdi>'
162
            );
163
            $form->addTagClose('span');
164
165
166
            html_sizechange($sizechange, $form);
0 ignored issues
show
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...
167
168
            $form->addHTML('('.$lang['current'].')');
169
170
            if ($media_id) $form->addTagClose('div');
171
172
            $form->addTagClose('div');
173
            $form->addTagClose('li');
174
        }
175
176
        foreach ($revisions as $rev) {
177
            $date = dformat($rev);
178
            $info = $changelog->getRevisionInfo($rev);
179
            if ($media_id) {
180
                $exists = file_exists(mediaFN($id, $rev));
181
            } else {
182
                $exists = page_exists($id, $rev);
183
            }
184
185
            $class = '';
186
            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
187
                $class = 'minor';
188
            }
189
190
            $form->addTagOpen('li')->addClass($class);
191
            $form->addTagOpen('div')->addClass('li');
192
193
            if ($exists){
194
                $form->addCheckbox('rev2[]')->val($rev);
195
            } else {
196
                $form->addTag('img')->attrs([
197
                    'src' => DOKU_BASE.'lib/images/blank.gif',
198
                    'width' => 15,
199
                    'height' => 11,
200
                    'alt' => '',
201
                ]);
202
            }
203
204
            $form->addTagOpen('span')->addClass('date');
205
            $form->addHTML($date);
206
            $form->addTagClose('span');
207
208
            if ($exists) {
209
                if (!$media_id) {
210
                    $href = wl($id, "rev=$rev,do=diff", false, '&');
211
                } else {
212
                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
213
                }
214
                $form->addTagOpen('a')->attr('href', $href)->addClass('diff_link');
0 ignored issues
show
Bug introduced by
It seems like $href defined by media_managerURL(array('...diado' => 'diff'), '&') on line 212 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...
215
                $form->addTag('img')->attrs([
216
                    'src'    => DOKU_BASE.'lib/images/diff.png',
217
                    'width'  => 15,
218
                    'height' => 11,
219
                    'title'  => $lang['diff'],
220
                    'alt'    => $lang['diff'],
221
                ]);
222
                $form->addTagClose('a');
223
224
                if (!$media_id) {
225
                    $href = wl($id, "rev=$rev", false, '&');
226
                } else {
227
                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
228
                }
229
                $form->addTagOpen('a')->attr('href', $href)->addClass('wikilink1');
0 ignored issues
show
Bug introduced by
It seems like $href defined by media_managerURL(array('...', 'rev' => $rev), '&') on line 227 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...
230
                $form->addHTML($display_name);
231
                $form->addTagClose('a');
232
            } else {
233
                $form->addTag('img')->attrs([
234
                    'src'    => DOKU_BASE.'lib/images/blank.gif',
235
                    'width'  => 15,
236
                    'height' => 11,
237
                    'alt'    => '',
238
                ]);
239
                $form->addHTML($display_name);
240
            }
241
242
            if ($media_id) $form->addTagOpen('div');
243
244
            if ($info['sum']) {
245
                $form->addTagOpen('span')->addClass('sum');
246
                if (!$media_id) $form->addHTML(' – ');
247
                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
248
                $form->addTagClose('span');
249
            }
250
251
            $form->addTagOpen('span')->addClass('user');
252
            if ($info['user']) {
253
                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
254
                if (auth_ismanager()) {
255
                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
256
                }
257
            } else {
258
                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
259
            }
260
            $form->addTagClose('span');
261
262
            html_sizechange($info['sizechange'], $form);
0 ignored issues
show
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...
263
264
            if ($media_id) $form->addTagClose('div');
265
266
            $form->addTagClose('div');
267
            $form->addTagClose('li');
268
        }
269
270
        // end of revision list
271
        $form->addTagClose('ul');
272
273
        // show button for diff view
274
        if (!$media_id) {
275
            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
276
        } else {
277
            $form->setHiddenField('mediado', 'diff');
278
            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
279
        }
280
281
        $form->addTagClose('div'); // close div class=no
282
283
        // emit HTML_REVISIONSFORM_OUTPUT event, print the form
284
        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, 'html_form_output', false);
285
286
        print DOKU_LF;
287
288
        // provide navigation for pagenated revision list (of pages and/or media files)
289
        print '<div class="pagenav">';
290
        $last = $first + $conf['recent'];
291
        if ($first > 0) {
292
            $first = $first - $conf['recent'];
293
            if ($first < 0) $first = 0;
294
            print '<div class="pagenav-prev">';
295
            if ($media_id) {
296
                print html_btn('newer',$media_id,"p",media_managerURL(array('first' => $first), '&amp;', false, true));
297
            } else {
298
                print html_btn('newer',$id,"p",array('do' => 'revisions', 'first' => $first));
299
            }
300
            print '</div>';
301
        }
302
        if ($hasNext) {
303
            print '<div class="pagenav-next">';
304
            if ($media_id) {
305
                print html_btn('older',$media_id,"n",media_managerURL(array('first' => $last), '&amp;', false, true));
306
            } else {
307
                print html_btn('older',$id,"n",array('do' => 'revisions', 'first' => $last));
308
            }
309
            print '</div>';
310
        }
311
        print '</div>';
312
313
        print DOKU_LF;
314
    }
315
316
}
317