[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace dokuwiki\ChangeLog; 4 5 /** 6 * Class RevisionInfo 7 * 8 * Provides methods to show Revision Information in DokuWiki Ui components: 9 * - Ui\Recent 10 * - Ui\PageRevisions 11 * - Ui\MediaRevisions 12 */ 13 class RevisionInfo 14 { 15 /* @var array */ 16 protected $info; 17 18 /** 19 * Constructor 20 * 21 * @param array $info Revision Information structure with entries: 22 * - date: unix timestamp 23 * - ip: IPv4 or IPv6 address 24 * - type: change type (log line type) 25 * - id: page id 26 * - user: user name 27 * - sum: edit summary (or action reason) 28 * - extra: extra data (varies by line type) 29 * - sizechange: change of filesize 30 * additionally, 31 * - current: (optional) whether current revision or not 32 * - timestamp: (optional) set only when external edits occurred 33 * - mode: (internal use) ether "media" or "page" 34 */ 35 public function __construct($info = null) 36 { 37 if (is_array($info) && isset($info['id'])) { 38 // define strategy context 39 $info['mode'] = $info['media'] ? 'media' : 'page'; 40 } else { 41 $info = [ 42 'mode' => 'page', 43 'date' => false, 44 ]; 45 } 46 $this->info = $info; 47 } 48 49 /** 50 * Set or return whether this revision is current page or media file 51 * 52 * This method does not check exactly whether the revision is current or not. Instead, 53 * set value of associated "current" key for internal use. Some UI element like diff 54 * link button depend on relation to current page or media file. A changelog line does 55 * not indicate whether it corresponds to current page or media file. 56 * 57 * @param bool $value true if the revision is current, otherwise false 58 * @return bool 59 */ 60 public function isCurrent($value = null) 61 { 62 return (bool) $this->val('current', $value); 63 } 64 65 /** 66 * Return or set a value of associated key of revision information 67 * but does not allow to change values of existing keys 68 * 69 * @param string $key 70 * @param mixed $value 71 * @return string|null 72 */ 73 public function val($key, $value = null) 74 { 75 if (isset($value) && !array_key_exists($key, $this->info)) { 76 // setter, only for new keys 77 $this->info[$key] = $value; 78 } 79 if (array_key_exists($key, $this->info)) { 80 // getter 81 return $this->info[$key]; 82 } 83 return null; 84 } 85 86 /** 87 * Set extra key-value to the revision information 88 * but does not allow to change values of existing keys 89 * @param array $info 90 * @return void 91 */ 92 public function append(array $info) 93 { 94 foreach ($info as $key => $value) { 95 $this->val($key, $value); 96 } 97 } 98 99 100 /** 101 * file icon of the page or media file 102 * used in [Ui\recent] 103 * 104 * @return string 105 */ 106 public function showFileIcon() 107 { 108 $id = $this->val('id'); 109 switch ($this->val('mode')) { 110 case 'media': // media file revision 111 return media_printicon($id); 112 case 'page': // page revision 113 return '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />'; 114 } 115 } 116 117 /** 118 * edit date and time of the page or media file 119 * used in [Ui\recent, Ui\Revisions] 120 * 121 * @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false 122 * @return string 123 */ 124 public function showEditDate($checkTimestamp = false) 125 { 126 $formatted = dformat($this->val('date')); 127 if ($checkTimestamp && $this->val('timestamp') === false) { 128 // exact date is unknown for externally deleted file 129 // when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__" 130 $formatted = preg_replace('/[0-9a-zA-Z]/','_', $formatted); 131 } 132 return '<span class="date">'. $formatted .'</span>'; 133 } 134 135 /** 136 * edit summary 137 * used in [Ui\recent, Ui\Revisions] 138 * 139 * @return string 140 */ 141 public function showEditSummary() 142 { 143 return '<span class="sum">'.' – '. hsc($this->val('sum')).'</span>'; 144 } 145 146 /** 147 * editor of the page or media file 148 * used in [Ui\recent, Ui\Revisions] 149 * 150 * @return string 151 */ 152 public function showEditor() 153 { 154 if ($this->val('user')) { 155 $html = '<bdi>'. editorinfo($this->val('user')) .'</bdi>'; 156 if (auth_ismanager()) $html .= ' <bdo dir="ltr">('. $this->val('ip') .')</bdo>'; 157 } else { 158 $html = '<bdo dir="ltr">'. $this->val('ip') .'</bdo>'; 159 } 160 return '<span class="user">'. $html. '</span>'; 161 } 162 163 /** 164 * name of the page or media file 165 * used in [Ui\recent, Ui\Revisions] 166 * 167 * @return string 168 */ 169 public function showFileName() 170 { 171 $id = $this->val('id'); 172 $rev = $this->isCurrent() ? '' : $this->val('date'); 173 174 switch ($this->val('mode')) { 175 case 'media': // media file revision 176 $params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id]; 177 if ($rev) $params += ['rev'=> $rev]; 178 $href = media_managerURL($params, '&'); 179 $display_name = $id; 180 $exists = file_exists(mediaFN($id, $rev)); 181 break; 182 case 'page': // page revision 183 $params = $rev ? ['rev'=> $rev] : []; 184 $href = wl($id, $params, false, '&'); 185 $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; 186 if (!$display_name) $display_name = $id; 187 $exists = page_exists($id, $rev); 188 } 189 190 if($exists) { 191 $class = 'wikilink1'; 192 } else { 193 if($this->isCurrent()) { 194 //show only not-existing link for current page, which allows for directly create a new page/upload 195 $class = 'wikilink2'; 196 } else { 197 //revision is not in attic 198 return $display_name; 199 } 200 } 201 if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) { 202 $class = 'wikilink2'; 203 } 204 return '<a href="'.$href.'" class="'.$class.'">'.$display_name.'</a>'; 205 } 206 207 /** 208 * Revision Title for PageDiff table headline 209 * 210 * @return string 211 */ 212 public function showRevisionTitle() 213 { 214 global $lang; 215 216 if (!$this->val('date')) return '—'; 217 218 $id = $this->val('id'); 219 $rev = $this->isCurrent() ? '' : $this->val('date'); 220 $params = ($rev) ? ['rev'=> $rev] : []; 221 222 // revision info may have timestamp key when external edits occurred 223 $date = ($this->val('timestamp') === false) 224 ? $lang['unknowndate'] 225 : dformat($this->val('date')); 226 227 228 switch ($this->val('mode')) { 229 case 'media': // media file revision 230 $href = ml($id, $params, false, '&'); 231 $exists = file_exists(mediaFN($id, $rev)); 232 break; 233 case 'page': // page revision 234 $href = wl($id, $params, false, '&'); 235 $exists = page_exists($id, $rev); 236 } 237 if($exists) { 238 $class = 'wikilink1'; 239 } else { 240 if($this->isCurrent()) { 241 //show only not-existing link for current page, which allows for directly create a new page/upload 242 $class = 'wikilink2'; 243 } else { 244 //revision is not in attic 245 return $id.' ['.$date.']'; 246 } 247 } 248 if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) { 249 $class = 'wikilink2'; 250 } 251 return '<bdi><a class="'.$class.'" href="'.$href.'">'.$id.' ['.$date.']'.'</a></bdi>'; 252 } 253 254 /** 255 * diff link icon in recent changes list, to compare (this) current revision with previous one 256 * all items in "recent changes" are current revision of the page or media 257 * 258 * @return string 259 */ 260 public function showIconCompareWithPrevious() 261 { 262 global $lang; 263 $id = $this->val('id'); 264 265 $href = ''; 266 switch ($this->val('mode')) { 267 case 'media': // media file revision 268 // unlike page, media file does not copied to media_attic when uploaded. 269 // diff icon will not be shown when external edit occurred 270 // because no attic file to be compared with current. 271 $revs = (new MediaChangeLog($id))->getRevisions(0, 1); 272 $showLink = (count($revs) && file_exists(mediaFN($id,$revs[0])) && file_exists(mediaFN($id))); 273 if ($showLink) { 274 $param = ['tab_details'=>'history', 'mediado'=>'diff', 'ns'=> getNS($id), 'image'=> $id]; 275 $href = media_managerURL($param, '&'); 276 } 277 break; 278 case 'page': // page revision 279 // when a page just created anyway, it is natural to expect no older revisions 280 // even if it had once existed but deleted before. Simply ignore to check changelog. 281 if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE) { 282 $href = wl($id, ['do'=>'diff'], false, '&'); 283 } 284 } 285 286 if ($href) { 287 return '<a href="'.$href.'" class="diff_link">' 288 .'<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 289 .' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' 290 .'</a>'; 291 } else { 292 return '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 293 } 294 } 295 296 /** 297 * diff link icon in revisions list, compare this revision with current one 298 * the icon does not displayed for the current revision 299 * 300 * @return string 301 */ 302 public function showIconCompareWithCurrent() 303 { 304 global $lang; 305 $id = $this->val('id'); 306 $rev = $this->isCurrent() ? '' : $this->val('date'); 307 308 $href = ''; 309 switch ($this->val('mode')) { 310 case 'media': // media file revision 311 if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) { 312 $param = ['mediado'=>'diff', 'image'=> $id, 'rev'=> $rev]; 313 $href = media_managerURL($param, '&'); 314 } 315 break; 316 case 'page': // page revision 317 if (!$this->isCurrent()) { 318 $href = wl($id, ['rev'=> $rev, 'do'=>'diff'], false, '&'); 319 } 320 } 321 322 if ($href) { 323 return '<a href="'.$href.'" class="diff_link">' 324 .'<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 325 .' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' 326 .'</a>'; 327 } else { 328 return '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 329 } 330 } 331 332 /** 333 * icon for revision action 334 * used in [Ui\recent] 335 * 336 * @return string 337 */ 338 public function showIconRevisions() 339 { 340 global $lang; 341 342 if (!actionOK('revisions')) { 343 return ''; 344 } 345 346 $id = $this->val('id'); 347 switch ($this->val('mode')) { 348 case 'media': // media file revision 349 $param = ['tab_details'=>'history', 'ns'=> getNS($id), 'image'=> $id]; 350 $href = media_managerURL($param, '&'); 351 break; 352 case 'page': // page revision 353 $href = wl($id, ['do'=>'revisions'], false, '&'); 354 } 355 return '<a href="'.$href.'" class="revisions_link">' 356 . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"' 357 . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />' 358 . '</a>'; 359 } 360 361 /** 362 * size change 363 * used in [Ui\recent, Ui\Revisions] 364 * 365 * @return string 366 */ 367 public function showSizeChange() 368 { 369 $class = 'sizechange'; 370 $value = filesize_h(abs($this->val('sizechange'))); 371 if ($this->val('sizechange') > 0) { 372 $class .= ' positive'; 373 $value = '+' . $value; 374 } elseif ($this->val('sizechange') < 0) { 375 $class .= ' negative'; 376 $value = '-' . $value; 377 } else { 378 $value = '±' . $value; 379 } 380 return '<span class="'.$class.'">'.$value.'</span>'; 381 } 382 383 /** 384 * current indicator, used in revision list 385 * not used in Ui\Recent because recent files are always current one 386 * 387 * @return string 388 */ 389 public function showCurrentIndicator() 390 { 391 global $lang; 392 return $this->isCurrent() ? '('.$lang['current'].')' : ''; 393 } 394 395 396 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body