Failed Conditions
Push — master ( 96da53...0afbc1 )
by Andreas
03:17 queued 11s
created

inc/Ui/Recent.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
     * @return void
40
     */
41
    public function show()
42
    {
43
        global $conf, $lang;
44
        global $ID;
45
46
        // get recent items, and set correct pagenation parameters (first, hasNext)
47
        $first = $this->first;
48
        $hasNext = false;
49
        $recents = $this->getRecents($first, $hasNext);
50
51
        // print intro
52
        print p_locale_xhtml('recent');
53
54
        if (getNS($ID) != '') {
55
            print '<div class="level1"><p>'
56
                . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent'))
57
                .'</p></div>';
58
        }
59
60
        // create the form
61
        $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']);
62
        $form->addTagOpen('div')->addClass('no');
63
        $form->setHiddenField('sectok', null);
64
        $form->setHiddenField('do', 'recent');
65
        $form->setHiddenField('id', $ID);
66
67
        // show dropdown selector, whether include not only recent pages but also recent media files?
68
        if ($conf['mediarevisions']) {
69
            $this->addRecentItemSelector($form);
70
        }
71
72
        // start listing of recent items
73
        $form->addTagOpen('ul');
74
        foreach ($recents as $recent) {
75
            $objRevInfo = $this->getObjRevInfo($recent);
76
            $class = ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': '';
77
            $form->addTagOpen('li')->addClass($class);
78
            $form->addTagOpen('div')->addClass('li');
79
            $html = implode(' ', [
80
                $objRevInfo->itemIcon(),          // filetype icon
81
                $objRevInfo->editDate(),          // edit date and time
82
                $objRevInfo->difflink(),          // link to diffview icon
83
                $objRevInfo->revisionlink(),      // linkto revisions icon
84
                $objRevInfo->itemName(),          // name of page or media
85
                $objRevInfo->editSummary(),       // edit summary
86
                $objRevInfo->editor(),            // editor info
87
                $objRevInfo->sizechange(),        // size change indicator
88
            ]);
89
            $form->addHTML($html);
90
            $form->addTagClose('div');
91
            $form->addTagClose('li');
92
        }
93
        $form->addTagClose('ul');
94
95
        $form->addTagClose('div'); // close div class=no
96
97
        // provide navigation for pagenated recent list (of pages and/or media files)
98
        $form->addHTML($this->htmlNavigation($first, $hasNext));
99
100
        print $form->toHTML('Recent');
101
    }
102
103
    /**
104
     * Get recent items, and set correct pagenation parameters (first, hasNext)
105
     *
106
     * @param int  $first
107
     * @param bool $hasNext
108
     * @return array  recent items to be shown in a pagenated list
109
     *
110
     * @see also dokuwiki\Changelog::getRevisionInfo()
111
     */
112
    protected function getRecents(&$first, &$hasNext)
113
    {
114
        global $ID, $conf;
115
116
        $flags = 0;
117
        if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
118
            $flags = RECENTS_MEDIA_CHANGES;
119
        } elseif ($this->show_changes == 'pages') {
120
            $flags = 0;
121
        } elseif ($conf['mediarevisions']) {
122
            $flags = RECENTS_MEDIA_PAGES_MIXED;
123
        }
124
125
        /* we need to get one additionally log entry to be able to
126
         * decide if this is the last page or is there another one.
127
         * This is the cheapest solution to get this information.
128
         */
129
        $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
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...
130
        if (count($recents) == 0 && $first != 0) {
131
            $first = 0;
132
            $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
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...
133
        }
134
135
        $hasNext = false;
136
        if (count($recents) > $conf['recent']) {
137
            $hasNext = true;
138
            array_pop($recents); // remove extra log entry
139
        }
140
        return $recents;
141
    }
142
143
    /**
144
     * Navigation buttons for Pagenation (prev/next)
145
     *
146
     * @param int  $first
147
     * @param bool $hasNext
148
     * @return array  html
149
     */
150
    protected function htmlNavigation($first, $hasNext)
151
    {
152
        global $conf, $lang;
153
154
        $last = $first + $conf['recent'];
155
        $html = '<div class="pagenav">';
156
        if ($first > 0) {
157
            $first = max($first - $conf['recent'], 0);
158
            $html.= '<div class="pagenav-prev">';
159
            $html.= '<button type="submit" name="first['.$first.']" accesskey="n"'
160
                  . ' title="'.$lang['btn_newer'].' [N]" class="button show">'
161
                  . $lang['btn_newer']
162
                  . '</button>';
163
            $html.= '</div>';
164
        }
165
        if ($hasNext) {
166
            $html.= '<div class="pagenav-next">';
167
            $html.= '<button type="submit" name="first['.$last.']" accesskey="p"'
168
                  . ' title="'.$lang['btn_older'].' [P]" class="button show">'
169
                  . $lang['btn_older']
170
                  . '</button>';
171
            $html.= '</div>';
172
        }
173
        $html.= '</div>';
174
        return $html;
175
    }
176
177
    /**
178
     * Add dropdown selector of item types to the form instance
179
     *
180
     * @param Form $form
181
     * @return void
182
     */
183
    protected function addRecentItemSelector(Form $form)
184
    {
185
        global $lang;
186
187
        $form->addTagOpen('div')->addClass('changeType');
188
        $options = array(
189
                    'pages'      => $lang['pages_changes'],
190
                    'mediafiles' => $lang['media_changes'],
191
                    'both'       => $lang['both_changes'],
192
        );
193
        $form->addDropdown('show_changes', $options, $lang['changes_type'])
194
                ->val($this->show_changes)->addClass('quickselect');
195
        $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit');
196
        $form->addTagClose('div');
197
    }
198
199
    /**
200
     * Returns instance of objRevInfo
201
     * @param array $info  Revision info structure of page or media
202
     * @return objRevInfo object (anonymous class)
203
     */
204
    protected function getObjRevInfo(array $info)
205
    {
206
        return new class ($info) // anonymous class (objRevInfo)
207
        {
208
            protected $info;
209
210
            public function __construct(array $info)
211
            {
212
                $this->info = $info;
213
            }
214
215
            // fileicon of the page or media file
216
            public function itemIcon()
217
            {
218
                $id = $this->info['id'];
219
                if (isset($this->info['media'])) {
220
                    $html = media_printicon($id);
221
                } else {
222
                    $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />';
223
                }
224
                return $html;
225
            }
226
227
            // edit date and time of the page or media file
228
            public function editDate()
229
            {
230
                return '<span class="date">'. dformat($this->info['date']) .'</span>';
231
            }
232
233
            // edit summary
234
            public function editSummary()
235
            {
236
                return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>';
237
            }
238
239
            // editor of the page or media file
240
            public function editor()
241
            {
242
                $html = '<span class="user">';
243
                if ($this->info['user']) {
244
                    $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
245
                    if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
246
                } else {
247
                    $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
248
                }
249
                $html.= '</span>';
250
                return $html;
251
            }
252
253
            // name of the page or media file
254
            public function itemName()
255
            {
256
                $id = $this->info['id'];
257
                if (isset($this->info['media'])) {
258
                    $href = media_managerURL(['tab_details'=>'view', 'image'=> $id, 'ns'=> getNS($id)], '&');
259
                    $class = file_exists(mediaFN($id)) ? 'wikilink1' : 'wikilink2';
260
                    $html = '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>';
261
                } else {
262
                    $html = html_wikilink(':'.$id, (useHeading('navigation') ? null : $id));
263
                }
264
                return $html;
265
            }
266
267
            // icon difflink
268
            public function difflink()
269
            {
270
                global $lang;
271
                $id = $this->info['id'];
272
273
                if (isset($this->info['media'])) {
274
                    $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
275
                    $diff = (count($revs) && file_exists(mediaFN($id)));
276
                    if ($diff) {
277
                        $href = media_managerURL(
278
                            ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&'
279
                        );
280
                    } else {
281
                        $href = '';
282
                    }
283
                } else {
284
                    $href = wl($id, "do=diff", false, '&');
285
                }
286
287
                if ($href) {
288
                    $html = '<a href="'.$href.'" class="diff_link">'
289
                          . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
290
                          . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
291
                          . '</a>';
292
                } else {
293
                    $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
294
                }
295
                return $html;
296
            }
297
298
            // icon revision link
299
            public function revisionlink()
300
            {
301
                global $lang;
302
                $id = $this->info['id'];
303
                if (isset($this->info['media'])) {
304
                    $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&');
305
                } else {
306
                    $href = wl($id, "do=revisions", false, '&');
307
                }
308
                $html = '<a href="'.$href.'" class="revisions_link">'
309
                      . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"'
310
                      . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
311
                      . '</a>';
312
                return $html;
313
            }
314
315
            // size change
316
            public function sizeChange()
317
            {
318
                $class = 'sizechange';
319
                $value = filesize_h(abs($this->info['sizechange']));
320
                if ($this->info['sizechange'] > 0) {
321
                    $class .= ' positive';
322
                    $value = '+' . $value;
323
                } elseif ($this->info['sizechange'] < 0) {
324
                    $class .= ' negative';
325
                    $value = '-' . $value;
326
                } else {
327
                    $value = '±' . $value;
328
                }
329
                return '<span class="'.$class.'">'.$value.'</span>';
330
            }
331
        }; // end of anonymous class (objRevInfo)
332
    }
333
334
}
335