xref: /dokuwiki/inc/Ui/Revisions.php (revision 6c9fde8289c5959cefa114d8249b987ac85eb3f1)
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 Insterface
12 *
13 * @package dokuwiki\Ui
14 */
15class Revisions extends Ui
16{
17    /**
18     * Display list of old revisions
19     *
20     * @author Andreas Gohr <andi@splitbrain.org>
21     * @author Ben Coburn <btcoburn@silicodon.net>
22     * @author Kate Arzamastseva <pshns@ukr.net>
23     *
24     * @triggers HTML_REVISIONSFORM_OUTPUT
25     * @param int $first skip the first n changelog lines
26     * @param bool|string $media_id id of media, or false for current page
27     * @return void
28     */
29    public function show($first = 0, $media_id = false)
30    {
31        global $ID;
32        global $INFO;
33        global $conf;
34        global $lang;
35        $id = $ID;
36        if ($media_id) {
37            $id = $media_id;
38            $changelog = new MediaChangeLog($id);
39        } else {
40            $changelog = new PageChangeLog($id);
41        }
42
43        /* we need to get one additional log entry to be able to
44         * decide if this is the last page or is there another one.
45         * see html_recent()
46         */
47
48        $revisions = $changelog->getRevisions($first, $conf['recent'] +1);
49
50        if (count($revisions) == 0 && $first != 0) {
51            $first = 0;
52            $revisions = $changelog->getRevisions($first, $conf['recent'] +1);
53        }
54        $hasNext = false;
55        if (count($revisions) > $conf['recent']) {
56            $hasNext = true;
57            array_pop($revisions); // remove extra log entry
58        }
59
60        // print intro
61        if (!$media_id) {
62            print p_locale_xhtml('revisions');
63            $exists = $INFO['exists'];
64            $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
65            if (!$display_name) {
66                $display_name = $id;
67            }
68        } else {
69            $exists = file_exists(mediaFN($id));
70            $display_name = $id;
71        }
72
73        // create the form
74        $form = new Form(['id' => 'page__revisions']);
75        $form->addClass('changes');
76        if ($media_id) {
77            $form->attr('action', media_managerURL(array('image' => $media_id), '&'));
78        }
79
80        // start listing
81        $form->addTagOpen('ul');
82
83        if ($exists && $first == 0) {
84            $minor = false;
85            if ($media_id) {
86                $date = dformat(@filemtime(mediaFN($id)));
87                $href = media_managerURL(array('image' => $id, 'tab_details' => 'view'), '&');
88
89                $changelog->setChunkSize(1024);
90                $revinfo = $changelog->getRevisionInfo(@filemtime(fullpath(mediaFN($id))));
91
92                $summary = $revinfo['sum'];
93                $editor = $revinfo['user'] ?: $revinfo['ip'];
94                $sizechange = $revinfo['sizechange'];
95            } else {
96                $date = dformat($INFO['lastmod']);
97                if (isset($INFO['meta']) && isset($INFO['meta']['last_change'])) {
98                    if ($INFO['meta']['last_change']['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
99                        $minor = true;
100                    }
101                    if (isset($INFO['meta']['last_change']['sizechange'])) {
102                        $sizechange = $INFO['meta']['last_change']['sizechange'];
103                    } else {
104                        $sizechange = null;
105                    }
106                }
107                $pagelog = new PageChangeLog($ID);
108                $latestrev = $pagelog->getRevisions(-1, 1);
109                $latestrev = array_pop($latestrev);
110                $href = wl($id, "rev=$latestrev", false, '&');
111                $summary = $INFO['sum'];
112                $editor = $INFO['editor'];
113            }
114
115            $form->addTagOpen('li')->addClass($minor ? 'minor' : '');
116            $form->addTagOpen('div')->addClass('li');
117            $form->addCheckbox('rev2[]')->val('current');
118
119            $form->addTagOpen('span')->addClass('data');
120            $form->addHTML($date);
121            $form->addTagClose('span');
122
123            $form->addTag('img')->attrs([
124                'src' => DOKU_BASE.'lib/images/blank.gif',
125                'width' => 15,
126                'height' => 11,
127                'alt' => '',
128            ]);
129
130            $form->addTagOPen('a')->attr('href', $href)->addClass('wikilink1');
131            $form->addHTML($display_name);
132            $form->addTagClose('a');
133
134            if ($media_id) $form->addTagOpen('div');
135
136            if ($summary) {
137                $form->addTagOpen('span')->addClass('sum');
138                if (!$media_id) $form->addHTML(' – ');
139                $form->addHTML('<bdi>' . hsc($summary) . '</bdi>');
140                $form->addTagClose('span');
141            }
142
143            $form->addTagOpen('span')->addClass('user');
144            $form->addHTML(
145                (empty($editor)) ? ('('.$lang['external_edit'].')') : '<bdi>'.editorinfo($editor).'</bdi>'
146            );
147            $form->addTagClose('span');
148
149
150            html_sizechange($sizechange, $form);
151
152            $form->addHTML('('.$lang['current'].')');
153
154            if ($media_id) $form->addTagClose('div');
155
156            $form->addTagClose('div');
157            $form->addTagClose('li');
158        }
159
160        foreach ($revisions as $rev) {
161            $date = dformat($rev);
162            $info = $changelog->getRevisionInfo($rev);
163            if ($media_id) {
164                $exists = file_exists(mediaFN($id, $rev));
165            } else {
166                $exists = page_exists($id, $rev);
167            }
168
169            $class = '';
170            if ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
171                $class = 'minor';
172            }
173
174            $form->addTagOpen('li')->addClass($class);
175            $form->addTagOpen('div')->addClass('li');
176
177            if ($exists){
178                $form->addCheckbox('rev2[]')->val($rev);
179            } else {
180                $form->addTag('img')->attrs([
181                    'src' => DOKU_BASE.'lib/images/blank.gif',
182                    'width' => 15,
183                    'height' => 11,
184                    'alt' => '',
185                ]);
186            }
187
188            $form->addTagOpen('span')->addClass('date');
189            $form->addHTML($date);
190            $form->addTagClose('span');
191
192            if ($exists) {
193                if (!$media_id) {
194                    $href = wl($id, "rev=$rev,do=diff", false, '&');
195                } else {
196                    $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
197                }
198                $form->addTagOpen('a')->attr('href', $href)->addClass('diff_link');
199                $form->addTag('img')->attrs([
200                    'src'    => DOKU_BASE.'lib/images/diff.png',
201                    'width'  => 15,
202                    'height' => 11,
203                    'title'  => $lang['diff'],
204                    'alt'    => $lang['diff'],
205                ]);
206                $form->addTagClose('a');
207
208                if (!$media_id) {
209                    $href = wl($id, "rev=$rev", false, '&');
210                } else {
211                    $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
212                }
213                $form->addTagOpen('a')->attr('href', $href)->addClass('wikilink1');
214                $form->addHTML($display_name);
215                $form->addTagClose('a');
216            } else {
217                $form->addTag('img')->attrs([
218                    'src'    => DOKU_BASE.'lib/images/blank.gif',
219                    'width'  => 15,
220                    'height' => 11,
221                    'alt'    => '',
222                ]);
223                $form->addHTML($display_name);
224            }
225
226            if ($media_id) $form->addTagOpen('div');
227
228            if ($info['sum']) {
229                $form->addTagOpen('span')->addClass('sum');
230                if (!$media_id) $form->addHTML(' – ');
231                $form->addHTML('<bdi>'. hsc($info['sum']) .'</bdi>');
232                $form->addTagClose('span');
233            }
234
235            $form->addTagOpen('span')->addClass('user');
236            if ($info['user']) {
237                $form->addHTML('<bdi>'. editorinfo($info['user']) .'</bdi>');
238                if (auth_ismanager()) {
239                    $form->addHTML(' <bdo dir="ltr">('. $info['ip'] .')</bdo>');
240                }
241            } else {
242                $form->addHTML('<bdo dir="ltr">' .$info['ip'] .'</bdo>');
243            }
244            $form->addTagClose('span');
245
246            html_sizechange($info['sizechange'], $form);
247
248            if ($media_id) $form->addTagClose('div');
249
250            $form->addTagClose('div');
251            $form->addTagClose('li');
252        }
253
254        // end of revision list
255        $form->addTagClose('ul');
256
257        // show button for diff view
258        if (!$media_id) {
259            $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
260        } else {
261            $form->setHiddenField('mediado', 'diff');
262            $form->addButton('', $lang['diff2'])->attr('type', 'submit');
263        }
264
265        $form->addTagClose('div'); // close div class=no
266
267        // emit HTML_REVISIONSFORM_OUTPUT event, print the form
268        Event::createAndTrigger('HTML_REVISIONSFORM_OUTPUT', $form, 'html_form_output', false);
269
270        print DOKU_LF;
271
272        // provide navigation for pagenated revision list (of pages and/or media files)
273        print '<div class="pagenav">';
274        $last = $first + $conf['recent'];
275        if ($first > 0) {
276            $first = $first - $conf['recent'];
277            if ($first < 0) $first = 0;
278            print '<div class="pagenav-prev">';
279            if ($media_id) {
280                print html_btn('newer',$media_id,"p",media_managerURL(array('first' => $first), '&amp;', false, true));
281            } else {
282                print html_btn('newer',$id,"p",array('do' => 'revisions', 'first' => $first));
283            }
284            print '</div>';
285        }
286        if ($hasNext) {
287            print '<div class="pagenav-next">';
288            if ($media_id) {
289                print html_btn('older',$media_id,"n",media_managerURL(array('first' => $last), '&amp;', false, true));
290            } else {
291                print html_btn('older',$id,"n",array('do' => 'revisions', 'first' => $last));
292            }
293            print '</div>';
294        }
295        print '</div>';
296
297        print DOKU_LF;
298    }
299
300}
301