xref: /dokuwiki/inc/Ui/Revisions.php (revision 9e3166413adffd9d067b4cde8da8d04c44d9c8bf)
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                if (isset($INFO['meta']) && isset($INFO['meta']['last_change'])) {
115                    if ($INFO['meta']['last_change']['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
116                        $minor = true;
117                    }
118                    if (isset($INFO['meta']['last_change']['sizechange'])) {
119                        $sizechange = $INFO['meta']['last_change']['sizechange'];
120                    } else {
121                        $sizechange = null;
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
136            $form->addTagOpen('span')->addClass('data');
137            $form->addHTML($date);
138            $form->addTagClose('span');
139
140            $form->addTag('img')->attrs([
141                'src' => DOKU_BASE.'lib/images/blank.gif',
142                'width' => 15,
143                'height' => 11,
144                'alt' => '',
145            ]);
146
147            $form->addTagOPen('a')->attr('href', $href)->addClass('wikilink1');
148            $form->addHTML($display_name);
149            $form->addTagClose('a');
150
151            if ($media_id) $form->addTagOpen('div');
152
153            if ($summary) {
154                $form->addTagOpen('span')->addClass('sum');
155                if (!$media_id) $form->addHTML(' – ');
156                $form->addHTML('<bdi>' . hsc($summary) . '</bdi>');
157                $form->addTagClose('span');
158            }
159
160            $form->addTagOpen('span')->addClass('user');
161            $form->addHTML(
162                (empty($editor)) ? ('('.$lang['external_edit'].')') : '<bdi>'.editorinfo($editor).'</bdi>'
163            );
164            $form->addTagClose('span');
165
166
167            html_sizechange($sizechange, $form);
168
169            $form->addHTML('('.$lang['current'].')');
170
171            if ($media_id) $form->addTagClose('div');
172
173            $form->addTagClose('div');
174            $form->addTagClose('li');
175        }
176
177        foreach ($revisions as $rev) {
178            $date = dformat($rev);
179            $info = $changelog->getRevisionInfo($rev);
180            if ($media_id) {
181                $exists = file_exists(mediaFN($id, $rev));
182            } else {
183                $exists = page_exists($id, $rev);
184            }
185
186            $class = '';
187            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
188                $class = 'minor';
189            }
190
191            $form->addTagOpen('li')->addClass($class);
192            $form->addTagOpen('div')->addClass('li');
193
194            if ($exists){
195                $form->addCheckbox('rev2[]')->val($rev);
196            } else {
197                $form->addTag('img')->attrs([
198                    'src' => DOKU_BASE.'lib/images/blank.gif',
199                    'width' => 15,
200                    'height' => 11,
201                    'alt' => '',
202                ]);
203            }
204
205            $form->addTagOpen('span')->addClass('date');
206            $form->addHTML($date);
207            $form->addTagClose('span');
208
209            if ($exists) {
210                if (!$media_id) {
211                    $href = wl($id, "rev=$rev,do=diff", false, '&');
212                } else {
213                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
214                }
215                $form->addTagOpen('a')->attr('href', $href)->addClass('diff_link');
216                $form->addTag('img')->attrs([
217                    'src'    => DOKU_BASE.'lib/images/diff.png',
218                    'width'  => 15,
219                    'height' => 11,
220                    'title'  => $lang['diff'],
221                    'alt'    => $lang['diff'],
222                ]);
223                $form->addTagClose('a');
224
225                if (!$media_id) {
226                    $href = wl($id, "rev=$rev", false, '&');
227                } else {
228                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
229                }
230                $form->addTagOpen('a')->attr('href', $href)->addClass('wikilink1');
231                $form->addHTML($display_name);
232                $form->addTagClose('a');
233            } else {
234                $form->addTag('img')->attrs([
235                    'src'    => DOKU_BASE.'lib/images/blank.gif',
236                    'width'  => 15,
237                    'height' => 11,
238                    'alt'    => '',
239                ]);
240                $form->addHTML($display_name);
241            }
242
243            if ($media_id) $form->addTagOpen('div');
244
245            if ($info['sum']) {
246                $form->addTagOpen('span')->addClass('sum');
247                if (!$media_id) $form->addHTML(' – ');
248                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
249                $form->addTagClose('span');
250            }
251
252            $form->addTagOpen('span')->addClass('user');
253            if ($info['user']) {
254                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
255                if (auth_ismanager()) {
256                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
257                }
258            } else {
259                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
260            }
261            $form->addTagClose('span');
262
263            html_sizechange($info['sizechange'], $form);
264
265            if ($media_id) $form->addTagClose('div');
266
267            $form->addTagClose('div');
268            $form->addTagClose('li');
269        }
270
271        // end of revision list
272        $form->addTagClose('ul');
273
274        // show button for diff view
275        if (!$media_id) {
276            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
277        } else {
278            $form->setHiddenField('mediado', 'diff');
279            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
280        }
281
282        $form->addTagClose('div'); // close div class=no
283
284        // emit HTML_REVISIONSFORM_OUTPUT event, print the form
285        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, 'html_form_output', false);
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