From 464439d195fc895079176498cb28d182dc8aef14 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 7 Sep 2013 23:03:36 +0200 Subject: [PATCH] [HttpFoundation] added a way to override the Request class --- .../Component/HttpFoundation/Request.php | 35 +++++++++++++++++-- .../HttpFoundation/Tests/RequestTest.php | 19 +++++++++- .../Fragment/InlineFragmentRenderer.php | 2 +- .../HttpKernel/HttpCache/HttpCache.php | 2 +- .../Component/Security/Http/HttpUtils.php | 2 +- 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index a1659c4fa5..0d79a07fa1 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -187,6 +187,8 @@ class Request */ protected static $formats; + protected static $requestFactory; + /** * Constructor. * @@ -252,7 +254,7 @@ class Request */ public static function createFromGlobals() { - $request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER); + $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER); if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH')) @@ -361,7 +363,21 @@ class Request $server['REQUEST_URI'] = $components['path'].('' !== $queryString ? '?'.$queryString : ''); $server['QUERY_STRING'] = $queryString; - return new static($query, $request, array(), $cookies, $files, $server, $content); + return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content); + } + + /** + * Sets a callable able to create a Request instance. + * + * This is mainly useful when you need to override the Request class + * to keep BC with an existing system. It should not be used for any + * other purpose. + * + * @param callable $callable A PHP callable + */ + public static function setFactory($callable) + { + self::$requestFactory = $callable; } /** @@ -1786,4 +1802,19 @@ class Request return false; } + + private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) + { + if (self::$requestFactory) { + $request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content); + + if (!$request instanceof Request) { + throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.'); + } + + return $request; + } + + return new static($query, $request, $attributes, $cookies, $files, $server, $content); + } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 357176100b..95b04d409e 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1465,7 +1465,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct'); $subRequestUri = '/bar/foo'; - $subRequest = $request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all()); + $subRequest = Request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all()); $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request'); } @@ -1572,6 +1572,15 @@ class RequestTest extends \PHPUnit_Framework_TestCase // reset request for following tests Request::setTrustedHosts(array()); } + + public function testFactory() + { + Request::setFactory(function (array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { + return new NewRequest(); + }); + + $this->assertEquals('foo', Request::create('/')->getFoo()); + } } class RequestContentProxy extends Request @@ -1581,3 +1590,11 @@ class RequestContentProxy extends Request return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent')); } } + +class NewRequest extends Request +{ + public function getFoo() + { + return 'foo'; + } +} diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index 7d6a2f5c75..c6ca3d475e 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -132,7 +132,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer $server['REMOTE_ADDR'] = '127.0.0.1'; - $subRequest = $request::create($uri, 'get', array(), $cookies, array(), $server); + $subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server); if ($request->headers->has('Surrogate-Capability')) { $subRequest->headers->set('Surrogate-Capability', $request->headers->get('Surrogate-Capability')); } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 63cde7e5b2..76691a542c 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -268,7 +268,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface // As per the RFC, invalidate Location and Content-Location URLs if present foreach (array('Location', 'Content-Location') as $header) { if ($uri = $response->headers->get($header)) { - $subRequest = $request::create($uri, 'get', array(), array(), array(), $request->server->all()); + $subRequest = Request::create($uri, 'get', array(), array(), array(), $request->server->all()); $this->store->invalidate($subRequest); } diff --git a/src/Symfony/Component/Security/Http/HttpUtils.php b/src/Symfony/Component/Security/Http/HttpUtils.php index 0453520a58..b5e828008f 100644 --- a/src/Symfony/Component/Security/Http/HttpUtils.php +++ b/src/Symfony/Component/Security/Http/HttpUtils.php @@ -70,7 +70,7 @@ class HttpUtils */ public function createRequest(Request $request, $path) { - $newRequest = $request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all()); + $newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all()); if ($request->hasSession()) { $newRequest->setSession($request->getSession()); }