1<?php 2 3namespace dokuwiki\Ui; 4 5use dokuwiki\ChangeLog\PageChangeLog; 6use dokuwiki\Form\Form; 7 8/** 9 * DokuWiki PageRevisions Interface 10 * 11 * @package dokuwiki\Ui 12 */ 13class PageRevisions extends Revisions 14{ 15 /* @var PageChangeLog */ 16 protected $changelog; 17 18 /** 19 * PageRevisions Ui constructor 20 * 21 * @param string $id id of page 22 */ 23 public function __construct($id = null) 24 { 25 global $INFO; 26 if (!isset($id)) $id = $INFO['id']; 27 $this->item = 'page'; 28 parent::__construct($id); 29 } 30 31 /** @inheritdoc */ 32 protected function setChangeLog() 33 { 34 $this->changelog = new PageChangeLog($this->id); 35 } 36 37 /** @inheritdoc */ 38 protected function itemFN($id, $rev = '') 39 { 40 return wikiFN($id, $rev); 41 } 42 43 /** 44 * Display list of old revisions of the page 45 * 46 * @author Andreas Gohr <andi@splitbrain.org> 47 * @author Ben Coburn <btcoburn@silicodon.net> 48 * @author Kate Arzamastseva <pshns@ukr.net> 49 * @author Satoshi Sahara <sahara.satoshi@gmail.com> 50 * 51 * @param int $first skip the first n changelog lines 52 * @return void 53 */ 54 public function show($first = 0) 55 { 56 global $lang, $REV; 57 58 // get revisions, and set correct pagenation parameters (first, hasNext) 59 if ($first === null) $first = 0; 60 $hasNext = false; 61 $revisions = $this->getRevisions($first, $hasNext); 62 63 // print intro 64 print p_locale_xhtml('revisions'); 65 66 // create the form 67 $form = new Form([ 68 'id' => 'page__revisions', 69 'class' => 'changes', 70 ]); 71 $form->addTagOpen('div')->addClass('no'); 72 73 // start listing 74 $form->addTagOpen('ul'); 75 foreach ($revisions as $info) { 76 $rev = $info['date']; 77 $class = ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : ''; 78 $form->addTagOpen('li')->addClass($class); 79 $form->addTagOpen('div')->addClass('li'); 80 81 if (isset($info['current'])) { 82 $form->addCheckbox('rev2[]')->val('current'); 83 } elseif ($rev == $REV) { 84 $form->addCheckbox('rev2[]')->val($rev)->attr('checked','checked'); 85 } elseif (page_exists($this->id, $rev)) { 86 $form->addCheckbox('rev2[]')->val($rev); 87 } else { 88 $form->addCheckbox('')->val($rev)->attr('disabled','disabled'); 89 } 90 $form->addHTML(' '); 91 92 $objRevInfo = $this->getObjRevInfo($info); 93 $html = implode(' ', [ 94 $objRevInfo->editDate(), // edit date and time 95 $objRevInfo->difflink(), // link to diffview icon 96 $objRevInfo->itemName(), // name of page or media 97 $objRevInfo->editSummary(), // edit summary 98 $objRevInfo->editor(), // editor info 99 $objRevInfo->sizechange(), // size change indicator 100 $objRevInfo->currentIndicator(), // current indicator (only when k=1) 101 ]); 102 $form->addHTML($html); 103 $form->addTagClose('div'); 104 $form->addTagClose('li'); 105 } 106 $form->addTagClose('ul'); // end of revision list 107 108 // show button for diff view 109 $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit'); 110 111 $form->addTagClose('div'); // close div class=no 112 113 print $form->toHTML('Revisions'); 114 115 // provide navigation for pagenated revision list (of pages and/or media files) 116 print $this->navigation($first, $hasNext, function ($n) { 117 return array('do' => 'revisions', 'first' => $n); 118 }); 119 } 120 121 /** 122 * Get revisions, and set correct pagenation parameters (first, hasNext) 123 * 124 * @param int $first 125 * @param bool $hasNext 126 * @return array revisions to be shown in a pagenated list 127 * @see also https://www.dokuwiki.org/devel:changelog 128 */ 129 protected function getRevisions(&$first, &$hasNext) 130 { 131 global $INFO, $conf; 132 133 if ($this->id != $INFO['id']) { 134 return parent::getRevisions($first, $hasNext); 135 } 136 137 $changelog =& $this->changelog; 138 $revisions = []; 139 140 $extEditRevInfo = $changelog->getExternalEditRevInfo(); 141 142 /* we need to get one additional log entry to be able to 143 * decide if this is the last page or is there another one. 144 * see also Ui\Recent::getRecents() 145 */ 146 $num = $conf['recent']; 147 if ($first == 0) { 148 $num = $extEditRevInfo ? $num - 1 : $num; 149 } 150 $revlist = $changelog->getRevisions($first - 1, $num + 1); 151 if (count($revlist) == 0 && $first != 0) { 152 // resets to zero if $first requested a too high number 153 $first = 0; 154 $num = $extEditRevInfo ? $num - 1 : $num; 155 $revlist = $changelog->getRevisions(-1, $num + 1); 156 } 157 158 if ($first == 0 && $extEditRevInfo) { 159 $revisions[] = $extEditRevInfo + [ 160 'item' => $this->item, 161 'current' => true 162 ]; 163 } 164 165 // decide if this is the last page or is there another one 166 $hasNext = false; 167 if (count($revlist) > $num) { 168 $hasNext = true; 169 array_pop($revlist); // remove one additional log entry 170 } 171 172 // append each revison info array to the revisions 173 $fileLastMod = wikiFN($this->id); 174 $lastMod = @filemtime($fileLastMod); // from wiki page, suppresses warning in case the file not exists 175 foreach ($revlist as $rev) { 176 $more = ['item' => $this->item]; 177 if ($rev == $lastMod) { 178 $more['current'] = true; 179 } 180 $revisions[] = $changelog->getRevisionInfo($rev) + $more; 181 } 182 return $revisions; 183 } 184 185} 186