Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Show file tree
Hide file tree
Showing 40 changed files with 595 additions and 458 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -9,7 +9,7 @@
"homepage": "https://github.com/zendframework/zend-config",
"autoload": {
"psr-4": {
"Zend\\Config": "src/"
"Zend\\Config\\": "src/"
}
},
"require": {
Expand Down
10 changes: 7 additions & 3 deletions src/Config.php
Expand Up @@ -10,10 +10,9 @@

namespace Zend\Config;

use ArrayAccess;
use Countable;
use Iterator;
use ArrayAccess;
use Zend\Stdlib\ArrayUtils;

/**
* Provides a property based interface to an array.
Expand Down Expand Up @@ -122,8 +121,13 @@ public function __get($name)
public function __set($name, $value)
{
if ($this->allowModifications) {

if (is_array($value)) {
$this->data[$name] = new self($value, true);
$value = new self($value, true);
}

if (null === $name) {
$this->data[] = $value;
} else {
$this->data[$name] = $value;
}
Expand Down
155 changes: 141 additions & 14 deletions src/Factory.php
Expand Up @@ -25,6 +25,13 @@ class Factory
*/
public static $readers = null;

/**
* Plugin manager for loading writers
*
* @var null|WriterPluginManager
*/
public static $writers = null;

/**
* Registered config file extensions.
* key is extension, value is reader instance or plugin name
Expand All @@ -38,43 +45,56 @@ class Factory
'yaml' => 'yaml',
);

/**
* Register config file extensions for writing
* key is extension, value is writer instance or plugin name
*
* @var array
*/
protected static $writerExtensions = array(
'php' => 'php',
'ini' => 'ini',
'json' => 'json',
'xml' => 'xml',
'yaml' => 'yaml',
);

/**
* Read a config from a file.
*
* @param string $filename
* @param boolean $returnConfigObject
* @param boolean $returnConfigObject
* @return array|Config
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
*/
public static function fromFile($filename, $returnConfigObject = false)
{
$pathinfo = pathinfo($filename);

if (!isset($pathinfo['extension'])) {
throw new Exception\RuntimeException(sprintf(
'Filename "%s" is missing an extension and cannot be auto-detected',
$filename
));
}

$extension = strtolower($pathinfo['extension']);

if ($extension === 'php') {
if (!is_file($filename) || !is_readable($filename)) {
throw new Exception\RuntimeException(sprintf(
"File '%s' doesn't exist or not readable",
$filename
));
}

$config = include $filename;
} elseif (isset(self::$extensions[$extension])) {
$reader = self::$extensions[$extension];
} elseif (isset(static::$extensions[$extension])) {
$reader = static::$extensions[$extension];
if (!$reader instanceof Reader\ReaderInterface) {
$reader = self::getReaderPluginManager()->get($reader);
self::$extensions[$extension] = $reader;
$reader = static::getReaderPluginManager()->get($reader);
static::$extensions[$extension] = $reader;
}

/** @var Reader\ReaderInterface $reader */
Expand All @@ -93,28 +113,85 @@ public static function fromFile($filename, $returnConfigObject = false)
* Read configuration from multiple files and merge them.
*
* @param array $files
* @param boolean $returnConfigObject
* @param boolean $returnConfigObject
* @return array|Config
*/
public static function fromFiles(array $files, $returnConfigObject = false)
{
$config = array();

foreach ($files as $file) {
$config = ArrayUtils::merge($config, self::fromFile($file));
$config = ArrayUtils::merge($config, static::fromFile($file));
}

return ($returnConfigObject) ? new Config($config) : $config;
}

/**
* Writes a config to a file
*
* @param string $filename
* @param array|Config $config
* @return boolean TRUE on success | FALSE on failure
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public static function toFile($filename, $config)
{
if (
(is_object($config) && !($config instanceOf Config)) ||
(!is_object($config) && !is_array($config))
) {
throw new Exception\InvalidArgumentException(
__METHOD__." \$config should be an array or instance of Zend\\Config\\Config"
);
}

$extension = substr(strrchr($filename, '.'), 1);
$directory = dirname($filename);

if (!is_dir($directory)) {
throw new Exception\RuntimeException(
"Directory '{$directory}' does not exists!"
);
}

if (!is_writable($directory)) {
throw new Exception\RuntimeException(
"Cannot write in directory '{$directory}'"
);
}

if(!isset(self::$writerExtensions[$extension])) {
throw new Exception\RuntimeException(
"Unsupported config file extension: '.{$extension}' for writing."
);
}

$writer = self::$writerExtensions[$extension];
if (($writer instanceOf Writer\AbstractWriter) === false) {
$writer = self::getWriterPluginManager()->get($writer);
self::$writerExtensions[$extension] = $writer;
}

if (is_object($config)) {
$config = $config->toArray();
}

$content = $writer->processConfig($config);

return (bool) (file_put_contents($filename, $content) !== false);
}

/**
* Set reader plugin manager
*
* @param ReaderPluginManager $readers
* @return void
*/
public static function setReaderPluginManager(ReaderPluginManager $readers)
{
self::$readers = $readers;
static::$readers = $readers;
}

/**
Expand All @@ -130,12 +207,38 @@ public static function getReaderPluginManager()
return static::$readers;
}

/**
* Set writer plugin manager
*
* @param WriterPluginManager $writers
* @return void
*/
public static function setWriterPluginManager(WriterPluginManager $writers)
{
self::$writers = $writers;
}

/**
* Get the writer plugin manager
*
* @return WriterPluginManager
*/
public static function getWriterPluginManager()
{
if (static::$writers === null) {
static::$writers = new WriterPluginManager();
}

return static::$writers;
}

/**
* Set config reader for file extension
*
* @param string $extension
* @param string|Reader\ReaderInterface $reader
* @throws Exception\InvalidArgumentException
* @return void
*/
public static function registerReader($extension, $reader)
{
Expand All @@ -144,12 +247,36 @@ public static function registerReader($extension, $reader)
if (!is_string($reader) && !$reader instanceof Reader\ReaderInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Reader should be plugin name, class name or ' .
'instance of %s\Reader\ReaderInterface; recieved "%s"',
'instance of %s\Reader\ReaderInterface; received "%s"',
__NAMESPACE__,
(is_object($reader) ? get_class($reader) : gettype($reader))
));
}

self::$extensions[$extension] = $reader;
static::$extensions[$extension] = $reader;
}

/**
* Set config writer for file extension
*
* @param string $extension
* @param string|Writer\AbstractWriter $writer
* @throw Exception\InvalidArgumentException
* @return void
*/
public static function registerWriter($extension, $writer)
{
$extension = strtolower($extension);

if (!is_string($writer) && !$writer instanceof Writer\AbstractWriter) {
throw new Exception\InvalidArgumentException(sprintf(
'Writer should be plugin name, class name or ' .
'instance of %s\Writer\AbstractWriter; received "%s"',
__NAMESPACE__,
(is_object($writer) ? get_class($writer) : gettype($writer))
));
}

self::$writerExtensions[$extension] = $writer;
}
}
2 changes: 1 addition & 1 deletion src/Processor/Filter.php
Expand Up @@ -56,7 +56,7 @@ public function getFilter()

/**
* Process
*
*
* @param Config $config
* @return Config
* @throws Exception\InvalidArgumentException
Expand Down
2 changes: 1 addition & 1 deletion src/Processor/Queue.php
Expand Up @@ -11,8 +11,8 @@
namespace Zend\Config\Processor;

use Zend\Config\Config;
use Zend\Stdlib\PriorityQueue;
use Zend\Config\Exception;
use Zend\Stdlib\PriorityQueue;

/**
* @category Zend
Expand Down
6 changes: 3 additions & 3 deletions src/Processor/Token.php
Expand Up @@ -10,9 +10,9 @@

namespace Zend\Config\Processor;

use Traversable;
use Zend\Config\Config;
use Zend\Config\Exception;
use Traversable;

/**
* @category Zend
Expand Down Expand Up @@ -51,7 +51,7 @@ class Token implements ProcessorInterface

/**
* Token Processor walks through a Config structure and replaces all
* occurences of tokens with supplied values.
* occurrences of tokens with supplied values.
*
* @param array|Config|Traversable $tokens Associative array of TOKEN => value
* to replace it with
Expand Down Expand Up @@ -200,7 +200,7 @@ protected function buildMap()
*
* @param Config $config
* @return Config
* @throws InvalidArgumentException
* @throws Exception\InvalidArgumentException
*/
public function process(Config $config)
{
Expand Down
13 changes: 9 additions & 4 deletions src/Reader/Ini.php
Expand Up @@ -63,7 +63,7 @@ public function getNestSeparator()
* @see ReaderInterface::fromFile()
* @param string $filename
* @return array
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
*/
public function fromFile($filename)
{
Expand All @@ -86,7 +86,7 @@ function($error, $message = '', $file = '', $line = 0) use ($filename) {
);
$ini = parse_ini_file($filename, true);
restore_error_handler();

return $this->process($ini);
}

Expand Down Expand Up @@ -114,7 +114,7 @@ function($error, $message = '', $file = '', $line = 0) {
);
$ini = parse_ini_string($string, true);
restore_error_handler();

return $this->process($ini);
}

Expand All @@ -130,7 +130,12 @@ protected function process(array $data)

foreach ($data as $section => $value) {
if (is_array($value)) {
$config[$section] = $this->processSection($value);
if (strpos($section, $this->nestSeparator) !== false) {
$section = explode($this->nestSeparator, $section, 2);
$config[$section[0]][$section[1]] = $this->processSection($value);
} else {
$config[$section] = $this->processSection($value);
}
} else {
$this->processKey($section, $value, $config);
}
Expand Down

0 comments on commit da4af46

Please sign in to comment.