Problem/Motivation
#956186: Allow AJAX to use GET requests moved all the parameters for a views request into the GET query which now includes ajax_page_state
. This is sometimes leaking into URL building for things like facets. #3343860: Support views AJAX GET requests after https://www.drupal.org/project/drupal/issues/956186 / 10.1.x
The core of this is trying to be addressed in #2504709: Prevent _wrapper_format and ajax_form parameters from bleeding through to generated URLs but until we should remove this from the request in a similar way in ViewsAjaxController.
Steps to reproduce
This is tricky. You can do it with facets but also if you try to use the request object in a twig template to preserve query values, you will run into it there as well.
Proposed resolution
Remove the parameter from the global request in ViewsAjaxController.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#19 | media-library-missing-styles.gif | 752.91 KB | lauriii |
Issue fork drupal-3399951
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
Comment #2
neclimdulComment #3
neclimdulComment #5
catchThis looks good. Not sure how to add test coverage and wondering if we should commit it as-is and defer that to #2504709: Prevent _wrapper_format and ajax_form parameters from bleeding through to generated URLs which will remove all the whack-a-mole anyway?
Comment #6
smustgrave CreditAttribution: smustgrave at Mobomo commentedReran the tests 3 times so appears the test failure is legit.
Comment #7
neclimdulYeah, doesn't really makes sense but they did fail. Some of the failure messages don't make any sense though so going to do some manual testing to get to the bottom of things.
Comment #8
neclimdulInvestigating something yesterday I think I figured this out. It might require referencing Wim's D8 render pipeline flow chart and understanding that `ajax_page_state` actually happens in a AjaxResponseSubscriber though. It boils down to, since we're _entirely_ removing the query from the request in the controller, later when it gets to the response subscriber its also gone. The subscriber then thinks it never existed and doesn't recompute the libraries to return correctly. This then can cause problems for interactions with the page since the libraries that previously existed on the page have been removed from Drupal's list its tracking.
There's _probably_ an argument to be made that AjaxResponseSubscriber should capture the query during the response event and hold it to be more resilient to things happening during the rest of the request handling. I'm not sure if that's the correct way or if there's an appetite to change it and its definitely a big change of scope from this issue so going to try avoid addressing it here.
That said, since this code is already specifically trying to handle this sort of request hackery, we can do a little more to work around this limitation. The merge request has been updated to hopefully handle handle things. If it works it could probably use some documentation on why it needs to work the way it does and maybe a link to an additional follow up.
Comment #9
neclimdulRandom test failure #3400150: [random test failure] TimestampFormatterWithTimeDiffTest::testTimestampFormatterWithTimeDiff in Javascript tests. Nightwatch looks like chrome crashing?
Seems that change fixed the problem.
Comment #10
smustgrave CreditAttribution: smustgrave at Mobomo commentedReran the failing nightwatch and javascript and they passed. @catch mentioned moving tests to another ticket in #5.
So think this is good.
Comment #11
xjmI'm waffling about descoping the test coverage. The code already tried to fix this and already references the followup we're proposing descoping the test coverage to, so how do we actually know that it is and will stay any better this time around?
That said, I couldn't think of what to test either.
But maybe we could add inline comments to the current change set, at least, to reduce the risk of further regressions before we fix this properly?
Comment #12
smustgrave CreditAttribution: smustgrave at Mobomo commentedFor #11
Comment #13
neclimdulSo I started doing that and then I'm like "Well, this isn't really different then '_drupal_ajax' so we should probably use a similar constant so we can track dependencies in the same way.
Unfortunately, this was like pulling up the proverbial rock and all the bugs rushed out. The reason it didn't "affect" core was it seems like there are a number of tests and workarounds placed directly in various core systems. Specifically Pager and medial_library filter this and only this parameter out of some URL building.
I've gone ahead removed the work arounds, cleaned up the documentation related to these query filters, and consolidated the filtering list to hopefully make systems that need similar workarounds in the future easier to implement.
Comment #14
megadesk3000 CreditAttribution: megadesk3000 at Unic commentedI experience the same issue in Drupal 10.1.6 using Facets 2.0.6 and the MR does not apply here.
Is there also a version of the Patch for Drupal 10 somewhere?
Comment #15
catchThis looks great, and probably as good as we're going to get things before #2504709: Prevent _wrapper_format and ajax_form parameters from bleeding through to generated URLs.
Comment #16
neclimdulThanks catch! I was definitely thinking about moving towards that so glad you agree.
As far as the 10.1 patch, you should be able to use the earlier version. it doesn't have the docs but behaves the same.:
https://git.drupalcode.org/project/drupal/-/commit/827b13b4bd8beaf77861b...
Comment #17
megadesk3000 CreditAttribution: megadesk3000 at Unic commentedThanks neclimul!
I use
"3399951: Fix ajax_page_state leaks through request in Views Ajax": "https://git.drupalcode.org/project/drupal/-/commit/827b13b4bd8beaf77861b86b8ace48500ecdf6d1.patch"
in my composer patches section. That seems to resolve the issue for us.
Thanks again for the hint.
Comment #19
lauriiiLooks like there's a regression where some styles get lost after applying filters in Media Library:
Comment #20
catchNice find - we should at least be able to add a test to catch that issue, even if more generic tests will be easier in #2504709: Prevent _wrapper_format and ajax_form parameters from bleeding through to generated URLs
Comment #21
neclimdulLooks like this code is behaving correctly but maybe media is being naughty?
Basically, media has
media_library_views_post_render
which callsMediaLibraryState::fromRequest($view->getRequest())
.You might think this is generating a media state from the request but it _also_ mangles the request on the view.
Because the views request is the _actual_ request and not the cloned version, this mangling was able to remove the actual page state. But when this patch adds the state back it breaks this little hack which apparently doesn't have a test. Or more accurately, it kinda had a test we are now removing in this patch. However it didn't test that it's hack was actually changing view's ajax behavior so it didn't see this change as breaking.
So... maybe this is blocked on #3396650: MediaLibraryState passes all query parameters around, not just the ones it needs? I'm not sure what the next steps are because I'm not really familiar with what media is trying to accomplish and why it is fighting with asset management like this.
Comment #22
catchThe partial history is that whatever media is doing was 'working' because all AJAX requests were POST requests prior to 10.1.0. When we made AJAX requests for views use GET, it started breaking, but we didn't have sufficient test coverage for all of the behaviour to notice in the original patch/MR. What media is doing is definitely weird, but like you I also don't understand why it is doing it, nor do I have a clear idea of what it should be doing instead.
Comment #23
godotislate CreditAttribution: godotislate at Digital Polygon commentedThe regression seen in #19 isn't specific to media. Doing this shows a similar issue:
What's happening is that because
ajax_page_state
is temporarily removed from the Request object, when$view->preview()
is executed, AjaxBasePageNegotiator does not apply becauseajax_page_state['theme']
andajax_page_state['theme_token']
are unset, so instead of the admin theme, the AJAX content is rendered in the default theme.Since
$request->get()
also checks the contents of theattributes
parameter bag, adding this to the MR diff worked for me, but I don't know if it's ideal:Comment #24
godotislate CreditAttribution: godotislate at Digital Polygon commentedAdded the changes mentioned in the previous comment along with a test to the MR and rebased.
Comment #25
catchI think the constant is out of scope here, and it's also on an event subscriber which shouldn't be relied on as part of the API. Bumping this to major since it can cause problems with complex views / ajax combinations.
Comment #26
godotislate CreditAttribution: godotislate at Digital Polygon commentedReverted constant use and rebased.
Comment #27
smustgrave CreditAttribution: smustgrave at Mobomo commentedI ran the test-only job and locally but the testExposedFilteringThemeNegotiation seems to be passing without the changes.
Comment #28
godotislate CreditAttribution: godotislate at Digital Polygon commentedThat test is for an issue that arose because of previous commits introduced in the MR (see #19). It's expected that it will pass without the changes. To see it fail, you'd need to remove changes mentioned in #23.
Comment #29
smustgrave CreditAttribution: smustgrave at Mobomo commentedSo I have to set up my local to get a failing test? How come we aren’t testing the scenario described?
Sorry if something isn’t clicking for me
Comment #30
godotislate CreditAttribution: godotislate at Digital Polygon commentedThe test added is for coverage that was originally missing, per #20 and #22. As mentioned in #23, the issue in #19 is not specific to the media library, so the test is a more generic Views Ajax use case. If others feel it's necessary to test media library, that test can be added, but it seems redundant to me.
Comment #31
smustgrave CreditAttribution: smustgrave at Mobomo commentedBut we currently don't have coverage for this specific bug?
Comment #32
catchI think the added generic test coverage here is fine, that's going to catch more issues than a test specific to the media library hopefully.
Comment #33
smustgrave CreditAttribution: smustgrave at Mobomo commentedWill rely on yall for that decision! just seems like could leave us open for this bug to come back because this edge case isn't covered.
Comment #34
catchWe've still got #2504709: Prevent _wrapper_format and ajax_form parameters from bleeding through to generated URLs lined up after this issue and will probably add more coverage there too. It would be good to add an extra media library functional test (or extend an existing one) with filtering + paging but I think that could be done in its own issue as a task.
Comment #35
godotislate CreditAttribution: godotislate at Digital Polygon commentedI will say that downloading and applying the MR diff fixes a weird issue on our project with a Facets-driven AJAX view. The server is set up to send "no-cache, no-store" headers on every response (I'm not sure why). After applying Facet-ed filters on the view, clicking on one of the results to view the node, and then using browser back navigation to return to the results listing, the listing page was completely missing CSS/JS even though the correct theme was being used.
I haven't tried to see whether this is reproducible with a core-only view, because this server set up seems very edge-casey. But if others think it's a worthwhile thing to try to test, I can give it a go.
Comment #36
smustgrave CreditAttribution: smustgrave at Mobomo commentedCould we open a follow up for this one?
Then probably good to mark, leaning on that @catch has done a review less then 2 weeks ago. And I don't personally see anything in the code
Comment #37
godotislate CreditAttribution: godotislate at Digital Polygon commentedFollow up: #3413820: Add functional test for media library appearance after filtering and paging
Comment #38
smustgrave CreditAttribution: smustgrave at Mobomo commentedThanks!
Comment #41
catchCommitted/pushed to 11.x and cherry-picked to 10.2.x, thanks!
Comment #43
rgpublicIf I open the media library under Drupal 10.2.2 and then - still within the media library modal dialog - cause any AJAX request e.g. by changing the view exposed filters, all(!) page assets (like drupal.js etc) are loaded again causing many follow-up problems. This seems to happen because of:
in MediaLibraryState.php. Will this problem also be solved by this bug and won't appear in Drupal 10.2.3 ?