16c9fde82SSatoshi Sahara<?php 26c9fde82SSatoshi Sahara 36c9fde82SSatoshi Saharanamespace dokuwiki\Ui; 46c9fde82SSatoshi Sahara 590c7493eSSatoshi Saharause dokuwiki\ChangeLog\ChangeLog; 690c7493eSSatoshi Sahara 76c9fde82SSatoshi Sahara/** 89e316641SSatoshi Sahara * DokuWiki Revisions Interface 9ae5d2354SSatoshi Sahara * parent class of PageRevisions and MediaRevisions 106c9fde82SSatoshi Sahara * 116c9fde82SSatoshi Sahara * @package dokuwiki\Ui 126c9fde82SSatoshi Sahara */ 13ae5d2354SSatoshi Saharaabstract class Revisions extends Ui 146c9fde82SSatoshi Sahara{ 15ae5d2354SSatoshi Sahara /* @var string */ 16e71e09a6SSatoshi Sahara protected $id; // page id or media id 17e71e09a6SSatoshi Sahara 18e71e09a6SSatoshi Sahara /* @var ChangeLog */ 19e71e09a6SSatoshi Sahara protected $changelog; // PageChangeLog or MediaChangeLog object 209e316641SSatoshi Sahara 219e316641SSatoshi Sahara /** 229e316641SSatoshi Sahara * Revisions Ui constructor 239e316641SSatoshi Sahara * 24e71e09a6SSatoshi Sahara * @param string $id page id or media id 259e316641SSatoshi Sahara */ 26ae5d2354SSatoshi Sahara public function __construct($id) 279e316641SSatoshi Sahara { 28ae5d2354SSatoshi Sahara $this->id = $id; 29e71e09a6SSatoshi Sahara $this->setChangeLog(); 30e71e09a6SSatoshi Sahara } 31e71e09a6SSatoshi Sahara 32e71e09a6SSatoshi Sahara /** 33e71e09a6SSatoshi Sahara * set class property changelog 34e71e09a6SSatoshi Sahara */ 35e71e09a6SSatoshi Sahara abstract protected function setChangeLog(); 36e71e09a6SSatoshi Sahara 37e71e09a6SSatoshi Sahara /** 38ad088cbcSSatoshi Sahara * Get revisions, and set correct pagination parameters (first, hasNext) 3967ef3e88SSatoshi Sahara * 4067ef3e88SSatoshi Sahara * @param int $first 4167ef3e88SSatoshi Sahara * @param bool $hasNext 4267ef3e88SSatoshi Sahara * @return array revisions to be shown in a pagenated list 435525369fSSatoshi Sahara * @see also https://www.dokuwiki.org/devel:changelog 4467ef3e88SSatoshi Sahara */ 45e71e09a6SSatoshi Sahara protected function getRevisions(&$first, &$hasNext) 46e71e09a6SSatoshi Sahara { 47e71e09a6SSatoshi Sahara global $conf; 48e71e09a6SSatoshi Sahara 49e71e09a6SSatoshi Sahara $changelog =& $this->changelog; 5090c7493eSSatoshi Sahara $revisions = []; 51e71e09a6SSatoshi Sahara 52ad088cbcSSatoshi Sahara $currentRevInfo = $changelog->getCurrentRevisionInfo(); 53ad088cbcSSatoshi Sahara if (!$currentRevInfo) return $revisions; 54e71e09a6SSatoshi Sahara 5590c7493eSSatoshi Sahara $num = $conf['recent']; 5690c7493eSSatoshi Sahara if ($first == 0) { 57*dbf582ddSSatoshi Sahara // add extrenal or existing last revision that is excluded from $changelog->getRevisions() 58*dbf582ddSSatoshi Sahara if (array_key_exists('timestamp', $currentRevInfo) || ( 59*dbf582ddSSatoshi Sahara $currentRevInfo['type'] != DOKU_CHANGE_TYPE_DELETE && 60*dbf582ddSSatoshi Sahara $currentRevInfo['date'] == $changelog->lastRevision() ) 61*dbf582ddSSatoshi Sahara ) { 62ad088cbcSSatoshi Sahara $revisions[] = $currentRevInfo; 63ad088cbcSSatoshi Sahara $num = $num - 1; 6490c7493eSSatoshi Sahara } 65*dbf582ddSSatoshi Sahara } 66ad088cbcSSatoshi Sahara /* we need to get one additional log entry to be able to 67ad088cbcSSatoshi Sahara * decide if this is the last page or is there another one. 68ad088cbcSSatoshi Sahara * see also Ui\Recent::getRecents() 69ad088cbcSSatoshi Sahara */ 70ad088cbcSSatoshi Sahara $revlist = $changelog->getRevisions($first, $num + 1); 71ad088cbcSSatoshi Sahara if (count($revlist) == 0 && $first > 0) { 72ad088cbcSSatoshi Sahara // resets to zero if $first requested a too high number 73e71e09a6SSatoshi Sahara $first = 0; 74ad088cbcSSatoshi Sahara return $this->getRevisions($first, $hasNext); 75e71e09a6SSatoshi Sahara } 76e71e09a6SSatoshi Sahara 77e71e09a6SSatoshi Sahara // decide if this is the last page or is there another one 78e71e09a6SSatoshi Sahara $hasNext = false; 7990c7493eSSatoshi Sahara if (count($revlist) > $num) { 80e71e09a6SSatoshi Sahara $hasNext = true; 81e71e09a6SSatoshi Sahara array_pop($revlist); // remove one additional log entry 82e71e09a6SSatoshi Sahara } 83e71e09a6SSatoshi Sahara 84e71e09a6SSatoshi Sahara // append each revison info array to the revisions 85e71e09a6SSatoshi Sahara foreach ($revlist as $rev) { 86ad088cbcSSatoshi Sahara $revisions[] = $changelog->getRevisionInfo($rev); 87e71e09a6SSatoshi Sahara } 88e71e09a6SSatoshi Sahara return $revisions; 89e71e09a6SSatoshi Sahara } 9067ef3e88SSatoshi Sahara 9167ef3e88SSatoshi Sahara /** 9267ef3e88SSatoshi Sahara * Navigation buttons for Pagenation (prev/next) 9367ef3e88SSatoshi Sahara * 9467ef3e88SSatoshi Sahara * @param int $first 9567ef3e88SSatoshi Sahara * @param bool $hasNext 96ae5d2354SSatoshi Sahara * @param callable $callback returns array of hidden fields for the form button 9790c7493eSSatoshi Sahara * @return string html 9867ef3e88SSatoshi Sahara */ 99ae5d2354SSatoshi Sahara protected function navigation($first, $hasNext, $callback) 10067ef3e88SSatoshi Sahara { 10167ef3e88SSatoshi Sahara global $conf; 10267ef3e88SSatoshi Sahara 10367ef3e88SSatoshi Sahara $html = '<div class="pagenav">'; 1046c9fde82SSatoshi Sahara $last = $first + $conf['recent']; 1056c9fde82SSatoshi Sahara if ($first > 0) { 10667ef3e88SSatoshi Sahara $first = max($first - $conf['recent'], 0); 10767ef3e88SSatoshi Sahara $html.= '<div class="pagenav-prev">'; 108ae5d2354SSatoshi Sahara $html.= html_btn('newer', $this->id, "p", $callback($first)); 10967ef3e88SSatoshi Sahara $html.= '</div>'; 1106c9fde82SSatoshi Sahara } 1116c9fde82SSatoshi Sahara if ($hasNext) { 11267ef3e88SSatoshi Sahara $html.= '<div class="pagenav-next">'; 113ae5d2354SSatoshi Sahara $html.= html_btn('older', $this->id, "n", $callback($last)); 11467ef3e88SSatoshi Sahara $html.= '</div>'; 1156c9fde82SSatoshi Sahara } 11667ef3e88SSatoshi Sahara $html.= '</div>'; 11767ef3e88SSatoshi Sahara return $html; 11867ef3e88SSatoshi Sahara } 1196c9fde82SSatoshi Sahara 12067ef3e88SSatoshi Sahara /** 12167ef3e88SSatoshi Sahara * Returns instance of objRevInfo 12267ef3e88SSatoshi Sahara * 12367ef3e88SSatoshi Sahara * @param array $info Revision info structure of a page or media file 12467ef3e88SSatoshi Sahara * @return objRevInfo object (anonymous class) 12567ef3e88SSatoshi Sahara */ 1260bb448f0SSatoshi Sahara public function getObjRevInfo(array $info) 12767ef3e88SSatoshi Sahara { 12867ef3e88SSatoshi Sahara return new class ($info) // anonymous class (objRevInfo) 12967ef3e88SSatoshi Sahara { 13067ef3e88SSatoshi Sahara protected $info; 13167ef3e88SSatoshi Sahara 13267ef3e88SSatoshi Sahara public function __construct(array $info) 13367ef3e88SSatoshi Sahara { 134ad088cbcSSatoshi Sahara $info['item'] = strrpos($info['id'], '.') ? 'media' : 'page'; 1355ec96136SSatoshi Sahara $info['current'] = $info['current'] ?? false; 136*dbf582ddSSatoshi Sahara // revision info may have timestamp key when external edits occurred 137*dbf582ddSSatoshi Sahara $info['timestamp'] = $info['timestamp'] ?? true; 13867ef3e88SSatoshi Sahara $this->info = $info; 13967ef3e88SSatoshi Sahara } 14067ef3e88SSatoshi Sahara 14167ef3e88SSatoshi Sahara // current indicator 14267ef3e88SSatoshi Sahara public function currentIndicator() 14367ef3e88SSatoshi Sahara { 14467ef3e88SSatoshi Sahara global $lang; 14567ef3e88SSatoshi Sahara return ($this->info['current']) ? '('.$lang['current'].')' : ''; 14667ef3e88SSatoshi Sahara } 14767ef3e88SSatoshi Sahara 14867ef3e88SSatoshi Sahara // edit date and time of the page or media file 14967ef3e88SSatoshi Sahara public function editDate() 15067ef3e88SSatoshi Sahara { 15190c7493eSSatoshi Sahara global $lang; 15290c7493eSSatoshi Sahara $date = dformat($this->info['date']); 153*dbf582ddSSatoshi Sahara if ($this->info['timestamp'] === false) { 1545ec96136SSatoshi Sahara // externally deleted or older file restored 155ad088cbcSSatoshi Sahara $date = preg_replace('/[0-9a-zA-Z]/','_', $date); 15690c7493eSSatoshi Sahara } 15790c7493eSSatoshi Sahara return '<span class="date">'. $date .'</span>'; 15867ef3e88SSatoshi Sahara } 15967ef3e88SSatoshi Sahara 16067ef3e88SSatoshi Sahara // edit summary 16167ef3e88SSatoshi Sahara public function editSummary() 16267ef3e88SSatoshi Sahara { 16367ef3e88SSatoshi Sahara return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>'; 16467ef3e88SSatoshi Sahara } 16567ef3e88SSatoshi Sahara 16667ef3e88SSatoshi Sahara // editor of the page or media file 16767ef3e88SSatoshi Sahara public function editor() 16867ef3e88SSatoshi Sahara { 16967ef3e88SSatoshi Sahara // slightly different with display of Ui\Recent, i.e. external edit 17067ef3e88SSatoshi Sahara global $lang; 17167ef3e88SSatoshi Sahara $html = '<span class="user">'; 17267ef3e88SSatoshi Sahara if (!$this->info['user'] && !$this->info['ip']) { 17367ef3e88SSatoshi Sahara $html.= '('.$lang['external_edit'].')'; 17467ef3e88SSatoshi Sahara } elseif ($this->info['user']) { 17567ef3e88SSatoshi Sahara $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>'; 17667ef3e88SSatoshi Sahara if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>'; 17767ef3e88SSatoshi Sahara } else { 17867ef3e88SSatoshi Sahara $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>'; 17967ef3e88SSatoshi Sahara } 18067ef3e88SSatoshi Sahara $html.= '</span>'; 18167ef3e88SSatoshi Sahara return $html; 18267ef3e88SSatoshi Sahara } 18367ef3e88SSatoshi Sahara 18467ef3e88SSatoshi Sahara // name of the page or media file 18567ef3e88SSatoshi Sahara public function itemName() 18667ef3e88SSatoshi Sahara { 18767ef3e88SSatoshi Sahara // slightly different with display of Ui\Recent, i.e. revison may not exists 18867ef3e88SSatoshi Sahara $id = $this->info['id']; 18967ef3e88SSatoshi Sahara $rev = $this->info['date']; 19067ef3e88SSatoshi Sahara 191e71e09a6SSatoshi Sahara switch ($this->info['item']) { 192e71e09a6SSatoshi Sahara case 'media': // media file revision 1935ec96136SSatoshi Sahara if ($this->info['current']) { 19467ef3e88SSatoshi Sahara $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view'], '&'); 19567ef3e88SSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>'; 19667ef3e88SSatoshi Sahara } elseif (file_exists(mediaFN($id, $rev))) { 19767ef3e88SSatoshi Sahara $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view', 'rev'=> $rev], '&'); 19867ef3e88SSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>'; 19967ef3e88SSatoshi Sahara } else { 20067ef3e88SSatoshi Sahara $html = $id; 20167ef3e88SSatoshi Sahara } 20267ef3e88SSatoshi Sahara return $html; 203e71e09a6SSatoshi Sahara case 'page': // page revision 20467ef3e88SSatoshi Sahara $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; 20567ef3e88SSatoshi Sahara if (!$display_name) $display_name = $id; 206ad088cbcSSatoshi Sahara if ($this->info['type'] == DOKU_CHANGE_TYPE_DELETE) { 207*dbf582ddSSatoshi Sahara // externally deleted or older file restored 2085d9428a0SSatoshi Sahara $href = wl($id, "", false, '&'); 2095d9428a0SSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink2">'.$display_name.'</a>'; 2105d9428a0SSatoshi Sahara } elseif ($this->info['current'] || page_exists($id, $rev)) { 21167ef3e88SSatoshi Sahara $href = wl($id, "rev=$rev", false, '&'); 21267ef3e88SSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink1">'.$display_name.'</a>'; 21367ef3e88SSatoshi Sahara } else { 21467ef3e88SSatoshi Sahara $html = $display_name; 21567ef3e88SSatoshi Sahara } 21667ef3e88SSatoshi Sahara return $html; 21767ef3e88SSatoshi Sahara } 218e71e09a6SSatoshi Sahara return ''; 21967ef3e88SSatoshi Sahara } 22067ef3e88SSatoshi Sahara 22167ef3e88SSatoshi Sahara // icon difflink 22267ef3e88SSatoshi Sahara public function difflink() 22367ef3e88SSatoshi Sahara { 22467ef3e88SSatoshi Sahara global $lang; 22567ef3e88SSatoshi Sahara $id = $this->info['id']; 22667ef3e88SSatoshi Sahara $rev = $this->info['date']; 22767ef3e88SSatoshi Sahara 228e71e09a6SSatoshi Sahara switch ($this->info['item']) { 229e71e09a6SSatoshi Sahara case 'media': // media file revision 2305ec96136SSatoshi Sahara if ($this->info['current'] || !file_exists(mediaFN($id, $rev))) { 23167ef3e88SSatoshi Sahara $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 23267ef3e88SSatoshi Sahara } else { 23367ef3e88SSatoshi Sahara $href = media_managerURL(['image'=> $id, 'rev'=> $rev, 'mediado'=>'diff'], '&'); 23467ef3e88SSatoshi Sahara $html = '<a href="'.$href.'" class="diff_link">' 23567ef3e88SSatoshi Sahara . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 23667ef3e88SSatoshi Sahara . ' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' 23767ef3e88SSatoshi Sahara . '</a> '; 23867ef3e88SSatoshi Sahara } 23967ef3e88SSatoshi Sahara return $html; 240e71e09a6SSatoshi Sahara case 'page': // page revision 24167ef3e88SSatoshi Sahara if ($this->info['current'] || !page_exists($id, $rev)) { 24267ef3e88SSatoshi Sahara $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 24367ef3e88SSatoshi Sahara } else { 24467ef3e88SSatoshi Sahara $href = wl($id, "rev=$rev,do=diff", false, '&'); 24567ef3e88SSatoshi Sahara $html = '<a href="'.$href.'" class="diff_link">' 24667ef3e88SSatoshi Sahara . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 24767ef3e88SSatoshi Sahara . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />' 24867ef3e88SSatoshi Sahara . '</a>'; 24967ef3e88SSatoshi Sahara } 25067ef3e88SSatoshi Sahara return $html; 25167ef3e88SSatoshi Sahara } 252e71e09a6SSatoshi Sahara return ''; 25367ef3e88SSatoshi Sahara } 25467ef3e88SSatoshi Sahara 25567ef3e88SSatoshi Sahara // size change 25667ef3e88SSatoshi Sahara public function sizeChange() 25767ef3e88SSatoshi Sahara { 25867ef3e88SSatoshi Sahara $class = 'sizechange'; 25967ef3e88SSatoshi Sahara $value = filesize_h(abs($this->info['sizechange'])); 26067ef3e88SSatoshi Sahara if ($this->info['sizechange'] > 0) { 26167ef3e88SSatoshi Sahara $class .= ' positive'; 26267ef3e88SSatoshi Sahara $value = '+' . $value; 26367ef3e88SSatoshi Sahara } elseif ($this->info['sizechange'] < 0) { 26467ef3e88SSatoshi Sahara $class .= ' negative'; 26567ef3e88SSatoshi Sahara $value = '-' . $value; 26667ef3e88SSatoshi Sahara } else { 26767ef3e88SSatoshi Sahara $value = '±' . $value; 26867ef3e88SSatoshi Sahara } 26967ef3e88SSatoshi Sahara return '<span class="'.$class.'">'.$value.'</span>'; 27067ef3e88SSatoshi Sahara } 27167ef3e88SSatoshi Sahara }; // end of anonymous class (objRevInfo) 2726c9fde82SSatoshi Sahara } 2736c9fde82SSatoshi Sahara 2746c9fde82SSatoshi Sahara} 275