xref: /dokuwiki/inc/Ui/Revisions.php (revision c29600d0904c807516924fcc91be645b0af2079a)
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
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');
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
166            html_sizechange($sizechange, $form);
167
168            $form->addHTML('('.$lang['current'].')');
169
170            if ($media_id) $form->addTagClose('div');
171
172            $form->addTagClose('div');
173            $form->addTagClose('li');
174        }
175
176        foreach ($revisions as $rev) {
177            $date = dformat($rev);
178            $info = $changelog->getRevisionInfo($rev);
179            if ($media_id) {
180                $exists = file_exists(mediaFN($id, $rev));
181            } else {
182                $exists = page_exists($id, $rev);
183            }
184
185            $class = '';
186            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
187                $class = 'minor';
188            }
189
190            $form->addTagOpen('li')->addClass($class);
191            $form->addTagOpen('div')->addClass('li');
192
193            if ($exists){
194                $form->addCheckbox('rev2[]')->val($rev);
195            } else {
196                $form->addTag('img')->attrs([
197                    'src' => DOKU_BASE.'lib/images/blank.gif',
198                    'width' => 15,
199                    'height' => 11,
200                    'alt' => '',
201                ]);
202            }
203
204            $form->addTagOpen('span')->addClass('date');
205            $form->addHTML($date);
206            $form->addTagClose('span');
207
208            if ($exists) {
209                if (!$media_id) {
210                    $href = wl($id, "rev=$rev,do=diff", false, '&');
211                } else {
212                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
213                }
214                $form->addTagOpen('a')->attr('href', $href)->addClass('diff_link');
215                $form->addTag('img')->attrs([
216                    'src'    => DOKU_BASE.'lib/images/diff.png',
217                    'width'  => 15,
218                    'height' => 11,
219                    'title'  => $lang['diff'],
220                    'alt'    => $lang['diff'],
221                ]);
222                $form->addTagClose('a');
223
224                if (!$media_id) {
225                    $href = wl($id, "rev=$rev", false, '&');
226                } else {
227                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
228                }
229                $form->addTagOpen('a')->attr('href', $href)->addClass('wikilink1');
230                $form->addHTML($display_name);
231                $form->addTagClose('a');
232            } else {
233                $form->addTag('img')->attrs([
234                    'src'    => DOKU_BASE.'lib/images/blank.gif',
235                    'width'  => 15,
236                    'height' => 11,
237                    'alt'    => '',
238                ]);
239                $form->addHTML($display_name);
240            }
241
242            if ($media_id) $form->addTagOpen('div');
243
244            if ($info['sum']) {
245                $form->addTagOpen('span')->addClass('sum');
246                if (!$media_id) $form->addHTML(' – ');
247                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
248                $form->addTagClose('span');
249            }
250
251            $form->addTagOpen('span')->addClass('user');
252            if ($info['user']) {
253                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
254                if (auth_ismanager()) {
255                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
256                }
257            } else {
258                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
259            }
260            $form->addTagClose('span');
261
262            html_sizechange($info['sizechange'], $form);
263
264            if ($media_id) $form->addTagClose('div');
265
266            $form->addTagClose('div');
267            $form->addTagClose('li');
268        }
269
270        // end of revision list
271        $form->addTagClose('ul');
272
273        // show button for diff view
274        if (!$media_id) {
275            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
276        } else {
277            $form->setHiddenField('mediado', 'diff');
278            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
279        }
280
281        $form->addTagClose('div'); // close div class=no
282
283        // emit HTML_REVISIONSFORM_OUTPUT event
284        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, null, false);
285        print $form->toHTML();
286
287        print DOKU_LF;
288
289        // provide navigation for pagenated revision list (of pages and/or media files)
290        print '<div class="pagenav">';
291        $last = $first + $conf['recent'];
292        if ($first > 0) {
293            $first = $first - $conf['recent'];
294            if ($first < 0) $first = 0;
295            print '<div class="pagenav-prev">';
296            if ($media_id) {
297                print html_btn('newer',$media_id,"p",media_managerURL(array('first' => $first), '&amp;', false, true));
298            } else {
299                print html_btn('newer',$id,"p",array('do' => 'revisions', 'first' => $first));
300            }
301            print '</div>';
302        }
303        if ($hasNext) {
304            print '<div class="pagenav-next">';
305            if ($media_id) {
306                print html_btn('older',$media_id,"n",media_managerURL(array('first' => $last), '&amp;', false, true));
307            } else {
308                print html_btn('older',$id,"n",array('do' => 'revisions', 'first' => $last));
309            }
310            print '</div>';
311        }
312        print '</div>';
313
314        print DOKU_LF;
315    }
316
317}
318