From 71c2f384ece75e6e3508302fbc4b0343684749e8 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Sun, 27 Aug 2017 22:45:50 -0500 Subject: [PATCH] Support retrieving array syntax values from POST, GET, etc. Fixes #627 --- system/Entity.php | 4 +- system/HTTP/Request.php | 106 +++++++++------------- system/Model.php | 1 + tests/system/HTTP/IncomingRequestTest.php | 61 ++++++++++++- 4 files changed, 107 insertions(+), 65 deletions(-) diff --git a/system/Entity.php b/system/Entity.php index 6cac6c65f5b2..bd7e54f6795a 100644 --- a/system/Entity.php +++ b/system/Entity.php @@ -285,7 +285,7 @@ protected function mapProperty(string $key) * * @return \CodeIgniter\I18n\Time */ - private function mutateDate($value) + protected function mutateDate($value) { if ($value instanceof Time) { @@ -320,7 +320,7 @@ private function mutateDate($value) * * @return mixed */ - private function castAs($value, string $type) + protected function castAs($value, string $type) { switch($type) { diff --git a/system/HTTP/Request.php b/system/HTTP/Request.php index 6b1d6f3d5842..2c3b9c4947fa 100644 --- a/system/HTTP/Request.php +++ b/system/HTTP/Request.php @@ -322,24 +322,26 @@ protected function fetchGlobal($type, $index = null, $filter = null, $flags = nu $filter = FILTER_DEFAULT; } + $loopThrough = []; + switch ($type) + { + case INPUT_GET : $loopThrough = $_GET; + break; + case INPUT_POST : $loopThrough = $_POST; + break; + case INPUT_COOKIE : $loopThrough = $_COOKIE; + break; + case INPUT_SERVER : $loopThrough = $_SERVER; + break; + case INPUT_ENV : $loopThrough = $_ENV; + break; + case INPUT_REQUEST : $loopThrough = $_REQUEST; + break; + } + // If $index is null, it means that the whole input type array is requested if (is_null($index)) { - $loopThrough = []; - switch ($type) - { - case INPUT_GET : $loopThrough = $_GET; - break; - case INPUT_POST : $loopThrough = $_POST; - break; - case INPUT_COOKIE : $loopThrough = $_COOKIE; - break; - case INPUT_SERVER : $loopThrough = $_SERVER; - break; - case INPUT_ENV : $loopThrough = $_ENV; - break; - } - $values = []; foreach ($loopThrough as $key => $value) { @@ -361,57 +363,37 @@ protected function fetchGlobal($type, $index = null, $filter = null, $flags = nu return $output; } -// -// // Does the index contain array notation? -// if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation -// { -// $value = $array; -// for ($i = 0; $i < $count; $i++) -// { -// $key = trim($matches[0][$i], '[]'); -// if ($key === '') // Empty notation will return the value as array -// { -// break; -// } -// -// if (isset($value[$key])) -// { -// $value = $value[$key]; -// } -// else -// { -// return NULL; -// } -// } -// } + + // Does the index contain array notation? + if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) + { + $value = $loopThrough; + for ($i = 0; $i < $count; $i++) + { + $key = trim($matches[0][$i], '[]'); + + if ($key === '') // Empty notation will return the value as array + { + break; + } + + if (isset($value[$key])) + { + $value = $value[$key]; + } + else + { + return null; + } + } + } + // Due to issues with FastCGI and testing, // we need to do these all manually instead // of the simpler filter_input(); - switch ($type) + if (empty($value)) { - case INPUT_GET: - $value = $_GET[$index] ?? null; - break; - case INPUT_POST: - $value = $_POST[$index] ?? null; - break; - case INPUT_SERVER: - $value = $_SERVER[$index] ?? null; - break; - case INPUT_ENV: - $value = $_ENV[$index] ?? null; - break; - case INPUT_COOKIE: - $value = $_COOKIE[$index] ?? null; - break; - case INPUT_REQUEST: - $value = $_REQUEST[$index] ?? null; - break; - case INPUT_SESSION: - $value = $_SESSION[$index] ?? null; - break; - default: - $value = ''; + $value = $loopThrough[$index] ?? null; } if (is_array($value) || is_object($value) || is_null($value)) diff --git a/system/Model.php b/system/Model.php index 831abc0df1d0..c28966d083c0 100644 --- a/system/Model.php +++ b/system/Model.php @@ -1321,6 +1321,7 @@ protected function trigger(string $event, array $data) } //-------------------------------------------------------------------- + //-------------------------------------------------------------------- // Magic //-------------------------------------------------------------------- diff --git a/tests/system/HTTP/IncomingRequestTest.php b/tests/system/HTTP/IncomingRequestTest.php index 92a27fc3d77e..ff8622d5239d 100644 --- a/tests/system/HTTP/IncomingRequestTest.php +++ b/tests/system/HTTP/IncomingRequestTest.php @@ -121,7 +121,66 @@ public function testFetchGlobalReturnsSingleValue() //-------------------------------------------------------------------- - /** + public function testFetchGlobalWithArrayTop() + { + $_POST = [ + 'clients' => [ + 'address' => [ + 'zipcode' => 90210 + ] + ] + ]; + + $this->assertEquals(['address' => ['zipcode' => 90210]], $this->request->getPost('clients')); + } + + public function testFetchGlobalWithArrayChildNumeric() + { + $_POST = [ + 'clients' => [ + [ + 'address' => [ + 'zipcode' => 90210 + ], + ], + [ + 'address' => [ + 'zipcode' => 60610 + ], + ], + ] + ]; + + $this->assertEquals(['zipcode' => 60610], $this->request->getPost('clients[1][address]')); + } + + public function testFetchGlobalWithArrayChildElement() + { + $_POST = [ + 'clients' => [ + 'address' => [ + 'zipcode' => 90210 + ], + ] + ]; + + $this->assertEquals(['zipcode' => 90210], $this->request->getPost('clients[address]')); + } + + public function testFetchGlobalWithArrayLastElement() + { + $_POST = [ + 'clients' => [ + 'address' => [ + 'zipcode' => 90210 + ] + ] + ]; + + $this->assertEquals(90210, $this->request->getPost('clients[address][zipcode]')); + } + + /** * @see https://github.com/bcit-ci/CodeIgniter4/issues/353 */ public function testGetPostReturnsArrayValues()