Failed Conditions
Pull Request — master (#3198)
by
unknown
02:54
created

Revisions   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
dl 0
loc 316
rs 8.96
c 0
b 0
f 0
wmc 43
lcom 1
cbo 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
F show() 0 287 42

How to fix   Complexity   

Complex Class

Complex classes like Revisions 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 Revisions, and based on these observations, apply Extract Interface, too.

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
        $form->addTagOpen('div')->addClass('no');
97
98
        // start listing
99
        $form->addTagOpen('ul');
100
101
        if ($exists && $first == 0) {
102
            $minor = false;
103
            if ($media_id) {
104
                $date = dformat(@filemtime(mediaFN($id)));
105
                $href = media_managerURL(array('image' => $id, 'tab_details' => 'view'), '&');
106
107
                $changelog->setChunkSize(1024);
108
                $revinfo = $changelog->getRevisionInfo(@filemtime(fullpath(mediaFN($id))));
109
110
                $summary = $revinfo['sum'];
111
                $editor = $revinfo['user'] ?: $revinfo['ip'];
112
                $sizechange = $revinfo['sizechange'];
113
            } else {
114
                $date = dformat($INFO['lastmod']);
115
                $sizechange = null;
116
                if (isset($INFO['meta']) && isset($INFO['meta']['last_change'])) {
117
                    if ($INFO['meta']['last_change']['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
118
                        $minor = true;
119
                    }
120
                    if (isset($INFO['meta']['last_change']['sizechange'])) {
121
                        $sizechange = $INFO['meta']['last_change']['sizechange'];
122
                    }
123
                }
124
                $pagelog = new PageChangeLog($ID);
125
                $latestrev = $pagelog->getRevisions(-1, 1);
126
                $latestrev = array_pop($latestrev);
127
                $href = wl($id, "rev=$latestrev", false, '&');
128
                $summary = $INFO['sum'];
129
                $editor = $INFO['editor'];
130
            }
131
132
            $form->addTagOpen('li')->addClass($minor ? 'minor' : '');
133
            $form->addTagOpen('div')->addClass('li');
134
            $form->addCheckbox('rev2[]')->val('current');
135
            $form->addHTML(' ');
136
137
            $form->addTagOpen('span')->addClass('data');
138
            $form->addHTML($date);
139
            $form->addTagClose('span');
140
            $form->addHTML(' ');
141
142
            $form->addTag('img')->attrs([
143
                'src' => DOKU_BASE.'lib/images/blank.gif',
144
                'width' => 15,
145
                'height' => 11,
146
                'alt' => '',
147
            ]);
148
            $form->addHTML(' ');
149
150
            $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 105 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...
151
            $form->addHTML($display_name);
152
            $form->addTagClose('a');
153
            $form->addHTML(' ');
154
155
            if ($media_id) $form->addTagOpen('div');
156
157
            if ($summary) {
158
                $form->addTagOpen('span')->addClass('sum');
159
                if (!$media_id) $form->addHTML(' – ');
160
                $form->addHTML('<bdi>' . hsc($summary) . '</bdi>');
161
                $form->addTagClose('span');
162
            }
163
            $form->addHTML(' ');
164
165
            $form->addTagOpen('span')->addClass('user');
166
            $form->addHTML(
167
                (empty($editor)) ? ('('.$lang['external_edit'].')') : '<bdi>'.editorinfo($editor).'</bdi>'
168
            );
169
            $form->addTagClose('span');
170
            $form->addHTML(' ');
171
172
            $form->addHTML(html_sizechange($sizechange));
173
            $form->addHTML(' ');
174
175
            $form->addHTML('('.$lang['current'].')');
176
177
            if ($media_id) $form->addTagClose('div');
178
179
            $form->addTagClose('div');
180
            $form->addTagClose('li');
181
        }
182
183
        foreach ($revisions as $rev) {
184
            $date = dformat($rev);
185
            $info = $changelog->getRevisionInfo($rev);
186
            if ($media_id) {
187
                $exists = file_exists(mediaFN($id, $rev));
188
            } else {
189
                $exists = page_exists($id, $rev);
190
            }
191
192
            $class = '';
193
            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
194
                $class = 'minor';
195
            }
196
197
            $form->addTagOpen('li')->addClass($class);
198
            $form->addTagOpen('div')->addClass('li');
199
200
            if ($exists){
201
                $form->addCheckbox('rev2[]')->val($rev);
202
            } else {
203
                $form->addTag('img')->attrs([
204
                    'src' => DOKU_BASE.'lib/images/blank.gif',
205
                    'width' => 15,
206
                    'height' => 11,
207
                    'alt' => '',
208
                ]);
209
            }
210
            $form->addHTML(' ');
211
212
            $form->addTagOpen('span')->addClass('date');
213
            $form->addHTML($date);
214
            $form->addTagClose('span');
215
            $form->addHTML(' ');
216
217
            if ($exists) {
218
                if (!$media_id) {
219
                    $href = wl($id, "rev=$rev,do=diff", false, '&');
220
                } else {
221
                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
222
                }
223
                $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 221 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...
224
                $form->addTag('img')->attrs([
225
                    'src'    => DOKU_BASE.'lib/images/diff.png',
226
                    'width'  => 15,
227
                    'height' => 11,
228
                    'title'  => $lang['diff'],
229
                    'alt'    => $lang['diff'],
230
                ]);
231
                $form->addTagClose('a');
232
                $form->addHTML(' ');
233
234
                if (!$media_id) {
235
                    $href = wl($id, "rev=$rev", false, '&');
236
                } else {
237
                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
238
                }
239
                $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 237 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...
240
                $form->addHTML($display_name);
241
                $form->addTagClose('a');
242
            } else {
243
                $form->addTag('img')->attrs([
244
                    'src'    => DOKU_BASE.'lib/images/blank.gif',
245
                    'width'  => 15,
246
                    'height' => 11,
247
                    'alt'    => '',
248
                ]);
249
                $form->addHTML($display_name);
250
            }
251
            $form->addHTML(' ');
252
253
            if ($media_id) $form->addTagOpen('div');
254
255
            if ($info['sum']) {
256
                $form->addTagOpen('span')->addClass('sum');
257
                if (!$media_id) $form->addHTML(' – ');
258
                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
259
                $form->addTagClose('span');
260
            }
261
            $form->addHTML(' ');
262
263
            $form->addTagOpen('span')->addClass('user');
264
            if ($info['user']) {
265
                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
266
                if (auth_ismanager()) {
267
                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
268
                }
269
            } else {
270
                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
271
            }
272
            $form->addTagClose('span');
273
            $form->addHTML(' ');
274
275
            $form->addHTML(html_sizechange($info['sizechange']));
276
277
            if ($media_id) $form->addTagClose('div');
278
279
            $form->addTagClose('div');
280
            $form->addTagClose('li');
281
        }
282
283
        // end of revision list
284
        $form->addTagClose('ul');
285
286
        // show button for diff view
287
        if (!$media_id) {
288
            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
289
        } else {
290
            $form->setHiddenField('mediado', 'diff');
291
            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
292
        }
293
294
        $form->addTagClose('div'); // close div class=no
295
296
        // emit HTML_REVISIONSFORM_OUTPUT event
297
        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, null, false);
298
        print $form->toHTML();
299
300
        print DOKU_LF;
301
302
        // provide navigation for pagenated revision list (of pages and/or media files)
303
        print '<div class="pagenav">';
304
        $last = $first + $conf['recent'];
305
        if ($first > 0) {
306
            $first = $first - $conf['recent'];
307
            if ($first < 0) $first = 0;
308
            print '<div class="pagenav-prev">';
309
            if ($media_id) {
310
                print html_btn('newer',$media_id,"p",media_managerURL(array('first' => $first), '&amp;', false, true));
311
            } else {
312
                print html_btn('newer',$id,"p",array('do' => 'revisions', 'first' => $first));
313
            }
314
            print '</div>';
315
        }
316
        if ($hasNext) {
317
            print '<div class="pagenav-next">';
318
            if ($media_id) {
319
                print html_btn('older',$media_id,"n",media_managerURL(array('first' => $last), '&amp;', false, true));
320
            } else {
321
                print html_btn('older',$id,"n",array('do' => 'revisions', 'first' => $last));
322
            }
323
            print '</div>';
324
        }
325
        print '</div>';
326
327
        print DOKU_LF;
328
    }
329
330
}
331