Skip to content

Commit addc51f

Browse files
committed
feat: add IncomingRequest::getRawInputVar() method to work with raw stream data
1 parent e2c4a3b commit addc51f

5 files changed

Lines changed: 191 additions & 1 deletion

File tree

system/HTTP/IncomingRequest.php

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

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

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
@@ -295,6 +295,7 @@ Others
295295
- **View:** Added ``Controlled Cells`` that provide more structure and flexibility to your View Cells. See :ref:`View Cells <controlled-cells>` for details.
296296
- **Config:** Now you can specify Composer packages to auto-discover manually. See :ref:`Code Modules <modules-specify-composer-packages>`.
297297
- **Debug:** Kint has been updated to 5.0.1.
298+
- **Request:** Added new ``$request->getRawInputVar()`` method to return a specified variable from raw stream. See :ref:`Retrieving Raw data <incomingrequest-retrieving-raw-data>`.
298299

299300
Message Changes
300301
***************

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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
// foo=one&bar=two&baz[]=10&baz[]=20
4+
var_dump($request->getRawInputVar('bar'));
5+
6+
// Outputs: two
7+
8+
// foo=one&bar=two&baz[]=10&baz[]=20
9+
var_dump($request->getRawInputVar(['foo', 'bar']));
10+
11+
/*
12+
* Outputs:
13+
* [
14+
* 'foo' => 'one',
15+
* 'bar' => 'two'
16+
* ]
17+
*/
18+
19+
// foo=one&bar=two&baz[]=10&baz[]=20
20+
var_dump($request->getRawInputVar('baz'));
21+
22+
/*
23+
* Outputs:
24+
* [
25+
* 10,
26+
* 20
27+
* ]
28+
*/
29+
30+
// foo=one&bar=two&baz[]=10&baz[]=20
31+
var_dump($request->getRawInputVar('baz.0'));
32+
33+
// Outputs: 10

0 commit comments

Comments
 (0)