Skip to content

Commit

Permalink
Merge pull request #6943 from michalsn/feature/getRawInputVar
Browse files Browse the repository at this point in the history
feat: add IncomingRequest::getRawInputVar() method
  • Loading branch information
kenjis authored Dec 11, 2022
2 parents 569b636 + d1bcbd8 commit ddf1af1
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 1 deletion.
54 changes: 54 additions & 0 deletions system/HTTP/IncomingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,60 @@ public function getRawInput()
return $output;
}

/**
* Gets a specific variable from raw input stream (send method in PUT, PATCH, DELETE).
*
* @param array|string|null $index The variable that you want which can use dot syntax for getting specific values.
* @param int|null $filter Filter Constant
* @param array|int|null $flags Option
*
* @return mixed
*/
public function getRawInputVar($index = null, ?int $filter = null, $flags = null)
{
helper('array');

parse_str($this->body ?? '', $output);

if (is_string($index)) {
$output = dot_array_search($index, $output);
} elseif (is_array($index)) {
$data = [];

foreach ($index as $key) {
$data[$key] = dot_array_search($key, $output);
}

[$output, $data] = [$data, null];
}

$filter ??= FILTER_DEFAULT;
$flags = is_array($flags) ? $flags : (is_numeric($flags) ? (int) $flags : 0);

if (is_array($output)
&& (
$filter !== FILTER_DEFAULT
|| (
(is_numeric($flags) && $flags !== 0)
|| is_array($flags) && $flags !== []
)
)
) {
// Iterate over array and append filter and flags
array_walk_recursive($output, static function (&$val) use ($filter, $flags) {
$val = filter_var($val, $filter, $flags);
});

return $output;
}

if (is_string($output)) {
return filter_var($output, $filter, $flags);
}

return $output;
}

/**
* Fetch an item from GET data.
*
Expand Down
98 changes: 98 additions & 0 deletions tests/system/HTTP/IncomingRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,104 @@ public function testCanGrabGetRawInput()
$this->assertSame($expected, $request->getRawInput());
}

public function provideRawInputVarChecks()
{
return [
[
'username=admin001&role=administrator&usepass=0',
'username',
'admin001',
null,
null,
],
[
'username=admin001&role=administrator&usepass=0',
['role', 'usepass'],
[
'role' => 'administrator',
'usepass' => '0',
],
null,
null,
],
[
'username=admin001&role=administrator&usepass=0',
'not_exists',
null,
null,
null,
],
[
'username=admin001&role=administrator&usepass=0',
null,
[
'username' => 'admin001',
'role' => 'administrator',
'usepass' => '0',
],
null,
null,
],
[
'',
null,
[],
null,
null,
],
[
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two',
['username', 'foo'],
[
'username' => 'admin001',
'foo' => ['one', 'two'],
],
null,
null,
],
[
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two',
'foo.0',
'one',
null,
null,
],
[
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two&bar[baz]=hello',
'bar.baz',
'hello',
null,
null,
],
[
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two&bar[baz]=hello6.5world',
'bar.baz',
'6.5',
FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_FRACTION,
],
];
}

/**
* @dataProvider provideRawInputVarChecks
*
* @param string $rawstring
* @param mixed $var
* @param mixed $expected
* @param mixed $filter
* @param mixed $flag
*/
public function testCanGrabGetRawInputVar($rawstring, $var, $expected, $filter, $flag)
{
$config = new App();
$config->baseURL = 'http://example.com/';

$request = new IncomingRequest($config, new URI(), $rawstring, new UserAgent());

$this->assertSame($expected, $request->getRawInputVar($var, $filter, $flag));
}

public function testIsCLI()
{
$this->assertFalse($this->request->isCLI());
Expand Down
1 change: 1 addition & 0 deletions user_guide_src/source/changelogs/v4.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ Others
- **View:** Added ``Controlled Cells`` that provide more structure and flexibility to your View Cells. See :ref:`View Cells <controlled-cells>` for details.
- **Config:** Now you can specify Composer packages to auto-discover manually. See :ref:`Code Modules <modules-specify-composer-packages>`.
- **Debug:** Kint has been updated to 5.0.1.
- **Request:** Added new ``$request->getRawInputVar()`` method to return a specified variable from raw stream. See :ref:`Retrieving Raw data <incomingrequest-retrieving-raw-data>`.

Message Changes
***************
Expand Down
6 changes: 5 additions & 1 deletion user_guide_src/source/incoming/incomingrequest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ This will retrieve data and convert it to an array. Like this:

.. literalinclude:: incomingrequest/013.php

You can also use ``getRawInputVar()``, to get the specified variable from raw stream and filter it.

.. literalinclude:: incomingrequest/039.php

Filtering Input Data
====================

Expand All @@ -168,7 +172,7 @@ Filtering a POST variable would look like this:
.. literalinclude:: incomingrequest/014.php

All of the methods mentioned above support the filter type passed in as the second parameter, with the
exception of ``getJSON()``.
exception of ``getJSON()`` and ``getRawInput()``.

Retrieving Headers
******************
Expand Down
29 changes: 29 additions & 0 deletions user_guide_src/source/incoming/incomingrequest/039.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

// When the request body is 'foo=one&bar=two&baz[]=10&baz[]=20'
var_dump($request->getRawInputVar('bar'));
// Outputs: two

// foo=one&bar=two&baz[]=10&baz[]=20
var_dump($request->getRawInputVar(['foo', 'bar']));
/*
* Outputs:
* [
* 'foo' => 'one',
* 'bar' => 'two'
* ]
*/

// foo=one&bar=two&baz[]=10&baz[]=20
var_dump($request->getRawInputVar('baz'));
/*
* Outputs:
* [
* '10',
* '20'
* ]
*/

// foo=one&bar=two&baz[]=10&baz[]=20
var_dump($request->getRawInputVar('baz.0'));
// Outputs: 10

0 comments on commit ddf1af1

Please sign in to comment.