1<?php 2 3namespace dokuwiki\ChangeLog; 4 5/** 6 * Class RevisionInfo 7 * 8 * Provides methods to show Revision Information in DokuWiki Ui compoments: 9 * - Ui\Recent 10 * - Ui\PageRevisions 11 * - Ui\MediaRevisions 12 */ 13class RevisionInfo 14{ 15 protected $info; 16 17 /** 18 * Constructor 19 * 20 * @param array $info Revision Infomation structure with entries: 21 * - date: unix timestamp 22 * - ip: IPv4 or IPv6 address 23 * - type: change type (log line type) 24 * - id: page id 25 * - user: user name 26 * - sum: edit summary (or action reason) 27 * - extra: extra data (varies by line type) 28 * - sizechange: change of filesize 29 * additionally, 30 * - current: (optional) whether current revison or not 31 * - timestamp: (optional) set only when external edits occurred 32 */ 33 public function __construct(array $info) 34 { 35 $info['item'] = strrpos($info['id'], '.') ? 'media' : 'page'; 36 // current is always true for irems shown in Ui\Recents 37 $info['current'] = $info['current'] ?? true; 38 // revision info may have timestamp key when external edits occurred 39 $info['timestamp'] = $info['timestamp'] ?? true; 40 41 $this->info = $info; 42 } 43 44 /** 45 * fileicon of the page or media file 46 * used in [Ui\recent] 47 * 48 * @return string 49 */ 50 public function itemIcon() 51 { 52 $id = $this->info['id']; 53 $html = ''; 54 switch ($this->info['item']) { 55 case 'media': // media file revision 56 $html = media_printicon($id); 57 break; 58 case 'page': // page revision 59 $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />'; 60 } 61 return $html; 62 } 63 64 /** 65 * edit date and time of the page or media file 66 * used in [Ui\recent, Ui\Revisions] 67 * 68 * @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false 69 * @return string 70 */ 71 public function editDate($checkTimestamp = false) 72 { 73 $formatted = dformat($this->info['date']); 74 if ($checkTimestamp && $this->info['timestamp'] === false) { 75 // exact date is unknown for item has externally deleted or older file restored 76 // when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__" 77 $formatted = preg_replace('/[0-9a-zA-Z]/','_', $formatted); 78 } 79 return '<span class="date">'. $formatted .'</span>'; 80 } 81 82 /** 83 * edit summary 84 * used in [Ui\recent, Ui\Revisions] 85 * 86 * @return string 87 */ 88 public function editSummary() 89 { 90 return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>'; 91 } 92 93 /** 94 * editor of the page or media file 95 * used in [Ui\recent, Ui\Revisions] 96 * 97 * @return string 98 */ 99 public function editor() 100 { 101 $html = '<span class="user">'; 102 if ($this->info['user']) { 103 $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>'; 104 if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>'; 105 } else { 106 $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>'; 107 } 108 $html.= '</span>'; 109 return $html; 110 } 111 112 /** 113 * name of the page or media file 114 * used in [Ui\recent, Ui\Revisions] 115 * 116 * @return string 117 */ 118 public function itemName() 119 { 120 $id = $this->info['id']; 121 $rev = ($this->info['current']) ? '' : $this->info['date']; 122 123 switch ($this->info['item']) { 124 case 'media': // media file revision 125 $params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id]; 126 if ($rev) $params += ['rev'=> $rev]; 127 $href = media_managerURL($params, '&'); 128 $class = file_exists(mediaFN($id, $rev)) ? 'wikilink1' : 'wikilink2'; 129 return '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>'; 130 case 'page': // page revision 131 $params = $rev ? ['rev'=> $rev] : []; 132 $href = wl($id, $params, false, '&'); 133 $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; 134 if (!$display_name) $display_name = $id; 135 $class = page_exists($id, $rev) ? 'wikilink1' : 'wikilink2'; 136 if ($this->info['type'] == DOKU_CHANGE_TYPE_DELETE) { 137 $class = 'wikilink2'; 138 } 139 return '<a href="'.$href.'" class="'.$class.'">'.$display_name.'</a>'; 140 } 141 142 return ''; 143 } 144 145 /** 146 * difflink icon in recents list 147 * all items in the recents are "current" revision of the page or media 148 * 149 * @return string 150 */ 151 public function difflinkRecent() 152 { 153 global $lang; 154 $id = $this->info['id']; 155 156 $href = ''; 157 switch ($this->info['item']) { 158 case 'media': // media file revision 159 $revs = (new MediaChangeLog($id))->getRevisions(0, 1); 160 $showLink = (count($revs) && file_exists(mediaFN($id))); 161 if ($showLink) { 162 $href = media_managerURL( 163 ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&' 164 ); 165 } 166 break; 167 case 'page': // page revision 168 if($this->info['type'] !== DOKU_CHANGE_TYPE_CREATE) { 169 $href = wl($id, "do=diff", false, '&'); 170 } 171 } 172 173 if ($href) { 174 $html = '<a href="'.$href.'" class="diff_link">' 175 . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 176 . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />' 177 . '</a>'; 178 } else { 179 $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 180 } 181 return $html; 182 } 183 184 /** 185 * difflink icon in revsions list 186 * the icon does not displayed for the current revision 187 * 188 * @return string 189 */ 190 public function difflinkRevision() 191 { 192 global $lang; 193 $id = $this->info['id']; 194 $rev = $this->info['date']; 195 196 switch ($this->info['item']) { 197 case 'media': // media file revision 198 if ($this->info['current'] || !file_exists(mediaFN($id, $rev))) { 199 $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 200 } else { 201 $href = media_managerURL(['image'=> $id, 'rev'=> $rev, 'mediado'=>'diff'], '&'); 202 $html = '<a href="'.$href.'" class="diff_link">' 203 . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 204 . ' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' 205 . '</a> '; 206 } 207 return $html; 208 case 'page': // page revision 209 if ($this->info['current'] || !page_exists($id, $rev)) { 210 $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 211 } else { 212 $href = wl($id, "rev=$rev,do=diff", false, '&'); 213 $html = '<a href="'.$href.'" class="diff_link">' 214 . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 215 . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />' 216 . '</a>'; 217 } 218 return $html; 219 } 220 return ''; 221 } 222 223 /** 224 * icon revision link 225 * used in [Ui\recent] 226 * 227 * @return string 228 */ 229 public function revisionlink() 230 { 231 global $lang; 232 233 if (!actionOK('revisions')) { 234 return ''; //FIXME check page, media 235 } 236 237 $id = $this->info['id']; 238 $href = ''; 239 switch ($this->info['item']) { 240 case 'media': // media file revision 241 $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&'); 242 break; 243 case 'page': // page revision 244 $href = wl($id, "do=revisions", false, '&'); 245 } 246 return '<a href="'.$href.'" class="revisions_link">' 247 . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"' 248 . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />' 249 . '</a>'; 250 } 251 252 /** 253 * size change 254 * used in [Ui\recent, Ui\Revisions] 255 * 256 * @return string 257 */ 258 public function sizeChange() 259 { 260 $class = 'sizechange'; 261 $value = filesize_h(abs($this->info['sizechange'])); 262 if ($this->info['sizechange'] > 0) { 263 $class .= ' positive'; 264 $value = '+' . $value; 265 } elseif ($this->info['sizechange'] < 0) { 266 $class .= ' negative'; 267 $value = '-' . $value; 268 } else { 269 $value = '±' . $value; 270 } 271 return '<span class="'.$class.'">'.$value.'</span>'; 272 } 273 274 /** 275 * current indicator, used in revison list 276 * not used in Ui\Recents because recent items are always current one 277 * 278 * @return string 279 */ 280 public function currentIndicator() 281 { 282 global $lang; 283 return ($this->info['current']) ? '('.$lang['current'].')' : ''; 284 } 285 286 287} 288