web-dev-qa-db-fra.com

Supprimer correctement les publications avec méta et pièces jointes

J'ai un aperçu des types d'articles personnalisés. Ceux-ci ont une taxe douanière et aussi une pièce jointe.

Dans mon aperçu, je dois fournir des liens pour supprimer les entrées. Avec cela, je dois aussi supprimer la pièce jointe et les métadonnées.

J'utilisais ceci:

    if ( !current_user_can( 'delete_bkroadkill', $post->ID ) )
        return;

    $link = "<a href='" . wp_nonce_url( get_bloginfo('url') . "/wp-admin/post.php?action=delete&amp;post=" . $post->ID, 'delete-post_' . $post->ID) . "'>".$link."</a>";
    echo $before . $link . $after;

J'ai trouvé Delete Post Link pour supprimer post, sa méta et ses pièces jointes mais aucune solution n'a été fournie.

Ce qui ne supprimera rien d’autre que le message. Quelle est la bonne façon de faire cela?

7
4ndro1d

@s_ha_dum suggère que les méta-publications soient automatiquement supprimées. Par conséquent, comme sa réputation suggère qu'il sait de quoi il parle, cette solution ne gère que les pièces jointes Post.

Je suggérerais de consulter la documentation de before_delete_post () hook, car il est très pratique de pouvoir vérifier quel type de message est supprimé, etc.

add_action('before_delete_post', 'delete_post_attachments');
function delete_post_attachments($post_id){

    global $post_type;   
    if($post_type !== 'my_custom_post_type') return;

    global $wpdb;

    $args = array(
        'post_type'         => 'attachment',
        'post_status'       => 'any',
        'posts_per_page'    => -1,
        'post_parent'       => $post_id
    );
    $attachments = new WP_Query($args);
    $attachment_ids = array();
    if($attachments->have_posts()) : while($attachments->have_posts()) : $attachments->the_post();
            $attachment_ids[] = get_the_id();
        endwhile;
    endif;
    wp_reset_postdata();

    if(!empty($attachment_ids)) :
        $delete_attachments_query = $wpdb->prepare('DELETE FROM %1$s WHERE %1$s.ID IN (%2$s)', $wpdb->posts, join(',', $attachment_ids));
        $wpdb->query($delete_attachments_query);
    endif;

}

Une note importante tirée des documents susmentionnés -

Il est important de noter que le hook ne fonctionne que lorsque l'utilisateur WordPress vide la corbeille. Si vous utilisez ce hook, notez qu'il ne se déclenchera pas si l'utilisateur supprime une pièce jointe, car les pièces jointes sont forcées, c'est-à-dire non envoyées à la corbeille. Utilisez plutôt le delete_post () hook.

Une autre note

Je devrais mentionner que, bien que le code dans cette réponse supprime toutes les lignes de la base de données liées aux pièces jointes Post, il ne supprime pas réellement les pièces jointes elles-mêmes.

Mon raisonnement pour cela est la performance. Selon le nombre de pièces jointes que vous avez, leur suppression peut prendre un certain temps. Je suggère qu'il soit préférable de ne supprimer que les entrées de base de données de toutes les pièces jointes initialement pour améliorer l'expérience de l'utilisateur, puis d'exécuter plusieurs tâches de conservation distinctes à un autre moment pour supprimer les pièces jointes réelles (il est assez facile de rechercher et de supprimer des éléments non associés). des dossiers). Fondamentalement, moins de requêtes + moins de travail pendant l'expérience utilisateur = moins de temps.

5
David Gard

J'utilise ceci pour supprimer le média associé avec post. Si vous souhaitez tester un type de publication spécifique, vous pouvez inclure la variable global $post_type. En gros, il récupère toutes les pièces jointes et les supprime un par un. Référence

function delete_associated_media( $id ) {
    $media = get_children( array(
        'post_parent' => $id,
        'post_type'   => 'attachment'
    ) );

    if( empty( $media ) ) {
        return;
    }

    foreach( $media as $file ) {
        wp_delete_attachment( $file->ID );
    }
}
add_action( 'before_delete_post', 'delete_associated_media' );
9
Howdy_McGee