diff --git a/app/bootstrap.php b/app/bootstrap.php index e4958ca7..e98f54f2 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -15,6 +15,7 @@ use Zend\Diactoros\ServerRequestFactory; use Zend\Diactoros\Response; use Aviat\Ion\Di\Container; +use Aviat\Ion\Cache\CacheManager; use Aviat\AnimeClient\Auth\HummingbirdAuth; use Aviat\AnimeClient\Model; @@ -30,7 +31,6 @@ return function(array $config_array = []) { $app_logger = new Logger('animeclient'); $app_logger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::NOTICE)); - $app_logger->pushHandler(new BrowserConsoleHandler(Logger::INFO)); $container->setLogger($app_logger, 'default'); // ------------------------------------------------------------------------- @@ -83,6 +83,8 @@ return function(array $config_array = []) { $container->set('anime-collection-model', new Model\AnimeCollection($container)); $container->set('auth', new HummingbirdAuth($container)); + + $container->set('cache', new CacheManager($container)); // ------------------------------------------------------------------------- // Dispatcher diff --git a/app/config/config.toml.example b/app/config/config.toml.example index a5afd3a6..9e311655 100644 --- a/app/config/config.toml.example +++ b/app/config/config.toml.example @@ -14,5 +14,8 @@ show_anime_collection = true # do you wish to show the manga collection? show_manga_collection = false +# cache driver for api calls (SQLDriver, RedisDriver, MemcacheDriver) +cache_driver = SQLDriver + # path to public directory on the server asset_dir = "/../../public" \ No newline at end of file diff --git a/migrations/20160404202433_cache_migration.php b/migrations/20160404202433_cache_migration.php index 59450fbf..e1ba079d 100644 --- a/migrations/20160404202433_cache_migration.php +++ b/migrations/20160404202433_cache_migration.php @@ -27,8 +27,8 @@ class CacheMigration extends AbstractMigration */ public function change() { - $this->table('cache', ['id' => FALSE, 'primary_key' => ['key']]) - ->addColumn('key', 'text') + $cacheTable = $this->table('cache', ['id' => FALSE, 'primary_key' => ['key']]); + $cacheTable->addColumn('key', 'text') ->addColumn('value', 'text') ->create(); } diff --git a/src/Aviat/AnimeClient/Controller/Anime.php b/src/Aviat/AnimeClient/Controller/Anime.php index 99372c0a..270c6108 100644 --- a/src/Aviat/AnimeClient/Controller/Anime.php +++ b/src/Aviat/AnimeClient/Controller/Anime.php @@ -37,6 +37,11 @@ class Anime extends BaseController { * @var array $base_data */ protected $base_data; + + /** + * Data cache + */ + protected $cache; /** * Constructor @@ -55,6 +60,8 @@ class Anime extends BaseController { 'other_type' => 'manga', 'config' => $this->config, ]); + + $this->cache = $container->get('cache'); } /** @@ -98,10 +105,14 @@ class Anime extends BaseController { '' => 'cover', 'list' => 'list' ]; - + $data = ($type != 'all') + ? $this->cache->get($this->model, 'get_list', ['status' => $model_map[$type]]) + : $this->cache->get($this->model, 'get_all_lists', []); + + /*$data = ($type != 'all') ? $this->model->get_list($model_map[$type]) - : $this->model->get_all_lists(); + : $this->model->get_all_lists();*/ $this->outputHTML('anime/' . $view_map[$view], [ 'title' => $title, diff --git a/src/Aviat/Ion/Cache/CacheDriverInterface.php b/src/Aviat/Ion/Cache/CacheDriverInterface.php index 4c45ba3f..add6cef0 100644 --- a/src/Aviat/Ion/Cache/CacheDriverInterface.php +++ b/src/Aviat/Ion/Cache/CacheDriverInterface.php @@ -1,36 +1,44 @@ -get('config'); + $driverConf = $config->get('cache_driver'); + + $driverClass = __NAMESPACE__ . "\\Driver\\{$driverConf}"; + $driver = new $driverClass($container); + + $this->driver = $driver; + } + + /** + * Retreive a cached value if it exists, otherwise, get the value + * from the passed arguments + * + * @param object $object - object to retrieve fresh value from + * @param string $method - method name to call + * @param [array] $args - the arguments to pass to the retrieval method + * @return mixed - the cached or fresh data + */ + public function get($object, $method, array $args=[]) + { + $hash = $this->generateHashForMethod($object, $method, $args); + + $data = $this->driver->get($hash); + + if (empty($data)) + { + $data = call_user_func_array([$object, $method], $args); + $this->driver->set($hash, $data); + } + + return $data; + } + + /** + * Retreive a fresh value from the method, and update the cache + * @param object $object - object to retrieve fresh value from + * @param string $method - method name to call + * @param [array] $args - the arguments to pass to the retrieval method + * @return mixed - the fresh data + */ + public function getFresh($object, $method, array $args=[]) + { + $hash = $this->generateHashForMethod($object, $method, $args); + $data = call_user_func_array([$object, $method], $args); + $this->driver->set($hash, $data); + return $data; + } + + /** + * Generate a hash as a cache key from the current method call + * + * @param object $object + * @param string $method + * @param array $args + * @return string + */ + public function generateHashForMethod($object, $method, array $args) + { + $classname = get_class($object); + $keyObj = [ + 'class' => $classname, + 'method' => $method, + 'args' => $args, + ]; + $hash = sha1(json_encode($keyObj)); + return $hash; + } +} +// End of CacheManager.php \ No newline at end of file diff --git a/src/Aviat/Ion/Cache/Driver/SQLDriver.php b/src/Aviat/Ion/Cache/Driver/SQLDriver.php new file mode 100644 index 00000000..e5ac36f7 --- /dev/null +++ b/src/Aviat/Ion/Cache/Driver/SQLDriver.php @@ -0,0 +1,110 @@ +db = \Query($this->db_config['collection']); + } + catch (\PDOException $e) + { + $this->valid_database = FALSE; + return FALSE; + } + } + + /** + * Retreive a value from the cache backend + * + * @param string $key + * @return mixed + */ + public function get($key) + { + $query = $this->db->select('value') + ->from('cache') + ->where('key', $key) + ->get(); + + $row = $query->fetch(\PDO::FETCH_ASSOC); + if ( ! empty($row)) + { + return unserialize($row['value']); + } + + return NULL; + } + + /** + * Set a cached value + * + * @param string $key + * @param mixed $value + * @return CacheDriverInterface + */ + public function set($key, $value) + { + $this->db->set([ + 'key' => $key, + 'value' => serialize($value), + ]); + + /*if ( ! empty($this->get($key))) + { + $this->db->update('cache'); + } + else*/ + { + $this->db->insert('cache'); + } + + return $this; + } + + /** + * Invalidate a cached value + * + * @param string $key + * @return CacheDriverInterface + */ + public function invalidate($key) + { + $this->db->where('key', $key) + ->delete('cache'); + + return $this; + } +} +// End of SQLDriver.php \ No newline at end of file