function getNumberingNextNumber($db, $start) { io_lock($db); $ar = unserialize(io_readFile($db, false)); if (!$ar) { $ar['saved'] = $start; $ar['start'] = $start; } else { $number = $ar['saved']; if ($ar['start'] != $start) { $ar['start'] = $start; $number = $start; } else { $number = $ar['saved']; } } if ($number < $start) { $number = $start - 1; } $ar['saved'] = ++$number; file_put_contents($db, serialize($ar)); io_unlock($db); return "{$number}"; }
/** * Trims the recent changes cache (or imports the old changelog) as needed. * * @param media_changes If the media changelog shall be trimmed instead of * the page changelog * * @author Ben Coburn <*****@*****.**> */ function runTrimRecentChanges($media_changes = false) { global $conf; echo "runTrimRecentChanges({$media_changes}): started" . NL; $fn = $media_changes ? $conf['media_changelog'] : $conf['changelog']; // Trim the Recent Changes // Trims the recent changes cache to the last $conf['changes_days'] recent // changes or $conf['recent'] items, which ever is larger. // The trimming is only done once a day. if (@file_exists($fn) && @filemtime($fn . '.trimmed') + 86400 < time() && !@file_exists($fn . '_tmp')) { @touch($fn . '.trimmed'); io_lock($fn); $lines = file($fn); if (count($lines) <= $conf['recent']) { // nothing to trim io_unlock($fn); echo "runTrimRecentChanges({$media_changes}): finished" . NL; return false; } io_saveFile($fn . '_tmp', ''); // presave tmp as 2nd lock $trim_time = time() - $conf['recent_days'] * 86400; $out_lines = array(); for ($i = 0; $i < count($lines); $i++) { $log = parseChangelogLine($lines[$i]); if ($log === false) { continue; } // discard junk if ($log['date'] < $trim_time) { $old_lines[$log['date'] . ".{$i}"] = $lines[$i]; // keep old lines for now (append .$i to prevent key collisions) } else { $out_lines[$log['date'] . ".{$i}"] = $lines[$i]; // definitely keep these lines } } if (count($lines) == count($out_lines)) { // nothing to trim @unlink($fn . '_tmp'); io_unlock($fn); echo "runTrimRecentChanges({$media_changes}): finished" . NL; return false; } // sort the final result, it shouldn't be necessary, // however the extra robustness in making the changelog cache self-correcting is worth it ksort($out_lines); $extra = $conf['recent'] - count($out_lines); // do we need extra lines do bring us up to minimum if ($extra > 0) { ksort($old_lines); $out_lines = array_merge(array_slice($old_lines, -$extra), $out_lines); } // save trimmed changelog io_saveFile($fn . '_tmp', implode('', $out_lines)); @unlink($fn); if (!rename($fn . '_tmp', $fn)) { // rename failed so try another way... io_unlock($fn); io_saveFile($fn, implode('', $out_lines)); @unlink($fn . '_tmp'); } else { io_unlock($fn); } echo "runTrimRecentChanges({$media_changes}): finished" . NL; return true; } // nothing done echo "runTrimRecentChanges({$media_changes}): finished" . NL; return false; }
/** * Delete exact linematch for $badline from $file. * * Be sure to include the trailing newline in $badline * * Uses gzip if extension is .gz * * 2005-10-14 : added regex option -- Christopher Smith <*****@*****.**> * * @author Steven Danz <*****@*****.**> * @return bool true on success */ function io_deleteFromFile($file, $badline, $regex = false) { if (!@file_exists($file)) { return true; } io_lock($file); // load into array if (substr($file, -3) == '.gz') { $lines = gzfile($file); } else { $lines = file($file); } // remove all matching lines if ($regex) { $lines = preg_grep($badline, $lines, PREG_GREP_INVERT); } else { $pos = array_search($badline, $lines); //return null or false if not found while (is_int($pos)) { unset($lines[$pos]); $pos = array_search($badline, $lines); } } if (count($lines)) { $content = join('', $lines); if (substr($file, -3) == '.gz') { $fh = @gzopen($file, 'wb9'); if (!$fh) { msg("Removing content from {$file} failed", -1); io_unlock($file); return false; } gzwrite($fh, $content); gzclose($fh); } else { $fh = @fopen($file, 'wb'); if (!$fh) { msg("Removing content from {$file} failed", -1); io_unlock($file); return false; } fwrite($fh, $content); fclose($fh); } } else { @unlink($file); } io_unlock($file); return true; }
/** * Trims the recent comments cache to the last $conf['changes_days'] recent * changes or $conf['recent'] items, which ever is larger. * The trimming is only done once a day. * * @author Ben Coburn <*****@*****.**> */ function _trimRecentCommentsLog($changelog) { global $conf; if (@file_exists($changelog) && filectime($changelog) + 86400 < time() && !@file_exists($changelog . '_tmp')) { io_lock($changelog); $lines = file($changelog); if (count($lines) < $conf['recent']) { // nothing to trim io_unlock($changelog); return true; } io_saveFile($changelog . '_tmp', ''); // presave tmp as 2nd lock $trim_time = time() - $conf['recent_days'] * 86400; $out_lines = array(); $num = count($lines); for ($i = 0; $i < $num; $i++) { $log = parseChangelogLine($lines[$i]); if ($log === false) { continue; } // discard junk if ($log['date'] < $trim_time) { $old_lines[$log['date'] . ".{$i}"] = $lines[$i]; // keep old lines for now (append .$i to prevent key collisions) } else { $out_lines[$log['date'] . ".{$i}"] = $lines[$i]; // definitely keep these lines } } // sort the final result, it shouldn't be necessary, // however the extra robustness in making the changelog cache self-correcting is worth it ksort($out_lines); $extra = $conf['recent'] - count($out_lines); // do we need extra lines do bring us up to minimum if ($extra > 0) { ksort($old_lines); $out_lines = array_merge(array_slice($old_lines, -$extra), $out_lines); } // save trimmed changelog io_saveFile($changelog . '_tmp', implode('', $out_lines)); @unlink($changelog); if (!rename($changelog . '_tmp', $changelog)) { // rename failed so try another way... io_unlock($changelog); io_saveFile($changelog, implode('', $out_lines)); @unlink($changelog . '_tmp'); } else { io_unlock($changelog); } return true; } }
/** * Replace one or more occurrences of a line in a file. * * The default, when $maxlines is 0 is to delete all matching lines then append a single line. * A regex that matches any part of the line will remove the entire line in this mode. * Captures in $newline are not available. * * Otherwise each line is matched and replaced individually, up to the first $maxlines lines * or all lines if $maxlines is -1. If $regex is true then captures can be used in $newline. * * Be sure to include the trailing newline in $oldline when replacing entire lines. * * Uses gzip if extension is .gz * and bz2 if extension is .bz2 * * @author Steven Danz <*****@*****.**> * @author Christopher Smith <*****@*****.**> * @author Patrick Brown <*****@*****.**> * * @param string $file filename * @param string $oldline exact linematch to remove * @param string $newline new line to insert * @param bool $regex use regexp? * @param int $maxlines number of occurrences of the line to replace * @return bool true on success */ function io_replaceInFile($file, $oldline, $newline, $regex = false, $maxlines = 0) { if ((string) $oldline === '') { trigger_error('$oldline parameter cannot be empty in io_replaceInFile()', E_USER_WARNING); return false; } if (!file_exists($file)) { return true; } io_lock($file); // load into array if (substr($file, -3) == '.gz') { if (!DOKU_HAS_GZIP) { return false; } $lines = gzfile($file); } else { if (substr($file, -4) == '.bz2') { if (!DOKU_HAS_BZIP) { return false; } $lines = bzfile($file, true); } else { $lines = file($file); } } // make non-regexes into regexes $pattern = $regex ? $oldline : '/^' . preg_quote($oldline, '/') . '$/'; $replace = $regex ? $newline : addcslashes($newline, '\\$'); // remove matching lines if ($maxlines > 0) { $count = 0; $matched = 0; while ($count < $maxlines && (list($i, $line) = each($lines))) { // $matched will be set to 0|1 depending on whether pattern is matched and line replaced $lines[$i] = preg_replace($pattern, $replace, $line, -1, $matched); if ($matched) { $count++; } } } else { if ($maxlines == 0) { $lines = preg_grep($pattern, $lines, PREG_GREP_INVERT); if ((string) $newline !== '') { $lines[] = $newline; } } else { $lines = preg_replace($pattern, $replace, $lines); } } if (count($lines)) { if (!_io_saveFile($file, join('', $lines), false)) { msg("Removing content from {$file} failed", -1); io_unlock($file); return false; } } else { @unlink($file); } io_unlock($file); return true; }