Skip to content

Commit

Permalink
Merge pull request #4 from maschmann/feature/import_and_default_values
Browse files Browse the repository at this point in the history
Feature/import and default values
  • Loading branch information
maschmann committed Apr 24, 2015
2 parents 2841c7d + 1fc4859 commit 684e48d
Show file tree
Hide file tree
Showing 17 changed files with 413 additions and 142 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Changelog

## v2.0.0

* Dropping php 5.3 support
* architectural changes

## v1.2.0

* improved overall code quality (scrutinizer suggestions)
* improved code coverage
* reworked __construct() behavior of Config classes

## v1.1.0

* Moved to PSR-4, closed extension points

## v1.0.0

* First stable draft release
166 changes: 166 additions & 0 deletions Config/AbstractConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php
/*
* This file is part of the php-utilities package.
*
* (c) Marc Aschmann <maschmann@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Asm\Config;

use Asm\Data\Data;
use Symfony\Component\Yaml\Yaml;

/**
* Class AbstractConfig
*
* @package Asm\Config
* @author marc aschmann <maschmann@gmail.com>
* @codeCoverageIgnore
* @uses Asm\Data\Data
* @uses Symfony\Component\Yaml\Yaml
*/
abstract class AbstractConfig extends Data
{
/**
* @var bool
*/
protected $filecheck = true;

/**
* @var array
*/
protected $imports = [];

/**
* @var array
*/
protected $default = [];

/**
* Default constructor.
*
* @param array $param
*/
public function __construct(array $param)
{
if (isset($param['filecheck'])) {
$this->filecheck = (bool)$param['filecheck'];
}

$this->setConfig($param['file']);
}

/**
* Add named property to config object
* and insert config as array.
*
* @param string $name name of property
* @param string $file string $file absolute filepath/filename.ending
*/
public function addConfig($name, $file)
{
$this->set($name, $this->readConfig($file));
}

/**
* Read config file via YAML parser.
*
* @param string $file absolute filepath/filename.ending
* @return array config array
*/
public function readConfig($file)
{
$config = $this->readFile($file);
$config = $this->extractImports($config);
$config = $this->extractDefault($config);
$this->mergeDefault();

return array_replace_recursive(
$this->default,
$config
);
}

/**
* Add config to data storage.
*
* @param string $file absolute filepath/filename.ending
*/
public function setConfig($file)
{
$this->setByArray(
array_replace_recursive(
$this->default,
$this->readConfig($file)
)
);
}

/**
* Read yaml files.
*
* @param string $file path/filename
* @return array
*/
private function readFile($file)
{
if ($this->filecheck && !is_file($file)) {
throw new \InvalidArgumentException(
'Config::Abstract() - Given config file ' . $file . ' does not exist!'
);
}

return (array)Yaml::parse($file);
}

/**
* get all import files from config, if set and remove node.
*
* @param array $config
* @return array
*/
private function extractImports(array $config)
{
if (array_key_exists('imports', $config) && 0 < count($config['imports'])) {
$this->imports = [];
foreach ($config['imports'] as $key => $import) {
if (false === empty($import['resource'])) {
$this->imports = array_replace_recursive(
$this->imports,
$this->readFile($import['resource'])
);
}
}

unset($config['imports']);
}

return $config;
}

/**
* Get default values if set and remove node from config.
*
* @param array $config
* @return array
*/
private function extractDefault($config)
{
if (array_key_exists('default', $config)) {
$this->default = $config['default'];
unset($config['default']);
}

return $config;
}

/**
* Prepare the defaults and replace recursively.
*/
private function mergeDefault()
{
$this->default = array_replace_recursive($this->imports, $this->default);
}
}
17 changes: 4 additions & 13 deletions Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@
*/
final class Config
{
/**
* @var array
*/
private static $whitelist = [
'ConfigDefault',
'ConfigEnv',
'ConfigTimer',
];

/**
* Get object of specific class.
*
Expand All @@ -37,11 +28,11 @@ final class Config
*/
public static function factory(array $param, $class = 'ConfigDefault')
{
if (in_array($class, self::$whitelist)) {
if (false === strpos($class, 'Asm')) {
$class = __NAMESPACE__ . '\\' . $class;
}
if (false === strpos($class, 'Asm')) {
$class = __NAMESPACE__ . '\\' . $class;
}

if (class_exists($class)) {
// allow config names without ending
if (empty($param['file'])) {
throw new \InvalidArgumentException('Config::factory() - config filename missing in param array!');
Expand Down
83 changes: 0 additions & 83 deletions Config/ConfigAbstract.php

This file was deleted.

2 changes: 1 addition & 1 deletion Config/ConfigDefault.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
* @package Asm\Config
* @author marc aschmann <maschmann@gmail.com>
*/
final class ConfigDefault extends ConfigAbstract implements ConfigInterface
final class ConfigDefault extends AbstractConfig implements ConfigInterface
{
}
9 changes: 7 additions & 2 deletions Config/ConfigEnv.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @package Asm\Config
* @author marc aschmann <maschmann@gmail.com>
*/
final class ConfigEnv extends ConfigAbstract implements ConfigInterface
final class ConfigEnv extends AbstractConfig implements ConfigInterface
{
/**
* @var string
Expand Down Expand Up @@ -66,6 +66,11 @@ private function mergeEnvironments($param)
$merged = $config->get($this->defaultEnv);
}

$this->setByArray($merged);
$this->setByArray(
array_replace_recursive(
$this->default,
$merged
)
);
}
}
2 changes: 1 addition & 1 deletion Config/ConfigTimer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @package Asm\Config
* @author marc aschmann <maschmann@gmail.com>
*/
final class ConfigTimer extends ConfigAbstract implements ConfigInterface
final class ConfigTimer extends AbstractConfig implements ConfigInterface
{
/**
* Convert config date strings to \DateTime objects or \DateIntervals.
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ Available types are:
* ConfigEnv - provides the possibility to get an environment-merged config. Based on the currently provided env, you'll have e.g. prod -> dev merged, with prod node as a master.
* ConfigTimer is a specialised for of config to provide pre-generated DateTime objects for the Timer class.

Configs now also support the "imports" syntax from symfony configs.

```
imports:
- { resource: defaults.yml }
```
There is the possibility to use a "default" node in all configs, except timers, which will be used as merge-base.
Imported configs will be treated just like the "default" node and also become the base for merging.
The order of merges is import -> default -> prod -> $env.

### Timer
Provides functionality to check if there's a current holiday, has configurable "timers" to check uf e.g. your hotline should be available etc.
Extensive examples can be found within both, the TestData and UnitTests :-)
Expand Down
Loading

0 comments on commit 684e48d

Please sign in to comment.