Skip to content

Commit c0bd749

Browse files
committed
feature #24409 [Bridge\Doctrine][FrameworkBundle] Deprecate some remaining uses of ContainerAwareTrait (nicolas-grekas)
This PR was merged into the 3.4 branch. Discussion ---------- [Bridge\Doctrine][FrameworkBundle] Deprecate some remaining uses of ContainerAwareTrait | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - With this PR, the last two remaining uses of ContainerAwareTrait will be `Symfony\Component\HttpKernel\Bundle\Bundle` and `Symfony\Bundle\FrameworkBundle\Controller\Controller`. For Bundle, I think it's legitimate, for Controller, I think it's not, but that we should wait for 4.1 before considering its deprecation, alongside with `ContainerAwareCommand` (maybe). Commits ------- df9c8748e3 [Bridge\Doctrine][FrameworkBundle] Deprecate some remaining uses of ContainerAwareTrait
2 parents fee5680 + 09ae506 commit c0bd749

File tree

6 files changed

+163
-39
lines changed

6 files changed

+163
-39
lines changed

Controller/ControllerResolver.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,7 @@ protected function createController($controller)
4848
$resolvedController = parent::createController($controller);
4949

5050
if (1 === substr_count($controller, ':') && is_array($resolvedController)) {
51-
if ($resolvedController[0] instanceof ContainerAwareInterface) {
52-
$resolvedController[0]->setContainer($this->container);
53-
}
54-
55-
if ($resolvedController[0] instanceof AbstractController && null !== $previousContainer = $resolvedController[0]->setContainer($this->container)) {
56-
$resolvedController[0]->setContainer($previousContainer);
57-
}
51+
$resolvedController[0] = $this->configureController($resolvedController[0]);
5852
}
5953

6054
return $resolvedController;
@@ -65,9 +59,19 @@ protected function createController($controller)
6559
*/
6660
protected function instantiateController($class)
6761
{
68-
$controller = parent::instantiateController($class);
62+
return $this->configureController(parent::instantiateController($class));
63+
}
6964

65+
private function configureController($controller)
66+
{
7067
if ($controller instanceof ContainerAwareInterface) {
68+
// @deprecated switch, to be removed in 4.0 where these classes
69+
// won't implement ContainerAwareInterface anymore
70+
switch (\get_class($controller)) {
71+
case RedirectController::class:
72+
case TemplateController::class:
73+
return $controller;
74+
}
7175
$controller->setContainer($this->container);
7276
}
7377
if ($controller instanceof AbstractController && null !== $previousContainer = $controller->setContainer($this->container)) {

Controller/RedirectController.php

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Controller;
1313

1414
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
15-
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
15+
use Symfony\Component\DependencyInjection\ContainerInterface;
1616
use Symfony\Component\HttpFoundation\RedirectResponse;
1717
use Symfony\Component\HttpFoundation\Request;
1818
use Symfony\Component\HttpFoundation\Response;
@@ -23,10 +23,37 @@
2323
* Redirects a request to another URL.
2424
*
2525
* @author Fabien Potencier <[email protected]>
26+
*
27+
* @final since version 3.4
2628
*/
2729
class RedirectController implements ContainerAwareInterface
2830
{
29-
use ContainerAwareTrait;
31+
/**
32+
* @deprecated since version 3.4, to be removed in 4.0
33+
*/
34+
protected $container;
35+
36+
private $router;
37+
private $httpPort;
38+
private $httpsPort;
39+
40+
public function __construct(UrlGeneratorInterface $router = null, $httpPort = null, $httpsPort = null)
41+
{
42+
$this->router = $router;
43+
$this->httpPort = $httpPort;
44+
$this->httpsPort = $httpsPort;
45+
}
46+
47+
/**
48+
* @deprecated since version 3.4, to be removed in 4.0 alongside with the ContainerAwareInterface type.
49+
*/
50+
public function setContainer(ContainerInterface $container = null)
51+
{
52+
@trigger_error(sprintf('The "%s()" method is deprecated since version 3.4 and will be removed in 4.0. Inject an UrlGeneratorInterface using the constructor instead.', __METHOD__), E_USER_DEPRECATED);
53+
54+
$this->container = $container;
55+
$this->router = $container->get('router');
56+
}
3057

3158
/**
3259
* Redirects to another route with the given name.
@@ -61,7 +88,7 @@ public function redirectAction(Request $request, $route, $permanent = false, $ig
6188
}
6289
}
6390

64-
return new RedirectResponse($this->container->get('router')->generate($route, $attributes, UrlGeneratorInterface::ABSOLUTE_URL), $permanent ? 301 : 302);
91+
return new RedirectResponse($this->router->generate($route, $attributes, UrlGeneratorInterface::ABSOLUTE_URL), $permanent ? 301 : 302);
6592
}
6693

6794
/**
@@ -115,8 +142,11 @@ public function urlRedirectAction(Request $request, $path, $permanent = false, $
115142
if (null === $httpPort) {
116143
if ('http' === $request->getScheme()) {
117144
$httpPort = $request->getPort();
118-
} elseif ($this->container->hasParameter('request_listener.http_port')) {
145+
} elseif ($this->container && $this->container->hasParameter('request_listener.http_port')) {
146+
@trigger_error(sprintf('Passing the http port as a container parameter is deprecated since Symfony 3.4 and won\'t be possible in 4.0. Pass it to the constructor of the "%s" class instead.', __CLASS__), E_USER_DEPRECATED);
119147
$httpPort = $this->container->getParameter('request_listener.http_port');
148+
} else {
149+
$httpPort = $this->httpPort;
120150
}
121151
}
122152

@@ -127,8 +157,11 @@ public function urlRedirectAction(Request $request, $path, $permanent = false, $
127157
if (null === $httpsPort) {
128158
if ('https' === $request->getScheme()) {
129159
$httpsPort = $request->getPort();
130-
} elseif ($this->container->hasParameter('request_listener.https_port')) {
160+
} elseif ($this->container && $this->container->hasParameter('request_listener.https_port')) {
161+
@trigger_error(sprintf('Passing the https port as a container parameter is deprecated since Symfony 3.4 and won\'t be possible in 4.0. Pass it to the constructor of the "%s" class instead.', __CLASS__), E_USER_DEPRECATED);
131162
$httpsPort = $this->container->getParameter('request_listener.https_port');
163+
} else {
164+
$httpsPort = $this->httpsPort;
132165
}
133166
}
134167

Controller/TemplateController.php

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,48 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Controller;
1313

1414
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
15-
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
15+
use Symfony\Component\DependencyInjection\ContainerInterface;
1616
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\Templating\EngineInterface;
18+
use Twig\Environment;
1719

1820
/**
1921
* TemplateController.
2022
*
2123
* @author Fabien Potencier <[email protected]>
24+
*
25+
* @final since version 3.4
2226
*/
2327
class TemplateController implements ContainerAwareInterface
2428
{
25-
use ContainerAwareTrait;
29+
/**
30+
* @deprecated since version 3.4, to be removed in 4.0
31+
*/
32+
protected $container;
33+
34+
private $twig;
35+
private $templating;
36+
37+
public function __construct(Environment $twig = null, EngineInterface $templating = null)
38+
{
39+
$this->twig = $twig;
40+
$this->templating = $templating;
41+
}
42+
43+
/**
44+
* @deprecated since version 3.4, to be removed in 4.0 alongside with the ContainerAwareInterface type.
45+
*/
46+
public function setContainer(ContainerInterface $container = null)
47+
{
48+
@trigger_error(sprintf('The "%s()" method is deprecated since version 3.4 and will be removed in 4.0. Inject a Twig Environment or an EngineInterface using the constructor instead.', __METHOD__), E_USER_DEPRECATED);
49+
50+
if ($container->has('templating')) {
51+
$this->templating = $container->get('templating');
52+
} elseif ($container->has('twig')) {
53+
$this->twig = $container->get('twig');
54+
}
55+
$this->container = $container;
56+
}
2657

2758
/**
2859
* Renders a template.
@@ -36,10 +67,10 @@ class TemplateController implements ContainerAwareInterface
3667
*/
3768
public function templateAction($template, $maxAge = null, $sharedAge = null, $private = null)
3869
{
39-
if ($this->container->has('templating')) {
40-
$response = $this->container->get('templating')->renderResponse($template);
41-
} elseif ($this->container->has('twig')) {
42-
$response = new Response($this->container->get('twig')->render($template));
70+
if ($this->templating) {
71+
$response = new Response($this->templating->render($template));
72+
} elseif ($this->twig) {
73+
$response = new Response($this->twig->render($template));
4374
} else {
4475
throw new \LogicException('You can not use the TemplateController if the Templating Component or the Twig Bundle are not available.');
4576
}

Resources/config/routing.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,16 @@
112112
<argument>%kernel.project_dir%</argument>
113113
<argument>%kernel.debug%</argument>
114114
</service>
115+
116+
<service id="Symfony\Bundle\FrameworkBundle\Controller\RedirectController" public="true">
117+
<argument type="service" id="router" />
118+
<argument>%request_listener.http_port%</argument>
119+
<argument>%request_listener.https_port%</argument>
120+
</service>
121+
122+
<service id="Symfony\Bundle\FrameworkBundle\Controller\TemplateController" public="true">
123+
<argument type="service" id="twig" on-invalid="ignore" />
124+
<argument type="service" id="templating" on-invalid="ignore" />
125+
</service>
115126
</services>
116127
</container>

Tests/Controller/RedirectControllerTest.php

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpFoundation\ParameterBag;
1616
use Symfony\Component\HttpFoundation\Request;
1717
use Symfony\Component\HttpKernel\Exception\HttpException;
18+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
1819
use Symfony\Bundle\FrameworkBundle\Controller\RedirectController;
1920
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
2021

@@ -66,23 +67,14 @@ public function testRoute($permanent, $ignoreAttributes, $expectedCode, $expecte
6667

6768
$request->attributes = new ParameterBag($attributes);
6869

69-
$router = $this->getMockBuilder('Symfony\Component\Routing\RouterInterface')->getMock();
70+
$router = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock();
7071
$router
7172
->expects($this->once())
7273
->method('generate')
7374
->with($this->equalTo($route), $this->equalTo($expectedAttributes))
7475
->will($this->returnValue($url));
7576

76-
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
77-
78-
$container
79-
->expects($this->once())
80-
->method('get')
81-
->with($this->equalTo('router'))
82-
->will($this->returnValue($router));
83-
84-
$controller = new RedirectController();
85-
$controller->setContainer($container);
77+
$controller = new RedirectController($router);
8678

8779
$returnResponse = $controller->redirectAction($request, $route, $permanent, $ignoreAttributes);
8880

@@ -130,7 +122,7 @@ public function testFullURL()
130122
$this->assertEquals(302, $returnResponse->getStatusCode());
131123
}
132124

133-
public function testUrlRedirectDefaultPortParameters()
125+
public function testUrlRedirectDefaultPorts()
134126
{
135127
$host = 'www.example.com';
136128
$baseUrl = '/base';
@@ -151,6 +143,30 @@ public function testUrlRedirectDefaultPortParameters()
151143
$this->assertRedirectUrl($returnValue, $expectedUrl);
152144
}
153145

146+
/**
147+
* @group legacy
148+
*/
149+
public function testUrlRedirectDefaultPortParameters()
150+
{
151+
$host = 'www.example.com';
152+
$baseUrl = '/base';
153+
$path = '/redirect-path';
154+
$httpPort = 1080;
155+
$httpsPort = 1443;
156+
157+
$expectedUrl = "https://$host:$httpsPort$baseUrl$path";
158+
$request = $this->createRequestObject('http', $host, $httpPort, $baseUrl);
159+
$controller = $this->createLegacyRedirectController(null, $httpsPort);
160+
$returnValue = $controller->urlRedirectAction($request, $path, false, 'https');
161+
$this->assertRedirectUrl($returnValue, $expectedUrl);
162+
163+
$expectedUrl = "http://$host:$httpPort$baseUrl$path";
164+
$request = $this->createRequestObject('https', $host, $httpPort, $baseUrl);
165+
$controller = $this->createLegacyRedirectController($httpPort);
166+
$returnValue = $controller->urlRedirectAction($request, $path, false, 'http');
167+
$this->assertRedirectUrl($returnValue, $expectedUrl);
168+
}
169+
154170
public function urlRedirectProvider()
155171
{
156172
return array(
@@ -256,6 +272,14 @@ private function createRequestObject($scheme, $host, $port, $baseUrl, $queryStri
256272
}
257273

258274
private function createRedirectController($httpPort = null, $httpsPort = null)
275+
{
276+
return new RedirectController(null, $httpPort, $httpsPort);
277+
}
278+
279+
/**
280+
* @deprecated
281+
*/
282+
private function createLegacyRedirectController($httpPort = null, $httpsPort = null)
259283
{
260284
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
261285

Tests/Controller/TemplateControllerTest.php

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
1313

1414
use Symfony\Bundle\FrameworkBundle\Controller\TemplateController;
15+
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
1516
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
16-
use Symfony\Component\HttpFoundation\Response;
1717

1818
/**
1919
* @author Kévin Dunglas <[email protected]>
@@ -25,6 +25,29 @@ public function testTwig()
2525
$twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock();
2626
$twig->expects($this->once())->method('render')->willReturn('bar');
2727

28+
$controller = new TemplateController($twig);
29+
30+
$this->assertEquals('bar', $controller->templateAction('mytemplate')->getContent());
31+
}
32+
33+
public function testTemplating()
34+
{
35+
$templating = $this->getMockBuilder(EngineInterface::class)->getMock();
36+
$templating->expects($this->once())->method('render')->willReturn('bar');
37+
38+
$controller = new TemplateController(null, $templating);
39+
40+
$this->assertEquals('bar', $controller->templateAction('mytemplate')->getContent());
41+
}
42+
43+
/**
44+
* @group legacy
45+
*/
46+
public function testLegacyTwig()
47+
{
48+
$twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock();
49+
$twig->expects($this->once())->method('render')->willReturn('bar');
50+
2851
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
2952
$container->expects($this->at(0))->method('has')->will($this->returnValue(false));
3053
$container->expects($this->at(1))->method('has')->will($this->returnValue(true));
@@ -36,10 +59,13 @@ public function testTwig()
3659
$this->assertEquals('bar', $controller->templateAction('mytemplate')->getContent());
3760
}
3861

39-
public function testTemplating()
62+
/**
63+
* @group legacy
64+
*/
65+
public function testLegacyTemplating()
4066
{
4167
$templating = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface')->getMock();
42-
$templating->expects($this->once())->method('renderResponse')->willReturn(new Response('bar'));
68+
$templating->expects($this->once())->method('render')->willReturn('bar');
4369

4470
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
4571
$container->expects($this->at(0))->method('has')->willReturn(true);
@@ -57,12 +83,7 @@ public function testTemplating()
5783
*/
5884
public function testNoTwigNorTemplating()
5985
{
60-
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
61-
$container->expects($this->at(0))->method('has')->willReturn(false);
62-
$container->expects($this->at(1))->method('has')->willReturn(false);
63-
6486
$controller = new TemplateController();
65-
$controller->setContainer($container);
6687

6788
$controller->templateAction('mytemplate')->getContent();
6889
}

0 commit comments

Comments
 (0)