From b23a5782793891f63beec507abc1449309d45656 Mon Sep 17 00:00:00 2001 From: Artur Bodera Date: Sat, 3 Mar 2012 14:38:00 +0100 Subject: [PATCH 1/9] Fix indendation. --- test/ConfigTest.php | 51 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/test/ConfigTest.php b/test/ConfigTest.php index 16c9589..effe49c 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -672,33 +672,32 @@ public function testZF6995_toArrayDoesNotDisturbInternalIterator() * @link http://framework.zend.com/issues/browse/ZF2-186 */ public function testZF2_186_mergeReplacingUnnamedConfigSettings(){ -$arrayA = array( - 'flag' => true, - 'text' => 'foo', - 'list' => array( 'a', 'b', 'c' ), - 'aSpecific' => 12 -); - -$arrayB = array( - 'flag' => false, - 'text' => 'bar', - 'list' => array( 'd', 'e' ), - 'bSpecific' => 100 -); - -$mergeResult = array( - 'flag' => false, - 'text' => 'bar', - 'list' => array( 'a', 'b', 'c', 'd', 'e' ), - 'aSpecific' => 12, - 'bSpecific' => 100 -); - -$configA = new Config($arrayA); -$configB = new Config($arrayB); - -$configA->merge($configB); // merge B onto A + $arrayA = array( + 'flag' => true, + 'text' => 'foo', + 'list' => array( 'a', 'b', 'c' ), + 'aSpecific' => 12 + ); + + $arrayB = array( + 'flag' => false, + 'text' => 'bar', + 'list' => array( 'd', 'e' ), + 'bSpecific' => 100 + ); + + $mergeResult = array( + 'flag' => false, + 'text' => 'bar', + 'list' => array( 'a', 'b', 'c', 'd', 'e' ), + 'aSpecific' => 12, + 'bSpecific' => 100 + ); + + $configA = new Config($arrayA); + $configB = new Config($arrayB); + $configA->merge($configB); // merge B onto A $this->assertEquals($mergeResult, $configA->toArray()); } } From 63070f557172d9828491c216363c514ff027d00c Mon Sep 17 00:00:00 2001 From: Artur Bodera Date: Sat, 3 Mar 2012 14:49:41 +0100 Subject: [PATCH 2/9] Fix method descr. --- src/Config.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Config.php b/src/Config.php index 7093aa2..3152530 100644 --- a/src/Config.php +++ b/src/Config.php @@ -335,10 +335,10 @@ public function offsetUnset($offset) } /** - * Replace values from in this config with values from other config. + * Replace values in this config with values from another config. * - * If an item exists in current config, it will be replaced by an item from $replace. - * If an item contains numerical list (array), respective elements will be REPLACED with values from $replace. + * If an item with the same key exists in current config, it will be replaced by an item from $replace. + * If an item contains a list (numerical array), elements will be REPLACED with values from $replace. * * @param Config $replace * @return Config @@ -369,7 +369,7 @@ public function replace(self $replace) /** * Merge values from another config into this one, replacing named values and appending items in lists. * - * If an item exists in current config, it will be replaced by item from $merge. + * If an item with the same key exists in current config, it will be replaced by item from $merge. * If an item contains numerical list (array), list will be APPENDED with items from $merge. * * @param Config $merge From a3f2c6c1659faa5ae81fc3afa43f11fda01965b4 Mon Sep 17 00:00:00 2001 From: Ben Scholzen Date: Sun, 4 Mar 2012 23:16:30 +0100 Subject: [PATCH 3/9] Some performance improvements --- src/Config.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Config.php b/src/Config.php index 101c342..abbcc24 100644 --- a/src/Config.php +++ b/src/Config.php @@ -336,19 +336,31 @@ public function offsetUnset($offset) /** * Merge another Config with this one. * - * @see ArrayReplergeRecursive::replerge() * @param self $merge * @return self */ public function merge(self $merge) { - $data = ArrayReplergeRecursive::replerge( - $this->toArray(), - $merge->toArray() - ); - - foreach ($data as $key => $value) { - $this->__set($key, $value); + foreach ($merge as $key => $value) { + if (array_key_exists($key, $this->data)) { + if (is_int($key)) { + $this->data[] = $value; + } elseif ($value instanceof self && $this->data[$key] instanceof self) { + $this->data[$key] = $this->data[$key]->merge($value); + } else { + if ($value instanceof self) { + $this->data[$key] = new self($value->toArray(), $this->allowModifications); + } else { + $this->data[$key] = $value; + } + } + } else { + if ($value instanceof self) { + $this->data[$key] = new self($value->toArray(), $this->allowModifications); + } else { + $this->data[$key] = $value; + } + } } return $this; From 5adff395c40ac1962d9bc8ccef54fda85258b393 Mon Sep 17 00:00:00 2001 From: Ben Scholzen Date: Mon, 5 Mar 2012 23:21:55 +0100 Subject: [PATCH 4/9] Renamed ArrayReplergeRecursive to RecursiveArrayMerge and updated doc blocks --- src/Config.php | 1 + src/Factory.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Config.php b/src/Config.php index abbcc24..870dfc9 100644 --- a/src/Config.php +++ b/src/Config.php @@ -336,6 +336,7 @@ public function offsetUnset($offset) /** * Merge another Config with this one. * + * @see Zend\Stdlib\RecursiveArrayMerge::merge() * @param self $merge * @return self */ diff --git a/src/Factory.php b/src/Factory.php index 6e11422..6a3577e 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -20,7 +20,7 @@ namespace Zend\Config; -use Zend\Stdlib\ArrayReplergeRecursive; +use Zend\Stdlib\RecursiveArrayMerge; /** * Declared abstract to prevent instantiation @@ -97,7 +97,7 @@ public static function fromFiles(array $files, $returnConfigObject = false) $config = array(); foreach ($files as $file) { - $config = ArrayReplergeRecursive::replerge($config, self::fromFile($file)); + $config = RecursiveArrayMerge::merge($config, self::fromFile($file)); } return ($returnConfigObject) ? new Config($config) : $config; From 06ca1944fa444521b677d3aeeb8f34947d1af17a Mon Sep 17 00:00:00 2001 From: Ben Scholzen Date: Mon, 5 Mar 2012 23:49:46 +0100 Subject: [PATCH 5/9] Removed unused use statement --- src/Config.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Config.php b/src/Config.php index 870dfc9..fa77e46 100644 --- a/src/Config.php +++ b/src/Config.php @@ -22,8 +22,7 @@ use Countable, Iterator, - ArrayAccess, - Zend\Stdlib\ArrayReplergeRecursive; + ArrayAccess; /** * @category Zend From 397ebe5a306ab6660ab0fe8fc84912357a88eca6 Mon Sep 17 00:00:00 2001 From: Artur Bodera Date: Tue, 6 Mar 2012 14:04:56 +0100 Subject: [PATCH 6/9] Introduce Stdlib\ArrayTools, refactor other components to use it. - add Stdlib\ArrayTools which combines the following: - Stdlib\RecursiveArrayMerge - Stdlib\IteratorToArray - Stdlib\IsAssocArray - add ArrayTools array testing functionality: - ::isList() - ::isHashTable() - ::hasNumericKeys() - ::hasIntegerKeys() - ::hasStringKeys() - add more exhaustive unit tests for ArrayTools including edge-cases for different types of arrays --- src/Config.php | 58 +++-------------------------------- src/Factory.php | 4 +-- src/Writer/AbstractWriter.php | 4 +-- test/ConfigTest.php | 55 +++------------------------------ 4 files changed, 14 insertions(+), 107 deletions(-) diff --git a/src/Config.php b/src/Config.php index 58aedc8..5fe13f7 100644 --- a/src/Config.php +++ b/src/Config.php @@ -23,7 +23,7 @@ use Countable, Iterator, ArrayAccess, - Zend\Stdlib\IsAssocArray + Zend\Stdlib\ArrayTools ; /** @@ -337,8 +337,10 @@ public function offsetUnset($offset) /** * Merge another Config with this one. * - * If an item with the same key exists in current config, it will be replaced by an item from $replace. - * If an item contains a list (numerical array), elements will be REPLACED with values from $replace. + * For duplicate keys, the following will be performed: + * - Nested Configs will be recursively merged. + * - Items in $merge with INTEGER keys will be appended. + * - Items in $merge with STRING keys will overwrite current values. * * @param Config $replace * @return Config @@ -370,56 +372,6 @@ public function merge(self $merge) return $this; } - /** - * Merge values from another config into this one, replacing named values and appending items in lists. - * - * If an item with the same key exists in current config, it will be replaced by item from $merge. - * If an item contains numerical list (array), list will be APPENDED with items from $merge. - * - * @param Config $merge - * @return Config - */ - public function merge(self $merge) - { - if ($merge->isNumerical() && $this->isNumerical()) { - // if both configs are numerical, append one to the other - foreach ($merge as $item) { - if ($item instanceof self) { - $this->data[] = new self($item->toArray(), $this->allowModifications); - } else { - $this->data[] = $item; - } - } - } else { - // if one of the configs is not numerical, perform standard replace - foreach ($merge as $key => $item) { - if (array_key_exists($key, $this->data)) { - if ($item instanceof self && $this->data[$key] instanceof self) { - $this->data[$key] = $this->data[$key]->merge(new self($item->toArray(), $this->allowModifications)); - } else { - $this->data[$key] = $item; - } - } else { - if ($item instanceof self) { - $this->data[$key] = new self($item->toArray(), $this->allowModifications); - } else { - $this->data[$key] = $item; - } - } - } - } - return $this; - } - - /** - * Check if current config is numerical - i.e. only contains numeric keys starting from 0 - * - * @return bool - */ - public function isNumerical(){ - return !IsAssocArray::test($this->data); - } - /** * Prevent any more modifications being made to this instance. * diff --git a/src/Factory.php b/src/Factory.php index 6a3577e..c0a554c 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -20,7 +20,7 @@ namespace Zend\Config; -use Zend\Stdlib\RecursiveArrayMerge; +use Zend\Stdlib\ArrayTools; /** * Declared abstract to prevent instantiation @@ -97,7 +97,7 @@ public static function fromFiles(array $files, $returnConfigObject = false) $config = array(); foreach ($files as $file) { - $config = RecursiveArrayMerge::merge($config, self::fromFile($file)); + $config = ArrayTools::merge($config, self::fromFile($file)); } return ($returnConfigObject) ? new Config($config) : $config; diff --git a/src/Writer/AbstractWriter.php b/src/Writer/AbstractWriter.php index 39ec779..3215754 100644 --- a/src/Writer/AbstractWriter.php +++ b/src/Writer/AbstractWriter.php @@ -23,7 +23,7 @@ use Zend\Config\Writer, Zend\Config\Exception, Zend\Config\Config, - Zend\Stdlib\IteratorToArray, + Zend\Stdlib\ArrayTools, Traversable; /** @@ -77,7 +77,7 @@ function($error, $message = '', $file = '', $line = 0) use ($filename) { public function toString($config) { if ($config instanceof Traversable) { - $config = IteratorToArray::convert($config); + $config = ArrayTools::iteratorToArray($config); } elseif (!is_array($config)) { throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable config'); } diff --git a/test/ConfigTest.php b/test/ConfigTest.php index d9fe207..c970ca3 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -120,7 +120,7 @@ public function setUp() false ), 'replaceAssoc' => null, - 'replaceNumerical' => null + 'replaceNumerical' => true ); $this->leadingdot = array('.test' => 'dot-test'); @@ -395,10 +395,10 @@ public function testMerge() // config->misaligned $this->assertInstanceOf('\Zend\Config\Config',$configA->misaligned); - $this->assertEquals(null,$configA->misaligned->{0}); - $this->assertEquals(null,$configA->misaligned->{1}); $this->assertEquals('foo',$configA->misaligned->{2}); - $this->assertEquals('baz',$configA->misaligned->{3}); + $this->assertEquals('bar',$configA->misaligned->{3}); + $this->assertEquals('baz',$configA->misaligned->{4}); + $this->assertEquals(null,$configA->misaligned->{0}); // config->mixed $this->assertInstanceOf('\Zend\Config\Config',$configA->mixed); @@ -410,55 +410,10 @@ public function testMerge() $this->assertSame(null,$configA->replaceAssoc); // config->replaceNumerical - $this->assertSame(null,$configA->replaceNumerical); + $this->assertSame(true,$configA->replaceNumerical); } - public function testReplace() - { - $configA = new Config($this->toCombineA); - $configB = new Config($this->toCombineB); - $configA->replace($configB); - - // config-> - $this->assertEquals(3, $configA->foo); - $this->assertEquals(2, $configA->bar); - $this->assertEquals('bar', $configA->text); - - // config->numerical-> ... - $this->assertInstanceOf('\Zend\Config\Config',$configA->numerical); - $this->assertEquals('fourth',$configA->numerical->{0}); - $this->assertEquals('fifth',$configA->numerical->{1}); - - // config->numerical->{2}-> ... - $this->assertInstanceOf('\Zend\Config\Config',$configA->numerical->{2}); - $this->assertEquals('sixth',$configA->numerical->{2}->{0}); - $this->assertEquals(null,$configA->numerical->{2}->{1}); - - // config->numerical-> ... - $this->assertEquals(null,$configA->numerical->{3}); - $this->assertEquals(null,$configA->numerical->{4}); - - // config->misaligned - $this->assertInstanceOf('\Zend\Config\Config',$configA->misaligned); - $this->assertEquals(null,$configA->misaligned->{0}); - $this->assertEquals(null,$configA->misaligned->{1}); - $this->assertEquals('foo',$configA->misaligned->{2}); - $this->assertEquals('baz',$configA->misaligned->{3}); - - // config->mixed - $this->assertInstanceOf('\Zend\Config\Config',$configA->mixed); - $this->assertEquals('bar',$configA->mixed->foo); - $this->assertSame(false,$configA->mixed->{0}); - $this->assertSame(null,$configA->mixed->{1}); - - // config->replaceAssoc - $this->assertSame(null,$configA->replaceAssoc); - - // config->replaceNumerical - $this->assertSame(null,$configA->replaceNumerical); - } - public function testArrayAccess() { $config = new Config($this->all, true); From 1549d3f31ea898c3985e0efb4184e3cf295188cd Mon Sep 17 00:00:00 2001 From: Artur Bodera Date: Tue, 6 Mar 2012 16:54:06 +0100 Subject: [PATCH 7/9] Remove unneeded assignment, remove redundant RecursiveArrayMerge.php --- src/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Config.php b/src/Config.php index 5fe13f7..1f65e33 100644 --- a/src/Config.php +++ b/src/Config.php @@ -352,7 +352,7 @@ public function merge(self $merge) if (is_int($key)) { $this->data[] = $value; } elseif ($value instanceof self && $this->data[$key] instanceof self) { - $this->data[$key] = $this->data[$key]->merge($value); + $this->data[$key]->merge($value); } else { if ($value instanceof self) { $this->data[$key] = new self($value->toArray(), $this->allowModifications); From 1e630affda733b0297d3080ef0bceb6eb2848332 Mon Sep 17 00:00:00 2001 From: Thinkscape Date: Thu, 8 Mar 2012 17:29:22 +0100 Subject: [PATCH 8/9] Refactor Zend\Stdlib\ArrayTools to ArrayUtils, add missing headers. - ArrayTools will now be called ArrayUtils after an anonymous vote (http://framework.zend.com/wiki/display/ZFDEV2/POLL+-+Array+class+name). - Add missing Zend Framework headers to ArrayUtils class file and tests. --- src/Config.php | 2 +- src/Factory.php | 4 ++-- src/Writer/AbstractWriter.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Config.php b/src/Config.php index 1f65e33..a36341f 100644 --- a/src/Config.php +++ b/src/Config.php @@ -23,7 +23,7 @@ use Countable, Iterator, ArrayAccess, - Zend\Stdlib\ArrayTools + Zend\Stdlib\ArrayUtils ; /** diff --git a/src/Factory.php b/src/Factory.php index c0a554c..5fd1366 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -20,7 +20,7 @@ namespace Zend\Config; -use Zend\Stdlib\ArrayTools; +use Zend\Stdlib\ArrayUtils; /** * Declared abstract to prevent instantiation @@ -97,7 +97,7 @@ public static function fromFiles(array $files, $returnConfigObject = false) $config = array(); foreach ($files as $file) { - $config = ArrayTools::merge($config, self::fromFile($file)); + $config = ArrayUtils::merge($config, self::fromFile($file)); } return ($returnConfigObject) ? new Config($config) : $config; diff --git a/src/Writer/AbstractWriter.php b/src/Writer/AbstractWriter.php index 3215754..4ae0022 100644 --- a/src/Writer/AbstractWriter.php +++ b/src/Writer/AbstractWriter.php @@ -23,7 +23,7 @@ use Zend\Config\Writer, Zend\Config\Exception, Zend\Config\Config, - Zend\Stdlib\ArrayTools, + Zend\Stdlib\ArrayUtils, Traversable; /** @@ -77,7 +77,7 @@ function($error, $message = '', $file = '', $line = 0) use ($filename) { public function toString($config) { if ($config instanceof Traversable) { - $config = ArrayTools::iteratorToArray($config); + $config = ArrayUtils::iteratorToArray($config); } elseif (!is_array($config)) { throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable config'); } From 07cb2e629b60e9e8cbd46cc767fbda19fd33fc92 Mon Sep 17 00:00:00 2001 From: Thinkscape Date: Thu, 8 Mar 2012 18:56:16 +0100 Subject: [PATCH 9/9] Minor cleanup --- test/ConfigTest.php | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/test/ConfigTest.php b/test/ConfigTest.php index c970ca3..c67efc2 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -331,38 +331,6 @@ public function testUnset() } - public function testMerge_old() - { - $stdArray = array( - 'test_feature' => false, - 'some_files' => array( - 'foo'=>'dir/foo.xml', - 'bar'=>'dir/bar.xml', - ), - 2 => 123, - ); - $stdConfig = new Config($stdArray, true); - - $devArray = array( - 'test_feature'=>true, - 'some_files' => array( - 'bar' => 'myDir/bar.xml', - 'baz' => 'myDir/baz.xml', - ), - 2 => 456, - ); - $devConfig = new Config($devArray); - - $stdConfig->merge($devConfig); - - $this->assertTrue($stdConfig->test_feature); - $this->assertEquals('myDir/bar.xml', $stdConfig->some_files->bar); - $this->assertEquals('myDir/baz.xml', $stdConfig->some_files->baz); - $this->assertEquals('dir/foo.xml', $stdConfig->some_files->foo); - $this->assertEquals(123, $stdConfig->{2}); - $this->assertEquals(456, $stdConfig->{3}); - } - public function testMerge() { $configA = new Config($this->toCombineA);