"Page History", "version" => "0.3", "author" => "Starbeamrainbowlabs", "description" => "Adds the ability to keep unlimited page history, limited only by your disk space. Note that this doesn't store file history (yet). Currently depends on feature-recent-changes for rendering of the history page.", "id" => "feature-history", "code" => function() { /** * @api {get} ?action=history&page={pageName} Get a list of revisions for a page * @apiName History * @apiGroup Page * @apiPermission Anonymous * * @apiParam {string} page The page name to return a revision list for. */ /* * ██ ██ ██ ███████ ████████ ██████ ██████ ██ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ * ███████ ██ ███████ ██ ██ ██ ██████ ████ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ * ██ ██ ██ ███████ ██ ██████ ██ ██ ██ */ add_action("history", function() { global $settings, $env, $pageindex; $supported_formats = [ "html", "json", "text" ]; $format = $_GET["format"] ?? "html"; switch($format) { case "html": $content = "
(None yet! Try editing this page and then coming back here.)
\n"; } exit(page_renderer::render_main("$env->page - History - $settings->sitename", $content)); case "json": $page_history = $pageindex->{$env->page}->history ?? []; foreach($page_history as &$history_entry) { unset($history_entry->filename); } header("content-type: application/json"); exit(json_encode($page_history, JSON_PRETTY_PRINT)); case "csv": $page_history = $pageindex->{$env->page}->history ?? []; header("content-type: text/csv"); echo("revision_id,timestamp,type,editor,newsize,sizediff\n"); foreach($page_history as $hentry) { echo("$hentry->rid,$hentry->timestamp,$hentry->type,$hentry->editor,$hentry->newsize,$hentry->sizediff\n"); } exit(); default: http_response_code(400); exit(page_renderer::render_main("Format Error - $env->page - History - $settings->sitename", "The format " . htmlentities($format) . "
isn't currently supported. Supported formats: html, json, csv"));
}
});
register_save_preprocessor("history_add_revision");
}
]);
function history_add_revision(&$pageinfo, &$newsource, &$oldsource, $save_pageindex = true) {
global $pageindex, $paths, $env;
if(!isset($pageinfo->history))
$pageinfo->history = [];
// Save the *new source* as a revision
// This results in 2 copies of the current source, but this is ok
// since any time someone changes something, it create a new
// revision
// Note that we can't save the old source here because we'd have no
// clue who edited it since $pageinfo has already been updated by
// this point
// TODO Store tag changes here
$nextRid = count($pageinfo->history); // The next revision id
$ridFilename = "$pageinfo->filename.r$nextRid";
// Insert a new entry into the history
$pageinfo->history[] = [
"type" => "edit", // We might want to store other types later (e.g. page moves)
"rid" => $nextRid,
"timestamp" => time(),
"filename" => $ridFilename,
"newsize" => strlen($newsource),
"sizediff" => strlen($newsource) - strlen($oldsource),
"editor" => $pageinfo->lasteditor
];
// Save the new source as a revision
file_put_contents("$env->storage_prefix$ridFilename", $newsource);
// Save the edited pageindex
if($save_pageindex)
file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
}
?>