[regression] toUrl can incorrectly return edit-form url when another link template shares the canonical url

Created on 20 December 2023, 2 months ago
Updated 20 February 2024, 12 days ago


After upgrading to Drupal 10.2, one of our tests was failing that asserted that visiting the canonical route of an entity returned the latest revision. That's because we have the following link templates in the entity definition

 *     "canonical" = "/admin/content/location/{location}",
 *     "latest-version" = "/admin/content/location/{location}",

This worked perfectly fine in 10.1. However, since πŸ“Œ Fall back to 'edit-form' as default $rel in EntityBase::toUrl() Fixed this behaviour has changed. Most importantly, the issue is with the array_flip. Link templates don't have to have unique url patterns, flipping the above example deletes the canonical route because of the duplicate keys, therefore the new fallback logic in EntityBase::toUrl uses the edit-form link template.

Steps to reproduce

Install Drupal 10.2
Create an entity type with 2 link templates with the same url template and an edit-form template
Call toUrl with no parameters
Notice you get the edit-form url, not the canonical one.

Proposed resolution

Dont use array_flip

Remaining tasks


πŸ› Bug report



11.0 πŸ”₯

BaseΒ  β†’

Last updated 1 minute ago

Created by

πŸ‡¦πŸ‡ΊAustralia acbramley

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @acbramley
  • Status changed to Needs review 2 months ago
  • πŸ‡¦πŸ‡ΊAustralia acbramley

    So swapping to intersecting by key works, although it still feels a bit icky to me. It would be nice to have a triple null coalescing but I don't think that's possible.

  • Status changed to Needs work 2 months ago
  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    Added a simpler suggestion.

  • πŸ‡¨πŸ‡­Switzerland Berdir Switzerland

    media uses that for canonical/edit as well FWIW.

    latest and canonical on the same is a bit weird though I think, what does that even mean? You can't access the default revision anymore if there's a draft? what happens if you don't have access to view that?

  • Status changed to Needs review 2 months ago
  • πŸ‡¦πŸ‡ΊAustralia acbramley

    latest and canonical on the same is a bit weird though I think, what does that even mean?

    True it's weird, but for this particular entity type that's how we wanted it. It means the View route shows the latest revision. Revision access isn't an issue in this scenario and you can access the default revision via the revision view route :)

  • Status changed to RTBC 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave
    1) Drupal\Tests\Core\Entity\EntityUrlTest::testToUrlDefaultFallback
    Failed asserting that two strings are equal.
    --- Expected
    +++ Actual
    @@ @@
    Tests: 22, Assertions: 98, Failures: 1.

    Additional test coverage seems to be there.

    Change makes sense and know from the block_content module uses the same as media. Working on adding that setting to use standalone URLs too, but a separate issue.

    • catch β†’ committed 9231c9cf on 11.x
      Issue #3409895 by acbramley, longwave, smustgrave: [regression] toUrl...
    • catch β†’ committed 554598a5 on 10.2.x
      Issue #3409895 by acbramley, longwave, smustgrave: [regression] toUrl...
  • Status changed to Fixed 19 days ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    This seems reasonable. Committed/pushed to 11.x and cherry-picked to 10.2.x, thanks!

  • πŸ‡©πŸ‡ͺGermany tstoeckler Essen, Germany

    Wow, just saw this. Sorry for introducing this! I can only speculate as to what lead to me use that indirection, but absolutely agreed that it's much more readable now, thanks! And this will (hopefully) teach me to more carefully consider the consequences of array_flip() in the future. In any case, great to see this fixed, thanks again!

Production build https://api.contrib.social 0.61.6-2-g546bc20