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

Revisions   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 267
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 33
dl 0
loc 267
rs 9.76
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
setChangeLog() 0 1 ?
itemFN() 0 1 ?
B getRevisions() 0 51 8
A navigation() 0 20 3
A hp$0 ➔ __construct() 0 7 2
A hp$0 ➔ currentIndicator() 0 5 2
A hp$0 ➔ editDate() 0 4 1
A hp$0 ➔ editSummary() 0 4 1
A hp$0 ➔ editor() 0 16 5
B hp$0 ➔ itemName() 0 31 9
B hp$0 ➔ difflink() 0 32 7
A hp$0 ➔ sizeChange() 0 15 3
B getObjRevInfo() 0 136 3
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
                if (!isset($info['current'])) {
149
                    $info['current'] = false;
150
                }
151
                $this->info = $info;
152
            }
153
154
            // current indicator
155
            public function currentIndicator()
156
            {
157
                global $lang;
158
                return ($this->info['current']) ? '('.$lang['current'].')' : '';
159
            }
160
161
            // edit date and time of the page or media file
162
            public function editDate()
163
            {
164
                return '<span class="date">'. dformat($this->info['date']) .'</span>';
165
            }
166
167
            // edit summary
168
            public function editSummary()
169
            {
170
                return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>';
171
            }
172
173
            // editor of the page or media file
174
            public function editor()
175
            {
176
                // slightly different with display of Ui\Recent, i.e. external edit
177
                global $lang;
178
                $html = '<span class="user">';
179
                if (!$this->info['user'] && !$this->info['ip']) {
180
                    $html.= '('.$lang['external_edit'].')';
181
                } elseif ($this->info['user']) {
182
                    $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
183
                    if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
184
                } else {
185
                    $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
186
                }
187
                $html.= '</span>';
188
                return $html;
189
            }
190
191
            // name of the page or media file
192
            public function itemName()
193
            {
194
                // slightly different with display of Ui\Recent, i.e. revison may not exists
195
                $id = $this->info['id'];
196
                $rev = $this->info['date'];
197
198
                switch ($this->info['item']) {
199
                    case 'media': // media file revision
200
                        if (isset($this->info['current'])) {
201
                            $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view'], '&');
202
                            $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>';
203
                        } elseif (file_exists(mediaFN($id, $rev))) {
204
                            $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view', 'rev'=> $rev], '&');
205
                            $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>';
206
                        } else {
207
                            $html = $id;
208
                        }
209
                        return $html;
210
                    case 'page': // page revision
211
                        $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
212
                        if (!$display_name) $display_name = $id;
213
                        if ($this->info['current'] || page_exists($id, $rev)) {
214
                            $href = wl($id, "rev=$rev", false, '&');
215
                            $html = '<a href="'.$href.'" class="wikilink1">'.$display_name.'</a>';
216
                        } else {
217
                            $html = $display_name;
218
                        }
219
                        return $html;
220
                }
221
                return '';
222
            }
223
224
            // icon difflink
225
            public function difflink()
226
            {
227
                global $lang;
228
                $id = $this->info['id'];
229
                $rev = $this->info['date'];
230
231
                switch ($this->info['item']) {
232
                    case 'media': // media file revision
233
                        if (isset($this->info['current']) || !file_exists(mediaFN($id, $rev))) {
234
                            $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
235
                        } else {
236
                            $href = media_managerURL(['image'=> $id, 'rev'=> $rev, 'mediado'=>'diff'], '&');
237
                            $html = '<a href="'.$href.'" class="diff_link">'
238
                                  . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
239
                                  . ' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />'
240
                                  . '</a> ';
241
                        }
242
                        return $html;
243
                    case 'page': // page revision
244
                        if ($this->info['current'] || !page_exists($id, $rev)) {
245
                            $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
246
                        } else {
247
                            $href = wl($id, "rev=$rev,do=diff", false, '&');
248
                            $html = '<a href="'.$href.'" class="diff_link">'
249
                                  . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
250
                                  . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
251
                                  . '</a>';
252
                        }
253
                        return $html;
254
                }
255
                return '';
256
            }
257
258
            // size change
259
            public function sizeChange()
260
            {
261
                $class = 'sizechange';
262
                $value = filesize_h(abs($this->info['sizechange']));
263
                if ($this->info['sizechange'] > 0) {
264
                    $class .= ' positive';
265
                    $value = '+' . $value;
266
                } elseif ($this->info['sizechange'] < 0) {
267
                    $class .= ' negative';
268
                    $value = '-' . $value;
269
                } else {
270
                    $value = '±' . $value;
271
                }
272
                return '<span class="'.$class.'">'.$value.'</span>';
273
            }
274
        }; // end of anonymous class (objRevInfo)
275
    }
276
277
}
278