[HttpFoundation] add InputBag
This commit is contained in:
parent
402909ff7b
commit
0a2ef70c04
@ -63,7 +63,7 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $request->query->get($name);
|
||||
$data = $request->query->all()[$name];
|
||||
}
|
||||
} else {
|
||||
// Mark the form with an error if the uploaded size was too large
|
||||
@ -87,7 +87,7 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
|
||||
$files = $request->files->all();
|
||||
} elseif ($request->request->has($name) || $request->files->has($name)) {
|
||||
$default = $form->getConfig()->getCompound() ? [] : null;
|
||||
$params = $request->request->get($name, $default);
|
||||
$params = $request->request->all()[$name] ?? $default;
|
||||
$files = $request->files->get($name, $default);
|
||||
} else {
|
||||
// Don't submit the form if it is not present in the request
|
||||
|
@ -16,6 +16,8 @@ CHANGELOG
|
||||
* added `MarshallingSessionHandler`, `IdentityMarshaller`
|
||||
* made `Session` accept a callback to report when the session is being used
|
||||
* Add support for all core cache control directives
|
||||
* Added `Symfony\Component\HttpFoundation\InputBag`
|
||||
* Deprecated retrieving non-string values using `InputBag::get()`, use `InputBag::all()` if you need access to the collection of values
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation\Exception;
|
||||
|
||||
/**
|
||||
* Raised when a user sends a malformed request.
|
||||
*/
|
||||
class BadRequestException extends \UnexpectedValueException implements RequestExceptionInterface
|
||||
{
|
||||
}
|
119
src/Symfony/Component/HttpFoundation/InputBag.php
Normal file
119
src/Symfony/Component/HttpFoundation/InputBag.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
|
||||
/**
|
||||
* InputBag is a container for user input values such as $_GET, $_POST, $_REQUEST, and $_COOKIE.
|
||||
*
|
||||
* @author Saif Eddin Gmati <saif.gmati@symfony.com>
|
||||
*/
|
||||
final class InputBag extends ParameterBag
|
||||
{
|
||||
/**
|
||||
* Returns a string input value by name.
|
||||
*
|
||||
* @param string|null $default The default value if the input key does not exist
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get(string $key, $default = null)
|
||||
{
|
||||
if (null !== $default && !is_scalar($default) && !method_exists($default, '__toString')) {
|
||||
trigger_deprecation('symfony/http-foundation', '5.1', 'Passing a non-string value as 2nd argument to "%s()" is deprecated, pass a string or null instead.', __METHOD__);
|
||||
}
|
||||
|
||||
$value = parent::get($key, $this);
|
||||
|
||||
if (null !== $value && $this !== $value && !is_scalar($value) && !method_exists($value, '__toString')) {
|
||||
trigger_deprecation('symfony/http-foundation', '5.1', 'Retrieving a non-string value from "%s()" is deprecated, and will throw a "%s" exception in Symfony 6.0, use "%s::all()" instead.', __METHOD__, BadRequestException::class, __CLASS__);
|
||||
}
|
||||
|
||||
return $this === $value ? $default : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inputs.
|
||||
*
|
||||
* @param string|null $key The name of the input to return or null to get them all
|
||||
*/
|
||||
public function all(string $key = null): array
|
||||
{
|
||||
if (null === $key) {
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
$value = $this->parameters[$key] ?? [];
|
||||
if (!\is_array($value)) {
|
||||
throw new BadRequestException(sprintf('Unexpected value for "%s" input, expecting "array", got "%s".', $key, get_debug_type($value)));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the current input values by a new set.
|
||||
*/
|
||||
public function replace(array $inputs = [])
|
||||
{
|
||||
$this->parameters = [];
|
||||
$this->add($inputs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds input values.
|
||||
*/
|
||||
public function add(array $inputs = [])
|
||||
{
|
||||
foreach ($inputs as $input => $value) {
|
||||
$this->set($input, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an input by name.
|
||||
*
|
||||
* @param string|array $value
|
||||
*/
|
||||
public function set(string $key, $value)
|
||||
{
|
||||
if (!is_scalar($value) && !method_exists($value, '__toString') && !\is_array($value)) {
|
||||
trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a string or an array instead.', get_debug_type($value), __METHOD__);
|
||||
}
|
||||
|
||||
$this->parameters[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function filter(string $key, $default = null, int $filter = FILTER_DEFAULT, $options = [])
|
||||
{
|
||||
$value = $this->has($key) ? $this->all()[$key] : $default;
|
||||
|
||||
// Always turn $options into an array - this allows filter_var option shortcuts.
|
||||
if (!\is_array($options) && $options) {
|
||||
$options = ['flags' => $options];
|
||||
}
|
||||
|
||||
if (\is_array($value) && !(($options['flags'] ?? 0) & (FILTER_REQUIRE_ARRAY | FILTER_FORCE_ARRAY))) {
|
||||
trigger_deprecation('symfony/http-foundation', '5.1', 'Filtering an array value with "%s()" without passing the FILTER_REQUIRE_ARRAY or FILTER_FORCE_ARRAY flag is deprecated', __METHOD__);
|
||||
|
||||
if (!isset($options['flags'])) {
|
||||
$options['flags'] = FILTER_REQUIRE_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
return filter_var($value, $filter, $options);
|
||||
}
|
||||
}
|
@ -84,14 +84,14 @@ class Request
|
||||
/**
|
||||
* Request body parameters ($_POST).
|
||||
*
|
||||
* @var ParameterBag
|
||||
* @var InputBag
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Query string parameters ($_GET).
|
||||
*
|
||||
* @var ParameterBag
|
||||
* @var InputBag
|
||||
*/
|
||||
public $query;
|
||||
|
||||
@ -112,7 +112,7 @@ class Request
|
||||
/**
|
||||
* Cookies ($_COOKIE).
|
||||
*
|
||||
* @var ParameterBag
|
||||
* @var InputBag
|
||||
*/
|
||||
public $cookies;
|
||||
|
||||
@ -267,10 +267,10 @@ class Request
|
||||
*/
|
||||
public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
|
||||
{
|
||||
$this->request = new ParameterBag($request);
|
||||
$this->query = new ParameterBag($query);
|
||||
$this->request = new InputBag($request);
|
||||
$this->query = new InputBag($query);
|
||||
$this->attributes = new ParameterBag($attributes);
|
||||
$this->cookies = new ParameterBag($cookies);
|
||||
$this->cookies = new InputBag($cookies);
|
||||
$this->files = new FileBag($files);
|
||||
$this->server = new ServerBag($server);
|
||||
$this->headers = new HeaderBag($this->server->getHeaders());
|
||||
@ -301,7 +301,7 @@ class Request
|
||||
&& \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'])
|
||||
) {
|
||||
parse_str($request->getContent(), $data);
|
||||
$request->request = new ParameterBag($data);
|
||||
$request->request = new InputBag($data);
|
||||
}
|
||||
|
||||
return $request;
|
||||
@ -443,16 +443,16 @@ class Request
|
||||
{
|
||||
$dup = clone $this;
|
||||
if (null !== $query) {
|
||||
$dup->query = new ParameterBag($query);
|
||||
$dup->query = new InputBag($query);
|
||||
}
|
||||
if (null !== $request) {
|
||||
$dup->request = new ParameterBag($request);
|
||||
$dup->request = new InputBag($request);
|
||||
}
|
||||
if (null !== $attributes) {
|
||||
$dup->attributes = new ParameterBag($attributes);
|
||||
}
|
||||
if (null !== $cookies) {
|
||||
$dup->cookies = new ParameterBag($cookies);
|
||||
$dup->cookies = new InputBag($cookies);
|
||||
}
|
||||
if (null !== $files) {
|
||||
$dup->files = new FileBag($files);
|
||||
@ -708,12 +708,12 @@ class Request
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($this !== $result = $this->query->get($key, $this)) {
|
||||
return $result;
|
||||
if ($this->query->has($key)) {
|
||||
return $this->query->all()[$key];
|
||||
}
|
||||
|
||||
if ($this !== $result = $this->request->get($key, $this)) {
|
||||
return $result;
|
||||
if ($this->request->has($key)) {
|
||||
return $this->request->all()[$key];
|
||||
}
|
||||
|
||||
return $default;
|
||||
@ -1564,8 +1564,8 @@ class Request
|
||||
|
||||
/**
|
||||
* Gets the preferred format for the response by inspecting, in the following order:
|
||||
* * the request format set using setRequestFormat
|
||||
* * the values of the Accept HTTP header
|
||||
* * the request format set using setRequestFormat;
|
||||
* * the values of the Accept HTTP header.
|
||||
*
|
||||
* Note that if you use this method, you should send the "Vary: Accept" header
|
||||
* in the response to prevent any issues with intermediary HTTP caches.
|
||||
|
103
src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
Normal file
103
src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\InputBag;
|
||||
|
||||
class InputBagTest extends TestCase
|
||||
{
|
||||
use ExpectDeprecationTrait;
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$bag = new InputBag(['foo' => 'bar', 'null' => null]);
|
||||
|
||||
$this->assertEquals('bar', $bag->get('foo'), '->get() gets the value of a parameter');
|
||||
$this->assertEquals('default', $bag->get('unknown', 'default'), '->get() returns second argument as default if a parameter is not defined');
|
||||
$this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set');
|
||||
}
|
||||
|
||||
public function testGetDoesNotUseDeepByDefault()
|
||||
{
|
||||
$bag = new InputBag(['foo' => ['bar' => 'moo']]);
|
||||
|
||||
$this->assertNull($bag->get('foo[bar]'));
|
||||
}
|
||||
|
||||
public function testAllWithInputKey()
|
||||
{
|
||||
$bag = new InputBag(['foo' => ['bar', 'baz'], 'null' => null]);
|
||||
|
||||
$this->assertEquals(['bar', 'baz'], $bag->all('foo'), '->all() gets the value of a parameter');
|
||||
$this->assertEquals([], $bag->all('unknown'), '->all() returns an empty array if a parameter is not defined');
|
||||
}
|
||||
|
||||
public function testAllThrowsForNonArrayValues()
|
||||
{
|
||||
$this->expectException(BadRequestException::class);
|
||||
$bag = new InputBag(['foo' => 'bar', 'null' => null]);
|
||||
$bag->all('foo');
|
||||
}
|
||||
|
||||
public function testFilterArray()
|
||||
{
|
||||
$bag = new InputBag([
|
||||
'foo' => ['12', '8'],
|
||||
]);
|
||||
|
||||
$result = $bag->filter('foo', null, \FILTER_VALIDATE_INT, \FILTER_FORCE_ARRAY);
|
||||
$this->assertSame([12, 8], $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testSetWithNonStringishOrArrayIsDeprecated()
|
||||
{
|
||||
$bag = new InputBag();
|
||||
$this->expectDeprecation('Since symfony/http-foundation 5.1: Passing "Symfony\Component\HttpFoundation\InputBag" as a 2nd Argument to "Symfony\Component\HttpFoundation\InputBag::set()" is deprecated, pass a string or an array instead.');
|
||||
$bag->set('foo', new InputBag());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGettingANonStringValueIsDeprecated()
|
||||
{
|
||||
$bag = new InputBag(['foo' => ['a', 'b']]);
|
||||
$this->expectDeprecation('Since symfony/http-foundation 5.1: Retrieving a non-string value from "Symfony\Component\HttpFoundation\InputBag::get()" is deprecated, and will throw a "Symfony\Component\HttpFoundation\Exception\BadRequestException" exception in Symfony 6.0, use "Symfony\Component\HttpFoundation\InputBag::all()" instead.');
|
||||
$bag->get('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetWithNonStringDefaultValueIsDeprecated()
|
||||
{
|
||||
$bag = new InputBag(['foo' => 'bar']);
|
||||
$this->expectDeprecation('Since symfony/http-foundation 5.1: Passing a non-string value as 2nd argument to "Symfony\Component\HttpFoundation\InputBag::get()" is deprecated, pass a string or null instead.');
|
||||
$bag->get('foo', ['a', 'b']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testFilterArrayWithoutArrayFlagIsDeprecated()
|
||||
{
|
||||
$bag = new InputBag(['foo' => ['bar', 'baz']]);
|
||||
$this->expectDeprecation('Since symfony/http-foundation 5.1: Filtering an array value with "Symfony\Component\HttpFoundation\InputBag::filter()" without passing the FILTER_REQUIRE_ARRAY or FILTER_FORCE_ARRAY flag is deprecated');
|
||||
$bag->filter('foo', \FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
@ -36,12 +36,12 @@ final class ParameterBagUtils
|
||||
public static function getParameterBagValue(ParameterBag $parameters, string $path)
|
||||
{
|
||||
if (false === $pos = strpos($path, '[')) {
|
||||
return $parameters->get($path);
|
||||
return $parameters->all()[$path] ?? null;
|
||||
}
|
||||
|
||||
$root = substr($path, 0, $pos);
|
||||
|
||||
if (null === $value = $parameters->get($root)) {
|
||||
if (null === $value = $parameters->all()[$root] ?? null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user