forked from blallo/rss-bridge
Merge branch 'ImproveCaching' of https://github.com/logmanoriginal/rss-bridge
This commit is contained in:
commit
46ce0f85d7
8 changed files with 86 additions and 111 deletions
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
|
17
index.php
17
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -3,4 +3,5 @@ interface CacheInterface {
|
|||
public function loadData();
|
||||
public function saveData($datas);
|
||||
public function getTime();
|
||||
public function purgeCache($duration);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue