xref: /dokuwiki/inc/Ui/Diff.php (revision 0bb448f077ade9d29503dc6909dee96f6a0c4221)
163ab9afeSSatoshi Sahara<?php
263ab9afeSSatoshi Sahara
363ab9afeSSatoshi Saharanamespace dokuwiki\Ui;
463ab9afeSSatoshi Sahara
563ab9afeSSatoshi Saharause dokuwiki\ChangeLog\PageChangeLog;
663ab9afeSSatoshi Saharause dokuwiki\ChangeLog\MediaChangeLog;
763ab9afeSSatoshi Sahara
863ab9afeSSatoshi Sahara/**
963ab9afeSSatoshi Sahara * DokuWiki Diff Interface
1063ab9afeSSatoshi Sahara * parent class of PageDiff and MediaDiff
1163ab9afeSSatoshi Sahara *
1263ab9afeSSatoshi Sahara * @package dokuwiki\Ui
1363ab9afeSSatoshi Sahara */
1463ab9afeSSatoshi Saharaabstract class Diff extends Ui
1563ab9afeSSatoshi Sahara{
16edb50e6aSSatoshi Sahara    /* @var string */
17edb50e6aSSatoshi Sahara    protected $id;  // page id or media id
18edb50e6aSSatoshi Sahara
19b4b4c5c6SSatoshi Sahara    /* @var int */
20b4b4c5c6SSatoshi Sahara    protected $old_rev;  // older revision, timestamp of left side
21b4b4c5c6SSatoshi Sahara    protected $new_rev;  // newer revision, timestamp of right side
22*0bb448f0SSatoshi Sahara    protected $last_rev; // current revision, or last revision when it had removed
23b4b4c5c6SSatoshi Sahara
24edb50e6aSSatoshi Sahara    /* @var array */
25edb50e6aSSatoshi Sahara    protected $preference = [];
26edb50e6aSSatoshi Sahara
278068440fSSatoshi Sahara    /* @var ChangeLog */
288068440fSSatoshi Sahara    protected $changelog; // PageChangeLog or MediaChangeLog object
298068440fSSatoshi Sahara
30edb50e6aSSatoshi Sahara    /**
31edb50e6aSSatoshi Sahara     * Diff Ui constructor
32edb50e6aSSatoshi Sahara     *
33edb50e6aSSatoshi Sahara     * @param string $id  page id or media id
34edb50e6aSSatoshi Sahara     */
35edb50e6aSSatoshi Sahara    public function __construct($id)
36edb50e6aSSatoshi Sahara    {
37edb50e6aSSatoshi Sahara        $this->id = $id;
388068440fSSatoshi Sahara        $this->setChangeLog();
39edb50e6aSSatoshi Sahara    }
40edb50e6aSSatoshi Sahara
41edb50e6aSSatoshi Sahara    /**
428068440fSSatoshi Sahara     * set class property changelog
438068440fSSatoshi Sahara     */
448068440fSSatoshi Sahara    abstract protected function setChangeLog();
458068440fSSatoshi Sahara
468068440fSSatoshi Sahara    /**
47b4b4c5c6SSatoshi Sahara     * Set a pair of revisions to be compared
48b4b4c5c6SSatoshi Sahara     *
49b4b4c5c6SSatoshi Sahara     * @param int $old_rev
50b4b4c5c6SSatoshi Sahara     * @param int $new_rev
51b4b4c5c6SSatoshi Sahara     * @return $this
52b4b4c5c6SSatoshi Sahara     */
53b4b4c5c6SSatoshi Sahara    public function compare($old_rev, $new_rev)
54b4b4c5c6SSatoshi Sahara    {
55b4b4c5c6SSatoshi Sahara        $this->old_rev = $old_rev;
56b4b4c5c6SSatoshi Sahara        $this->new_rev = $new_rev;
57b4b4c5c6SSatoshi Sahara        return $this;
58b4b4c5c6SSatoshi Sahara    }
59b4b4c5c6SSatoshi Sahara
60b4b4c5c6SSatoshi Sahara    /**
61edb50e6aSSatoshi Sahara     * Gets or Sets preference of the Ui\Diff object
62edb50e6aSSatoshi Sahara     *
63edb50e6aSSatoshi Sahara     * @param string|array $prefs  a key name or key-value pair(s)
64edb50e6aSSatoshi Sahara     * @param mixed $value         value used when the first args is string
65edb50e6aSSatoshi Sahara     * @return array|$this
66edb50e6aSSatoshi Sahara     */
67edb50e6aSSatoshi Sahara    public function preference($prefs = null, $value = null)
68edb50e6aSSatoshi Sahara    {
69edb50e6aSSatoshi Sahara        // set
70295564cdSSatoshi Sahara        if (is_string($prefs) && isset($value)) {
71295564cdSSatoshi Sahara            $this->preference[$prefs] = $value;
72295564cdSSatoshi Sahara            return $this;
73295564cdSSatoshi Sahara        } elseif (is_array($prefs)) {
74edb50e6aSSatoshi Sahara            foreach ($prefs as $name => $value) {
75edb50e6aSSatoshi Sahara                $this->preference[$name] = $value;
76edb50e6aSSatoshi Sahara            }
77edb50e6aSSatoshi Sahara            return $this;
78edb50e6aSSatoshi Sahara        }
79edb50e6aSSatoshi Sahara        // get
80edb50e6aSSatoshi Sahara        return $this->preference;
81edb50e6aSSatoshi Sahara    }
82edb50e6aSSatoshi Sahara
83b4b4c5c6SSatoshi Sahara    /**
84b4b4c5c6SSatoshi Sahara     * Retrieve requested revision(s) and difftype from Ui\Revisions
85b4b4c5c6SSatoshi Sahara     *
86b4b4c5c6SSatoshi Sahara     * @return void
87b4b4c5c6SSatoshi Sahara     */
88b4b4c5c6SSatoshi Sahara    protected function preProcess()
89b4b4c5c6SSatoshi Sahara    {
90b4b4c5c6SSatoshi Sahara        global $INPUT;
91b4b4c5c6SSatoshi Sahara
92b4b4c5c6SSatoshi Sahara        // difflink icon click, eg. ?rev=123456789&do=diff
93b4b4c5c6SSatoshi Sahara        if ($INPUT->has('rev')) {
94b4b4c5c6SSatoshi Sahara            $this->old_rev = $INPUT->int('rev');
95b4b4c5c6SSatoshi Sahara            $this->new_rev = ''; // current revision
96b4b4c5c6SSatoshi Sahara        }
97b4b4c5c6SSatoshi Sahara
98b4b4c5c6SSatoshi Sahara        // submit button with two checked boxes
99b4b4c5c6SSatoshi Sahara        $rev2 = $INPUT->arr('rev2', []);
100b4b4c5c6SSatoshi Sahara        if (count($rev2) > 1) {
101b4b4c5c6SSatoshi Sahara            if ($rev2[0] == 'current') {
102b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[1], ''];
103b4b4c5c6SSatoshi Sahara            } elseif ($rev2[1] == 'current') {
104b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[0], ''];
105b4b4c5c6SSatoshi Sahara            } elseif ($rev2[0] < $rev2[1]) {
106b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[0], $rev2[1]];
107b4b4c5c6SSatoshi Sahara            } else {
108b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[1], $rev2[0]];
109b4b4c5c6SSatoshi Sahara            }
110b4b4c5c6SSatoshi Sahara        }
111b4b4c5c6SSatoshi Sahara
112b4b4c5c6SSatoshi Sahara        // diff view type
113b4b4c5c6SSatoshi Sahara        if ($INPUT->has('difftype')) {
114b4b4c5c6SSatoshi Sahara            // retrieve requested $difftype
115b4b4c5c6SSatoshi Sahara            $this->preference['difftype'] = $INPUT->str('difftype');
116b4b4c5c6SSatoshi Sahara        } else {
117b4b4c5c6SSatoshi Sahara            // read preference from DokuWiki cookie. PageDiff only
11891e70b5fSSatoshi Sahara            get_doku_pref('difftype', $mode);
11991e70b5fSSatoshi Sahara            if (isset($mode)) $this->preference['difftype'] = $mode;
120b4b4c5c6SSatoshi Sahara        }
121b4b4c5c6SSatoshi Sahara    }
122b4b4c5c6SSatoshi Sahara
123b4b4c5c6SSatoshi Sahara
124edb50e6aSSatoshi Sahara
12563ab9afeSSatoshi Sahara    /**
126ec019cbfSSatoshi Sahara     * Build header of diff HTML
12763ab9afeSSatoshi Sahara     *
12863ab9afeSSatoshi Sahara     * @param string $l_rev   Left revisions
12963ab9afeSSatoshi Sahara     * @param string $r_rev   Right revision
13063ab9afeSSatoshi Sahara     * @return string[] HTML snippets for diff header
13163ab9afeSSatoshi Sahara     */
1328068440fSSatoshi Sahara    public function buildDiffHead($l_rev, $r_rev)
13363ab9afeSSatoshi Sahara    {
13463ab9afeSSatoshi Sahara        global $lang;
135edb50e6aSSatoshi Sahara
136edb50e6aSSatoshi Sahara        // detect PageDiff or MediaDiff
1378068440fSSatoshi Sahara        switch (get_class($this->changelog)) {
138edb50e6aSSatoshi Sahara            case PageChangeLog::class :
139*0bb448f0SSatoshi Sahara                $isMedia = false;
140*0bb448f0SSatoshi Sahara                $ui = new PageRevisions($this->id);
141edb50e6aSSatoshi Sahara                break;
142edb50e6aSSatoshi Sahara            case MediaChangeLog::class :
143*0bb448f0SSatoshi Sahara                $isMedia = true;
144*0bb448f0SSatoshi Sahara                $ui = new MediaRevisions($this->id);
145edb50e6aSSatoshi Sahara                break;
14663ab9afeSSatoshi Sahara        }
147edb50e6aSSatoshi Sahara
148edb50e6aSSatoshi Sahara        $head_separator = ($this->preference['difftype'] === 'inline') ? ' ' : '<br />';
149*0bb448f0SSatoshi Sahara
150*0bb448f0SSatoshi Sahara        // assign minor edit checker to the variable
151*0bb448f0SSatoshi Sahara        $minor = function ($info) {
152*0bb448f0SSatoshi Sahara            return ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'class="minor"' : '';
153*0bb448f0SSatoshi Sahara        };
154*0bb448f0SSatoshi Sahara
155*0bb448f0SSatoshi Sahara        // assign link builder to the variable
156*0bb448f0SSatoshi Sahara        $idToUrl = function ($id, $rev = '') use ($isMedia) {
157*0bb448f0SSatoshi Sahara            return ($isMedia) ? ml($id, $rev) : wl($id, $rev);
158*0bb448f0SSatoshi Sahara        };
159*0bb448f0SSatoshi Sahara
160*0bb448f0SSatoshi Sahara        // assign title builder to the variable
161*0bb448f0SSatoshi Sahara        $idToTitle = function ($id, $rev = '') use ($isMedia) {
162*0bb448f0SSatoshi Sahara            return ($isMedia) ? dformat($rev) : $id.' ['.dformat($rev).']';
163*0bb448f0SSatoshi Sahara        };
16463ab9afeSSatoshi Sahara
165edb50e6aSSatoshi Sahara        // left side
16663ab9afeSSatoshi Sahara        if (!$l_rev) {
167*0bb448f0SSatoshi Sahara            $l_minor = '';
16863ab9afeSSatoshi Sahara            $l_head = '&mdash;';
16963ab9afeSSatoshi Sahara        } else {
170*0bb448f0SSatoshi Sahara            $info = $this->changelog->getRevisionInfo($l_rev);
171*0bb448f0SSatoshi Sahara            $objRevInfo = $ui->getObjRevInfo($info);
172*0bb448f0SSatoshi Sahara            $l_minor = $minor($info);
173*0bb448f0SSatoshi Sahara            $l_head = '<bdi><a class="wikilink1" href="'.$idToUrl($this->id, "rev=$l_rev").'">'
174*0bb448f0SSatoshi Sahara                    .$idToTitle($this->id, $l_rev).'</a></bdi>'.$head_separator
175*0bb448f0SSatoshi Sahara                    .$objRevInfo->editor().' '.$objRevInfo->editSummary();
17663ab9afeSSatoshi Sahara
17763ab9afeSSatoshi Sahara        }
17863ab9afeSSatoshi Sahara
179edb50e6aSSatoshi Sahara        // right side
18063ab9afeSSatoshi Sahara        if ($r_rev) {
181*0bb448f0SSatoshi Sahara            $info  = $this->changelog->getRevisionInfo($r_rev);
182*0bb448f0SSatoshi Sahara            $objRevInfo = $ui->getObjRevInfo($info);
183*0bb448f0SSatoshi Sahara            $r_minor = $minor($info);
184*0bb448f0SSatoshi Sahara            $r_head = '<bdi><a class="wikilink1" href="'.$idToUrl($this->id, "rev=$r_rev").'">'
185*0bb448f0SSatoshi Sahara                    .$idToTitle($this->id, $r_rev).'</a></bdi>'.$head_separator
186*0bb448f0SSatoshi Sahara                    .$objRevInfo->editor().' '.$objRevInfo->editSummary();
187*0bb448f0SSatoshi Sahara        } elseif ($this->last_rev) {
188*0bb448f0SSatoshi Sahara            $_rev = $this->last_rev;
189*0bb448f0SSatoshi Sahara            $info = $this->changelog->getRevisionInfo($_rev);
190*0bb448f0SSatoshi Sahara            $objRevInfo = $ui->getObjRevInfo($info);
191*0bb448f0SSatoshi Sahara            $r_minor = $minor($info);
192*0bb448f0SSatoshi Sahara            $r_head  = '<bdi><a class="wikilink1" href="'.$idToUrl($this->id).'">'
193*0bb448f0SSatoshi Sahara                     .$idToTitle($this->id, $_rev).'</a></bdi> '.'('.$lang['current'].')'.$head_separator
194*0bb448f0SSatoshi Sahara                     .$objRevInfo->editor().' '.$objRevInfo->editSummary();
19563ab9afeSSatoshi Sahara        } else {
196*0bb448f0SSatoshi Sahara            $r_minor = '';
19763ab9afeSSatoshi Sahara            $r_head = '&mdash; ('.$lang['current'].')';
19863ab9afeSSatoshi Sahara        }
19963ab9afeSSatoshi Sahara
20063ab9afeSSatoshi Sahara        return array($l_head, $r_head, $l_minor, $r_minor);
20163ab9afeSSatoshi Sahara    }
20263ab9afeSSatoshi Sahara
20363ab9afeSSatoshi Sahara}
204