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

Recent   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 325
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 325
rs 10
c 0
b 0
f 0
wmc 25

15 Methods

Rating   Name   Duplication   Size   Complexity  
A hp$0 ➔ __construct() 0 4 1
A hp$0 ➔ itemIcon() 0 10 2
A __construct() 0 5 1
B show() 0 62 5
B getRecents() 0 30 8
A htmlNavigation() 0 26 3
A addRecentItemSelector() 0 15 1
A hp$0 ➔ editDate() 0 4 1
A hp$0 ➔ editSummary() 0 4 1
A hp$0 ➔ editor() 0 12 3
A hp$0 ➔ itemName() 0 12 4
A hp$0 ➔ difflink() 0 30 5
A hp$0 ➔ revisionlink() 0 15 2
A hp$0 ➔ sizeChange() 0 15 3
B getObjRevInfo() 0 130 3
1
<?php
2
3
namespace dokuwiki\Ui;
4
5
use dokuwiki\ChangeLog\MediaChangeLog;
6
use dokuwiki\Form\Form;
7
8
/**
9
 * DokuWiki Recent Interface
10
 *
11
 * @package dokuwiki\Ui
12
 */
13
class Recent extends Ui
14
{
15
    protected $first;
16
    protected $show_changes;
17
18
    /** 
19
     * Recent Ui constructor
20
     *
21
     * @param int $first  skip the first n changelog lines
22
     * @param string $show_changes  type of changes to show; pages, mediafiles, or both
23
     */
24
    public function __construct($first = 0, $show_changes = 'both')
25
    {
26
        $this->first        = $first;
27
        $this->show_changes = $show_changes;
28
    }
29
30
    /**
31
     * Display recent changes
32
     *
33
     * @author Andreas Gohr <[email protected]>
34
     * @author Matthias Grimm <[email protected]>
35
     * @author Ben Coburn <[email protected]>
36
     * @author Kate Arzamastseva <[email protected]>
37
     * @author Satoshi Sahara <[email protected]>
38
     *
39
     * @triggers HTMLFORM_RECENT_OUTPUT
40
     * @return void
41
     */
42
    public function show()
43
    {
44
        global $conf, $lang;
45
        global $ID;
46
47
        // get recent items, and set correct pagenation parameters (first, hasNext)
48
        $first = $this->first;
49
        $hasNext = false;
50
        $recents = $this->getRecents($first, $hasNext);
51
52
        // print intro
53
        print p_locale_xhtml('recent');
54
55
        if (getNS($ID) != '') {
56
            print '<div class="level1"><p>'
57
                . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent'))
58
                .'</p></div>';
59
        }
60
61
        // create the form
62
        $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']);
63
        $form->addTagOpen('div')->addClass('no');
64
        $form->setHiddenField('sectok', null);
65
        $form->setHiddenField('do', 'recent');
66
        $form->setHiddenField('id', $ID);
67
68
        // show dropdown selector, whether include not only recent pages but also recent media files?
69
        if ($conf['mediarevisions']) {
70
            $this->addRecentItemSelector($form);
71
        }
72
73
        // start listing of recent items
74
        $form->addTagOpen('ul');
75
        foreach ($recents as $recent) {
76
            $objRevInfo = $this->getObjRevInfo($recent);
77
            $class = ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': '';
78
            $form->addTagOpen('li')->addClass($class);
79
            $form->addTagOpen('div')->addClass('li');
80
            $html = implode(' ', [
81
                $objRevInfo->itemIcon(),          // filetype icon
82
                $objRevInfo->editDate(),          // edit date and time
83
                $objRevInfo->difflink(),          // link to diffview icon
84
                $objRevInfo->revisionlink(),      // linkto revisions icon
85
                $objRevInfo->itemName(),          // name of page or media
86
                $objRevInfo->editSummary(),       // edit summary
87
                $objRevInfo->editor(),            // editor info
88
                $objRevInfo->sizechange(),        // size change indicator
89
            ]);
90
            $form->addHTML($html);
91
            $form->addTagClose('div');
92
            $form->addTagClose('li');
93
        }
94
        $form->addTagClose('ul');
95
96
        $form->addTagClose('div'); // close div class=no
97
98
        // provide navigation for pagenated recent list (of pages and/or media files)
99
        $form->addHTML($this->htmlNavigation($first, $hasNext));
100
101
        // print form that might be modified by HTMLFORM_RECENT_OUTPUT event handlers
102
        print $form->toHTML('recent');
103
    }
104
105
    /**
106
     * Get recent items, and set correct pagenation parameters (first, hasNext)
107
     *
108
     * @param int  $first
109
     * @param bool $hasNext
110
     * @return array  recent items to be shown in a pagenated list
111
     *
112
     * @see also dokuwiki\Changelog::getRevisionInfo()
113
     */
114
    protected function getRecents(&$first, &$hasNext)
115
    {
116
        global $ID, $conf;
117
118
        $flags = 0;
119
        if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
120
            $flags = RECENTS_MEDIA_CHANGES;
121
        } elseif ($this->show_changes == 'pages') {
122
            $flags = 0;
123
        } elseif ($conf['mediarevisions']) {
124
            $flags = RECENTS_MEDIA_PAGES_MIXED;
125
        }
126
127
        /* we need to get one additionally log entry to be able to
128
         * decide if this is the last page or is there another one.
129
         * This is the cheapest solution to get this information.
130
         */
131
        $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
Security Bug introduced by
It seems like getNS($ID) targeting getNS() can also be of type false; however, getRecents() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
132
        if (count($recents) == 0 && $first != 0) {
133
            $first = 0;
134
            $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
Security Bug introduced by
It seems like getNS($ID) targeting getNS() can also be of type false; however, getRecents() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
135
        }
136
137
        $hasNext = false;
138
        if (count($recents) > $conf['recent']) {
139
            $hasNext = true;
140
            array_pop($recents); // remove extra log entry
141
        }
142
        return $recents;
143
    }
144
145
    /**
146
     * Navigation buttons for Pagenation (prev/next)
147
     *
148
     * @param int  $first
149
     * @param bool $hasNext
150
     * @return array  html
151
     */
152
    protected function htmlNavigation($first, $hasNext)
153
    {
154
        global $conf, $lang;
155
156
        $last = $first + $conf['recent'];
157
        $html = '<div class="pagenav">';
158
        if ($first > 0) {
159
            $first = max($first - $conf['recent'], 0);
160
            $html.= '<div class="pagenav-prev">';
161
            $html.= '<button type="submit" name="first['.$first.']" accesskey="n"'
162
                  . ' title="'.$lang['btn_newer'].' [N]" class="button show">'
163
                  . $lang['btn_newer']
164
                  . '</button>';
165
            $html.= '</div>';
166
        }
167
        if ($hasNext) {
168
            $html.= '<div class="pagenav-next">';
169
            $html.= '<button type="submit" name="first['.$last.']" accesskey="p"'
170
                  . ' title="'.$lang['btn_older'].' [P]" class="button show">'
171
                  . $lang['btn_older']
172
                  . '</button>';
173
            $html.= '</div>';
174
        }
175
        $html.= '</div>';
176
        return $html;
177
    }
178
179
    /**
180
     * Add dropdown selector of item types to the form instance
181
     *
182
     * @param Form $form
183
     * @return void
184
     */
185
    protected function addRecentItemSelector(Form $form)
186
    {
187
        global $lang;
188
189
        $form->addTagOpen('div')->addClass('changeType');
190
        $options = array(
191
                    'pages'      => $lang['pages_changes'],
192
                    'mediafiles' => $lang['media_changes'],
193
                    'both'       => $lang['both_changes'],
194
        );
195
        $form->addDropdown('show_changes', $options, $lang['changes_type'])
196
                ->val($this->show_changes)->addClass('quickselect');
197
        $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit');
198
        $form->addTagClose('div');
199
    }
200
201
    /**
202
     * Returns instance of objRevInfo
203
     * @param array $info  Revision info structure of page or media
204
     * @return objRevInfo object (anonymous class)
205
     */
206
    protected function getObjRevInfo(array $info)
207
    {
208
        return new class ($info) // anonymous class (objRevInfo)
209
        {
210
            protected $info;
211
212
            public function __construct(array $info)
213
            {
214
                $this->info = $info;
215
            }
216
217
            // fileicon of the page or media file
218
            public function itemIcon()
219
            {
220
                $id = $this->info['id'];
221
                if (isset($this->info['media'])) {
222
                    $html = media_printicon($id);
223
                } else {
224
                    $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />';
225
                }
226
                return $html;
227
            }
228
229
            // edit date and time of the page or media file
230
            public function editDate()
231
            {
232
                return '<span class="date">'. dformat($this->info['date']) .'</span>';
233
            }
234
235
            // edit summary
236
            public function editSummary()
237
            {
238
                return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>';
239
            }
240
241
            // editor of the page or media file
242
            public function editor()
243
            {
244
                $html = '<span class="user">';
245
                if ($this->info['user']) {
246
                    $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
247
                    if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
248
                } else {
249
                    $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
250
                }
251
                $html.= '</span>';
252
                return $html;
253
            }
254
255
            // name of the page or media file
256
            public function itemName()
257
            {
258
                $id = $this->info['id'];
259
                if (isset($this->info['media'])) {
260
                    $href = media_managerURL(['tab_details'=>'view', 'image'=> $id, 'ns'=> getNS($id)], '&');
261
                    $class = file_exists(mediaFN($id)) ? 'wikilink1' : 'wikilink2';
262
                    $html = '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>';
263
                } else {
264
                    $html = html_wikilink(':'.$id, (useHeading('navigation') ? null : $id));
265
                }
266
                return $html;
267
            }
268
269
            // icon difflink
270
            public function difflink()
271
            {
272
                global $lang;
273
                $id = $this->info['id'];
274
                $diff = false;
0 ignored issues
show
Unused Code introduced by
$diff is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
275
276
                if (isset($this->info['media'])) {
277
                    $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
278
                    $diff = (count($revs) && file_exists(mediaFN($id)));
279
                    if ($diff) {
280
                        $href = media_managerURL(
281
                            ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&'
282
                        );
283
                    } else {
284
                        $href = '';
285
                    }
286
                } else {
287
                    $href = wl($id, "do=diff", false, '&');
288
                }
289
290
                if ($href) {
291
                    $html = '<a href="'.$href.'" class="diff_link">'
292
                          . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
293
                          . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
294
                          . '</a>';
295
                } else {
296
                    $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
297
                }
298
                return $html;
299
            }
300
301
            // icon revision link
302
            public function revisionlink()
303
            {
304
                global $lang;
305
                $id = $this->info['id'];
306
                if (isset($this->info['media'])) {
307
                    $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&');
308
                } else {
309
                    $href = wl($id, "do=revisions", false, '&');
310
                }
311
                $html = '<a href="'.$href.'" class="revisions_link">'
312
                      . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"'
313
                      . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
314
                      . '</a>';
315
                return $html;
316
            }
317
318
            // size change
319
            public function sizeChange()
320
            {
321
                $class = 'sizechange';
322
                $value = filesize_h(abs($this->info['sizechange']));
323
                if ($this->info['sizechange'] > 0) {
324
                    $class .= ' positive';
325
                    $value = '+' . $value;
326
                } elseif ($this->info['sizechange'] < 0) {
327
                    $class .= ' negative';
328
                    $value = '-' . $value;
329
                } else {
330
                    $value = '±' . $value;
331
                }
332
                return '<span class="'.$class.'">'.$value.'</span>';
333
            }
334
        }; // end of anonymous class (objRevInfo)
335
    }
336
337
}
338