123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- <?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 '—';
- $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'].')' : '';
- }
- }
|