8000 [HttpKernel] Allow to inject PSR-7 ServerRequest in controllers. · symfony/symfony@2f73f0f · GitHub
[go: up one dir, main page]

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
31
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;
35

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)
0