xref: /dokuwiki/inc/Ui/Diff.php (revision 295564cdcae151b907a029a6535147f59c9e5ae1)
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
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    /**
46b4b4c5c6SSatoshi Sahara     * Set a pair of revisions to be compared
47b4b4c5c6SSatoshi Sahara     *
48b4b4c5c6SSatoshi Sahara     * @param int $old_rev
49b4b4c5c6SSatoshi Sahara     * @param int $new_rev
50b4b4c5c6SSatoshi Sahara     * @return $this
51b4b4c5c6SSatoshi Sahara     */
52b4b4c5c6SSatoshi Sahara    public function compare($old_rev, $new_rev)
53b4b4c5c6SSatoshi Sahara    {
54b4b4c5c6SSatoshi Sahara        $this->old_rev = $old_rev;
55b4b4c5c6SSatoshi Sahara        $this->new_rev = $new_rev;
56b4b4c5c6SSatoshi Sahara        return $this;
57b4b4c5c6SSatoshi Sahara    }
58b4b4c5c6SSatoshi Sahara
59b4b4c5c6SSatoshi Sahara    /**
60edb50e6aSSatoshi Sahara     * Gets or Sets preference of the Ui\Diff object
61edb50e6aSSatoshi Sahara     *
62edb50e6aSSatoshi Sahara     * @param string|array $prefs  a key name or key-value pair(s)
63edb50e6aSSatoshi Sahara     * @param mixed $value         value used when the first args is string
64edb50e6aSSatoshi Sahara     * @return array|$this
65edb50e6aSSatoshi Sahara     */
66edb50e6aSSatoshi Sahara    public function preference($prefs = null, $value = null)
67edb50e6aSSatoshi Sahara    {
68edb50e6aSSatoshi Sahara        // set
69*295564cdSSatoshi Sahara        if (is_string($prefs) && isset($value)) {
70*295564cdSSatoshi Sahara            $this->preference[$prefs] = $value;
71*295564cdSSatoshi Sahara            return $this;
72*295564cdSSatoshi Sahara        } elseif (is_array($prefs)) {
73edb50e6aSSatoshi Sahara            foreach ($prefs as $name => $value) {
74edb50e6aSSatoshi Sahara                $this->preference[$name] = $value;
75edb50e6aSSatoshi Sahara            }
76edb50e6aSSatoshi Sahara            return $this;
77edb50e6aSSatoshi Sahara        }
78edb50e6aSSatoshi Sahara        // get
79edb50e6aSSatoshi Sahara        return $this->preference;
80edb50e6aSSatoshi Sahara    }
81edb50e6aSSatoshi Sahara
82b4b4c5c6SSatoshi Sahara    /**
83b4b4c5c6SSatoshi Sahara     * Retrieve requested revision(s) and difftype from Ui\Revisions
84b4b4c5c6SSatoshi Sahara     *
85b4b4c5c6SSatoshi Sahara     * @return void
86b4b4c5c6SSatoshi Sahara     */
87b4b4c5c6SSatoshi Sahara    protected function preProcess()
88b4b4c5c6SSatoshi Sahara    {
89b4b4c5c6SSatoshi Sahara        global $INPUT;
90b4b4c5c6SSatoshi Sahara
91b4b4c5c6SSatoshi Sahara        // difflink icon click, eg. ?rev=123456789&do=diff
92b4b4c5c6SSatoshi Sahara        if ($INPUT->has('rev')) {
93b4b4c5c6SSatoshi Sahara            $this->old_rev = $INPUT->int('rev');
94b4b4c5c6SSatoshi Sahara            $this->new_rev = ''; // current revision
95b4b4c5c6SSatoshi Sahara        }
96b4b4c5c6SSatoshi Sahara
97b4b4c5c6SSatoshi Sahara        // submit button with two checked boxes
98b4b4c5c6SSatoshi Sahara        $rev2 = $INPUT->arr('rev2', []);
99b4b4c5c6SSatoshi Sahara        if (count($rev2) > 1) {
100b4b4c5c6SSatoshi Sahara            if ($rev2[0] == 'current') {
101b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[1], ''];
102b4b4c5c6SSatoshi Sahara            } elseif ($rev2[1] == 'current') {
103b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[0], ''];
104b4b4c5c6SSatoshi Sahara            } elseif ($rev2[0] < $rev2[1]) {
105b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[0], $rev2[1]];
106b4b4c5c6SSatoshi Sahara            } else {
107b4b4c5c6SSatoshi Sahara                [$this->old_rev, $this->new_rev] = [$rev2[1], $rev2[0]];
108b4b4c5c6SSatoshi Sahara            }
109b4b4c5c6SSatoshi Sahara        }
110b4b4c5c6SSatoshi Sahara
111b4b4c5c6SSatoshi Sahara        // diff view type
112b4b4c5c6SSatoshi Sahara        if ($INPUT->has('difftype')) {
113b4b4c5c6SSatoshi Sahara            // retrieve requested $difftype
114b4b4c5c6SSatoshi Sahara            $this->preference['difftype'] = $INPUT->str('difftype');
115b4b4c5c6SSatoshi Sahara        } else {
116b4b4c5c6SSatoshi Sahara            // read preference from DokuWiki cookie. PageDiff only
11791e70b5fSSatoshi Sahara            get_doku_pref('difftype', $mode);
11891e70b5fSSatoshi Sahara            if (isset($mode)) $this->preference['difftype'] = $mode;
119b4b4c5c6SSatoshi Sahara        }
120b4b4c5c6SSatoshi Sahara    }
121b4b4c5c6SSatoshi Sahara
122b4b4c5c6SSatoshi Sahara
123edb50e6aSSatoshi Sahara
12463ab9afeSSatoshi Sahara    /**
125ec019cbfSSatoshi Sahara     * Build header of diff HTML
12663ab9afeSSatoshi Sahara     *
12763ab9afeSSatoshi Sahara     * @param string $l_rev   Left revisions
12863ab9afeSSatoshi Sahara     * @param string $r_rev   Right revision
12963ab9afeSSatoshi Sahara     * @return string[] HTML snippets for diff header
13063ab9afeSSatoshi Sahara     */
1318068440fSSatoshi Sahara    public function buildDiffHead($l_rev, $r_rev)
13263ab9afeSSatoshi Sahara    {
13363ab9afeSSatoshi Sahara        global $lang;
134edb50e6aSSatoshi Sahara
135edb50e6aSSatoshi Sahara        // detect PageDiff or MediaDiff
1368068440fSSatoshi Sahara        switch (get_class($this->changelog)) {
137edb50e6aSSatoshi Sahara            case PageChangeLog::class :
138edb50e6aSSatoshi Sahara                $media_or_wikiFN = 'wikiFN';
139edb50e6aSSatoshi Sahara                $ml_or_wl = 'wl';
140edb50e6aSSatoshi Sahara                $media = false;
141edb50e6aSSatoshi Sahara                break;
142edb50e6aSSatoshi Sahara            case MediaChangeLog::class :
143edb50e6aSSatoshi Sahara                $media_or_wikiFN = 'mediaFN';
144edb50e6aSSatoshi Sahara                $ml_or_wl = 'ml';
145edb50e6aSSatoshi Sahara                $media = true;
146edb50e6aSSatoshi Sahara                break;
14763ab9afeSSatoshi Sahara        }
148edb50e6aSSatoshi Sahara
149edb50e6aSSatoshi Sahara        $head_separator = ($this->preference['difftype'] === 'inline') ? ' ' : '<br />';
15063ab9afeSSatoshi Sahara        $l_minor = $r_minor = '';
15163ab9afeSSatoshi Sahara
152edb50e6aSSatoshi Sahara        // left side
15363ab9afeSSatoshi Sahara        if (!$l_rev) {
15463ab9afeSSatoshi Sahara            $l_head = '&mdash;';
15563ab9afeSSatoshi Sahara        } else {
1568068440fSSatoshi Sahara            $l_info = $this->changelog->getRevisionInfo($l_rev);
15763ab9afeSSatoshi Sahara            if ($l_info['user']) {
15863ab9afeSSatoshi Sahara                $l_user = '<bdi>'.editorinfo($l_info['user']).'</bdi>';
15963ab9afeSSatoshi Sahara                if (auth_ismanager()) $l_user .= ' <bdo dir="ltr">('.$l_info['ip'].')</bdo>';
16063ab9afeSSatoshi Sahara            } else {
16163ab9afeSSatoshi Sahara                $l_user = '<bdo dir="ltr">'.$l_info['ip'].'</bdo>';
16263ab9afeSSatoshi Sahara            }
16363ab9afeSSatoshi Sahara            $l_user = '<span class="user">'.$l_user.'</span>';
16463ab9afeSSatoshi Sahara            $l_sum  = ($l_info['sum']) ? '<span class="sum"><bdi>'.hsc($l_info['sum']).'</bdi></span>' : '';
16563ab9afeSSatoshi Sahara            if ($l_info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) $l_minor = 'class="minor"';
16663ab9afeSSatoshi Sahara
167edb50e6aSSatoshi Sahara            $l_head_title = ($media) ? dformat($l_rev) : $this->id.' ['.dformat($l_rev).']';
168edb50e6aSSatoshi Sahara            $l_head = '<bdi><a class="wikilink1" href="'.$ml_or_wl($this->id,"rev=$l_rev").'">'
16963ab9afeSSatoshi Sahara                . $l_head_title.'</a></bdi>'.$head_separator.$l_user.' '.$l_sum;
17063ab9afeSSatoshi Sahara        }
17163ab9afeSSatoshi Sahara
172edb50e6aSSatoshi Sahara        // right side
17363ab9afeSSatoshi Sahara        if ($r_rev) {
1748068440fSSatoshi Sahara            $r_info  = $this->changelog->getRevisionInfo($r_rev);
17563ab9afeSSatoshi Sahara            if ($r_info['user']) {
17663ab9afeSSatoshi Sahara                $r_user = '<bdi>'.editorinfo($r_info['user']).'</bdi>';
17763ab9afeSSatoshi Sahara                if (auth_ismanager()) $r_user .= ' <bdo dir="ltr">('.$r_info['ip'].')</bdo>';
17863ab9afeSSatoshi Sahara            } else {
17963ab9afeSSatoshi Sahara                $r_user = '<bdo dir="ltr">'.$r_info['ip'].'</bdo>';
18063ab9afeSSatoshi Sahara            }
18163ab9afeSSatoshi Sahara            $r_user = '<span class="user">'.$r_user.'</span>';
18263ab9afeSSatoshi Sahara            $r_sum  = ($r_info['sum']) ? '<span class="sum"><bdi>'.hsc($r_info['sum']).'</bdi></span>' : '';
18363ab9afeSSatoshi Sahara            if ($r_info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) $r_minor = 'class="minor"';
18463ab9afeSSatoshi Sahara
185edb50e6aSSatoshi Sahara            $r_head_title = ($media) ? dformat($r_rev) : $this->id.' ['.dformat($r_rev).']';
186edb50e6aSSatoshi Sahara            $r_head = '<bdi><a class="wikilink1" href="'.$ml_or_wl($this->id,"rev=$r_rev").'">'
18763ab9afeSSatoshi Sahara                . $r_head_title.'</a></bdi>'.$head_separator.$r_user.' '.$r_sum;
188edb50e6aSSatoshi Sahara        } elseif ($_rev = @filemtime($media_or_wikiFN($this->id))) {
1898068440fSSatoshi Sahara            $_info = $this->changelog->getRevisionInfo($_rev);
19063ab9afeSSatoshi Sahara            if ($_info['user']) {
19163ab9afeSSatoshi Sahara                $_user = '<bdi>'.editorinfo($_info['user']).'</bdi>';
19263ab9afeSSatoshi Sahara                if (auth_ismanager()) $_user .= ' <bdo dir="ltr">('.$_info['ip'].')</bdo>';
19363ab9afeSSatoshi Sahara            } else {
19463ab9afeSSatoshi Sahara                $_user = '<bdo dir="ltr">'.$_info['ip'].'</bdo>';
19563ab9afeSSatoshi Sahara            }
19663ab9afeSSatoshi Sahara            $_user = '<span class="user">'.$_user.'</span>';
19763ab9afeSSatoshi Sahara            $_sum  = ($_info['sum']) ? '<span class="sum"><bdi>'.hsc($_info['sum']).'</span></bdi>' : '';
19863ab9afeSSatoshi Sahara            if ($_info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) $r_minor = 'class="minor"';
19963ab9afeSSatoshi Sahara
200edb50e6aSSatoshi Sahara            $r_head_title = ($media) ? dformat($_rev) : $this->id.' ['.dformat($_rev).']';
201edb50e6aSSatoshi Sahara            $r_head  = '<bdi><a class="wikilink1" href="'.$ml_or_wl($this->id).'">'
20263ab9afeSSatoshi Sahara                . $r_head_title.'</a></bdi> '.'('.$lang['current'].')'.$head_separator.$_user.' '.$_sum;
20363ab9afeSSatoshi Sahara        }else{
20463ab9afeSSatoshi Sahara            $r_head = '&mdash; ('.$lang['current'].')';
20563ab9afeSSatoshi Sahara        }
20663ab9afeSSatoshi Sahara
20763ab9afeSSatoshi Sahara        return array($l_head, $r_head, $l_minor, $r_minor);
20863ab9afeSSatoshi Sahara    }
20963ab9afeSSatoshi Sahara
21063ab9afeSSatoshi Sahara}
211