--- a/lib/pChart2.1.0/class/pCache.class.php +++ b/lib/pChart2.1.0/class/pCache.class.php @@ -1,1 +1,271 @@ - +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); + } + } +?>