xref: /dokuwiki/inc/Ui/Diff.php (revision 90c7493e5431e6bb1956245e233ab58734b59b05)
1<?php
2
3namespace dokuwiki\Ui;
4
5/**
6 * DokuWiki Diff Interface
7 * parent class of PageDiff and MediaDiff
8 *
9 * @package dokuwiki\Ui
10 */
11abstract class Diff extends Ui
12{
13    /* @var string */
14    protected $id;   // page id or media id
15    protected $item; // page or media
16
17    /* @var int|string */
18    protected $oldRev;  // timestamp of older revision, '' means current one
19    protected $newRev;  // timestamp of newer revision, '' means current one
20
21    /* @var array */
22    protected $preference = [];
23
24    /* @var ChangeLog */
25    protected $changelog; // PageChangeLog or MediaChangeLog object
26
27    /**
28     * Diff Ui constructor
29     *
30     * @param string $id  page id or media id
31     */
32    public function __construct($id)
33    {
34        $this->id = $id;
35        $this->setChangeLog();
36    }
37
38    /**
39     * set class property changelog
40     */
41    abstract protected function setChangeLog();
42
43    /**
44     * item filename resolver
45     *
46     * @param string $id  page id or media id
47     * @param int|string $rev revision timestamp, or empty string for current one
48     * @return string full path
49     */
50    abstract protected function itemFN($id, $rev = '');
51
52    /**
53     * Set a pair of revisions to be compared
54     *
55     * @param int $oldRev
56     * @param int $newRev
57     * @return $this
58     */
59    public function compare($oldRev, $newRev)
60    {
61        $this->oldRev = $oldRev;
62        $this->newRev = $newRev;
63        return $this;
64    }
65
66    /**
67     * Gets or Sets preference of the Ui\Diff object
68     *
69     * @param string|array $prefs  a key name or key-value pair(s)
70     * @param mixed $value         value used when the first args is string
71     * @return array|$this
72     */
73    public function preference($prefs = null, $value = null)
74    {
75        // set
76        if (is_string($prefs) && isset($value)) {
77            $this->preference[$prefs] = $value;
78            return $this;
79        } elseif (is_array($prefs)) {
80            foreach ($prefs as $name => $value) {
81                $this->preference[$name] = $value;
82            }
83            return $this;
84        }
85        // get
86        return $this->preference;
87    }
88
89    /**
90     * Retrieve requested revision(s) and difftype from Ui\Revisions
91     *
92     * @return void
93     */
94    protected function preProcess()
95    {
96        global $INPUT;
97
98        // difflink icon click, eg. ?rev=123456789&do=diff
99        if ($INPUT->has('rev')) {
100            $this->oldRev = $INPUT->int('rev');
101            $this->newRev = ''; // current revision
102        }
103
104        // submit button with two checked boxes
105        $rev2 = $INPUT->arr('rev2', []);
106        if (count($rev2) > 1) {
107            if ($rev2[0] == 'current') {
108                [$this->oldRev, $this->newRev] = [$rev2[1], ''];
109            } elseif ($rev2[1] == 'current') {
110                [$this->oldRev, $this->newRev] = [$rev2[0], ''];
111            } elseif ($rev2[0] < $rev2[1]) {
112                [$this->oldRev, $this->newRev] = [$rev2[0], $rev2[1]];
113            } else {
114                [$this->oldRev, $this->newRev] = [$rev2[1], $rev2[0]];
115            }
116        }
117
118        // diff view type
119        if ($INPUT->has('difftype')) {
120            // retrieve requested $difftype
121            $this->preference['difftype'] = $INPUT->str('difftype');
122        } else {
123            // read preference from DokuWiki cookie. PageDiff only
124            $mode = get_doku_pref('difftype', $mode = null);
125            if (isset($mode)) $this->preference['difftype'] = $mode;
126        }
127    }
128
129    /**
130     * get extended revision info
131     *
132     * @param int|string $rev  revision identifier, '' means current one
133     * @return array  revision info structure of a page or media file
134     */
135    protected function getExtendedRevisionInfo($rev)
136    {
137        $changelog =& $this->changelog;
138
139        if ($rev) {
140            $info = $changelog->getRevisionInfo($rev);
141        } elseif (file_exists($filename = $this->itemFN($this->id))) {
142            $rev = filemtime(fullpath($filename));
143            $info = $changelog->getRevisionInfo($rev) + array(
144                'current' => true,
145            );
146        } else { // once exists, but now removed
147            $info = array(
148                'current' => true,
149            );
150        }
151        return array('item' => $this->item) + $info;
152    }
153
154
155
156    /**
157     * Build header of diff HTML
158     *
159     * @param string $l_rev   Left revisions
160     * @param string $r_rev   Right revision
161     * @return string[] HTML snippets for diff header
162     * @deprecated 2020-12-31
163     */
164    public function buildDiffHead($l_rev, $r_rev)
165    {
166        dbg_deprecated('not used see '. \dokuwiki\Ui\PageDiff::class .'::show()');
167    }
168
169}
170