Make WordPress Core

Opened 17 years ago

Last modified 2 weeks ago

#10762 assigned defect (bug)

Bulk editing creates invalid URIs

Reported by: hakre Owned by:
Priority: normal Milestone: Future Release
Component: Quick/Bulk Edit Version: 2.8.4
Severity: normal Keywords: has-patch has-unit-tests
Cc: Focuses:

Description

They simply get too long for example if you move 999 posts to trash. It might be helpfull to switch to the post form method.

Attachments (1)

misc-10762-1.diff​ (404 bytes ) - added by nikolov.tmw 11 years ago.
Adds 'ids' to the list of query args that should be removed from admin URLs

Download all attachments as: .zip

Change History (26)

#1 @scribu
17 years ago

Never did understand why a GET request is used in this case. Should use POST.

#2 @azaozz
17 years ago

Bulk Edit submits the main form on the page which uses GET. It could be refactored to use POST but that's not a trivial task.

#3 follow-up: @hakre
17 years ago

For me it seems that replacing $_GET with $_REQUEST is pretty trivial. It might not be trivial to test if that's working then.

#4 @hakre
17 years ago

Related: #11114

#5 @hakre
17 years ago

Related: #10360

#6 in reply to: ↑ 3 @nacin
17 years ago

  • Milestone 2.9 → 3.0

Replying to hakre:

For me it seems that replacing $_GET with $_REQUEST is pretty trivial. It might not be trivial to test if that's working then.

If you bulk-delete posts, the IDs are passed back to the form, that way the undo button can be generated. So hidden fields would also need to be created to ensure that the URI can't get too long.

It's a complicated process to go through however many forms use bulk actions and redo all of the add_query_arg code and such. Definitely quite the task.

#7 @dd32
17 years ago

  • Milestone 3.0 → Future Release

As this isnt a Regression from a previous version, and there is no patch, I'm moving to Future Release.

#8 @scribu
16 years ago

  • Keywords gsoc added
  • Owner set to scribu
  • Status new → assigned

#10 @voyagerfan5761
16 years ago

  • Cc WordPress@… added

#11 @scribu
16 years ago

  • Milestone Future Release → 3.1
  • Resolution → fixed
  • Status assigned → closed

#12 @nacin
16 years ago

  • Component Accessibility → Administration
  • Keywords gsoc removed
  • Milestone 3.1 → Future Release
  • Resolution fixed
  • Status closed → reopened

#16335. We'll need to fix this in conjunction with ajax redux.

#13 @scribu
14 years ago

  • Owner scribu removed
  • Status reopened → assigned

#14 @scribu
14 years ago

#22062 was marked as a duplicate.

#15 @scribu
14 years ago

#22062 was marked as a duplicate.

#16 @ocean90
13 years ago

#24323 was marked as a duplicate.

#17 @ocean90
13 years ago

  • Component Administration → Quick/Bulk Edit

#18 @ocean90
12 years ago

#28192 was marked as a duplicate.

#19 @ocean90
12 years ago

#29049 was marked as a duplicate.

#20 @SergeyBiryukov
12 years ago

#29116 was marked as a duplicate.

@nikolov.tmw
11 years ago

Adds 'ids' to the list of query args that should be removed from admin URLs

#21 @nikolov.tmw
11 years ago

Thought - why not use the $removable_query_args feature introduced in 4.2 that allows us to remove certain query parameters from the URL with JS on page load? It won't work for everyone, but it's a rather easy to apply fix(instead of digging through all of the places where we'd have to use remove_query_arg() for form actions). I've submitted a simple patch that does exactly that, while seemingly not breaking anything(the "Undo" link still works fine).

#22 @SergeyBiryukov
9 years ago

#43783 was marked as a duplicate.

This ticket was mentioned in ​Slack in #core-restapi by desrosj. ​View the logs.


8 years ago

#24 @SergeyBiryukov
8 years ago

#45618 was marked as a duplicate.

This ticket was mentioned in ​PR #13958 on ​WordPress/wordpress-develop by ​@vidugupta.


2 weeks ago
#25

  • Keywords has-patch has-unit-tests added; needs-patch removed

Problem

Selecting many posts on the posts list adds post[]=ID for each one to the URL, because the bulk form submits with GET. With 999 posts per page the URL is about 15 KB, and the server rejects it with a 414 before PHP runs, so the bulk action never happens.

After a bulk trash, the redirect also carries every ID in ids=1,2,3,... only so that the Undo link can be built, which recreates the same problem on the way back.

Root Cause

The bulk action buttons submit the #posts-filter form, which is method="get" because it doubles as the filter and search form. edit.php already reads the selected IDs from $_REQUEST, so it never needed GET.

Switching the whole form to POST would break bookmarkable filtered views, and changing the base WP_List_Table for everyone would break plugin list tables whose handlers read $_GET. A fix has to move only the bulk action submissions, and only for core's own table.

The trash redirect adds ids unconditionally, which is why moving the request to POST alone is not enough for a large selection.

Solution

  1. Added WP_List_Table::get_bulk_actions_method():
    • Returns 'get' by default, so every existing list table keeps its current behavior.
    • bulk_actions() adds formmethod="post" to the Apply button only when it returns 'post'.
  2. WP_Posts_List_Table overrides it to return 'post'. The Empty Trash and bulk edit Update buttons also use formmethod="post", since they submit the selected rows too. The Filter button and the form itself stay GET.
  3. In edit.php the trash redirect now leaves ids out when the list is over 1000 characters. The IDs are only used for the Undo link, so the Undo link is skipped in that case and the trash itself still works.
  4. Added tests:
    • wpPostsListTable.php: the Apply button, the Empty Trash button and the bulk edit Update button each submit with POST.
    • wpCommentsListTable.php: a list table that does not opt in keeps the default form method.

Example Usage

// BEFORE: 999 selected posts become a single GET request.
GET /wp-admin/edit.php?s=...&action=trash&post[]=6&post[]=7&...   (14,932 characters)
-> 414 Request-URI Too Large
// AFTER: the bulk action is submitted as a POST to the current URL.
POST /wp-admin/edit.php?s=...   (post[] and action in the request body)

// 250 posts: no ids, no Undo link
-> edit.php?s=...&paged=1&trashed=250&locked=0                    (101 characters)

// 8 posts: Undo link kept
-> edit.php?...&trashed=8&ids=16,17,18,19,20,21,22,6&locked=0

Impact

  • A bulk action on a long selection of posts is no longer rejected for URL length.
  • Behavior for every other list table is unchanged. Plugin list tables keep submitting with GET unless they opt in through get_bulk_actions_method().
  • Filtering and searching still use GET, so filtered views remain bookmarkable.
  • Selections large enough to exceed the ID limit lose the Undo link on the redirect.
  • PHP's max_input_vars (default 1000) still limits a POST to about 1000 fields.

https://core.trac.wordpress.org/ticket/10762

Note: See TracTickets for help on using tickets.