drupal-console icon indicating copy to clipboard operation
drupal-console copied to clipboard

[generate:entity:content] Adding 'collection' to links in annotation causes menu items to be deleted!

Open Sut3kh opened this issue 8 years ago • 6 comments

Problem/Motivation

As of 8.4, when an entity is deleted, menu_link_content_entity_predelete() loops all uri relationships and checks for menu items that match. If a match is found then it automagically deletes the menu item.

As generate:entity:content adds i.e. "collection" = "/admin/structure/myentity", to links in the annotation, this ends up causing any menu items pointed to the collection to be deleted when any entity of that type is deleted! I thought I was going mad at first...

How to reproduce

  • Drupal version: 8.4.2
  • Console version: 1.0.2
  • Create an entity named 'myentity' using drupal generate:entity:content
  • Add a menu link pointed at the collection (i.e. /admin/structure/myentity) to any menu
  • Create a 'myentity' entity
  • Delete the new entity

The menu item has been deleted.

Solution

Do not add 'collection' to links in the entity annotation but add the collection to the routing.yml as per the user module i.e.

entity.user.collection:
  path: '/admin/people'
  defaults:
    _entity_list: 'user'
    _title: 'People'
  requirements:
    _permission: 'administer users'

Possibly also/instead report bug on drupal.org? I do not have the knowledge to say whether this is being used as intended or not, all I know is that I cannot find any core entities doing it via the annotation like this.

Sut3kh avatar Nov 10 '17 16:11 Sut3kh

The presence of collection in the link templates is not the problem per se here - this is also done by core (see Drupal\taxonomy\Entity\Vocabulary for an example). The routing.yml definition is not a replacement for this link template on its own - if you only define the route, $entity->toUrl('collection') will not work.

However, Drupal Console generated entities do differ from core in that entity routes are built by a provider class directly from the annotation's link templates and handlers, rather than being defined statically in routing.yml.

~~This might trigger some hidden bug that core avoids with static definitions. Investigation is needed there.~~ (Update: Nope, this is a non-hidden core bug; it affects user entities as well - which are the only content entities that have a collection link template in core.)

Edit: Actually, unlike most config entities, Node and Term don't have collection link templates in the annotation (but they also don't have that link template, period - \Drupal\node\Entity\Node::load(1)->toUrl('collection') does not work). User does, so there is at least one content entity.

cburschka-pwc avatar Nov 28 '17 14:11 cburschka-pwc

I can confirm that some bad stuff is happening (in the current version, 1.2.0).

  1. Create a new module and a content entity type, leave all default options.
  2. Create a new menu item that links to /admin/structure/... (the collection link).
  3. Create a new content entity and delete it.

Result:

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Drupal\Core\Entity\EntityStorageException</em>: Some mandatory parameters are missing (&quot;content_x_revision&quot;) to generate a URL for route &quot;entity.content_x.revision_revert&quot;. in <em class="placeholder">Drupal\Core\Entity\Sql\SqlContentEntityStorage-&gt;delete()</em> (line <em class="placeholder">753</em> of <em class="placeholder">core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php</em>). <pre class="backtrace">Drupal\Core\Routing\UrlGenerator-&gt;getInternalPathFromRoute(&#039;entity.content_x.revision_revert&#039;, Object, Array, Array) (Line: 293)
Drupal\Core\Routing\UrlGenerator-&gt;generateFromRoute(&#039;entity.content_x.revision_revert&#039;, Array, Array, 1) (Line: 105)
Drupal\Core\Render\MetadataBubblingUrlGenerator-&gt;generateFromRoute(&#039;entity.content_x.revision_revert&#039;, Array, Array, 1) (Line: 753)
Drupal\Core\Url-&gt;toString(1) (Line: 333)
Drupal\Core\Entity\Entity-&gt;Drupal\Core\Entity\{closure}(&#039;revision_revert&#039;)
array_filter(Array, Object) (Line: 339)
Drupal\Core\Entity\Entity-&gt;uriRelationships() (Line: 92)
menu_link_content_entity_predelete(Object)

cburschka-pwc avatar Nov 28 '17 15:11 cburschka-pwc

The problem I encountered seems to be specific to revisionable content entities (note the "revision_revert"), and in fact actively prevents deleting any entities which have a revision_revert or revision_delete link template, whether or not a custom menu link was created. (The translation_revert and revision templates, interestingly, do not cause a problem even though they also use the revision route parameter.)

Reproduce:

  1. Create module and content entity type (default options).
  2. Create entity
  3. Try to delete entity.
  4. Remove revision_* link templates from annotation, clear cache.
  5. Delete entity successfully.

Edit: This particular bug has already been reported, see https://www.drupal.org/project/drupal/issues/2924338

cburschka-pwc avatar Nov 28 '17 17:11 cburschka-pwc

I can also confirm the problem @Sut3kh encountered, but it is not limited to Drupal Console content entities.

  1. Create a menu link to /admin/people.
  2. Create a user account.
  3. Delete (not disable) the user account.
  4. Custom menu link is gone.

This is a core bug.

Edit: Also confirmed that it's a regression in 8.4, and doesn't happen in 8.3.7.

Edit2: Introduced by https://drupal.org/node/2350797

cburschka-pwc avatar Nov 28 '17 17:11 cburschka-pwc

Follow-up: I filed the bug report at https://www.drupal.org/node/2926897

cburschka-pwc avatar Nov 28 '17 18:11 cburschka-pwc

This command will have a refactor for Drupal Console 2.0

hjuarez20 avatar Aug 05 '19 20:08 hjuarez20