Initial Github commit
This commit is contained in:
280
webdata/graph/pchart/class/pCache.class.php
Normal file
280
webdata/graph/pchart/class/pCache.class.php
Normal file
@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/*
|
||||
pCache - speed up the rendering by caching up the pictures
|
||||
|
||||
Version : 2.1.4
|
||||
Made by : Jean-Damien POGOLOTTI
|
||||
Last Update : 19/01/2014
|
||||
|
||||
This file can be distributed under the license you can find at :
|
||||
|
||||
http://www.pchart.net/license
|
||||
|
||||
You 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 pCache($Settings="")
|
||||
{
|
||||
$CacheFolder = isset($Settings["CacheFolder"]) ? $Settings["CacheFolder"] : "cache";
|
||||
$CacheIndex = isset($Settings["CacheIndex"]) ? $Settings["CacheIndex"] : "index.db";
|
||||
$CacheDB = isset($Settings["CacheDB"]) ? $Settings["CacheDB"] : "cache.db";
|
||||
|
||||
$this->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);
|
||||
}
|
||||
|
||||
/* 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 == 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);
|
||||
}
|
||||
}
|
||||
?>
|
Reference in New Issue
Block a user