Heuristic ranking analysis
[contractdashboard.git] / lib / pChart2.1.0 / class / pCache.class.php
blob:a/lib/pChart2.1.0/class/pCache.class.php -> blob:b/lib/pChart2.1.0/class/pCache.class.php
  <?php
  /*
  pCache - speed up the rendering by caching up the pictures
   
  Version : 2.1.0
  Made by : Jean-Damien POGOLOTTI
  Last Update : 26/01/11
   
  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);
  }
   
  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);
  }
  }
  ?>