AutorÃa | Ultima modificación | Ver Log |
<?php/*pCache - speed up the rendering by caching up the picturesVersion : 2.1.4Made by : Jean-Damien POGOLOTTILast Update : 19/01/2014This file can be distributed under the license you can find at :http://www.pchart.net/licenseYou can find the whole class documentation on the pChart web site.*//* pData class definition */class pCache{var $CacheFolder;var $CacheIndex;var $CacheDB;/* Class creator */function __construct(array $Settings = []){#if (!is_dir("cache")){# mkdir("cache", 0775);#}$this->CacheFolder = isset($Settings["CacheFolder"]) ? $Settings["CacheFolder"] : "cache";$this->CacheIndex = isset($Settings["CacheIndex"]) ? $Settings["CacheIndex"] : "index.db";$this->CacheIndex = $this->CacheFolder . "/" . $this->CacheIndex;$this->CacheDB = isset($Settings["CacheDB"]) ? $Settings["CacheDB"] : "cache.db";$this->CacheDB = $this->CacheFolder . "/" . $this->CacheDB;if (!file_exists($this->CacheIndex)) {touch($this->CacheIndex);}if (!file_exists($this->CacheDB)) {touch($this->CacheDB);}}/* Flush the cache contents */function flush(){file_put_contents($this->CacheIndex, "");file_put_contents($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";/* Flush the picture to a temporary file */imagepng($pChartObject->Picture, $TemporaryFile);/* Retrieve the files size */$PictureSize = filesize($TemporaryFile);$DBSize = filesize($this->CacheDB);/* Save the index */$Handle = fopen($this->CacheIndex, "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($this->CacheDB, "a");fwrite($Handle, $Raw);fclose($Handle);/* Remove temporary file */unlink($TemporaryFile);}/* Remove object older than the specified TS */function removeOlderThan($Expiry){$this->dbRemoval(["Expiry" => $Expiry]);}/* Remove an object from the cache */function remove($ID){$this->dbRemoval(["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 */$DatabaseTemp = $this->CacheDB . ".tmp";$IndexTemp = $this->CacheIndex . ".tmp";/* Single file removal */if ($ID != NULL) {/* If it's not in the cache DB, go away */if (!$this->isInCache($ID, TRUE)) {return 0;}}/* Create the temporary files */if (!file_exists($DatabaseTemp)) {touch($DatabaseTemp);}if (!file_exists($IndexTemp)) {touch($IndexTemp);}/* Open the file handles */$IndexHandle = fopen($this->CacheIndex, "r");$IndexTempHandle = fopen($IndexTemp, "w");$DBHandle = fopen($this->CacheDB, "r");$DBTempHandle = fopen($DatabaseTemp, "w");/* Remove the selected ID from the database */if ($IndexHandle && $IndexTempHandle && $DBHandle && $DBTempHandle) {while (!feof($IndexHandle)) {$Entry = fgets($IndexHandle, 4096);$Entry = str_replace("\r", "", $Entry);$Entry = str_replace("\n", "", $Entry);$Settings = explode(",", $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($this->CacheDB);unlink($this->CacheIndex);/* Swap the temp & prod DB */rename($DatabaseTemp, $this->CacheDB);rename($IndexTemp, $this->CacheIndex);}function isInCache($ID, $Verbose = FALSE, $UpdateHitsCount = FALSE){/* Search the picture in the index file */$Handle = fopen($this->CacheIndex, "r");if ($Handle){while (!feof($Handle)) {$IndexPos = ftell($Handle);$Entry = fgets($Handle, 4096);if ($Entry != "") {$Settings = explode(",", $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($this->CacheIndex, "r+");fseek($Handle, $IndexPos);fwrite($Handle, $PicID . "," . $DBPos . "," . $PicSize . "," . $GeneratedTS . "," . $Hits . "\r\n");fclose($Handle);}if ($Verbose) {return ["DBPos" => $DBPos,"PicSize" => $PicSize,"GeneratedTS" => $GeneratedTS,"Hits" => $Hits];} else {return TRUE;}}}}fclose($Handle);}/* Picture isn't in the cache */return FALSE;}/* Automatic output method based on the calling interface */function autoOutput($ID, $Destination = "output.png"){if (php_sapi_name() == "cli") {$this->saveFromCache($ID, $Destination);} else {$this->strokeFromCache($ID);}}function strokeFromCache($ID){/* Get the raw picture from the cache */$Picture = $this->getFromCache($ID);/* Do we have a hit? */if ($Picture == FALSE) {return FALSE;}header('Content-type: image/png');echo $Picture;}function saveFromCache($ID, $Destination){/* Get the raw picture from the cache */$Picture = $this->getFromCache($ID);/* Do we have a hit? */if ($Picture == FALSE) {return FALSE;}/* Flush the picture to a file */file_put_contents($Destination, $Picture);}function getFromCache($ID){/* Lookup for the picture in the cache */$CacheInfo = $this->isInCache($ID, TRUE, TRUE);/* Not in the cache */if (!$CacheInfo) {# Momchil: fread returns FALSE on failure. Return FALSE here as well and not NULLreturn FALSE;}/* Get the database extended information */$DBPos = $CacheInfo["DBPos"];$PicSize = $CacheInfo["PicSize"];/* Extract the picture from the solid cache file */$Handle = fopen($this->CacheDB, "r");fseek($Handle, $DBPos);$Picture = fread($Handle, $PicSize);fclose($Handle);/* Return back the raw picture data */return $Picture;}}?>