web-dev-qa-db-ja.com

Save_postアクションでの更新と新規投稿の確認

Save_postアクション内で、新しい投稿が作成されているのか、既存の投稿が更新されているのかを判断することは可能ですか。

21
hereswhatidid

設定する前に、カスタム値の存在を確認するだけになりました。そのように、それが新しく作成された投稿であるならば、カスタム値はまだ存在しないでしょう。

function attributes_save_postdata($post_id) {
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
  if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
  if ('page' == $_POST['post_type']) {
    if (!current_user_can('edit_page', $post_id)) return;
  } else {
    if (!current_user_can('edit_post', $post_id)) return;
  }
  $termid = get_post_meta($post_id, '_termid', true);
  if ($termid != '') {
    // it's a new record
    $termid = 'update';
  } else {
    // it's an existing record
  }
  update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
6
hereswhatidid

WordPressバージョン3.7以降。 - IIRC - save_postフック - コードリファレンス:save_post および コード参照:save_post でのフックとその使用方法の詳細 - ちょうどそのことを判断するために使用できる3番目のパラメータ$updateを持つ。

@param int $ post_ID投稿ID。
@param WP_Post $ postポストオブジェクト。
@ param bool $ updateこれが更新中の既存の投稿かどうか。


注:

$updateは常にtrueであるとは限りません - あなたはそれを以下のコードで見てテストすることができます。それはおそらく十分に文書化されておらず、おそらく最適名からは程遠いので、誤解を招くような期待を生み出します。以下のコードはデバッグに使用することができます、そうでなければ情報/メッセージを見ることができないので、コード実行をいつ傍受するかを試してみてください。詐欺的な行動の原因はリビジョンと自動保存の処理にあると思います - 無効にすることもできますが、お勧めしませんし、テストもしていません。これが Trac Ticket を保証するものであるかどうかわからないので、私はそれを開かなかった、あなたがそう思うならば、リンクをたどってあなた自身でそれをしてください。それ以外に、コメントに記載されているように、あなたが特定の問題を抱えているならば、新しい質問を投稿してください。

add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {

  echo '<pre>';
  print_r( $post ); echo '<br>';
  echo '$update == ';
  echo $update ? 'true' : 'false';

  //conditions
  if( ! $update && $post->post_status == "auto-draft" ) {
    // applies to new post
    echo ' && $post->post_status == "auto-draft"';
    //die();
  } else if ( ! $update ) {
    // applies basically to the (auto saved) revision 
    //die();
  } else {
    // applies to updating a published post
    // when there is a revision, which is normally the case, 
    // standard behavior of WordPress, then it is considered 
    // an update, which is where the confusion sets in
    // there are other methods, like checking time or post status
    // depending on your use case it might be more appropriate 
    // to use one of those alternatives 
    //die();
  }

  echo '</pre>';
  //die();
}
15
Nicolai

私が(フックされた機能の中で)このチェックを実行する方法は、投稿日と修正日を比較することです(標準化のためにGMTで)

function check_new_vs_update( $post_id ){
    $myPost        = get_post($post_id);
    $post_created  = new DateTime( $myPost->post_date_gmt );
    $post_modified = new DateTime( $myPost->post_modified_gmt );

    if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
        // New post
    }else{
        // Updated post
    }
}
add_action('save_post', 'check_new_vs_update' );

これは、作成時でさえも投稿に '修正'日付が添付されているために機能します。これは '作成'日付とまったく同じです。ポスト。

11
James Cushing

"update"パラメータを使用したalocin回答の例:

function save_func($ID, $post,$update) {

   if($update == false) {
     // do something if its first time publish
   } else {
     // Do something if its update
   }
}

add_action( 'save_post', 'save_func', 10, 3 );
4

Darshan Thankiが示唆したように(そしてStephen Harrisがさらに詳しく述べたように)、pre_post_updateをあなたの有利に使うことができます。

global $___new_post;
$___new_post = true;

add_action(
  'pre_post_update',
  function() {
    global $___new_post;
    $___new_post = false;
  },
  0
);

function is_new_post() {
  global $___new_post;
  return $___new_post;
}

私がグローバルを使用したのは、function is_new_post() use ( &$new_post )がPHPでは無効なためです(衝撃的です)。そのため、その変数を関数スコープに取り込むのはうまくいきません。つまりグローバルです。

これは実際にはsave_postイベントの中/後にしか確実に使用することができないことに注意してください(通常これで十分です、少なくともこれを使ってやっていることには十分です)。

1
Qix

更新コードにはpre_post_updateアクションフックを、新しい投稿コードにはsave_postを使用できます。投稿が更新される前に機能します。

1
Darshan Thanki

組み込み関数を使用し、データベースに追加しない別のアプローチはget_post_status()を含みます。

$post_status = get_post_status();
if ( $post_status != 'draft' ) {
    //draft
} else { 
    //not a draft: can be published, pending, etc. 
}

ただし、後でステータスを "ドラフト"に戻す予定がある場合は適切ではない可能性があります。次回投稿を更新するときに指示が繰り返されます。状況に応じて、より適切なシナリオを構築するためにget_post_status()によって返される可能性があるさまざまな文字列を検討することをお勧めします。

get_post_status() および Post Status のCodexを参照してください。

可能な値は次のとおりです。

  • 'publish' - 公開された投稿またはページ
  • 'pending' - 投稿はレビュー待ちです
  • 'ドラフト' - ドラフト状態の投稿
  • 'auto-draft' - 新しく作成された投稿、内容なし
  • '未来' - 将来出版する記事
  • 'private' - ログインしていないユーザーには見えません
  • '継承' - リビジョン。 get_childrenを参照してください。
  • 'trash' - 投稿はゴミ箱に入っています。バージョン2.9で追加されました。
0
John112

Save_postが起動されると、その投稿に関するすべての情報がすでに利用可能になるので、理論的には次のようにします。

function f4553265_check_post() {

    if (!get_posts($post_id)) {
    // if this is a new post get_posts($post_id) should return null
    } else {
    // $post_id already exists on the database
    }
}
add_action('save_post','f4553265_check_post');

これはまだテストされていません。 =)

0
moraleida