connected === true && $this->ping() === true) { return $this->server->set( $key, ($this->isRedis ? ($this->IgBinarySupport ? igbinary_serialize($data) : serialize($data)) : $data), $expiration ); } return false; } /** * Attempt to retrieve a value from the cache server, if not set it. * * @param string $key Key we can use to retrieve the data. * * @return bool|string False on failure or String, data belonging to the key. * @access public */ public function get($key) { if ($this->connected === true && $this->ping() === true) { $data = $this->server->get($key); return ($this->isRedis ? ($this->IgBinarySupport ? igbinary_unserialize($data) : unserialize($data)) : $data); } return false; } /** * Delete data tied to a key on the cache server. * * @param string $key Key we can use to retrieve the data. * * @return bool True if deleted, false if not. * @access public */ public function delete($key) { if ($this->connected === true && $this->ping() === true) { return (bool)$this->server->delete($key); } return false; } /** * Flush all data from the cache server? */ public function flush() { if ($this->connected === true && $this->ping() === true) { if ($this->isRedis === true) { $this->server->flushAll(); } else { $this->server->flush(); } } } /** * Create a SHA1 hash from a string which can be used to store/retrieve data. * * @param string $string * * @return string SHA1 hash of the input string. * @access public */ public function createKey($string) { return sha1($string); } /** * Get cache server statistics. * * @return array|string * @access public */ public function serverStatistics() { if ($this->connected === true && $this->ping() === true) { if ($this->isRedis === true) { return $this->server->info(); } else { return $this->server->getStats(); } } return array(); } /** * Verify the user's cache settings, try to connect to the cache server. */ public function __construct() { if (!defined('NN_CACHE_HOSTS')) { throw new \CacheException( 'The NN_CACHE_HOSTS is not defined! Define it in settings.php' ); } if (!defined('NN_CACHE_TIMEOUT')) { throw new \CacheException( 'The NN_CACHE_TIMEOUT is not defined! Define it in settings.php, it is the time in seconds to time out from your cache server.' ); } $this->socketFile = false; if (defined('NN_CACHE_SOCKET_FILE') && NN_CACHE_SOCKET_FILE != '') { $this->socketFile = true; } $this->serializerType = false; if (defined('NN_CACHE_SERIALIZER')) { $this->serializerType = true; } switch (NN_CACHE_TYPE) { case self::TYPE_REDIS: if (!extension_loaded('redis')) { throw new CacheException('The redis extension is not loaded!'); } $this->server = new \Redis(); $this->isRedis = true; $this->connect(); if ($this->serializerType !== false) { $this->serializerType = $this->verifySerializer(); $this->server->setOption(\Redis::OPT_SERIALIZER, $this->serializerType); } break; case self::TYPE_MEMCACHED: if (!extension_loaded('memcached')) { throw new CacheException('The memcached extension is not loaded!'); } $this->server = new \Memcached(); $this->isRedis = false; if ($this->serializerType !== false) { $this->serializerType = $this->verifySerializer(); $this->server->setOption(\Memcached::OPT_SERIALIZER, $this->serializerType); } $this->server->setOption(\Memcached::OPT_COMPRESSION, (defined('NN_CACHE_COMPRESSION') ? NN_CACHE_COMPRESSION : false)); $this->connect(); break; case self::TYPE_DISABLED: default: return; } } /** * Destroy the connections. */ public function __destruct() { switch (NN_CACHE_TYPE) { case self::TYPE_REDIS: $this->server->close(); break; case self::TYPE_MEMCACHED: $this->server->quit(); break; } } /** * Connect to the cache server(s). * * @throws CacheException * @access private */ private function connect() { $this->connected = false; if ($this->isRedis === true) { if ($this->socketFile === false) { $servers = unserialize(NN_CACHE_HOSTS); foreach ($servers as $server) { if ($this->server->connect($server['host'], $server['port'], (float)NN_CACHE_TIMEOUT) === false) { throw new CacheException('Error connecting to the Redis server!'); } else { $this->connected = true; } } } else { if ($this->server->connect(NN_CACHE_SOCKET_FILE) === false) { throw new CacheException('Error connecting to the Redis server!'); } else { $this->connected = true; } } } else { if ($this->socketFile === false) { if ($this->server->addServers(unserialize(NN_CACHE_HOSTS)) === false) { throw new CacheException('Error connecting to the Memcached server!'); } else { $this->connected = true; } } else { if ($this->server->addServers(array(array(NN_CACHE_SOCKET_FILE, 'port' => 0))) === false) { throw new CacheException('Error connecting to the Memcached server!'); } else { $this->connected = true; } } } } /** * Redis supports ping'ing the server, so use it. */ private function ping() { if ($this->isRedis === true) { try { return (bool)$this->server->ping(); } catch (\RedisException $error) { $this->connect(); return $this->connected; } } return true; } /** * Verify the user selected serializer, return the memcached or redis appropriate serializer option. * * @return int * @throws CacheException * @access private */ private function verifySerializer() { switch (NN_CACHE_SERIALIZER) { case self::SERIALIZER_IGBINARY: if (extension_loaded('igbinary')) { $this->IgBinarySupport = true; if ($this->isRedis === true) { return \Redis::SERIALIZER_IGBINARY; } else { if (\Memcached::HAVE_IGBINARY > 0) { return \Memcached::SERIALIZER_IGBINARY; } else { throw new CacheException('Error: You have not compiled Memcached with igbinary support!'); } } } else { throw new CacheException('Error: The igbinary extension is not loaded!'); } case self::SERIALIZER_NONE: if ($this->isRedis === true) { return \Redis::SERIALIZER_NONE; } else { throw new CacheException('Error: Disabled serialization is not available on Memcached!'); } case self::SERIALIZER_PHP: default: if ($this->isRedis === true) { return \Redis::SERIALIZER_PHP; } else { return \Memcached::SERIALIZER_PHP; } } } } /** * Class CacheException * * @package newznab\libraries */ class CacheException extends \Exception { }