0
0
mirror of https://github.com/salesagility/SuiteCRM.git synced 2024-11-22 07:52:36 +00:00
salesagility_SuiteCRM/modules/AOR_Charts/lib/pChart/class/pCache.class.php
2023-07-18 15:53:09 +01:00

304 lines
9.6 KiB
PHP

<?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 */
#[\AllowDynamicProperties]
class pCache
{
public $CacheFolder;
public $CacheIndex;
public $CacheDB;
/* Class creator */
public function __construct($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 */
public 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 */
public function getHash($Data, $Marker="")
{
return(md5($Marker.serialize($Data->Data)));
}
/* Write the generated picture to the cache */
public function writeToCache($ID, $pChartObject)
{
/* Compute the paths */
$TemporaryFile = $this->CacheFolder."/tmp_".mt_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, 'ab');
fwrite($Handle, $ID.",".$DBSize.",".$PictureSize.",".time().",0 \r\n");
fclose($Handle);
/* Get the picture raw contents */
$Handle = fopen($TemporaryFile, 'rb');
$Raw = fread($Handle, $PictureSize);
fclose($Handle);
/* Save the picture in the solid database file */
$Handle = fopen($Database, 'ab');
fwrite($Handle, $Raw);
fclose($Handle);
/* Remove temporary file */
unlink($TemporaryFile);
}
/* Remove object older than the specified TS */
public function removeOlderThan($Expiry)
{
$this->dbRemoval(array("Expiry"=>$Expiry));
}
/* Remove an object from the cache */
public function remove($ID)
{
$this->dbRemoval(array("Name"=>$ID));
}
/* Remove with specified criterias */
public 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, 'rb');
$IndexTempHandle = @fopen($IndexTemp, 'wb');
$DBHandle = @fopen($Database, 'rb');
$DBTempHandle = @fopen($DatabaseTemp, 'wb');
/* 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);
}
public 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, 'rb');
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 = (int)$Settings[4];
if ($UpdateHitsCount) {
$Hits++;
if (strlen($Hits) < 7) {
$Hits = $Hits.str_repeat(" ", 7-strlen($Hits));
}
$Handle = @fopen($Index, 'rb+');
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));
}
return(true);
}
}
}
fclose($Handle);
/* Picture isn't in the cache */
return(false);
}
/* Automatic output method based on the calling interface */
public function autoOutput($ID, $Destination="output.png")
{
if (php_sapi_name() == "cli") {
$this->saveFromCache($ID, $Destination);
} else {
$this->strokeFromCache($ID);
}
}
public 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);
}
public 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, 'wb');
fwrite($Handle, $Picture);
fclose($Handle);
/* All went fine */
return(true);
}
public 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, 'rb');
fseek($Handle, $DBPos);
$Picture = fread($Handle, $PicSize);
fclose($Handle);
/* Return back the raw picture data */
return($Picture);
}
}