BUGFIX Merge request arrays recursively

This commit is contained in:
Simon Welsh 2011-12-23 11:04:44 +13:00
parent 53506f37f2
commit dd546a9888
5 changed files with 312 additions and 7 deletions

View File

@ -84,7 +84,7 @@ class Director {
(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 @@ class Director {
}
// 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 File

@ -149,7 +149,7 @@ class SS_HTTPRequest implements ArrayAccess {
* @return array
*/
function requestVars() {
return array_merge($this->getVars, $this->postVars);
return ArrayLib::array_merge_recursive($this->getVars, $this->postVars);
}
function getVar($name) {

View File

@ -141,6 +141,39 @@ class ArrayLib {
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;
}
}
?>

View File

@ -99,4 +99,135 @@ class HTTPRequestTest extends SapphireTest {
);
}
}
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 File

@ -45,5 +45,146 @@ class ArrayLibTest extends SapphireTest {
)
);
}
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'
);
}
}