View source
<?php
class pCache {
var $CacheFolder;
var $CacheIndex;
var $CacheDB;
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);
}
}
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);
}
}
function getHash($Data, $Marker = "") {
return md5($Marker . serialize($Data->Data));
}
function writeToCache($ID, $pChartObject) {
$TemporaryFile = $this->CacheFolder . "/tmp_" . rand(0, 1000) . ".png";
$Database = $this->CacheFolder . "/" . $this->CacheDB;
$Index = $this->CacheFolder . "/" . $this->CacheIndex;
imagepng($pChartObject->Picture, $TemporaryFile);
$PictureSize = filesize($TemporaryFile);
$DBSize = filesize($Database);
$Handle = fopen($Index, "a");
fwrite($Handle, $ID . "," . $DBSize . "," . $PictureSize . "," . time() . ",0 \r\n");
fclose($Handle);
$Handle = fopen($TemporaryFile, "r");
$Raw = fread($Handle, $PictureSize);
fclose($Handle);
$Handle = fopen($Database, "a");
fwrite($Handle, $Raw);
fclose($Handle);
unlink($TemporaryFile);
}
function removeOlderThan($Expiry) {
$this
->dbRemoval(array(
"Expiry" => $Expiry,
));
}
function remove($ID) {
$this
->dbRemoval(array(
"Name" => $ID,
));
}
function dbRemoval($Settings) {
$ID = isset($Settings["Name"]) ? $Settings["Name"] : NULL;
$Expiry = isset($Settings["Expiry"]) ? $Settings["Expiry"] : -(24 * 60 * 60);
$TS = time() - $Expiry;
$Database = $this->CacheFolder . "/" . $this->CacheDB;
$Index = $this->CacheFolder . "/" . $this->CacheIndex;
$DatabaseTemp = $this->CacheFolder . "/" . $this->CacheDB . ".tmp";
$IndexTemp = $this->CacheFolder . "/" . $this->CacheIndex . ".tmp";
if ($ID != NULL) {
$Object = $this
->isInCache($ID, TRUE);
if (!$Object) {
return 0;
}
}
if (!file_exists($DatabaseTemp)) {
touch($DatabaseTemp);
}
if (!file_exists($IndexTemp)) {
touch($IndexTemp);
}
$IndexHandle = @fopen($Index, "r");
$IndexTempHandle = @fopen($IndexTemp, "w");
$DBHandle = @fopen($Database, "r");
$DBTempHandle = @fopen($DatabaseTemp, "w");
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);
}
}
}
fclose($IndexHandle);
fclose($IndexTempHandle);
fclose($DBHandle);
fclose($DBTempHandle);
unlink($Database);
unlink($Index);
rename($DatabaseTemp, $Database);
rename($IndexTemp, $Index);
}
function isInCache($ID, $Verbose = FALSE, $UpdateHitsCount = FALSE) {
$Index = $this->CacheFolder . "/" . $this->CacheIndex;
$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);
return FALSE;
}
function autoOutput($ID, $Destination = "output.png") {
if (php_sapi_name() == "cli") {
$this
->saveFromCache($ID, $Destination);
}
else {
$this
->strokeFromCache($ID);
}
}
function strokeFromCache($ID) {
$Picture = $this
->getFromCache($ID);
if ($Picture == NULL) {
return FALSE;
}
header('Content-type: image/png');
echo $Picture;
return TRUE;
}
function saveFromCache($ID, $Destination) {
$Picture = $this
->getFromCache($ID);
if ($Picture == NULL) {
return FALSE;
}
$Handle = fopen($Destination, "w");
fwrite($Handle, $Picture);
fclose($Handle);
return TRUE;
}
function getFromCache($ID) {
$Database = $this->CacheFolder . "/" . $this->CacheDB;
$CacheInfo = $this
->isInCache($ID, TRUE, TRUE);
if (!$CacheInfo) {
return NULL;
}
$DBPos = $CacheInfo["DBPos"];
$PicSize = $CacheInfo["PicSize"];
$Handle = @fopen($Database, "r");
fseek($Handle, $DBPos);
$Picture = fread($Handle, $PicSize);
fclose($Handle);
return $Picture;
}
}