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 3306dc2

Browse filesBrowse files
committed
feature #22157 [FrameworkBundle] Introduce AbstractController, replacing ControllerTrait (nicolas-grekas)
This PR was merged into the 3.3-dev branch. Discussion ---------- [FrameworkBundle] Introduce AbstractController, replacing ControllerTrait | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no (master only) | Deprecations? | yes | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Basically reverts and replaces #18193. Instead of using getter injection to provide our controller helpers, let's leverage the new `ServiceSubscriberInterface` (see #21708). This is what the proposed `AbstractController` class provides. So, instead of extending `Controller`, this would encourage extending `AbstractController`. This provides almost the same experience, but makes the container private, thus not usable by userland (this safeguard was already provided by `ControllerTrait`). I did not deprecate `Controller`, but I think we should. Now that we also have "controller.service_arguments" (see #21771), we have everything in place to encourage *not* using the container in controllers directly anymore. My target in doing so is removing getter injection, which won't have any use case in core anymore. The wiring for this could be: ```yaml services: _instanceof: Symfony\Bundle\FrameworkBundle\Controller\AbstractController: calls: [ [ setContainer, [ '@container' ] ] ] tags: [ container.service_subscriber ] ```` But this is optional, because we don't really need to inject a scoped service locator: injecting the real container is fine also, since everything is private. And this is done automatically on ControllerResolver. Commits ------- a93f059 [FrameworkBundle] Introduce AbstractController, replacing ControllerTrait
2 parents 8901c7e + a93f059 commit 3306dc2
Copy full SHA for 3306dc2

10 files changed

+736
-1502
lines changed

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+2-6Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CHANGELOG
66

77
* Added a new new version strategy option called json_manifest_path
88
that allows you to use the `JsonManifestVersionStrategy`.
9+
* Added `Symfony\Bundle\FrameworkBundle\Controller\AbstractController`. It provides the same helpers than the `Controller` class,
10+
but does not allow accessing the dependency injection container, in order to encourage explicit dependency declarations.
911
* Added support for the `controller.service_arguments` tag, for injecting services into controllers' actions
1012
* Deprecated `cache:clear` with warmup (always call it with `--no-warmup`)
1113
* Deprecated the "framework.trusted_proxies" configuration option and the corresponding "kernel.trusted_proxies" parameter
@@ -26,12 +28,6 @@ CHANGELOG
2628
Use `Symfony\Component\Console\DependencyInjection\ConfigCachePass` instead.
2729
* Deprecated `PropertyInfoPass`, use `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass` instead
2830
* Deprecated extending `ConstraintValidatorFactory`
29-
* Added `Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait` (requires PHP 7). Unlike the `Symfony\Bundle\FrameworkBundle\Controller\Controller`
30-
class, this trait does not have access to the dependency injection container. Its dependencies are explicitly and lazily
31-
injected using getter injection.
32-
`render()`, `renderView()` and `stream()` methods can only use Twig (using the Templating component is not supported).
33-
The `json()` method requires the Serializer component (use `Symfony\Component\HttpFoundation\JsonResponse` directly if
34-
you do not want to use the Serializer).
3531
* Deprecated `ControllerArgumentValueResolverPass`. Use
3632
`Symfony\Component\HttpKernel\DependencyInjection\ControllerArgumentValueResolverPass` instead
3733
* Deprecated `RoutingResolverPass`, use `Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` instead
+69Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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\Bundle\FrameworkBundle\Controller;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Doctrine\Common\Persistence\ManagerRegistry;
16+
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
17+
use Symfony\Component\Form\FormFactoryInterface;
18+
use Symfony\Component\HttpFoundation\RequestStack;
19+
use Symfony\Component\HttpFoundation\Session\Session;
20+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
21+
use Symfony\Component\HttpKernel\HttpKernelInterface;
22+
use Symfony\Component\Routing\RouterInterface;
23+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
24+
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
25+
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
26+
use Symfony\Component\Serializer\SerializerInterface;
27+
use Symfony\Component\Templating\EngineInterface;
28+
29+
/**
30+
* Provides common features needed in controllers.
31+
*
32+
* @author Fabien Potencier <fabien@symfony.com>
33+
*/
34+
abstract class AbstractController implements ServiceSubscriberInterface
35+
{
36+
use ControllerTrait;
37+
38+
private $container;
39+
40+
/**
41+
* @internal
42+
* @required
43+
*/
44+
public function setContainer(ContainerInterface $container)
45+
{
46+
$previous = $this->container;
47+
$this->container = $container;
48+
49+
return $previous;
50+
}
51+
52+
public static function getSubscribedServices()
53+
{
54+
return array(
55+
'router' => '?'.RouterInterface::class,
56+
'request_stack' => '?'.RequestStack::class,
57+
'http_kernel' => '?'.HttpKernelInterface::class,
58+
'serializer' => '?'.SerializerInterface::class,
59+
'session' => '?'.SessionInterface::class,
60+
'security.authorization_checker' => '?'.AuthorizationCheckerInterface::class,
61+
'templating' => '?'.EngineInterface::class,
62+
'twig' => '?'.\Twig_Environment::class,
63+
'doctrine' => '?'.ManagerRegistry::class,
64+
'form.factory' => '?'.FormFactoryInterface::class,
65+
'security.token_storage' => '?'.TokenStorageInterface::class,
66+
'security.csrf.token_manager' => '?'.CsrfTokenManagerInterface::class,
67+
);
68+
}
69+
}

0 commit comments

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