Updated: Comment #N

Problem/Motivation

Entity type annotations use a path based "links template" for the Entity::uri() method.
This is problematic because it means the paths are hardcoded in various parts of core, which will break when someone tries to alter a route's path.

This is part of a larger effort to only have paths defined in code in the *.routing.yml files or in a RouteSubscriber class.

Proposed resolution

Instead of specifying paths with placeholders like /node/{node}, change the entity type links to hold route names like node.view

Remaining tasks

N/A

User interface changes

N/A

API changes

Entity type links are now route names.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett’s picture

Status: Active » Needs review
FileSize
16.59 KB
tim.plunkett’s picture

FileSize
17.94 KB

Whoops, missed the hook_entity_info() ones.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
1.35 KB

And the interdiff

Status: Needs review » Needs work

The last submitted patch, 2: entity-2133469-2.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
Issue tags: +D8MI
FileSize
24.57 KB
4.72 KB

content_translation_entity_info_alter is still just appending /translations to the canonincal path.

In #1810350: Remove menu_* entity keys and replace them with entity links it was moved out of ContentTranslationRouteSubscriber, but that's almost worse...

I think I fixed the other cases.

damiankloip’s picture

What's the change to the hal normalizer base test class about?

tim.plunkett’s picture

Well I could have just changed NormalizeTest, DenormalizeTest was fine, but DUTB cannot handle routes properly AFAIK. I had to make the same change to FieldRdfaTestBase

Status: Needs review » Needs work

The last submitted patch, 5: entity-2133469-3.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
22.58 KB
3.43 KB

Hmm, can't we just revert those changes to WebTestBase and add the router schema to the DUTB tests? I think that should work, let's try.

Interdiff includes reverting changes in those tests from the last patch and the changes needed.

EDIT:

+++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
@@ -58,6 +58,10 @@
+    $this->installSchema('system', array('variable', 'url_alias', 'router')); << Just 'router'.

+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php
@@ -43,7 +43,16 @@
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->installSchema('system', array('router'));
+  }

For ease, this is all that I added to those tests after the code reverts.

Gábor Hojtsy’s picture

Status: Needs review » Needs work

Great patch!

+++ b/core/modules/content_translation/content_translation.module
@@ -91,6 +91,7 @@ function content_translation_entity_info_alter(array &$entity_info) {
       if (!empty($info['links']['canonical'])) {
         // Provide default links for the translation paths.
+        // @todo NOPE NOPE NOPE NOPE NOPE.
         $info['links'] += array(
           'drupal:content-translation-overview' => $info['links']['canonical'] . '/translations',

Sounds like this would need to be fixed in this patch too? I believe the content translation module has derivative routes based on entity routes, so this can be placed here these. The routes are 'content_translation.translation_overview_' . $entity_type.

It is true they are created based on this path provided here, but I think the path automation can just as well be moved to the route subscriber, those needing to alter that can alter the routes. AFAIS that should be very rare. That means this can go away from the info hook.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
26.34 KB
4.48 KB

Could we do something like this? Genuine question.

Status: Needs review » Needs work

The last submitted patch, 11: 2133469-11.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
34.31 KB
10.05 KB

The config_test fail was because the test assumes there is a valid translation permission when there is not.
The rest was just cleaning up the places that check for these link templates.

Status: Needs review » Needs work

The last submitted patch, 13: route-2133469-13.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
20.37 KB
46.82 KB

The PHPUnit tests weren't updated.
To do so, I needed to move content_translation_supported() to a service.

Status: Needs review » Needs work

The last submitted patch, 15: route-2133469-15.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
47.13 KB
1.36 KB

We need to also check the collections being processed, not just the pre-existing one.

Gábor Hojtsy’s picture

tim.plunkett’s picture

Now that we have a passing patch, I went back through and cleaned up some.

There are changes to content_translation that ideally wouldn't be included here, but they could not happen without this issue, and it is necessary for them to be included here. Sorry for the seeming scope-creep.

tim.plunkett’s picture

Issue tags: +WSCCI, +MenuSystemRevamp
FileSize
50.47 KB
5.17 KB

d.o ate my patches and tags

dawehner’s picture

  1. index 0171dd5..604bf5d 100644
    --- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
    
    --- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
    +++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
    
    +++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
    @@ -267,9 +267,7 @@ class EntityType extends Plugin {
    
    @@ -267,9 +267,7 @@ class EntityType extends Plugin {
        *
    

    The documentation of EntityType.$links has to be changed as well.

  2. +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
    @@ -38,8 +38,8 @@
    - *     "canonical" = "/block/{custom_block}",
    - *     "edit-form" = "/block/{custom_block}"
    + *     "canonical" = "custom_block.edit",
    + *     "edit-form" = "custom_block.edit"
    

    <3

  3. +++ b/core/modules/content_translation/content_translation.module
    @@ -162,7 +156,7 @@ function content_translation_menu() {
    -      $keys = array_flip(array('theme_callback', 'theme_arguments', 'access_callback', 'access_arguments', 'load_arguments'));
    +      $keys = array_flip(array('theme_callback', 'theme_arguments', 'load_arguments'));
    

    Wait: we do remove access_callback but keep it above? I would like to understand that.

  4. +++ b/core/modules/content_translation/content_translation.services.yml
    @@ -5,9 +5,9 @@ services:
    -      - { name: event_subscriber }
    +      - { name: event_subscriber, priority: -100 }
    

    What is the reason to make an event subscriber have a different priority? The priority of it will be handled in the actual getSubscribers method anyway.

  5. +++ b/core/modules/content_translation/content_translation.services.yml
    @@ -20,3 +20,7 @@ services:
    +    arguments: ['@plugin.manager.entity']
    

    ... this should be @entity.manager

  6. +++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationManager.php
    @@ -0,0 +1,54 @@
    +
    +class ContentTranslationManager implements ContentTranslationManagerInterface {
    

    What is the responsibility of this class?

  7. +++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationManager.php
    @@ -0,0 +1,54 @@
    +  public function isSupported($entity_type, $info = NULL) {
    

    I wonder myself about the usecase to specify the $info manually. I haven't looked core though, yet.

  8. +++ b/core/modules/content_translation/lib/Drupal/content_translation/Plugin/Derivative/ContentTranslationLocalTasks.php
    @@ -91,20 +76,15 @@ public function getDerivativeDefinitions(array $base_plugin_definition) {
    -        if ($routes = $this->routeProvider->getRoutesByPattern($path)->all()) {
    

    I really really love this line!

  9. +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php
    @@ -7,10 +7,19 @@
    -class EntityUriTest extends EntityUnitTestBase {
    +class EntityUriTest extends WebTestBase {
    

    What is the reason for this change? Doesn't this causes a big slow down for the test?

tim.plunkett’s picture

FileSize
50.74 KB
6.6 KB

Addressed the other points:

3) Left access_callback in for this in \Drupal\content_translation\Access\ContentTranslationOverviewAccess

      $access_callback = $definitions[$entity_type]['translation']['content_translation']['access_callback'];
      if (call_user_func($access_callback, $entity)) {
        return static::ALLOW;
      }

4) I can remove this, but @damiankloip added it, and I'm not sure what might break.

7) I'm removing this, its too confusing to be useful.

9) This is just leftover from me working through failures.

damiankloip’s picture

Yeah sorry, I think that may be able to go. Not sure? I originally added it so this ran after any other subscribers.

damiankloip’s picture

+++ b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
@@ -18,124 +20,144 @@
+      // First try to get the route from the current collection.

Nitpick: I think this comment should state this is basically to cover routes added in the dynamic_routes set.

Otherwise, I think this is looookin' good.

tim.plunkett’s picture

FileSize
51.03 KB
1.79 KB

@damiankloip pointed out that the priority is to help ensure this runs last, similar to content_translation having a higher module weight.

Also fixed the comment, good point.

damiankloip’s picture

Yeah, similar to why you had to add the fix to try and find the route from the current collection I guess. If its last we should always be able to find any dynamic route.

dawehner’s picture

FileSize
51.18 KB
1.16 KB

The priority is not controlled on the services level.

damiankloip’s picture

+++ b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
@@ -161,4 +162,13 @@ protected function routes(RouteCollection $collection) {
+    $events[RoutingEvents::ALTER] = array('onAlterRoutes', -100);

We are using routes(), so onDynamicRoutes and not alter ?

tim.plunkett’s picture

FileSize
51.13 KB
1.53 KB

Right change, wrong event. Also removing the useless one from the services.yml.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

You wanted to say: good will, but just horrible execution.

damiankloip’s picture

Yeah, right idea. Wrong implementation there :-) same goes for the priority too!

This is looking good now.

tim.plunkett’s picture

Issue summary: View changes
alexpott’s picture

Title: Replace path-based entity links with route names » Change notice: Replace path-based entity links with route names
Status: Reviewed & tested by the community » Active
Issue tags: +Needs change record

Committed 7b8e204 and pushed to 8.x. Thanks!

Xano’s picture

For more PHPUnit coverage of this change in the entity API, see #2134857: PHPUnit test the entity base classes.

Crell’s picture

Crell’s picture

This is potentially quite problematic. We *need* the canonical relationship there. Also, we added those link patterns originally for REST module, so that we could *generate* the routes off of the links. That is, the whole point was the other way around from what this issue just did. See #2019123: Use the same canonical URI paths as for HTML routes There's been on and off discussion of generating the HTML route off of the defined URI, too.

Really, I think this issue is a regression. :-(

tim.plunkett’s picture

This patch did two things at once.
It switched the "links" part of the Entity annotation to be a route name instead of a path, and it fixed up the content_translation entity routes part.

Crell is only taking issue with the annotation part, please do not roll back the content_translation hunks at the same time.

Crell’s picture

Title: Change notice: Replace path-based entity links with route names » Switch back to URI templates in entity annotations
Priority: Major » Critical
Issue tags: -Needs change record +beta blocker

We discussed this issue at length in today's WSCCI meeting. The resolution:

* We need a new patch on this issue to roll back the switch from URI templates to routes in the entity annotations. Entity annotations must be URIs.
* We cannot just revert this patch as is, as it also fixed various translation issues.
* Once that's done, we will move the HTML route generation to be dynamic, just like the non-HTML routes. This has some implementation details we did not fully finish fleshing out, but that's a topic for a new issue.

So the action item here is: We need a patch to switch back to URI template routes, but not break the translation work here. Volunteers?

Because this is an API change, and we have 2 other issues blocked hard until this is done, I am bumping the priority.

damiankloip’s picture

We seriously need to stop renaming and repurposing the same issues...

catch’s picture

Yes please close this issue and open a new one, it's incredibly confusing restarting issues, messes up git blame and all kinds of other problems.

dawehner’s picture

tim.plunkett’s picture

Title: Switch back to URI templates in entity annotations » Change notice: Replace path-based entity links with route names
effulgentsia’s picture

Priority: Critical » Major
Issue tags: -beta blocker +Needs change record
Crell’s picture

We don't need a change notice here if we're about to undo it, do we?

klausi’s picture

Title: Change notice: Replace path-based entity links with route names » Replace path-based entity links with route names
Status: Active » Closed (fixed)
Issue tags: -Needs change record

I agree, no change notice needed here since we should roll this back in #2150747: Switch back to URI templates in entity annotations.