wp_delete_auto_drafts() deletes links in menus

Since yesterday the wp_scheduled_auto_draft_delete cron job somehow deletes all page entries from our menus. All entries in the table wp_postmeta with meta_key = '_menu_item_object' and meta_value = 'page' get deleted in the process. By tracing back the DELETE query I found out that the menu entries are deleted by a function called _wp_delete_post_menu_item. I got the following stacktrace for that function:

#0  _wp_delete_post_menu_item(3244)
#1  call_user_func_array(_wp_delete_post_menu_item, Array ([0] => 3244))
called at [/srv/www/htdocs/biva/wp-includes/plugin.php:470]
#2  do_action(delete_post, 3244) called at
[/srv/www/htdocs/biva/wp-includes/post.php:2483]
#3  wp_delete_post(3244, 1) called at
[/srv/www/htdocs/biva/wp-includes/post.php:5645]
#4  wp_delete_auto_drafts()
#5  call_user_func_array(wp_delete_auto_drafts, Array ()) called at
[/srv/www/htdocs/biva/wp-includes/plugin.php:546]
#6  do_action_ref_array(wp_scheduled_auto_draft_delete, Array ()) called
at [/srv/www/htdocs/biva/wp-cron.php:100]

But I’m stuck here, I’m not a wordpress developer and I have no clue why deleting old drafts results in deleting attached menu entries although the main pages still exist.

Workaround:
As a workaround we added the following to the top of wp-config, wich will disable wp-cron:

/** Disable wp-cron to prevent menu from getting deleted. Detailed Bug description:
http://wordpress.stackexchange.com/questions/145953 **/
define('DISABLE_WP_CRON', true);

If you are experiencing similar difficulties you might try locking the rows in the table wp_postmeta with meta_key = '_menu_item_object' and meta_value = 'page' and then tracing back the error message when WP trys to delete these rows, that’s how we nailed down our error.

Reproduce the Error:
It is definitely the stealth publish plugin that is causing our error, one can easily reproduce it, by doing the following:

  1. Install a fresh WordPress 3.9.1.
  2. Install the stealth publish plugin http://wordpress.org/plugins/stealth-publish.
  3. Create a few test pages and add them to a new menu.
  4. Create a new page, with some dummy content, but do not save it!. Leave the page without saving.
  5. Change the system time 8 days into the future.
  6. The wp_scheduled_auto_draft_delete cron job will run because it runs daily and it hasn’t run for 7 days as soon as you visit your page. It will then find your never saved dummy page delete it as it is older than 7 days and the menu will vanish.
  7. You might need to refresh the page a few times till the effect becomes visible.

I’ve recorded a screencast on how to reproduce the error (but I took not the time to comment it): http://www.youtube.com/watch?v=R9CTggjIfDY

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

This is what normal query run by wp_get_associated_nav_menu_items() looks like:

SELECT wp_posts.* 
FROM   wp_posts 
       INNER JOIN wp_postmeta 
               ON ( wp_posts.id = wp_postmeta.post_id ) 
WHERE  1 = 1 
       AND wp_posts.post_type = 'nav_menu_item' 
       AND (( wp_posts.post_status <> 'trash' 
              AND wp_posts.post_status <> 'auto-draft' )) 
       AND (( wp_postmeta.meta_key = '_menu_item_object_id' 
              AND Cast(wp_postmeta.meta_value AS CHAR) = '3111' )) 
GROUP  BY wp_posts.id 
ORDER  BY wp_posts.post_date DESC

This is what yours looks like:

SELECT wp_posts.* 
FROM   wp_posts 
       INNER JOIN wp_postmeta 
               ON ( wp_posts.id = wp_postmeta.post_id ) 
       LEFT JOIN wp_postmeta AS mt1 
              ON ( wp_posts.id = mt1.post_id 
                   AND mt1.meta_key = '_stealth-publish' ) 
       INNER JOIN wp_postmeta AS mt2 
               ON ( wp_posts.id = mt2.post_id ) 
WHERE  1 = 1 
       AND wp_posts.post_type = 'nav_menu_item' 
       AND (( wp_posts.post_status <> 'trash' 
              AND wp_posts.post_status <> 'auto-draft' )) 
       AND ( ( wp_postmeta.meta_key = '_menu_item_object_id' 
               AND Cast(wp_postmeta.meta_value AS CHAR) = '3244' ) 
              OR mt1.post_id IS NULL 
              OR ( mt2.meta_key = '_stealth-publish' 
                   AND Cast(mt2.meta_value AS CHAR) != '1' ) ) 
GROUP  BY wp_posts.id 
ORDER  BY wp_posts.post_date DESC

It would be my guess that _stealth-publish stuff has no business whatsoever interfering with querying for nav menu items.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x