Problem/Motivation

Upcasting of route named Views parameters does not work. For instance, I'm expecting that a %user Views argument, which is set to validate as a valid user entity, will be upcasted to a user entity object. Running the following code should pass:

$account = \Drupal::routeMatch()->getParameter('user');
assert($account instanceof \Drupal\user\UserInterface);

Instead, the route matcher is still returning the raw argument as user ID.

Proposed resolution

Allow named parameters upcating to entities. Use the argument validation plugin to determine if a named parameter can be upcasted to its entity object.

Remaining tasks

None.

User interface changes

None.

API changes

Named Views arguments, validating as entities, are now upcasted as entity objects.

Data model changes

None.

Release notes snippet

If a named Views argument is validated as an entity then it will upcast as entity object.

Issue fork drupal-2528166

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

webflo’s picture

Status: Needs review » Needs work

The last submitted patch, views-named-argument-upcast.patch, failed testing.

dawehner’s picture

+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -168,6 +169,7 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
         $bits[$pos] = '{' . $parameter_name . '}';
+        $parameters[$parameter_name]['type'] = 'entity:' . $parameter_name;
       }

yeah that is not really enough, I mean, this will try to upcast things which aren't necessarily entities.

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

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.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.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.

webflo’s picture

StatusFileSize
new2.27 KB

I think we can use the argument validation plugin to find the proper entity type.

webflo’s picture

Version: 8.2.x-dev » 8.3.x-dev
Status: Needs work » Needs review
dawehner’s picture

As written in IRC I'm wondering whether it would be a good idea to have some flag, hidden from the UI maybe even, to enable that kind of behaviour.

Status: Needs review » Needs work

The last submitted patch, 6: 2528166-6.patch, failed testing.

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

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now 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.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now 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.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now 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.

branana’s picture

StatusFileSize
new2.26 KB

Modified the patch from #6 so that it would apply to 8.5.

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

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.

hanoii’s picture

This helped using %user as a named argument and a contextual filter with "User ID from route context".

I am not sure why tests are failing, seems unrelated. Might try to look.

I would ask though, why %user didn't work with this patch. In regular routes on yaml you only need to provide a type hint in case you don't use one of the known named parameters. And as such, I would have expected that %user worked regardless.

hanoii’s picture

Title: Upcast named arguments in views » Upcast named arguments/named parameters in views
hanoii’s picture

Taxonomy edit page is broken, gives fatal error. I guess that's why tests were failing.

hanoii’s picture

Status: Needs work » Needs review
StatusFileSize
new2.31 KB

Not setting an empty parameters when there's none helps with the fatal issue, likely because taxonomy/term/% is a view.

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

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.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.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). 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.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now 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.

jonathan_hunt’s picture

@hanoii The patch in #18 applies for me on 8.8.5, thanks.

dww’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Interesting issue / patch.

  1. --- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
    +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
    

    For this to be RTBC, it'll need test coverage for changes to this class.

  2. +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
    @@ -159,11 +160,18 @@ protected function getRoute($view_id, $display_id) {
    +        if (isset($arguments[$argument_position]['specify_validation']) && $arguments[$argument_position]['specify_validation'] == TRUE) {
    

    !empty() instead?

  3. +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
    @@ -159,11 +160,18 @@ protected function getRoute($view_id, $display_id) {
    +          if (count($validation_plugin) == 2 && $validation_plugin[0] == 'entity') {
    

    s/==/===/

Thanks,
-Derek

dpi’s picture

pavnish’s picture

Assigned: Unassigned » pavnish

@dww i am working on it.

pavnish’s picture

I am unable to apply the patch #18 on 9.1.x need to re-roll for 9.1.x

pavnish’s picture

Assigned: pavnish » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.37 KB

@dww I have created a new patch for this i was unable to apply this patch on 9.1 and 9.0
For #23
#23.1: The test case already exist and run successfully
PHPUnit 8.5.4 by Sebastian Bergmann and contributors.

Testing Drupal\Tests\views\Unit\Plugin\display\PathPluginBaseTest
.............. 14 / 14 (100%)

Time: 309 ms, Memory: 12.00 MB

OK (14 tests, 94 assertions)
#23.2: Changes has been done
#23.3: Changes has been done

Please review

dww’s picture

Status: Needs review » Needs work

Thanks for the updates, @pavnish!

1. Please provide an interdiff with a new patch to make it easier to see what you changed.

2. Thanks for finding Drupal\Tests\views\Unit\Plugin\display\PathPluginBaseTest -- however, that class has no coverage of this bug report, or we wouldn't have the bug in the first place. ;) The point is, we need to expand that test to cover the behavioral changes introduced with this patch. That's why I added the 'Needs tests' tag -- we need to test *this* bug, not just have any test coverage at all of the class where the bug fix is happening.

3. The best practice is to make such changes to the test, and upload a patch that only includes the changes to the test, without the underlying bug fix. You can call this patch something like "2528166-{comment_number}.test-only.patch". Upload that first, then upload the full patch with both the test changes and the fix. The test-only should fail, and it should fail in a way that makes sense to reveal the bug. Then the full patch should pass all tests (old and new/changed). That way, the core committers can review the test-only to see what it takes to trigger the bug, verify that the test is legitimate, and then see that the new test coverage passes once the fix is applied. This helps verify the bug fix is correct, and ensures we won't re-break the bug with future changes to core.

Thanks!
-Derek

dww’s picture

p.s. For extra credit (more quickly see the failed test results, save pointless bot cycles, save the DA $$), your test-only patch can include changes to core/drupalci.yml to tell the bot to only run the new/changed test(s). For a recent example, see https://www.drupal.org/files/issues/2020-05-17/3136668-27.orphaned-and-p... from #3136668-27: Invalid system.schema key_value entry causes fatal on updating to 8.8.5

Enjoy,
-Derek

dww’s picture

p.p.s. Upon closer read, that's maybe not the most clear example, since it included *some* of the proposed fix. ;) This is a cleaner example:

#2830326-32: Broken link to 'Put your site into maintenance mode' on update.php results in WSOD
https://www.drupal.org/files/issues/2020-05-15/2830326-32.8_8_x.test-onl...

pavnish’s picture

Assigned: Unassigned » pavnish
pavnish’s picture

Assigned: pavnish » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.3 KB
new1.08 KB

@dww
RE #28.1 interdiff added
RE ##28.2 Need help.

pavnish’s picture

Need work on #28.2 #28.3

pavnish’s picture

Status: Needs review » Needs work
dww’s picture

@pavnish: Thanks. The point of #23.2 is that empty() checks for existence and truth in 1 call. So you can replace all of:

if (isset($a['b']) and $a['b'] == TRUE)) {

with:

if (!empty($a['b'])) {

Re: #28.2: Yeah, to write good test coverage for this, you need to understand what "upcast named arguments" means, and what functionality it unlocks. ;) I'll freely admit it's not clear from reading the issue summary. It's basically the plumbing in core that gives you a loaded object in a route Controller callback based on the value of a specific part of a URL, if you specify the route with something like {node} or {user} or whatever. So, we need a test that sets up a view to use an argument that expects some kind of entity, and then make sure that the underlying functionality gets the right kind of entity object. Or something. ;) Honestly, I'm not totally sure myself what "bug" this is fixing, what functionality doesn't work, etc. I know how to make use of a named argument in a Controller callback, but I'm not sure how/why Views itself would care about that. I'd have to dig a lot deeper, and I don't have time for that anytime soon. Hopefully someone else who cares about this can better articulate what functionality is broken as a result of this omission. A summary update would help a lot, so tagging for that, too.

Thanks/sorry,
-Derek

pavnish’s picture

Assigned: Unassigned » pavnish
pavnish’s picture

Assigned: pavnish » Unassigned
nitesh624’s picture

Assigned: Unassigned » nitesh624
nitesh624’s picture

Assigned: nitesh624 » Unassigned
nitesh624’s picture

Assigned: Unassigned » nitesh624
nitesh624’s picture

StatusFileSize
new2.25 KB
new933 bytes

done changes suggested in #35
replace all of:
if (isset($a['b']) and $a['b'] == TRUE)) {
with:
if (!empty($a['b'])) {

nitesh624’s picture

Assigned: nitesh624 » Unassigned
nitesh624’s picture

Status: Needs work » Needs review
dww’s picture

Status: Needs review » Needs work

Thanks. We still need tests and an issue summary update.

jibran’s picture

+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -156,11 +157,18 @@ protected function getRoute($view_id, $display_id) {
+            $parameters[$parameter_name]['type'] = 'entity:' . $validation_plugin[1];

@@ -201,6 +209,11 @@ protected function getRoute($view_id, $display_id) {
+      $route->setOption('parameters', $parameters);

Unfortunately, this not a single instance where we have to fix this. #2847224: Add views argument_default for getting Entity ID from URL and #2847233: Allow entity field value as argument_default also needs this functionality. It is not just that Views plugins need this, in contrib moderation_sidebar #3047936: Generic support for any entity type and metatags see metatag_get_route_entity need this as well.

I think we need an issue to add a service for the entity system which will reliably provide the parameter from the route with the correct version and access. IOW, convert metatag_get_route_entity to a core service which is the best solution for this problem IMO.

claudiu.cristea’s picture

Status: Needs work » Needs review
StatusFileSize
new8.49 KB
new9.61 KB

It's not enough to inspect the argument validator plugin ID. There are cases when the plugin ID has a pattern different than entity:{entity_type}, see \Drupal\user\Plugin\views\argument_validator\UserName. In that case we still can upcast the route parameter to an entity.

@jibran, I'm not sure I got the relevance of #45 for this issue. Could you, please, elaborate?

claudiu.cristea’s picture

StatusFileSize
new2.66 KB
new11.14 KB

Forgot to add the new param in create() static method.

Status: Needs review » Needs work

The last submitted patch, 47: 2528166-47.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

claudiu.cristea’s picture

Status: Needs work » Needs review
Issue tags: +Needs change record
StatusFileSize
new5.8 KB
new15.78 KB

Fixing broken existing tests. Still needs tests for the issue scope.

claudiu.cristea’s picture

Now, I think I like more the idea from #3034919-5: Explore making views routes add parameter options for named entity-type arguments. Avoids using the argument validator plugin ID but also avoids injecting the argument validator plugin manager. However, the test is coupled with the comment & content moderation modules.

Status: Needs review » Needs work

The last submitted patch, 49: 2528166-49.patch, failed testing. View results

claudiu.cristea’s picture

Status: Needs work » Needs review
StatusFileSize
new16.21 KB
new4.81 KB

Applying the solution from #3034919-5: Explore making views routes add parameter options for named entity-type arguments. Adding credits. Still needs test.

claudiu.cristea’s picture

Category: Bug report » Feature request
Issue summary: View changes
Issue tags: -Needs tests, -Needs issue summary update, -Needs change record
StatusFileSize
new5.54 KB
new10.35 KB

Adding tests. There's also a "test only" patch that acts here also as interdiff. Fixing IS. And i think this is a "Feature request".

claudiu.cristea’s picture

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

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

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

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

johan.s’s picture

Version: 9.3.x-dev » 9.2.x-dev
StatusFileSize
new10 KB
new10 KB

Fix tests

johan.s’s picture

StatusFileSize
new10 KB
claudiu.cristea’s picture

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

9.3.x is the development branch and this is a feature request.

claudiu.cristea’s picture

Issue tags: +Needs change record

Yep, needs a change note.

claudiu.cristea’s picture

StatusFileSize
new5.54 KB

Let's see a test only run.

claudiu.cristea’s picture

Fix coding standards for "test only" patch. The main work has been moved to MR.

claudiu.cristea’s picture

StatusFileSize
new5.54 KB
new5.54 KB

Status: Needs review » Needs work

The last submitted patch, 66: 2528166-65.test-only.patch, failed testing. View results

claudiu.cristea’s picture

Status: Needs work » Needs review
claudiu.cristea’s picture

claudiu.cristea’s picture

Issue summary: View changes

Fixing IS.

yogeshmpawar made their first commit to this issue’s fork.

kingdutch’s picture

I ran into this issue when trying to figure out why adding a _entity_access to a views route failed, it was because parameters were not upcast.

Although the test and fix look good to me I'm hesitant to put this to RTBC. Primarily I'm worried that this may not be a backwards compatible change. Contrib modules may currently have named route parameters that expect to receive the entity ID rather than an upcast entity. Specifically anyone who wrote a views access handler and looks at the route parameter and then naïvely loads an entity based on it would find their code broken now that they receive an entity instead.

The group module currently manually alters the route to enable upcasting in the GroupPermission access handler. In Open Social we also have access checks that deal with views routes although I believe most of these are written to handle both the entity ID and loaded entity case. An example is access to a user event view.

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

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

johan.s’s picture

StatusFileSize
new9.68 KB

Fix for version 9.3.x

johan.s’s picture

StatusFileSize
new8.8 KB

Fix test pipeline

Status: Needs review » Needs work

The last submitted patch, 75: 2528166-75.patch, failed testing. View results

kevinquillen’s picture

I just ran into this myself.

https://drupal.stackexchange.com/questions/311028/view-with-a-path-of-ap...

It makes it hard to build Views with routes like this without upcasting to take advantage of other chained arguments. All that argument will receive is an ID.

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

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now 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.

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

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now 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.

claudiu.cristea’s picture

Status: Needs work » Needs review

Opened a new MR !2979 against 10.1.x.

claudiu.cristea’s picture

@Kingdutch, I understand your point but we already did this for node revisions in #2730631: Upcast node and node_revision parameters of node revision routes. How to move on wit this?

kingdutch’s picture

Status: Needs review » Reviewed & tested by the community

I think this is mostly up to core maintainers, going to move this to RTBC to get their visibility.
I've slightly changed my point of view since my last message in that I think currently a lot of code dealing with routes already needs to handle both cases to be resilient (I found this after trying to simplify some code after my last message and all of my assertions failing).

For example /user/:id is currently upcast but /user/%user/custom-view is not. So a block that wants to work on both pages will need to take both instances into account.

With that in mind I think a move towards standardisation is much more likely to allow people to simplify their code base in the future than it is to break code that currently works sometimes, but is silently broken other times. So I for one would be very happy if we can get this in.

xjm’s picture

Status: Reviewed & tested by the community » Needs work

Tests for this issue are currently fataling:
https://www.drupal.org/pift-ci-job/2524962

Meanwhile, re:

Contrib modules may currently have named route parameters that expect to receive the entity ID rather than an upcast entity. Specifically anyone who wrote a views access handler and looks at the route parameter and then naïvely loads an entity based on it would find their code broken now that they receive an entity instead.

Could we add a BC layer with a __toString() method or the equivalent so that the caller would get the deprecation?

Could we add a test for the current behavior with the entity ID as the parameter so that we can analyze the BC break?

I think it's a good point to explore, and we might need to handle it with a deprecation process for D11 otherwise.

Thank you @Kingdutch for your feedback on this point; I think it's important to understand the potential disruption of this issue.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

candelas’s picture

Any news on this? Thanks

claudiu.cristea changed the visibility of the branch 2528166-upcast-arg to hidden.

claudiu.cristea changed the visibility of the branch 2528166-upcast-arg-d10 to hidden.

claudiu.cristea’s picture

Status: Needs work » Needs review

Fixed the tests but nothing has changed in substance, only adapted to new PHPCS, PHPStan, Drupal core changes. This was once RTBCed by @kingdutch, in #84

smustgrave’s picture

Status: Needs review » Needs work

Thanks for reviving this one!

Could we add a BC layer with a __toString() method or the equivalent so that the caller would get the deprecation?

Could we add a test for the current behavior with the entity ID as the parameter so that we can analyze the BC break?

Seems this feedback from @xjm is still needed.

alorenc made their first commit to this issue’s fork.

alorenc’s picture

The latest changes from the main branch have been merged.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.