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 switch ($this->info['item']) { 54 case 'media': // media file revision 55 $html = media_printicon($id); 56 break; 57 case 'page': // page revision 58 $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />'; 59 } 60 return $html; 61 } 62 63 /** 64 * edit date and time of the page or media file 65 * used in [Ui\recent, Ui\Revisions] 66 * 67 * @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false 68 * @return string 69 */ 70 public function editDate($checkTimestamp = false) 71 { 72 global $lang; 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 global $lang; 102 $html = '<span class="user">'; 103 if ($this->info['user']) { 104 $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>'; 105 if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>'; 106 } else { 107 $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>'; 108 } 109 $html.= '</span>'; 110 return $html; 111 } 112 113 /** 114 * name of the page or media file 115 * used in [Ui\recent, Ui\Revisions] 116 * 117 * @return string 118 */ 119 public function itemName() 120 { 121 $id = $this->info['id']; 122 $rev = ($this->info['current']) ? '' : $this->info['date']; 123 124 switch ($this->info['item']) { 125 case 'media': // media file revision 126 $params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id]; 127 if ($rev) $params += ['rev'=> $rev]; 128 $href = media_managerURL($params, '&'); 129 $class = file_exists(mediaFN($id, $rev)) ? 'wikilink1' : 'wikilink2'; 130 return '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>'; 131 case 'page': // page revision 132 $params = ($rev) ? '' : "rev=$rev"; 133 $href = wl($id, $params, false, '&'); 134 $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; 135 if (!$display_name) $display_name = $id; 136 $class = page_exists($id, $rev) ? 'wikilink1' : 'wikilink2'; 137 if ($this->info['type'] == DOKU_CHANGE_TYPE_DELETE) { 138 $class = 'wikilink2'; 139 } 140 return '<a href="'.$href.'" class="'.$class.'">'.$display_name.'</a>'; 141 } 142 } 143 144 /** 145 * difflink icon in recents list 146 * all items in the recents are "current" revision of the page or media 147 * 148 * @return string 149 */ 150 public function difflinkRecent() 151 { 152 global $lang; 153 $id = $this->info['id']; 154 155 $href = ''; 156 switch ($this->info['item']) { 157 case 'media': // media file revision 158 $revs = (new MediaChangeLog($id))->getRevisions(0, 1); 159 $showLink = (count($revs) && file_exists(mediaFN($id))); 160 if ($showLink) { 161 $href = media_managerURL( 162 ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&' 163 ); 164 } 165 break; 166 case 'page': // page revision 167 if($this->info['type'] !== DOKU_CHANGE_TYPE_CREATE) { 168 $href = wl($id, "do=diff", false, '&'); 169 } 170 } 171 172 if ($href) { 173 $html = '<a href="'.$href.'" class="diff_link">' 174 . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 175 . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />' 176 . '</a>'; 177 } else { 178 $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 179 } 180 return $html; 181 } 182 183 /** 184 * difflink icon in revsions list 185 * the icon does not displayed for the current revision 186 * 187 * @return string 188 */ 189 public function difflinkRevision() 190 { 191 global $lang; 192 $id = $this->info['id']; 193 $rev = $this->info['date']; 194 195 switch ($this->info['item']) { 196 case 'media': // media file revision 197 if ($this->info['current'] || !file_exists(mediaFN($id, $rev))) { 198 $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 199 } else { 200 $href = media_managerURL(['image'=> $id, 'rev'=> $rev, 'mediado'=>'diff'], '&'); 201 $html = '<a href="'.$href.'" class="diff_link">' 202 . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 203 . ' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' 204 . '</a> '; 205 } 206 return $html; 207 case 'page': // page revision 208 if ($this->info['current'] || !page_exists($id, $rev)) { 209 $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; 210 } else { 211 $href = wl($id, "rev=$rev,do=diff", false, '&'); 212 $html = '<a href="'.$href.'" class="diff_link">' 213 . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' 214 . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />' 215 . '</a>'; 216 } 217 return $html; 218 } 219 return ''; 220 } 221 222 /** 223 * icon revision link 224 * used in [Ui\recent] 225 * 226 * @return string 227 */ 228 public function revisionlink() 229 { 230 global $lang, $conf; 231 232 if (!actionOK('revisions')) { 233 return ''; //FIXME check page, media 234 } 235 236 $id = $this->info['id']; 237 switch ($this->info['item']) { 238 case 'media': // media file revision 239 $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&'); 240 break; 241 case 'page': // page revision 242 $href = wl($id, "do=revisions", false, '&'); 243 } 244 return '<a href="'.$href.'" class="revisions_link">' 245 . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"' 246 . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />' 247 . '</a>'; 248 } 249 250 /** 251 * size change 252 * used in [Ui\recent, Ui\Revisions] 253 * 254 * @return string 255 */ 256 public function sizeChange() 257 { 258 $class = 'sizechange'; 259 $value = filesize_h(abs($this->info['sizechange'])); 260 if ($this->info['sizechange'] > 0) { 261 $class .= ' positive'; 262 $value = '+' . $value; 263 } elseif ($this->info['sizechange'] < 0) { 264 $class .= ' negative'; 265 $value = '-' . $value; 266 } else { 267 $value = '±' . $value; 268 } 269 return '<span class="'.$class.'">'.$value.'</span>'; 270 } 271 272 /** 273 * current indicator, used in revison list 274 * not used in Ui\Recents because recent items are always current one 275 * 276 * @return string 277 */ 278 public function currentIndicator() 279 { 280 global $lang; 281 return ($this->info['current']) ? '('.$lang['current'].')' : ''; 282 } 283 284 285} 286