[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Changelog handling functions 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9 use dokuwiki\ChangeLog\ChangeLog; 10 use dokuwiki\File\PageFile; 11 12 /** 13 * parses a changelog line into it's components 14 * 15 * @author Ben Coburn <btcoburn@silicodon.net> 16 * 17 * @param string $line changelog line 18 * @return array|bool parsed line or false 19 */ 20 function parseChangelogLine($line) { 21 return ChangeLog::parseLogLine($line); 22 } 23 24 /** 25 * Adds an entry to the changelog and saves the metadata for the page 26 * 27 * Note: timestamp of the change might not be unique especially after very quick 28 * repeated edits (e.g. change checkbox via do plugin) 29 * 30 * @param int $date Timestamp of the change 31 * @param String $id Name of the affected page 32 * @param String $type Type of the change see DOKU_CHANGE_TYPE_* 33 * @param String $summary Summary of the change 34 * @param mixed $extra In case of a revert the revision (timestamp) of the reverted page 35 * @param array $flags Additional flags in a key value array. 36 * Available flags: 37 * - ExternalEdit - mark as an external edit. 38 * @param null|int $sizechange Change of filesize 39 * 40 * @author Andreas Gohr <andi@splitbrain.org> 41 * @author Esther Brunner <wikidesign@gmail.com> 42 * @author Ben Coburn <btcoburn@silicodon.net> 43 * @deprecated 2021-11-28 44 */ 45 function addLogEntry( 46 $date, 47 $id, 48 $type = DOKU_CHANGE_TYPE_EDIT, 49 $summary = '', 50 $extra = '', 51 $flags = null, 52 $sizechange = null) 53 { 54 // no more used in DokuWiki core, but left for third-party plugins 55 dbg_deprecated('see '. PageFile::class .'::saveWikiText()'); 56 57 /** @var Input $INPUT */ 58 global $INPUT; 59 60 // check for special flags as keys 61 if (!is_array($flags)) $flags = array(); 62 $flagExternalEdit = isset($flags['ExternalEdit']); 63 64 $id = cleanid($id); 65 66 if (!$date) $date = time(); //use current time if none supplied 67 $remote = (!$flagExternalEdit) ? clientIP(true) : '127.0.0.1'; 68 $user = (!$flagExternalEdit) ? $INPUT->server->str('REMOTE_USER') : ''; 69 $sizechange = ($sizechange === null) ? '' : (int)$sizechange; 70 71 // update changelog file and get the added entry that is also to be stored in metadata 72 $pageFile = new PageFile($id); 73 $logEntry = $pageFile->changelog->addLogEntry([ 74 'date' => $date, 75 'ip' => $remote, 76 'type' => $type, 77 'id' => $id, 78 'user' => $user, 79 'sum' => $summary, 80 'extra' => $extra, 81 'sizechange' => $sizechange, 82 ]); 83 84 // update metadata 85 $pageFile->updateMetadata($logEntry); 86 } 87 88 /** 89 * Adds an entry to the media changelog 90 * 91 * @author Michael Hamann <michael@content-space.de> 92 * @author Andreas Gohr <andi@splitbrain.org> 93 * @author Esther Brunner <wikidesign@gmail.com> 94 * @author Ben Coburn <btcoburn@silicodon.net> 95 * 96 * @param int $date Timestamp of the change 97 * @param String $id Name of the affected page 98 * @param String $type Type of the change see DOKU_CHANGE_TYPE_* 99 * @param String $summary Summary of the change 100 * @param mixed $extra In case of a revert the revision (timestamp) of the reverted page 101 * @param array $flags Additional flags in a key value array. 102 * Available flags: 103 * - (none, so far) 104 * @param null|int $sizechange Change of filesize 105 */ 106 function addMediaLogEntry( 107 $date, 108 $id, 109 $type = DOKU_CHANGE_TYPE_EDIT, 110 $summary = '', 111 $extra = '', 112 $flags = null, 113 $sizechange = null) 114 { 115 /** @var Input $INPUT */ 116 global $INPUT; 117 118 // check for special flags as keys 119 if (!is_array($flags)) $flags = array(); 120 $flagExternalEdit = isset($flags['ExternalEdit']); 121 122 $id = cleanid($id); 123 124 if (!$date) $date = time(); //use current time if none supplied 125 $remote = (!$flagExternalEdit) ? clientIP(true) : '127.0.0.1'; 126 $user = (!$flagExternalEdit) ? $INPUT->server->str('REMOTE_USER') : ''; 127 $sizechange = ($sizechange === null) ? '' : (int)$sizechange; 128 129 // update changelog file and get the added entry 130 (new \dokuwiki\ChangeLog\MediaChangeLog($id, 1024))->addLogEntry([ 131 'date' => $date, 132 'ip' => $remote, 133 'type' => $type, 134 'id' => $id, 135 'user' => $user, 136 'sum' => $summary, 137 'extra' => $extra, 138 'sizechange' => $sizechange, 139 ]); 140 } 141 142 /** 143 * returns an array of recently changed files using the changelog 144 * 145 * The following constants can be used to control which changes are 146 * included. Add them together as needed. 147 * 148 * RECENTS_SKIP_DELETED - don't include deleted pages 149 * RECENTS_SKIP_MINORS - don't include minor changes 150 * RECENTS_ONLY_CREATION - only include new created pages and media 151 * RECENTS_SKIP_SUBSPACES - don't include subspaces 152 * RECENTS_MEDIA_CHANGES - return media changes instead of page changes 153 * RECENTS_MEDIA_PAGES_MIXED - return both media changes and page changes 154 * 155 * @param int $first number of first entry returned (for paginating 156 * @param int $num return $num entries 157 * @param string $ns restrict to given namespace 158 * @param int $flags see above 159 * @return array recently changed files 160 * 161 * @author Ben Coburn <btcoburn@silicodon.net> 162 * @author Kate Arzamastseva <pshns@ukr.net> 163 */ 164 function getRecents($first, $num, $ns = '', $flags = 0) { 165 global $conf; 166 $recent = array(); 167 $count = 0; 168 169 if (!$num) 170 return $recent; 171 172 // read all recent changes. (kept short) 173 if ($flags & RECENTS_MEDIA_CHANGES) { 174 $lines = @file($conf['media_changelog']) ?: []; 175 } else { 176 $lines = @file($conf['changelog']) ?: []; 177 } 178 if (!is_array($lines)) { 179 $lines = array(); 180 } 181 $lines_position = count($lines) - 1; 182 $media_lines_position = 0; 183 $media_lines = array(); 184 185 if ($flags & RECENTS_MEDIA_PAGES_MIXED) { 186 $media_lines = @file($conf['media_changelog']) ?: []; 187 if (!is_array($media_lines)) { 188 $media_lines = array(); 189 } 190 $media_lines_position = count($media_lines) - 1; 191 } 192 193 $seen = array(); // caches seen lines, _handleRecent() skips them 194 195 // handle lines 196 while ($lines_position >= 0 || (($flags & RECENTS_MEDIA_PAGES_MIXED) && $media_lines_position >= 0)) { 197 if (empty($rec) && $lines_position >= 0) { 198 $rec = _handleRecent(@$lines[$lines_position], $ns, $flags, $seen); 199 if (!$rec) { 200 $lines_position --; 201 continue; 202 } 203 } 204 if (($flags & RECENTS_MEDIA_PAGES_MIXED) && empty($media_rec) && $media_lines_position >= 0) { 205 $media_rec = _handleRecent( 206 @$media_lines[$media_lines_position], 207 $ns, 208 $flags | RECENTS_MEDIA_CHANGES, 209 $seen 210 ); 211 if (!$media_rec) { 212 $media_lines_position --; 213 continue; 214 } 215 } 216 if (($flags & RECENTS_MEDIA_PAGES_MIXED) && @$media_rec['date'] >= @$rec['date']) { 217 $media_lines_position--; 218 $x = $media_rec; 219 $x['media'] = true; 220 $media_rec = false; 221 } else { 222 $lines_position--; 223 $x = $rec; 224 if ($flags & RECENTS_MEDIA_CHANGES){ 225 $x['media'] = true; 226 } else { 227 $x['media'] = false; 228 } 229 $rec = false; 230 } 231 if (--$first >= 0) continue; // skip first entries 232 $recent[] = $x; 233 $count++; 234 // break when we have enough entries 235 if ($count >= $num) { break; } 236 } 237 return $recent; 238 } 239 240 /** 241 * returns an array of files changed since a given time using the 242 * changelog 243 * 244 * The following constants can be used to control which changes are 245 * included. Add them together as needed. 246 * 247 * RECENTS_SKIP_DELETED - don't include deleted pages 248 * RECENTS_SKIP_MINORS - don't include minor changes 249 * RECENTS_ONLY_CREATION - only include new created pages and media 250 * RECENTS_SKIP_SUBSPACES - don't include subspaces 251 * RECENTS_MEDIA_CHANGES - return media changes instead of page changes 252 * 253 * @param int $from date of the oldest entry to return 254 * @param int $to date of the newest entry to return (for pagination, optional) 255 * @param string $ns restrict to given namespace (optional) 256 * @param int $flags see above (optional) 257 * @return array of files 258 * 259 * @author Michael Hamann <michael@content-space.de> 260 * @author Ben Coburn <btcoburn@silicodon.net> 261 */ 262 function getRecentsSince($from, $to = null, $ns = '', $flags = 0) { 263 global $conf; 264 $recent = array(); 265 266 if ($to && $to < $from) 267 return $recent; 268 269 // read all recent changes. (kept short) 270 if ($flags & RECENTS_MEDIA_CHANGES) { 271 $lines = @file($conf['media_changelog']); 272 } else { 273 $lines = @file($conf['changelog']); 274 } 275 if (!$lines) return $recent; 276 277 // we start searching at the end of the list 278 $lines = array_reverse($lines); 279 280 // handle lines 281 $seen = array(); // caches seen lines, _handleRecent() skips them 282 283 foreach ($lines as $line) { 284 $rec = _handleRecent($line, $ns, $flags, $seen); 285 if ($rec !== false) { 286 if ($rec['date'] >= $from) { 287 if (!$to || $rec['date'] <= $to) { 288 $recent[] = $rec; 289 } 290 } else { 291 break; 292 } 293 } 294 } 295 296 return array_reverse($recent); 297 } 298 299 /** 300 * Internal function used by getRecents 301 * 302 * don't call directly 303 * 304 * @see getRecents() 305 * @author Andreas Gohr <andi@splitbrain.org> 306 * @author Ben Coburn <btcoburn@silicodon.net> 307 * 308 * @param string $line changelog line 309 * @param string $ns restrict to given namespace 310 * @param int $flags flags to control which changes are included 311 * @param array $seen listing of seen pages 312 * @return array|bool false or array with info about a change 313 */ 314 function _handleRecent($line, $ns, $flags, &$seen) { 315 if (empty($line)) return false; //skip empty lines 316 317 // split the line into parts 318 $recent = ChangeLog::parseLogLine($line); 319 if ($recent === false) return false; 320 321 // skip seen ones 322 if (isset($seen[$recent['id']])) return false; 323 324 // skip changes, of only new items are requested 325 if ($recent['type'] !== DOKU_CHANGE_TYPE_CREATE && ($flags & RECENTS_ONLY_CREATION)) return false; 326 327 // skip minors 328 if ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT && ($flags & RECENTS_SKIP_MINORS)) return false; 329 330 // remember in seen to skip additional sights 331 $seen[$recent['id']] = 1; 332 333 // check if it's a hidden page 334 if (isHiddenPage($recent['id'])) return false; 335 336 // filter namespace 337 if (($ns) && (strpos($recent['id'], $ns.':') !== 0)) return false; 338 339 // exclude subnamespaces 340 if (($flags & RECENTS_SKIP_SUBSPACES) && (getNS($recent['id']) != $ns)) return false; 341 342 // check ACL 343 if ($flags & RECENTS_MEDIA_CHANGES) { 344 $recent['perms'] = auth_quickaclcheck(getNS($recent['id']).':*'); 345 } else { 346 $recent['perms'] = auth_quickaclcheck($recent['id']); 347 } 348 if ($recent['perms'] < AUTH_READ) return false; 349 350 // check existence 351 if ($flags & RECENTS_SKIP_DELETED) { 352 $fn = (($flags & RECENTS_MEDIA_CHANGES) ? mediaFN($recent['id']) : wikiFN($recent['id'])); 353 if (!file_exists($fn)) return false; 354 } 355 356 return $recent; 357 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body