Skip to content

Commit

Permalink
Merge pull request #19 from PhpGt/16-overrides
Browse files Browse the repository at this point in the history
Config override files
  • Loading branch information
g105b authored Jun 7, 2018
2 parents a270fbb + e964298 commit ab9fbd7
Show file tree
Hide file tree
Showing 15 changed files with 375 additions and 233 deletions.
3 changes: 3 additions & 0 deletions bin/config-generator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env php
<?php
$args = new CommandLineArguments($argv);
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"type": "library",

"require": {
"php": ">=7.1.0"
"php": ">=7.1.0",
"magicalex/write-ini-file": "v1.2.3"
},
"require-dev": {
"phpunit/phpunit": "6.4.*"
Expand All @@ -29,4 +30,4 @@
"Gt\\Config\\Test\\": "./test/unit"
}
}
}
}
52 changes: 50 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 31 additions & 80 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,12 @@
namespace Gt\Config;

class Config {
const INI_EXTENSION = "ini";
const FILE_OVERRIDE_DEV = "dev";
const FILE_OVERRIDE_DEPLOY = "deploy";
const FILE_OVERRIDE_PRODUCTION = "production";
const FILE_OVERRIDE_ORDER = [
self::FILE_OVERRIDE_DEV,
self::FILE_OVERRIDE_DEPLOY,
self::FILE_OVERRIDE_PRODUCTION,
];
/** @var ConfigSection[] */
protected $sectionList = [];

protected $projectRoot;
protected $kvp = [];
protected $delimeter;

public function __construct(
string $projectRoot = "",
string $filename = "config",
string $delimeter = "."
) {
$this->projectRoot = $projectRoot;
$iniConfig = $this->loadIni($projectRoot, $filename);
$this->kvp = $iniConfig;
$this->delimeter = $delimeter;
}

public function mergeDefaults(
string $defaultDirectoryPath = null,
string $filename = "config.default",
bool $override = false
):void {
if(is_null($defaultDirectoryPath)) {
$defaultDirectoryPath = $this->projectRoot;
}

$defaults = $this->loadIni(
$defaultDirectoryPath,
$filename
);

foreach($defaults as $section => $data) {
foreach($data as $key => $value) {
if(!isset($this->kvp[$section])) {
$this->kvp[$section] = [];
}

if(!isset($this->kvp[$section][$key])) {
$this->kvp[$section][$key] = $value;
}

if($override) {
$this->kvp[$section][$key] = $value;
}
}
}
}

public function loadOverrides():void {
foreach(self::FILE_OVERRIDE_ORDER as $override) {
$this->mergeDefaults(
$this->projectRoot,
"config.$override",
true
);
public function __construct(ConfigSection...$sectionList) {
foreach($sectionList as $section) {
$this->sectionList[$section->getName()] = $section;
}
}

Expand All @@ -78,38 +21,46 @@ public function get(string $name):?string {
}

public function getSection(string $sectionName):?ConfigSection {
if(!isset($this->kvp[$sectionName])) {
return null;
}

return new ConfigSection($this->kvp[$sectionName]);
return $this->sectionList[$sectionName] ?? null;
}

protected function getSectionValue(string $name):?string {
$parts = explode($this->delimeter, $name, 2);
$parts = explode(".", $name, 2);
$section = $this->getSection($parts[0]);

if(is_null($section)
|| empty($parts[1])) {
return null;
}

return $section[$parts[1]];
return $section->get($parts[1]);
}

protected function loadIni(string $directoryPath, string $filename):array {
$kvp = [];

$iniPath = $directoryPath
. DIRECTORY_SEPARATOR
. $filename
. "."
. self::INI_EXTENSION;
public function getSectionNames():array {
$names = [];

if(is_file($iniPath)) {
$kvp = parse_ini_file($iniPath, true);
foreach($this->sectionList as $section) {
$names []= $section->getName();
}

return $kvp;
return $names;
}

public function merge(Config $configToOverride):void {
foreach($configToOverride->getSectionNames() as $sectionName) {
if(isset($this->sectionList[$sectionName])) {
foreach($configToOverride->getSection($sectionName)
as $key => $value) {
if(empty($this->sectionList[$sectionName][$key])) {
$this->sectionList[$sectionName][$key] = $value;
}
}
}
else {
$this->sectionList[$sectionName] = $configToOverride->getSection(
$sectionName
);
}
}
}
}
63 changes: 63 additions & 0 deletions src/ConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
namespace Gt\Config;

class ConfigFactory {
const EXTENSION = "ini";
const FILE_DEFAULT = "default";
const FILE_OVERRIDE_ORDER = [
"dev",
"deploy",
"production",
];

public static function createForProject(string $projectRoot):Config {
$order = array_merge(
[self::FILE_DEFAULT, ""],
self::FILE_OVERRIDE_ORDER
);

$previousConfig = null;

foreach($order as $file) {
$fileName = "config";
$fileName .= ".";

if(!empty($file)) {
$fileName .= $file;
$fileName .= ".";
}

$fileName .= self::EXTENSION;
$config = self::createFromPathName(
implode(DIRECTORY_SEPARATOR,[
$projectRoot,
$fileName,
])
);
if(is_null($config)) {
continue;
}

if($previousConfig) {
$config->merge($previousConfig);
}

$previousConfig = $config;
}

return $config;
}

public static function createFromPathName(string $pathName):?Config {
if(!is_file($pathName)) {
return null;
}

$parser = new IniParser($pathName);
return $parser->parse();
}

public static function createFromArray(array $input):Config {

}
}
14 changes: 10 additions & 4 deletions src/ConfigSection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
use Iterator;

class ConfigSection implements ArrayAccess, Iterator {
protected $name;
protected $data;
protected $iteratorIndex;

public function __construct(array $data) {
public function __construct(string $name, array $data) {
$this->name = $name;
$this->data = $data;
}

Expand All @@ -19,7 +21,7 @@ public function get(string $key):?string {
/**
* @link http://php.net/manual/en/iterator.current.php
*/
public function current():array {
public function current():string {
$key = $this->getIteratorKey();
return $this->data[$key];
}
Expand Down Expand Up @@ -71,14 +73,18 @@ public function offsetGet($offset):?string {
* @link http://php.net/manual/en/arrayaccess.offsetset.php
*/
public function offsetSet($offset, $value):void {
throw new ImmutableObjectMutationException();
$this->data[$offset] = $value;
}

/**
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
*/
public function offsetUnset($offset):void {
throw new ImmutableObjectMutationException();
unset($this->data[$offset]);
}

public function getName():string {
return $this->name;
}

protected function getIteratorKey():?string {
Expand Down
39 changes: 39 additions & 0 deletions src/FileWriter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
namespace Gt\Config;

use Exception;
use WriteiniFile\WriteiniFile;

class FileWriter {
private $config;

public function __construct(Config $config) {
$this->config = $config;
}

public function writeIni(string $filePath):void {
if(!is_dir(dirname($filePath))) {
mkdir(dirname($filePath), 0775, true);
}

$writer = new WriteiniFile($filePath);

foreach($this->config->getSectionNames() as $sectionName) {
foreach($this->config->getSection($sectionName)
as $key => $value) {
$writer->add([
$sectionName => [
$key => $value,
]
]);
}
}

try {
$writer->write();
}
catch(Exception $exception) {
throw new ConfigException("Unable to write to file: $filePath");
}
}
}
4 changes: 0 additions & 4 deletions src/ImmutableObjectMutationException.php

This file was deleted.

Loading

0 comments on commit ab9fbd7

Please sign in to comment.