web-dev-qa-db-ja.com

メタと添付ファイルのある投稿を正しく削除する

カスタム投稿タイプの概要を説明しています。これらは税金と添付ファイルを持っています。

私の概要では、エントリを削除するためのリンクを提供する必要があります。それに伴い、添付ファイルとメタデータも削除する必要があります。

私はこれを使っていました:

    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 しかし解決策が提供されていない。

これは投稿以外に何も削除しません。これを行うための適切な方法は何ですか?

7
4ndro1d

@s_ha_dumはPostメタが自動的に削除されることを示唆しています。したがって、彼の評判は自分が何を話しているのかを知っていることを示唆しているので、このソリューションではPost添付ファイルのみを処理します。

どのPost Typeが削除されているのかなどをチェックするのはとても便利なので、 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;

}

前述の文書からの重要なメモ -

フックはWordPressユーザーがゴミ箱を空にしたときにのみ実行されることに注意することが重要です。このフックを使用している場合、添付ファイルは強制的に削除されるので、ユーザーが添付ファイルを削除しても起動しません。つまり、ゴミ箱には送信されません。代わりに delete_post() フックを使用してください。

もう1つの注意事項

この回答のコードではPost添付ファイルに関連するデータベースからすべての行が削除されますが、実際には添付ファイル自体は削除されません。

これに対する私の推論はパフォーマンスです。添付ファイルの数によっては、一度に1つずつ削除するのに時間がかかる場合があります。ユーザーエクスペリエンスを向上させるために、最初にすべての添付ファイルのデータベースエントリを削除し、次に別のハウスキーピングを実行して実際の添付ファイルを削除することをお勧めします。ファイル)。基本的に、ユーザーエクスペリエンス中のクエリ数の減少と作業時間の短縮=時間の短縮。

5
David Gard

私はこれを使って投稿に関連するメディアを削除します。特定の投稿タイプに対してテストしたい場合は、global $post_type変数を含めることができます。ほとんどすべての添付ファイルを取得し、それらを1つずつ削除します。 参照

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