web-dev-qa-db-ja.com

まったく新しい投稿のためのadd_actionフック?

publish_post投稿が公開されたとき、または投稿が編集され、そのステータスが "公開済み"の場合に実行されます。アクション関数の引数:投稿ID.

- プラグインAPIドキュメント

私が書いているWordPressプラグインにpublish_postフックを追加しました。フック自体によって呼び出される関数は、wp_update_post関数を使用して複数の投稿のカテゴリを変更することを目的としています。

Wp_update_postを実行すると返される結果は常に0なので、このフックは機能しません。私の最善の推測は、wp_update_postを実行すると、ポストが再発行されるために別のインスタンスが実行されることです。 "...またはそれが編集され、そのステータスが" published ""の場合上記のステートメント。

私が使用できる他のアクションフックは、追加された投稿がまったく新しく編集されていない場合にのみ呼び出されるものですか?

<?php
 /* 
 Plugin Name: Category Switcher Plugin
 Plugin URI: http://www.example.com
 Description: When a new post is created this plugin will cause the 
 Version: 0.1
 Author: Me
 License: GPL2 
?>
<?php
class categoryShifter {
  function shiftCategories($post_ID) {

    $maxNumPostsFirstTeir = 4;

    $first_teir_cat = "Fresh News Stories 1";
    $second_teir_cat = "Slightly Dated Stories 2";  

    $firephp = FirePHP::getInstance(true);

    $firephp->info('BEGIN: categoryShifter.shiftCategories()');

    $firephp->log($post_ID, 'post_ID: ');
    $firephp->trace('trace to here');    

    $first_teir_id = categoryShifter::getIDForCategory($first_teir_cat, $firephp); 
    $second_teir_id = categoryShifter::getIDForCategory($second_teir_cat, $firephp);

    $firephp->log($first_teir_id, '$first_teir_id');
    $firephp->log($second_teir_id, '$second_teir_id');   

    $qPostArgs = array(
      'numberposts' => 100,
      'order' => 'DESC', 
      'orderby' => 'post_date',
      'post_type' => 'post',
      'post_status' => 'published', 
      'category_name' => $first_teir_cat
    );

    $firstTeirPosts = get_posts($qPostArgs);   
    $firephp->log($firstTeirPosts, 'got posts:');

    $firephp->log(sizeof($firstTeirPosts), 'sizeof');


    // NOTE: This appears to work.
    for($i = sizeof($firstTeirPosts)-1; $i > $maxNumPostsFirstTeir-4; $i--) 
    {
      $newCats = array($second_teir_id);
      $editingId = $firstTeirPosts->ID;
      $result = wp_set_post_categories($editingId, $newCats); /* NOTE: Doesn't work presently... returns an array with the $second_teir_id in it. */
      $firephp->log($result, 'Result'); 
    }



    /*
    $my_post = array();
    $my_post['ID'] = 132;
    $my_post['post_category'] = array($second_teir_id);


    $firephp->log('Before', 'Before'); 
    if(wp_update_post( $my_post ) == 0) {
        $firephp->Error('Fatal Error, Post not updated', 'error');
    }
    $firephp->log('After', 'After');
    */
    return $post_ID;
  }


  function getIDForCategory($cat_name, $logger) {
    $logger->Info("Begin: getIDForCategory()");

    $cats = get_categories();      

    $whichCatId = "";

    foreach($cats as $single_cat) {
      if($single_cat->name == $cat_name) {
       $whichCatId = $single_cat->term_id;
       break;
      }
    }
    $logger->Info("End: getIDForCategory()");
    return (int)$whichCatId;
  }
}

/* Hook Post Creation */
/* add_action('publish_post', array('categoryShifter','shiftCategories')); */
add_action('wp_insert_post', array('categoryShifter', 'shiftCategories'));
?>

当分の間wp_insert_postフックを使用するようにしました...しかし私はまだ投稿のカテゴリを変更するためにwp_set_post_categories関数を得ることができません。

私はおそらくこのコードを更新して、投稿の既存のカテゴリーを考慮に入れ、プラグインで指定されたカテゴリーのみを変更する必要があることを理解していますが、今のところそれは本当に単なるアルファです。

6
leeand00
add_action('new_to_publish', 'your_function');
add_action('draft_to_publish', 'your_function');
add_action('pending_to_publish', 'your_function');
17
Pippin

正確にターゲットを絞った新しい投稿を作成することは、実際よりもトリッキーです。技術的には、投稿を作成または更新する方法は複数ありますが、技術的に投稿されたもの(たとえば改訂)もそれほど明白ではないものがたくさんあります。

WordPressは投稿作成だけでなく、それが何であったのか、そしてそれがどうなったのかを追跡する動的なフックを提供します。 Codexの ポストステータスの移行 を参照してください。

5
Rarst

私はWordPresssコアを詳しく読み、それをすべて試しました。 wp_transition_post_status()new_to_publish()new_{post_type}()wp_insert_post()

結局のところ、これらのすべてが信頼できません。

新しい投稿 "publish"は、新しい投稿の作成と既存の投稿の更新の両方のデフォルトの状態であるため、wp_transition_post_status()は信頼できません。何が新しい投稿であるのか、ドラフト、自動ドラフト、公開などが可能であるからではないのかを定義するのに古いステータスは信頼できません。

new_to_publish()はカスタム投稿タイプでは機能しません。

new_{post_type}はパラメータとして$ postを渡すだけです、そしてそれが新しいものか既存のものを更新しているかはわかりません。

wp_insert_post()には$ updateパラメータがあり、既存の投稿を更新する場合はTRUE、新しい投稿を作成する場合はFALSEにする必要があります。

私はこれをやってしまった:

/**
*   Do something when a new book is created
*/
function new_book($post_id, $post, $update) {
    if ($post->post_type == 'book' && $post->post_status == 'publish' && empty(get_post_meta( $post_id, 'check_if_run_once' ))) {
        # New Post

        # Do something here...

        # And update the meta so it won't run again
        update_post_meta( $post_id, 'check_if_run_once', true );
    }
}
add_action( 'wp_insert_post', 'new_book', 10, 3 );

必要に応じて、既存の投稿を "check_if_run_once"メタで更新する必要がある場合は、その関数を追加する前に作成された既存の投稿に対して上記のコードを実行しないでください。

/**
*   This is a temporary function to update existing posts with the "check_if_run_once" post meta
*   Access your website logged in as admin and add ?debug to the URL.
*/
function temporary_function() {
    if (current_user_can('manage_options')) {
        $posts = get_posts(array(
            'post_type' => 'book'
        ));
        foreach($posts as $post) {
            update_post_meta($post->ID, 'check_if_run_once', true);
        }
    }
}
if (isset($_GET['debug']));
    add_action('init', 'temporary_function');
1

ドキュメントに従うよりも実験的なことを使うと、これは私にとってはうまくいきます(WP 3.3)。新しい投稿を作成すると、$ new_statusが "auto-draft"に設定されたtransition_post_statusフック呼び出しが表示されます。

function my_post_new($new_status, $old_status=null, $post=null){
    if ($new_status == "auto-draft"){
        // do stuff here
    }
}
add_action('transition_post_status', 'my_post_new');
1
PapaFreud