From 187f91c30a125157379fce5ba826af718617920e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Simon?= Date: Sat, 23 Mar 2013 17:46:56 +0100 Subject: [PATCH 1/2] added request factory Squashed commits: [Httpernel] added request factory [FrameworkBundle] added request_factory service moved request factory in HttpFoundation component [HttpFoundation] added request factory class check --- src/Symfony/Bundle/FrameworkBundle/Client.php | 5 +- .../DependencyInjection/Configuration.php | 7 +++ .../FrameworkExtension.php | 2 +- .../FrameworkBundle/HttpCache/HttpCache.php | 10 ++-- .../Resources/config/services.xml | 5 ++ .../FrameworkBundle/Resources/config/test.xml | 1 + .../DependencyInjection/ConfigurationTest.php | 1 + .../HttpFoundation/Factory/RequestFactory.php | 53 +++++++++++++++++++ .../Factory/RequestFactoryInterface.php | 35 ++++++++++++ src/Symfony/Component/HttpKernel/Client.php | 17 +++--- .../Component/HttpKernel/HttpCache/Esi.php | 13 +++-- .../Component/HttpKernel/HttpCache/Store.php | 11 ++-- .../Tests/Request/RequestFactoryTest.php | 28 ++++++++++ 13 files changed, 169 insertions(+), 19 deletions(-) create mode 100644 src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php create mode 100644 src/Symfony/Component/HttpFoundation/Factory/RequestFactoryInterface.php create mode 100644 src/Symfony/Component/HttpKernel/Tests/Request/RequestFactoryTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index 181964976903..c3e61293b21a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -19,6 +19,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; /** * Client simulates a browser and makes requests to a Kernel object. @@ -33,9 +34,9 @@ class Client extends BaseClient /** * @inheritdoc */ - public function __construct(KernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null) + public function __construct(KernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null, RequestFactoryInterface $requestFactory = null) { - parent::__construct($kernel, $server, $history, $cookieJar); + parent::__construct($kernel, $server, $history, $cookieJar, $requestFactory); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 32df4ba2ee8a..98bf08a49c1c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -39,6 +39,13 @@ public function getConfigTreeBuilder() ->info("Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests.") ->defaultTrue() ->end() + ->scalarNode('request_class') + ->defaultValue('Symfony\Component\HttpFoundation\Request') + ->validate() + ->ifTrue(function ($v) { return !class_exists($v); }) + ->thenInvalid('Request class "%s" does not exist') + ->end() + ->end() ->arrayNode('trusted_proxies') ->beforeNormalization() ->ifTrue(function($v) { return !is_array($v) && !is_null($v); }) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 4466b260ff5a..b022e4a8b70c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -69,7 +69,7 @@ public function load(array $configs, ContainerBuilder $container) } $container->setParameter('kernel.http_method_override', $config['http_method_override']); - + $container->setParameter('kernel.request_class', $config['request_class']); $container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']); $container->setParameter('kernel.default_locale', $config['default_locale']); diff --git a/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php b/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php index f07c994a5d71..960ff1bbb1fc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php +++ b/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php @@ -17,6 +17,7 @@ use Symfony\Component\HttpKernel\HttpCache\Store; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; /** * Manages HTTP cache objects in a Container. @@ -32,7 +33,7 @@ abstract class HttpCache extends BaseHttpCache * Constructor. * * @param HttpKernelInterface $kernel An HttpKernelInterface instance - * @param string $cacheDir The cache directory (default used if null) + * @param string|null $cacheDir The cache directory (default used if null) */ public function __construct(HttpKernelInterface $kernel, $cacheDir = null) { @@ -72,11 +73,14 @@ protected function getOptions() protected function createEsi() { - return new Esi(); + return new Esi($this->getKernel()->getContainer()->get('request_factory')); } protected function createStore() { - return new Store($this->cacheDir ?: $this->kernel->getCacheDir().'/http_cache'); + return new Store( + $this->cacheDir ?: $this->kernel->getCacheDir().'/http_cache', + $this->getKernel()->getContainer()->get('request_factory') + ); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml index 674e28f1c98a..ea6a46882c78 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -10,6 +10,7 @@ Symfony\Component\Filesystem\Filesystem Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer + Symfony\Component\HttpFoundation\Factory\RequestFactory Symfony\Component\HttpKernel\Config\FileLocator Symfony\Component\HttpKernel\UriSigner @@ -42,6 +43,10 @@ --> + + %kernel.request_class% + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml index 4e609a06e5d9..816f82198c12 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml @@ -18,6 +18,7 @@ %test.client.parameters% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 9c9aa83b9a57..a4c6c491eb88 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -90,6 +90,7 @@ protected static function getBundleDefaultConfig() { return array( 'http_method_override' => true, + 'request_class' => 'Symfony\Component\HttpFoundation\Request', 'trusted_proxies' => array(), 'ide' => null, 'default_locale' => 'en', diff --git a/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php b/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php new file mode 100644 index 000000000000..f0997f596f46 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Factory; + +use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; + +/** + * @author Jean-François Simon + */ +class RequestFactory implements RequestFactoryInterface +{ + const REQUEST_CLASS = 'Symfony\Component\HttpFoundation\Request'; + + /** + * @var string + */ + private $class; + + /** + * Constructor. + * + * @param string $class + * + * @throws \InvalidArgumentException + */ + public function __construct($class = self::REQUEST_CLASS) + { + if ($class !== self::REQUEST_CLASS && !is_subclass_of($class, self::REQUEST_CLASS)) { + throw new \InvalidArgumentException(sprintf('Request class "%s" must extend "%s" class.', $class, self::REQUEST_CLASS)); + } + + $this->class = $class; + } + + /** + * {@inheritdoc} + */ + public function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null) + { + $callable = $this->class.'::create'; + + return call_user_func($callable, $uri, $method, $parameters, $cookies, $files, $server, $content); + } +} diff --git a/src/Symfony/Component/HttpFoundation/Factory/RequestFactoryInterface.php b/src/Symfony/Component/HttpFoundation/Factory/RequestFactoryInterface.php new file mode 100644 index 000000000000..dbd074bf0f02 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Factory/RequestFactoryInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Factory; + +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Jean-François Simon + */ +interface RequestFactoryInterface +{ + /** + * Creates a Request based on a given URI and configuration. + * + * @param string $uri The URI + * @param string $method The HTTP method + * @param array $parameters The query (GET) or request (POST) parameters + * @param array $cookies The request cookies ($_COOKIE) + * @param array $files The request files ($_FILES) + * @param array $server The server parameters ($_SERVER) + * @param string $content The raw body data + * + * @return Request + */ + public function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null); +} diff --git a/src/Symfony/Component/HttpKernel/Client.php b/src/Symfony/Component/HttpKernel/Client.php index bb427b35af22..d453de8c39d5 100644 --- a/src/Symfony/Component/HttpKernel/Client.php +++ b/src/Symfony/Component/HttpKernel/Client.php @@ -20,6 +20,8 @@ use Symfony\Component\BrowserKit\Cookie as DomCookie; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\HttpFoundation\Factory\RequestFactory; +use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; use Symfony\Component\HttpKernel\TerminableInterface; /** @@ -32,18 +34,21 @@ class Client extends BaseClient { protected $kernel; + private $requestFactory; /** * Constructor. * - * @param HttpKernelInterface $kernel An HttpKernel instance - * @param array $server The server parameters (equivalent of $_SERVER) - * @param History $history A History instance to store the browser history - * @param CookieJar $cookieJar A CookieJar instance to store the cookies + * @param HttpKernelInterface $kernel An HttpKernel instance + * @param array $server The server parameters (equivalent of $_SERVER) + * @param History $history A History instance to store the browser history + * @param CookieJar $cookieJar A CookieJar instance to store the cookies + * @param RequestFactoryInterface|null $requestFactory The class used to create a request (must extend 'Symfony\Component\HttpFoundation\Request') */ - public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null) + public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null, RequestFactoryInterface $requestFactory = null) { $this->kernel = $kernel; + $this->requestFactory = $requestFactory ?: new RequestFactory(); parent::__construct($server, $history, $cookieJar); @@ -127,7 +132,7 @@ protected function getScript($request) */ protected function filterRequest(DomRequest $request) { - $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent()); + $httpRequest = $this->requestFactory->create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent()); $httpRequest->files->replace($this->filterFiles($httpRequest->files->all())); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php index 455b3dcce968..6253f1987cc3 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php @@ -14,6 +14,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Factory\RequestFactory; +use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; /** * Esi implements the ESI capabilities to Request and Response instances. @@ -29,16 +31,19 @@ class Esi { private $contentTypes; + private $requestFactory; /** * Constructor. * - * @param array $contentTypes An array of content-type that should be parsed for ESI information. - * (default: text/html, text/xml, application/xhtml+xml, and application/xml) + * @param array $contentTypes An array of content-type that should be parsed for ESI information. + * (default: text/html, text/xml, application/xhtml+xml, and application/xml) + * @param \Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface|null $requestFactory */ - public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml')) + public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'), RequestFactoryInterface $requestFactory = null) { $this->contentTypes = $contentTypes; + $this->requestFactory = $requestFactory ?: new RequestFactory(); } /** @@ -194,7 +199,7 @@ public function process(Request $request, Response $response) */ public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) { - $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); + $subRequest = $this->requestFactory->create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); try { $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Store.php b/src/Symfony/Component/HttpKernel/HttpCache/Store.php index a1cda1fd2709..14a99d7f06b0 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Store.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Store.php @@ -16,6 +16,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Factory\RequestFactory; +use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; /** * Store implements all the logic for storing cache metadata (Request and Response headers). @@ -27,18 +29,21 @@ class Store implements StoreInterface protected $root; private $keyCache; private $locks; + private $requestFactory; /** * Constructor. * - * @param string $root The path to the cache directory + * @param string $root The path to the cache directory + * @param RequestFactoryInterface|null $requestFactory */ - public function __construct($root) + public function __construct($root, RequestFactoryInterface $requestFactory = null) { $this->root = $root; if (!is_dir($this->root)) { mkdir($this->root, 0777, true); } + $this->requestFactory = $requestFactory ?: new RequestFactory(); $this->keyCache = new \SplObjectStorage(); $this->locks = array(); } @@ -303,7 +308,7 @@ private function getMetadata($key) */ public function purge($url) { - if (is_file($path = $this->getPath($this->getCacheKey(Request::create($url))))) { + if (is_file($path = $this->getPath($this->getCacheKey($this->requestFactory->create($url))))) { unlink($path); return true; diff --git a/src/Symfony/Component/HttpKernel/Tests/Request/RequestFactoryTest.php b/src/Symfony/Component/HttpKernel/Tests/Request/RequestFactoryTest.php new file mode 100644 index 000000000000..341c008a6ed8 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Tests/Request/RequestFactoryTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Tests\Request; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Factory\RequestFactory; + +class RequestFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testCreateRequest() + { + $factory = new RequestFactory(); + + $this->assertEquals( + Request::create('uri', 'method', array('parameter' => 'value'), array('cookie' => 'value'), array(), array('server' => 'value'), 'content'), + $factory->create('uri', 'method', array('parameter' => 'value'), array('cookie' => 'value'), array(), array('server' => 'value'), 'content') + ); + } +} From d805ca8bc0a89a191888affde589a9e50393a5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Simon?= Date: Wed, 10 Jul 2013 07:26:55 +0200 Subject: [PATCH 2/2] removed unuseful kernel.request_class parameter --- .../DependencyInjection/Configuration.php | 7 ----- .../FrameworkExtension.php | 1 - .../Resources/config/services.xml | 4 +-- .../DependencyInjection/ConfigurationTest.php | 1 - .../HttpFoundation/Factory/RequestFactory.php | 28 ++----------------- 5 files changed, 3 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 98bf08a49c1c..32df4ba2ee8a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -39,13 +39,6 @@ public function getConfigTreeBuilder() ->info("Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests.") ->defaultTrue() ->end() - ->scalarNode('request_class') - ->defaultValue('Symfony\Component\HttpFoundation\Request') - ->validate() - ->ifTrue(function ($v) { return !class_exists($v); }) - ->thenInvalid('Request class "%s" does not exist') - ->end() - ->end() ->arrayNode('trusted_proxies') ->beforeNormalization() ->ifTrue(function($v) { return !is_array($v) && !is_null($v); }) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index b022e4a8b70c..463d2aa1df68 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -69,7 +69,6 @@ public function load(array $configs, ContainerBuilder $container) } $container->setParameter('kernel.http_method_override', $config['http_method_override']); - $container->setParameter('kernel.request_class', $config['request_class']); $container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']); $container->setParameter('kernel.default_locale', $config['default_locale']); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml index ea6a46882c78..fa477ba4e4f8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -43,9 +43,7 @@ --> - - %kernel.request_class% - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index a4c6c491eb88..9c9aa83b9a57 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -90,7 +90,6 @@ protected static function getBundleDefaultConfig() { return array( 'http_method_override' => true, - 'request_class' => 'Symfony\Component\HttpFoundation\Request', 'trusted_proxies' => array(), 'ide' => null, 'default_locale' => 'en', diff --git a/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php b/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php index f0997f596f46..17f96ae6b495 100644 --- a/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php +++ b/src/Symfony/Component/HttpFoundation/Factory/RequestFactory.php @@ -12,42 +12,18 @@ namespace Symfony\Component\HttpFoundation\Factory; use Symfony\Component\HttpFoundation\Factory\RequestFactoryInterface; +use Symfony\Component\HttpFoundation\Request; /** * @author Jean-François Simon */ class RequestFactory implements RequestFactoryInterface { - const REQUEST_CLASS = 'Symfony\Component\HttpFoundation\Request'; - - /** - * @var string - */ - private $class; - - /** - * Constructor. - * - * @param string $class - * - * @throws \InvalidArgumentException - */ - public function __construct($class = self::REQUEST_CLASS) - { - if ($class !== self::REQUEST_CLASS && !is_subclass_of($class, self::REQUEST_CLASS)) { - throw new \InvalidArgumentException(sprintf('Request class "%s" must extend "%s" class.', $class, self::REQUEST_CLASS)); - } - - $this->class = $class; - } - /** * {@inheritdoc} */ public function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null) { - $callable = $this->class.'::create'; - - return call_user_func($callable, $uri, $method, $parameters, $cookies, $files, $server, $content); + return Request::create($uri, $method, $parameters, $cookies, $files, $server, $content); } }