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

Revisions   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 302
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
dl 0
loc 302
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 273 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
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
            $form->addHTML(html_sizechange($sizechange));
166
167
            $form->addHTML('('.$lang['current'].')');
168
169
            if ($media_id) $form->addTagClose('div');
170
171
            $form->addTagClose('div');
172
            $form->addTagClose('li');
173
        }
174
175
        foreach ($revisions as $rev) {
176
            $date = dformat($rev);
177
            $info = $changelog->getRevisionInfo($rev);
178
            if ($media_id) {
179
                $exists = file_exists(mediaFN($id, $rev));
180
            } else {
181
                $exists = page_exists($id, $rev);
182
            }
183
184
            $class = '';
185
            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
186
                $class = 'minor';
187
            }
188
189
            $form->addTagOpen('li')->addClass($class);
190
            $form->addTagOpen('div')->addClass('li');
191
192
            if ($exists){
193
                $form->addCheckbox('rev2[]')->val($rev);
194
            } else {
195
                $form->addTag('img')->attrs([
196
                    'src' => DOKU_BASE.'lib/images/blank.gif',
197
                    'width' => 15,
198
                    'height' => 11,
199
                    'alt' => '',
200
                ]);
201
            }
202
203
            $form->addTagOpen('span')->addClass('date');
204
            $form->addHTML($date);
205
            $form->addTagClose('span');
206
207
            if ($exists) {
208
                if (!$media_id) {
209
                    $href = wl($id, "rev=$rev,do=diff", false, '&');
210
                } else {
211
                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
212
                }
213
                $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 211 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...
214
                $form->addTag('img')->attrs([
215
                    'src'    => DOKU_BASE.'lib/images/diff.png',
216
                    'width'  => 15,
217
                    'height' => 11,
218
                    'title'  => $lang['diff'],
219
                    'alt'    => $lang['diff'],
220
                ]);
221
                $form->addTagClose('a');
222
223
                if (!$media_id) {
224
                    $href = wl($id, "rev=$rev", false, '&');
225
                } else {
226
                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
227
                }
228
                $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 226 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...
229
                $form->addHTML($display_name);
230
                $form->addTagClose('a');
231
            } else {
232
                $form->addTag('img')->attrs([
233
                    'src'    => DOKU_BASE.'lib/images/blank.gif',
234
                    'width'  => 15,
235
                    'height' => 11,
236
                    'alt'    => '',
237
                ]);
238
                $form->addHTML($display_name);
239
            }
240
241
            if ($media_id) $form->addTagOpen('div');
242
243
            if ($info['sum']) {
244
                $form->addTagOpen('span')->addClass('sum');
245
                if (!$media_id) $form->addHTML(' – ');
246
                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
247
                $form->addTagClose('span');
248
            }
249
250
            $form->addTagOpen('span')->addClass('user');
251
            if ($info['user']) {
252
                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
253
                if (auth_ismanager()) {
254
                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
255
                }
256
            } else {
257
                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
258
            }
259
            $form->addTagClose('span');
260
261
            $form->addHTML(html_sizechange($info['sizechange']));
262
263
            if ($media_id) $form->addTagClose('div');
264
265
            $form->addTagClose('div');
266
            $form->addTagClose('li');
267
        }
268
269
        // end of revision list
270
        $form->addTagClose('ul');
271
272
        // show button for diff view
273
        if (!$media_id) {
274
            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
275
        } else {
276
            $form->setHiddenField('mediado', 'diff');
277
            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
278
        }
279
280
        $form->addTagClose('div'); // close div class=no
281
282
        // emit HTML_REVISIONSFORM_OUTPUT event
283
        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, null, false);
284
        print $form->toHTML();
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