Closed (fixed)
Project:
Drupal core
Version:
8.0.x-dev
Component:
menu system
Priority:
Major
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
20 Nov 2012 at 04:40 UTC
Updated:
29 Jul 2014 at 21:32 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
catchBumping to major since this blocks the conversion of menu links to the new router. See #1848648: [meta] Convert menu system to new routing system for related issues.
Comment #2
catchThis also depends on the #access key from menu_get_item(). That'll need to check both systems as well.
Comment #3
klausiOk, so here is a first patch that updates drupal_valid_path() to look at both routing systems. Added a helper function _drupal_valid_path_new_router() for that.
Depends on #1793520: Add access control mechanism for new router system.
I also included a special key for hook_menu() that we can use for conversion until menu links are sorted out.
Please review the interdiff.
Comment #4
Crell commentedDo we need to still define menu items in the old router as no-ops? Hm. Well, I guess we do for menu links for the time being. Blargh.
However, if we need to do that... instead of flagging it as "the princess is in the other router" let's be nice to Mario and say where. Vis, have a route_name property that is the machine name of the route that corresponds to this menu_item. We may be able to eliminate the subrequest then, no? Since we can just grab the route by name?
Comment #5
catchThe current patch has potentially two performance issues, I'm assuming the first will be more severe than the second:
- every access check requires an individual database query to find the router item associated with the link, we've previously had that attached to menu links so it didn't require a separate lookup.
- every access check requires mocking the request object.
Since this patch will be the first opportunity to actually test this with the new router system, I'm adding the 'needs profiling' tag.
It'd be good to compare before/after with a large-ish menu tree (admin/config with a lot of modules enabled for example) - we might need to fake it with some dummy router items/links to have enough access checks to be comparable.
Comment #6
moshe weitzman commentedFYI devel_generate can generate menu links. Might need updating for D8.
Comment #7
catchThis came up in irc and I remembered why I thought the issue title was strange.
menu_valid_item() is one place this gets checked, but for menu link access when they're rendered, it's
http://api.drupal.org/api/drupal/core%21includes%21menu.inc/function/_me...
and
http://api.drupal.org/api/drupal/core%21includes%21menu.inc/function/_me... (which loads menu objects ready for the access check).
Since this is going to be similar, I think we should do the two places at the same time, but could be persuaded otherwise if there's a really good reason to split.
Comment #8
chx commentedIf you need a different access check then your point of attack is the _menu_link_translate call in _menu_tree_check_access. You need to replace _menu_link_translate with something else. You will have a world of pain with links containing % signs. Otherwise, not so much. Obviously, the _menu_check_access call also needs to be replaced in this _menu_link_translate replacement .
Comment #9
klausiI'm currently busy with getting rest.module into shape, so unfortunately I don't have time to continue with this patch. The posted patch is really far from ready, so setting to needs work.
Comment #10
g.oechsler commentedI am not entirely sure if I understood what we need to do here. So for starters I tried to port the patch from #3 (or merely just the interdiff) to the new routing system.
To document what I think it should possibly do I added a Test for it. :)
Further advice is very welcome.
Comment #11
g.oechsler commentedComment #12
Crell commentedThis should be possible without making a POST request. Just call the appropriate APIs, no?
I am not sure that this approach is still valid. Unfortunately I fear this patch is realistically blocked on #916388: Convert menu links into entities, since that's going to change how menu links work at a fundamental level. :-/
Comment #13
webchickOne of the user.module hunks was failing, so here's a free re-roll, courtesy of porting pants module to D8.
I'm still not sure how to make a menu item both have its route defined in a YML file, and also appear as a clickable link under admin/foo* though. This patch doesn't seem to help.
Comment #14
webchickHm. Nevermind, I was able to hack around it with the same hack user/register is currently doing, of defining its access callback twice: once in YAML and once in hook_menu(). I don't think we can ship this way though, so I wonder if this needs to be critical.
Comment #15
Crell commentedSplitting this off from #1889790: [Meta] Allow modules to register links for menus, breadcrumbs and tabs (if not with hook_menu)
We take hook_menu as it exists now and add a "route" key. That "route" key refers to a route to which that menu link points. The path of the route *overrides* the path that the menu item has. Then we remove the now-duplicated parts of the menu item definition: page_callback, page_arguments, access control, etc.
Then we modify the link build process to pull in the corresponding route and build out the same structure we have now, more or less. This would also partially if not entirely resolve #1845402: Update menu link access checks for new router.
Benefit: We're no longer duplicating route information between hook_menu and routes. hook_menu is now defining just, er, menus.
-----
That relates to that issue, so let's do it here as one.
Comment #16
catch@webchick this issue is in the summary of #1848648: [meta] Convert menu system to new routing system which is marked as critical, although it's definitely critical in its own right as well.
@Crell that sounds like a good plan with the current menu link system, although I have no idea how it'll interact with menu links as entities.
Comment #17
amateescu commented@catch, the interaction with menu links as entities should be pretty minor, we can load all the needed routes (at once) and reconstruct the current structure in attachLoad().
Comment #18
Crell commentedamateescu: So is it safe to work on this issue in parallel with the links-as-entities patch, or would one going in screw over the other?
Comment #19
amateescu commentedThis one will definitely screw the menu links as entities patch because there are a lot of places where we do db queries for getting menu links instead of using api functions (like menu_link_load())..
Even more, because our current access checks are closely tied to upcasting, I would say that this is also blocked by #1798214: Upcast request arguments/attributes to full objects and maybe #1906810: Require type hints for automatic entity upcasting too.
Comment #20
Crell commentedTaking a stab at this on the plane today.
Comment #21
Crell commentedOK, let's see how well the bot likes this.
I've extended the code above. It now binds a route to a menu link, and pulls data from there as necessary. I also modified the Link entity to include that route object, and mass-load them when the Link is loaded. There may be a better way there; I'm open to suggestions. However, this does, I think, get us working access control and a thinner hook_menu definition.
Note: In order to make access control work, I had to include the code from #1907750: Symfony update exposes fatal error during installation due to 'access_manager' service depending on 'request', which we need anyway. If that goes in first we can rebase it out of my branch here, or if this goes in first that issue can move on to other things.
Comment #23
Crell commentedNow with 100% less failing installer!
Comment #25
Crell commentedNow I've got real failures to fix! This should do it, I think. Book module apparently hadn't been fully converted to entity links; I did a bit more of that.
Comment #26
amateescu commentedThis should go into attachLoad().
No, no, no.. this is mixing the route property of a router item with a menu link property, and I thought the goal was to untangle them :/
Or.. did you actually want to add the 'route' column to the {menu_links} instead of {router}?
Comment #27
Crell commentedTalked to amateescu in IRC. Attached patch fixes load() vs. attachLoad() (thanks!). Also moves the route information to the menu_links table, as that's nominally more proper. That keeps the property public, but should reduce future work to rip out menu_router when the time comes.
Comment #29
Crell commented#27: 1845402-menu-links-access.patch queued for re-testing.
Comment #31
jthorson commentedFrom testbot apache error log:
PHP Fatal error: Call to a member function setRouteObject() on a non-object in /var/lib/drupaltestbot/sites/default/files/checkout/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php on line 84Comment #32
Crell commentedThat's fascinating, because I am able to install, logout, and login just fine without issue on my local.
Comment #33
jthorson commented#27: 1845402-menu-links-access.patch queued for re-testing.
Comment #35
Crell commentedRerolling for update hook increment.
Comment #37
jthorson commentedFrom testbot checkout watchdog log:
Notice: Undefined variable: id in Drupal\menu_link\MenuLinkStorageController->attachLoad() (line 76 of /var/lib/drupaltestbot/sites/default/files/checkout/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php).Notice: Undefined index: in Drupal\menu_link\MenuLinkStorageController->attachLoad() (line 84 of /var/lib/drupaltestbot/sites/default/files/checkout/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php).Along with the PHP fatal listed above.
Just for completeness sake ... drupalLogin() is returning 3 passes, 3 fails. I'm also seeing warnings in the tesbot log itself (though those appear somewhat more randomly):
Warning: simplexml_import_dom(): Invalid Nodetype to import in DrupalWebTestCase->parse() (line 1594 of /var/lib/drupaltestbot/sites/all/modules/simpletest/drupal_web_test_case.php).x2Comment #38
dawehnerLet's see.
Comment #39
andypostWhy they are in different modules? Also not sure that 255 is enough for route as urls could be x4 longer
Possibly caused by #1239370: Module updates of new modules in core are not executed
Do not need to touch deprecated functions!
Maybe better to replace it with @todo and link?
This entries looks useless
Needs @todo for #1889790: [Meta] Allow modules to register links for menus, breadcrumbs and tabs (if not with hook_menu)
Comment #40
dawehnerYeah you are probably right on that point.
That's the router name, not the path, so for example "edit_metadata", see edit.routing.yml
There is already a @todo in the beginning of user_menu().
Not sure whether it really makes sense to add the todo, because, you would have to add one to all menu items already.
Fixed some other pieces.
Comment #41
Crell commentedThanks, @dawehner! I've added you to the WSCCI sandbox. :-) Please push your changes to the branch that is there for safe keeping.
Can we get a review of the approach in general? What else is needed here to move forward? This is only aiming to be an incremental improvement.
Comment #42
Crell commentedBah, Drupal.
Comment #43
dawehnerI'm wondering whether we want to have explicit tests for this kind of functionality?
Comment #44
Crell commentedCan you clarify what you mean by "this kind of functionality?"
Comment #45
dawehnerThis has been a bad comment from mine.
Create an explicit test for a hook_menu entry with a connected route, that has an access check and test, for example, that _menu_translate() returns what's expected.
Comment #46
amateescu commentedI'll take a stab at that test tomorrow.
Comment #47
amateescu commentedDiscussed this with @dawehner and we agreed that the expected functionality is already tested by the
'user/register'route (which has to stay in hook_menu() because it's a MENU_LOCAL_TASK) and there's really no point in testing_menu_link_translate()since it will be going away soon-ish anyway.I found a couple of other doxygen issues and also that we don't need hook_menu() entries anymore for user autocomplete routes, since this patch fixes the @todo that was keeping them in place!
Therefore, I think this is good enough for now and allows the conversion of
MENU_CALLBACKrouter items to be crowdsourced this weekend :)Comment #49
amateescu commentedMerged HEAD.
Comment #51
amateescu commentedThis is what happens when we work with and without branches :( We were missing the fix from #38.
Comment #52
amateescu commentedFinally!
Comment #53
dries commentedIt's not clear whether catch's performance concern in #5 was addressed?
Comment #54
webchickTossing it at him. :)
Comment #55
Crell commentedThe query-per-check should have been addressed by the way we load the routes with the menu links. We're still mocking the request, but not with a full subrequest but just a direct call to the matcher so it should be reasonably expedient. I'm not sure how to make that any faster at the moment.
Comment #56
catchmsonnabaum said he'd be profiling this today. The query-per-route was my main concern and that's fixed, I think smaller regressions we can make up if we do #1805054: Cache localized, access filtered, URL resolved, and rendered menu trees (since current menu link caching in 7/8 is not that efficient).
Assuming profiling comes back OK I'm happy for someone else to commit this (and I know people are keen to have it in tomorrow for conversions - I won't be around for most of tomorrow so don't want to hold it up).
Comment #57
tim.plunkett#51: drupal-1845402-51.patch queued for re-testing.
Comment #58
webchickComment #59
msonnabaum commentedI profiled this patch on new d8 install, hitting user/register 30 times each. That seemed to be a decent place to trigger the new code path, but please correct me if I'm wrong here.
I'm actually showing a slight improvement in wall time with the patch. I dug into it a bit and it looks like there's some savings from not calling things like _menu_check_access, which in turn makes a bunch of config calls, etc.
I could dig further, but it doesn't seem worth it. This patch feels very low risk performance-wise to me.
Comment #60
webchickOk, looks like the poor patch survived both testbot and msonnabaum :D so going to go ahead and get this in to help people attending the Drupal Global Sprint Weekend crank on conversion patches! :)
I love love love that this patch gets rid of totally awkward stuff like the NOT_USED value. It's a little unfortunate you need to manually specify the route name for visual links, but I can't think of another way now that path is no longer unique between routes.
Committed and pushed to 8.x. Thanks!
This'll need an update to the routing system change notice. We might be getting close to be able to stop updating that now. :P
Comment #61
Crell commentedWoo! Thanks all!
I will update the change notice for this and #1934832: Provide a dedicated approach for using forms in routes at the Chicago sprint tomorrow.
Comment #62
Crell commentedChange notice updated.
Comment #63
Crell commented.