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