1*b370ebcdSSatoshi Sahara<?php 2*b370ebcdSSatoshi Sahara 3*b370ebcdSSatoshi Saharanamespace dokuwiki\Ui; 4*b370ebcdSSatoshi Sahara 5*b370ebcdSSatoshi Saharause dokuwiki\ChangeLog\PageChangeLog; 6*b370ebcdSSatoshi Saharause dokuwiki\Form\Form; 7*b370ebcdSSatoshi Sahara 8*b370ebcdSSatoshi Sahara/** 9*b370ebcdSSatoshi Sahara * DokuWiki PageRevisions Interface 10*b370ebcdSSatoshi Sahara * 11*b370ebcdSSatoshi Sahara * @package dokuwiki\Ui 12*b370ebcdSSatoshi Sahara */ 13*b370ebcdSSatoshi Saharaclass PageRevisions extends Ui 14*b370ebcdSSatoshi Sahara{ 15*b370ebcdSSatoshi Sahara /* @var string */ 16*b370ebcdSSatoshi Sahara protected $id; 17*b370ebcdSSatoshi Sahara 18*b370ebcdSSatoshi Sahara /** 19*b370ebcdSSatoshi Sahara * PageRevisions Ui constructor 20*b370ebcdSSatoshi Sahara * 21*b370ebcdSSatoshi Sahara * @param string $id id of page 22*b370ebcdSSatoshi Sahara */ 23*b370ebcdSSatoshi Sahara public function __construct($id) 24*b370ebcdSSatoshi Sahara { 25*b370ebcdSSatoshi Sahara global $ID, $INFO; 26*b370ebcdSSatoshi Sahara if (!$id) $id = $INFO['id']; 27*b370ebcdSSatoshi Sahara $this->id = $id; 28*b370ebcdSSatoshi Sahara } 29*b370ebcdSSatoshi Sahara 30*b370ebcdSSatoshi Sahara /** 31*b370ebcdSSatoshi Sahara * Display list of old revisions of the page 32*b370ebcdSSatoshi Sahara * 33*b370ebcdSSatoshi Sahara * @author Andreas Gohr <andi@splitbrain.org> 34*b370ebcdSSatoshi Sahara * @author Ben Coburn <btcoburn@silicodon.net> 35*b370ebcdSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 36*b370ebcdSSatoshi Sahara * @author Satoshi Sahara <sahara.satoshi@gmail.com> 37*b370ebcdSSatoshi Sahara * 38*b370ebcdSSatoshi Sahara * @param int $first skip the first n changelog lines 39*b370ebcdSSatoshi Sahara * @return void 40*b370ebcdSSatoshi Sahara */ 41*b370ebcdSSatoshi Sahara public function show($first = 0) 42*b370ebcdSSatoshi Sahara { 43*b370ebcdSSatoshi Sahara global $lang; 44*b370ebcdSSatoshi Sahara 45*b370ebcdSSatoshi Sahara // get revisions, and set correct pagenation parameters (first, hasNext) 46*b370ebcdSSatoshi Sahara if ($first === null) $first = 0; 47*b370ebcdSSatoshi Sahara $hasNext = false; 48*b370ebcdSSatoshi Sahara $revisions = $this->getRevisions($first, $hasNext); 49*b370ebcdSSatoshi Sahara 50*b370ebcdSSatoshi Sahara // print intro 51*b370ebcdSSatoshi Sahara print p_locale_xhtml('revisions'); 52*b370ebcdSSatoshi Sahara 53*b370ebcdSSatoshi Sahara // create the form 54*b370ebcdSSatoshi Sahara $form = new Form([ 55*b370ebcdSSatoshi Sahara 'id' => 'page__revisions', 56*b370ebcdSSatoshi Sahara 'class' => 'changes', 57*b370ebcdSSatoshi Sahara ]); 58*b370ebcdSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 59*b370ebcdSSatoshi Sahara 60*b370ebcdSSatoshi Sahara // start listing 61*b370ebcdSSatoshi Sahara $form->addTagOpen('ul'); 62*b370ebcdSSatoshi Sahara foreach ($revisions as $info) { 63*b370ebcdSSatoshi Sahara $rev = $info['date']; 64*b370ebcdSSatoshi Sahara $class = ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : ''; 65*b370ebcdSSatoshi Sahara $form->addTagOpen('li')->addClass($class); 66*b370ebcdSSatoshi Sahara $form->addTagOpen('div')->addClass('li'); 67*b370ebcdSSatoshi Sahara 68*b370ebcdSSatoshi Sahara if (page_exists($this->id, $rev)) { 69*b370ebcdSSatoshi Sahara $form->addCheckbox('rev2[]')->val($rev); 70*b370ebcdSSatoshi Sahara } else { 71*b370ebcdSSatoshi Sahara $form->addCheckbox('')->val($rev)->attr('disabled','disabled'); 72*b370ebcdSSatoshi Sahara } 73*b370ebcdSSatoshi Sahara $form->addHTML(' '); 74*b370ebcdSSatoshi Sahara 75*b370ebcdSSatoshi Sahara $objRevInfo = $this->getObjRevInfo($info); 76*b370ebcdSSatoshi Sahara $html = implode(' ', [ 77*b370ebcdSSatoshi Sahara $objRevInfo->editDate(), // edit date and time 78*b370ebcdSSatoshi Sahara $objRevInfo->difflink(), // link to diffview icon 79*b370ebcdSSatoshi Sahara $objRevInfo->itemName(), // name of page or media 80*b370ebcdSSatoshi Sahara $objRevInfo->editSummary(), // edit summary 81*b370ebcdSSatoshi Sahara $objRevInfo->editor(), // editor info 82*b370ebcdSSatoshi Sahara $objRevInfo->sizechange(), // size change indicator 83*b370ebcdSSatoshi Sahara $objRevInfo->currentIndicator(), // current indicator (only when k=1) 84*b370ebcdSSatoshi Sahara ]); 85*b370ebcdSSatoshi Sahara $form->addHTML($html); 86*b370ebcdSSatoshi Sahara $form->addTagClose('div'); 87*b370ebcdSSatoshi Sahara $form->addTagClose('li'); 88*b370ebcdSSatoshi Sahara } 89*b370ebcdSSatoshi Sahara $form->addTagClose('ul'); // end of revision list 90*b370ebcdSSatoshi Sahara 91*b370ebcdSSatoshi Sahara // show button for diff view 92*b370ebcdSSatoshi Sahara $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit'); 93*b370ebcdSSatoshi Sahara 94*b370ebcdSSatoshi Sahara $form->addTagClose('div'); // close div class=no 95*b370ebcdSSatoshi Sahara 96*b370ebcdSSatoshi Sahara print $form->toHTML('Revisions'); 97*b370ebcdSSatoshi Sahara 98*b370ebcdSSatoshi Sahara // provide navigation for pagenated revision list (of pages and/or media files) 99*b370ebcdSSatoshi Sahara print $this->htmlNavigation($first, $hasNext); 100*b370ebcdSSatoshi Sahara } 101*b370ebcdSSatoshi Sahara 102*b370ebcdSSatoshi Sahara /** 103*b370ebcdSSatoshi Sahara * Get revisions, and set correct pagenation parameters (first, hasNext) 104*b370ebcdSSatoshi Sahara * 105*b370ebcdSSatoshi Sahara * @param int $first 106*b370ebcdSSatoshi Sahara * @param bool $hasNext 107*b370ebcdSSatoshi Sahara * @return array revisions to be shown in a pagenated list 108*b370ebcdSSatoshi Sahara * @see also https://www.dokuwiki.org/devel:changelog 109*b370ebcdSSatoshi Sahara */ 110*b370ebcdSSatoshi Sahara protected function getRevisions(&$first, &$hasNext) 111*b370ebcdSSatoshi Sahara { 112*b370ebcdSSatoshi Sahara global $INFO, $conf; 113*b370ebcdSSatoshi Sahara 114*b370ebcdSSatoshi Sahara $changelog = new PageChangeLog($INFO['id']); 115*b370ebcdSSatoshi Sahara 116*b370ebcdSSatoshi Sahara $revisions = []; 117*b370ebcdSSatoshi Sahara 118*b370ebcdSSatoshi Sahara /* we need to get one additional log entry to be able to 119*b370ebcdSSatoshi Sahara * decide if this is the last page or is there another one. 120*b370ebcdSSatoshi Sahara * see also Ui\Recent::getRecents() 121*b370ebcdSSatoshi Sahara */ 122*b370ebcdSSatoshi Sahara $revlist = $changelog->getRevisions($first, $conf['recent'] +1); 123*b370ebcdSSatoshi Sahara if (count($revlist) == 0 && $first != 0) { 124*b370ebcdSSatoshi Sahara $first = 0; 125*b370ebcdSSatoshi Sahara $revlist = $changelog->getRevisions($first, $conf['recent'] +1); 126*b370ebcdSSatoshi Sahara } 127*b370ebcdSSatoshi Sahara $exists = $INFO['exists']; 128*b370ebcdSSatoshi Sahara if ($first === 0 && $exists) { 129*b370ebcdSSatoshi Sahara // add current page as revision[0] 130*b370ebcdSSatoshi Sahara $revisions[] = array( 131*b370ebcdSSatoshi Sahara 'date' => $INFO['lastmod'], 132*b370ebcdSSatoshi Sahara 'ip' => null, 133*b370ebcdSSatoshi Sahara 'type' => $INFO['meta']['last_change']['type'], 134*b370ebcdSSatoshi Sahara 'id' => $INFO['id'], 135*b370ebcdSSatoshi Sahara 'user' => $INFO['editor'], 136*b370ebcdSSatoshi Sahara 'sum' => $INFO['sum'], 137*b370ebcdSSatoshi Sahara 'extra' => null, 138*b370ebcdSSatoshi Sahara 'sizechange' => $INFO['meta']['last_change']['sizechange'], 139*b370ebcdSSatoshi Sahara 'current' => true, 140*b370ebcdSSatoshi Sahara ); 141*b370ebcdSSatoshi Sahara } 142*b370ebcdSSatoshi Sahara 143*b370ebcdSSatoshi Sahara // decide if this is the last page or is there another one 144*b370ebcdSSatoshi Sahara $hasNext = false; 145*b370ebcdSSatoshi Sahara if (count($revlist) > $conf['recent']) { 146*b370ebcdSSatoshi Sahara $hasNext = true; 147*b370ebcdSSatoshi Sahara array_pop($revlist); // remove one additional log entry 148*b370ebcdSSatoshi Sahara } 149*b370ebcdSSatoshi Sahara 150*b370ebcdSSatoshi Sahara // append each revison info array to the revisions 151*b370ebcdSSatoshi Sahara foreach ($revlist as $rev) { 152*b370ebcdSSatoshi Sahara $revisions[] = $changelog->getRevisionInfo($rev); 153*b370ebcdSSatoshi Sahara } 154*b370ebcdSSatoshi Sahara return $revisions; 155*b370ebcdSSatoshi Sahara } 156*b370ebcdSSatoshi Sahara 157*b370ebcdSSatoshi Sahara /** 158*b370ebcdSSatoshi Sahara * Navigation buttons for Pagenation (prev/next) 159*b370ebcdSSatoshi Sahara * 160*b370ebcdSSatoshi Sahara * @param int $first 161*b370ebcdSSatoshi Sahara * @param bool $hasNext 162*b370ebcdSSatoshi Sahara * @return array html 163*b370ebcdSSatoshi Sahara */ 164*b370ebcdSSatoshi Sahara protected function htmlNavigation($first, $hasNext) 165*b370ebcdSSatoshi Sahara { 166*b370ebcdSSatoshi Sahara global $conf; 167*b370ebcdSSatoshi Sahara 168*b370ebcdSSatoshi Sahara $html = '<div class="pagenav">'; 169*b370ebcdSSatoshi Sahara $last = $first + $conf['recent']; 170*b370ebcdSSatoshi Sahara if ($first > 0) { 171*b370ebcdSSatoshi Sahara $first = max($first - $conf['recent'], 0); 172*b370ebcdSSatoshi Sahara $html.= '<div class="pagenav-prev">'; 173*b370ebcdSSatoshi Sahara $html.= html_btn('newer', $this->id, "p" ,['do' => 'revisions', 'first' => $first]); 174*b370ebcdSSatoshi Sahara $html.= '</div>'; 175*b370ebcdSSatoshi Sahara } 176*b370ebcdSSatoshi Sahara if ($hasNext) { 177*b370ebcdSSatoshi Sahara $html.= '<div class="pagenav-next">'; 178*b370ebcdSSatoshi Sahara $html.= html_btn('older', $this->id, "n", ['do' => 'revisions', 'first' => $last]); 179*b370ebcdSSatoshi Sahara $html.= '</div>'; 180*b370ebcdSSatoshi Sahara } 181*b370ebcdSSatoshi Sahara $html.= '</div>'; 182*b370ebcdSSatoshi Sahara return $html; 183*b370ebcdSSatoshi Sahara } 184*b370ebcdSSatoshi Sahara 185*b370ebcdSSatoshi Sahara /** 186*b370ebcdSSatoshi Sahara * Returns instance of objRevInfo 187*b370ebcdSSatoshi Sahara * 188*b370ebcdSSatoshi Sahara * @param array $info Revision info structure of a page or media file 189*b370ebcdSSatoshi Sahara * @return objRevInfo object (anonymous class) 190*b370ebcdSSatoshi Sahara */ 191*b370ebcdSSatoshi Sahara protected function getObjRevInfo(array $info) 192*b370ebcdSSatoshi Sahara { 193*b370ebcdSSatoshi Sahara return new class ($info) // anonymous class (objRevInfo) 194*b370ebcdSSatoshi Sahara { 195*b370ebcdSSatoshi Sahara protected $info; 196*b370ebcdSSatoshi Sahara 197*b370ebcdSSatoshi Sahara public function __construct(array $info) 198*b370ebcdSSatoshi Sahara { 199*b370ebcdSSatoshi Sahara $this->info = $info; 200*b370ebcdSSatoshi Sahara } 201*b370ebcdSSatoshi Sahara 202*b370ebcdSSatoshi Sahara // current indicator 203*b370ebcdSSatoshi Sahara public function currentIndicator() 204*b370ebcdSSatoshi Sahara { 205*b370ebcdSSatoshi Sahara global $lang; 206*b370ebcdSSatoshi Sahara return ($this->info['current']) ? '('.$lang['current'].')' : ''; 207*b370ebcdSSatoshi Sahara } 208*b370ebcdSSatoshi Sahara 209*b370ebcdSSatoshi Sahara // edit date and time of the page or media file 210*b370ebcdSSatoshi Sahara public function editDate() 211*b370ebcdSSatoshi Sahara { 212*b370ebcdSSatoshi Sahara return '<span class="date">'. dformat($this->info['date']) .'</span>'; 213*b370ebcdSSatoshi Sahara } 214*b370ebcdSSatoshi Sahara 215*b370ebcdSSatoshi Sahara // edit summary 216*b370ebcdSSatoshi Sahara public function editSummary() 217*b370ebcdSSatoshi Sahara { 218*b370ebcdSSatoshi Sahara return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>'; 219*b370ebcdSSatoshi Sahara } 220*b370ebcdSSatoshi Sahara 221*b370ebcdSSatoshi Sahara // editor of the page or media file 222*b370ebcdSSatoshi Sahara public function editor() 223*b370ebcdSSatoshi Sahara { 224*b370ebcdSSatoshi Sahara // slightly different with display of Ui\Recent, i.e. external edit 225*b370ebcdSSatoshi Sahara global $lang; 226*b370ebcdSSatoshi Sahara $html = '<span class="user">'; 227*b370ebcdSSatoshi Sahara if (!$this->info['user'] && !$this->info['ip']) { 228*b370ebcdSSatoshi Sahara $html.= '('.$lang['external_edit'].')'; 229*b370ebcdSSatoshi Sahara } elseif ($this->info['user']) { 230*b370ebcdSSatoshi Sahara $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>'; 231*b370ebcdSSatoshi Sahara if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>'; 232*b370ebcdSSatoshi Sahara } else { 233*b370ebcdSSatoshi Sahara $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>'; 234*b370ebcdSSatoshi Sahara } 235*b370ebcdSSatoshi Sahara $html.= '</span>'; 236*b370ebcdSSatoshi Sahara return $html; 237*b370ebcdSSatoshi Sahara } 238*b370ebcdSSatoshi Sahara 239*b370ebcdSSatoshi Sahara // name of the page or media file 240*b370ebcdSSatoshi Sahara public function itemName() 241*b370ebcdSSatoshi Sahara { 242*b370ebcdSSatoshi Sahara // slightly different with display of Ui\Recent, i.e. revison may not exists 243*b370ebcdSSatoshi Sahara $id = $this->info['id']; 244*b370ebcdSSatoshi Sahara $rev = $this->info['date']; 245*b370ebcdSSatoshi Sahara 246*b370ebcdSSatoshi Sahara if (isset($this->info['media'])) { 247*b370ebcdSSatoshi Sahara // media file revision 248*b370ebcdSSatoshi Sahara if (isset($this->info['current'])) { 249*b370ebcdSSatoshi Sahara $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view'], '&'); 250*b370ebcdSSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>'; 251*b370ebcdSSatoshi Sahara } elseif (file_exists(mediaFN($id, $rev))) { 252*b370ebcdSSatoshi Sahara $href = media_managerURL(['image'=> $id, 'tab_details'=> 'view', 'rev'=> $rev], '&'); 253*b370ebcdSSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink1">'.$id.'</a>'; 254*b370ebcdSSatoshi Sahara } else { 255*b370ebcdSSatoshi Sahara $html = $id; 256*b370ebcdSSatoshi Sahara } 257*b370ebcdSSatoshi Sahara return $html; 258*b370ebcdSSatoshi Sahara } else { 259*b370ebcdSSatoshi Sahara // page revision 260*b370ebcdSSatoshi Sahara $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; 261*b370ebcdSSatoshi Sahara if (!$display_name) $display_name = $id; 262*b370ebcdSSatoshi Sahara if ($this->info['current'] || page_exists($id, $rev)) { 263*b370ebcdSSatoshi Sahara $href = wl($id, "rev=$rev", false, '&'); 264*b370ebcdSSatoshi Sahara $html = '<a href="'.$href.'" class="wikilink1">'.$display_name.'</a>'; 265*b370ebcdSSatoshi Sahara } else { 266*b370ebcdSSatoshi Sahara $html = $display_name; 267*b370ebcdSSatoshi Sahara } 268*b370ebcdSSatoshi Sahara return $html; 269*b370ebcdSSatoshi Sahara } 270*b370ebcdSSatoshi Sahara } 271*b370ebcdSSatoshi Sahara 272*b370ebcdSSatoshi Sahara // icon difflink 273*b370ebcdSSatoshi Sahara public function difflink() 274*b370ebcdSSatoshi Sahara { 275*b370ebcdSSatoshi Sahara global $lang; 276*b370ebcdSSatoshi Sahara $id = $this->info['id']; 277*b370ebcdSSatoshi Sahara $rev = $this->info['date']; 278*b370ebcdSSatoshi Sahara 279*b370ebcdSSatoshi Sahara if (isset($this->info['media'])) { 280*b370ebcdSSatoshi Sahara // media file revision 281*b370ebcdSSatoshi Sahara if (isset($this->info['current']) || !file_exists(mediaFN($id, $rev))) { 282*b370ebcdSSatoshi Sahara $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 283*b370ebcdSSatoshi Sahara } else { 284*b370ebcdSSatoshi Sahara $href = media_managerURL(['image'=> $id, 'rev'=> $rev, 'mediado'=>'diff'], '&'); 285*b370ebcdSSatoshi Sahara $html = '<a href="'.$href.'" class="diff_link">' 286*b370ebcdSSatoshi Sahara . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 287*b370ebcdSSatoshi Sahara . ' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' 288*b370ebcdSSatoshi Sahara . '</a> '; 289*b370ebcdSSatoshi Sahara } 290*b370ebcdSSatoshi Sahara return $html; 291*b370ebcdSSatoshi Sahara } else { 292*b370ebcdSSatoshi Sahara // page revision 293*b370ebcdSSatoshi Sahara if ($this->info['current'] || !page_exists($id, $rev)) { 294*b370ebcdSSatoshi Sahara $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 295*b370ebcdSSatoshi Sahara } else { 296*b370ebcdSSatoshi Sahara $href = wl($id, "rev=$rev,do=diff", false, '&'); 297*b370ebcdSSatoshi Sahara $html = '<a href="'.$href.'" class="diff_link">' 298*b370ebcdSSatoshi Sahara . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 299*b370ebcdSSatoshi Sahara . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />' 300*b370ebcdSSatoshi Sahara . '</a>'; 301*b370ebcdSSatoshi Sahara } 302*b370ebcdSSatoshi Sahara return $html; 303*b370ebcdSSatoshi Sahara } 304*b370ebcdSSatoshi Sahara } 305*b370ebcdSSatoshi Sahara 306*b370ebcdSSatoshi Sahara // size change 307*b370ebcdSSatoshi Sahara public function sizeChange() 308*b370ebcdSSatoshi Sahara { 309*b370ebcdSSatoshi Sahara $class = 'sizechange'; 310*b370ebcdSSatoshi Sahara $value = filesize_h(abs($this->info['sizechange'])); 311*b370ebcdSSatoshi Sahara if ($this->info['sizechange'] > 0) { 312*b370ebcdSSatoshi Sahara $class .= ' positive'; 313*b370ebcdSSatoshi Sahara $value = '+' . $value; 314*b370ebcdSSatoshi Sahara } elseif ($this->info['sizechange'] < 0) { 315*b370ebcdSSatoshi Sahara $class .= ' negative'; 316*b370ebcdSSatoshi Sahara $value = '-' . $value; 317*b370ebcdSSatoshi Sahara } else { 318*b370ebcdSSatoshi Sahara $value = '±' . $value; 319*b370ebcdSSatoshi Sahara } 320*b370ebcdSSatoshi Sahara return '<span class="'.$class.'">'.$value.'</span>'; 321*b370ebcdSSatoshi Sahara } 322*b370ebcdSSatoshi Sahara }; // end of anonymous class (objRevInfo) 323*b370ebcdSSatoshi Sahara } 324*b370ebcdSSatoshi Sahara 325*b370ebcdSSatoshi Sahara} 326