web-dev-qa-db-fra.com

wp_delete_auto_drafts () supprime les liens dans les menus

Depuis hier, le travail wp_scheduled_auto_draft_delete cron supprime en quelque sorte toutes les entrées de page de nos menus. Toutes les entrées de la table wp_postmeta avec meta_key = '_menu_item_object' et meta_value = 'page' sont supprimées au cours du processus. En retraçant la requête DELETE, j'ai découvert que les entrées de menu étaient supprimées par une fonction appelée _wp_delete_post_menu_item. J'ai reçu le stacktrace suivant pour cette fonction:

#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]

Mais je suis coincé ici, je ne suis pas un développeur wordpress et je ne sais pas pourquoi la suppression d'anciens brouillons entraîne la suppression d'entrées de menu attachées bien que les pages principales existent toujours.

Solution de contournement: Comme solution de contournement, nous avons ajouté ce qui suit en haut de wp-config, ce qui désactivera 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);

Si vous rencontrez des difficultés similaires, vous pouvez essayer de verrouiller les lignes de la table wp_postmeta avec meta_key = '_menu_item_object' et meta_value = 'page', puis de retracer le message d'erreur lorsque WP essaie de supprimer ces lignes. C'est ainsi que nous avons corrigé notre erreur.

Reproduit l'erreur: C'est certainement le plug-in de publication furtive qui cause notre erreur, on peut facilement la reproduire en procédant comme suit:

  1. Installez un nouveau Wordpress 3.9.1.
  2. Installez le plug-in de publication furtive http://wordpress.org/plugins/stealth-publish .
  3. Créez quelques pages de test et ajoutez-les à un nouveau menu.
  4. Créez une nouvelle page, avec du contenu factice, mais ne la sauvegardez pas! . Quitter la page sans sauvegarder.
  5. Changez l'heure du système 8 jours dans le futur.
  6. Le travail cron wp_scheduled_auto_draft_delete sera exécuté car il est exécuté quotidiennement et il ne s’est pas exécuté depuis 7 jours dès que vous visitez votre page. Il trouvera ensuite votre page factice jamais enregistrée, supprimez-la car elle date de plus de 7 jours et le menu disparaîtra.
  7. Vous devrez peut-être actualiser la page plusieurs fois jusqu'à ce que l'effet devienne visible.

J'ai enregistré un screencast sur la façon de reproduire l'erreur (mais je n'ai pas pris le temps de le commenter): http://www.youtube.com/watch?v=R9CTggjIfDY

5
Gellweiler

Voici à quoi ressemble une requête normale exécutée par wp_get_associated_nav_menu_items() :

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 

Voici à quoi ressemble le tien:

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 

Je pense que _stealth-publish n'a absolument aucune raison d'interférer avec la recherche d'éléments de menu de navigation.

5
Rarst