diff --git a/caches/FileCache.php b/caches/FileCache.php index a8ab88d7..ce8394e2 100644 --- a/caches/FileCache.php +++ b/caches/FileCache.php @@ -2,20 +2,17 @@ /** * Cache with file system */ -class FileCache extends CacheAbstract { - protected $cacheDirCreated; // boolean to avoid always chck dir cache existance +class FileCache implements CacheInterface { + + protected $path; + protected $param; public function loadData(){ - $this->isPrepareCache(); $datas = unserialize(file_get_contents($this->getCacheFile())); return $datas; } public function saveData($datas){ - $this->isPrepareCache(); - - //Re-encode datas to UTF-8 - //$datas = Cache::utf8_encode_deep($datas); $writeStream = file_put_contents($this->getCacheFile(), serialize($datas)); if(!$writeStream) { @@ -26,8 +23,6 @@ class FileCache extends CacheAbstract { } public function getTime(){ - $this->isPrepareCache(); - $cacheFile = $this->getCacheFile(); if(file_exists($cacheFile)){ return filemtime($cacheFile); @@ -36,35 +31,67 @@ class FileCache extends CacheAbstract { return false; } + public function purgeCache($duration){ + $cachePath = $this->getPath(); + if(file_exists($cachePath)){ + $cacheIterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($cachePath), + RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach($cacheIterator as $cacheFile){ + if(in_array($cacheFile->getBasename(), array('.', '..'))) + continue; + elseif($cacheFile->isFile()){ + if(filemtime($cacheFile->getPathname()) < time() - $duration) + unlink($cacheFile->getPathname()); + } + } + } + } + /** - * Cache is prepared ? - * Note : Cache name is based on request information, then cache must be prepare before use - * @return \Exception|true + * Set cache path + * @return self */ - protected function isPrepareCache(){ - if(is_null($this->param)){ - throw new \Exception('Please feed "prepare" method before try to load'); + public function setPath($path){ + if(is_null($path) || !is_string($path)){ + throw new \Exception('The given path is invalid!'); } - return true; + $this->path = $path; + + // Make sure path ends with '/' or '\' + $lastchar = substr($this->path, -1, 1); + if($lastchar !== '/' && $lastchar !== '\\') + $this->path .= '/'; + + if(!is_dir($this->path)) + mkdir($this->path, 0755, true); + + return $this; + } + + /** + * Set HTTP GET parameters + * @return self + */ + public function setParameters(array $param){ + $this->param = array_map('strtolower', $param); + + return $this; } /** * Return cache path (and create if not exist) * @return string Cache path */ - protected function getCachePath(){ - $cacheDir = __DIR__ . '/../cache/'; // FIXME : configuration ? - - // FIXME : implement recursive dir creation - if(is_null($this->cacheDirCreated) && !is_dir($cacheDir)){ - $this->cacheDirCreated = true; - - mkdir($cacheDir,0705); - chmod($cacheDir,0705); + protected function getPath(){ + if(is_null($this->path)){ + throw new \Exception('Call "setPath" first!'); } - return $cacheDir; + return $this->path; } /** @@ -72,7 +99,7 @@ class FileCache extends CacheAbstract { * @return string Path to the file cache */ protected function getCacheFile(){ - return $this->getCachePath() . $this->getCacheName(); + return $this->getPath() . $this->getCacheName(); } /** @@ -80,10 +107,10 @@ class FileCache extends CacheAbstract { * return string */ protected function getCacheName(){ - $this->isPrepareCache(); + if(is_null($this->param)){ + throw new \Exception('Call "setParameters" first!'); + } - $stringToEncode = $_SERVER['REQUEST_URI'] . http_build_query($this->param); - $stringToEncode = preg_replace('/(\?|&)format=[^&]*/i', '$1', $stringToEncode); - return hash('sha1', $stringToEncode) . '.cache'; + return hash('sha1', http_build_query($this->param)) . '.cache'; } } diff --git a/index.php b/index.php index d104caa4..fba21678 100644 --- a/index.php +++ b/index.php @@ -19,6 +19,9 @@ define('PROXY_NAME', 'Hidden Proxy Name'); date_default_timezone_set('UTC'); error_reporting(0); +// Specify directory for cached files (using FileCache) +define('CACHE_DIR', __DIR__ . '/cache'); + /* Create a file named 'DEBUG' for enabling debug mode. For further security, you may put whitelisted IP addresses @@ -84,8 +87,6 @@ if(!file_exists($whitelist_file)){ $whitelist_selection = explode("\n", file_get_contents($whitelist_file)); } -Cache::purge(); - try { Bridge::setDir(__DIR__ . '/bridges/'); @@ -119,9 +120,6 @@ try { // Data retrieval $bridge = Bridge::create($bridge); - $cache = Cache::create('FileCache'); - $bridge->setCache($cache); - $noproxy = filter_input(INPUT_GET, '_noproxy', FILTER_VALIDATE_BOOLEAN); if(defined('PROXY_URL') && PROXY_BYBRIDGE && $noproxy){ define('NOPROXY',true); @@ -132,6 +130,15 @@ try { unset($params['bridge']); unset($params['format']); unset($params['_noproxy']); + + // Initialize cache + $cache = Cache::create('FileCache'); + $cache->setPath(CACHE_DIR); + $cache->purgeCache(86400); // 24 hours + $cache->setParameters($params); + + // Load cache & data + $bridge->setCache($cache); $bridge->setDatas($params); // Data transformation diff --git a/lib/BridgeAbstract.php b/lib/BridgeAbstract.php index 2a648329..95170996 100644 --- a/lib/BridgeAbstract.php +++ b/lib/BridgeAbstract.php @@ -138,7 +138,6 @@ abstract class BridgeAbstract implements BridgeInterface { */ public function setDatas(array $inputs){ if(!is_null($this->cache)){ - $this->cache->prepare($inputs); $time = $this->cache->getTime(); if($time !== false && (time() - static::CACHE_TIMEOUT < $time) @@ -196,7 +195,7 @@ abstract class BridgeAbstract implements BridgeInterface { return static::URI; } - public function setCache(\CacheAbstract $cache){ + public function setCache(\CacheInterface $cache){ $this->cache = $cache; } } diff --git a/lib/Cache.php b/lib/Cache.php index a1649a0b..414e6824 100644 --- a/lib/Cache.php +++ b/lib/Cache.php @@ -50,45 +50,4 @@ class Cache { static public function isValidNameCache($nameCache){ return preg_match('@^[A-Z][a-zA-Z0-9-]*$@', $nameCache); } - - - static public function utf8_encode_deep(&$input){ - if (is_string($input)){ - $input = utf8_encode($input); - } elseif(is_array($input)){ - foreach($input as &$value){ - Cache::utf8_encode_deep($value); - } - - unset($value); - } elseif(is_object($input)){ - $vars = array_keys(get_object_vars($input)); - - foreach($vars as $var){ - Cache::utf8_encode_deep($input->$var); - } - } - } - - - static public function purge(){ - $cacheTimeLimit = time() - 86400; // 86400 -> 24h - $cachePath = 'cache'; - if(file_exists($cachePath)){ - $cacheIterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($cachePath), - RecursiveIteratorIterator::CHILD_FIRST - ); - - foreach($cacheIterator as $cacheFile){ - if(in_array($cacheFile->getBasename(), array('.', '..'))) - continue; - elseif($cacheFile->isFile()){ - if(filemtime($cacheFile->getPathname()) < $cacheTimeLimit) - unlink($cacheFile->getPathname()); - } - } - } - } - } diff --git a/lib/CacheAbstract.php b/lib/CacheAbstract.php deleted file mode 100644 index e6c39d8c..00000000 --- a/lib/CacheAbstract.php +++ /dev/null @@ -1,11 +0,0 @@ -param = $param; - - return $this; - } -} diff --git a/lib/CacheInterface.php b/lib/CacheInterface.php index 4c59df30..5753c0eb 100644 --- a/lib/CacheInterface.php +++ b/lib/CacheInterface.php @@ -3,4 +3,5 @@ interface CacheInterface { public function loadData(); public function saveData($datas); public function getTime(); + public function purgeCache($duration); } diff --git a/lib/RssBridge.php b/lib/RssBridge.php index 0052abc4..37992d38 100644 --- a/lib/RssBridge.php +++ b/lib/RssBridge.php @@ -14,7 +14,6 @@ require __DIR__ . '/Bridge.php'; require __DIR__ . '/BridgeAbstract.php'; require __DIR__ . '/FeedExpander.php'; require __DIR__ . '/Cache.php'; -require __DIR__ . '/CacheAbstract.php'; require __DIR__ . '/validation.php'; require __DIR__ . '/html.php'; diff --git a/lib/contents.php b/lib/contents.php index 747db5bf..470efeb3 100644 --- a/lib/contents.php +++ b/lib/contents.php @@ -103,30 +103,24 @@ function getSimpleHTMLDOMCached($url ){ debugMessage('Caching url ' . $url . ', duration ' . $duration); - $filepath = __DIR__ . '/../cache/pages/' . sha1($url) . '.cache'; - debugMessage('Cache file ' . $filepath); + // Initialize cache + $cache = Cache::create('FileCache'); + $cache->setPath(CACHE_DIR . '/pages'); + $cache->purgeCache(86400); // 24 hours (forced) - if(file_exists($filepath) && filectime($filepath) < time() - $duration){ - unlink ($filepath); - debugMessage('Cached file deleted: ' . $filepath); - } - - if(file_exists($filepath)){ - debugMessage('Loading cached file ' . $filepath); - touch($filepath); - $content = file_get_contents($filepath); - } else { - debugMessage('Caching ' . $url . ' to ' . $filepath); - $dir = substr($filepath, 0, strrpos($filepath, '/')); - - if(!is_dir($dir)){ - debugMessage('Creating directory ' . $dir); - mkdir($dir, 0777, true); - } + $params = [$url]; + $cache->setParameters($params); + // Determine if cached file is within duration + $time = $cache->getTime(); + if($time !== false + && (time() - $duration < $time) + && (!defined('DEBUG') || DEBUG !== true)){ // Contents within duration + $content = $cache->loadData(); + } else { // Content not within duration $content = getContents($url, $use_include_path, $context, $offset, $maxLen); if($content !== false){ - file_put_contents($filepath, $content); + $cache->saveData($content); } }