3 namespace dokuwiki\ChangeLog
;
8 * Provides methods to show Revision Information in DokuWiki Ui components:
21 * @param array $info Revision Information structure with entries:
22 * - date: unix timestamp
23 * - ip: IPv4 or IPv6 address
24 * - type: change type (log line type)
27 * - sum: edit summary (or action reason)
28 * - extra: extra data (varies by line type)
29 * - sizechange: change of filesize
31 * - current: (optional) whether current revision or not
32 * - timestamp: (optional) set only when external edits occurred
33 * - mode: (internal use) ether "media" or "page"
35 public function __construct($info = null)
37 if (is_array($info) && isset($info['id'])) {
38 // define strategy context
39 $info['mode'] = $info['media'] ?
'media' : 'page';
50 * Set or return whether this revision is current page or media file
52 * This method does not check exactly whether the revision is current or not. Instead,
53 * set value of associated "current" key for internal use. Some UI element like diff
54 * link button depend on relation to current page or media file. A changelog line does
55 * not indicate whether it corresponds to current page or media file.
57 * @param bool $value true if the revision is current, otherwise false
60 public function isCurrent($value = null)
62 return (bool) $this->val('current', $value);
66 * Return or set a value of associated key of revision information
67 * but does not allow to change values of existing keys
73 public function val($key, $value = null)
75 if (isset($value) && !array_key_exists($key, $this->info
)) {
76 // setter, only for new keys
77 $this->info
[$key] = $value;
79 if (array_key_exists($key, $this->info
)) {
81 return $this->info
[$key];
87 * Set extra key-value to the revision information
88 * but does not allow to change values of existing keys
92 public function append(array $info)
94 foreach ($info as $key => $value) {
95 $this->val($key, $value);
101 * file icon of the page or media file
102 * used in [Ui\recent]
106 public function showFileIcon()
108 $id = $this->val('id');
109 if ($this->val('mode') == 'media') {
110 // media file revision
111 return media_printicon($id);
112 } elseif ($this->val('mode') == 'page') {
114 return '<img class="icon" src="'.DOKU_BASE
.'lib/images/fileicons/file.png" alt="'.$id.'" />';
119 * edit date and time of the page or media file
120 * used in [Ui\recent, Ui\Revisions]
122 * @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false
125 public function showEditDate($checkTimestamp = false)
127 $formatted = dformat($this->val('date'));
128 if ($checkTimestamp && $this->val('timestamp') === false) {
129 // exact date is unknown for externally deleted file
130 // when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__"
131 $formatted = preg_replace('/[0-9a-zA-Z]/', '_', $formatted);
133 return '<span class="date">'. $formatted .'</span>';
138 * used in [Ui\recent, Ui\Revisions]
142 public function showEditSummary()
144 return '<span class="sum">'.' – '. hsc($this->val('sum')).'</span>';
148 * editor of the page or media file
149 * used in [Ui\recent, Ui\Revisions]
153 public function showEditor()
155 if ($this->val('user')) {
156 $html = '<bdi>'. editorinfo($this->val('user')) .'</bdi>';
157 if (auth_ismanager()) $html .= ' <bdo dir="ltr">('. $this->val('ip') .')</bdo>';
159 $html = '<bdo dir="ltr">'. $this->val('ip') .'</bdo>';
161 return '<span class="user">'. $html. '</span>';
165 * name of the page or media file
166 * used in [Ui\recent, Ui\Revisions]
170 public function showFileName()
172 $id = $this->val('id');
173 $rev = $this->isCurrent() ?
'' : $this->val('date');
175 if ($this->val('mode') == 'media') {
176 // media file revision
177 $params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id];
178 if ($rev) $params +
= ['rev'=> $rev];
179 $href = media_managerURL($params, '&');
181 $exists = file_exists(mediaFN($id, $rev));
182 } elseif ($this->val('mode') == 'page') {
184 $params = $rev ?
['rev'=> $rev] : [];
185 $href = wl($id, $params, false, '&');
186 $display_name = useHeading('navigation') ?
hsc(p_get_first_heading($id)) : $id;
187 if (!$display_name) $display_name = $id;
188 $exists = page_exists($id, $rev);
192 $class = 'wikilink1';
193 } elseif ($this->isCurrent()) {
194 //show only not-existing link for current page, which allows for directly create a new page/upload
195 $class = 'wikilink2';
197 //revision is not in attic
198 return $display_name;
200 if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE
) {
201 $class = 'wikilink2';
203 return '<a href="'.$href.'" class="'.$class.'">'.$display_name.'</a>';
207 * Revision Title for PageDiff table headline
211 public function showRevisionTitle()
215 if (!$this->val('date')) return '—';
217 $id = $this->val('id');
218 $rev = $this->isCurrent() ?
'' : $this->val('date');
219 $params = ($rev) ?
['rev'=> $rev] : [];
221 // revision info may have timestamp key when external edits occurred
222 $date = ($this->val('timestamp') === false)
223 ?
$lang['unknowndate']
224 : dformat($this->val('date'));
227 if ($this->val('mode') == 'media') {
228 // media file revision
229 $href = ml($id, $params, false, '&');
230 $exists = file_exists(mediaFN($id, $rev));
231 } elseif ($this->val('mode') == 'page') {
233 $href = wl($id, $params, false, '&');
234 $exists = page_exists($id, $rev);
237 $class = 'wikilink1';
238 } elseif ($this->isCurrent()) {
239 //show only not-existing link for current page, which allows for directly create a new page/upload
240 $class = 'wikilink2';
242 //revision is not in attic
243 return $id.' ['.$date.']';
245 if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE
) {
246 $class = 'wikilink2';
248 return '<bdi><a class="'.$class.'" href="'.$href.'">'.$id.' ['.$date.']'.'</a></bdi>';
252 * diff link icon in recent changes list, to compare (this) current revision with previous one
253 * all items in "recent changes" are current revision of the page or media
257 public function showIconCompareWithPrevious()
260 $id = $this->val('id');
263 if ($this->val('mode') == 'media') {
264 // media file revision
265 // unlike page, media file does not copied to media_attic when uploaded.
266 // diff icon will not be shown when external edit occurred
267 // because no attic file to be compared with current.
268 $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
269 $showLink = (count($revs) && file_exists(mediaFN($id, $revs[0])) && file_exists(mediaFN($id)));
271 $param = ['tab_details'=>'history', 'mediado'=>'diff', 'ns'=> getNS($id), 'image'=> $id];
272 $href = media_managerURL($param, '&');
274 } elseif ($this->val('mode') == 'page') {
276 // when a page just created anyway, it is natural to expect no older revisions
277 // even if it had once existed but deleted before. Simply ignore to check changelog.
278 if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE
) {
279 $href = wl($id, ['do'=>'diff'], false, '&');
284 return '<a href="'.$href.'" class="diff_link">'
285 .'<img src="'.DOKU_BASE
.'lib/images/diff.png" width="15" height="11"'
286 .' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />'
289 return '<img src="'.DOKU_BASE
.'lib/images/blank.gif" width="15" height="11" alt="" />';
294 * diff link icon in revisions list, compare this revision with current one
295 * the icon does not displayed for the current revision
299 public function showIconCompareWithCurrent()
302 $id = $this->val('id');
303 $rev = $this->isCurrent() ?
'' : $this->val('date');
306 if ($this->val('mode') == 'media') {
307 // media file revision
308 if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) {
309 $param = ['mediado'=>'diff', 'image'=> $id, 'rev'=> $rev];
310 $href = media_managerURL($param, '&');
312 } elseif ($this->val('mode') == 'page') {
314 if (!$this->isCurrent()) {
315 $href = wl($id, ['rev'=> $rev, 'do'=>'diff'], false, '&');
320 return '<a href="'.$href.'" class="diff_link">'
321 .'<img src="'.DOKU_BASE
.'lib/images/diff.png" width="15" height="11"'
322 .' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />'
325 return '<img src="'.DOKU_BASE
.'lib/images/blank.gif" width="15" height="11" alt="" />';
330 * icon for revision action
331 * used in [Ui\recent]
335 public function showIconRevisions()
339 if (!actionOK('revisions')) {
343 $id = $this->val('id');
344 if ($this->val('mode') == 'media') {
345 // media file revision
346 $param = ['tab_details'=>'history', 'ns'=> getNS($id), 'image'=> $id];
347 $href = media_managerURL($param, '&');
348 } elseif ($this->val('mode') == 'page') {
350 $href = wl($id, ['do'=>'revisions'], false, '&');
352 return '<a href="'.$href.'" class="revisions_link">'
353 . '<img src="'.DOKU_BASE
.'lib/images/history.png" width="12" height="14"'
354 . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
360 * used in [Ui\recent, Ui\Revisions]
364 public function showSizeChange()
366 $class = 'sizechange';
367 $value = filesize_h(abs($this->val('sizechange')));
368 if ($this->val('sizechange') > 0) {
369 $class .= ' positive';
370 $value = '+' . $value;
371 } elseif ($this->val('sizechange') < 0) {
372 $class .= ' negative';
373 $value = '-' . $value;
375 $value = '±' . $value;
377 return '<span class="'.$class.'">'.$value.'</span>';
381 * current indicator, used in revision list
382 * not used in Ui\Recent because recent files are always current one
386 public function showCurrentIndicator()
389 return $this->isCurrent() ?
'('.$lang['current'].')' : '';