web-dev-qa-db-ja.com

時間の経過後に投稿カテゴリを操作する

与えられた時間での投稿カテゴリ操作に関するいくつかの投稿を読んだ後、私は日付後に投稿を操作するプラグインを作りたいと思いました。私の元の投稿の参照は6年前のものです: " 投稿日に基づいて投稿のカテゴリを変更するためのプラグイン? "しかし、私は操作に関していくつかの投稿を参照しました:

ただし、カテゴリを削除して新しいカテゴリを追加するわけではありません。

コード:

function check_if_cat_has_reached_time() {
    // test if term exists and if doesn't return
    $test_term1 = term_exists('Uncategorized', 'category');
    if ($test_term1 !== 0 && $test_term1 !== null) :
        // $default_cat = get_term_by('id', 'Uncategorized', 'category');
        $default_cat = get_cat_ID('uncategorized');
    else :
        return;
    endif;

    // test if term exists and if doesn't return
    $test_term2 = term_exists('failed', 'category');
    if ($test_term2 !== 0 && $test_term2 !== null) :
        $new_cat = get_cat_ID('failed');
    else :
        return;
    endif;

    global $post;

    // the Post ID
    $the_ID = $post->ID;

    // Post creation time in Epoch
    // $post_creation   = get_the_time('U',$the_ID);
    // current time in Epoch
    $current_time = time();

    // two years in Epoch
    $two_years = 31556926*2;

    // post time plus two years
    $post_plus_two = (int)$two_years + (int)get_the_time('U',$the_ID);

    if ($current_time >= $post_plus_two && has_category($default_cat,$the_ID)) :
        wp_remove_object_terms($the_ID, $default_cat, 'category');
        $update_post_cat = array(
            'post_category' => array($new_cat),
        );
        wp_insert_post($update_post_cat);
    endif;
}
add_action('save_post', 'check_if_cat_has_reached_time');

wp_remove_object_terms()が機能しない理由はありますか? 記事から特定のカテゴリを削除して を読んだ後にこれを使用しました。

だから私の質問は次のとおりです。

  • カテゴリを正しく削除しますか?
  • カテゴリーを正しく更新していますか?
  • プラグインの投稿を操作するためのより良いフックはありますか?
  • 数千の投稿があるサイトにこれを実装した場合、パフォーマンス上の問題はありますか?

EDIT:

以下の答えは私が私のテーマのfunction.phpに実装しようとしました、しかしそれはまだうまくいきません。デフォルトのテーマを WP Test で使用しています。機能の前に私はカテゴリを必ず作成します。

function create_foo_category() {
    wp_insert_term(
        'Foo',
        'category',
        array(
            'description'   => 'This is the Foo',
            'slug'          => 'foo'
        )
    );
}
add_action('after_setup_theme', 'create_foo_category');

barの場合:

function create_bar_category() {
    wp_insert_term(
        'Bar',
        'category',
        array(
            'description'   => 'This is the bar',
            'slug'          => 'bar'
        )
    );
}
add_action('after_setup_theme', 'create_bar_category');

私は提供された答えを操作しようとしました:

function check_if_cat_has_reached_time() {
    global $post; 

    $the_ID = $post->ID;

    if (!wp_is_post_revision($the_ID)) {

    // unhook this function so it doesn't loop infinitely
    remove_action('save_post', 'check_if_cat_has_reached_time');

    // test if term exists and if doesn't return
    $check_default_cat = term_exists('Foo', 'category');
    if ($check_default_cat !== 0 && $check_default_cat !== null) {
        $default_cat = get_cat_ID('foo');
    } else {
        return;
    }

    // test if term exists and if doesn't return
    $check_new_cat = term_exists('Bar', 'category');
    if ($check_new_cat !== 0 && $check_new_cat !== null) {
        $new_cat = get_cat_ID('bar');
    } else {
        return;
    }

    // current time in Epoch
    $current_time = time();

    // two years in Epoch
    $two_years = 31556926*2;

    // post time plus two years
    $post_plus_two = (int)$two_years + (int)get_the_time('U',$the_ID);

    if ($current_time >= $post_plus_two && has_category($default_cat,$the_ID)) {
        wp_remove_object_terms($the_ID, $default_cat, 'category');
        $args = array(
            'ID'            => $the_ID,
            'post_category' => array($new_cat),
        );
        wp_update_post($args);
    }

    // re-hook this function
    add_action('save_post', 'check_if_cat_has_reached_time');
    }
}
add_action('publish_post', 'check_if_cat_has_reached_time');

EDIT:

何人かの人々と話をした後、私は上記の意図された目的が何のためにあるのか多少不明確だったと思います。毎日のようなイベントで実際に投稿することなく投稿を修正しようと思っています。この問題についてさらに議論した後、私は wp_schedule_event() に気付かされ、私はテストして編集するつもりです。

あなたの現在の関数はかなりうまく機能しますが、それは投稿更新フックにフックされているのでそれを実行するためには実際に投稿を編集/更新する必要があります。指定した時間の経過後に投稿を自動的に修正したい場合は、予定されたイベントを設定する必要があります。スケジュールを設定する方法は2つ考えられます。

1.all(関連する)投稿をチェックする定期的な予定

wp_schedule_event() を使用して、指定した間隔でフックで実行できます。

// a custom hook to schedule
add_action( 'wpse_269529_check_posts', 'wpse_269529_check_posts_cats' );

// make sure the event hasn't been scheduled
if( !wp_next_scheduled( 'wpse_269529_check_posts' ) ) {

    // Schedule the event
    wp_schedule_event( time(), 'daily', 'wpse_269529_check_posts' );
}

wp_schedule_event()のパラメータは(順番に)です。最初のイベントが実行されるタイミング(今から実行するためにtime()を渡すことができます)、それらが実行される頻度( "hourly"、 "twicedaily"、 "daily"のいずれか)、そして実行するフック。いくつかの引数を渡すこともできますが、それは必要ありません。

イベントがまだスケジュールされていないことを確認するために wp_next_scheduled() も使用します。

それから、そのフックで動作する関数が必要です。これを使用して、置換したいカテゴリを持つすべての投稿をループ処理し、それらを新しいカテゴリで更新します。

function wpse_269529_check_posts_cats() {

    //categories
    $old_cat = get_cat_ID( 'foo' );
    $new_cat = get_cat_ID( 'bar' );

    // get all posts with the required category
    $args = array( 'posts_per_page' => -1, 'category' => $old_cat );
    $myposts = get_posts( $args );

    // loop through all posts and update with new category
    foreach ( $myposts as $mypost ) {
        $args = array(
            'ID'            => $mypost->ID,
            'post_category' => array( $new_cat ),
        );
        wp_update_post($args);
    }
}

あなたはパフォーマンスについて言及します、そしてこれはカテゴリでallpostsを通してループを実行します、それで多分それはおそらく最良の選択肢ではありません...

2.単一の予定されたイベント投稿ごと

wp_schedule_single_event() でそれをすることができ、投稿作成のスケジュールを作成することができます(ただし、既存の投稿ではなく新規投稿にのみ有効です)。スケジュールを設定する関数をpublish_postにフックします。

// runs when a post is published
add_action( 'publish_post', 'wpse_269529_schedule_post_check' );

function wpse_269529_schedule_post_check( $post_id ) {

    // set the time when the event should be scheduled
    $timestamp = strtotime( '+2 years' );

    // Schedule the event
    wp_schedule_single_event( $timestamp, 'wpse_269529_check_post', array( $post_id ) );    
}

これを publish_post にフックしたので、投稿IDをスケジュールされたイベントに渡し、それに基づいてその投稿を更新することができます(アクションフックのパラメータの数をIDに対して "1"に設定することを忘れないでください):

// a custom hook to schedule
add_action( 'wpse_269529_check_post', 'wpse_269529_check_post_cats', 10, 1 );

// replace post categories
function wpse_269529_check_post_cats( $post_id ) {

    //categories
    $old_cat = get_cat_ID( 'foo' );
    $new_cat = get_cat_ID( 'bar' );

    // check for the old category
    if ( has_category( $old_cat, $post_id ) ) {
        // update post with new category
        $args = array(
            'ID'            => $post_id,
            'post_category' => array( $new_cat ),
        );
        wp_update_post($args);
    }
}

この2つの組み合わせを使用して、プラグインまたはテーマの有効化に関する既存のすべての投稿(またはこれを行うタイミング、理由、方法に応じてその他のもの)をループしてから、すべての新しい投稿を投稿ごとに更新するようにスケジュールできます。

1
Cai

save_postフックはポストのIDをそのコールバック関数に渡すので、get_the_ID()を使う必要はありません。

wp_insert_post()を使用すると、投稿を保存するたびに新しい投稿がデータベースに挿入されます。代わりにwp_update_post()を使用してください。

function check_if_cat_has_reached_time($post_id) {
    if ( ! wp_is_post_revision( $post_id ) ){

        // unhook this function so it doesn't loop infinitely
        remove_action('save_post', 'check_if_cat_has_reached_time');

        // test if term exists and if doesn't return
        $check_default_cat = term_exists('Uncategorized', 'category');
        if ($check_default_cat !== 0 && $check_default_cat !== null) {
            $default_cat = get_cat_ID('uncategorized');
        } else {
            return;
        }

        // test if term exists and if doesn't return
        $check_new_cat = term_exists('failed', 'category');
        if ($check_new_cat !== 0 && $check_new_cat !== null) {
            $new_cat = get_cat_ID('failed');
        } else {
            return;
        }

        // post time plus two years
        $post_plus_two = strtotime('+2 years') + strtotime(get_the_date('Y-M-d',$post_id));

        if (strototime(date('Y-M-d')) >= $post_plus_two && has_category($default_cat,$post_id)) {
            wp_remove_object_terms($post_id, $default_cat, 'category');
            $args = array(
                'ID' => $post_id,
                'post_category' => array($new_cat),
            );
            wp_update_post($args);
        }

        // re-hook this function
        add_action('save_post', 'check_if_cat_has_reached_time');
    }
}
add_action('publish_post', 'check_if_cat_has_reached_time');

remove_actionは呼び出されるたびにwp_update_postフックを起動するので、save_postの部分は重要です。したがって、無限ループを作成することが可能です。

1
Jack Johansson