Skip to content

Commit ddf1af1

Browse files
authored
Merge pull request #6943 from michalsn/feature/getRawInputVar
feat: add IncomingRequest::getRawInputVar() method
2 parents 569b636 + d1bcbd8 commit ddf1af1

5 files changed

Lines changed: 187 additions & 1 deletion

File tree

system/HTTP/IncomingRequest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,60 @@ public function getRawInput()
609609
return $output;
610610
}
611611

612+
/**
613+
* Gets a specific variable from raw input stream (send method in PUT, PATCH, DELETE).
614+
*
615+
* @param array|string|null $index The variable that you want which can use dot syntax for getting specific values.
616+
* @param int|null $filter Filter Constant
617+
* @param array|int|null $flags Option
618+
*
619+
* @return mixed
620+
*/
621+
public function getRawInputVar($index = null, ?int $filter = null, $flags = null)
622+
{
623+
helper('array');
624+
625+
parse_str($this->body ?? '', $output);
626+
627+
if (is_string($index)) {
628+
$output = dot_array_search($index, $output);
629+
} elseif (is_array($index)) {
630+
$data = [];
631+
632+
foreach ($index as $key) {
633+
$data[$key] = dot_array_search($key, $output);
634+
}
635+
636+
[$output, $data] = [$data, null];
637+
}
638+
639+
$filter ??= FILTER_DEFAULT;
640+
$flags = is_array($flags) ? $flags : (is_numeric($flags) ? (int) $flags : 0);
641+
642+
if (is_array($output)
643+
&& (
644+
$filter !== FILTER_DEFAULT
645+
|| (
646+
(is_numeric($flags) && $flags !== 0)
647+
|| is_array($flags) && $flags !== []
648+
)
649+
)
650+
) {
651+
// Iterate over array and append filter and flags
652+
array_walk_recursive($output, static function (&$val) use ($filter, $flags) {
653+
$val = filter_var($val, $filter, $flags);
654+
});
655+
656+
return $output;
657+
}
658+
659+
if (is_string($output)) {
660+
return filter_var($output, $filter, $flags);
661+
}
662+
663+
return $output;
664+
}
665+
612666
/**
613667
* Fetch an item from GET data.
614668
*

tests/system/HTTP/IncomingRequestTest.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,104 @@ public function testCanGrabGetRawInput()
442442
$this->assertSame($expected, $request->getRawInput());
443443
}
444444

445+
public function provideRawInputVarChecks()
446+
{
447+
return [
448+
[
449+
'username=admin001&role=administrator&usepass=0',
450+
'username',
451+
'admin001',
452+
null,
453+
null,
454+
],
455+
[
456+
'username=admin001&role=administrator&usepass=0',
457+
['role', 'usepass'],
458+
[
459+
'role' => 'administrator',
460+
'usepass' => '0',
461+
],
462+
null,
463+
null,
464+
],
465+
[
466+
'username=admin001&role=administrator&usepass=0',
467+
'not_exists',
468+
null,
469+
null,
470+
null,
471+
],
472+
[
473+
'username=admin001&role=administrator&usepass=0',
474+
null,
475+
[
476+
'username' => 'admin001',
477+
'role' => 'administrator',
478+
'usepass' => '0',
479+
],
480+
null,
481+
null,
482+
],
483+
[
484+
'',
485+
null,
486+
[],
487+
null,
488+
null,
489+
],
490+
[
491+
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two',
492+
['username', 'foo'],
493+
[
494+
'username' => 'admin001',
495+
'foo' => ['one', 'two'],
496+
],
497+
null,
498+
null,
499+
],
500+
[
501+
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two',
502+
'foo.0',
503+
'one',
504+
null,
505+
null,
506+
],
507+
[
508+
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two&bar[baz]=hello',
509+
'bar.baz',
510+
'hello',
511+
null,
512+
null,
513+
],
514+
[
515+
'username=admin001&role=administrator&usepass=0&foo[]=one&foo[]=two&bar[baz]=hello6.5world',
516+
'bar.baz',
517+
'6.5',
518+
FILTER_SANITIZE_NUMBER_FLOAT,
519+
FILTER_FLAG_ALLOW_FRACTION,
520+
],
521+
];
522+
}
523+
524+
/**
525+
* @dataProvider provideRawInputVarChecks
526+
*
527+
* @param string $rawstring
528+
* @param mixed $var
529+
* @param mixed $expected
530+
* @param mixed $filter
531+
* @param mixed $flag
532+
*/
533+
public function testCanGrabGetRawInputVar($rawstring, $var, $expected, $filter, $flag)
534+
{
535+
$config = new App();
536+
$config->baseURL = 'http://example.com/';
537+
538+
$request = new IncomingRequest($config, new URI(), $rawstring, new UserAgent());
539+
540+
$this->assertSame($expected, $request->getRawInputVar($var, $filter, $flag));
541+
}
542+
445543
public function testIsCLI()
446544
{
447545
$this->assertFalse($this->request->isCLI());

user_guide_src/source/changelogs/v4.3.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ Others
307307
- **View:** Added ``Controlled Cells`` that provide more structure and flexibility to your View Cells. See :ref:`View Cells <controlled-cells>` for details.
308308
- **Config:** Now you can specify Composer packages to auto-discover manually. See :ref:`Code Modules <modules-specify-composer-packages>`.
309309
- **Debug:** Kint has been updated to 5.0.1.
310+
- **Request:** Added new ``$request->getRawInputVar()`` method to return a specified variable from raw stream. See :ref:`Retrieving Raw data <incomingrequest-retrieving-raw-data>`.
310311

311312
Message Changes
312313
***************

user_guide_src/source/incoming/incomingrequest.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ This will retrieve data and convert it to an array. Like this:
155155

156156
.. literalinclude:: incomingrequest/013.php
157157

158+
You can also use ``getRawInputVar()``, to get the specified variable from raw stream and filter it.
159+
160+
.. literalinclude:: incomingrequest/039.php
161+
158162
Filtering Input Data
159163
====================
160164

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

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

173177
Retrieving Headers
174178
******************
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
// When the request body is 'foo=one&bar=two&baz[]=10&baz[]=20'
4+
var_dump($request->getRawInputVar('bar'));
5+
// Outputs: two
6+
7+
// foo=one&bar=two&baz[]=10&baz[]=20
8+
var_dump($request->getRawInputVar(['foo', 'bar']));
9+
/*
10+
* Outputs:
11+
* [
12+
* 'foo' => 'one',
13+
* 'bar' => 'two'
14+
* ]
15+
*/
16+
17+
// foo=one&bar=two&baz[]=10&baz[]=20
18+
var_dump($request->getRawInputVar('baz'));
19+
/*
20+
* Outputs:
21+
* [
22+
* '10',
23+
* '20'
24+
* ]
25+
*/
26+
27+
// foo=one&bar=two&baz[]=10&baz[]=20
28+
var_dump($request->getRawInputVar('baz.0'));
29+
// Outputs: 10

0 commit comments

Comments
 (0)