xref: /dokuwiki/inc/Ui/Revisions.php (revision 057cd775517a85c2f56cb87b185165d9a7434aab)
1<?php
2
3namespace dokuwiki\Ui;
4
5use dokuwiki\ChangeLog\PageChangeLog;
6use dokuwiki\ChangeLog\MediaChangeLog;
7use dokuwiki\Extension\Event;
8use dokuwiki\Form\Form;
9
10/**
11 * DokuWiki Revisions Interface
12 *
13 * @package dokuwiki\Ui
14 */
15class 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 <andi@splitbrain.org>
36     * @author Ben Coburn <btcoburn@silicodon.net>
37     * @author Kate Arzamastseva <pshns@ukr.net>
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), '&'));
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');
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');
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');
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