<?php
// comment this line out if on windows 9x or any other os not supporting flock()
define("WITH_FLOCK", 1);
/*************************************************
morecache.php - a general-purpose script-output caching class
home page: www.samscripts.com/scripts/morecache
support: support.samscripts.com/index.php
licence: freeware / optionally giftware ( www.samscripts.com/donate.php )
author: Sam Yapp
date: 8th September 2002
documentation and examples at www.samscripts.com
*************************************************/
class morecache{
var $expireafter;
var $expiretype;
var $filenames;
var $searchvars;
var $replacevars;
var $activecaches = -1;
var $cachepath = "./cached";
function setexpiry($expireafter = 60){
$this->expireafter = $expireafter;
if( is_int($expireafter) ){
$this->expiretype = "sec";
}else{
$this->expiretype = "date";
}
}
function morecache( $cachepath = "", $expireafter = 3600){
if( $cachepath != "" ) $this->cachepath = $cachepath;
$this->setexpiry($expireafter);
$this->filenames = array();
$this->searchvars = array();
$this->replacevars = array();
$this->activecaches = -1;
}
function makecachename($id){
return $this->cachepath."/".md5($id).".cache";
}
function expirecache($cachename){
$filename = $this->makecachename($cachename);
@unlink($filename);
}
function cache($cachename, $expireafter = "", $search = array(), $replace=array()){
if( !is_array($search) ) $search = array($search);
$this->activecaches++;
$this->filenames[$this->activecaches] = $this->makecachename($cachename);
$this->searches[$this->activecaches] = &$search;
$this->replaces[$this->activecaches] = &$replace;
if( $expireafter == "" ) $expireafter = $this->expireafter;
$this->setexpiry($expireafter);
$update = 0;
if( !file_exists($this->filenames[$this->activecaches]) ){
$update = 1;
$exist = 0;
}else{
$exist = 1;
$updated = filemtime($this->filenames[$this->activecaches]);
}
if( $exist ==0 || $updated < ($this->expiretype == "sec" ? time() - $this->expireafter : strtotime($this->expireafter))){
$update = 1;
}
if( $update){
ob_start();
return true;
}else{
if( count($this->searches[$this->activecaches]) == 0 ){
$fp = $this->flock($this->filenames[$this->activecaches], "r");
if(!@readfile( $this->filenames[$this->activecaches])) $this->error = "readfile failed for ".$this->filenames[$this->activecaches];
$this->funlock($fp);
}else{
$f = join("", file($this->filenames[$this->activecaches]));
echo str_replace($this->searches[$this->activecaches], $this->replaces[$this->activecaches], $f);
}
return false;
}
}
function stop($returnbuffer = false, $showoutput = true){ // if returnbuffer is true, returns the contents of the cache to the calling script
$this->cachecontents = ob_get_contents();
$this->save();
if( $showoutput == true && count( $this->searches[$this->activecaches]) != 0 ){
ob_end_clean();
echo str_replace($this->searches[$this->activecaches], $this->replaces[$this->activecaches], $this->cachecontents);
}elseif( $showoutput == true ){
ob_end_flush();
}else{
ob_end_clean();
}
$this->activecaches--;
return ($showoutput == true ? $this->cachecontents : true);
}
function flock($filename, $mode){
$fp = @fopen($filename, $mode = "r" ? "r" : "wb");
if( defined(WITH_FLOCK) ) flock($fp, $mode="r" ? LOCK_SH : LOCK_EX);
ignore_user_abort(true);
return $fp;
}
function funlock($fp){
if( $fp ){
flock($fp, LOCK_UN);
@fclose($fp);
}
}
function save(){
$fo = $this->flock($this->filenames[$this->activecaches], "w");
if( $fo ){
if( !@fwrite( $fo, $this->cachecontents)) $this->error = "Error writing to file ".$this->filenames[$this->activecaches];
$this->funlock($fo);
}else{
$this->error = "Failed opening file ".$this->filenames[$this->activecaches]." for output.";
}
}
}
?>