bebeboutik/override/classes/CacheRedis.php
2017-09-25 12:24:44 +02:00

288 lines
8.5 KiB
PHP

<?php
use Predis\Collection\Iterator;
class CacheRedis
{
/*
* remember to add a definition for the 4 following parameters in settings.inc.php
define('_REDIS_AUTH_STRING_','')
define('_REDIS_HOST_STRING_','127.0.0.1')
define('_REDIS_PORT_STRING_','6379')
define('_REDIS_DEFAULT_TTL_','60')
* remember to add this line in defines.inc.php
define('_PS_PREDIS_DIR_', _PS_TOOL_DIR_.'predis/')
* autoload call to should be in autoload.php
*/
protected static $_instance;
private $auth;
private $port;
private $host;
private $db;
private $redis_client;
private $default_ttl;
private $short_ttl;
private $medium_ttl;
private $long_ttl;
private $is_connected = false;
const DEFAULT_CONTROLLER_NAME = "none";
const HASHING_ALGORITHM = "sha1";
const SHORT_TTL = '_REDIS_SHORT_TTL_';
const MEDIUM_TTL = '_REDIS_MEDIUM_TTL_';
const LONG_TTL = '_REDIS_LONG_TTL_';
public function __construct()
{
$this->auth = _REDIS_AUTH_STRING_;
$this->host = _REDIS_HOST_STRING_;
$this->port = _REDIS_PORT_STRING_;
$this->db = _REDIS_DB_STRING_;
$this->default_ttl = _REDIS_DEFAULT_TTL_;
$this->short_ttl = defined('_REDIS_SHORT_TTL_') ? _REDIS_SHORT_TTL_ : _REDIS_DEFAULT_TTL_;
$this->medium_ttl = defined('_REDIS_MEDIUM_TTL_') ? _REDIS_MEDIUM_TTL_ : _REDIS_DEFAULT_TTL_;
$this->long_ttl = defined('_REDIS_LONG_TTL_') ? _REDIS_LONG_TTL_ : _REDIS_DEFAULT_TTL_;
if ($this->auth !== '') {
$this->redis_client = new Predis\Client(['scheme' => 'tcp',
'host' => $this->host,
'port' => $this->port,
'password' => $this->auth,
],
['parameters' => [
'database' => (int)$this->db,
],
]);
} else {
$this->redis_client = new Predis\Client(['scheme' => 'tcp',
'host' => $this->host,
'port' => $this->port,
],
['parameters' => [
'database' => (int)$this->db,
],
]);
}
try {
$this->redis_client->connect();
$this->is_connected = $this->redis_client->isConnected();
} catch (Exception $e) {
$this->is_connected = false;
}
}
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new CacheRedis();
}
return self::$_instance;
}
public function get($key, $controller, $ignoreCheckIp = false)
{
if (!$this->isConnected()) {
return false;
}
if (!$ignoreCheckIp && $this->checkIpDisableCache()) {
return false;
}
if ($controller === '') {
$controller = self::DEFAULT_CONTROLLER_NAME;
}
$value = $this->redis_client->get($this->createKey($key, $controller));
if (null === $value) {
return false;
} else {
return $this->decode($value);
}
}
public function delete($key)
{
if (!$this->isConnected()) {
return false;
}
return $this->redis_client->del($key);
}
public function del($key) {
return $this->delete($key);
}
public function set($key, $controller, $value, $expire = null)
{
if (!$this->isConnected()) {
return false;
}
if ($controller === '') {
$controller = self::DEFAULT_CONTROLLER_NAME;
}
if (null === $expire) {
$expire = (int)$this->default_ttl;
} else {
switch ($expire) {
case self::SHORT_TTL:
$expire = (int)$this->short_ttl;
break;
case self::MEDIUM_TTL:
$expire = (int)$this->medium_ttl;
break;
case self::LONG_TTL:
$expire = (int)$this->long_ttl;
break;
default:
$expire = (int)$expire;
break;
}
}
$this->redis_client->setex($this->createKey($key, $controller), $expire, $this->encode($value));
}
public function expire($key, $controller, $expire)
{
if (!$this->isConnected()) {
return false;
}
if ($controller === '') {
$controller = self::DEFAULT_CONTROLLER_NAME;
}
$this->redis_client->expire($this->createKey($key, $controller), $expire);
}
public function isConnected()
{
return $this->is_connected;
}
public function flush()
{
if (!$this->isConnected()) {
return false;
}
$this->redis_client->flushall();
}
public function setQuery($query, $controller, $value, $expire = null)
{
if (!$this->isConnected()) {
return false;
}
if (null === $expire) {
$expire = (int)$this->default_ttl;
} else {
switch ($expire) {
case self::SHORT_TTL:
$expire = (int)$this->short_ttl;
break;
case self::MEDIUM_TTL:
$expire = (int)$this->medium_ttl;
break;
case self::LONG_TTL:
$expire = (int)$this->long_ttl;
break;
default:
$expire = (int)$expire;
break;
}
}
if ($controller === '') {
$controller = self::DEFAULT_CONTROLLER_NAME;
}
if (is_string($query) && trim($query) !== '') {
$this->redis_client->setex($this->createKey($query, $controller), $expire, $this->encode($value));
}
}
public function getQuery($query, $controller, $ignoreCheckIp = false)
{
if (!$this->isConnected()) {
return false;
}
if (!$ignoreCheckIp && $this->checkIpDisableCache()) {
return false;
}
if ($controller === '') {
$controller = self::DEFAULT_CONTROLLER_NAME;
}
$value = null;
if (is_string($query) && trim($query) !== '') {
$value = $this->redis_client->get($this->createKey($query, $controller));
}
if (is_null($value)) {
return false;
} else {
return $this->decode($value);
}
}
public function scan($key, $count = 1024)
{
$result = array();
foreach (new Iterator\Keyspace(
$this->redis_client,
$key,
$count
) as $result_key) {
$result[] = $result_key;
}
return $result;
}
public function clear($key)
{
$keys = $this->scan($key);
$replies = false;
foreach (array_chunk($keys, 256) as $data) {
$pipe = $this->redis_client->pipeline();
foreach ($data as $item) {
$pipe->del($item);
}
$replies = $pipe->execute();
}
return $replies;
}
private function encode($value)
{
return serialize($value);
}
private function decode($value)
{
return unserialize($value);
}
private function createKey($key, $controller)
{
return $controller . '-' . hash(self::HASHING_ALGORITHM, $key);
}
private function checkIpDisableCache()
{
$disableCache = false;
$no_cache_ip = Configuration::get('PS_REDIS_NOCACHE_IP');
if ($no_cache_ip) {
$no_cache_ip_list = explode(',', $no_cache_ip);
if (isset($_SERVER['REMOTE_ADDR']) && in_array($_SERVER['REMOTE_ADDR'], $no_cache_ip_list)) {
$disableCache = true;
}
}
return $disableCache;
}
}