Problem/Motivation

ControllerResolver::getArguments() has been removed in Symfony 4, leading to test failures when 8.x is updated.

Proposed resolution

Re-implement it in our subclass, mark it as internal for removal in Drupal 9.

This appears to be only called by our test coverage, so another option would be to remove the test coverage and treat the inherited method as 'dead code'.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

catch created an issue. See original summary.

catch’s picture

Title: ControllerResolver::getArguments() is removed in Symfony 4 » ControllerResolver::getArguments() is removed in Symfony 4 and ControllerResolver no longer implements ArgumentResolverInterface
StatusFileSize
new1.82 KB

Also need to directly implement the interface.

kim.pepper’s picture

Nit. Looks like some whitespace issues.

alexpott’s picture

This appears to be only called by our test coverage, so another option would be to remove the test coverage and treat the inherited method as 'dead code'.

Is this only legacy tests that are calling it? If so they could be skipped if Symfony > 3.

catch’s picture

Status: Needs review » Needs work
Issue tags: +Novice, +Needs re-roll

It looks like only Drupal\Tests\Core\Controller\ControllerResolverTest::testGetArguments() which is indeed legacy. That's testing for a deprecation message on doGetArguments(), which is only called by getArguments(). How would we skip tests based on Symfony version though?

Tagging novice and needs re-roll for fixing the Symfony -> Drupal coding standards stuff.

sjerdo’s picture

Status: Needs work » Needs review
StatusFileSize
new2.35 KB
new2.7 KB

Updated indent of patch and removed a use of ArgumentResolverInterface::class which wasn't used in sprintf.

sjerdo’s picture

Issue tags: -Novice, -Needs re-roll
sjerdo’s picture

StatusFileSize
new2.42 KB

Excuse me, I've add the wrong interdiff. Here is the correct one.

alexpott’s picture

Done some more thinking about this. I think we need to add a deprecation to our new getArguments() because ideally we don't want people to use it. But if we want people to be able to use Symfony 4 on Drupal 8 then we need to provide it. For me though this pseudo-backporting of Symfony code is one of the reasons that I'm suspicious that making Drupal 8 core AND contrib AND custom be able to run with both Symfony 3 and 4 is likely to be complex and quite involving. That doesn't mean that prepping Drupal 8 to support Symfony 4 is wrong as that will result in less work but this is different and feels like a dangerous precedent.

catch’s picture

I think we need to add a deprecation to our new getArguments() because ideally we don't want people to use it.

doGetArguments() already has a deprecation notice and getArguments() always calls it, so it's impossible to call the method without getting a deprecation, but it would be clearer if it was on the main method.

one of the reasons that I'm suspicious that making Drupal 8 core AND contrib AND custom be able to run with both Symfony 3 and 4 is likely to be complex and quite involving.

Apart from #3020385: Symfony 3 and Symfony ^4.2 JsonEncode constructors are incompatible this is the only tricky change in Symfony 4.2, everything else has been minor test updates, so I don't think it's that bad. Of course we have Symfony 4.4 deprecations still to come which could be harder to deal with. I don't think we should try to support Symfony APIs that core doesn't use/test that contrib might happen to rely on or anything like that though, since that's a promise we may well not be able to keep.

These are changes where if we were making the change directly in the 9.x branch, that we'd just be able to delete the old test and doGetArguments() and be done, but the difference between doing it now and in one year makes it worth it for me.

alexpott’s picture

I don't think we should try to support Symfony APIs that core doesn't use/test that contrib might happen to rely on or anything like that though, since that's a promise we may well not be able to keep.

That's going to be hard to discover though. We're far from 100% test coverage and we've changed stuff in core for Symfony 3 -> 4 deprecations already. For me adding this method to our code is the start of us providing a facade to Symfony 4.

The other idea of detecting Symfony 3 maybe could be done with an explicit assertion on whether \Symfony\Component\HttpKernel\Controller\ControllerResolver::getArguments() exists.

catch’s picture

StatusFileSize
new2.79 KB

That's going to be hard to discover though.

Well I meant literally just fixing what we have test coverage for.

The other idea of detecting Symfony 3 maybe could be done with an explicit assertion on whether \Symfony\Component\HttpKernel\Controller\ControllerResolver::getArguments() exists.

Here's a patch that does that, it's not too bad, had to remove a @covers from a couple of tests.

catch’s picture

StatusFileSize
new2.79 KB
new157.91 KB

The 'combined' patch includes the Symfony 4 update and some other patches, it should theoretically only have a fail in page caching at this point and maybe one or two others.

alexpott’s picture

I like #12. The changes to @covers seem great to me because we really ought to be only covering our own code and we don't implement getArguments().

The last submitted patch, 13: 3020536-combined.patch, failed testing. View results

catch’s picture

StatusFileSize
new5.88 KB

Three more tests testing the same deprecation that need the same approach.

wim leers’s picture

  1. +++ b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
    @@ -75,6 +75,10 @@ protected function setUp() {
       public function testGetArguments() {
    +
    +    if (!in_array('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface', class_implements('Symfony\Component\HttpKernel\Controller\ControllerResolver'))) {
    

    Nit: extraneous \n.

  2. +++ b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
    @@ -240,12 +246,14 @@ public function testGetArgumentsWithRouteMatchAndRequest() {
    +    if (!in_array('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface', class_implements('Symfony\Component\HttpKernel\Controller\ControllerResolver'))) {
    

    Why not use ::class?

  3. +++ b/core/tests/Drupal/Tests/Core/Controller/FormControllerTest.php
    @@ -20,6 +20,10 @@ class FormControllerTest extends UnitTestCase {
    +    if (!in_array('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface',                                                                       class_implements('Symfony\Component\HttpKernel\Controller\ControllerResolver'))) {
    

    This looks like invalid PHP. Yet … it did pass tests. WTF? 😱

wim leers’s picture

StatusFileSize
new33.71 KB

This looks like invalid PHP. Yet … it did pass tests. WTF? 😱

Apparently that's dreditor screwing this up. First time that ever happened to me.

catch’s picture

Why not use ::class?

Neither of these classes are used anywhere else in the file, so we'd be importing them at the top (using the fully qualified class name as you do in a use statement), then here using the namespaced version... to get the FQCN again via ::class, which seems like a lot of indirection compared to using the string.

wim leers’s picture

Component: asset library system » base system
Status: Needs review » Reviewed & tested by the community

Fair! LGTM then :) Trivial test-only changes, really.

#17.1 can be fixed on commit (or not at all, it's super nitpicky).

I don't think asset library system is the right component though.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

All the tests being changed here are already legacy tests so this looks great to me.

Committed 8b6fd65 and pushed to 8.7.x. Thanks!

Fixed the unnecessary new line on commit.

Also fixed

PHPCS: core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php passed

FILE: ...l/core/tests/Drupal/Tests/Core/Controller/FormControllerTest.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 1 LINE
----------------------------------------------------------------------
 23 | ERROR | [x] Expected 1 space after comma in function call; 71
    |       |     found
 23 | ERROR | [x] Expected one space after the comma, 71 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Time: 46ms; Memory: 4Mb

PHPCS: core/tests/Drupal/Tests/Core/Menu/LocalActionManagerTest.php passed

FILE: ...rupal/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 1 LINE
----------------------------------------------------------------------
 254 | ERROR | [x] Expected 1 space after comma in function call; 71
     |       |     found
 254 | ERROR | [x] Expected one space after the comma, 71 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

I guess these were the cause of the dreditor weirdness :)

  • alexpott committed 8b6fd65 on 8.7.x
    Issue #3020536 by catch, sjerdo, Wim Leers, alexpott: ControllerResolver...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

xjm’s picture

Issue tags: +Symfony 4