xref: /dokuwiki/inc/Ui/MediaRevisions.php (revision ae5d2354c9aa93da542d9f0607167c5e0a6100be)
1<?php
2
3namespace dokuwiki\Ui;
4
5use dokuwiki\ChangeLog\MediaChangeLog;
6use dokuwiki\Form\Form;
7
8/**
9 * DokuWiki MediaRevisions Interface
10 *
11 * @package dokuwiki\Ui
12 */
13class MediaRevisions extends Revisions
14{
15    /**
16     * MediaRevisions Ui constructor
17     *
18     * @param string $id  id of media
19     */
20    public function __construct($id)
21    {
22        parent::__construct($id);
23    }
24
25    /**
26     * Display a list of Media Revisions in the MediaManager
27     *
28     * @author Andreas Gohr <andi@splitbrain.org>
29     * @author Ben Coburn <btcoburn@silicodon.net>
30     * @author Kate Arzamastseva <pshns@ukr.net>
31     * @author Satoshi Sahara <sahara.satoshi@gmail.com>
32     *
33     * @param int $first  skip the first n changelog lines
34     * @return void
35     */
36    public function show($first = 0)
37    {
38        global $lang;
39
40        // get revisions, and set correct pagenation parameters (first, hasNext)
41        if ($first === null) $first = 0;
42        $hasNext = false;
43        $revisions = $this->getRevisions($first, $hasNext);
44
45        // create the form
46        $form = new Form([
47                'id' => 'page__revisions', // must not be "media__revisions"
48                'action' => media_managerURL(['image' => $this->id], '&'),
49                'class'  => 'changes',
50        ]);
51        $form->setHiddenField('mediado', 'diff'); // required for media revisions
52        $form->addTagOpen('div')->addClass('no');
53
54        // start listing
55        $form->addTagOpen('ul');
56        foreach ($revisions as $info) {
57            $rev = $info['date'];
58            $class = ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : '';
59            $form->addTagOpen('li')->addClass($class);
60            $form->addTagOpen('div')->addClass('li');
61
62            if (isset($info['current'])) {
63               $form->addCheckbox('rev2[]')->val('current');
64            } elseif (file_exists(mediaFN($this->id, $rev))) {
65                $form->addCheckbox('rev2[]')->val($rev);
66            } else {
67                $form->addCheckbox('')->val($rev)->attr('disabled','disabled');
68            }
69            $form->addHTML(' ');
70
71            $objRevInfo = $this->getObjRevInfo($info);
72            $html = implode(' ', [
73                $objRevInfo->editDate(),          // edit date and time
74                $objRevInfo->difflink(),          // link to diffview icon
75                $objRevInfo->itemName(),          // name of page or media
76                '<div>',
77                $objRevInfo->editSummary(),       // edit summary
78                $objRevInfo->editor(),            // editor info
79                $objRevInfo->sizechange(),        // size change indicator
80                $objRevInfo->currentIndicator(),  // current indicator (only when k=1)
81                '</div>',
82            ]);
83            $form->addHTML($html);
84
85            $form->addTagClose('div');
86            $form->addTagClose('li');
87        }
88        $form->addTagClose('ul');  // end of revision list
89
90        // show button for diff view
91        $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit');
92
93        $form->addTagClose('div'); // close div class=no
94
95        print $form->toHTML('Revisions');
96
97        // provide navigation for pagenated revision list (of pages and/or media files)
98        print $this->navigation($first, $hasNext, function ($n) {
99            return media_managerURL(['first' => $n], '&', false, true);
100        });
101    }
102
103    /**
104     * Get revisions, and set correct pagenation parameters (first, hasNext)
105     *
106     * @param int  $first
107     * @param bool $hasNext
108     * @return array  revisions to be shown in a pagenated list
109     * @see also https://www.dokuwiki.org/devel:changelog
110     */
111    protected function getRevisions(&$first, &$hasNext)
112    {
113        global $conf;
114
115        $changelog = new MediaChangeLog($this->id);
116
117        $revisions = [];
118
119        /* we need to get one additional log entry to be able to
120         * decide if this is the last page or is there another one.
121         * see also Ui\Recent::getRecents()
122         */
123        $revlist = $changelog->getRevisions($first, $conf['recent'] +1);
124        if (count($revlist) == 0 && $first != 0) {
125            $first = 0;
126            $revlist = $changelog->getRevisions($first, $conf['recent'] +1);
127        }
128        $exists = file_exists(mediaFN($this->id));
129        if ($first === 0 && $exists) {
130            // add current media as revision[0]
131            $rev = filemtime(fullpath(mediaFN($this->id)));
132            $changelog->setChunkSize(1024);
133            $revinfo = $changelog->getRevisionInfo($rev) ?: array(
134                    'date' => $rev,
135                    'ip'   => null,
136                    'type' => null,
137                    'id'   => $this->id,
138                    'user' => null,
139                    'sum'  => null,
140                    'extra' => null,
141                    'sizechange' => null,
142            );
143            $revisions[] = $revinfo + array(
144                    'media' => true,
145                    'current' => true,
146            );
147        }
148
149        // decide if this is the last page or is there another one
150        $hasNext = false;
151        if (count($revlist) > $conf['recent']) {
152            $hasNext = true;
153            array_pop($revlist); // remove one additional log entry
154        }
155
156        // append each revison info array to the revisions
157        foreach ($revlist as $rev) {
158            $revisions[] = $changelog->getRevisionInfo($rev) + array('media' => true);
159        }
160        return $revisions;
161    }
162
163}
164