8000 Deprecate bundle:controller:action and service:method notation · symfony/symfony@f8a609c · GitHub
[go: up one dir, main page]

Skip to content

Commit f8a609c

Browse files
Tobionfabpot
authored andcommitted
Deprecate bundle:controller:action and service:method notation
1 parent e0bdc0c commit f8a609c

File tree

40 files changed

+494
-450
lines changed
  • Controller
  • EventListener
  • Kernel
  • Routing
  • Tests
  • SecurityBundle
  • TwigBundle
  • WebProfilerBundle/Resources/config/routing
  • Component
  • 40 files changed

    +494
    -450
    lines changed

    UPGRADE-4.1.md

    Lines changed: 32 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -15,6 +15,38 @@ EventDispatcher
    1515
    FrameworkBundle
    1616
    ---------------
    1717

    18+
    * Deprecated `bundle:controller:action` and `service:action` syntaxes to reference controllers. Use `serviceOrFqcn::method`
    19+
    instead where `serviceOrFqcn` is either the service ID when using controllers as services or the FQCN of the controller.
    20+
    21+
    Before:
    22+
    23+
    ```yml
    24+
    bundle_controller:
    25+
    path: /
    26+
    defaults:
    27+
    _controller: FrameworkBundle:Redirect:redirect
    28+
    29+
    service_controller:
    30+
    path: /
    31+
    defaults:
    32+
    _controller: app.my_controller:myAction
    33+
    ```
    34+
    35+
    After:
    36+
    37+
    ```yml
    38+
    bundle_controller:
    39+
    path: /
    40+
    defaults:
    41+
    _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction
    42+
    43+
    service_controller:
    44+
    path: /
    45+
    defaults:
    46+
    _controller: app.my_controller::myAction
    47+
    ```
    48+
    49+
    * Deprecated `Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser`
    1850
    * A `RouterInterface` that does not implement the `WarmableInterface` is deprecated.
    1951
    * The `RequestDataCollector` class has been deprecated. Use the `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector` class instead.
    2052

    UPGRADE-5.0.md

    Lines changed: 32 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -14,6 +14,38 @@ EventDispatcher
    1414
    FrameworkBundle
    1515
    ---------------
    1616

    17+
    * Removed support for `bundle:controller:action` and `service:action` syntaxes to reference controllers. Use `serviceOrFqcn::method`
    18+
    instead where `serviceOrFqcn` is either the service ID when using controllers as services or the FQCN of the controller.
    19+
    20+
    Before:
    21+
    22+
    ```yml
    23+
    bundle_controller:
    24+
    path: /
    25+
    defaults:
    26+
    _controller: FrameworkBundle:Redirect:redirect
    27+
    28+
    service_controller:
    29+
    path: /
    30+
    defaults:
    31+
    _controller: app.my_controller:myAction
    32+
    ```
    33+
    34+
    After:
    35+
    36+
    ```yml
    37+
    bundle_controller:
    38+
    path: /
    39+
    defaults:
    40+
    _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction
    41+
    42+
    service_controller:
    43+
    path: /
    44+
    defaults:
    45+
    _controller: app.my_controller::myAction
    46+
    ```
    47+
    48+
    * Removed `Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser`
    1749
    * Using a `RouterInterface` that does not implement the `WarmableInterface` is not supported anymore.
    1850
    * The `RequestDataCollector` class has been removed. Use the `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector` class instead.
    1951

    src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

    Lines changed: 3 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -11,6 +11,9 @@ CHANGELOG
    1111
    * Using a `RouterInterface` that does not implement the `WarmableInterface` is deprecated.
    1212
    * The `RequestDataCollector` class has been deprecated. Use the `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector` class instead.
    1313
    * The `RedirectController` class allows for 307/308 HTTP status codes
    14+
    * Deprecated `bundle:controller:action` syntax to reference controllers. Use `serviceOrFqcn::method` instead where `serviceOrFqcn`
    15+
    is either the service ID or the FQCN of the controller.
    16+
    * Deprecated `Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser`
    1417

    1518
    4.0.0
    1619
    -----

    src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php

    Lines changed: 0 additions & 47 deletions
    Original file line numberDiff line numberDiff line change
    @@ -12,16 +12,13 @@
    1212
    namespace Symfony\Bundle\FrameworkBundle\Command;
    1313

    1414
    use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper;
    15-
    use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
    1615
    use Symfony\Component\Console\Command\Command;
    1716
    use Symfony\Component\Console\Input\InputArgument;
    1817
    use Symfony\Component\Console\Input\InputInterface;
    1918
    use Symfony\Component\Console\Input\InputOption;
    2019
    use Symfony\Component\Console\Output\OutputInterface;
    2120
    use Symfony\Component\Console\Style\SymfonyStyle;
    22-
    use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
    2321
    use Symfony\Component\Routing\RouterInterface;
    24-
    use Symfony\Component\Routing\Route;
    2522

    2623
    /**
    2724
    * A console command for retrieving information about routes.
    @@ -83,20 +80,13 @@ protected function execute(InputInterface $input, OutputInterface $output)
    8380
    throw new \InvalidArgumentException(sprintf('The route "%s" does not exist.', $name));
    8481
    }
    8582

    86-
    $callable = $this->extractCallable($route);
    87-
    8883
    $helper->describe($io, $route, array(
    8984
    'format' => $input->getOption('format'),
    9085
    'raw_text' => $input->getOption('raw'),
    9186
    'name' => $name,
    9287
    'output' => $io,
    93-
    'callable' => $callable,
    9488
    ));
    9589
    } else {
    96-
    foreach ($routes as $route) {
    97-
    $this->convertController($route);
    98-
    }
    99-
    10090
    $helper->describe($io, $routes, array(
    10191
    'format' => $input->getOption('format'),
    10292
    'raw_text' => $input->getOption('raw'),
    @@ -105,41 +95,4 @@ protected function execute(InputInterface $input, OutputInterface $output)
    10595
    ));
    10696
    }
    10797
    }
    108-
    109-
    private function convertController(Route $route)
    110-
    {
    111-
    if ($route->hasDefault('_controller')) {
    112-
    $nameParser = new ControllerNameParser($this->getApplication()->getKernel());
    113-
    try {
    114-
    $route->setDefault('_controller', $nameParser->build($route->getDefault('_controller')));
    115-
    } catch (\InvalidArgumentException $e) {
    116-
    }
    117-
    }
    118-
    }
    119-
    120-
    private function extractCallable(Route $route)
    121-
    {
    122-
    if (!$route->hasDefault('_controller')) {
    123-
    return;
    124-
    }
    125-
    126-
    $controller = $route->getDefault('_controller');
    127-
    128-
    if (1 === substr_count($controller, ':')) {
    129-
    list($service, $method) = explode(':', $controller);
    130-
    try {
    131-
    return sprintf('%s::%s', get_class($this->getApplication()->getKernel()->getContainer()->get($service)), $method);
    132-
    } catch (ServiceNotFoundException $e) {
    133-
    }
    134-
    }
    135-
    136-
    $nameParser = new ControllerNameParser($this->getApplication()->getKernel());
    137-
    try {
    138-
    $shortNotation = $nameParser->build($controller);
    139-
    $route->setDefault('_controller', $shortNotation);
    140-
    141-
    return $controller;
    142-
    } catch (\InvalidArgumentException $e) {
    143-
    }
    144-
    }
    14598
    }

    src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php

    Lines changed: 0 additions & 3 deletions
    Original file line numberDiff line numberDiff line change
    @@ -95,9 +95,6 @@ protected function describeRoute(Route $route, array $options = array())
    9595
    array('Defaults', $this->formatRouterConfig($route->getDefaults())),
    9696
    array('Options', $this->formatRouterConfig($route->getOptions())),
    9797
    );
    98-
    if (isset($options['callable'])) {
    99-
    $tableRows[] = array('Callable', $options['callable']);
    100-
    }
    10198

    10299
    $table = new Table($this->getOutput());
    103100
    $table->setHeaders($tableHeaders)->setRows($tableRows);

    src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php

    Lines changed: 8 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -19,6 +19,8 @@
    1919
    * (Bundle\BlogBundle\Controller\PostController::indexAction).
    2020
    *
    2121
    * @author Fabien Potencier <fabien@symfony.com>
    22+
    *
    23+
    * @deprecated since Symfony 4.1
    2224
    */
    2325
    class ControllerNameParser
    2426
    {
    @@ -41,6 +43,10 @@ public function __construct(KernelInterface $kernel)
    4143
    */
    4244
    public function parse($controller)
    4345
    {
    46+
    if (2 > func_num_args() || func_get_arg(1)) {
    47+
    @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.1.', __CLASS__), E_USER_DEPRECATED);
    48+
    }
    49+
    4450
    $parts = explode(':', $controller);
    4551
    if (3 !== count($parts) || in_array('', $parts, true)) {
    4652
    throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "a:b:c" controller string.', $controller));
    @@ -86,6 +92,8 @@ public function parse($controller)
    8692
    */
    8793
    public function build($controller)
    8894
    {
    95+
    @trigger_error(sprintf('The %s class is deprecated since Symfony 4.1.', __CLASS__), E_USER_DEPRECATED);
    96+
    8997
    if (0 === preg_match('#^(.*?\\\\Controller\\\\(.+)Controller)::(.+)Action$#', $controller, $match)) {
    9098
    throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "class::method" string.', $controller));
    9199
    }

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

    Lines changed: 4 additions & 7 deletions
    Original file line numberDiff line numberDiff line change
    @@ -37,16 +37,13 @@ protected function createController($controller)
    3737
    {
    3838
    if (false === strpos($controller, '::') && 2 === substr_count($controller, ':')) {
    3939
    // controller in the a:b:c notation then
    40-
    $controller = $this->parser->parse($controller);
    41-
    }
    42-
    43-
    $resolvedController = parent::createController($controller);
    40+
    $deprecatedNotation = $controller;
    41+
    $controller = $this->parser->parse($deprecatedNotation, false);
    4442

    45-
    if (1 === substr_count($controller, ':') && is_array($resolvedController)) {
    46-
    $resolvedController[0] = $this->configureController($resolvedController[0]);
    43+
    @trigger_error(sprintf('Referencing controllers with %s is deprecated since Symfony 4.1. Use %s instead.', $deprecatedNotation, $controller), E_USER_DEPRECATED);
    4744
    }
    4845

    49-
    return $resolvedController;
    46+
    return parent::createController($controller);
    5047
    }
    5148

    5249
    /**

    src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php

    Lines changed: 3 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -20,6 +20,8 @@
    2020
    * Guarantees that the _controller key is parsed into its final format.
    2121
    *
    2222
    * @author Ryan Weaver <ryan@knpuniversity.com>
    23+
    *
    24+
    * @deprecated since Symfony 4.1
    2325
    */
    2426
    class ResolveControllerNameSubscriber implements EventSubscriberInterface
    2527
    {
    @@ -35,7 +37,7 @@ public function onKernelRequest(GetResponseEvent $event)
    3537
    $controller = $event->getRequest()->attributes->get('_controller');
    3638
    if (is_string($controller) && false === strpos($controller, '::') && 2 === substr_count($controller, ':')) {
    3739
    // controller in the a:b:c notation then
    38-
    $event->getRequest()->attributes->set('_controller', $this->parser->parse($controller));
    40+
    $event->getRequest()->attributes->set('_controller', $this->parser->parse($controller, false));
    3941
    }
    4042
    }
    4143

    src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -64,7 +64,7 @@ public function registerContainerConfiguration(LoaderInterface $loader)
    6464
    $loader->load(function (ContainerBuilder $container) use ($loader) {
    6565
    $container->loadFromExtension('framework', array(
    6666
    'router' => array(
    67-
    'resource' => 'kernel:loadRoutes',
    67+
    'resource' => 'kernel::loadRoutes',
    6868
    'type' => 'service',
    6969
    ),
    7070
    ));

    src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php

    Lines changed: 20 additions & 5 deletions
    Original file line numberDiff line numberDiff line change
    @@ -73,14 +73,29 @@ public function load($resource, $type = null)
    7373
    }
    7474

    7575
    foreach ($collection->all() as $route) {
    76-
    if (!is_string($controller = $route->getDefault('_controller')) || !$controller) {
    76+
    if (!is_string($controller = $route->getDefault('_controller'))) {
    7777
    continue;
    7878
    }
    7979

    80-
    try {
    81-
    $controller = $this->parser->parse($controller);
    82-
    } catch (\InvalidArgumentException $e) {
    83-
    // unable to optimize unknown notation
    80+
    if (false !== strpos($controller, '::')) {
    81+
    continue;
    82+
    }
    83+
    84+
    if (2 === substr_count($controller, ':')) {
    85+
    $deprecatedNotation = $controller;
    86+
    87+
    try {
    88+
    $controller = $this->parser->parse($controller, false);
    89+
    90+
    @trigger_error(sprintf('Referencing controllers with %s is deprecated since Symfony 4.1. Use %s instead.', $deprecatedNotation, $controller), E_USER_DEPRECATED);
    91+
    } catch (\InvalidArgumentException $e) {
    92+
    < 10000 span class=pl-c>// unable to optimize unknown notation
    93+
    }
    94+
    }
    95+
    96+
    if (1 === substr_count($controller, ':')) {
    97+
    $controller = str_replace(':', '::', $controller);
    98+
    @trigger_error(sprintf('Referencing controllers with a single colon is deprecated since Symfony 4.1. Use %s instead.', $controller), E_USER_DEPRECATED);
    8499
    }
    85100

    86101
    $route->setDefault('_controller', $controller);

    src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php

    Lines changed: 3 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -16,6 +16,9 @@
    1616
    use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
    1717
    use Symfony\Component\HttpKernel\Kernel;
    1818

    19+
    /**
    20+
    * @group legacy
    21+
    */
    1922
    class ControllerNameParserTest extends TestCase
    2023
    {
    2124
    protected $loader;

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

    Lines changed: 10 additions & 4 deletions
    Original file line numberDiff line numberDiff line change
    @@ -20,6 +20,7 @@
    2020
    use Symfony\Component\DependencyInjection\ContainerAwareInterface;
    2121
    use Symfony\Component\DependencyInjection\ContainerInterface;
    2222
    use Symfony\Component\HttpFoundation\Request;
    23+
    use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
    2324
    use Symfony\Component\HttpKernel\Tests\Controller\ContainerControllerResolverTest;
    2425

    2526
    class ControllerResolverTest extends ContainerControllerResolverTest
    @@ -32,6 +33,7 @@ public function testGetControllerOnContainerAware()
    3233

    3334
    $controller = $resolver->getController($request);
    3435

    36+
    $this->assertInstanceOf('Symfony\Bundle\FrameworkBundle\Tests\Controller\ContainerAwareController', $controller[0]);
    3537
    $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $controller[0]->getContainer());
    3638
    $this->assertSame('testAction', $controller[1]);
    3739
    }
    @@ -48,6 +50,10 @@ public function testGetControllerOnContainerAwareInvokable()
    4850
    $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $controller->getContainer());
    4951
    }
    5052

    53+
    /**
    54+
    * @group legacy
    55+
    * @expectedDeprecation Referencing controllers with FooBundle:Default:test is deprecated since Symfony 4.1. Use Symfony\Bundle\FrameworkBundle\Tests\Controller\ContainerAwareController::testAction instead.
    56+
    */
    5157
    public function testGetControllerWithBundleNotation()
    5258
    {
    5359
    $shortName = 'FooBundle:Default:test';
    @@ -81,7 +87,7 @@ class_exists(AbstractControllerTest::class);
    8187
    $resolver = $this->createControllerResolver(null, $container);
    8288

    8389
    $request = Request::create('/');
    84-
    $request->attributes->set('_controller', TestAbstractController::class.':testAction');
    90+
    $request->attributes->set('_controller', TestAbstractController::class.'::testAction');
    8591

    8692
    $this->assertSame(array($controller, 'testAction'), $resolver->getController($request));
    8793
    $this->assertSame($container, $controller->getContainer());
    @@ -117,7 +123,7 @@ class_exists(AbstractControllerTest::class);
    117123
    $resolver = $this->createControllerResolver(null, $container);
    118124

    119125
    $request = Request::create('/');
    120-
    $request->attributes->set('_controller', DummyController::class.':fooAction');
    126+
    $request->attributes->set('_controller', DummyController::class.'::fooAction');
    121127

    122128
    $this->assertSame(array($controller, 'fooAction'), $resolver->getController($request));
    123129
    $this->assertSame($container, $controller->getContainer());
    @@ -157,13 +163,13 @@ class_exists(AbstractControllerTest::class);
    157163
    $resolver = $this->createControllerResolver(null, $container);
    158164

    159165
    $request = Request::create('/');
    160-
    $request->attributes->set('_controller', DummyController::class.':fooAction');
    166+
    $request->attributes->set('_controller', DummyController::class.'::fooAction');
    161167

    162168
    $this->assertSame(array($controller, 'fooAction'), $resolver->getController($request));
    163169
    $this->assertSame($controllerContainer, $controller->getContainer());
    164170
    }
    165171

    166-
    protected function createControllerResolver(LoggerInterface $logger = null, Psr11ContainerInterface $container = null, ControllerNameParser $parser = null)
    172+
    protected function createControllerResolver(LoggerInterface $logger = null, Psr11ContainerInterface $container = null, ControllerNameParser $parser = null): ControllerResolverInterface
    167173
    {
    168174
    if (!$parser) {
    169175
    $parser = $this->createMockParser();

    src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SubRequestController.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -33,7 +33,7 @@ public function indexAction($handler)
    3333
    // ...to check that the FragmentListener still references the right Request
    3434
    // when rendering another fragment after the error occurred
    3535
    // should render en/html instead of fr/json
    36-
    $content .= $handler->render(new ControllerReference('TestBundle:SubRequest:fragment'));
    36+
    $content .= $handler->render(new ControllerReference(self::class.'::fragmentAction'));
    3737

    3838
    // forces the LocaleListener to set fr for the locale...
    3939
    // should render fr/json

    src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SubRequestServiceResolutionController.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -24,7 +24,7 @@ class SubRequestServiceResolutionController implements ContainerAwareInterface
    2424
    public function indexAction()
    2525
    {
    2626
    $request = $this->container->get('request_stack')->getCurrentRequest();
    27-
    $path['_controller'] = 'TestBundle:SubRequestServiceResolution:fragment';
    27+
    $path['_controller'] = self::class.'::fragmentAction';
    2828
    $subRequest = $request->duplicate(array(), null, $path);
    2929

    3030
    return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);

    0 commit comments

    Comments
     (0)
    0