web-dev-qa-db-ja.com

ポストパブリッシュの投稿リビジョンを削除する

投稿/ページが公開されたときにデータベースから投稿/ページのリビジョンを削除することは可能ですか?

11/05/12答え:bueltgeの下のプラグインを見てください

5,000件の投稿と125,000件のコメントがあるサイトでこれを行いたいと思います。それはVPS上にあり、wp_postsテーブルサイズを扱うことができます - 私はすべてのリビジョンを削除する前に、テーブルは1.5ギグでした - しかし、私はまだリビジョンを防ぐことによって全体的なデータベースサイズを最小に保ちたいです。

しかし、クライアントは、ブラウザがフリーズしたために大きな投稿を失ったことを私に伝えています。それで、それが公開されるとき、投稿/ページごとにデータベースから投稿/ページリビジョンを削除することは可能ですか?

どんなフックが使われるでしょうか? save_postは正しいものですか? http://codex.wordpress.org/Plugin_API/Action_Reference/save_post

私はwp-config.phpでautosaveパラメータを設定していますが、docsによれば、作業中の投稿/ページを自動保存し、各自動保存を上書きします。

私がやりたいことは下書きのためにリビジョンを蓄積させることです - しかし、何回も "Save"と "Update"が作者によって使われるかに依存します - しかし下書きが公開されたら、すべてのリビジョンを削除します。 1つの投稿に対してのみリビジョンがありますが、post_IDを試して解析するのではなく、すべての投稿に対してSQLクエリを実行できます。

これはfunctions.phpで試していることですが、Call to a member function query() on a non-objectエラーが出ます。

function delete_revisions_on_publish( $post_id ) {

    if ( !wp_is_post_revision( $post_id ) ) {

remove_action('save_post', 'delete_revisions_on_publish');

    $wpdb->query( 
    $wpdb->prepare( 
    "DELETE a,b,c
    FROM wp_posts a
    LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id)
    LEFT JOIN wp_postmeta c ON (a.ID = c.post_id)
    WHERE a.post_type = 'revision' "
        )
);
        }
}
add_action( 'save_post', 'delete_revisions_on_publish' );
1
markratledge

フック 'publish_posts'を持つ小さなプラグインで十分だと思います。しかし、私はリビジョンを削除するためのコア関数について知らないし、私はWP関数でクエリを使います。ソースはテストされておらず、この記事のために書かれています。

<?php
/**
 * Plugin Name: WPSE71248 Delete Revisions on Publish Posts
 * Plugin URI:  http://wordpress.stackexchange.com/questions/71248/
 * Description: 
 * Version:     1.0.0
 * Author:      Frank Bültge
 * Author URI:  http://bueltge.de
 * License:     GPLv3
 */

! defined( 'ABSPATH' ) and exit;

add_action( 'publish_post', 'fb_remove_revisions' );

function fb_remove_revisions( $post_id = FALSE ) {

    $post_id = (int) $post_id;

    $revisions = '';
    // Get the revisions
    $revisions = new WP_Query( array(
        'post_status'    => 'inherit',
        'post_type'      => 'revision',
        'showposts'      => -1,
        'posts_per_page' => -1,
        'post_parent'    => $post_id
    ) );

    if ( empty( $revisions ) )
        return $post_id;

    // Remove the revisions the non-core-way
    global $wpdb;
    foreach ( $revisions->posts as $revision ) {
        $query = $wpdb->prepare(
            "
            DELETE FROM $wpdb->posts 
            WHERE ID = %d
            AND post_parent = %d
            ",
            $revision->ID, 
            $post_id
        );
        $wpdb->query( $query );
    }

    return $post_id;
}

代わりに Gist 4017151 からダウンロードを使用する

5
bueltge

私はそれを達成するために異なるアプローチを好むでしょう。グローバルな$wpdbを使用して直接DBにアクセスし、リビジョンを削除するのではなく、WP関数を使用しました。次のコードは、Publishをサポートし、Updateステータスを持つすべての投稿タイプのrevisionsまたはpublishに対するリビジョンを削除します。

add_action( 'admin_init', 'add_delete_revision_actions' );
function add_delete_revision_actions () {

    // get all post types, except 'revision'
    $post_types = get_post_types( array( 'exclude_from_search' => false ) );

    // add action for each post type that supports 'revisions'
    foreach ($post_types as $post_type) {
        if ( post_type_supports( $post_type, 'revisions' )) {
            add_action("publish_$post_type", 'delete_revisions_on_publish', 10, 1);
        }
    }
}

function delete_revisions_on_publish ($post_id) {

    // get revisions for this post
    $revisions = wp_get_post_revisions($post_id);

    // .. and delete it
    foreach ($revisions as $revision) {
        $delete = wp_delete_post_revision($revision->ID);
        // check for errors
        // if ( is_wp_error($delete) ) { ... }
    }
}
1
Ahmad M

それは可能であるべきであり、それはあなたが正しい軌道に乗っているように見えます。

「メンバー関数への呼び出し」エラーを解決するには、その関数の先頭にglobal $wpdb;が必要だと思います。

以前はpublish_post として知られていたフックが、公開された投稿に固有のものであるため、より良いフックになると思います。 save_postはすべての保存に対して実行されます。

また、 "SQLクエリはすべての投稿に渡って実行できる"と言っていますが、作品に複数の投稿がある場合、または下書きがある間に公開投稿に編集を保存すると、すべての下書きのリビジョンが消去されます作品集。とにかく、それはあなたの選択です、しかし、あなたがそうするならば、あなたは$wpdb->prepareを全く必要としません。ハードコードされたSQL文字列以外の入力はないので、何も「準備」する必要はありません。

$wpdb->query( 
    $wpdb->prepare( 
    "DELETE a,b,c
    FROM wp_posts a
    LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id)
    LEFT JOIN wp_postmeta c ON (a.ID = c.post_id)
    WHERE a.post_type = 'revision' 
    AND a.ID = %d",
    $post_id
  )
);
0
s_ha_dum