diff --git a/src/Processor.php b/src/Processor.php
index 996260c..1e289ec 100644
--- a/src/Processor.php
+++ b/src/Processor.php
@@ -18,9 +18,6 @@
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-/**
- * @namespace
- */
namespace Zend\Config;
/**
diff --git a/src/Processor/Constant.php b/src/Processor/Constant.php
index 5821e5a..da32f56 100644
--- a/src/Processor/Constant.php
+++ b/src/Processor/Constant.php
@@ -18,9 +18,6 @@
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-/**
- * @namespace
- */
namespace Zend\Config\Processor;
use Zend\Config\Config,
diff --git a/src/Processor/Filter.php b/src/Processor/Filter.php
index e27b1d2..402b053 100644
--- a/src/Processor/Filter.php
+++ b/src/Processor/Filter.php
@@ -18,9 +18,6 @@
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-/**
- * @namespace
- */
namespace Zend\Config\Processor;
use Zend\Config\Config,
diff --git a/src/Processor/Queue.php b/src/Processor/Queue.php
index 8cb3029..7b91d90 100644
--- a/src/Processor/Queue.php
+++ b/src/Processor/Queue.php
@@ -18,9 +18,6 @@
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-/**
- * @namespace
- */
namespace Zend\Config\Processor;
use Zend\Config\Config,
diff --git a/src/Processor/Token.php b/src/Processor/Token.php
index 0264941..44041a4 100644
--- a/src/Processor/Token.php
+++ b/src/Processor/Token.php
@@ -18,9 +18,6 @@
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-/**
- * @namespace
- */
namespace Zend\Config\Processor;
use Zend\Config\Config,
@@ -200,7 +197,7 @@ protected function buildMap()
foreach ($this->tokens as $token => $value) {
$this->map[$this->prefix . $token . $this->suffix] = $value;
}
- }
+ }
}
/**
@@ -228,7 +225,7 @@ public function process(Config $config)
if ($val instanceof Config) {
$this->process($val);
} else {
- $config->$key = str_replace($keys,$values,$val);
+ $config->$key = str_replace($keys, $values, $val);
}
}
@@ -248,6 +245,6 @@ public function processValue($value)
}
$keys = array_keys($this->map);
$values = array_values($this->map);
- return str_replace($keys,$values,$value);
+ return str_replace($keys, $values, $value);
}
}
\ No newline at end of file
diff --git a/src/Processor/Translator.php b/src/Processor/Translator.php
index 74c1080..1549bfb 100644
--- a/src/Processor/Translator.php
+++ b/src/Processor/Translator.php
@@ -18,9 +18,6 @@
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
-/**
- * @namespace
- */
namespace Zend\Config\Processor;
use Zend\Config\Config,
@@ -108,22 +105,22 @@ public function process(Config $config)
if ($val instanceof Config) {
$this->process($val);
} else {
- $config->$key = $this->translator->translate($val,$this->locale);
+ $config->$key = $this->translator->translate($val, $this->locale);
}
}
return $config;
}
- /**
- * Process a single value
- *
- * @param $value
- * @return mixed
- */
- public function processValue($value)
- {
- return $this->translator->translate($value,$this->locale);
- }
+ /**
+ * Process a single value
+ *
+ * @param $value
+ * @return mixed
+ */
+ public function processValue($value)
+ {
+ return $this->translator->translate($value, $this->locale);
+ }
}
diff --git a/src/Reader/Ini.php b/src/Reader/Ini.php
index a5ce4cb..949bef0 100644
--- a/src/Reader/Ini.php
+++ b/src/Reader/Ini.php
@@ -141,7 +141,7 @@ protected function process(array $data)
if (is_array($value)) {
$config[$section] = $this->processSection($value);
} else {
- $config[$section] = $value;
+ $this->processKey($section, $value, $config);
}
}
diff --git a/src/Reader/Json.php b/src/Reader/Json.php
new file mode 100644
index 0000000..b559a88
--- /dev/null
+++ b/src/Reader/Json.php
@@ -0,0 +1,113 @@
+directory = dirname($filename);
+
+ try {
+ $config = JsonFormat::decode(file_get_contents($filename), JsonFormat::TYPE_ARRAY);
+ } catch (\Zend\Json\Exception\RuntimeException $e) {
+ throw new Exception\RuntimeException($e->getMessage());
+ }
+
+ return $this->process($config);
+ }
+
+ /**
+ * fromString(): defined by Reader interface.
+ *
+ * @see Reader::fromString()
+ * @param string $string
+ * @return array
+ */
+ public function fromString($string)
+ {
+ if (empty($string)) {
+ return array();
+ }
+ $this->directory = null;
+
+ try {
+ $config = JsonFormat::decode($string, JsonFormat::TYPE_ARRAY);
+ } catch (\Zend\Json\Exception\RuntimeException $e) {
+ throw new Exception\RuntimeException($e->getMessage());
+ }
+
+ return $this->process($config);
+ }
+ /**
+ * Process the array for @include
+ *
+ * @param array $data
+ * @return array
+ */
+ protected function process(array $data) {
+ foreach ($data as $key => $value) {
+ if (is_array($value)) {
+ $data[$key] = $this->process($value);
+ }
+ if (trim($key)==='@include') {
+ if ($this->directory === null) {
+ throw new Exception\RuntimeException('Cannot process @include statement for a json string');
+ }
+ $reader = clone $this;
+ unset($data[$key]);
+ $data = array_replace_recursive($data, $reader->fromFile($this->directory . '/' . $value));
+ }
+ }
+ return $data;
+ }
+}
\ No newline at end of file
diff --git a/src/Reader/Yaml.php b/src/Reader/Yaml.php
new file mode 100644
index 0000000..d8aa081
--- /dev/null
+++ b/src/Reader/Yaml.php
@@ -0,0 +1,160 @@
+setYamlDecoder($yamlDecoder);
+ } else {
+ if (function_exists('yaml_parse')) {
+ $this->setYamlDecoder('yaml_parse');
+ }
+ }
+ }
+ /**
+ * Get callback for decoding YAML
+ *
+ * @return callable
+ */
+ public function getYamlDecoder()
+ {
+ return $this->yamlDecoder;
+ }
+ /**
+ * Set callback for decoding YAML
+ *
+ * @param callable $yamlDecoder the decoder to set
+ * @return Yaml
+ */
+ public function setYamlDecoder($yamlDecoder)
+ {
+ if (!is_callable($yamlDecoder)) {
+ throw new Exception\InvalidArgumentException('Invalid parameter to setYamlDecoder() - must be callable');
+ }
+ $this->yamlDecoder = $yamlDecoder;
+ return $this;
+ }
+ /**
+ * fromFile(): defined by Reader interface.
+ *
+ * @see Reader::fromFile()
+ * @param string $filename
+ * @return array
+ */
+ public function fromFile($filename)
+ {
+ if (!file_exists($filename)) {
+ throw new Exception\RuntimeException("The file $filename doesn't exists.");
+ }
+ if (null === $this->getYamlDecoder()) {
+ throw new Exception\RuntimeException("You didn't specify a Yaml callback decoder");
+ }
+
+ $this->directory = dirname($filename);
+
+ $config = call_user_func($this->getYamlDecoder(), file_get_contents($filename));
+ if (null === $config) {
+ throw new Exception\RuntimeException("Error parsing YAML data");
+ }
+
+ return $this->process($config);
+ }
+
+ /**
+ * fromString(): defined by Reader interface.
+ *
+ * @see Reader::fromString()
+ * @param string $string
+ * @return array
+ */
+ public function fromString($string)
+ {
+ if (null === $this->getYamlDecoder()) {
+ throw new Exception\RuntimeException("You didn't specify a Yaml callback decoder");
+ }
+ if (empty($string)) {
+ return array();
+ }
+
+ $this->directory = null;
+
+ $config = call_user_func($this->getYamlDecoder(), $string);
+ if (null === $config) {
+ throw new Exception\RuntimeException("Error parsing YAML data");
+ }
+
+ return $this->process($config);
+ }
+ /**
+ * Process the array for @include
+ *
+ * @param array $data
+ * @return array
+ */
+ protected function process(array $data) {
+ foreach ($data as $key => $value) {
+ if (is_array($value)) {
+ $data[$key] = $this->process($value);
+ }
+ if (trim($key)==='@include') {
+ if ($this->directory === null) {
+ throw new Exception\RuntimeException('Cannot process @include statement for a json string');
+ }
+ $reader = clone $this;
+ unset($data[$key]);
+ $data = array_replace_recursive($data, $reader->fromFile($this->directory . '/' . $value));
+ }
+ }
+ return $data;
+ }
+}
\ No newline at end of file
diff --git a/src/Writer/Json.php b/src/Writer/Json.php
new file mode 100644
index 0000000..5020f5b
--- /dev/null
+++ b/src/Writer/Json.php
@@ -0,0 +1,43 @@
+setYamlEncoder($yamlEncoder);
+ } else {
+ if (function_exists('yaml_parse')) {
+ $this->setYamlEncoder('yaml_parse');
+ }
+ }
+ }
+ /**
+ * Get callback for decoding YAML
+ *
+ * @return callable
+ */
+ public function getYamlEncoder()
+ {
+ return $this->yamlEncoder;
+ }
+ /**
+ * Set callback for decoding YAML
+ *
+ * @param callable $yamlEncoder the decoder to set
+ * @return Yaml
+ */
+ public function setYamlEncoder($yamlEncoder)
+ {
+ if (!is_callable($yamlEncoder)) {
+ throw new Exception\InvalidArgumentException('Invalid parameter to setYamlEncoder() - must be callable');
+ }
+ $this->yamlEncoder = $yamlEncoder;
+ return $this;
+ }
+ /**
+ * processConfig(): defined by AbstractWriter.
+ *
+ * @param array $config
+ * @return string
+ */
+ public function processConfig(array $config)
+ {
+ if (null === $this->getYamlEncoder()) {
+ throw new Exception\RuntimeException("You didn't specify a Yaml callback encoder");
+ }
+
+ $config = call_user_func($this->getYamlEncoder(), $config);
+ if (null === $config) {
+ throw new Exception\RuntimeException("Error generating YAML data");
+ }
+
+ return $config;
+ }
+}
diff --git a/test/Reader/AbstractReaderTestCase.php b/test/Reader/AbstractReaderTestCase.php
index a3e07e8..4c13cdc 100644
--- a/test/Reader/AbstractReaderTestCase.php
+++ b/test/Reader/AbstractReaderTestCase.php
@@ -57,7 +57,7 @@ public function testMissingFile()
public function testFromFile()
{
$config = $this->reader->fromFile($this->getTestAssetPath('include-base'));
- $this->assertEquals('foo', $config['base']['foo']);
+ $this->assertEquals('foo', $config['foo']);
}
public function testFromEmptyString()
diff --git a/test/Reader/JsonTest.php b/test/Reader/JsonTest.php
new file mode 100644
index 0000000..7ae3702
--- /dev/null
+++ b/test/Reader/JsonTest.php
@@ -0,0 +1,83 @@
+reader = new Json();
+ }
+
+ /**
+ * getTestAssetPath(): defined by AbstractReaderTestCase.
+ *
+ * @see AbstractReaderTestCase::getTestAssetPath()
+ * @return string
+ */
+ protected function getTestAssetPath($name)
+ {
+ return __DIR__ . '/TestAssets/Json/' . $name . '.json';
+ }
+
+ public function testInvalidJsonFile()
+ {
+ $this->setExpectedException('Zend\Config\Exception\RuntimeException');
+ $arrayJson = $this->reader->fromFile($this->getTestAssetPath('invalid'));
+ }
+
+ public function testIncludeAsElement()
+ {
+ $arrayJson = $this->reader->fromFile($this->getTestAssetPath('include-base_nested'));
+ $this->assertEquals($arrayJson['bar']['foo'], 'foo');
+ }
+
+ public function testFromString()
+ {
+ $json = '{ "test" : "foo", "bar" : [ "baz", "foo" ] }';
+
+ $arrayJson = $this->reader->fromString($json);
+
+ $this->assertEquals($arrayJson['test'], 'foo');
+ $this->assertEquals($arrayJson['bar'][0], 'baz');
+ $this->assertEquals($arrayJson['bar'][1], 'foo');
+ }
+
+ public function testInvalidString()
+ {
+ $json = '{"foo":"bar"';
+
+ $this->setExpectedException('Zend\Config\Exception\RuntimeException');
+ $arrayIni = $this->reader->fromString($json);
+ }
+
+}
diff --git a/test/Reader/TestAssets/Ini/include-base.ini b/test/Reader/TestAssets/Ini/include-base.ini
index d81f5c3..a4e9480 100644
--- a/test/Reader/TestAssets/Ini/include-base.ini
+++ b/test/Reader/TestAssets/Ini/include-base.ini
@@ -1,2 +1 @@
-[base]
@include = 'include-target.ini'
diff --git a/test/Reader/TestAssets/Json/include-base.json b/test/Reader/TestAssets/Json/include-base.json
new file mode 100644
index 0000000..ee3af2e
--- /dev/null
+++ b/test/Reader/TestAssets/Json/include-base.json
@@ -0,0 +1,3 @@
+{
+ "@include" : "include-target.json"
+}
\ No newline at end of file
diff --git a/test/Reader/TestAssets/Json/include-base_nested.json b/test/Reader/TestAssets/Json/include-base_nested.json
new file mode 100644
index 0000000..7ee7b59
--- /dev/null
+++ b/test/Reader/TestAssets/Json/include-base_nested.json
@@ -0,0 +1,3 @@
+{
+ "bar" : { "@include" : "include-target.json" }
+}
\ No newline at end of file
diff --git a/test/Reader/TestAssets/Json/include-target.json b/test/Reader/TestAssets/Json/include-target.json
new file mode 100644
index 0000000..67e4d41
--- /dev/null
+++ b/test/Reader/TestAssets/Json/include-target.json
@@ -0,0 +1,3 @@
+{
+ "foo" : "foo"
+}
diff --git a/test/Reader/TestAssets/Json/invalid.json b/test/Reader/TestAssets/Json/invalid.json
new file mode 100644
index 0000000..3e1b208
--- /dev/null
+++ b/test/Reader/TestAssets/Json/invalid.json
@@ -0,0 +1,3 @@
+{
+ "test": "test"
+
diff --git a/test/Reader/TestAssets/Xml/include-base.xml b/test/Reader/TestAssets/Xml/include-base.xml
index b2862b5..3c52f34 100644
--- a/test/Reader/TestAssets/Xml/include-base.xml
+++ b/test/Reader/TestAssets/Xml/include-base.xml
@@ -1,6 +1,4 @@
-
-
-
+
\ No newline at end of file
diff --git a/test/Reader/TestAssets/Yaml/include-base.yaml b/test/Reader/TestAssets/Yaml/include-base.yaml
new file mode 100644
index 0000000..4f891f2
--- /dev/null
+++ b/test/Reader/TestAssets/Yaml/include-base.yaml
@@ -0,0 +1 @@
+@include: include-target.yaml
\ No newline at end of file
diff --git a/test/Reader/TestAssets/Yaml/include-target.yaml b/test/Reader/TestAssets/Yaml/include-target.yaml
new file mode 100644
index 0000000..d867783
--- /dev/null
+++ b/test/Reader/TestAssets/Yaml/include-target.yaml
@@ -0,0 +1 @@
+foo: foo
\ No newline at end of file
diff --git a/test/Reader/YamlTest.php b/test/Reader/YamlTest.php
new file mode 100644
index 0000000..ea8087f
--- /dev/null
+++ b/test/Reader/YamlTest.php
@@ -0,0 +1,104 @@
+markTestSkipped('Yaml test for Zend\Config skipped');
+ }
+
+ if (constant('TESTS_ZEND_CONFIG_YAML_LIB_INCLUDE')) {
+ require_once constant('TESTS_ZEND_CONFIG_YAML_LIB_INCLUDE');
+ }
+
+ $yamlReader = explode('::', constant('TESTS_ZEND_CONFIG_READER_YAML_CALLBACK'));
+ if (isset($yamlReader[1])) {
+ $this->reader = new YamlReader(array($yamlReader[0], $yamlReader[1]));
+ } else {
+ $this->reader = new YamlReader(array($yamlReader[0]));
+ }
+ }
+
+ /**
+ * getTestAssetPath(): defined by AbstractReaderTestCase.
+ *
+ * @see AbstractReaderTestCase::getTestAssetPath()
+ * @return string
+ */
+ protected function getTestAssetPath($name)
+ {
+ return __DIR__ . '/TestAssets/Yaml/' . $name . '.yaml';
+ }
+
+ public function testInvalidIniFile()
+ {
+ $this->setExpectedException('Zend\Config\Exception\RuntimeException');
+ $arrayIni = $this->reader->fromFile($this->getTestAssetPath('invalid'));
+ }
+
+ public function testFromString()
+ {
+ $yaml = <<reader->fromString($yaml);
+ $this->assertEquals($arrayYaml['test'], 'foo');
+ $this->assertEquals($arrayYaml['bar'][0], 'baz');
+ $this->assertEquals($arrayYaml['bar'][1], 'foo');
+ }
+
+ public function testFromStringWithSection()
+ {
+ $yaml = <<reader->fromString($yaml);
+ $this->assertEquals($arrayYaml['all']['test'], 'foo');
+ $this->assertEquals($arrayYaml['all']['bar'][0], 'baz');
+ $this->assertEquals($arrayYaml['all']['bar'][1], 'foo');
+ }
+}
diff --git a/test/Writer/JsonTest.php b/test/Writer/JsonTest.php
new file mode 100644
index 0000000..ed89f00
--- /dev/null
+++ b/test/Writer/JsonTest.php
@@ -0,0 +1,70 @@
+reader = new JsonReader();
+ $this->writer = new JsonWriter();
+ }
+
+
+
+ public function testNoSection()
+ {
+ $config = new Config(array('test' => 'foo', 'test2' => array('test3' => 'bar')));
+
+ $this->writer->toFile($this->getTestAssetFileName(), $config);
+
+ $config = $this->reader->fromFile($this->getTestAssetFileName());
+
+ $this->assertEquals('foo', $config['test']);
+ $this->assertEquals('bar', $config['test2']['test3']);
+ }
+
+ public function testWriteAndReadOriginalFile()
+ {
+ $config = $this->reader->fromFile(__DIR__ . '/files/allsections.json');
+
+ $this->writer->toFile($this->getTestAssetFileName(), $config);
+
+ $config = $this->reader->fromFile($this->getTestAssetFileName());
+
+ $this->assertEquals('multi', $config['all']['one']['two']['three']);
+
+ }
+}
diff --git a/test/Writer/YamlTest.php b/test/Writer/YamlTest.php
new file mode 100644
index 0000000..73e9a40
--- /dev/null
+++ b/test/Writer/YamlTest.php
@@ -0,0 +1,87 @@
+markTestSkipped('Yaml test for Zend\Config skipped');
+ }
+
+ if (constant('TESTS_ZEND_CONFIG_YAML_LIB_INCLUDE')) {
+ require_once constant('TESTS_ZEND_CONFIG_YAML_LIB_INCLUDE');
+ }
+
+ $yamlReader = explode('::', constant('TESTS_ZEND_CONFIG_READER_YAML_CALLBACK'));
+ if (isset($yamlReader[1])) {
+ $this->reader = new YamlReader(array($yamlReader[0], $yamlReader[1]));
+ } else {
+ $this->reader = new YamlReader(array($yamlReader[0]));
+ }
+
+ $yamlWriter = explode('::', constant('TESTS_ZEND_CONFIG_WRITER_YAML_CALLBACK'));
+ if (isset($yamlWriter[1])) {
+ $this->writer = new YamlWriter(array($yamlWriter[0], $yamlWriter[1]));
+ } else {
+ $this->writer = new YamlWriter(array($yamlWriter[0]));
+ }
+ }
+
+ public function testNoSection()
+ {
+ $config = new Config(array('test' => 'foo', 'test2' => array('test3' => 'bar')));
+
+ $this->writer->toFile($this->getTestAssetFileName(), $config);
+
+ $config = $this->reader->fromFile($this->getTestAssetFileName());
+
+ $this->assertEquals('foo', $config['test']);
+ $this->assertEquals('bar', $config['test2']['test3']);
+ }
+
+ public function testWriteAndReadOriginalFile()
+ {
+ $config = $this->reader->fromFile(__DIR__ . '/files/allsections.yaml');
+
+ $this->writer->toFile($this->getTestAssetFileName(), $config);
+
+ $config = $this->reader->fromFile($this->getTestAssetFileName());
+
+ $this->assertEquals('multi', $config['all']['one']['two']['three']);
+
+ }
+}
diff --git a/test/Writer/files/allsections.json b/test/Writer/files/allsections.json
new file mode 100644
index 0000000..d47bd4e
--- /dev/null
+++ b/test/Writer/files/allsections.json
@@ -0,0 +1,45 @@
+{
+"all" : {
+ "hostname" : "all",
+ "name" : "thisname",
+ "db" : {
+ "host" : "127.0.0.1",
+ "user" : "username",
+ "pass" : "password",
+ "name" : "live"
+ },
+ "one" : {
+ "two" : {
+ "three" : "multi"
+ }
+ }
+},
+"staging" : {
+ "hostname" : "staging",
+ "db" : {
+ "name" : "dbstaging"
+ },
+ "debug" : "false"
+},
+"debug" : {
+ "hostname" : "debug",
+ "debug" : "true",
+ "values" : {
+ "changed" : "yes"
+ },
+ "db" : {
+ "name" : "dbdebug"
+ },
+ "special" : {
+ "no" : "no",
+ "null" : "null",
+ "false" : "false"
+ }
+},
+"other_staging" : {
+ "only_in" : "otherStaging",
+ "db" : {
+ "pass" : "anotherpwd"
+ }
+}
+}
\ No newline at end of file
diff --git a/test/Writer/files/allsections.yaml b/test/Writer/files/allsections.yaml
new file mode 100644
index 0000000..1dafe98
--- /dev/null
+++ b/test/Writer/files/allsections.yaml
@@ -0,0 +1,35 @@
+all:
+# this is a comment
+ hostname: all
+ name: thisname
+ db:
+ host: 127.0.0.1
+ user: username
+ pass: password
+ name: live
+ one:
+ two:
+ three: multi
+
+staging:
+ hostname: staging
+ db:
+ name: dbstaging
+ debug:
+ _extends: all
+debug:
+ hostname: debug
+ debug: 1
+ values:
+ changed: 1
+ db:
+ name: dbdebug
+ special:
+ no:
+ null:
+ false:
+ _extends: all
+other_staging:
+ only_in: otherStaging
+ db:
+ pass: anotherpwd