xref: /dokuwiki/inc/Ui/Diff.php (revision e71e09a62e4986d588e0afb8128f2eb7cfa41a12)
163ab9afeSSatoshi Sahara<?php
263ab9afeSSatoshi Sahara
363ab9afeSSatoshi Saharanamespace dokuwiki\Ui;
463ab9afeSSatoshi Sahara
563ab9afeSSatoshi Sahara/**
663ab9afeSSatoshi Sahara * DokuWiki Diff Interface
763ab9afeSSatoshi Sahara * parent class of PageDiff and MediaDiff
863ab9afeSSatoshi Sahara *
963ab9afeSSatoshi Sahara * @package dokuwiki\Ui
1063ab9afeSSatoshi Sahara */
1163ab9afeSSatoshi Saharaabstract class Diff extends Ui
1263ab9afeSSatoshi Sahara{
13edb50e6aSSatoshi Sahara    /* @var string */
14edb50e6aSSatoshi Sahara    protected $id;   // page id or media id
15*e71e09a6SSatoshi Sahara    protected $item; // page or media
16edb50e6aSSatoshi Sahara
17b4b4c5c6SSatoshi Sahara    /* @var int */
18b4b4c5c6SSatoshi Sahara    protected $old_rev;  // older revision, timestamp of left side
19b4b4c5c6SSatoshi Sahara    protected $new_rev;  // newer revision, timestamp of right side
200bb448f0SSatoshi Sahara    protected $last_rev; // current revision, or last revision when it had removed
21b4b4c5c6SSatoshi Sahara
22edb50e6aSSatoshi Sahara    /* @var array */
23edb50e6aSSatoshi Sahara    protected $preference = [];
24edb50e6aSSatoshi Sahara
258068440fSSatoshi Sahara    /* @var ChangeLog */
268068440fSSatoshi Sahara    protected $changelog; // PageChangeLog or MediaChangeLog object
278068440fSSatoshi Sahara
28edb50e6aSSatoshi Sahara    /**
29edb50e6aSSatoshi Sahara     * Diff Ui constructor
30edb50e6aSSatoshi Sahara     *
31edb50e6aSSatoshi Sahara     * @param string $id  page id or media id
32edb50e6aSSatoshi Sahara     */
33edb50e6aSSatoshi Sahara    public function __construct($id)
34edb50e6aSSatoshi Sahara    {
35edb50e6aSSatoshi Sahara        $this->id = $id;
368068440fSSatoshi Sahara        $this->setChangeLog();
37edb50e6aSSatoshi Sahara    }
38edb50e6aSSatoshi Sahara
39edb50e6aSSatoshi Sahara    /**
408068440fSSatoshi Sahara     * set class property changelog
418068440fSSatoshi Sahara     */
428068440fSSatoshi Sahara    abstract protected function setChangeLog();
438068440fSSatoshi Sahara
448068440fSSatoshi Sahara    /**
45b4b4c5c6SSatoshi Sahara     * Set a pair of revisions to be compared
46b4b4c5c6SSatoshi Sahara     *
47b4b4c5c6SSatoshi Sahara     * @param int $old_rev
48b4b4c5c6SSatoshi Sahara     * @param int $new_rev
49b4b4c5c6SSatoshi Sahara     * @return $this
50b4b4c5c6SSatoshi Sahara     */
51b4b4c5c6SSatoshi Sahara    public function compare($old_rev, $new_rev)
52b4b4c5c6SSatoshi Sahara    {
53b4b4c5c6SSatoshi Sahara        $this->old_rev = $old_rev;
54b4b4c5c6SSatoshi Sahara        $this->new_rev = $new_rev;
55b4b4c5c6SSatoshi Sahara        return $this;
56b4b4c5c6SSatoshi Sahara    }
57b4b4c5c6SSatoshi Sahara
58b4b4c5c6SSatoshi Sahara    /**
59edb50e6aSSatoshi Sahara     * Gets or Sets preference of the Ui\Diff object
60edb50e6aSSatoshi Sahara     *
61edb50e6aSSatoshi Sahara     * @param string|array $prefs  a key name or key-value pair(s)
62edb50e6aSSatoshi Sahara     * @param mixed $value         value used when the first args is string
63edb50e6aSSatoshi Sahara     * @return array|$this
64edb50e6aSSatoshi Sahara     */
65edb50e6aSSatoshi Sahara    public function preference($prefs = null, $value = null)
66edb50e6aSSatoshi Sahara    {
67edb50e6aSSatoshi Sahara        // set
68295564cdSSatoshi Sahara        if (is_string($prefs) && isset($value)) {
69295564cdSSatoshi Sahara            $this->preference[$prefs] = $value;
70295564cdSSatoshi Sahara            return $this;
71295564cdSSatoshi Sahara        } elseif (is_array($prefs)) {
72edb50e6aSSatoshi Sahara            foreach ($prefs as $name => $value) {
73edb50e6aSSatoshi Sahara                $this->preference[$name] = $value;
74edb50e6aSSatoshi Sahara            }
75edb50e6aSSatoshi Sahara            return $this;
76edb50e6aSSatoshi Sahara        }
77edb50e6aSSatoshi Sahara        // get
78edb50e6aSSatoshi Sahara        return $this->preference;
79edb50e6aSSatoshi Sahara    }
80edb50e6aSSatoshi Sahara
81b4b4c5c6SSatoshi Sahara    /**
82b4b4c5c6SSatoshi Sahara     * Retrieve requested revision(s) and difftype from Ui\Revisions
83b4b4c5c6SSatoshi Sahara     *
84b4b4c5c6SSatoshi Sahara     * @return void
85b4b4c5c6SSatoshi Sahara     */
86b4b4c5c6SSatoshi Sahara    protected function preProcess()
87b4b4c5c6SSatoshi Sahara    {
88b4b4c5c6SSatoshi Sahara        global $INPUT;
89b4b4c5c6SSatoshi Sahara
90b4b4c5c6SSatoshi Sahara        // difflink icon click, eg. ?rev=123456789&do=diff
91b4b4c5c6SSatoshi Sahara        if ($INPUT->has('rev')) {
92b4b4c5c6SSatoshi Sahara            $this->old_rev = $INPUT->int('rev');
93b4b4c5c6SSatoshi Sahara            $this->new_rev = ''; // current revision
94b4b4c5c6SSatoshi Sahara        }
95b4b4c5c6SSatoshi Sahara
96b4b4c5c6SSatoshi Sahara        // submit button with two checked boxes
97b4b4c5c6SSatoshi Sahara        $rev2 = $INPUT->arr('rev2', []);
98b4b4c5c6SSatoshi Sahara        if (count($rev2) > 1) {
99b4b4c5c6SSatoshi Sahara            if ($rev2[0] == 'current') {
100b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[1], ''];
101b4b4c5c6SSatoshi Sahara            } elseif ($rev2[1] == 'current') {
102b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[0], ''];
103b4b4c5c6SSatoshi Sahara            } elseif ($rev2[0] < $rev2[1]) {
104b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[0], $rev2[1]];
105b4b4c5c6SSatoshi Sahara            } else {
106b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[1], $rev2[0]];
107b4b4c5c6SSatoshi Sahara            }
108b4b4c5c6SSatoshi Sahara        }
109b4b4c5c6SSatoshi Sahara
110b4b4c5c6SSatoshi Sahara        // diff view type
111b4b4c5c6SSatoshi Sahara        if ($INPUT->has('difftype')) {
112b4b4c5c6SSatoshi Sahara            // retrieve requested $difftype
113b4b4c5c6SSatoshi Sahara            $this->preference['difftype'] = $INPUT->str('difftype');
114b4b4c5c6SSatoshi Sahara        } else {
115b4b4c5c6SSatoshi Sahara            // read preference from DokuWiki cookie. PageDiff only
11691e70b5fSSatoshi Sahara            get_doku_pref('difftype', $mode);
11791e70b5fSSatoshi Sahara            if (isset($mode)) $this->preference['difftype'] = $mode;
118b4b4c5c6SSatoshi Sahara        }
119b4b4c5c6SSatoshi Sahara    }
120b4b4c5c6SSatoshi Sahara
121b4b4c5c6SSatoshi Sahara
122edb50e6aSSatoshi Sahara
12363ab9afeSSatoshi Sahara    /**
124ec019cbfSSatoshi Sahara     * Build header of diff HTML
12563ab9afeSSatoshi Sahara     *
12663ab9afeSSatoshi Sahara     * @param string $l_rev   Left revisions
12763ab9afeSSatoshi Sahara     * @param string $r_rev   Right revision
12863ab9afeSSatoshi Sahara     * @return string[] HTML snippets for diff header
12963ab9afeSSatoshi Sahara     */
1308068440fSSatoshi Sahara    public function buildDiffHead($l_rev, $r_rev)
13163ab9afeSSatoshi Sahara    {
13263ab9afeSSatoshi Sahara        global $lang;
133edb50e6aSSatoshi Sahara
134*e71e09a6SSatoshi Sahara        $changelog =& $this->changelog;
135*e71e09a6SSatoshi Sahara
136*e71e09a6SSatoshi Sahara        switch ($this->item) {
137*e71e09a6SSatoshi Sahara            case 'page':
1380bb448f0SSatoshi Sahara                $isMedia = false;
1390bb448f0SSatoshi Sahara                $ui = new PageRevisions($this->id);
140edb50e6aSSatoshi Sahara                break;
141*e71e09a6SSatoshi Sahara            case 'media':
1420bb448f0SSatoshi Sahara                $isMedia = true;
1430bb448f0SSatoshi Sahara                $ui = new MediaRevisions($this->id);
144edb50e6aSSatoshi Sahara                break;
14563ab9afeSSatoshi Sahara        }
146edb50e6aSSatoshi Sahara
147edb50e6aSSatoshi Sahara        $head_separator = ($this->preference['difftype'] === 'inline') ? ' ' : '<br />';
1480bb448f0SSatoshi Sahara
1490bb448f0SSatoshi Sahara        // assign minor edit checker to the variable
150*e71e09a6SSatoshi Sahara        $isMinorEdit = function ($info) {
151*e71e09a6SSatoshi Sahara            return ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT);
1520bb448f0SSatoshi Sahara        };
1530bb448f0SSatoshi Sahara
1540bb448f0SSatoshi Sahara        // assign title builder to the variable
155*e71e09a6SSatoshi Sahara        $itemTitle = function ($id, $rev = '') use ($isMedia) {
1560bb448f0SSatoshi Sahara            return ($isMedia) ? dformat($rev) : $id.' ['.dformat($rev).']';
1570bb448f0SSatoshi Sahara        };
15863ab9afeSSatoshi Sahara
159edb50e6aSSatoshi Sahara        // left side
16063ab9afeSSatoshi Sahara        if (!$l_rev) {
1610bb448f0SSatoshi Sahara            $l_minor = '';
16263ab9afeSSatoshi Sahara            $l_head = '&mdash;';
16363ab9afeSSatoshi Sahara        } else {
164*e71e09a6SSatoshi Sahara            $info = $changelog->getRevisionInfo($l_rev);
1650bb448f0SSatoshi Sahara            $objRevInfo = $ui->getObjRevInfo($info);
166*e71e09a6SSatoshi Sahara            $l_minor = $isMinorEdit($info) ? ' class="minor"' : '';
167*e71e09a6SSatoshi Sahara            $l_head = '<bdi>'
168*e71e09a6SSatoshi Sahara                    .'<a class="wikilink1" href="'.$this->itemUrl($this->id, "rev=$l_rev").'">'
169*e71e09a6SSatoshi Sahara                    .$itemTitle($this->id, $l_rev).'</a></bdi>'.$head_separator
1700bb448f0SSatoshi Sahara                    .$objRevInfo->editor().' '.$objRevInfo->editSummary();
17163ab9afeSSatoshi Sahara        }
17263ab9afeSSatoshi Sahara
173edb50e6aSSatoshi Sahara        // right side
17463ab9afeSSatoshi Sahara        if ($r_rev) {
175*e71e09a6SSatoshi Sahara            $info  = $changelog->getRevisionInfo($r_rev);
1760bb448f0SSatoshi Sahara            $objRevInfo = $ui->getObjRevInfo($info);
177*e71e09a6SSatoshi Sahara            $r_minor = $isMinorEdit($info) ? ' class="minor"' : '';
178*e71e09a6SSatoshi Sahara            $r_head = '<bdi>'
179*e71e09a6SSatoshi Sahara                    .'<a class="wikilink1" href="'.$this->itemUrl($this->id, "rev=$r_rev").'">'
180*e71e09a6SSatoshi Sahara                    .$itemTitle($this->id, $r_rev).'</a></bdi>'.$head_separator
1810bb448f0SSatoshi Sahara                    .$objRevInfo->editor().' '.$objRevInfo->editSummary();
1820bb448f0SSatoshi Sahara        } elseif ($this->last_rev) {
1830bb448f0SSatoshi Sahara            $_rev = $this->last_rev;
184*e71e09a6SSatoshi Sahara            $info = $changelog->getRevisionInfo($_rev);
1850bb448f0SSatoshi Sahara            $objRevInfo = $ui->getObjRevInfo($info);
186*e71e09a6SSatoshi Sahara            $r_minor = $isMinorEdit($info) ? ' class="minor"' : '';
187*e71e09a6SSatoshi Sahara            $r_head  = '<bdi>'
188*e71e09a6SSatoshi Sahara                     .'<a class="wikilink1" href="'.$this->itemUrl($this->id).'">'
189*e71e09a6SSatoshi Sahara                     .$itemTitle($this->id, $_rev).'</a></bdi> '.'('.$lang['current'].')'.$head_separator
1900bb448f0SSatoshi Sahara                     .$objRevInfo->editor().' '.$objRevInfo->editSummary();
19163ab9afeSSatoshi Sahara        } else {
1920bb448f0SSatoshi Sahara            $r_minor = '';
19363ab9afeSSatoshi Sahara            $r_head = '&mdash; ('.$lang['current'].')';
19463ab9afeSSatoshi Sahara        }
19563ab9afeSSatoshi Sahara
19663ab9afeSSatoshi Sahara        return array($l_head, $r_head, $l_minor, $r_minor);
19763ab9afeSSatoshi Sahara    }
19863ab9afeSSatoshi Sahara
199*e71e09a6SSatoshi Sahara    /**
200*e71e09a6SSatoshi Sahara     * item url generator
201*e71e09a6SSatoshi Sahara     *
202*e71e09a6SSatoshi Sahara     * @param string $id  page id or media id
203*e71e09a6SSatoshi Sahara     * @param string|array $urlParameters  URL parameters, associative array recommended
204*e71e09a6SSatoshi Sahara     * @return string
205*e71e09a6SSatoshi Sahara     */
206*e71e09a6SSatoshi Sahara    protected function itemUrl($id, $urlParameters = '')
207*e71e09a6SSatoshi Sahara    {
208*e71e09a6SSatoshi Sahara        switch ($this->item) {
209*e71e09a6SSatoshi Sahara            case 'page':  return wl($id, $urlParameters, $absolute = false, '&');
210*e71e09a6SSatoshi Sahara            case 'media': return ml($id, $urlParameters, $direct = true, '&', $absolute = false);
211*e71e09a6SSatoshi Sahara        }
212*e71e09a6SSatoshi Sahara    }
213*e71e09a6SSatoshi Sahara
21463ab9afeSSatoshi Sahara}
215