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
*/
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';
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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());
}
}
}
}
}

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 saveData($datas);
public function getTime();
public function purgeCache($duration);
}

View file

@ -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';

View file

@ -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);
}
}