正确删除带有元和附件的帖子

时间:2014-02-17 作者:4ndro1d

我有一个自定义帖子类型的概述。这些有海关税和附件。

在我的概述中,我需要提供删除条目的链接。这样,我还需要删除附件和元数据。

我用的是:

    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;
我发现Delete Post Link to delete post, its meta and attachments 但没有提供解决方案。

它不会删除帖子以外的任何内容。正确的方法是什么?

2 个回复
最合适的回答,由SO网友:David Gard 整理而成

@s\\u ha\\u dum建议Post meta将自动删除。因此,因为他的名声表明他知道自己在说什么,所以这个解决方案只处理帖子附件。

我建议检查一下before_delete_post() 钩子,因为它非常方便,可以检查哪些帖子类型正在被删除,等等。

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;

}
An important note from the aforementioned docs -

需要注意的是,钩子只有在WordPress用户清空垃圾时才会运行。如果使用此钩子,请注意,如果用户正在删除附件,则不会触发该钩子,因为附件是强制删除的,即不会发送到垃圾箱。而是使用delete_post()

Another note

我应该提到的是,虽然这个答案中的代码将删除数据库中与Post附件相关的所有行,但它实际上不会删除附件本身。

我的理由是性能。根据您拥有的附件数量,一次删除一个附件可能需要一段时间。我建议最好一开始只删除所有附件的数据库条目,以增强用户体验,然后在另一个时间运行一些单独的内部管理来删除实际的附件(搜索和删除非关联文件很容易)。基本上,更少的查询+用户体验期间更少的工作=更少的时间。

SO网友:Howdy_McGee

我使用此选项删除与post关联的媒体。如果要针对某个帖子类型进行测试,可以包括global $post_type 变量它几乎可以获取所有附件并逐个删除它们。Reference

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\' );

结束