bash/snippets/dokuwiki-2023-04-04/inc/ChangeLog/RevisionInfo.php

397 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace dokuwiki\ChangeLog;
/**
* Class RevisionInfo
*
* Provides methods to show Revision Information in DokuWiki Ui components:
* - Ui\Recent
* - Ui\PageRevisions
* - Ui\MediaRevisions
*/
class RevisionInfo
{
/* @var array */
protected $info;
/**
* Constructor
*
* @param array $info Revision Information structure with entries:
* - date: unix timestamp
* - ip: IPv4 or IPv6 address
* - type: change type (log line type)
* - id: page id
* - user: user name
* - sum: edit summary (or action reason)
* - extra: extra data (varies by line type)
* - sizechange: change of filesize
* additionally,
* - current: (optional) whether current revision or not
* - timestamp: (optional) set only when external edits occurred
* - mode: (internal use) ether "media" or "page"
*/
public function __construct($info = null)
{
if (is_array($info) && isset($info['id'])) {
// define strategy context
$info['mode'] = $info['media'] ? 'media' : 'page';
} else {
$info = [
'mode' => 'page',
'date' => false,
];
}
$this->info = $info;
}
/**
* Set or return whether this revision is current page or media file
*
* This method does not check exactly whether the revision is current or not. Instead,
* set value of associated "current" key for internal use. Some UI element like diff
* link button depend on relation to current page or media file. A changelog line does
* not indicate whether it corresponds to current page or media file.
*
* @param bool $value true if the revision is current, otherwise false
* @return bool
*/
public function isCurrent($value = null)
{
return (bool) $this->val('current', $value);
}
/**
* Return or set a value of associated key of revision information
* but does not allow to change values of existing keys
*
* @param string $key
* @param mixed $value
* @return string|null
*/
public function val($key, $value = null)
{
if (isset($value) && !array_key_exists($key, $this->info)) {
// setter, only for new keys
$this->info[$key] = $value;
}
if (array_key_exists($key, $this->info)) {
// getter
return $this->info[$key];
}
return null;
}
/**
* Set extra key-value to the revision information
* but does not allow to change values of existing keys
* @param array $info
* @return void
*/
public function append(array $info)
{
foreach ($info as $key => $value) {
$this->val($key, $value);
}
}
/**
* file icon of the page or media file
* used in [Ui\recent]
*
* @return string
*/
public function showFileIcon()
{
$id = $this->val('id');
switch ($this->val('mode')) {
case 'media': // media file revision
return media_printicon($id);
case 'page': // page revision
return '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />';
}
}
/**
* edit date and time of the page or media file
* used in [Ui\recent, Ui\Revisions]
*
* @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false
* @return string
*/
public function showEditDate($checkTimestamp = false)
{
$formatted = dformat($this->val('date'));
if ($checkTimestamp && $this->val('timestamp') === false) {
// exact date is unknown for externally deleted file
// when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__"
$formatted = preg_replace('/[0-9a-zA-Z]/','_', $formatted);
}
return '<span class="date">'. $formatted .'</span>';
}
/**
* edit summary
* used in [Ui\recent, Ui\Revisions]
*
* @return string
*/
public function showEditSummary()
{
return '<span class="sum">'.' '. hsc($this->val('sum')).'</span>';
}
/**
* editor of the page or media file
* used in [Ui\recent, Ui\Revisions]
*
* @return string
*/
public function showEditor()
{
if ($this->val('user')) {
$html = '<bdi>'. editorinfo($this->val('user')) .'</bdi>';
if (auth_ismanager()) $html .= ' <bdo dir="ltr">('. $this->val('ip') .')</bdo>';
} else {
$html = '<bdo dir="ltr">'. $this->val('ip') .'</bdo>';
}
return '<span class="user">'. $html. '</span>';
}
/**
* name of the page or media file
* used in [Ui\recent, Ui\Revisions]
*
* @return string
*/
public function showFileName()
{
$id = $this->val('id');
$rev = $this->isCurrent() ? '' : $this->val('date');
switch ($this->val('mode')) {
case 'media': // media file revision
$params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id];
if ($rev) $params += ['rev'=> $rev];
$href = media_managerURL($params, '&');
$display_name = $id;
$exists = file_exists(mediaFN($id, $rev));
break;
case 'page': // page revision
$params = $rev ? ['rev'=> $rev] : [];
$href = wl($id, $params, false, '&');
$display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
if (!$display_name) $display_name = $id;
$exists = page_exists($id, $rev);
}
if($exists) {
$class = 'wikilink1';
} else {
if($this->isCurrent()) {
//show only not-existing link for current page, which allows for directly create a new page/upload
$class = 'wikilink2';
} else {
//revision is not in attic
return $display_name;
}
}
if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) {
$class = 'wikilink2';
}
return '<a href="'.$href.'" class="'.$class.'">'.$display_name.'</a>';
}
/**
* Revision Title for PageDiff table headline
*
* @return string
*/
public function showRevisionTitle()
{
global $lang;
if (!$this->val('date')) return '&mdash;';
$id = $this->val('id');
$rev = $this->isCurrent() ? '' : $this->val('date');
$params = ($rev) ? ['rev'=> $rev] : [];
// revision info may have timestamp key when external edits occurred
$date = ($this->val('timestamp') === false)
? $lang['unknowndate']
: dformat($this->val('date'));
switch ($this->val('mode')) {
case 'media': // media file revision
$href = ml($id, $params, false, '&');
$exists = file_exists(mediaFN($id, $rev));
break;
case 'page': // page revision
$href = wl($id, $params, false, '&');
$exists = page_exists($id, $rev);
}
if($exists) {
$class = 'wikilink1';
} else {
if($this->isCurrent()) {
//show only not-existing link for current page, which allows for directly create a new page/upload
$class = 'wikilink2';
} else {
//revision is not in attic
return $id.' ['.$date.']';
}
}
if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) {
$class = 'wikilink2';
}
return '<bdi><a class="'.$class.'" href="'.$href.'">'.$id.' ['.$date.']'.'</a></bdi>';
}
/**
* diff link icon in recent changes list, to compare (this) current revision with previous one
* all items in "recent changes" are current revision of the page or media
*
* @return string
*/
public function showIconCompareWithPrevious()
{
global $lang;
$id = $this->val('id');
$href = '';
switch ($this->val('mode')) {
case 'media': // media file revision
// unlike page, media file does not copied to media_attic when uploaded.
// diff icon will not be shown when external edit occurred
// because no attic file to be compared with current.
$revs = (new MediaChangeLog($id))->getRevisions(0, 1);
$showLink = (count($revs) && file_exists(mediaFN($id,$revs[0])) && file_exists(mediaFN($id)));
if ($showLink) {
$param = ['tab_details'=>'history', 'mediado'=>'diff', 'ns'=> getNS($id), 'image'=> $id];
$href = media_managerURL($param, '&');
}
break;
case 'page': // page revision
// when a page just created anyway, it is natural to expect no older revisions
// even if it had once existed but deleted before. Simply ignore to check changelog.
if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE) {
$href = wl($id, ['do'=>'diff'], false, '&');
}
}
if ($href) {
return '<a href="'.$href.'" class="diff_link">'
.'<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
.' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />'
.'</a>';
} else {
return '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
}
}
/**
* diff link icon in revisions list, compare this revision with current one
* the icon does not displayed for the current revision
*
* @return string
*/
public function showIconCompareWithCurrent()
{
global $lang;
$id = $this->val('id');
$rev = $this->isCurrent() ? '' : $this->val('date');
$href = '';
switch ($this->val('mode')) {
case 'media': // media file revision
if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) {
$param = ['mediado'=>'diff', 'image'=> $id, 'rev'=> $rev];
$href = media_managerURL($param, '&');
}
break;
case 'page': // page revision
if (!$this->isCurrent()) {
$href = wl($id, ['rev'=> $rev, 'do'=>'diff'], false, '&');
}
}
if ($href) {
return '<a href="'.$href.'" class="diff_link">'
.'<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
.' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />'
.'</a>';
} else {
return '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
}
}
/**
* icon for revision action
* used in [Ui\recent]
*
* @return string
*/
public function showIconRevisions()
{
global $lang;
if (!actionOK('revisions')) {
return '';
}
$id = $this->val('id');
switch ($this->val('mode')) {
case 'media': // media file revision
$param = ['tab_details'=>'history', 'ns'=> getNS($id), 'image'=> $id];
$href = media_managerURL($param, '&');
break;
case 'page': // page revision
$href = wl($id, ['do'=>'revisions'], false, '&');
}
return '<a href="'.$href.'" class="revisions_link">'
. '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"'
. ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
. '</a>';
}
/**
* size change
* used in [Ui\recent, Ui\Revisions]
*
* @return string
*/
public function showSizeChange()
{
$class = 'sizechange';
$value = filesize_h(abs($this->val('sizechange')));
if ($this->val('sizechange') > 0) {
$class .= ' positive';
$value = '+' . $value;
} elseif ($this->val('sizechange') < 0) {
$class .= ' negative';
$value = '-' . $value;
} else {
$value = '±' . $value;
}
return '<span class="'.$class.'">'.$value.'</span>';
}
/**
* current indicator, used in revision list
* not used in Ui\Recent because recent files are always current one
*
* @return string
*/
public function showCurrentIndicator()
{
global $lang;
return $this->isCurrent() ? '('.$lang['current'].')' : '';
}
}