xref: /dokuwiki/inc/Ui/Diff.php (revision cc5508fe8992ffd0353114ddea6cea638b31f1ac)
163ab9afeSSatoshi Sahara<?php
263ab9afeSSatoshi Sahara
363ab9afeSSatoshi Saharanamespace dokuwiki\Ui;
463ab9afeSSatoshi Sahara
5*cc5508feSSatoshi Saharause dokuwiki\ChangeLog\ChangeLog;
6*cc5508feSSatoshi Sahara
763ab9afeSSatoshi Sahara/**
863ab9afeSSatoshi Sahara * DokuWiki Diff Interface
963ab9afeSSatoshi Sahara * parent class of PageDiff and MediaDiff
1063ab9afeSSatoshi Sahara *
1163ab9afeSSatoshi Sahara * @package dokuwiki\Ui
1263ab9afeSSatoshi Sahara */
1363ab9afeSSatoshi Saharaabstract class Diff extends Ui
1463ab9afeSSatoshi Sahara{
15edb50e6aSSatoshi Sahara    /* @var string */
16edb50e6aSSatoshi Sahara    protected $id;   // page id or media id
17e71e09a6SSatoshi Sahara    protected $item; // page or media
18edb50e6aSSatoshi Sahara
1992440599SSatoshi Sahara    /* @var int|string */
2092440599SSatoshi Sahara    protected $oldRev;  // timestamp of older revision, '' means current one
2192440599SSatoshi Sahara    protected $newRev;  // timestamp of newer revision, '' means current one
22b4b4c5c6SSatoshi Sahara
23edb50e6aSSatoshi Sahara    /* @var array */
24edb50e6aSSatoshi Sahara    protected $preference = [];
25edb50e6aSSatoshi Sahara
268068440fSSatoshi Sahara    /* @var ChangeLog */
278068440fSSatoshi Sahara    protected $changelog; // PageChangeLog or MediaChangeLog object
288068440fSSatoshi Sahara
29edb50e6aSSatoshi Sahara    /**
30edb50e6aSSatoshi Sahara     * Diff Ui constructor
31edb50e6aSSatoshi Sahara     *
32edb50e6aSSatoshi Sahara     * @param string $id  page id or media id
33edb50e6aSSatoshi Sahara     */
34edb50e6aSSatoshi Sahara    public function __construct($id)
35edb50e6aSSatoshi Sahara    {
36edb50e6aSSatoshi Sahara        $this->id = $id;
378068440fSSatoshi Sahara        $this->setChangeLog();
38edb50e6aSSatoshi Sahara    }
39edb50e6aSSatoshi Sahara
40edb50e6aSSatoshi Sahara    /**
418068440fSSatoshi Sahara     * set class property changelog
428068440fSSatoshi Sahara     */
438068440fSSatoshi Sahara    abstract protected function setChangeLog();
448068440fSSatoshi Sahara
458068440fSSatoshi Sahara    /**
46d9c75b22SSatoshi Sahara     * item filename resolver
47d9c75b22SSatoshi Sahara     *
48d9c75b22SSatoshi Sahara     * @param string $id  page id or media id
49d9c75b22SSatoshi Sahara     * @param int|string $rev revision timestamp, or empty string for current one
50d9c75b22SSatoshi Sahara     * @return string full path
51d9c75b22SSatoshi Sahara     */
52d9c75b22SSatoshi Sahara    abstract protected function itemFN($id, $rev = '');
53d9c75b22SSatoshi Sahara
54d9c75b22SSatoshi Sahara    /**
55b4b4c5c6SSatoshi Sahara     * Set a pair of revisions to be compared
56b4b4c5c6SSatoshi Sahara     *
573d0f231eSSatoshi Sahara     * @param int $oldRev
583d0f231eSSatoshi Sahara     * @param int $newRev
59b4b4c5c6SSatoshi Sahara     * @return $this
60b4b4c5c6SSatoshi Sahara     */
613d0f231eSSatoshi Sahara    public function compare($oldRev, $newRev)
62b4b4c5c6SSatoshi Sahara    {
633d0f231eSSatoshi Sahara        $this->oldRev = $oldRev;
643d0f231eSSatoshi Sahara        $this->newRev = $newRev;
65b4b4c5c6SSatoshi Sahara        return $this;
66b4b4c5c6SSatoshi Sahara    }
67b4b4c5c6SSatoshi Sahara
68b4b4c5c6SSatoshi Sahara    /**
69edb50e6aSSatoshi Sahara     * Gets or Sets preference of the Ui\Diff object
70edb50e6aSSatoshi Sahara     *
71edb50e6aSSatoshi Sahara     * @param string|array $prefs  a key name or key-value pair(s)
72edb50e6aSSatoshi Sahara     * @param mixed $value         value used when the first args is string
73edb50e6aSSatoshi Sahara     * @return array|$this
74edb50e6aSSatoshi Sahara     */
75edb50e6aSSatoshi Sahara    public function preference($prefs = null, $value = null)
76edb50e6aSSatoshi Sahara    {
77edb50e6aSSatoshi Sahara        // set
78295564cdSSatoshi Sahara        if (is_string($prefs) && isset($value)) {
79295564cdSSatoshi Sahara            $this->preference[$prefs] = $value;
80295564cdSSatoshi Sahara            return $this;
81295564cdSSatoshi Sahara        } elseif (is_array($prefs)) {
82edb50e6aSSatoshi Sahara            foreach ($prefs as $name => $value) {
83edb50e6aSSatoshi Sahara                $this->preference[$name] = $value;
84edb50e6aSSatoshi Sahara            }
85edb50e6aSSatoshi Sahara            return $this;
86edb50e6aSSatoshi Sahara        }
87edb50e6aSSatoshi Sahara        // get
88edb50e6aSSatoshi Sahara        return $this->preference;
89edb50e6aSSatoshi Sahara    }
90edb50e6aSSatoshi Sahara
91b4b4c5c6SSatoshi Sahara    /**
92b4b4c5c6SSatoshi Sahara     * Retrieve requested revision(s) and difftype from Ui\Revisions
93b4b4c5c6SSatoshi Sahara     *
94b4b4c5c6SSatoshi Sahara     * @return void
95b4b4c5c6SSatoshi Sahara     */
96b4b4c5c6SSatoshi Sahara    protected function preProcess()
97b4b4c5c6SSatoshi Sahara    {
98b4b4c5c6SSatoshi Sahara        global $INPUT;
99b4b4c5c6SSatoshi Sahara
100b4b4c5c6SSatoshi Sahara        // difflink icon click, eg. ?rev=123456789&do=diff
101b4b4c5c6SSatoshi Sahara        if ($INPUT->has('rev')) {
1023d0f231eSSatoshi Sahara            $this->oldRev = $INPUT->int('rev');
1033d0f231eSSatoshi Sahara            $this->newRev = ''; // current revision
104b4b4c5c6SSatoshi Sahara        }
105b4b4c5c6SSatoshi Sahara
106b4b4c5c6SSatoshi Sahara        // submit button with two checked boxes
107b4b4c5c6SSatoshi Sahara        $rev2 = $INPUT->arr('rev2', []);
108b4b4c5c6SSatoshi Sahara        if (count($rev2) > 1) {
109b4b4c5c6SSatoshi Sahara            if ($rev2[0] == 'current') {
1103d0f231eSSatoshi Sahara                [$this->oldRev, $this->newRev] = [$rev2[1], ''];
111b4b4c5c6SSatoshi Sahara            } elseif ($rev2[1] == 'current') {
1123d0f231eSSatoshi Sahara                [$this->oldRev, $this->newRev] = [$rev2[0], ''];
113b4b4c5c6SSatoshi Sahara            } elseif ($rev2[0] < $rev2[1]) {
1143d0f231eSSatoshi Sahara                [$this->oldRev, $this->newRev] = [$rev2[0], $rev2[1]];
115b4b4c5c6SSatoshi Sahara            } else {
1163d0f231eSSatoshi Sahara                [$this->oldRev, $this->newRev] = [$rev2[1], $rev2[0]];
117b4b4c5c6SSatoshi Sahara            }
118b4b4c5c6SSatoshi Sahara        }
119b4b4c5c6SSatoshi Sahara
120b4b4c5c6SSatoshi Sahara        // diff view type
121b4b4c5c6SSatoshi Sahara        if ($INPUT->has('difftype')) {
122b4b4c5c6SSatoshi Sahara            // retrieve requested $difftype
123b4b4c5c6SSatoshi Sahara            $this->preference['difftype'] = $INPUT->str('difftype');
124b4b4c5c6SSatoshi Sahara        } else {
125b4b4c5c6SSatoshi Sahara            // read preference from DokuWiki cookie. PageDiff only
1262fe2fb53SSatoshi Sahara            $mode = get_doku_pref('difftype', $mode = null);
12791e70b5fSSatoshi Sahara            if (isset($mode)) $this->preference['difftype'] = $mode;
128b4b4c5c6SSatoshi Sahara        }
129b4b4c5c6SSatoshi Sahara    }
130b4b4c5c6SSatoshi Sahara
131179b4660SSatoshi Sahara    /**
132179b4660SSatoshi Sahara     * get extended revision info
133179b4660SSatoshi Sahara     *
134*cc5508feSSatoshi Sahara     * @param int|string $rev  revision identifier, '' means current one, null means
135179b4660SSatoshi Sahara     * @return array  revision info structure of a page or media file
136179b4660SSatoshi Sahara     */
137179b4660SSatoshi Sahara    protected function getExtendedRevisionInfo($rev)
138179b4660SSatoshi Sahara    {
139179b4660SSatoshi Sahara        $changelog =& $this->changelog;
140179b4660SSatoshi Sahara
141179b4660SSatoshi Sahara        if ($rev) {
142179b4660SSatoshi Sahara            $info = $changelog->getRevisionInfo($rev);
143*cc5508feSSatoshi Sahara            //if external deletion, rev 9999999999 was used.
144*cc5508feSSatoshi Sahara            $info = is_array($info) ? $info : $changelog->getExternalEditRevInfo() ?: [];
145*cc5508feSSatoshi Sahara        } elseif ($rev === null) { //if do=diff at just created page
146*cc5508feSSatoshi Sahara            $info = [
147*cc5508feSSatoshi Sahara                'none' => true
148*cc5508feSSatoshi Sahara            ];
149179b4660SSatoshi Sahara        } elseif (file_exists($filename = $this->itemFN($this->id))) {
150179b4660SSatoshi Sahara            $rev = filemtime(fullpath($filename));
151*cc5508feSSatoshi Sahara            $info = $changelog->getRevisionInfo($rev);
152*cc5508feSSatoshi Sahara            // if external edit, file exist but has no changelog line
153*cc5508feSSatoshi Sahara            $info = is_array($info) ? $info : $changelog->getExternalEditRevInfo() ?: [];
154*cc5508feSSatoshi Sahara            $info = $info + [
155*cc5508feSSatoshi Sahara                'current' => true
156*cc5508feSSatoshi Sahara            ];
157179b4660SSatoshi Sahara        } else { // once exists, but now removed
158*cc5508feSSatoshi Sahara            $lastRev = $changelog->getRevisions(-1, 1); // from changelog
159*cc5508feSSatoshi Sahara            $lastRev = (int) (empty($lastRev) ? 0 : $lastRev[0]);
160*cc5508feSSatoshi Sahara            $info = $changelog->getRevisionInfo($lastRev);
161*cc5508feSSatoshi Sahara            if (!(is_array($info) && $info['type'] == DOKU_CHANGE_TYPE_DELETE)) {
162*cc5508feSSatoshi Sahara                $info = $changelog->getExternalEditRevInfo();
163*cc5508feSSatoshi Sahara                $info = is_array($info) && $info['type'] == DOKU_CHANGE_TYPE_DELETE ? $info : [];
164179b4660SSatoshi Sahara            }
165*cc5508feSSatoshi Sahara            $info = $info + [
166*cc5508feSSatoshi Sahara                'current' => true
167*cc5508feSSatoshi Sahara            ];
168*cc5508feSSatoshi Sahara        }
169*cc5508feSSatoshi Sahara        return ['item' => $this->item] + $info;
170179b4660SSatoshi Sahara    }
171179b4660SSatoshi Sahara
172b4b4c5c6SSatoshi Sahara
173edb50e6aSSatoshi Sahara
17463ab9afeSSatoshi Sahara    /**
175ec019cbfSSatoshi Sahara     * Build header of diff HTML
17663ab9afeSSatoshi Sahara     *
17763ab9afeSSatoshi Sahara     * @param string $l_rev   Left revisions
17863ab9afeSSatoshi Sahara     * @param string $r_rev   Right revision
17963ab9afeSSatoshi Sahara     * @return string[] HTML snippets for diff header
180cb5998b4SSatoshi Sahara     * @deprecated 2020-12-31
18163ab9afeSSatoshi Sahara     */
1828068440fSSatoshi Sahara    public function buildDiffHead($l_rev, $r_rev)
18363ab9afeSSatoshi Sahara    {
184cb5998b4SSatoshi Sahara        dbg_deprecated('not used see '. \dokuwiki\Ui\PageDiff::class .'::show()');
18563ab9afeSSatoshi Sahara    }
18663ab9afeSSatoshi Sahara
18763ab9afeSSatoshi Sahara}
188