First commit -- split from timw4mail/HummingBirdAnimeClient

This commit is contained in:
Timothy Warren 2016-08-04 14:55:37 -04:00
commit 8c501e08b7
72 changed files with 4196 additions and 0 deletions

29
.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
.codelite
.phing_targets
.sonar/
*.phprj
*.workspace
vendor
**/cache/**
**/logs/**
**/coverage/**
**/docs/**
**/node_modules/**
public/images/*
composer.lock
*.sqlite
*.db
*.sqlite3
docs/*
tests/test_data/sessions/*
cache.properties
build/**
!build/*.txt
!build/*.xml
!build/*.php
app/config/*.toml
!app/config/*.toml.example
phinx.yml
.idea/
Caddyfile
build/humbuglog.txt

37
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,37 @@
# Composer stores all downloaded packages in the vendor/ directory.
# Do not use the following if the vendor/ directory is commited to
# your git repository.
cache:
paths:
- vendor/
services:
- redis:latest
test:5.6:
before_script:
- bash build/docker_install.sh > /dev/null
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install --no-dev
image: php:5.6
script:
- phpunit -c build
test:7:
before_script:
- bash build/docker_install.sh > /dev/null
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install --no-dev
image: php:7
script:
- phpunit -c build
test:hhvm:
before_script:
- /usr/local/bin/composer self-update
- curl -Lo /usr/local/bin/phpunit https://phar.phpunit.de/phpunit.phar
- chmod +x /usr/local/bin/phpunit
- composer install --no-dev
image: 51systems/docker-gitlab-ci-runner-hhvm
script:
- phpunit -c build

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Ion
Ion is a set of helpful PHP libraries for general web development

View File

@ -0,0 +1,11 @@
/**
* 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
*/

View File

@ -0,0 +1,10 @@
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/

131
build/phpdox.xml Normal file
View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- This is a skeleton phpDox config file - Check http://phpDox.de for latest version and more info -->
<phpdox xmlns="http://xml.phpdox.net/config" silent="false">
<!-- @silent: true | false to enable or disable visual output of progress -->
<!-- Additional bootstrap files to load for additional parsers, enrichers and/or engines -->
<!-- Place as many require nodes as you feel like in this container -->
<!-- syntax: <require file="/path/to/file.php" /> -->
<bootstrap />
<!-- A phpDox project to process, you can have multiple projects in one config file -->
<project name="Hummingbird Anime Client" source="../src" workdir="phpdox/xml">
<!-- @name - The name of the project -->
<!-- @source - The source directory of the application to process -->
<!-- @workdir - The directory to store the xml data files in -->
<!-- A phpDox config file can define additional variables (properties) per project -->
<!-- <property name="some.name" value="the.value" /> -->
<!-- Values can make use of previously defined properties -->
<!-- The following are defined by default:
${basedir} Directory the loaded config file is in
${phpDox.home} Directory of the phpDox installation
${phpDox.file} The current config file
${phpDox.version} phpDox' version number
${phpDox.project.name} The value of project/@name if set, otherwise 'unnamed'
${phpDox.project.source} The value of project/@source if set, otherwise '${basedir}/src'
${phpDox.project.workdir} The value of project/@workdir if set, otherwise '${basedir}/build/phpdox/xml'
${phpDox.php.version} The PHP Version of the interpreter in use
-->
<!-- Additional configuration for the collecting process (parsing of php code, generation of xml data) -->
<collector publiconly="false" backend="parser" encoding="auto">
<!-- @publiconly - Flag to disable/enable processing of non public methods and members -->
<!-- @backend - The collector backend to use, currently only shipping with 'parser' -->
<!-- @encoding - Charset encoding of source files (overwrite default 'auto' if detection fails) -->
<!-- <include / exclude filter for filelist generator, mask must follow fnmatch() requirements -->
<include mask="*.php" />
<exclude mask="" />
<!-- How to handle inheritance -->
<inheritance resolve="true">
<!-- @resolve - Flag to enable/disable resolving of inheritance -->
<!-- You can define multiple (external) dependencies to be included -->
<!-- <dependency path="" -->
<!-- @path - path to a directory containing an index.xml for a dependency project -->
</inheritance>
</collector>
<!-- Configuration of generation process -->
<generator output="../docs">
<!-- @output - (Base-)Directory to store output data in -->
<!-- A generation process consists of one or more build tasks and of (optional) enrich sources -->
<enrich base="logs">
<!-- @base - (Base-)Directory of datafiles used for enrich process -->
<!--<source type="...">-->
<!-- @type - the handler for the enrichment -->
<!-- known types by default are: build, checkstyle, git, phpcs, phploc, phpunit, pmd -->
<!-- every enrichment source can have additional configuration nodes, most probably need a logfile -->
<!-- <file name="path/to/log.xml" /> -->
<!--</source> -->
<!-- add phploc output -->
<source type="phploc">
<file name="phploc.xml" />
</source>
<!-- git vcs information -->
<source type="git">
<git binary="/usr/bin/git" />
<history enabled="true" limit="15" cache="${phpDox.project.workdir}/gitlog.xml" />
</source>
<!-- PHP Code Sniffer findings -->
<!--
<source type="phpcs">
<file name="logs/phpcs.xml" />
</source>
-->
<!-- PHPMessDetector -->
<!--
<source type="pmd">
<file name="pmd.xml" />
</source>
-->
<!-- PHPUnit Coverage XML -->
<source type="phpunit">
<!-- <coverage path="clover.xml" />-->
<!-- @path - the directory where the xml code coverage report can be found -->
<!--<filter directory="${phpDox.project.source}" />-->
<!-- @directory - path of the phpunit config whitelist filter directory -->
</source>
<!--
<source type="phpunit">
<filter directory="${phpDox.project.source}" />
</source>
-->
</enrich>
<!-- <build engine="..." enabled="true" output="..." /> -->
<!-- @engine - The name of the engine this build task uses, use ./phpDox - -engines to get a list of available engines -->
<!-- @enabled - Flag to enable/disable this engine, default: enabled=true -->
<!-- @output - (optional) Output directory; if relative (no / as first char) it is interpreted as relative to generator/@output -->
<!-- An engine and thus build node can have additional configuration child nodes, please check the documentation for the engine to find out more -->
<!-- default engine "html" -->
<build engine="html" enabled="true">
<template dir="${phpDox.home}/templates/html" />
<file extension="html" />
</build>
</generator>
</project>
</phpdox>

33
build/phpunit.xml Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
colors="true"
stopOnFailure="false"
bootstrap="../tests/bootstrap.php"
beStrictAboutTestsThatDoNotTestAnything="true"
checkForUnintentionallyCoveredCode="true"
>
<filter>
<whitelist>
<directory suffix=".php">../src/Aviat/Ion</directory>
</whitelist>
</filter>
<testsuites>
<testsuite name="Ion">
<directory>../tests/Ion</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-html" target="coverage"/>
<log type="coverage-clover" target="logs/clover.xml"/>
<log type="coverage-crap4j" target="logs/crap4j.xml"/>
<log type="coverage-xml" target="logs/coverage" />
<log type="junit" target="logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
<php>
<server name="HTTP_USER_AGENT" value="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393" />
<server name="HTTP_HOST" value="localhost" />
<server name="SERVER_NAME" value="localhost" />
<server name="REQUEST_URI" value="/" />
<server name="REQUEST_METHOD" value="GET" />
</php>
</phpunit>

View File

@ -0,0 +1,70 @@
<?php
$ion_file_patterns = [
'src/Aviat/Ion/*.php'
];
if ( ! function_exists('glob_recursive'))
{
// Does not support flag GLOB_BRACE
function glob_recursive($pattern, $flags = 0)
{
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir)
{
$files = array_merge($files, glob_recursive($dir . '/' . basename($pattern), $flags));
}
return $files;
}
}
function get_text_to_replace($tokens)
{
if ($tokens[0][0] !== T_OPEN_TAG)
{
return NULL;
}
// If there is already a docblock, as the second token after the
// open tag, get the contents of that token to replace
if ($tokens[1][0] === T_DOC_COMMENT)
{
return "<?php\n" . $tokens[1][1];
}
else if ($tokens[1][0] !== T_DOC_COMMENT)
{
return "<?php";
}
}
function get_tokens($source)
{
return token_get_all($source);
}
function replace_files(array $files, $template)
{
foreach ($files as $file)
{
$source = file_get_contents($file);
$tokens = get_tokens($source);
$text_to_replace = get_text_to_replace($tokens);
$header = file_get_contents(__DIR__ . $template);
$new_text = "<?php\n{$header}";
$new_source = str_replace($text_to_replace, $new_text, $source);
file_put_contents($file, $new_source);
}
}
foreach ($ion_file_patterns as $glob)
{
$files = glob_recursive($glob);
replace_files($files, '/ion_header_comment.txt');
}
echo "Successfully updated headers \n";

29
composer.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "aviat/ion",
"description": "Basic PHP Framework",
"license":"MIT",
"require": {
"aviat/query": "^2.5",
"aura/html": "2.*",
"container-interop/container-interop": "1.*",
"danielstjules/stringy": "~2.1",
"guzzlehttp/guzzle": "6.*",
"monolog/monolog": "1.*",
"predis/predis": "1.1.*",
"psr/http-message": "~1.0",
"psr/log": "~1.0",
"yosymfony/toml": "0.3.*",
"zendframework/zend-diactoros": "1.3.*"
},
"require-dev": {
"pdepend/pdepend": "^2.2",
"sebastian/phpcpd": "^2.0",
"theseer/phpdox": "0.8.1.1",
"phploc/phploc": "^3.0",
"phpmd/phpmd": "^2.4",
"phpunit/phpunit": "^5.4",
"robmorgan/phinx": "^0.6.4",
"humbug/humbug": "~1.0@dev",
"codegyre/robo": "*"
}
}

12
humbug.json.dist Normal file
View File

@ -0,0 +1,12 @@
{
"source": {
"directories": [
"src"
]
},
"timeout": 10,
"logs": {
"text": "build\/humbuglog.txt",
"json": "build\/humbug.json"
}
}

16
phpdoc.dist.xml Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<phpdoc>
<title>Hummingbird Anime Client</title>
<parser>
<target>docs</target>
</parser>
<transformer>
<target>docs</target>
</transformer>
<transformations>
<template name="clean" />
</transformations>
<files>
<directory>src/Aviat</directory>
</files>
</phpdoc>

25
phpunit.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
colors="true"
stopOnFailure="false"
bootstrap="tests/bootstrap.php"
beStrictAboutTestsThatDoNotTestAnything="true"
>
<filter>
<whitelist>
<directory suffix=".php">src/Aviat/Ion</directory>
</whitelist>
</filter>
<testsuites>
<testsuite name="Ion">
<directory>tests/Ion</directory>
</testsuite>
</testsuites>
<php>
<server name="HTTP_USER_AGENT" value="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0" />
<server name="HTTP_HOST" value="localhost" />
<server name="SERVER_NAME" value="localhost" />
<server name="REQUEST_URI" value="/" />
<server name="REQUEST_METHOD" value="GET" />
</php>
</phpunit>

View File

@ -0,0 +1,34 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion;
use Aviat\Ion\Type\ArrayType;
/**
* Wrapper to shortcut creating ArrayType objects
*/
trait ArrayWrapper {
/**
* Convenience method for wrapping an array
* with the array type class
*
* @param array $arr
* @return ArrayType
*/
public function arr(array $arr)
{
return new ArrayType($arr);
}
}
// End of ArrayWrapper.php

View File

@ -0,0 +1,48 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache;
/**
* Interface for retrieving values from cache
*/
interface CacheInterface {
/**
* Retrieve 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=[]);
/**
* Retrieve a fresh value, 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=[]);
/**
* Clear the entire cache
*
* @return void
*/
public function purge();
}
// End of CacheInterface.php

View File

@ -0,0 +1,117 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
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
*/
class CacheManager implements CacheInterface {
/**
* @var DriverInterface
*/
protected $driver;
/**
* Retrieve the appropriate driver from the container
*
* @param ConfigInterface $config The configuration management class
*/
public function __construct(ConfigInterface $config)
{
$driverConf = $config->get('cache_driver');
if (empty($driverConf))
{
$driverConf = 'NullDriver';
}
$driverClass = __NAMESPACE__ . "\\Driver\\{$driverConf}";
$driver = new $driverClass($config);
$this->driver = $driver;
}
/**
* Retrieve 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;
}
/**
* 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
* @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;
}
/**
* Clear the entire cache
*
* @return void
*/
public function purge()
{
$this->driver->invalidateAll();
}
/**
* Generate a hash as a cache key from the current method call
*
* @param object $object
* @param string $method
* @param array $args
* @return string
*/
protected 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

View 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\Cache\Driver;
/**
* Interface for cache drivers
*/
interface DriverInterface {
/**
* Retreive a value from the cache backend
*
* @param string $key
* @return mixed
*/
public function get($key);
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return DriverInterface
*/
public function set($key, $value);
/**
* Invalidate a cached value
*
* @param string $key
* @return DriverInterface
*/
public function invalidate($key);
/**
* Clear the contents of the cache
*
* @return void
*/
public function invalidateAll();
}
// End of DriverInterface.php

View 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

View File

@ -0,0 +1,74 @@
<?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\ConfigInterface;
/**
* The Driver for no real cache
*/
class NullDriver implements DriverInterface {
/**
* 'Cache' for Null data store
*/
protected $data = [];
/**
* Retrieve a value from the cache backend
*
* @param string $key
* @return mixed
*/
public function get($key)
{
return (array_key_exists($key, $this->data))
? $this->data[$key]
: NULL;
}
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return DriverInterface
*/
public function set($key, $value)
{
$this->data[$key] = $value;
return $this;
}
/**
* Invalidate a cached value
*
* @param string $key
* @return DriverInterface
*/
public function invalidate($key)
{
unset($this->data[$key]);
return $this;
}
/**
* Clear the contents of the cache
*
* @return void
*/
public function invalidateAll()
{
$this->data = [];
}
}
// End of NullDriver.php

View File

@ -0,0 +1,117 @@
<?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\ConfigInterface;
use Predis\Client;
/**
* Cache Driver for a Redis backend
*/
class RedisDriver implements DriverInterface {
use DriverTrait;
/**
* THe Predis library instance
*
* @var Client
*/
protected $redis;
/**
* Create the Redis cache driver
*
* @param ConfigInterface $config The configuration management class
*/
public function __construct(ConfigInterface $config)
{
$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']);
}
$this->redis = new Client($redisConfig);
}
/**
* Disconnect from redis
*/
public function __destruct()
{
$this->redis = null;
}
/**
* Retrieve a value from the cache backend
*
* @param string $rawKey
* @return mixed
*/
public function get($rawKey)
{
$key = $this->prefix($rawKey);
$serializedData = $this->redis->get($key);
return $this->unserialize($serializedData);
}
/**
* Set a cached value
*
* @param string $rawKey
* @param mixed $value
* @return DriverInterface
*/
public function set($rawKey, $value)
{
$key = $this->prefix($rawKey);
$serializedData = $this->serialize($value);
$this->redis->set($key, $serializedData);
return $this;
}
/**
* Invalidate a cached value
*
* @param string $rawKey
* @return DriverInterface
*/
public function invalidate($rawKey)
{
$key = $this->prefix($rawKey);
$this->redis->del($key);
return $this;
}
/**
* Clear the contents of the cache
*
* @return void
*/
public function invalidateAll()
{
$this->redis->flushdb();
}
}
// End of RedisDriver.php

View File

@ -0,0 +1,119 @@
<?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\ConfigInterface;
use Aviat\Ion\Exception\ConfigException;
use Aviat\Ion\Model\DB;
/**
* Driver for caching via a traditional SQL database
*/
class SQLDriver extends DB implements DriverInterface {
use DriverTrait;
/**
* The query builder object
* @var object $db
*/
protected $db;
/**
* Create the driver object
*
* @param ConfigInterface $config
* @throws ConfigException
*/
public function __construct(ConfigInterface $config)
{
parent::__construct($config);
if ( ! array_key_exists('cache', $this->db_config))
{
throw new ConfigException("Missing '[cache]' section in database config.");
}
$this->db = \Query($this->db_config['cache']);
}
/**
* Retrieve 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 NULL;
}
$serializedData = $row['value'];
return $this->unserialize($serializedData);
}
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return DriverInterface
*/
public function set($key, $value)
{
$serializedData = $this->serialize($value);
$this->db->set([
'key' => $key,
'value' => $serializedData,
]);
$this->db->insert('cache');
return $this;
}
/**
* Invalidate a cached value
*
* @param string $key
* @return DriverInterface
*/
public function invalidate($key)
{
$this->db->where('key', $key)
->delete('cache');
return $this;
}
/**
* Clear the contents of the cache
*
* @return void
*/
public function invalidateAll()
{
$this->db->truncate('cache');
}
}
// End of SQLDriver.php

106
src/Aviat/Ion/Config.php Normal file
View File

@ -0,0 +1,106 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion;
use Aviat\Ion\Exception\ConfigException;
use InvalidArgumentException;
/**
* Wrapper for configuration values
*/
class Config implements ConfigInterface {
use ArrayWrapper;
/**
* Config object
*
* @var \Aviat\Ion\Type\ArrayType
*/
protected $map = [];
/**
* Constructor
*
* @param array $config_array
*/
public function __construct(array $config_array = [])
{
$this->map = $this->arr($config_array);
}
/**
* Get a config value
*
* @param array|string $key
* @return mixed
* @throws ConfigException
*/
public function get($key)
{
if (is_array($key))
{
return $this->map->get_deep_key($key);
}
return $this->map->get($key);
}
/**
* Remove a config value
*
* @param string|array $key
* @return void
*/
public function delete($key)
{
if (is_array($key))
{
$this->map->set_deep_key($key, NULL);
}
else
{
$pos =& $this->map->get($key);
$pos = NULL;
}
}
/**
* Set a config value
*
* @param integer|string|array $key
* @param mixed $value
* @throws InvalidArgumentException
* @return Config
*/
public function set($key, $value)
{
if (is_array($key))
{
$this->map->set_deep_key($key, $value);
}
else if (is_scalar($key) && ! empty($key))
{
$this->map->set($key, $value);
}
else
{
throw new InvalidArgumentException("Key must be integer, string, or array, and cannot be empty");
}
return $this;
}
}
// End of config.php

View 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);
}

View File

@ -0,0 +1,171 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Di;
use Psr\Log\LoggerInterface;
use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException;
/**
* Dependency container
*/
class Container implements ContainerInterface {
/**
* Array with class instances
*
* @var array
*/
protected $container = [];
/**
* Map of logger instances
*
* @var array
*/
protected $loggers = [];
/**
* Constructor
*
* @param array $values (optional)
*/
public function __construct(array $values = [])
{
$this->container = $values;
$this->loggers = [];
}
/**
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id Identifier of the entry to look for.
*
* @throws NotFoundException No entry was found for this identifier.
* @throws ContainerException Error while retrieving the entry.
*
* @return mixed Entry.
*/
public function get($id)
{
if ( ! is_string($id))
{
throw new ContainerException("Id must be a string");
}
if ($this->has($id))
{
$item = $this->container[$id];
if (is_callable($item))
{
return $this->applyContainer($item($this));
}
else
{
return $item;
}
}
throw new NotFoundException("Item '{$id}' does not exist in container.");
}
/**
* Add a value to the container
*
* @param string $id
* @param mixed $value
* @return ContainerInterface
*/
public function set($id, $value)
{
$this->container[$id] = $value;
return $this;
}
/**
* Returns true if the container can return an entry for the given identifier.
* Returns false otherwise.
*
* @param string $id Identifier of the entry to look for.
*
* @return boolean
*/
public function has($id)
{
return array_key_exists($id, $this->container);
}
/**
* Determine whether a logger channel is registered
* @param string $key The logger channel
* @return boolean
*/
public function hasLogger($key = 'default')
{
return array_key_exists($key, $this->loggers);
}
/**
* Add a logger to the Container
*
* @param LoggerInterface $logger
* @param string $key The logger 'channel'
* @return ContainerInterface
*/
public function setLogger(LoggerInterface $logger, $key = 'default')
{
$this->loggers[$key] = $logger;
return $this;
}
/**
* Retrieve a logger for the selected channel
*
* @param string $key The logger to retrieve
* @return LoggerInterface|null
*/
public function getLogger($key = 'default')
{
return ($this->hasLogger($key))
? $this->loggers[$key]
: NULL;
}
/**
* Check if object implements ContainerAwareInterface
* or uses ContainerAware trait, and if so, apply the container
* to that object
*
* @param mixed $obj
* @return mixed
*/
private function applyContainer($obj)
{
$trait_name = __NAMESPACE__ . '\\ContainerAware';
$interface_name = __NAMESPACE__ . '\\ContainerAwareInterface';
$uses_trait = in_array($trait_name, class_uses($obj));
$implements_interface = in_array($interface_name, class_implements($obj));
if ($uses_trait || $implements_interface)
{
$obj->setContainer($this);
}
return $obj;
}
}
// End of Container.php

View File

@ -0,0 +1,49 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Di;
/**
* Trait implementation of ContainerAwareInterface
*/
trait ContainerAware {
/**
* Di Container
*
* @var ContainerInterface
*/
protected $container;
/**
* Set the container for the current object
*
* @param ContainerInterface $container
* @return $this
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
return $this;
}
/**
* Get the container object
*
* @return ContainerInterface
*/
public function getContainer()
{
return $this->container;
}
}
// End of ContainerAware.php

View File

@ -0,0 +1,36 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Di;
/**
* Interface for a class that is aware of the Di Container
*/
interface ContainerAwareInterface {
/**
* Set the container for the current object
*
* @param ContainerInterface $container
* @return void
*/
public function setContainer(ContainerInterface $container);
/**
* Get the container object
*
* @return ContainerInterface
*/
public function getContainer();
}
// End of ContainerAwareInterface.php

View File

@ -0,0 +1,54 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Di;
use Psr\Log\LoggerInterface;
/**
* Interface for the Dependency Injection Container
*/
interface ContainerInterface extends \Interop\Container\ContainerInterface {
/**
* Add a value to the container
*
* @param string $key
* @param mixed $value
* @return ContainerInterface
*/
public function set($key, $value);
/**
* Determine whether a logger channel is registered
* @param string $key The logger channel
* @return boolean
*/
public function hasLogger($key = 'default');
/**
* Add a logger to the Container
*
* @param LoggerInterface $logger
* @param string $key The logger 'channel'
* @return Container
*/
public function setLogger(LoggerInterface $logger, $key = 'default');
/**
* Retrieve a logger for the selected channel
*
* @param string $key The logger to retreive
* @return LoggerInterface|null
*/
public function getLogger($key = 'default');
}

View 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\Di\Exception;
/**
* Generic exception for Di Container
*/
class ContainerException extends \Exception implements \Interop\Container\Exception\ContainerException {
}
// End of ContainerException.php