Version 5.1 - All the GraphQL #32
@ -41,7 +41,7 @@ return function(array $config_array = []) {
|
||||
$container->set('config', $config);
|
||||
|
||||
// Create Cache Object
|
||||
$container->set('cache', new CacheManager($container));
|
||||
$container->set('cache', new CacheManager($config));
|
||||
|
||||
// Create Aura Router Object
|
||||
$container->set('aura-router', new RouterContainer);
|
||||
@ -71,9 +71,9 @@ return function(array $config_array = []) {
|
||||
$container->set('session', $session);
|
||||
|
||||
// Miscellaneous helper methods
|
||||
$anime_client = new AnimeClient();
|
||||
$anime_client->setContainer($container);
|
||||
$container->set('anime-client', $anime_client);
|
||||
$util = new Util($container);
|
||||
$container->set('anime-client', $util);
|
||||
$container->set('util', $util);
|
||||
|
||||
// Models
|
||||
$container->set('api-model', new Model\API($container));
|
||||
|
@ -50,8 +50,8 @@
|
||||
<?= $helper->menu($menu_name) ?>
|
||||
<br />
|
||||
<ul>
|
||||
<li class="<?= AnimeClient::is_not_selected('list', $urlGenerator->last_segment()) ?>"><a href="<?= $urlGenerator->url($route_path) ?>">Cover View</a></li>
|
||||
<li class="<?= AnimeClient::is_selected('list', $urlGenerator->last_segment()) ?>"><a href="<?= $urlGenerator->url("{$route_path}/list") ?>">List View</a></li>
|
||||
<li class="<?= Util::is_not_selected('list', $urlGenerator->last_segment()) ?>"><a href="<?= $urlGenerator->url($route_path) ?>">Cover View</a></li>
|
||||
<li class="<?= Util::is_selected('list', $urlGenerator->last_segment()) ?>"><a href="<?= $urlGenerator->url("{$route_path}/list") ?>">List View</a></li>
|
||||
</ul>
|
||||
<?php endif ?>
|
||||
</nav>
|
||||
|
@ -18,12 +18,11 @@ use Yosymfony\Toml\Toml;
|
||||
define('SRC_DIR', realpath(__DIR__ . '/../../'));
|
||||
|
||||
/**
|
||||
* Odds and Ends class
|
||||
* Application constants
|
||||
*/
|
||||
class AnimeClient {
|
||||
|
||||
use \Aviat\Ion\Di\ContainerAware;
|
||||
|
||||
const HUMMINGBIRD_AUTH_URL = 'https://hummingbird.me/api/v1/users/authenticate';
|
||||
const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth';
|
||||
const DEFAULT_CONTROLLER_NAMESPACE = 'Aviat\AnimeClient\Controller';
|
||||
const DEFAULT_CONTROLLER = 'Aviat\AnimeClient\Controller\Anime';
|
||||
@ -32,67 +31,6 @@ class AnimeClient {
|
||||
const ERROR_MESSAGE_METHOD = 'error_page';
|
||||
const SRC_DIR = SRC_DIR;
|
||||
|
||||
private static $form_pages = [
|
||||
'edit',
|
||||
'add',
|
||||
'update',
|
||||
'update_form',
|
||||
'login',
|
||||
'logout',
|
||||
'details'
|
||||
];
|
||||
|
||||
/**
|
||||
* HTML selection helper function
|
||||
*
|
||||
* @param string $a - First item to compare
|
||||
* @param string $b - Second item to compare
|
||||
* @return string
|
||||
*/
|
||||
public static function is_selected($a, $b)
|
||||
{
|
||||
return ($a === $b) ? 'selected' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse of selected helper function
|
||||
*
|
||||
* @param string $a - First item to compare
|
||||
* @param string $b - Second item to compare
|
||||
* @return string
|
||||
*/
|
||||
public static function is_not_selected($a, $b)
|
||||
{
|
||||
return ($a !== $b) ? 'selected' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to show the sub-menu
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_view_page()
|
||||
{
|
||||
$url = $this->container->get('request')
|
||||
->getUri();
|
||||
$page_segments = explode("/", $url);
|
||||
|
||||
$intersect = array_intersect($page_segments, self::$form_pages);
|
||||
|
||||
return empty($intersect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the page is a page with a form, and
|
||||
* not suitable for redirection
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_form_page()
|
||||
{
|
||||
return ! $this->is_view_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load configuration options from .toml files
|
||||
*
|
||||
|
@ -15,7 +15,6 @@ namespace Aviat\AnimeClient\Auth;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
use Aviat\AnimeClient\Model\API;
|
||||
|
||||
/**
|
||||
* Hummingbird API Authentication
|
||||
@ -102,6 +101,5 @@ class HummingbirdAuth {
|
||||
{
|
||||
return $this->segment->get('auth_token', FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
// End of HummingbirdAuth.php
|
@ -51,7 +51,7 @@ class BaseCommand extends Command {
|
||||
*/
|
||||
protected function setupContainer()
|
||||
{
|
||||
$CONF_DIR = __DIR__ . '/../../../../app/config/';
|
||||
$CONF_DIR = realpath(__DIR__ . '/../../../../app/config/');
|
||||
require_once $CONF_DIR . '/base_config.php'; // $base_config
|
||||
|
||||
$config = AnimeClient::load_toml($CONF_DIR);
|
||||
@ -65,7 +65,7 @@ class BaseCommand extends Command {
|
||||
$container->set('config', $config);
|
||||
|
||||
// Create Cache Object
|
||||
$container->set('cache', new CacheManager($container));
|
||||
$container->set('cache', new CacheManager($config));
|
||||
|
||||
// Create session Object
|
||||
$session = (new SessionFactory())->newInstance($_COOKIE);
|
||||
|
@ -13,12 +13,14 @@
|
||||
|
||||
namespace Aviat\AnimeClient;
|
||||
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Wrapper for configuration values
|
||||
*/
|
||||
class Config {
|
||||
class Config implements ConfigInterface {
|
||||
|
||||
use \Aviat\Ion\ArrayWrapper;
|
||||
|
||||
|
@ -17,7 +17,6 @@ use Aura\Web\Response;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\Friend;
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,8 @@ use GuzzleHttp\Psr7\ResponseInterface;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\AnimeClient\Model as BaseModel;
|
||||
use Aviat\Ion\Model;
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
|
||||
/**
|
||||
* Base model for api interaction
|
||||
@ -32,7 +33,15 @@ use Aviat\AnimeClient\Model as BaseModel;
|
||||
* @method ResponseInterface post(string $uri, array $options);
|
||||
* @method ResponseInterface put(string $uri, array $options);
|
||||
*/
|
||||
class API extends BaseModel {
|
||||
class API extends Model {
|
||||
|
||||
use \Aviat\Ion\Di\ContainerAware;
|
||||
|
||||
/**
|
||||
* Config manager
|
||||
* @var ConfigInterface
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Base url for making api requests
|
||||
@ -65,7 +74,8 @@ class API extends BaseModel {
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->container = $container;
|
||||
$this->config = $container->get('config');
|
||||
$this->cache = $container->get('cache');
|
||||
$this->init();
|
||||
}
|
||||
@ -171,7 +181,7 @@ class API extends BaseModel {
|
||||
*/
|
||||
public function authenticate($username, $password)
|
||||
{
|
||||
$response = $this->post('https://hummingbird.me/api/v1/users/authenticate', [
|
||||
$response = $this->post(AnimeClient::HUMMINGBIRD_AUTH_URL, [
|
||||
'form_params' => [
|
||||
'username' => $username,
|
||||
'password' => $password
|
||||
|
@ -226,9 +226,10 @@ class Anime extends API {
|
||||
$response = $this->get("users/{$username}/library", $config);
|
||||
$output = $this->transform($status, $response);
|
||||
|
||||
$util = $this->container->get('util');
|
||||
foreach ($output as &$row)
|
||||
{
|
||||
$row['anime']['image'] = $this->get_cached_image($row['anime']['image'], $row['anime']['slug'], 'anime');
|
||||
$row['anime']['image'] = $util->get_cached_image($row['anime']['image'], $row['anime']['slug'], 'anime');
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
@ -36,7 +36,7 @@ class Collection extends DB {
|
||||
* Create a new collection object
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
* @return boolean
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
|
@ -13,12 +13,14 @@
|
||||
namespace Aviat\AnimeClient\Model;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\AnimeClient\Model as BaseModel;
|
||||
use Aviat\Ion\Model;
|
||||
|
||||
/**
|
||||
* Base model for database interaction
|
||||
*/
|
||||
class DB extends BaseModel {
|
||||
class DB extends Model {
|
||||
use \Aviat\Ion\Di\ContainerAware;
|
||||
|
||||
/**
|
||||
* The query builder object
|
||||
* @var object $db
|
||||
@ -38,8 +40,8 @@ class DB extends BaseModel {
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->db_config = (array)$this->config->get('database');
|
||||
$this->db_config = $container->get('config')->get('database');
|
||||
$this->setContainer($container);
|
||||
}
|
||||
}
|
||||
// End of BaseDBModel.php
|
||||
// End of DB.php
|
@ -252,9 +252,11 @@ class Manga extends API {
|
||||
self::COMPLETED => [],
|
||||
];
|
||||
|
||||
$util = $this->container->get('util');
|
||||
|
||||
foreach ($data as &$entry)
|
||||
{
|
||||
$entry['manga']['image'] = $this->get_cached_image(
|
||||
$entry['manga']['image'] = $util->get_cached_image(
|
||||
$entry['manga']['image'],
|
||||
$entry['manga']['slug'],
|
||||
'manga'
|
||||
|
@ -1,140 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* Hummingbird Anime Client
|
||||
*
|
||||
* An API client for Hummingbird to manage anime and manga watch lists
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren
|
||||
* @copyright Copyright (c) 2015 - 2016
|
||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
||||
* @license MIT
|
||||
*/
|
||||
namespace Aviat\AnimeClient;
|
||||
|
||||
use abeautifulsite\SimpleImage;
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Common base for all Models
|
||||
*/
|
||||
class Model {
|
||||
|
||||
use \Aviat\Ion\StringWrapper;
|
||||
|
||||
/**
|
||||
* The global configuration object
|
||||
* @var Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* The container object
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->config = $container->get('config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path of the cached version of the image. Create the cached image
|
||||
* if the file does not already exist
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param string $api_path - The original image url
|
||||
* @param string $series_slug - The part of the url with the series name, becomes the image name
|
||||
* @param string $type - Anime or Manga, controls cache path
|
||||
* @return string - the frontend path for the cached image
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function get_cached_image($api_path, $series_slug, $type = "anime")
|
||||
{
|
||||
$path_parts = explode('?', basename($api_path));
|
||||
$path = current($path_parts);
|
||||
$ext_parts = explode('.', $path);
|
||||
$ext = end($ext_parts);
|
||||
|
||||
// Workaround for some broken file extensions
|
||||
if ($ext == "jjpg")
|
||||
{
|
||||
$ext = "jpg";
|
||||
}
|
||||
|
||||
// Failsafe for weird urls
|
||||
if (strlen($ext) > 3)
|
||||
{
|
||||
return $api_path;
|
||||
}
|
||||
|
||||
$img_cache_path = $this->config->get('img_cache_path');
|
||||
$cached_image = "{$series_slug}.{$ext}";
|
||||
$cached_path = "{$img_cache_path}/{$type}/{$cached_image}";
|
||||
|
||||
// Cache the file if it doesn't already exist
|
||||
if ( ! file_exists($cached_path))
|
||||
{
|
||||
if (function_exists('curl_init'))
|
||||
{
|
||||
$ch = curl_init($api_path);
|
||||
$fp = fopen($cached_path, 'wb');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_FILE => $fp,
|
||||
CURLOPT_HEADER => 0
|
||||
]);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
else if (ini_get('allow_url_fopen'))
|
||||
{
|
||||
copy($api_path, $cached_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DomainException("Couldn't cache images because they couldn't be downloaded.");
|
||||
}
|
||||
|
||||
// Resize the image
|
||||
if ($type == 'anime')
|
||||
{
|
||||
$resize_width = 220;
|
||||
$resize_height = 319;
|
||||
$this->_resize($cached_path, $resize_width, $resize_height);
|
||||
}
|
||||
}
|
||||
|
||||
return "/public/images/{$type}/{$cached_image}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize an image
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param string $path
|
||||
* @param string $width
|
||||
* @param string $height
|
||||
*/
|
||||
private function _resize($path, $width, $height)
|
||||
{
|
||||
try
|
||||
{
|
||||
$img = new SimpleImage($path);
|
||||
$img->resize($width, $height)->save();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Catch image errors, since they don't otherwise affect
|
||||
// functionality
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of BaseModel.php
|
||||
<?php
|
||||
/**
|
||||
* Hummingbird Anime Client
|
||||
*
|
||||
* An API client for Hummingbird to manage anime and manga watch lists
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren
|
||||
* @copyright Copyright (c) 2015 - 2016
|
||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
||||
* @license MIT
|
||||
*/
|
||||
namespace Aviat\AnimeClient;
|
||||
|
||||
use abeautifulsite\SimpleImage;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Utility method class
|
||||
*/
|
||||
class Util {
|
||||
|
||||
use \Aviat\Ion\Di\ContainerAware;
|
||||
|
||||
private static $form_pages = [
|
||||
'edit',
|
||||
'add',
|
||||
'update',
|
||||
'update_form',
|
||||
'login',
|
||||
'logout',
|
||||
'details'
|
||||
];
|
||||
|
||||
/**
|
||||
* The config manager
|
||||
* @var ConfigInterface
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Set up the Util class
|
||||
*
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->setContainer($container);
|
||||
$this->config = $container->get('config');
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML selection helper function
|
||||
*
|
||||
* @param string $a - First item to compare
|
||||
* @param string $b - Second item to compare
|
||||
* @return string
|
||||
*/
|
||||
public static function is_selected($a, $b)
|
||||
{
|
||||
return ($a === $b) ? 'selected' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse of selected helper function
|
||||
*
|
||||
* @param string $a - First item to compare
|
||||
* @param string $b - Second item to compare
|
||||
* @return string
|
||||
*/
|
||||
public static function is_not_selected($a, $b)
|
||||
{
|
||||
return ($a !== $b) ? 'selected' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to show the sub-menu
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_view_page()
|
||||
{
|
||||
$url = $this->container->get('request')
|
||||
->getUri();
|
||||
$page_segments = explode("/", $url);
|
||||
|
||||
$intersect = array_intersect($page_segments, self::$form_pages);
|
||||
|
||||
return empty($intersect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the page is a page with a form, and
|
||||
* not suitable for redirection
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_form_page()
|
||||
{
|
||||
return ! $this->is_view_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path of the cached version of the image. Create the cached image
|
||||
* if the file does not already exist
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param string $api_path - The original image url
|
||||
* @param string $series_slug - The part of the url with the series name, becomes the image name
|
||||
* @param string $type - Anime or Manga, controls cache path
|
||||
* @return string - the frontend path for the cached image
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function get_cached_image($api_path, $series_slug, $type = "anime")
|
||||
{
|
||||
$path_parts = explode('?', basename($api_path));
|
||||
$path = current($path_parts);
|
||||
$ext_parts = explode('.', $path);
|
||||
$ext = end($ext_parts);
|
||||
|
||||
// Workaround for some broken file extensions
|
||||
if ($ext == "jjpg")
|
||||
{
|
||||
$ext = "jpg";
|
||||
}
|
||||
|
||||
// Failsafe for weird urls
|
||||
if (strlen($ext) > 3)
|
||||
{
|
||||
return $api_path;
|
||||
}
|
||||
|
||||
$img_cache_path = $this->config->get('img_cache_path');
|
||||
$cached_image = "{$series_slug}.{$ext}";
|
||||
$cached_path = "{$img_cache_path}/{$type}/{$cached_image}";
|
||||
|
||||
// Cache the file if it doesn't already exist
|
||||
if ( ! file_exists($cached_path))
|
||||
{
|
||||
if (function_exists('curl_init'))
|
||||
{
|
||||
$ch = curl_init($api_path);
|
||||
$fp = fopen($cached_path, 'wb');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_FILE => $fp,
|
||||
CURLOPT_HEADER => 0
|
||||
]);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
else if (ini_get('allow_url_fopen'))
|
||||
{
|
||||
copy($api_path, $cached_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \DomainException("Couldn't cache images because they couldn't be downloaded.");
|
||||
}
|
||||
|
||||
// Resize the image
|
||||
if ($type == 'anime')
|
||||
{
|
||||
$resize_width = 220;
|
||||
$resize_height = 319;
|
||||
$this->_resize($cached_path, $resize_width, $resize_height);
|
||||
}
|
||||
}
|
||||
|
||||
return "/public/images/{$type}/{$cached_image}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize an image
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param string $path
|
||||
* @param string $width
|
||||
* @param string $height
|
||||
*/
|
||||
private function _resize($path, $width, $height)
|
||||
{
|
||||
try
|
||||
{
|
||||
$img = new SimpleImage($path);
|
||||
$img->resize($width, $height)->save();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Catch image errors, since they don't otherwise affect
|
||||
// functionality
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
|
||||
namespace Aviat\Ion\Cache;
|
||||
|
||||
use \Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
|
||||
/**
|
||||
* Class proxying cached and fresh values from the selected cache driver
|
||||
@ -25,11 +25,12 @@ class CacheManager implements CacheInterface {
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* Retreive the appropriate driver from the container
|
||||
* Retrieve the appropriate driver from the container
|
||||
*
|
||||
* @param ConfigInterface $config The configuration management class
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
$config = $container->get('config');
|
||||
$driverConf = $config->get('cache_driver');
|
||||
|
||||
if (empty($driverConf))
|
||||
@ -38,13 +39,13 @@ class CacheManager implements CacheInterface {
|
||||
}
|
||||
|
||||
$driverClass = __NAMESPACE__ . "\\Driver\\{$driverConf}";
|
||||
$driver = new $driverClass($container);
|
||||
$driver = new $driverClass($config);
|
||||
|
||||
$this->driver = $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -68,7 +69,7 @@ class CacheManager implements CacheInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive a fresh value from the method, and update the cache
|
||||
* Retrieve 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
|
||||
|
@ -12,12 +12,13 @@
|
||||
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\CacheDriverInterface;
|
||||
|
||||
/**
|
||||
* The Driver for no real cache
|
||||
*/
|
||||
class NullDriver implements \Aviat\Ion\Cache\CacheDriverInterface {
|
||||
class NullDriver implements CacheDriverInterface {
|
||||
|
||||
/**
|
||||
* 'Cache' for Null data store
|
||||
@ -25,9 +26,11 @@ class NullDriver implements \Aviat\Ion\Cache\CacheDriverInterface {
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Create the Redis cache driver
|
||||
* Create the Null cache driver
|
||||
*
|
||||
* @param ConfigInterface $config The configuration management class
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\CacheDriverInterface;
|
||||
|
||||
use Predis\Client;
|
||||
@ -20,17 +20,19 @@ use Predis\Client;
|
||||
class RedisDriver implements CacheDriverInterface {
|
||||
|
||||
/**
|
||||
* The redis extension class instance
|
||||
* @var Redis
|
||||
* THe Predis library instance
|
||||
*
|
||||
* @var Client
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* Create the Redis cache driver
|
||||
*
|
||||
* @param ConfigInterface $config The configuration management class
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
$config = $container->get('config');
|
||||
$redisConfig = $config->get('redis');
|
||||
|
||||
if (array_key_exists('password', $redisConfig) && $redisConfig['password'] === '')
|
||||
@ -50,7 +52,7 @@ class RedisDriver implements CacheDriverInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive a value from the cache backend
|
||||
* Retrieve a value from the cache backend
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
|
@ -12,9 +12,9 @@
|
||||
|
||||
namespace Aviat\Ion\Cache\Driver;
|
||||
|
||||
use Aviat\Ion\Di\ContainerInterface;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Cache\CacheDriverInterface;
|
||||
use Aviat\AnimeClient\Model\DB;
|
||||
use Aviat\Ion\Model\DB;
|
||||
|
||||
/**
|
||||
* Driver for caching via a traditional SQL database
|
||||
@ -29,15 +29,17 @@ class SQLDriver extends DB implements CacheDriverInterface {
|
||||
|
||||
/**
|
||||
* Create the driver object
|
||||
*
|
||||
* @param ConfigInterface $config
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
parent::__construct($container);
|
||||
parent::__construct($config);
|
||||
$this->db = \Query($this->db_config['collection']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive a value from the cache backend
|
||||
* Retrieve a value from the cache backend
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
|
41
src/Aviat/Ion/ConfigInterface.php
Normal file
41
src/Aviat/Ion/ConfigInterface.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Ion
|
||||
*
|
||||
* Building blocks for web development
|
||||
*
|
||||
* @package Ion
|
||||
* @author Timothy J. Warren
|
||||
* @copyright Copyright (c) 2015 - 2016
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace Aviat\Ion;
|
||||
|
||||
interface ConfigInterface {
|
||||
/**
|
||||
* Get a config value
|
||||
*
|
||||
* @param array|string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key);
|
||||
|
||||
/**
|
||||
* Set a config value
|
||||
*
|
||||
* @param integer|string|array $key
|
||||
* @param mixed $value
|
||||
* @throws \InvalidArgumentException
|
||||
* @return ConfigInterface
|
||||
*/
|
||||
public function set($key, $value);
|
||||
|
||||
/**
|
||||
* Remove a config value
|
||||
*
|
||||
* @param string|array $key
|
||||
* @return void
|
||||
*/
|
||||
public function delete($key);
|
||||
}
|
21
src/Aviat/Ion/Model.php
Normal file
21
src/Aviat/Ion/Model.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Ion
|
||||
*
|
||||
* Building blocks for web development
|
||||
*
|
||||
* @package Ion
|
||||
* @author Timothy J. Warren
|
||||
* @copyright Copyright (c) 2015 - 2016
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace Aviat\Ion;
|
||||
|
||||
/**
|
||||
* Common base for all Models
|
||||
*/
|
||||
class Model {
|
||||
use StringWrapper;
|
||||
}
|
||||
// End of Model.php
|
51
src/Aviat/Ion/Model/DB.php
Normal file
51
src/Aviat/Ion/Model/DB.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Ion
|
||||
*
|
||||
* Building blocks for web development
|
||||
*
|
||||
* @package Ion
|
||||
* @author Timothy J. Warren
|
||||
* @copyright Copyright (c) 2015 - 2016
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace Aviat\Ion\Model;
|
||||
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Aviat\Ion\Model as BaseModel;
|
||||
|
||||
/**
|
||||
* Base model for database interaction
|
||||
*/
|
||||
class DB extends BaseModel {
|
||||
/**
|
||||
* The query builder object
|
||||
* @var object $db
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* The config manager
|
||||
* @var ConfigInterface
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* The database connection information array
|
||||
* @var array $db_config
|
||||
*/
|
||||
protected $db_config;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ConfigInterface $config
|
||||
*/
|
||||
public function __construct(ConfigInterface $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->db_config = (array)$config->get('database');
|
||||
}
|
||||
}
|
||||
// End of DB.php
|
@ -5,13 +5,6 @@ use Aviat\AnimeClient\AnimeClient;
|
||||
|
||||
class AnimeClientTest extends AnimeClient_TestCase {
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->anime_client = new AnimeClient();
|
||||
$this->anime_client->setContainer($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic sanity test for _dir function
|
||||
*/
|
||||
@ -19,70 +12,4 @@ class AnimeClientTest extends AnimeClient_TestCase {
|
||||
{
|
||||
$this->assertEquals('foo' . DIRECTORY_SEPARATOR . 'bar', \_dir('foo', 'bar'));
|
||||
}
|
||||
|
||||
public function testIsSelected()
|
||||
{
|
||||
// Failure to match
|
||||
$this->assertEquals('', AnimeClient::is_selected('foo', 'bar'));
|
||||
|
||||
// Matches
|
||||
$this->assertEquals('selected', AnimeClient::is_selected('foo', 'foo'));
|
||||
}
|
||||
|
||||
public function testIsNotSelected()
|
||||
{
|
||||
// Failure to match
|
||||
$this->assertEquals('selected', AnimeClient::is_not_selected('foo', 'bar'));
|
||||
|
||||
// Matches
|
||||
$this->assertEquals('', AnimeClient::is_not_selected('foo', 'foo'));
|
||||
}
|
||||
|
||||
public function dataIsViewPage()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'uri' => '/anime/update',
|
||||
'expected' => FALSE
|
||||
],
|
||||
[
|
||||
'uri' => '/anime/watching',
|
||||
'expected' => TRUE
|
||||
],
|
||||
[
|
||||
'uri' => '/manga/reading',
|
||||
'expected' => TRUE
|
||||
],
|
||||
[
|
||||
'uri' => '/manga/update',
|
||||
'expected' => FALSE
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsViewPage
|
||||
*/
|
||||
public function testIsViewPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri
|
||||
]
|
||||
]);
|
||||
$this->assertEquals($expected, $this->anime_client->is_view_page());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsViewPage
|
||||
*/
|
||||
public function testIsFormPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(!$expected, $this->anime_client->is_form_page());
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ class MangaModelTest extends AnimeClient_TestCase {
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->container->set('util', new MockUtil($this->container));
|
||||
$this->model = new Friend(new TestMangaModel($this->container));
|
||||
$this->mockDir = __DIR__ . '/../../test_data/manga_list';
|
||||
}
|
||||
|
78
tests/AnimeClient/UtilTest.php
Normal file
78
tests/AnimeClient/UtilTest.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
use Aviat\AnimeClient\Util;
|
||||
|
||||
class UtilTest extends AnimeClient_TestCase {
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->util = new Util($this->container);
|
||||
}
|
||||
|
||||
public function testIsSelected()
|
||||
{
|
||||
// Failure to match
|
||||
$this->assertEquals('', Util::is_selected('foo', 'bar'));
|
||||
|
||||
// Matches
|
||||
$this->assertEquals('selected', Util::is_selected('foo', 'foo'));
|
||||
}
|
||||
|
||||
public function testIsNotSelected()
|
||||
{
|
||||
// Failure to match
|
||||
$this->assertEquals('selected', Util::is_not_selected('foo', 'bar'));
|
||||
|
||||
// Matches
|
||||
$this->assertEquals('', Util::is_not_selected('foo', 'foo'));
|
||||
}
|
||||
|
||||
public function dataIsViewPage()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'uri' => '/anime/update',
|
||||
'expected' => FALSE
|
||||
],
|
||||
[
|
||||
'uri' => '/anime/watching',
|
||||
'expected' => TRUE
|
||||
],
|
||||
[
|
||||
'uri' => '/manga/reading',
|
||||
'expected' => TRUE
|
||||
],
|
||||
[
|
||||
'uri' => '/manga/update',
|
||||
'expected' => FALSE
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsViewPage
|
||||
*/
|
||||
public function testIsViewPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri
|
||||
]
|
||||
]);
|
||||
$this->assertEquals($expected, $this->util->is_view_page());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsViewPage
|
||||
*/
|
||||
public function testIsFormPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(!$expected, $this->util->is_form_page());
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Aviat\AnimeClient\Model as BaseModel;
|
||||
use Aviat\Ion\Model as BaseModel;
|
||||
|
||||
class BaseModelTest extends AnimeClient_TestCase {
|
||||
|
||||
public function testBaseModelSanity()
|
||||
{
|
||||
$baseModel = new BaseModel($this->container);
|
||||
$baseModel = new BaseModel();
|
||||
$this->assertTrue(is_object($baseModel));
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ class CacheManagerText extends AnimeClient_TestCase {
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->cache = new CacheManager($this->container);
|
||||
$this->cache = new CacheManager($this->container->get('config'), $this->container);
|
||||
$this->friend = new Friend($this->cache);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,6 @@ class CacheNullDriverTest extends AnimeClient_TestCase {
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->driver = new NullDriver($this->container);
|
||||
$this->driver = new NullDriver($this->container->get('config'));
|
||||
}
|
||||
}
|
@ -16,16 +16,15 @@ class CacheRedisDriverTestTwo extends AnimeClient_TestCase {
|
||||
parent::setUp();
|
||||
|
||||
// Setup config with port and password
|
||||
$container = new Container();
|
||||
$container->set('config', new Config([
|
||||
$config = new Config([
|
||||
'redis' => [
|
||||
'host' => (array_key_exists('REDIS_HOST', $_ENV)) ? $_ENV['REDIS_HOST'] : 'localhost',
|
||||
'port' => 6379,
|
||||
'password' => '',
|
||||
'database' => 13,
|
||||
]
|
||||
]));
|
||||
$this->driver = new RedisDriver($container);
|
||||
]);
|
||||
$this->driver = new RedisDriver($config);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
|
@ -13,7 +13,7 @@ class CacheRedisDriverTest extends AnimeClient_TestCase {
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->driver = new RedisDriver($this->container);
|
||||
$this->driver = new RedisDriver($this->container->get('config'));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
|
@ -13,7 +13,7 @@ class CacheSQLDriverTest extends AnimeClient_TestCase {
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->driver = new SQLDriver($this->container);
|
||||
$this->driver = new SQLDriver($this->container->get('config'));
|
||||
$friend = new Friend($this->driver);
|
||||
$friend->db->query('CREATE TABLE IF NOT EXISTS "cache" ("key" TEXT NULL, "value" TEXT NULL, PRIMARY KEY ("key"))');
|
||||
}
|
||||
|
@ -99,6 +99,13 @@ trait MockViewOutputTrait {
|
||||
}
|
||||
}
|
||||
|
||||
class MockUtil {
|
||||
public function get_cached_image($api_path, $series_slug, $type = "anime")
|
||||
{
|
||||
return "/public/images/{$type}/{$series_slug}.jpg";
|
||||
}
|
||||
}
|
||||
|
||||
class TestView extends View {
|
||||
public function send() {}
|
||||
protected function output()
|
||||
@ -157,11 +164,6 @@ class TestAnimeModel extends AnimeModel {
|
||||
class TestMangaModel extends MangaModel {
|
||||
use MockInjectionTrait;
|
||||
|
||||
public function get_cached_image($api_path, $series_slug, $type = "anime")
|
||||
{
|
||||
return "/public/images/{$type}/{$series_slug}.jpg";
|
||||
}
|
||||
|
||||
protected function _check_cache($response)
|
||||
{
|
||||
$file = __DIR__ . '/test_data/manga_list/manga-transformed.json';
|
||||
|
Loading…
Reference in New Issue
Block a user