getPath())) { return true; } else { } return false; } /* * Init Cache Path */ function __construct($config = array()) { $this->setup($config); $this->getPath(); // force create path if(!$this->checkdriver() && !isset($config['skipError'])) { throw new Exception("Can't use this driver for your website!"); } } private function encodeFilename($keyword) { return trim(trim(preg_replace("/[^a-zA-Z0-9]+/","_",$keyword),"_")); // return rtrim(base64_encode($keyword), '='); } private function decodeFilename($filename) { return $filename; // return base64_decode($filename); } /* * Return $FILE FULL PATH */ private function getFilePath($keyword, $skip = false) { $path = $this->getPath(); $filename = $this->encodeFilename($keyword); $folder = substr($filename,0,2); $path = rtrim($path,"/")."/".$folder; /* * Skip Create Sub Folders; */ if($skip == false) { //if it doesn't exist, I can't create it, and nobody beat me to creating it: if(!@is_dir($path) && !@mkdir($path,$this->__setChmodAuto()) && !@is_dir($path)) { throw new Exception("PLEASE CHMOD ".$this->getPath()." - 0777 OR ANY WRITABLE PERMISSION!",92); } //if it does exist (after someone beat me to it, perhaps), but isn't writable or fixable: if(@is_dir($path) && !is_writeable($path) && !@chmod($path,$this->__setChmodAuto())) { throw new Exception("PLEASE CHMOD ".$this->getPath()." - 0777 OR ANY WRITABLE PERMISSION!",92); } } $file_path = $path."/".$filename.".txt"; return $file_path; } function driver_set($keyword, $value = "", $time = 300, $option = array() ) { $file_path = $this->getFilePath($keyword); $tmp_path = $file_path . ".tmp"; // echo "
DEBUG SET: ".$keyword." - ".$value." - ".$time."
"; $data = $this->encode($value); $toWrite = true; /* * Skip if Existing Caching in Options */ if(isset($option['skipExisting']) && $option['skipExisting'] == true && @file_exists($file_path)) { $content = $this->readfile($file_path); $old = $this->decode($content); $toWrite = false; if($this->isExpired($old)) { $toWrite = true; } } $written = true; /* * write to intent file to prevent race during read; race during write is ok * because first-to-lock wins and the file will exist before the writer attempts * to write. */ if($toWrite == true && !@file_exists($tmp_path) && !@file_exists($file_path)) { try { $f = @fopen($tmp_path, "c"); if ($f) { if (flock($f,LOCK_EX| LOCK_NB)) { $written = ($written && fwrite($f, $data)); $written = ($written && fflush($f)); $written = ($written && flock($f, LOCK_UN)); } else { //arguably the file is being written to so the job is done $written = false; } $written = ($written && @fclose($f)); $written = ($written && @rename($tmp_path,$file_path)); } } catch (Exception $e) { // miss cache $written = false; } } return $written; } function driver_get($keyword, $option = array()) { $file_path = $this->getFilePath($keyword); if(!@file_exists($file_path)) { return null; } $content = $this->readfile($file_path); $object = $this->decode($content); if($this->isExpired($object)) { @unlink($file_path); $this->auto_clean_expired(); return null; } return $object; } function driver_delete($keyword, $option = array()) { $file_path = $this->getFilePath($keyword,true); if(file_exists($file_path) && @unlink($file_path)) { return true; } else { return false; } } /* * Return total cache size + auto removed expired files */ function driver_stats($option = array()) { $res = array( "info" => "", "size" => "", "data" => "", ); $path = $this->getPath(); $dir = @opendir($path); if(!$dir) { throw new Exception("Can't read PATH:".$path,94); } $total = 0; $removed = 0; $content = array(); while($file=@readdir($dir)) { if($file!="." && $file!=".." && is_dir($path."/".$file)) { // read sub dir $subdir = @opendir($path."/".$file); if(!$subdir) { throw new Exception("Can't read path:".$path."/".$file,93); } while($f = @readdir($subdir)) { if($f!="." && $f!="..") { $file_path = $path."/".$file."/".$f; $size = @filesize($file_path); $object = $this->decode($this->readfile($file_path)); if(strpos($f,".") === false) { $key = $f; } else { //Because PHP 5.3, this cannot be written in single line $key = explode(".", $f); $key = $key[0]; } $content[$key] = array("size"=>$size,"write_time"=>$object["write_time"]); if($this->isExpired($object)) { @unlink($file_path); $removed += $size; } $total += $size; } } // end read subdir } // end if } // end while $res['size'] = $total - $removed; $res['info'] = array( "Total [bytes]" => $total, "Expired and removed [bytes]" => $removed, "Current [bytes]" => $res['size'], ); $res["data"] = $content; return $res; } function auto_clean_expired() { $autoclean = $this->get("keyword_clean_up_driver_files"); if($autoclean == null) { $this->set("keyword_clean_up_driver_files",3600*24); $res = $this->stats(); } } function driver_clean($option = array()) { $path = $this->getPath(); $dir = @opendir($path); if(!$dir) { throw new Exception("Can't read PATH:".$path,94); } while($file=@readdir($dir)) { if($file!="." && $file!=".." && is_dir($path."/".$file)) { // read sub dir $subdir = @opendir($path."/".$file); if(!$subdir) { throw new Exception("Can't read path:".$path."/".$file,93); } while($f = @readdir($subdir)) { if($f!="." && $f!="..") { $file_path = $path."/".$file."/".$f; @unlink($file_path); } } // end read subdir } // end if } // end while } function driver_isExisting($keyword) { $file_path = $this->getFilePath($keyword,true); if(!@file_exists($file_path)) { return false; } else { // check expired or not $value = $this->get($keyword); if($value == null) { return false; } else { return true; } } } function isExpired($object) { if(isset($object['expired_time']) && time() >= $object['expired_time']) { return true; } else { return false; } } }