Problem/Motivation
Steps to reproduce:
- Install the Standard profile
- Go to admin/structure/views
- Disable the Content view (admin/content)
Expected result:
Working site
Actual result:
WSOD
-----
When you disable the admin/content view, it no longer uses the View as a route, but falls back to the listing page provided by node module.
However, shortcut doesn't get updated, and continues to reference the no-longer-existing route.
Proposed resolution
Decouple shortcuts from menu links by creating a new content entity type: shortcut.
Remaining tasks
Patch is done, needs reviews.
User interface changes
None.
API changes
- shortcuts are no longer stored in the menu_links table, they have their own storage, and shortcut sets no longer act as semi-bundles for menu links but as actual bundles of the new 'shortcut' entity type
- shortcut sets no longer keep the weird uuid reference to their shortcuts, because it's not needed anymore
Comment | File | Size | Author |
---|---|---|---|
#86 | 2021779-followup.patch | 843 bytes | amateescu |
#76 | interdiff.txt | 913 bytes | amateescu |
#76 | shortcut_rewrite-76.patch | 91.75 KB | amateescu |
Comments
Comment #2
amateescu CreditAttribution: amateescu commentedI investigated this a bit a couple of days ago, and it's bad, really bad :/
Shortcut links don't have any kind of relationship with the menu link they were originally created from, so we have no good way of updating their 'route_name' property when the original menu link changes.
One way to do it would be in a hook_entity_presave() for menu_link, but that means doing one more select for each saved menu link, and _menu_navigation_links_rebuild() is already slow as hell.
The only way forward that I can think of is to decouple shortcuts from menu links and convert them to a separate entity type with an entity reference field.
Comment #3
klonosI was pointed to this issue here from #1895160-63: Convert admin/content to a View, keep a non-views fallback with no bulk operations...
STR:
Symfony\Component\Routing\Exception\RouteNotFoundException: Route "view.content.page_1" does not exist. in Drupal\Core\Routing\RouteProvider->getRouteByName() (line 126 of /home/s4d78154f0ffa1ad/www/core/lib/Drupal/Core/Routing/RouteProvider.php).
Comment #4
amateescu CreditAttribution: amateescu commentedThe patch just adds a test for this bug, it doesn't try to solve anything..
Comment #5
klonosok, thanx. I edited my comment above.
Comment #6
ibullockIn addition to #3:
Same error occurs if you try to enable Views again after disabling.
Comment #7
dawehnerI can't really imagine this to just be major to be honest.
Comment #8
dawehnerSadly we can't really know what is updated but there is at least a method on MenuLink.php which just would have to be executed again, to get the proper route name: findRouteName(). So we could truncate all route names, on module disable and then lazy-rebuild them on usage?
Comment #9
catchYeah this seems critical enough and I can't see it only happening if a module gets disabled/uninstalled - would be affected by any change in alters too no?
Comment #10
dawehnerI thought about introducing an event subscriber for module enable/update/disable/delete or router rebuild which updates all menu_links but this won't really work, as you can't mass-update menu links (and you shouldn't).
The question is: Is the entity storage the right place to store the route_name? Isn't that information which is just between the route system and menu links, and don't belong to the actual entity. If we store the mapping for example in a key value store, or maybe in some cache array, resetting the values on a router rebuild would be simple.
With a cache array you would also get lazy rebuilding of the information.
Comment #11
mgiffordI just replicated the problem in #3 on SimplyTest.me twice.
Can the router be re-built when modules are disabled?
Comment #12
tim.plunkettThe router is rebuilt when modules are disabled. This isn't the menu router, it's menu links, which aren't declarative.
Also, disabling a module is only one of a few ways to reproduce this. See the OP.
Comment #13
mgiffordThanks Tim. I just ran into this issue when trying to address another one. Appreciate the info though.
Comment #14
Wim LeersThis happened to me while simply disabling the
admin/content
view atadmin/structure/views
, i.e. not even disabling modules.Comment #15
dawehnerWhy would you ever want that ;)
Feedback on the idea of #10 is still wanted.
Comment #16
amateescu CreditAttribution: amateescu commentedI still prefer the decoupling from menu links and turning shortcuts into a separate entity type with a reference property. This wasn't possible when shortcut.module was written (D7) but it should be really easy to do now.
Comment #17
dawehnerI somehow doubt that a) this can actually happen due to API freeze and b) this will happen, given that people are already quite busy.
Comment #18
amateescu CreditAttribution: amateescu commentedAfaik, API freeze does not apply to critical bugs. And b) you knew exactly what buttons to push to make me work on it, didn't you? :P
First of all, we need to do #2036629: 'shortcut' entity type is very confusing and should be renamed to 'shortcut_set' so we have the 'shortcut' namespace available here.
Comment #19
catchAPI freeze doesn't apply to critical bugs when an API change is required to fix the bug in a sane way. #10 looks sane enough to me.
Comment #20
amateescu CreditAttribution: amateescu commentedThe thing is, I'm doing #16, not #10... Let me know if I should stop :)
Comment #21
catchUnless there's a particular reason not to do #10 let's do that please.
Comment #22
amateescu CreditAttribution: amateescu commentedHere are my reasons:
Comment #23
dawehner@amateescu
Just to be clear, does your port will solve it automatically or do you still need some similar logic as #10?
Comment #24
amateescu CreditAttribution: amateescu commentedIt will solve it because shortcuts will not be saved as menu links anymore (basically duplicating the menu link with a different menu and link_title), but as standalone entities with a reference to a menu link.
Comment #25
tim.plunkettSee #1987762: Convert node_add_page() to a new style controller for another puzzling bug in shortcut/menu_links
Comment #26
amateescu CreditAttribution: amateescu commentedHere's what I have so far. The new entity type seems to work, but we still need to update the old code that expected menu links and receive shorcuts now.
Comment #27
andypostanyway this approach requires re-sync of links and references when shortcut module disable/enable and there's no code that listens for changes on menu-link entity
otoh moving from string translation to entity translation looks promising
another abstraction on top of menu link? suppose translation become worth
maybe better use route_name here?
Comment #28
amateescu CreditAttribution: amateescu commentedI guess you missed the critical issue about removing module enable/disable functionality from D8? :)
And we can't reference a route name, because we need to reference an actual path (that would be route name + params), but it's totally not worth it because menu links will already do it for us.
P.S. Could you edit your comment to remove those table schemas? Keep the first row of the declaration, but the rest doesn't bring anything for someone trying to scan this issue :)
Comment #29
andypostSo the only translation of shortcut title is questionable.
#1199946: Disabled modules are broken beyond repair so the "disable" functionality needs to be removed is not in core yet.
PS: so shortcut becomes content entity? why not use link field for that?
Comment #30
amateescu CreditAttribution: amateescu commentedIt's not questionable, it's an improvement at the moment, because menu links are not yet translatable.
Yeah, removal of module disable is not in core yet, but it's critical, so it certainly will be.
And yes, shorcuts become content entities, and I'm not using a configurable field because this is kind of a "hidden" property, it's not even shown in the shortcut form, so I think that would be overkill.
Comment #31
amateescu CreditAttribution: amateescu commentedHere's the current state of things. It's almost there, just need a couple fixes and an upgrade path.
And, of course, I need to fix the initial problem, update the route name of the shortcut when the route is changed, but that's just copying the code that does it for menu links.
Comment #33
dawehner#2083123: Shortcut cleanup: Remove duplicated code and deprecate legacy functions
Comment #34
amateescu CreditAttribution: amateescu commentedGetting there.
Comment #36
amateescu CreditAttribution: amateescu commentedNow with upgrade path.
Comment #38
jibranI believe it is an API change. Issues summary is not in proper format and I think we should list all the api changes.
Comment #39
amateescu CreditAttribution: amateescu commentedA bit more progress. One of the fails will be fixed by #2029569: Convert node_admin_nodes to a new-style Controller.
Comment #40
amateescu CreditAttribution: amateescu commentedNope, I didn't want to remove those tags.
Comment #42
klonos...adding back tags that got removed again :/
Comment #43
amateescu CreditAttribution: amateescu commentedKeeping up with HEAD and a tentative fix for aliases.
Comment #45
amateescu CreditAttribution: amateescu commentedTurns out
drupal_schema_get_field_value()
had to be fixed, not removed from the storage controller.Comment #47
amateescu CreditAttribution: amateescu commentedAnd this fixes the last failures, spoke to @dawehner and it turns out getPathFromRoute() is not really deprecated after all. This should be green so I'll write a new issue summary.
Comment #48
amateescu CreditAttribution: amateescu commentedUpdate the issue summary and let's also add the original test from Tim :)
Comment #49
dawehnerAs written below, this should not really be a static function.
We should try to move the test given that this does not belong into the class anymore.
Should we just use the entity manager, which is already part of the EntityAccessController
It would be great to already use redirect_form here.
Afaik we don't use classes which are in the root namespace.
We do now have an interface for the entity manager.
It would be great if we could drop that odd spacing here.
Let's mark it public if we create a new function.
node is using node_field_data instead of _property_data ... do you know which one is the recommended one?
I am wondering whether we need to put the update into a batch process given that some sites might use shortcuts for every user.
Why not default to an empty array?
theme_links should be able to render links using the route_name and parameters, so we could already set it to drop additional work in the future.
I really think that this should be part of the service, not backed into yet another static function.
Just a general question: Do we really want to translate the title here and not while rendering the output?
Comment #50
BerdirYes, I think this should be shortcut_field_data.
I have no idea what this is doing now that route_parameters is a map_field... Seems like the unserialize should happen earlier, before it's assigned?
wrong class name.
FYI: A lot of attachLoad stuff in storage controllers is moving to entity classes in #2095283: Remove non-storage logic from the storage controllers
Comment #51
amateescu CreditAttribution: amateescu commentedGreat reviews, thanks guys! Fixed everything except the following:
Sadly enough, the entity manager is not part of EntityAccessController.
I wouldn't worry about it, this will be converted to a migration soon enough.
I looked at theme_links() and it's checking for a 'path' property, so it doesn't look able to use route names and parameters.
Until we introduce the mechanism for default content entities (with translation support), this is the best we got for having those titles translatable on l.d.o
Comment #52
amateescu CreditAttribution: amateescu commentedNoticed a problem in the form controller, we didn't use the shortcut set storage anywhere and the parent class needs the entity manager.
Comment #53
amateescu CreditAttribution: amateescu commentedRerolled.
Comment #55
amateescu CreditAttribution: amateescu commentedAnd again.
Comment #56
amateescu CreditAttribution: amateescu commentedAnd again. Sad to see this one still in NR.
Comment #57
dawehnerLet's see what we can do.
We should typehind for the interface instead.
Note: This was not an actual review, but to tease a bit.
Comment #58
star-szrLooks like this needs a reroll, patch applies to 14336d94b8da95f2c2f26edb7ffb5c12d58a1212.
Comment #59
amateescu CreditAttribution: amateescu commentedRerolled and fixed the review from #57.
Comment #60
amateescu CreditAttribution: amateescu commentedYet Another Reroll. Critical bug crying for reviews here :)
Comment #61
dawehnerThis looks really rock-solid.
Still not sure whether the url matcher is the right place. Can we replace that functionality by just using \Drupal::service('router')->match? I see why it is here ...
We don't use the query factory as far as I can see.
We could use \Drupal::url() directly.
Comment #63
herom CreditAttribution: herom commentedd.o, what failed testing?
Comment #64
amateescu CreditAttribution: amateescu commentedAs far as I see.. we can't. Here's what I get for
\Drupal::service('router')->match('node/1');
That's right, fixed.
Nope, we can't.. something to do with aliases.
@herom the patch failed initially and then I asked for a retest directly on qa.d.o
Comment #65
amateescu CreditAttribution: amateescu commentedThe real patch would be nice to have.
Comment #66
alexpottWithout this patch we can not import shortcut sets (configuration) entities since they have a hard dependency on the menu_link (content) entities because they sort the UUIDs for them in their configuration file.
Comment #67
alexpottComment #68
andypostLooks RTBC except few nitpicks
It makes UrlMatcher depends on container/service?
is it ok?
Any reason to mix title/path?
$entity_bundle optional? maybe better to use here storage controller directly?
It would be nice to have special PathValue in core :)
Comment #69
amateescu CreditAttribution: amateescu commentedThanks for reviewing!
Comment #70
xjmComment #71
alexpott69: shortcut_rewrite-69.patch queued for re-testing.
Comment #73
amateescu CreditAttribution: amateescu commentedI forgot to post back in this issue: opened #2153891: Add a Url value object for #68.1
Comment #74
amateescu CreditAttribution: amateescu commentedOr, since this patch is pretty much RTBC at this point, we can just go ahead here with a @todo (see interdiff) and make #2153891: Add a Url value object a non-critical followup?
Comment #75
catchI don't think we should postpone this. And if the Url value object doesn't block anything, could just be major yeah.
Comment #76
amateescu CreditAttribution: amateescu commentedProper fix for #68.2.
Comment #77
andypostAwesome! I see no other nitpicks to stop the critical
Comment #78
catchGreat to see this one green. Original shortcut issue to add that module discussed a separate entity at one point, in case anyone wants to read back and wish they had a time machine.
Committed/pushed to 8.x, thanks!
Comment #79
amateescu CreditAttribution: amateescu commentedWoot! I did a self-review on the patch in #76 and opened this followup: #2156923: Various code cleanups for the new shortcut entity
Comment #80
amateescu CreditAttribution: amateescu commentedWrote a change notice here: https://drupal.org/node/2156931
Comment #81
xjmSadly this has broken HEAD. :(
git revert d443c1
Comment #82
amateescu CreditAttribution: amateescu commentedIt seems this is a general problem with creating translatable content entities during installation. Opened an issue for it here #2156945: Clean up installer entity defaults following bugfix
I agree with the temporary revert :(
Edit: can someone unpublish the change record node?
Comment #83
xjmLooking at the verbose results, the failed assertions happen on an installer page where there's an exception displayed at the bottom:
Excitingly thrown from core/lib/Drupal/Core/Database/Query/Insert.php. :) So something is going funky when installing standard in the installer test. I did double-check and standard installs fine when I install it for real in a browser or via drush si.
Comment #84
xjmI unpublished the change record. Soon we will be able to revert it to a draft state instead. :) #2151041: Add a "draft" status for change records
Comment #85
amateescu CreditAttribution: amateescu commentedIt breaks only when installing in another language than English. But we can continue this in the issue I opened for it :)
Comment #86
amateescu CreditAttribution: amateescu commentedThis should fix it. Thanks to @Berdir for the tip in #2156945: Clean up installer entity defaults following bugfix.
Comment #87
jibranCan we merge #2156923: Various code cleanups for the new shortcut entity in this patch?
Comment #88
jibranOh nvm. We don't have the revert yet.
Comment #89
BerdirConfirmed that the change fixes the testfail, we have the other issue to try and improve it.
Comment #90
webchickCool, thanks for the fast turnaround, folks!
Committed and pushed #86 to 8.x.
Comment #91
webchickComment #92
andypost@xjm or @webchick please publish back change notice https://drupal.org/node/2156931
Comment #93
xjmFixed. :)
Comment #95
yched CreditAttribution: yched commentedFYI : #2354177: Shortcut::getRouteParams() should be named getRouteParameters() for consistency ?