aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/inc/Ui/Diff.php
blob: 70c050d6d58a7dae14c08cfd079fc67d8dceb7b7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php

namespace dokuwiki\Ui;

use dokuwiki\ChangeLog\ChangeLog;

/**
 * DokuWiki Diff Interface
 * parent class of PageDiff and MediaDiff
 *
 * @package dokuwiki\Ui
 */
abstract class Diff extends Ui
{
    /* @var string */
    protected $id;   // page id or media id

    /* @var int|false */
    protected $rev1;  // timestamp of older revision
    /* @var int|false */
    protected $rev2;  // timestamp of newer revision

    /* @var array */
    protected $preference = [];

    /* @var ChangeLog */
    protected $changelog; // PageChangeLog or MediaChangeLog object

    /**
     * Diff Ui constructor
     *
     * @param string $id page id or media id
     */
    public function __construct($id)
    {
        $this->id = $id;
        $this->setChangeLog();
    }

    /**
     * set class property changelog
     */
    abstract protected function setChangeLog();

    /**
     * Prepare revision info of comparison pair
     */
    abstract protected function preProcess();

    /**
     * Set a pair of revisions to be compared
     *
     * @param int $rev1 older revision
     * @param int $rev2 newer revision
     * @return $this
     */
    public function compare($rev1, $rev2)
    {
        if ($rev2 < $rev1) [$rev1, $rev2] = [$rev2, $rev1];
        $this->rev1 = (int)$rev1;
        $this->rev2 = (int)$this->changelog->traceCurrentRevision($rev2);
        return $this;
    }

    /**
     * Gets or Sets preference of the Ui\Diff object
     *
     * @param string|array $prefs a key name or key-value pair(s)
     * @param mixed $value value used when the first args is string
     * @return array|$this
     */
    public function preference($prefs = null, $value = null)
    {
        // set
        if (is_string($prefs) && isset($value)) {
            $this->preference[$prefs] = $value;
            return $this;
        } elseif (is_array($prefs)) {
            foreach ($prefs as $name => $value) {
                $this->preference[$name] = $value;
            }
            return $this;
        }
        // get
        return $this->preference;
    }

    /**
     * Handle requested revision(s)
     *
     * @return void
     */
    protected function handle()
    {
        global $INPUT;

        // diff link icon click, eg. &do=diff&rev=#
        if ($INPUT->has('rev')) {
            $this->rev1 = $INPUT->int('rev');
            $this->rev2 = $this->changelog->currentRevision();
            if ($this->rev2 <= $this->rev1) {
                // fallback to compare previous with current
                unset($this->rev1, $this->rev2);
            }
        }

        // submit button with two checked boxes, eg. &do=diff&rev2[0]=#&rev2[1]=#
        $revs = $INPUT->arr('rev2', []);
        if (count($revs) > 1) {
            [$rev1, $rev2] = $revs;
            if ($rev2 < $rev1) [$rev1, $rev2] = [$rev2, $rev1];
            $this->rev1 = (int)$rev1;
            $this->rev2 = (int)$this->changelog->traceCurrentRevision($rev2);
        }

        // no revision was given, compare previous to current
        if (!isset($this->rev1, $this->rev2)) {
            $rev2 = $this->changelog->currentRevision();
            if ($rev2 > $this->changelog->lastRevision()) {
                $rev1 = $this->changelog->lastRevision();
            } else {
                $revs = $this->changelog->getRevisions(0, 1);
                $rev1 = count($revs) ? $revs[0] : false;
            }
            $this->rev1 = $rev1;
            $this->rev2 = $rev2;
        }
    }
}