Problem/Motivation

This is a followup to #2651716: Entity::getEntityFromRouteMatch() should support bundles, which added partial support for bundle-based entity routes : it only supports them when the bundle is part of the route path, but not when it is a constant parameter, because it only checks using $route_match->getRawParameter() instead of $route_match->getParameter().

Using $route_match->getRawParameter() is needed because some parameters are likely to be upcasted, but to support route-defined (vs request-defined) parameter values, a pair of extra calls to $route_match->getParameter() appears to be required.

Steps to reproduce

TBD

Proposed resolution

TBD

Remaining tasks

Update issue summary
Code review

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

NA

Comments

fgm created an issue. See original summary.

fgm’s picture

Title: getEntityFromRouteMatch does not support route-level parameters » EntityForm::getEntityFromRouteMatch() does not support route-level parameters
Status: Active » Needs review
StatusFileSize
new1.14 KB

Testing initial simple patch to see where it goes. It fixes my current use case, but likely needs work.

fgm’s picture

fgm’s picture

tstoeckler’s picture

So, are you talking about what you could get from $route->getDefault($bundle_key) ? If so, could we do elseif ($bundle = $route_match->getRouteObject()->getDefault($bundle_key))? I personally would find that a bit more intuitive.

fgm’s picture

Indeed, that works just as well in my case (just tested). I used getParameter() instead of going through the route object because it was more direct (just a call to the underlying attributes bag), but I have no specific reason to use one or the other.

tstoeckler’s picture

So what I was intending to say before, but I kind of forgot, was whether we can maybe drop the rather verbose if-check if we go through the route object? If so, that would be a reason to do it IMHO. If we still have to do the same checks then I would agree with #6 that the parameter bag is preferable, but I think it shouldn't be necessary.

fgm’s picture

The problem AIUI is that these values can be arrays or objects if the route was configured that way, whether one uses the route object or the parameter bag: this is probably an error, though: I don't think I've seen any example with non-scalar arguments in the route definition. I could not find any description of restrictions regarding the parameters, hence these checks.

tstoeckler’s picture

So you're basically saying that this could happen:

entity.my_entity.add_form:
  path: /foo/bar/baz
  defaults:
    _entity_form: my_entity.add
    my_entity_bundle:
      not_sure: why_this
      is_an: array

?

Yeah, not sure we should support that TBH. We already check if the entity has bundles in the first place and if it does and you want to fetch the bundle in some way without a route parameter, only then does that mean that you can't also have a route default that happens to be named like the entity type ID of your bundle entity type.

fgm’s picture

Exactly so. At some point, we had a policy of "not babysitting broken code", and indeed in most cases d8 core does not try to catch errors caused by ill-advised code (like the example in #9), so maybe we can just skip this test : since the data does not come from the user but from the module (unlike rawParameters), there should not be a need for sanitizing these data.

I think that this remains true whether using the data from getParameter() or the route object. In that case, getParameter() seems a possibly more natural choice, relying on the "result" of route matching instead of manipulating the route ourselves.

Rerolled patch without the sanitization. Also, I did not include it to keep the patch minimal, but I think it would be nice to use the same $parameter = (...) ; $values[$bundle_key] = $parameter (or $parameter->id() in the first case) for the first two cases too.

tstoeckler’s picture

Also, I did not include it to keep the patch minimal, but I think it would be nice to use the same $parameter = (...) ; $values[$bundle_key] = $parameter (or $parameter->id() in the first case) for the first two cases too.

Note that the other two cases use getRawParameter() in the if-check and then use getParameter() in the "actual" code. I'm not sure why that is off the top of my head, but what you suggest would change that.

         elseif ($route_match->getRawParameter($bundle_key)) {
           $values[$bundle_key] = $route_match->getParameter($bundle_key);
         }
+        elseif ($parameter = $route_match->getParameter($bundle_key)) {
+          $values[$bundle_key] = $parameter;
+        }

This is also related to the above, but if we leave it this way (and if it actually works as intended) we need to document the usage of getParameter() in the "actual" code and then only later in the if-check. That's not at all self-documenting.

fgm’s picture

Right, so it's probably for the better not to add that change.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
tim bozeman’s picture

Nice! This is really close to fixing another use case too.

How about a route like this? Where there is no slug, but a default is provided.

my.node.add:  
  path: '/my/node/add/page'  
  host: ''  
  defaults:  
    node_type: 'page'  
    _entity_form: 'node.default'  
    _title_callback: '\Drupal\node\Controller\NodeController::addPageTitle'  
  requirements:  
    _entity_create_access: 'node:{node_type}'  
  options:  
    parameters:  
      node_type:  
        type: entity:node_type

Calling getParameter($bundle_entity_type_id) works swimmingly. The description says that we are calling getRawParameter() in case the parameter is upcasted, but I think we can check if we have an entity and get the ID and support both uses.

Oh, btw I think you'll need the patch from #3277784-2: copyRawVariables should support default route parameters too for that route to load.

Status: Needs review » Needs work

The last submitted patch, 22: 2743303-22-entity-form-route-parameters.patch, failed testing. View results

tim bozeman’s picture

Status: Needs work » Needs review
StatusFileSize
new610 bytes
new1.49 KB

Whoops, forgot to define $bundle. 🤦🏻‍♂️

fgm’s picture

Good improvements. I think you now need to add a couple tests for these changes, though.

tim bozeman’s picture

StatusFileSize
new0 bytes

hmm, on closer look, aside from this issue entirely, the existing test doesn't seem to be covering the code we are talking about.

The part of EntityForm->getEntityFromRouteMatch() inside of if ($bundle_key = $entity_type->getKey('bundle') ) isn't being tested because $bundle_key is empty.

Here is a tweak to get EntityFormTest to test that bundles from route part.

tim bozeman’s picture

StatusFileSize
new687 bytes

Whoops, forgot the patch. 🤦🏻‍♂️

tim bozeman’s picture

StatusFileSize
new1.46 KB
new2.96 KB

Here is testing a route like the example above where the bundle is resolved from a default route parameter via getParameters().

The last submitted patch, 28: test-only.patch, failed testing. View results

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

tim bozeman’s picture

StatusFileSize
new645 bytes
new3.18 KB

This one too!

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs issue summary update

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

This could use an issue summary update. I started it but will need someone more familiar with the issue to fill the rest in.

Thanks.

tim bozeman’s picture

Status: Needs work » Closed (outdated)