Refactor cache to remove dependency on container
This commit is contained in:
parent
893584696b
commit
6b9770698b
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project default="full-build" name="animeclient" basedir=".">
|
||||
<autoloader autoloaderpath="${project.basedir}/vendor/autoload.php" />
|
||||
<!-- By default, we assume all tools to be on the $PATH -->
|
||||
<property name="pdepend" value="pdepend" />
|
||||
<property name="phpcpd" value="phpcpd" />
|
||||
@ -10,7 +11,7 @@
|
||||
<property name="sonar" value="sonar-runner" />
|
||||
|
||||
<target name="full-build"
|
||||
depends="prepare,static-analysis,phpunit,phpdox,sonar"
|
||||
depends="prepare,static-analysis,phpunit,phpdox"
|
||||
description="Performs static analysis, runs the tests, and generates project documentation"
|
||||
/>
|
||||
<target name="quick-build"
|
||||
|
@ -19,6 +19,8 @@ use GuzzleHttp\Psr7\ResponseInterface;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Cache\CacheInterface;
|
||||
|
||||
use Aviat\Ion\Model;
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
namespace Aviat\AnimeClient\Model;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Model\DB;
|
||||
|
||||
/**
|
||||
* Base model for anime and manga collections
|
||||
@ -36,11 +37,10 @@ class Collection extends DB {
|
||||
* Create a new collection object
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
parent::__construct($container->get('config'));
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -162,7 +162,7 @@ class Manga extends API {
|
||||
$logger->warning("Non 200 response for search api call");
|
||||
$logger->warning($response->getBody());
|
||||
|
||||
throw new RuntimeException($response->getEffectiveUrl());
|
||||
throw new \RuntimeException($response->getEffectiveUrl());
|
||||
}
|
||||
|
||||
return Json::decode($response->getBody(), TRUE);
|
||||
|
@ -18,7 +18,7 @@ namespace Aviat\Ion\Cache;
|
||||
interface CacheInterface {
|
||||
|
||||
/**
|
||||
* Retreive a cached value if it exists, otherwise, get the value
|
||||
* Retrieve a cached value if it exists, otherwise, get the value
|
||||
* from the passed arguments
|
||||
*
|
||||
* @param object $object - object to retrieve fresh value from
|
||||
@ -29,7 +29,7 @@ interface CacheInterface {
|
||||
public function get($object, $method, array $args=[]);
|
||||
|
||||
/**
|
||||
* Retreive a fresh value, and update the cache
|
||||
* Retrieve a fresh value, and update the cache
|
||||
*
|
||||
* @param object $object - object to retrieve fresh value from
|
||||
* @param string $method - method name to call
|
||||
|
@ -13,6 +13,7 @@
|
||||
namespace Aviat\Ion\Cache;
|
||||
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\Driver\DriverInterface;
|
||||
|
||||
/**
|
||||
* Class proxying cached and fresh values from the selected cache driver
|
||||
@ -20,7 +21,7 @@ use Aviat\Ion\ConfigInterface;
|
||||
class CacheManager implements CacheInterface {
|
||||
|
||||
/**
|
||||
* @var CacheDriverInterface
|
||||
* @var DriverInterface
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
|
@ -10,12 +10,12 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace Aviat\Ion\Cache;
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
/**
|
||||
* Interface for cache drivers
|
||||
*/
|
||||
interface CacheDriverInterface {
|
||||
interface DriverInterface {
|
||||
/**
|
||||
* Retreive a value from the cache backend
|
||||
*
|
||||
@ -29,7 +29,7 @@ interface CacheDriverInterface {
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function set($key, $value);
|
||||
|
||||
@ -37,7 +37,7 @@ interface CacheDriverInterface {
|
||||
* Invalidate a cached value
|
||||
*
|
||||
* @param string $key
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function invalidate($key);
|
||||
|
||||
@ -48,4 +48,4 @@ interface CacheDriverInterface {
|
||||
*/
|
||||
public function invalidateAll();
|
||||
}
|
||||
// End of CacheDriverInterface.php
|
||||
// End of DriverInterface.php
|
62
src/Aviat/Ion/Cache/Driver/DriverTrait.php
Normal file
62
src/Aviat/Ion/Cache/Driver/DriverTrait.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Ion
|
||||
*
|
||||
* Building blocks for web development
|
||||
*
|
||||
* @package Ion
|
||||
* @author Timothy J. Warren
|
||||
* @copyright Copyright (c) 2015 - 2016
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\Ion\JsonException;
|
||||
|
||||
/**
|
||||
* Abstract base for Cache drivers to share common functionality
|
||||
*/
|
||||
trait DriverTrait {
|
||||
|
||||
/**
|
||||
* Key prefix for key / value cache stores
|
||||
*/
|
||||
protected static $CACHE_KEY_PREFIX = "hbac:cache:";
|
||||
|
||||
/**
|
||||
* Set key prefix for cache drivers that have global keys
|
||||
*
|
||||
* @param string $key - the raw key name
|
||||
* @return string - the prefixed key name
|
||||
*/
|
||||
protected function prefix($key)
|
||||
{
|
||||
return static::$CACHE_KEY_PREFIX . $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts data to cache to a string representation for storage in a cache
|
||||
*
|
||||
* @param mixed $data - data to store in the cache backend
|
||||
* @return string
|
||||
*/
|
||||
protected function serialize($data)
|
||||
{
|
||||
return Json::encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert serialized data from cache backend to native types
|
||||
*
|
||||
* @param string $data - data from cache backend
|
||||
* @return mixed
|
||||
* @throws JsonException
|
||||
*/
|
||||
protected function unserialize($data)
|
||||
{
|
||||
return Json::decode($data);
|
||||
}
|
||||
}
|
||||
// End of DriverTrait.php
|
@ -11,32 +11,20 @@
|
||||
*/
|
||||
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\CacheDriverInterface;
|
||||
|
||||
/**
|
||||
* The Driver for no real cache
|
||||
*/
|
||||
class NullDriver implements CacheDriverInterface {
|
||||
class NullDriver implements DriverInterface {
|
||||
|
||||
/**
|
||||
* 'Cache' for Null data store
|
||||
*/
|
||||
protected $data;
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* Create the Null cache driver
|
||||
*
|
||||
* @param ConfigInterface $config The configuration management class
|
||||
*/
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive a value from the cache backend
|
||||
* Retrieve a value from the cache backend
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
@ -53,7 +41,7 @@ class NullDriver implements CacheDriverInterface {
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
@ -65,7 +53,7 @@ class NullDriver implements CacheDriverInterface {
|
||||
* Invalidate a cached value
|
||||
*
|
||||
* @param string $key
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function invalidate($key)
|
||||
{
|
||||
|
@ -13,11 +13,15 @@
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\CacheDriverInterface;
|
||||
|
||||
use Predis\Client;
|
||||
|
||||
class RedisDriver implements CacheDriverInterface {
|
||||
/**
|
||||
* Cache Driver for a Redis backend
|
||||
*/
|
||||
class RedisDriver implements DriverInterface {
|
||||
|
||||
use DriverTrait;
|
||||
|
||||
/**
|
||||
* THe Predis library instance
|
||||
@ -35,6 +39,10 @@ class RedisDriver implements CacheDriverInterface {
|
||||
{
|
||||
$redisConfig = $config->get('redis');
|
||||
|
||||
// If you don't have a redis password set, and you attempt to send an
|
||||
// empty string, Redis will think you want to authenticate with a password
|
||||
// that is an empty string. To work around this, empty string passwords
|
||||
// are considered to be a lack of a password
|
||||
if (array_key_exists('password', $redisConfig) && $redisConfig['password'] === '')
|
||||
{
|
||||
unset($redisConfig['password']);
|
||||
@ -54,36 +62,45 @@ class RedisDriver implements CacheDriverInterface {
|
||||
/**
|
||||
* Retrieve a value from the cache backend
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $rawKey
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
public function get($rawKey)
|
||||
{
|
||||
return json_decode($this->redis->get($key));
|
||||
$key = $this->prefix($rawKey);
|
||||
$serializedData = $this->redis->get($key);
|
||||
|
||||
return $this->unserialize($serializedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cached value
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $rawKey
|
||||
* @param mixed $value
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function set($key, $value)
|
||||
public function set($rawKey, $value)
|
||||
{
|
||||
$this->redis->set($key, json_encode($value));
|
||||
$key = $this->prefix($rawKey);
|
||||
$serializedData = $this->serialize($value);
|
||||
|
||||
$this->redis->set($key, $serializedData);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate a cached value
|
||||
*
|
||||
* @param string $key
|
||||
* @return CacheDriverInterface
|
||||
* @param string $rawKey
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function invalidate($key)
|
||||
public function invalidate($rawKey)
|
||||
{
|
||||
$key = $this->prefix($rawKey);
|
||||
$this->redis->del($key);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -94,7 +111,7 @@ class RedisDriver implements CacheDriverInterface {
|
||||
*/
|
||||
public function invalidateAll()
|
||||
{
|
||||
$this->redis->flushDB();
|
||||
$this->redis->flushdb();
|
||||
}
|
||||
}
|
||||
// End of RedisDriver.php
|
@ -13,14 +13,15 @@
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\CacheDriverInterface;
|
||||
use Aviat\Ion\Exception\ConfigException;
|
||||
use Aviat\Ion\Model\DB;
|
||||
|
||||
/**
|
||||
* Driver for caching via a traditional SQL database
|
||||
*/
|
||||
class SQLDriver extends DB implements CacheDriverInterface {
|
||||
class SQLDriver extends DB implements DriverInterface {
|
||||
|
||||
use DriverTrait;
|
||||
|
||||
/**
|
||||
* The query builder object
|
||||
@ -60,12 +61,14 @@ class SQLDriver extends DB implements CacheDriverInterface {
|
||||
->get();
|
||||
|
||||
$row = $query->fetch(\PDO::FETCH_ASSOC);
|
||||
if ( ! empty($row))
|
||||
|
||||
if (empty($row))
|
||||
{
|
||||
return json_decode($row['value']);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
$serializedData = $row['value'];
|
||||
return $this->unserialize($serializedData);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,15 +76,17 @@ class SQLDriver extends DB implements CacheDriverInterface {
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$serializedData = $this->serialize($value);
|
||||
|
||||
$this->db->set([
|
||||
'key' => $key,
|
||||
'value' => json_encode($value),
|
||||
'value' => $serializedData,
|
||||
]);
|
||||
|
||||
|
||||
$this->db->insert('cache');
|
||||
|
||||
return $this;
|
||||
@ -91,7 +96,7 @@ class SQLDriver extends DB implements CacheDriverInterface {
|
||||
* Invalidate a cached value
|
||||
*
|
||||
* @param string $key
|
||||
* @return CacheDriverInterface
|
||||
* @return DriverInterface
|
||||
*/
|
||||
public function invalidate($key)
|
||||
{
|
||||
|
@ -60,7 +60,15 @@ class Json {
|
||||
*/
|
||||
public static function decode($json, $assoc = TRUE, $depth = 512, $options = 0)
|
||||
{
|
||||
$data = json_decode($json, $assoc, $depth, $options);
|
||||
// Don't try to decode null
|
||||
if (empty($json))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// cast json to string so that streams from guzzle are correctly decoded
|
||||
$data = json_decode((string) $json, $assoc, $depth, $options);
|
||||
|
||||
self::check_json_error();
|
||||
return $data;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ class AnimeCollectionModelTest extends AnimeClient_TestCase {
|
||||
public function testSanity()
|
||||
{
|
||||
$friend = new Friend($this->collectionModel);
|
||||
$this->assertInstanceOf('Aviat\AnimeClient\Model\DB', $this->collectionModel);
|
||||
$this->assertInstanceOf('Aviat\Ion\Model\DB', $this->collectionModel);
|
||||
$this->assertInstanceOf('Aviat\AnimeClient\Model\Anime', $friend->anime_model);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ use GuzzleHttp\Psr7\Response;
|
||||
use Zend\Diactoros\ServerRequestFactory;
|
||||
use Zend\Diactoros\Response as HttpResponse;
|
||||
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
|
||||
define('ROOT_DIR', __DIR__ . '/../');
|
||||
@ -119,6 +120,36 @@ class AnimeClient_TestCase extends PHPUnit_Framework_TestCase {
|
||||
$this->container->set('response', new HttpResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplify getting test data
|
||||
*
|
||||
* Takes multiple path arguments
|
||||
*
|
||||
* @return string - contents of the data file
|
||||
*/
|
||||
public function getMockFile()
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_unshift($args, TEST_DATA_DIR);
|
||||
$filePath = implode(DIRECTORY_SEPARATOR, $args);
|
||||
|
||||
return file_get_contents($filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplify getting mocked test data
|
||||
*
|
||||
* Takes multiple path arguments
|
||||
*
|
||||
* @return mixed - the decoded data
|
||||
*/
|
||||
public function getMockFileData()
|
||||
{
|
||||
$rawData = call_user_func_array([$this, 'getMockFile'], func_get_args());
|
||||
|
||||
return Json::decode($rawData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock guzzle client for testing
|
||||
* api call methods
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Aviat\AnimeClient\Model\DB as BaseDBModel;
|
||||
use Aviat\Ion\Model\DB as BaseDBModel;
|
||||
|
||||
class BaseDBModelTest extends AnimeClient_TestCase {
|
||||
|
||||
public function testBaseDBModelSanity()
|
||||
{
|
||||
$baseDBModel = new BaseDBModel($this->container);
|
||||
$baseDBModel = new BaseDBModel($this->container->get('config'));
|
||||
$this->assertTrue(is_object($baseDBModel));
|
||||
}
|
||||
}
|
@ -3,9 +3,6 @@
|
||||
* Global setup for unit tests
|
||||
*/
|
||||
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
|
||||
// Work around the silly timezone error
|
||||
$timezone = ini_get('date.timezone');
|
||||
if ($timezone === '' || $timezone === FALSE)
|
||||
|
@ -6,7 +6,6 @@
|
||||
use Aviat\Ion\Enum;
|
||||
use Aviat\Ion\Friend;
|
||||
use Aviat\Ion\Json;
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
||||
use Aviat\Ion\View;
|
||||
use Aviat\Ion\View\HtmlView;
|
||||
|
Loading…
Reference in New Issue
Block a user