1<?php
2
3namespace dokuwiki\Ui;
4
5use dokuwiki\ChangeLog\ChangeLog;
6
7/**
8 * DokuWiki Revisions Interface
9 * parent class of PageRevisions and MediaRevisions
10 *
11 * Note: navigation starts from -1, not 0. This is because our Revision management starts old revisions at 0 and
12 * will return the current revision only if the revisions starting at -1 are requested.
13 *
14 * @package dokuwiki\Ui
15 */
16abstract class Revisions extends Ui
17{
18    /* @var string */
19    protected $id;   // page id or media id
20
21    /* @var ChangeLog */
22    protected $changelog; // PageChangeLog or MediaChangeLog object
23
24    /**
25     * Revisions Ui constructor
26     *
27     * @param string $id page id or media id
28     */
29    public function __construct($id)
30    {
31        $this->id = $id;
32        $this->setChangeLog();
33    }
34
35    /**
36     * set class property changelog
37     */
38    abstract protected function setChangeLog();
39
40    /**
41     * Get revisions, and set correct pagination parameters (first, hasNext)
42     *
43     * @param int $first
44     * @param bool $hasNext
45     * @return array  revisions to be shown in a paginated list
46     * @see also https://www.dokuwiki.org/devel:changelog
47     */
48    protected function getRevisions(&$first, &$hasNext)
49    {
50        global $conf;
51
52        $changelog =& $this->changelog;
53        $revisions = [];
54
55        $currentRevInfo = $changelog->getCurrentRevisionInfo();
56        if (!$currentRevInfo) return $revisions;
57
58        $num = $conf['recent'];
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 also Ui\Recent::getRecents()
63         */
64        $revlist = $changelog->getRevisions($first, $num + 1);
65        if (count($revlist) == 0 && $first > -1) {
66            // resets to zero if $first requested a too high number
67            $first = -1;
68            return $this->getRevisions($first, $hasNext);
69        }
70
71        // decide if this is the last page or is there another one
72        $hasNext = false;
73        if (count($revlist) > $num) {
74            $hasNext = true;
75            array_pop($revlist); // remove one additional log entry
76        }
77
78        // append each revision info array to the revisions
79        foreach ($revlist as $rev) {
80            $revisions[] = $changelog->getRevisionInfo($rev);
81        }
82        return $revisions;
83    }
84
85    /**
86     * Navigation buttons for Pagination (prev/next)
87     *
88     * @param int $first
89     * @param bool $hasNext
90     * @param callable $callback returns array of hidden fields for the form button
91     * @return string html
92     */
93    protected function navigation($first, $hasNext, $callback)
94    {
95        global $conf;
96
97        $html = '<div class="pagenav">';
98        $last = $first + $conf['recent'];
99        if ($first > -1) {
100            $first = max($first - $conf['recent'], -1);
101            $html .= '<div class="pagenav-prev">';
102            $html .= html_btn('newer', $this->id, "p", $callback($first));
103            $html .= '</div>';
104        }
105        if ($hasNext) {
106            $html .= '<div class="pagenav-next">';
107            $html .= html_btn('older', $this->id, "n", $callback($last));
108            $html .= '</div>';
109        }
110        $html .= '</div>';
111        return $html;
112    }
113}
114