Failed Conditions
Pull Request — master (#3361)
by
unknown
03:07
created

anonymous//inc/Ui/Revisions.php$0   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 130
rs 10
c 0
b 0
f 0
wmc 29
lcom 1
cbo 0
1
<?php
2
3
namespace dokuwiki\Ui;
4
5
/**
6
 * DokuWiki Revisions Interface
7
 * parent class of PageRevisions and MediaRevisions
8
 *
9
 * @package dokuwiki\Ui
10
 */
11
abstract class Revisions extends Ui
12
{
13
    /* @var string */
14
    protected $id;   // page id or media id
15
    protected $item; // page or media
16
17
    /* @var ChangeLog */
18
    protected $changelog; // PageChangeLog or MediaChangeLog object
19
20
    /** 
21
     * Revisions Ui constructor
22
     *
23
     * @param string $id  page id or media id
24
     */
25
    public function __construct($id)
26
    {
27
        $this->id = $id;
28
        $this->setChangeLog();
29
    }
30
31
    /**
32
     * set class property changelog
33
     */
34
    abstract protected function setChangeLog();
35
36
    /**
37
     * item filename resolver
38
     *
39
     * @param string $id  page id or media id
40
     * @param int|string $rev revision timestamp, or empty string for current one
41
     * @return string full path
42
     */
43
    abstract protected function itemFN($id, $rev = '');
44
45
    /**
46
     * Get revisions, and set correct pagenation parameters (first, hasNext)
47
     *
48
     * @param int  $first
49
     * @param bool $hasNext
50
     * @return array  revisions to be shown in a pagenated list
51
     * @see also https://www.dokuwiki.org/devel:changelog
52
     */
53
    protected function getRevisions(&$first, &$hasNext)
54
    {
55
        global $conf;
56
57
        $changelog =& $this->changelog;
58
59
        $revisions = array();
60
61
        /* we need to get one additional log entry to be able to
62
         * decide if this is the last page or is there another one.
63
         * see also Ui\Recent::getRecents()
64
         */
65
        $revlist = $changelog->getRevisions($first, $conf['recent'] +1);
66
        if (count($revlist) == 0 && $first != 0) {
67
            $first = 0;
68
            $revlist = $changelog->getRevisions($first, $conf['recent'] +1);
69
        }
70
71
        // add current page or media as revision[0] when necessary
72
        if ($first === 0 && file_exists($this->itemFN($this->id))) {
73
            $rev = filemtime(fullpath($this->itemFN($this->id)));
74
            $changelog->setChunkSize(1024); //FIXME why does chunksize change wanted?
75
            $revinfo = $changelog->getRevisionInfo($rev) ?: array(
76
                    'date' => $rev,
77
                    'ip'   => null,
78
                    'type' => null,
79
                    'id'   => $this->id,
80
                    'user' => null,
81
                    'sum'  => null,
82
                    'extra' => null,
83
                    'sizechange' => null,
84
            );
85
            $revisions[] = $revinfo + array(
86
                    'item' => $this->item,
87
                    'current' => true,
88
            );
89
        }
90
91
        // decide if this is the last page or is there another one
92
        $hasNext = false;
93
        if (count($revlist) > $conf['recent']) {
94
            $hasNext = true;
95
            array_pop($revlist); // remove one additional log entry
96
        }
97
98
        // append each revison info array to the revisions
99
        foreach ($revlist as $rev) {
100
            $revisions[] = $changelog->getRevisionInfo($rev) + array('item' => $this->item);
101
        }
102
        return $revisions;
103
    }
104
105
    /**
106
     * Navigation buttons for Pagenation (prev/next)
107
     *
108
     * @param int  $first
109
     * @param bool $hasNext
110
     * @param callable $callback returns array of hidden fields for the form button
111
     * @return array  html
112
     */
113
    protected function navigation($first, $hasNext, $callback)
114
    {
115
        global $conf;
116
117
        $html = '<div class="pagenav">';
118
        $last = $first + $conf['recent'];
119
        if ($first > 0) {
120
            $first = max($first - $conf['recent'], 0);
121
            $html.= '<div class="pagenav-prev">';
122
            $html.= html_btn('newer', $this->id, "p", $callback($first));
123
            $html.= '</div>';
124
        }
125
        if ($hasNext) {
126
            $html.= '<div class="pagenav-next">';
127
            $html.= html_btn('older', $this->id, "n", $callback($last));
128
            $html.= '</div>';
129
        }
130
        $html.= '</div>';
131
        return $html;
132
    }
133
134
    /**
135
     * Returns instance of objRevInfo
136
     *
137
     * @param array $info  Revision info structure of a page or media file
138
     * @return objRevInfo object (anonymous class)
139
     */
140
    public function getObjRevInfo(array $info)
141
    {
142
        return new class ($info) // anonymous class (objRevInfo)
143
        {
144
            protected $info;
145
146
            public function __construct(array $info)
147
            {
148
                $this->info = $info;
149
            }
150
151
            // current indicator
152
            public function currentIndicator()
153
            {
154
                global $lang;
155
                return ($this->info['current']) ? '('.$lang['current'].')' : '';
156
            }
157
158
            // edit date and time of the page or media file
159
            public function editDate()
160
            {
161
                return '<span class="date">'. dformat($this->info['date']) .'</span>';
162
            }
163
164
            // edit summary
165
            public function editSummary()
166
            {
167
                return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>';
168
            }
169
170
            // editor of the page or media file
171
            public function editor()
172
            {
173
                // slightly different with display of Ui\Recent, i.e. external edit
174
                global $lang;
175
                $html = '<span class="user">';
176
                if (!$this->info['user'] && !$this->info['ip']) {
177
                    $html.= '('.$lang['external_edit'].')';
178
                } elseif ($this->info['user']) {
179
                    $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
180
                    if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
181
                } else {
182
                    $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
183
                }
184
                $html.= '</span>';
185
                return $html;
186
            }
187
188
            // name of the page or media file
189
            public function itemName()
190
            {
191
                // slightly different with display of Ui\Recent, i.e. revison may not exists
192
                $id = $this->info['id'];
193
                $rev = $this->info['date'];
194
195
                switch ($this->info['item']) {
196
                    case 'media': // media file revision
197
                        if (isset($this->info['current'])) {
198
                            $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view'], '&');
199
                            $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>';
200
                        } elseif (file_exists(mediaFN($id, $rev))) {
201
                            $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view', 'rev'=> $rev], '&');
202
                            $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>';
203
                        } else {
204
                            $html = $id;
205
                        }
206
                        return $html;
207
                    case 'page': // page revision
208
                        $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
209
                        if (!$display_name) $display_name = $id;
210
                        if ($this->info['current'] || page_exists($id, $rev)) {
211
                            $href = wl($id, "rev=$rev", false, '&');
212
                            $html = '<a href="'.$href.'" class="wikilink1">'.$display_name.'</a>';
213
                        } else {
214
                            $html = $display_name;
215
                        }
216
                        return $html;
217
                }
218
                return '';
219
            }
220
221
            // icon difflink
222
            public function difflink()
223
            {
224
                global $lang;
225
                $id = $this->info['id'];
226
                $rev = $this->info['date'];
227
228
                switch ($this->info['item']) {
229
                    case 'media': // media file revision
230
                        if (isset($this->info['current']) || !file_exists(mediaFN($id, $rev))) {
231
                            $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
232
                        } else {
233
                            $href = media_managerURL(['image'=> $id, 'rev'=> $rev, 'mediado'=>'diff'], '&');
234
                            $html = '<a href="'.$href.'" class="diff_link">'
235
                                  . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
236
                                  . ' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />'
237
                                  . '</a> ';
238
                        }
239
                        return $html;
240
                    case 'page': // page revision
241
                        if ($this->info['current'] || !page_exists($id, $rev)) {
242
                            $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
243
                        } else {
244
                            $href = wl($id, "rev=$rev,do=diff", false, '&');
245
                            $html = '<a href="'.$href.'" class="diff_link">'
246
                                  . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
247
                                  . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
248
                                  . '</a>';
249
                        }
250
                        return $html;
251
                }
252
                return '';
253
            }
254
255
            // size change
256
            public function sizeChange()
257
            {
258
                $class = 'sizechange';
259
                $value = filesize_h(abs($this->info['sizechange']));
260
                if ($this->info['sizechange'] > 0) {
261
                    $class .= ' positive';
262
                    $value = '+' . $value;
263
                } elseif ($this->info['sizechange'] < 0) {
264
                    $class .= ' negative';
265
                    $value = '-' . $value;
266
                } else {
267
                    $value = '±' . $value;
268
                }
269
                return '<span class="'.$class.'">'.$value.'</span>';
270
            }
271
        }; // end of anonymous class (objRevInfo)
272
    }
273
274
}
275