Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2353a34

Browse filesBrowse files
committed
feature #21768 [HttpKernel] Add a ContainerControllerResolver (psr-11) (ogizanagi)
This PR was merged into the 3.3-dev branch. Discussion ---------- [HttpKernel] Add a ContainerControllerResolver (psr-11) | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | N/A | License | MIT | Doc PR | N/A Extracts the controller as service resolution from the framework bundle controller resolver in a `Symfony/Component/HttpKernel/Controller/Psr11ControllerResolver`, allowing you to use `HttpKernel` with your own psr-11 container. Commits ------- 7bbae41 [HttpKernel] Add a ContainerControllerResolver (psr-11)
2 parents d1da474 + 7bbae41 commit 2353a34
Copy full SHA for 2353a34

File tree

4 files changed

+236
-150
lines changed
Filter options

4 files changed

+236
-150
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php
+7-32Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,17 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Controller;
1313

1414
use Psr\Log\LoggerInterface;
15-
use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
1615
use Symfony\Component\DependencyInjection\ContainerInterface;
1716
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
17+
use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver;
1818

1919
/**
2020
* ControllerResolver.
2121
*
2222
* @author Fabien Potencier <fabien@symfony.com>
2323
*/
24-
class ControllerResolver extends BaseControllerResolver
24+
class ControllerResolver extends ContainerControllerResolver
2525
{
26-
protected $container;
2726
protected $parser;
2827

2928
/**
@@ -35,39 +34,19 @@ class ControllerResolver extends BaseControllerResolver
3534
*/
3635
public function __construct(ContainerInterface $container, ControllerNameParser $parser, LoggerInterface $logger = null)
3736
{
38-
$this->container = $container;
3937
$this->parser = $parser;
4038

41-
parent::__construct($logger);
39+
parent::__construct($container, $logger);
4240
}
4341

4442
/**
45-
* Returns a callable for the given controller.
46-
*
47-
* @param string $controller A Controller string
48-
*
49-
* @return mixed A PHP callable
50-
*
51-
* @throws \LogicException When the name could not be parsed
52-
* @throws \InvalidArgumentException When the controller class does not exist
43+
* {@inheritdoc}
5344
*/
5445
protected function createController($controller)
5546
{
56-
if (false === strpos($controller, '::')) {
57-
$count = substr_count($controller, ':');
58-
if (2 == $count) {
59-
// controller in the a:b:c notation then
60-
$controller = $this->parser->parse($controller);
61-
} elseif (1 == $count) {
62-
// controller in the service:method notation
63-
list($service, $method) = explode(':', $controller, 2);
64-
65-
return array($this->container->get($service), $method);
66-
} elseif ($this->container->has($controller) && method_exists($service = $this->container->get($controller), '__invoke')) {
67-
return $service;
68-
} else {
69-
throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller));
70-
}
47+
if (false === strpos($controller, '::') && 2 === substr_count($controller, ':')) {
48+
// controller in the a:b:c notation then
49+
$controller = $this->parser->parse($controller);
7150
}
7251

7352
return parent::createController($controller);
@@ -78,10 +57,6 @@ protected function createController($controller)
7857
*/
7958
protected function instantiateController($class)
8059
{
81-
if ($this->container->has($class)) {
82-
return $this->container->get($class);
83-
}
84-
8560
$controller = parent::instantiateController($class);
8661

8762
if ($controller instanceof ContainerAwareInterface) {

‎src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php
+5-118Lines changed: 5 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
1313

14+
use Psr\Container\ContainerInterface as Psr11ContainerInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
1617
use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver;
1718
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
1819
use Symfony\Component\DependencyInjection\ContainerInterface;
1920
use Symfony\Component\HttpFoundation\Request;
20-
use Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest as BaseControllerResolverTest;
21+
use Symfony\Component\HttpKernel\Tests\Controller\ContainerControllerResolverTest;
2122

22-
class ControllerResolverTest extends BaseControllerResolverTest
23+
class ControllerResolverTest extends ContainerControllerResolverTest
2324
{
2425
public function testGetControllerOnContainerAware()
2526
{
@@ -55,7 +56,7 @@ public function testGetControllerWithBundleNotation()
5556
->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\Controller\ContainerAwareController::testAction'))
5657
;
5758

58-
$resolver = $this->createControllerResolver(null, $parser);
59+
$resolver = $this->createControllerResolver(null, null, $parser);
5960
$request = Request::create('/');
6061
$request->attributes->set('_controller', $shortName);
6162

@@ -66,110 +67,7 @@ public function testGetControllerWithBundleNotation()
6667
$this->assertSame('testAction', $controller[1]);
6768
}
6869

69-
public function testGetControllerService()
70-
{
71-
$container = $this->createMockContainer();
72-
$container->expects($this->once())
73-
->method('get')
74-
->with('foo')
75-
->will($this->returnValue($this))
76-
;
77-
78-
$resolver = $this->createControllerResolver(null, null, $container);
79-
$request = Request::create('/');
80-
$request->attributes->set('_controller', 'foo:controllerMethod1');
81-
82-
$controller = $resolver->getController($request);
83-
84-
$this->assertInstanceOf(get_class($this), $controller[0]);
85-
$this->assertSame('controllerMethod1', $controller[1]);
86-
}
87-
88-
public function testGetControllerInvokableService()
89-
{
90-
$invokableController = new InvokableController('bar');
91-
92-
$container = $this->createMockContainer();
93-
$container->expects($this->once())
94-
->method('has')
95-
->with('foo')
96-
->will($this->returnValue(true))
97-
;
98-
$container->expects($this->once())
99-
->method('get')
100-
->with('foo')
101-
->will($this->returnValue($invokableController))
102-
;
103-
104-
$resolver = $this->createControllerResolver(null, null, $container);
105-
$request = Request::create('/');
106-
$request->attributes->set('_controller', 'foo');
107-
108-
$controller = $resolver->getController($request);
109-
110-
$this->assertEquals($invokableController, $controller);
111-
}
112-
113-
public function testGetControllerInvokableServiceWithClassNameAsName()
114-
{
115-
$invokableController = new InvokableController('bar');
116-
$className = __NAMESPACE__.'\InvokableController';
117-
118-
$container = $this->createMockContainer();
119-
$container->expects($this->once())
120-
->method('has')
121-
->with($className)
122-
->will($this->returnValue(true))
123-
;
124-
$container->expects($this->once())
125-
->method('get')
126-
->with($className)
127-
->will($this->returnValue($invokableController))
128-
;
129-
130-
$resolver = $this->createControllerResolver(null, null, $container);
131-
$request = Request::create('/');
132-
$request->attributes->set('_controller', $className);
133-
134-
$controller = $resolver->getController($request);
135-
136-
$this->assertEquals($invokableController, $controller);
137-
}
138-
139-
/**
140-
* @dataProvider getUndefinedControllers
141-
*/
142-
public function testGetControllerOnNonUndefinedFunction($controller, $exceptionName = null, $exceptionMessage = null)
143-
{
144-
// All this logic needs to be duplicated, since calling parent::testGetControllerOnNonUndefinedFunction will override the expected excetion and not use the regex
145-
$resolver = $this->createControllerResolver();
146-
if (method_exists($this, 'expectException')) {
147-
$this->expectException($exceptionName);
148-
$this->expectExceptionMessageRegExp($exceptionMessage);
149-
} else {
150-
$this->setExpectedExceptionRegExp($exceptionName, $exceptionMessage);
151-
}
152-
153-
$request = Request::create('/');
154-
$request->attributes->set('_controller', $controller);
155-
$resolver->getController($request);
156-
}
157-
158-
public function getUndefinedControllers()
159-
{
160-
return array(
161-
array('foo', '\LogicException', '/Unable to parse the controller name "foo"\./'),
162-
array('oof::bar', '\InvalidArgumentException', '/Class "oof" does not exist\./'),
163-
array('stdClass', '\LogicException', '/Unable to parse the controller name "stdClass"\./'),
164-
array(
165-
'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar',
166-
'\InvalidArgumentException',
167-
'/.?[cC]ontroller(.*?) for URI "\/" is not callable\.( Expected method(.*) Available methods)?/',
168-
),
169-
);
170-
}
171-
172-
protected function createControllerResolver(LoggerInterface $logger = null, ControllerNameParser $parser = null, ContainerInterface $container = null)
70+
protected function createControllerResolver(LoggerInterface $logger = null, Psr11ContainerInterface $container = null, ControllerNameParser $parser = null)
17371
{
17472
if (!$parser) {
17573
$parser = $this->createMockParser();
@@ -215,14 +113,3 @@ public function __invoke()
215113
{
216114
}
217115
}
218-
219-
class InvokableController
220-
{
221-
public function __construct($bar) // mandatory argument to prevent automatic instantiation
222-
{
223-
}
224-
225-
public function __invoke()
226-
{
227-
}
228-
}
+76Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpKernel\Controller;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Psr\Log\LoggerInterface;
16+
17+
/**
18+
* A controller resolver searching for a controller in a psr-11 container when using the "service:method" notation.
19+
*
20+
* @author Fabien Potencier <fabien@symfony.com>
21+
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
22+
*/
23+
class ContainerControllerResolver extends ControllerResolver
24+
{
25+
protected $container;
26+
27+
public function __construct(ContainerInterface $container, LoggerInterface $logger = null)
28+
{
29+
$this->container = $container;
30+
31+
parent::__construct($logger);
32+
}
33+
34+
/**
35+
* Returns a callable for the given controller.
36+
*
37+
* @param string $controller A Controller string
38+
*
39+
* @return mixed A PHP callable
40+
*
41+
* @throws \LogicException When the name could not be parsed
42+
* @throws \InvalidArgumentException When the controller class does not exist
43+
*/
44+
protected function createController($controller)
45+
{
46+
if (false !== strpos($controller, '::')) {
47+
return parent::createController($controller);
48+
}
49+
50+
if (1 == substr_count($controller, ':')) {
51+
// controller in the "service:method" notation
52+
list($service, $method) = explode(':', $controller, 2);
53+
54+
return array($this->container->get($service), $method);
55+
}
56+
57+
if ($this->container->has($controller) && method_exists($service = $this->container->get($controller), '__invoke')) {
58+
// invokable controller in the "service" notation
59+
return $service;
60+
}
61+
62+
throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller));
63+
}
64+
65+
/**
66+
* {@inheritdoc}
67+
*/
68+
protected function instantiateController($class)
69+
{
70+
if ($this->container->has($class)) {
71+
return $this->container->get($class);
72+
}
73+
74+
return parent::instantiateController($class);
75+
}
76+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.