Skip to content

Commit 2f73f0f

Browse files
committed
[HttpKernel] Allow to inject PSR-7 ServerRequest in controllers.
1 parent a57ce90 commit 2f73f0f

File tree

3 files changed

+65
-15
lines changed

3 files changed

+65
-15
lines changed

src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\HttpKernel\Controller;
1313

1414
use Psr\Log\LoggerInterface;
15+
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
16+
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
1517
use Symfony\Component\HttpFoundation\Request;
1618

1719
/**
@@ -22,21 +24,27 @@
2224
* the controller method arguments.
2325
*
2426
* @author Fabien Potencier <fabien@symfony.com>
27+
* @author Kévin Dunglas <dunglas@gmail.com>
2528
*
2629
* @api
2730
*/
2831
class ControllerResolver implements ControllerResolverInterface
2932
{
3033
private $logger;
34+
private $httpMessageFactory;
3135

3236
/**
3337
* Constructor.
3438
*
3539
* @param LoggerInterface $logger A LoggerInterface instance
3640
*/
37-
public function __construct(LoggerInterface $logger = null)
41+
public function __construct(LoggerInterface $logger = null, HttpMessageFactoryInterface $httpMessageFactory = null)
3842
{
3943
$this->logger = $logger;
44+
45+
if (null === $httpMessageFactory && class_exists('Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory')) {
46+
$this->httpMessageFactory = new DiactorosFactory();
47+
}
4048
}
4149

4250
/**
@@ -112,21 +120,43 @@ protected function doGetArguments(Request $request, $controller, array $paramete
112120
foreach ($parameters as $param) {
113121
if (array_key_exists($param->name, $attributes)) {
114122
$arguments[] = $attributes[$param->name];
115-
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
116-
$arguments[] = $request;
117-
} elseif ($param->isDefaultValueAvailable()) {
118-
$arguments[] = $param->getDefaultValue();
119-
} else {
120-
if (is_array($controller)) {
121-
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
122-
} elseif (is_object($controller)) {
123-
$repr = get_class($controller);
124-
} else {
125-
$repr = $controller;
123+
124+
continue;
125+
}
126+
127+
if ($class = $param->getClass()) {
128+
if ($class->isInstance($request)) {
129+
$arguments[] = $request;
130+
131+
continue;
126132
}
127133

128-
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
134+
if ($class->implementsInterface('Psr\Http\Message\ServerRequestInterface')) {
135+
if (null === $this->httpMessageFactory) {
136+
throw new \RuntimeException('The PSR-7 Bridge must be installed to inject HttpMessage in controllers.');
137+
}
138+
139+
$arguments[] = $this->httpMessageFactory->createRequest($request);
140+
141+
continue;
142+
}
143+
}
144+
145+
if ($param->isDefaultValueAvailable()) {
146+
$arguments[] = $param->getDefaultValue();
147+
148+
continue;
129149
}
150+
151+
if (is_array($controller)) {
152+
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
153+
} elseif (is_object($controller)) {
154+
$repr = get_class($controller);
155+
} else {
156+
$repr = $controller;
157+
}
158+
159+
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
130160
}
131161

132162
return $arguments;

src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\HttpKernel\Tests\Controller;
1313

14+
use Psr\Http\Message\ServerRequestInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
1617
use Symfony\Component\HttpFoundation\Request;
@@ -195,6 +196,11 @@ public function testGetArguments()
195196
$request = Request::create('/');
196197
$controller = array(new self(), 'controllerMethod5');
197198
$this->assertEquals(array($request), $resolver->getArguments($request, $controller), '->getArguments() injects the request');
199+
200+
$request = Request::create('/');
201+
$controller = array(new self(), 'controllerMethod6');
202+
$args = $resolver->getArguments($request, $controller);
203+
$this->assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $args[0], '->getArguments() injects the PSR ServerRequest');
198204
}
199205

200206
public function testCreateControllerCanReturnAnyCallable()
@@ -235,6 +241,10 @@ protected static function controllerMethod4()
235241
protected function controllerMethod5(Request $request)
236242
{
237243
}
244+
245+
protected function controllerMethod6(ServerRequestInterface $request)
246+
{
247+
}
238248
}
239249

240250
function some_controller_function($foo, $foobar)

src/Symfony/Component/HttpKernel/composer.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
"homepage": "https://symfony.com/contributors"
1616
}
1717
],
18+
"repositories": [
19+
{
20+
"type": "vcs",
21+
"url": "https://github.com/dunglas/psr-http-message-bridge"
22+
}
23+
],
1824
"require": {
1925
"php": ">=5.3.9",
2026
"symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2|~3.0.0",
@@ -38,7 +44,9 @@
3844
"symfony/stopwatch": "~2.3|~3.0.0",
3945
"symfony/templating": "~2.2|~3.0.0",
4046
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
41-
"symfony/var-dumper": "~2.6|~3.0.0"
47+
"symfony/var-dumper": "~2.6|~3.0.0",
48+
"symfony/psr-http-message-bridge": "dev-wip",
49+
"zendframework/zend-diactoros": "~1.0"
4250
},
4351
"conflict": {
4452
"symfony/config": "<2.7"
@@ -50,7 +58,9 @@
5058
"symfony/console": "",
5159
"symfony/dependency-injection": "",
5260
"symfony/finder": "",
53-
"symfony/var-dumper": ""
61+
"symfony/var-dumper": "",
62+
"symfony/psr-http-message-bridge": "To enable PSR-7 support.",
63+
"zendframework/zend-diactoros": "To enable PSR-7 support."
5464
},
5565
"autoload": {
5666
"psr-4": { "Symfony\\Component\\HttpKernel\\": "" }

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy