This commit is contained in:
logmanoriginal 2016-10-08 16:36:19 +02:00
commit 46ce0f85d7
8 changed files with 86 additions and 111 deletions

View file

@ -2,20 +2,17 @@
/** /**
* Cache with file system * Cache with file system
*/ */
class FileCache extends CacheAbstract { class FileCache implements CacheInterface {
protected $cacheDirCreated; // boolean to avoid always chck dir cache existance
protected $path;
protected $param;
public function loadData(){ public function loadData(){
$this->isPrepareCache();
$datas = unserialize(file_get_contents($this->getCacheFile())); $datas = unserialize(file_get_contents($this->getCacheFile()));
return $datas; return $datas;
} }
public function saveData($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)); $writeStream = file_put_contents($this->getCacheFile(), serialize($datas));
if(!$writeStream) { if(!$writeStream) {
@ -26,8 +23,6 @@ class FileCache extends CacheAbstract {
} }
public function getTime(){ public function getTime(){
$this->isPrepareCache();
$cacheFile = $this->getCacheFile(); $cacheFile = $this->getCacheFile();
if(file_exists($cacheFile)){ if(file_exists($cacheFile)){
return filemtime($cacheFile); return filemtime($cacheFile);
@ -36,35 +31,67 @@ class FileCache extends CacheAbstract {
return false; 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 ? * Set cache path
* Note : Cache name is based on request information, then cache must be prepare before use * @return self
* @return \Exception|true
*/ */
protected function isPrepareCache(){ public function setPath($path){
if(is_null($this->param)){ if(is_null($path) || !is_string($path)){
throw new \Exception('Please feed "prepare" method before try to load'); 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 cache path (and create if not exist)
* @return string Cache path * @return string Cache path
*/ */
protected function getCachePath(){ protected function getPath(){
$cacheDir = __DIR__ . '/../cache/'; // FIXME : configuration ? if(is_null($this->path)){
throw new \Exception('Call "setPath" first!');
// FIXME : implement recursive dir creation
if(is_null($this->cacheDirCreated) && !is_dir($cacheDir)){
$this->cacheDirCreated = true;
mkdir($cacheDir,0705);
chmod($cacheDir,0705);
} }
return $cacheDir; return $this->path;
} }
/** /**
@ -72,7 +99,7 @@ class FileCache extends CacheAbstract {
* @return string Path to the file cache * @return string Path to the file cache
*/ */
protected function getCacheFile(){ protected function getCacheFile(){
return $this->getCachePath() . $this->getCacheName(); return $this->getPath() . $this->getCacheName();
} }
/** /**
@ -80,10 +107,10 @@ class FileCache extends CacheAbstract {
* return string * return string
*/ */
protected function getCacheName(){ 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); return hash('sha1', http_build_query($this->param)) . '.cache';
$stringToEncode = preg_replace('/(\?|&)format=[^&]*/i', '$1', $stringToEncode);
return hash('sha1', $stringToEncode) . '.cache';
} }
} }

View file

@ -19,6 +19,9 @@ define('PROXY_NAME', 'Hidden Proxy Name');
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
error_reporting(0); error_reporting(0);
// Specify directory for cached files (using FileCache)
define('CACHE_DIR', __DIR__ . '/cache');
/* /*
Create a file named 'DEBUG' for enabling debug mode. Create a file named 'DEBUG' for enabling debug mode.
For further security, you may put whitelisted IP addresses 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)); $whitelist_selection = explode("\n", file_get_contents($whitelist_file));
} }
Cache::purge();
try { try {
Bridge::setDir(__DIR__ . '/bridges/'); Bridge::setDir(__DIR__ . '/bridges/');
@ -119,9 +120,6 @@ try {
// Data retrieval // Data retrieval
$bridge = Bridge::create($bridge); $bridge = Bridge::create($bridge);
$cache = Cache::create('FileCache');
$bridge->setCache($cache);
$noproxy = filter_input(INPUT_GET, '_noproxy', FILTER_VALIDATE_BOOLEAN); $noproxy = filter_input(INPUT_GET, '_noproxy', FILTER_VALIDATE_BOOLEAN);
if(defined('PROXY_URL') && PROXY_BYBRIDGE && $noproxy){ if(defined('PROXY_URL') && PROXY_BYBRIDGE && $noproxy){
define('NOPROXY',true); define('NOPROXY',true);
@ -132,6 +130,15 @@ try {
unset($params['bridge']); unset($params['bridge']);
unset($params['format']); unset($params['format']);
unset($params['_noproxy']); 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); $bridge->setDatas($params);
// Data transformation // Data transformation

View file

@ -138,7 +138,6 @@ abstract class BridgeAbstract implements BridgeInterface {
*/ */
public function setDatas(array $inputs){ public function setDatas(array $inputs){
if(!is_null($this->cache)){ if(!is_null($this->cache)){
$this->cache->prepare($inputs);
$time = $this->cache->getTime(); $time = $this->cache->getTime();
if($time !== false if($time !== false
&& (time() - static::CACHE_TIMEOUT < $time) && (time() - static::CACHE_TIMEOUT < $time)
@ -196,7 +195,7 @@ abstract class BridgeAbstract implements BridgeInterface {
return static::URI; return static::URI;
} }
public function setCache(\CacheAbstract $cache){ public function setCache(\CacheInterface $cache){
$this->cache = $cache; $this->cache = $cache;
} }
} }

View file

@ -50,45 +50,4 @@ class Cache {
static public function isValidNameCache($nameCache){ static public function isValidNameCache($nameCache){
return preg_match('@^[A-Z][a-zA-Z0-9-]*$@', $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());
}
}
}
}
} }

View file

@ -1,11 +0,0 @@
<?php
require_once(__DIR__ . '/CacheInterface.php');
abstract class CacheAbstract implements CacheInterface {
protected $param;
public function prepare(array $param){
$this->param = $param;
return $this;
}
}

View file

@ -3,4 +3,5 @@ interface CacheInterface {
public function loadData(); public function loadData();
public function saveData($datas); public function saveData($datas);
public function getTime(); public function getTime();
public function purgeCache($duration);
} }

View file

@ -14,7 +14,6 @@ require __DIR__ . '/Bridge.php';
require __DIR__ . '/BridgeAbstract.php'; require __DIR__ . '/BridgeAbstract.php';
require __DIR__ . '/FeedExpander.php'; require __DIR__ . '/FeedExpander.php';
require __DIR__ . '/Cache.php'; require __DIR__ . '/Cache.php';
require __DIR__ . '/CacheAbstract.php';
require __DIR__ . '/validation.php'; require __DIR__ . '/validation.php';
require __DIR__ . '/html.php'; require __DIR__ . '/html.php';

View file

@ -103,30 +103,24 @@ function getSimpleHTMLDOMCached($url
){ ){
debugMessage('Caching url ' . $url . ', duration ' . $duration); debugMessage('Caching url ' . $url . ', duration ' . $duration);
$filepath = __DIR__ . '/../cache/pages/' . sha1($url) . '.cache'; // Initialize cache
debugMessage('Cache file ' . $filepath); $cache = Cache::create('FileCache');
$cache->setPath(CACHE_DIR . '/pages');
$cache->purgeCache(86400); // 24 hours (forced)
if(file_exists($filepath) && filectime($filepath) < time() - $duration){ $params = [$url];
unlink ($filepath); $cache->setParameters($params);
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);
}
// 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); $content = getContents($url, $use_include_path, $context, $offset, $maxLen);
if($content !== false){ if($content !== false){
file_put_contents($filepath, $content); $cache->saveData($content);
} }
} }