3 namespace dokuwiki\ChangeLog
;
8 * Provides methods to show Revision Information in DokuWiki Ui components:
17 public const MODE_PAGE
= 'page';
18 public const MODE_MEDIA
= 'media';
26 * @param array $info Revision Information structure with entries:
27 * - date: unix timestamp
28 * - ip: IPv4 or IPv6 address
29 * - type: change type (log line type)
32 * - sum: edit summary (or action reason)
33 * - extra: extra data (varies by line type)
34 * - sizechange: change of filesize
36 * - current: (optional) whether current revision or not
37 * - timestamp: (optional) set only when external edits occurred
38 * - mode: (internal use) ether "media" or "page"
40 public function __construct($info = null)
42 if (!is_array($info) ||
!isset($info['id'])) {
44 'mode' => self
::MODE_PAGE
,
52 * Set or return whether this revision is current page or media file
54 * This method does not check exactly whether the revision is current or not. Instead,
55 * set value of associated "current" key for internal use. Some UI element like diff
56 * link button depend on relation to current page or media file. A changelog line does
57 * not indicate whether it corresponds to current page or media file.
59 * @param bool $value true if the revision is current, otherwise false
62 public function isCurrent($value = null)
64 return (bool) $this->val('current', $value);
68 * Return or set a value of associated key of revision information
69 * but does not allow to change values of existing keys
75 public function val($key, $value = null)
77 if (isset($value) && !array_key_exists($key, $this->info
)) {
78 // setter, only for new keys
79 $this->info
[$key] = $value;
81 if (array_key_exists($key, $this->info
)) {
83 return $this->info
[$key];
89 * Set extra key-value to the revision information
90 * but does not allow to change values of existing keys
94 public function append(array $info)
96 foreach ($info as $key => $value) {
97 $this->val($key, $value);
103 * file icon of the page or media file
104 * used in [Ui\recent]
108 public function showFileIcon()
110 $id = $this->val('id');
111 if ($this->val('mode') == self
::MODE_MEDIA
) {
112 // media file revision
113 return media_printicon($id);
114 } elseif ($this->val('mode') == self
::MODE_PAGE
) {
116 return '<img class="icon" src="' . DOKU_BASE
. 'lib/images/fileicons/file.png" alt="' . $id . '" />';
121 * edit date and time of the page or media file
122 * used in [Ui\recent, Ui\Revisions]
124 * @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false
127 public function showEditDate($checkTimestamp = false)
129 $formatted = dformat($this->val('date'));
130 if ($checkTimestamp && $this->val('timestamp') === false) {
131 // exact date is unknown for externally deleted file
132 // when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__"
133 $formatted = preg_replace('/[0-9a-zA-Z]/', '_', $formatted);
135 return '<span class="date">' . $formatted . '</span>';
140 * used in [Ui\recent, Ui\Revisions]
144 public function showEditSummary()
146 return '<span class="sum">' . ' – ' . hsc($this->val('sum')) . '</span>';
150 * editor of the page or media file
151 * used in [Ui\recent, Ui\Revisions]
155 public function showEditor()
157 if ($this->val('user')) {
158 $html = '<bdi>' . editorinfo($this->val('user')) . '</bdi>';
159 if (auth_ismanager()) {
160 $html .= ' <bdo dir="ltr">(' . $this->val('ip') . ')</bdo>';
163 $html = '<bdo dir="ltr">' . $this->val('ip') . '</bdo>';
165 return '<span class="user">' . $html . '</span>';
169 * name of the page or media file
170 * used in [Ui\recent, Ui\Revisions]
174 public function showFileName()
176 $id = $this->val('id');
177 $rev = $this->isCurrent() ?
'' : $this->val('date');
179 if ($this->val('mode') == self
::MODE_MEDIA
) {
180 // media file revision
181 $params = ['tab_details' => 'view', 'ns' => getNS($id), 'image' => $id];
182 if ($rev) $params +
= ['rev' => $rev];
183 $href = media_managerURL($params, '&');
185 $exists = file_exists(mediaFN($id, $rev));
186 } elseif ($this->val('mode') == self
::MODE_PAGE
) {
188 $params = $rev ?
['rev' => $rev] : [];
189 $href = wl($id, $params, false, '&');
190 $display_name = useHeading('navigation') ?
hsc(p_get_first_heading($id)) : $id;
191 if (!$display_name) $display_name = $id;
192 $exists = page_exists($id, $rev);
196 $class = 'wikilink1';
197 } elseif ($this->isCurrent()) {
198 //show only not-existing link for current page, which allows for directly create a new page/upload
199 $class = 'wikilink2';
201 //revision is not in attic
202 return $display_name;
204 if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE
) {
205 $class = 'wikilink2';
207 return '<a href="' . $href . '" class="' . $class . '">' . $display_name . '</a>';
211 * Revision Title for PageDiff table headline
215 public function showRevisionTitle()
219 if (!$this->val('date')) return '—';
221 $id = $this->val('id');
222 $rev = $this->isCurrent() ?
'' : $this->val('date');
223 $params = ($rev) ?
['rev' => $rev] : [];
225 // revision info may have timestamp key when external edits occurred
226 $date = ($this->val('timestamp') === false)
227 ?
$lang['unknowndate']
228 : dformat($this->val('date'));
231 if ($this->val('mode') == self
::MODE_MEDIA
) {
232 // media file revision
233 $href = ml($id, $params, false, '&');
234 $exists = file_exists(mediaFN($id, $rev));
235 } elseif ($this->val('mode') == self
::MODE_PAGE
) {
237 $href = wl($id, $params, false, '&');
238 $exists = page_exists($id, $rev);
241 $class = 'wikilink1';
242 } elseif ($this->isCurrent()) {
243 //show only not-existing link for current page, which allows for directly create a new page/upload
244 $class = 'wikilink2';
246 //revision is not in attic
247 return $id . ' [' . $date . ']';
249 if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE
) {
250 $class = 'wikilink2';
252 return '<bdi><a class="' . $class . '" href="' . $href . '">' . $id . ' [' . $date . ']' . '</a></bdi>';
256 * diff link icon in recent changes list, to compare (this) current revision with previous one
257 * all items in "recent changes" are current revision of the page or media
261 public function showIconCompareWithPrevious()
264 $id = $this->val('id');
267 if ($this->val('mode') == self
::MODE_MEDIA
) {
268 // media file revision
269 // unlike page, media file does not copied to media_attic when uploaded.
270 // diff icon will not be shown when external edit occurred
271 // because no attic file to be compared with current.
272 $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
273 $showLink = (count($revs) && file_exists(mediaFN($id, $revs[0])) && file_exists(mediaFN($id)));
275 $param = ['tab_details' => 'history', 'mediado' => 'diff', 'ns' => getNS($id), 'image' => $id];
276 $href = media_managerURL($param, '&');
278 } elseif ($this->val('mode') == self
::MODE_PAGE
) {
280 // when a page just created anyway, it is natural to expect no older revisions
281 // even if it had once existed but deleted before. Simply ignore to check changelog.
282 if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE
) {
283 $href = wl($id, ['do' => 'diff'], false, '&');
288 return '<a href="' . $href . '" class="diff_link">'
289 . '<img src="' . DOKU_BASE
. 'lib/images/diff.png" width="15" height="11"'
290 . ' title="' . $lang['diff'] . '" alt="' . $lang['diff'] . '" />'
293 return '<img src="' . DOKU_BASE
. 'lib/images/blank.gif" width="15" height="11" alt="" />';
298 * diff link icon in revisions list, compare this revision with current one
299 * the icon does not displayed for the current revision
303 public function showIconCompareWithCurrent()
306 $id = $this->val('id');
307 $rev = $this->isCurrent() ?
'' : $this->val('date');
310 if ($this->val('mode') == self
::MODE_MEDIA
) {
311 // media file revision
312 if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) {
313 $param = ['mediado' => 'diff', 'image' => $id, 'rev' => $rev];
314 $href = media_managerURL($param, '&');
316 } elseif ($this->val('mode') == self
::MODE_PAGE
) {
318 if (!$this->isCurrent()) {
319 $href = wl($id, ['rev' => $rev, 'do' => 'diff'], false, '&');
324 return '<a href="' . $href . '" class="diff_link">'
325 . '<img src="' . DOKU_BASE
. 'lib/images/diff.png" width="15" height="11"'
326 . ' title="' . $lang['diff'] . '" alt="' . $lang['diff'] . '" />'
329 return '<img src="' . DOKU_BASE
. 'lib/images/blank.gif" width="15" height="11" alt="" />';
334 * icon for revision action
335 * used in [Ui\recent]
339 public function showIconRevisions()
343 if (!actionOK('revisions')) {
347 $id = $this->val('id');
348 if ($this->val('mode') == self
::MODE_MEDIA
) {
349 // media file revision
350 $param = ['tab_details' => 'history', 'ns' => getNS($id), 'image' => $id];
351 $href = media_managerURL($param, '&');
352 } elseif ($this->val('mode') == self
::MODE_PAGE
) {
354 $href = wl($id, ['do' => 'revisions'], false, '&');
356 return '<a href="' . $href . '" class="revisions_link">'
357 . '<img src="' . DOKU_BASE
. 'lib/images/history.png" width="12" height="14"'
358 . ' title="' . $lang['btn_revs'] . '" alt="' . $lang['btn_revs'] . '" />'
364 * used in [Ui\recent, Ui\Revisions]
368 public function showSizeChange()
370 $class = 'sizechange';
371 $value = filesize_h(abs($this->val('sizechange')));
372 if ($this->val('sizechange') > 0) {
373 $class .= ' positive';
374 $value = '+' . $value;
375 } elseif ($this->val('sizechange') < 0) {
376 $class .= ' negative';
377 $value = '-' . $value;
379 $value = '±' . $value;
381 return '<span class="' . $class . '">' . $value . '</span>';
385 * current indicator, used in revision list
386 * not used in Ui\Recent because recent files are always current one
390 public function showCurrentIndicator()
393 return $this->isCurrent() ?
'(' . $lang['current'] . ')' : '';