Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ generate:entity:content ] 500 Error when deleting a revisionable entity generated by drupal console on Drupal 8.4 #3556

Closed
fmfpereira opened this issue Oct 26, 2017 · 9 comments

Comments

@fmfpereira
Copy link

fmfpereira commented Oct 26, 2017

Problem/Motivation

After Drupal update to 8.4, when trying to delete a revisionable entity created by drupal console the following exception is thrown:
"Drupal\Core\Entity\EntityStorageException: Some mandatory parameters are missing ("console_entity_test_revision") to generate a URL for route "entity.console_entity_test.revision_revert". in Drupal\Core\Entity\Sql\SqlContentEntityStorage->delete() (line 753 of /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php)"

Details to include:

  • This issue is related with the following commit and the following issue
  • It appears that all the Entity annotation links are being generated on the fly, but the revision links must have the revision_id context that does not exist on the delete route.

How to reproduce

  • Generate an Content Entity [generate:entity:content]
  • Answer 'yes' to the ' Is your entity translatable (yes/no) [yes]' question.
  • Add a new "Entity name"
  • Delete the Entity

Details to include:

  • Drupal version: 8.4.0
  • Console version: 1.0.2
  • Console Launcher version: 1.0.2

Solution

Method urlRouteParameters on Entity Class is setting the default revision ID for the link relationship type revision.

  protected function urlRouteParameters($rel) {
    $uri_route_parameters = [];

    if (!in_array($rel, ['collection', 'add-page', 'add-form'], TRUE)) {
      // The entity ID is needed as a route parameter.
      $uri_route_parameters[$this->getEntityTypeId()] = $this->id();
    }
    if ($rel === 'add-form' && ($this->getEntityType()->hasKey('bundle'))) {
      $parameter_name = $this->getEntityType()->getBundleEntityType() ?: $this->getEntityType()->getKey('bundle');
      $uri_route_parameters[$parameter_name] = $this->bundle();
    }
    if ($rel === 'revision' && $this instanceof RevisionableInterface) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }

    return $uri_route_parameters;
  }

One possible solution is to override the method and do the same for the revision_revert and revision_delete links.

  protected function urlRouteParameters($rel) {
    $uri_route_parameters = parent::urlRouteParameters($rel);
    if ($rel === 'revision_revert' && $this instanceof RevisionableInterface) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }
    elseif ($rel === 'revision_delete' && $this instanceof RevisionableInterface) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }
    return $uri_route_parameters;
  }

Update

According to @thuben comment, in some cases the previous code does not work with bundled entities. So he proposes to implement the previous code checking if the entity is an instance of RevisionableContentEntityBase (it works in any cases [with or without bundles] ).

  protected function urlRouteParameters($rel) {
    $uri_route_parameters = parent::urlRouteParameters($rel);
    if ($rel === 'revision_revert' && $this instanceof RevisionableContentEntityBase) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }
    elseif ($rel === 'revision_delete' && $this instanceof RevisionableContentEntityBase) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }
    return $uri_route_parameters;
  }

@janstoeckler
Copy link
Contributor

Can confirm fmfpereira's solutions works, thanks!

@thuben
Copy link

thuben commented Oct 31, 2017

I have almost the same setup but I am using Bundles as well. In this case the

if ($rel === 'revision_revert' && $this instanceof RevisionableInterface) {

(two times) doesn't work. Instead I need the following:

if ($rel === 'revision_revert' && $this instanceof RevisionableContentEntityBase) {

Thanks for finding this fmfpereira!

@fmfpereira
Copy link
Author

@thuben You're right, i did not try with bundles. Thanks also for finding this.

@recidive
Copy link

Works.

@syammohanmp
Copy link

Works Great !!!. Thank you @fmfpereira and @thuben .

@Artusamak
Copy link
Contributor

I can confirm that it works with bundles with the suggested fix.
Thanks.

@Niklan
Copy link

Niklan commented Dec 15, 2017

Confirm, works for mee too!

@csegarra
Copy link
Contributor

The solution works for me too, also with bundles.

It's not necesary to match the instance with RevisionableContentEntityBase class, as proposed by @thuben.

In the original code from @fmfpereira an use statement is missing:

use Drupal\Core\Entity\RevisionableInterface;

@jasonawant
Copy link

I was still experiencing an issue when trying to delete an revisionable entity even with this change. This patch solved the error https://www.drupal.org/project/drupal/issues/2924338

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants