Make WordPress Core

Opened 6 years ago

Closed 6 years ago

#12473 closed defect (bug) (fixed)

_wp_old_slug not updated when updating post_name via quick edit

Reported by: mbarklund Owned by:
Milestone: 3.0 Priority: low
Severity: major Version: 2.9.2
Component: Quick/Bulk Edit Keywords:
Focuses: Cc:


I had a hard time tracking down the flow of data from post update to recording _wp_old_slug in wp_postmeta but tracked the issue down to:

When a post is edited via the "normal" full-featured form, the previous slug (post_name) is included in the hidden form field "wp-old-slug" via template.php:wp_remember_old_slug() called from action in default-filters.php:add_action('edit_form_advanced', 'wp_remember_old_slug');

When this field is present in the post data, the action handler wp-includes/post.php:wp_check_for_changed_slugs() makes sure to record the old slug in wp_postmeta, if different from the new slug.

But this field, $_POST['wp-old-slug'], is not present when updating the post via Quick Edit (form rendered via template.php:inline_edit_row). This form does not have a wp-old-slug hidden field, neither do the inline-edit-data rendered for each individual row and the inline-edit-post.js knows nothing about such a variable. This extra variable should be added in all three places as far as I can see, and then it would probably work correctly "out of the box" without further hacks.

One hack that does not require it to be added to the inline-post-data (rendered in template.php:get_inline_data) as it is initially identical to post_name, instead requires that inline-edit-post.js just transfers post_name to two input fields in the general form (one of them with name=wp-old-slug and type=hidden).

And one completely other possibility is adding $_POST['wp-old-slug'] in admin-ajax.php when handling action 'inline-edit'/'inline-save' by reading current post_name from DB and if different from submitted, store old post_name as $_POST['wp-old-slug'].

This bug caused great annoyances for me, as I changed my slug naming scheme at some point and edited a bunch of posts via Quick Edit - now these posts do not answer on the previous URL's as _wp_old_slug was not recorded for these.

Finally, somewhat related to this, I find that _wp_old_slug works very inconsistently. It seems to be able to save multiple old slugs, but that sometimes fails. Haven't been able to pinpoint when it does and when it doesn't, but have just experienced a lot of inconsistency.

Change History (8)

#1 @nacin
6 years ago

  • Milestone changed from Unassigned to 3.0

#2 @dd32
6 years ago

This could be simplified with the addition of a transition hook, For example:

do_action('updated_post', $id, $new_post_array, $old_post_array);

It would then be possible for the old slug memory function (wp_check_for_changed_slugs()) to not rely upon a hidden POST field.. the data is already stored on the server, its just a matter of passing the right data.

there is the 'pre_update_post' action, which only passes the post_id, and then the edit_post hook (which the above function is hooked to) but by that stage, its too late to retrieve the original post object, not only that, but its also used in a few locations for various meaning.

#3 @westi
6 years ago

  • Keywords needs-patch added; wp-old-slug removed

I the idea of hooking on an old/new data action as dd32 suggests.

#4 @westi
6 years ago

I had a quick look at what would be required to do this using the current process and it looks like adding a lot of code all over the place including js changes etc.

Therefore it definitely looks like a new hook is the best method for this.

#5 @dd32
6 years ago

I do have a patch which does this locally.

I'm currently using

$post_after = get_post($post_ID);
do_action( 'post_updated', $post_ID, $post_after, $post_before);

Any opinions on hook name?

#6 @westi
6 years ago

Just a name which details where the hook runs.

So if the update has already run then call it post_updated if it hasn't run call it pre_update_post

#7 @dd32
6 years ago

(In [14814]) Introduce a 'post_updated' action, Fires when a post is updated, Post ID, Current and Previous post objects are passed. Updatewp_check_for_changed_slugs() to use new hook. See #12473

#8 @dd32
6 years ago

  • Keywords needs-patch removed
  • Resolution set to fixed
  • Status changed from new to closed

I've tested Normal Edits, and Quick Edit. I cant see any problems with plugins updating posts (If anything, This may actually fix some which were not saving slugs on code-based updates, as rare as that may be).

Closing as fixed.

Note: See TracTickets for help on using tickets.