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