<?php /* Copyright (c) 2003 Reimer Behrends This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See http://www.gnu.org/copyleft/gpl.html for a copy of the license. Version: 0.5 Date: November 18, 2003 */ $BrowseDirectives['[[nocache]]'] = '$GLOBALS["EnableCache"]=0;'; if (isset($EnableCache) && !$EnableCache) return; $EnableCache = 1; // Setting $DebugCache will append a [Cached] to the title of the // page when a cached version is displayed. // $DebugCache = 1; // The directory path must be absolute, because by the time the shutdown // function is called, we've lost track of the current directory. $CacheDir = getcwd() . "/wiki.cache"; $CacheTimeStamp = "$CacheDir/.touched"; // Create $CacheDir and make it inaccessible mkgiddir($CacheDir); if (!file_exists("$CacheDir/.htaccess")) { $fp = @fopen("$CacheDir/.htaccess", "w"); if ($fp) { fwrite($fp, "Order Deny,Allow\n"); fwrite($fp, "Deny from all\n"); fclose($fp); } } // Update $HandleActions $CacheSavedBrowseAction = $HandleActions["browse"]; if (!$CacheSavedBrowseAction) $CacheSavedBrowseAction = "HandleBrowse"; $HandleActions["browse"] = 'CacheHandleBrowse'; $HandleActions["resetcache"] = 'ResetCache'; if (substr($action,0,4) == "post" || $action == "upload" || @$HTTP_POST_VARS["post"]) register_shutdown_function("InvalidateCache"); if ($CacheAuthCheck) { $CacheSavedAuth = $AuthFunction; $AuthFunction = 'CacheAuthHook'; $CacheReadAuthPages = array(); } $CacheFailedAuth = false; function InvalidateCache() { global $CacheTimeStamp; touch($CacheTimeStamp); } function CacheHandleBrowse($pagename) { global $CacheDir, $PageFileFmt, $CacheFile, $CacheTimeStamp, $CacheSavedBrowseAction, $DebugCache, $EnableCache, $Now, $CacheSavedAuth, $CacheReadAuthPages, $CacheFailedAuth; if (!$EnableCache) { $CacheSavedBrowseAction($pagename); return; } $pagefile = FmtPageName($PageFileFmt,$pagename); $CacheFile = "$CacheDir/$pagefile"; Lock(1); $cachedata = @unserialize(implode("", file($CacheFile))); $cachetime = $cachedata["time"]; $lastchange = @filemtime($CacheTimeStamp); // The following loop traverses scripts and other files in // local/ so that changes to those will invalidate the cache. $dfp = @opendir("local"); if ($dfp) { while ($file = readdir($dfp)) if ($file[0] != ".") $lastchange = max($lastchange, @filemtime("local/$file")); closedir($dfp); } // Catch local.php too, in case somebody uses that. $lastchange = max($lastchange, @filemtime("local.php")); // Was the cached version created after the last change? if ($cachetime > $lastchange) { if ($CacheAuthCheck) { $authok = true; foreach ($cachedata["included"] as $readpage) if (!$CacheSavedAuth($readpage, "read", false)) { $authok = false; break; } if (!$authok) { Lock(0); return $CacheSavedBrowseAction($pagename); } } $contents = $cachedata["html"]; if ($contents) { // Send our own headers, not the PHP default. PrintFmt("headers:", $pagename); if ($DebugCache) $contents = str_replace("</title>", " [Cached]</title>", $contents); print $contents; Lock(-1); return; } } // We have to drop back to Lock(0) to avoid a deadlock. Lock(0); ob_start(); register_shutdown_function("FlushOutputBuffer"); $CacheSavedBrowseAction($pagename); if ($EnableCache && !$CacheFailedAuth) { Lock(2); $fp = fopen($CacheFile, "w"); $cachedata = array("time" => $Now, "included" => $CacheReadAuthPages, "html" => ob_get_contents()); fwrite($fp, serialize($cachedata)); fclose($fp); } Lock(-1); } function FlushOutputBuffer() { ob_end_flush(); } function ResetCache($pagename) { global $HTMLTitleFmt, $CacheSavedBrowseAction; $HTMLTitleFmt = str_replace("</title>", " [Cache Reset]</title>", $HTMLTitleFmt); InvalidateCache(); $CacheSavedBrowseAction($pagename); } function CacheAuthHook($pagename, $level, $authprompt=true) { global $CacheSavedAuth, $CacheReadAuthPages, $CacheFailedAuth; if ($level == "read") $CacheReadAuthPages[] = $pagename; $result = $CacheSavedAuth($pagename, $level, $authprompt); if (!$result && $level == "read") $CacheFailedAuth = true; return $result; } ?>