1<?php 2namespace DALMP\Cache; 3 4/** 5 * Disk 6 * 7 * @author Nicolas Embriz <nbari@dalmp.com> 8 * @package DALMP 9 * @license BSD License 10 * @version 3.0.3 11 */ 12class Disk implements CacheInterface 13{ 14 public $cache_dir; 15 16 /** 17 * Constructor 18 * 19 * @param string $dir 20 */ 21 public function __construct() 22 { 23 $args = func_get_args(); 24 25 if (!$args || !isset($args[0])) { 26 $cache_dir = defined('DALMP_CACHE_DIR') ? DALMP_CACHE_DIR : '/tmp/dalmp_cache'; 27 } else { 28 $cache_dir = $args[0]; 29 } 30 31 if (!is_writable($cache_dir)) { 32 if (!is_dir($cache_dir) && !mkdir($cache_dir, 0700, true)) { 33 throw new \InvalidArgumentException("$cache_dir not accessible"); 34 } 35 } 36 37 $this->cache_dir = $cache_dir; 38 } 39 40 /** 41 * Store data at the server 42 * 43 * @param string $key 44 * @param string $value 45 * @param int $expire time in seconds(default is 2592000 '30 days') 46 */ 47 public function set($key, $value, $expire = 2592000) 48 { 49 $key = sha1($key); 50 $expire = ($expire == 0) ? 2592000 : $expire; 51 52 $cache_path = sprintf('%s/%s/%s/%s', $this->cache_dir, substr($key, 0, 2), substr($key, 2, 2), substr($key, 4, 2)); 53 54 if (!file_exists($cache_path)) { 55 if (!mkdir($cache_path, 0750, true)) { 56 throw new \Exception("Can't create cache directory tree : $cache_path"); 57 } 58 } 59 60 $cache_file = sprintf('%s/%s', $cache_path, "dalmp_{$key}.cache"); 61 62 if (!($fp = fopen($cache_file, 'w'))) { 63 throw new \Exception(__METHOD__ . ": Cannot create cache file $cache_file"); 64 } 65 66 if (flock($fp, LOCK_EX) && ftruncate($fp, 0)) { 67 if (fwrite($fp, serialize($value))) { 68 flock($fp, LOCK_UN); 69 fclose($fp); 70 $time = time() + (int) $expire; 71 72 return touch($cache_file, $time); 73 } else { 74 return false; 75 } 76 } else { 77 throw new \Exception(__METHOD__ . ": Cannot lock/truncate the cache file: $cache_file"); 78 } 79 } 80 81 /** 82 * Retrieve item from the server 83 * 84 * @param string $key 85 */ 86 public function Get($key) 87 { 88 $key = sha1($key); 89 90 $cache_file = sprintf('%s/%s/%s/%s/%s', $this->cache_dir, substr($key, 0, 2), substr($key, 2, 2), substr($key, 4, 2), "dalmp_{$key}.cache"); 91 92 if (file_exists($cache_file)) { 93 if (filemtime($cache_file) > time()) { 94 return unserialize(file_get_contents($cache_file)); 95 } else { 96 unlink($cache_file); 97 98 return false; 99 } 100 } else { 101 return false; 102 } 103 } 104 105 /** 106 * Delete item from the server 107 * 108 * @param string $key 109 */ 110 public function Delete($key) 111 { 112 $key = sha1($key); 113 $cache_file = sprintf('%s/%s/%s/%s/%s', $this->cache_dir, substr($key, 0, 2), substr($key, 2, 2), substr($key, 4, 2), "dalmp_{$key}.cache"); 114 115 return file_exists($cache_file) ? unlink($cache_file) : true; 116 } 117 118 /** 119 * Flush cache 120 */ 121 public function Flush() 122 { 123 $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->cache_dir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST); 124 125 foreach ($files as $fileinfo) { 126 if ($fileinfo->isDir()) { 127 rmdir($fileinfo->getRealPath()); 128 } else { 129 unlink($fileinfo->getRealPath()); 130 } 131 } 132 133 return rmdir($this->cache_dir); 134 } 135 136 /** 137 * Get cache stats 138 */ 139 public function Stats() 140 { 141 $total_bytes = 0; 142 $total_files = 0; 143 144 $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->cache_dir, \RecursiveDirectoryIterator::SKIP_DOTS)); 145 foreach ($files as $fileinfo) { 146 $total_bytes += $fileinfo->getSize(); 147 $total_files++; 148 } 149 150 return array('Total Bytes' => number_format($total_bytes), 151 'Files' => $total_files); 152 } 153 154 /** 155 * X execute/call custom methods 156 * 157 * @return cache object 158 */ 159 public function X() 160 { 161 return $this; 162 } 163 164} 165