Permalink
Browse files

BUGFIX Merge request arrays recursively

  • Loading branch information...
1 parent 53506f3 commit dd546a98882a1291863b0dbe5858c28410092237 @simonwelsh simonwelsh committed Dec 22, 2011
Showing with 312 additions and 7 deletions.
  1. +2 −2 control/Director.php
  2. +1 −1 control/HTTPRequest.php
  3. +35 −2 core/ArrayLib.php
  4. +132 −1 tests/control/HTTPRequestTest.php
  5. +142 −1 tests/core/ArrayLibTest.php
View
@@ -84,7 +84,7 @@ static function direct($url, DataModel $model) {
(isset($_SERVER['X-HTTP-Method-Override'])) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'],
$url,
$_GET,
- array_merge((array)$_POST, (array)$_FILES),
+ ArrayLib::array_merge_recursive((array)$_POST, (array)$_FILES),
@file_get_contents('php://input')
);
@@ -193,7 +193,7 @@ static function test($url, $postVars = null, $session = null, $httpMethod = null
}
// Replace the superglobals with appropriate test values
- $_REQUEST = array_merge((array)$getVars, (array)$postVars);
+ $_REQUEST = ArrayLib::array_merge_recursive((array)$getVars, (array)$postVars);
$_GET = (array)$getVars;
$_POST = (array)$postVars;
$_SESSION = $session ? $session->inst_getAll() : array();
View
@@ -149,7 +149,7 @@ function postVars() {
* @return array
*/
function requestVars() {
- return array_merge($this->getVars, $this->postVars);
+ return ArrayLib::array_merge_recursive($this->getVars, $this->postVars);
}
function getVar($name) {
View
@@ -141,6 +141,39 @@ static function in_array_recursive($needle, $haystack, $strict = false) {
return false; // Never found $needle :(
}
+ /**
+ * Recursively merges two or more arrays.
+ *
+ * Behaves similar to array_merge_recursive(), however it only merges values when both are arrays
+ * rather than creating a new array with both values, as the PHP version does. The same behaviour
+ * also occurs with numeric keys, to match that of what PHP does to generate $_REQUEST.
+ *
+ * @param array $array, ...
+ * @return array
+ */
+ static function array_merge_recursive($array) {
+ $arrays = func_get_args();
+ $merged = array();
+ if(count($arrays) == 1) {
+ return $array;
+ }
+ while ($arrays) {
+ $array = array_shift($arrays);
+ if (!is_array($array)) {
+ trigger_error('ArrayLib::array_merge_recursive() encountered a non array argument', E_USER_WARNING);
+ return;
+ }
+ if (!$array) {
+ continue;
+ }
+ foreach ($array as $key => $value) {
+ if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key])) {
+ $merged[$key] = ArrayLib::array_merge_recursive($merged[$key], $value);
+ } else {
+ $merged[$key] = $value;
+ }
+ }
+ }
+ return $merged;
+ }
}
-
-?>
@@ -99,4 +99,135 @@ public function testHttpMethodOverrides() {
);
}
-}
+ public function testRequestVars() {
+ $getVars = array(
+ 'first' => 'a',
+ 'second' => 'b',
+ );
+ $postVars = array(
+ 'third' => 'c',
+ 'fourth' => 'd',
+ );
+ $requestVars = array(
+ 'first' => 'a',
+ 'second' => 'b',
+ 'third' => 'c',
+ 'fourth' => 'd',
+ );
+ $request = new SS_HTTPRequest(
+ 'POST',
+ 'admin/crm',
+ $getVars,
+ $postVars
+ );
+ $this->assertEquals(
+ $requestVars,
+ $request->requestVars(),
+ 'GET parameters should supplement POST parameters'
+ );
+
+ $getVars = array(
+ 'first' => 'a',
+ 'second' => 'b',
+ );
+ $postVars = array(
+ 'first' => 'c',
+ 'third' => 'd',
+ );
+ $requestVars = array(
+ 'first' => 'c',
+ 'second' => 'b',
+ 'third' => 'd',
+ );
+ $request = new SS_HTTPRequest(
+ 'POST',
+ 'admin/crm',
+ $getVars,
+ $postVars
+ );
+ $this->assertEquals(
+ $requestVars,
+ $request->requestVars(),
+ 'POST parameters should override GET parameters'
+ );
+
+ $getVars = array(
+ 'first' => array(
+ 'first' => 'a',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ );
+ $postVars = array(
+ 'first' => array(
+ 'first' => 'c',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $requestVars = array(
+ 'first' => array(
+ 'first' => 'c',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $request = new SS_HTTPRequest(
+ 'POST',
+ 'admin/crm',
+ $getVars,
+ $postVars
+ );
+ $this->assertEquals(
+ $requestVars,
+ $request->requestVars(),
+ 'Nested POST parameters should override GET parameters'
+ );
+
+ $getVars = array(
+ 'first' => array(
+ 'first' => 'a',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ );
+ $postVars = array(
+ 'first' => array(
+ 'second' => 'c',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $requestVars = array(
+ 'first' => array(
+ 'first' => 'a',
+ 'second' => 'c',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $request = new SS_HTTPRequest(
+ 'POST',
+ 'admin/crm',
+ $getVars,
+ $postVars
+ );
+ $this->assertEquals(
+ $requestVars,
+ $request->requestVars(),
+ 'Nested GET parameters should supplement POST parameters'
+ );
+ }
+}
View
@@ -45,5 +45,146 @@ function testValuekey() {
)
);
}
-
+
+ function testArrayMergeRecursive() {
+ $first = array(
+ 'first' => 'a',
+ 'second' => 'b',
+ );
+ $second = array(
+ 'third' => 'c',
+ 'fourth' => 'd',
+ );
+ $expected = array(
+ 'first' => 'a',
+ 'second' => 'b',
+ 'third' => 'c',
+ 'fourth' => 'd',
+ );
+ $this->assertEquals(
+ $expected,
+ ArrayLib::array_merge_recursive($first, $second),
+ 'First values should supplement second values'
+ );
+
+ $first = array(
+ 'first' => 'a',
+ 'second' => 'b',
+ );
+ $second = array(
+ 'first' => 'c',
+ 'third' => 'd',
+ );
+ $expected = array(
+ 'first' => 'c',
+ 'second' => 'b',
+ 'third' => 'd',
+ );
+ $this->assertEquals(
+ $expected,
+ ArrayLib::array_merge_recursive($first, $second),
+ 'Second values should override first values'
+ );
+
+ $first = array(
+ 'first' => array(
+ 'first' => 'a',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ );
+ $second = array(
+ 'first' => array(
+ 'first' => 'c',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $expected = array(
+ 'first' => array(
+ 'first' => 'c',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $this->assertEquals(
+ $expected,
+ ArrayLib::array_merge_recursive($first, $second),
+ 'Nested second values should override first values'
+ );
+
+ $first = array(
+ 'first' => array(
+ 'first' => 'a',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ );
+ $second = array(
+ 'first' => array(
+ 'second' => 'c',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $expected = array(
+ 'first' => array(
+ 'first' => 'a',
+ 'second' => 'c',
+ ),
+ 'second' => array(
+ 'second' => 'b',
+ ),
+ 'third' => array(
+ 'third' => 'd',
+ ),
+ );
+ $this->assertEquals(
+ $expected,
+ ArrayLib::array_merge_recursive($first, $second),
+ 'Nested first values should supplement second values'
+ );
+
+ $first = array(
+ 'first' => array(
+ 0 => 'a',
+ ),
+ 'second' => array(
+ 1 => 'b',
+ ),
+ );
+ $second = array(
+ 'first' => array(
+ 0 => 'c',
+ ),
+ 'third' => array(
+ 2 => 'd',
+ ),
+ );
+ $expected = array(
+ 'first' => array(
+ 0 => 'c',
+ ),
+ 'second' => array(
+ 1 => 'b',
+ ),
+ 'third' => array(
+ 2 => 'd',
+ ),
+ );
+
+ $this->assertEquals(
+ $expected,
+ ArrayLib::array_merge_recursive($first, $second),
+ 'Numeric keys should behave like string keys'
+ );
+ }
}

0 comments on commit dd546a9

Please sign in to comment.