CacheFolder = $CacheFolder; $this->CacheIndex = $CacheIndex; $this->CacheDB = $CacheDB; if (!file_exists($this->CacheFolder."/".$this->CacheIndex)) { touch($this->CacheFolder."/".$this->CacheIndex); } if (!file_exists($this->CacheFolder."/".$this->CacheDB)) { touch($this->CacheFolder."/".$this->CacheDB); } } /* Flush the cache contents */ function flush() { if (file_exists($this->CacheFolder."/".$this->CacheIndex)) { unlink($this->CacheFolder."/".$this->CacheIndex); touch($this->CacheFolder."/".$this->CacheIndex); } if (file_exists($this->CacheFolder."/".$this->CacheDB)) { unlink($this->CacheFolder."/".$this->CacheDB); touch($this->CacheFolder."/".$this->CacheDB); } } /* Return the MD5 of the data array to clearly identify the chart */ function getHash($Data,$Marker="") { return(md5($Marker.serialize($Data->Data))); } /* Write the generated picture to the cache */ function writeToCache($ID,$pChartObject) { /* Compute the paths */ $TemporaryFile = $this->CacheFolder."/tmp_".rand(0,1000).".png"; $Database = $this->CacheFolder."/".$this->CacheDB; $Index = $this->CacheFolder."/".$this->CacheIndex; /* Flush the picture to a temporary file */ imagepng($pChartObject->Picture ,$TemporaryFile); /* Retrieve the files size */ $PictureSize = filesize($TemporaryFile); $DBSize = filesize($Database); /* Save the index */ $Handle = fopen($Index,"a"); fwrite($Handle, $ID.",".$DBSize.",".$PictureSize.",".time().",0 \r\n"); fclose($Handle); /* Get the picture raw contents */ $Handle = fopen($TemporaryFile,"r"); $Raw = fread($Handle,$PictureSize); fclose($Handle); /* Save the picture in the solid database file */ $Handle = fopen($Database,"a"); fwrite($Handle, $Raw); fclose($Handle); /* Remove temporary file */ unlink($TemporaryFile); } /* Remove object older than the specified TS */ function removeOlderThan($Expiry) { $this->dbRemoval(array("Expiry"=>$Expiry)); } /* Remove an object from the cache */ function remove($ID) { $this->dbRemoval(array("Name"=>$ID)); } /* Remove with specified criterias */ function dbRemoval($Settings) { $ID = isset($Settings["Name"]) ? $Settings["Name"] : NULL; $Expiry = isset($Settings["Expiry"]) ? $Settings["Expiry"] : -(24*60*60); $TS = time()-$Expiry; /* Compute the paths */ $Database = $this->CacheFolder."/".$this->CacheDB; $Index = $this->CacheFolder."/".$this->CacheIndex; $DatabaseTemp = $this->CacheFolder."/".$this->CacheDB.".tmp"; $IndexTemp = $this->CacheFolder."/".$this->CacheIndex.".tmp"; /* Single file removal */ if ( $ID != NULL ) { /* Retrieve object informations */ $Object = $this->isInCache($ID,TRUE); /* If it's not in the cache DB, go away */ if ( !$Object ) { return(0); } } /* Create the temporary files */ if (!file_exists($DatabaseTemp)) { touch($DatabaseTemp); } if (!file_exists($IndexTemp)) { touch($IndexTemp); } /* Open the file handles */ $IndexHandle = @fopen($Index, "r"); $IndexTempHandle = @fopen($IndexTemp, "w"); $DBHandle = @fopen($Database, "r"); $DBTempHandle = @fopen($DatabaseTemp, "w"); /* Remove the selected ID from the database */ while (!feof($IndexHandle)) { $Entry = fgets($IndexHandle, 4096); $Entry = str_replace("\r","",$Entry); $Entry = str_replace("\n","",$Entry); $Settings = preg_split("/,/",$Entry); if ( $Entry != "" ) { $PicID = $Settings[0]; $DBPos = $Settings[1]; $PicSize = $Settings[2]; $GeneratedTS = $Settings[3]; $Hits = $Settings[4]; if ( $Settings[0] != $ID && $GeneratedTS > $TS) { $CurrentPos = ftell($DBTempHandle); fwrite($IndexTempHandle, $PicID.",".$CurrentPos.",".$PicSize.",".$GeneratedTS.",".$Hits."\r\n"); fseek($DBHandle,$DBPos); $Picture = fread($DBHandle,$PicSize); fwrite($DBTempHandle,$Picture); } } } /* Close the handles */ fclose($IndexHandle); fclose($IndexTempHandle); fclose($DBHandle); fclose($DBTempHandle); /* Remove the prod files */ unlink($Database); unlink($Index); /* Swap the temp & prod DB */ rename($DatabaseTemp,$Database); rename($IndexTemp,$Index); } function isInCache($ID,$Verbose=FALSE,$UpdateHitsCount=FALSE) { /* Compute the paths */ $Index = $this->CacheFolder."/".$this->CacheIndex; /* Search the picture in the index file */ $Handle = @fopen($Index, "r"); while (!feof($Handle)) { $IndexPos = ftell($Handle); $Entry = fgets($Handle, 4096); if ( $Entry != "" ) { $Settings = preg_split("/,/",$Entry); $PicID = $Settings[0]; if ( $PicID == $ID ) { fclose($Handle); $DBPos = $Settings[1]; $PicSize = $Settings[2]; $GeneratedTS = $Settings[3]; $Hits = intval($Settings[4]); if ( $UpdateHitsCount ) { $Hits++; if ( strlen($Hits) < 7 ) { $Hits = $Hits.str_repeat(" ",7-strlen($Hits)); } $Handle = @fopen($Index, "r+"); fseek($Handle,$IndexPos); fwrite($Handle, $PicID.",".$DBPos.",".$PicSize.",".$GeneratedTS.",".$Hits."\r\n"); fclose($Handle); } if ($Verbose) { return(array("DBPos"=>$DBPos,"PicSize"=>$PicSize,"GeneratedTS"=>$GeneratedTS,"Hits"=>$Hits)); } else { return(TRUE); } } } } fclose($Handle); /* Picture isn't in the cache */ return(FALSE); } function strokeFromCache($ID) { /* Get the raw picture from the cache */ $Picture = $this->getFromCache($ID); /* Do we have a hit? */ if ( $Picture == NULL ) { return(FALSE); } header('Content-type: image/png'); echo $Picture; return(TRUE); } function saveFromCache($ID,$Destination) { /* Get the raw picture from the cache */ $Picture = $this->getFromCache($ID); /* Do we have a hit? */ if ( $Picture == NULL ) { return(FALSE); } /* Flush the picture to a file */ $Handle = fopen($Destination,"w"); fwrite($Handle,$Picture); fclose($Handle); /* All went fine */ return(TRUE); } function getFromCache($ID) { /* Compute the path */ $Database = $this->CacheFolder."/".$this->CacheDB; /* Lookup for the picture in the cache */ $CacheInfo = $this->isInCache($ID,TRUE,TRUE); /* Not in the cache */ if (!$CacheInfo) { return(NULL); } /* Get the database extended information */ $DBPos = $CacheInfo["DBPos"]; $PicSize = $CacheInfo["PicSize"]; /* Extract the picture from the solid cache file */ $Handle = @fopen($Database, "r"); fseek($Handle,$DBPos); $Picture = fread($Handle,$PicSize); fclose($Handle); /* Return back the raw picture data */ return($Picture); } } ?>