save_postアクションで更新と新しい投稿を確認する


21

save_postアクション内で、新しい投稿が作成されているのか、既存の投稿が更新されているのかを判断できますか?


これは可能だとは思いません。@moraleidaの答えの下に私のコメントを参照してください。なぜ新しい投稿なのか、更新されているのかを知る必要があるのですか?回避策または代替アプローチがあるかもしれません。
スティーブンハリス

回答:


16

WordPressバージョン3.7以降。-IIRC- save_postフック-Code Reference:save_postおよびCodex:save_postでのフックとその使用に関する詳細 - $updateそれを決定するために使用できる3番目のパラメーターがあります。

@param int $ post_ID投稿ID。
@param WP_Post $ post Postオブジェクト。
@param bool $ updateこれが更新される既存の投稿であるかどうか。


注意:

$update常にではありませんtrue。以下のコードで自分で確認してテストできます。ただし、最適な名前が付けられていない可能性があるため、十分に文書化されていないため、誤解を招くような期待が生じます。以下のコードは、デバッグに使用できます。コードの実行をインターセプトするタイミングを試してください。そうしないと、情報/メッセージが表示されません。不正な動作の原因は、リビジョンと自動保存の処理にあると思います。これは無効にできる可能性がありますが、お勧めできず、テストもしていません。これがTracチケットを保証するものかどうかはわかりませんので、私はそれを開きませんでした。それとは別に、コメントで述べたように、特定の問題がある場合は、新しい質問を投稿してください。

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();
}

3
$updateパラメータは、新しいポストであっても、常に真です。したがって、このパラメーターは無意味です。それがまったく機能したかどうかはわかりませんが、最新バージョンのwordpress 4.8で文書化されているように、地獄が機能していないことは確かです。
ソロモンクロッソン

@SolomonClossonを見るとwp_publish_post、はい。しかし、それはでの使用には当てはまりませんwp_insert_post。デバッグ関数を作成しました。答えに追加します。
ニコライ

@SolomonClosson実際に具体的な問題がある場合は、新しい質問をしてください。デバッグ機能の説明と説明をご覧ください。
ニコライ

save_postフックは、常に他のフックについては話していない、そうではないことを確認、これは他のフックに関係しているものを、TRUEに設定されている3番目のパラメータがあります。私はあなたの答えのフックについて話している。これは間違っています。
ソロモンクロッソン

@SolomonClosson私が言ったように、フックは2回発生しています:wp_insert_post()wp_publish_post()。後者は将来の投稿のみで、$update常にに設定されていますtrue。それ以外の場合、に関しては常にwp_insert_post()$updateはありませんtrue
ニコライ

11

このチェックを(フックされた関数内で)実行する方法は、投稿日と変更日(標準化のために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' );

これは機能します。なぜなら、作成時でも、投稿には「変更」日付が付けられており、これは「作成」日付とまったく同じですが、ポスト。


1
時にはpost_date_gmtある2019-03-12 01:31:30post_modified_gmtされます2019-03-12 01:31:31。:(
He Yifei何一非

1
@HeYifei何一非良い点は、処理が所定の秒の終わりに始まる場合、これが起こる可能性があります。回答を更新しました、ありがとう
ジェームス・クッシング

みんな、ただの情報。フックは、投稿を復元および削除するときに起動されます。
メルビン

6

設定する前に、カスタム値の存在を確認するだけになりました。そうすれば、新しく作成された投稿の場合、カスタム値はまだ存在しません。

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');

これが機能するには、最初にadd_post_metaを使用してカスタムフィールドを作成する必要がありますか?
MF1

コーデックスごと:add_post_meta()関数の代わりに[update_post_meta]を使用できます。codex.wordpress.org/Function_Reference/update_post_meta
hereswhatidid

プラグインのアクティベーションによってコードフックが有効になる前に投稿が作成された場合、これは失敗する可能性があります。古い投稿にはメタセットがないため、最初の更新は新規と見なされます。
Vasuチャウラ

4

「更新」パラメータを使用したアロイシン回答の例:

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 );

2
これを構築するためのより良い方法は、更新ブロックを最初に置いて、単に行うことを許可するif($update)か、新しいブロックを最初に保持してを使用することif( ! $update )です。後者は、より良い練習にOPを取得するなどのケースでWordPressのコーディング標準によってあなたの方法よりも優先される三項演算子
ジェームズ・カッシング

1

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


4
save_postフックは解雇され、両方のポストは(ワードプレスは、それをデータベースに保存した後)に作成し、更新されたとき。pre_post_update投稿が更新されたときに発生しますが、投稿が更新されるに-これは重要です。
スティーブンハリス

1

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イベント内/ イベント後にのみ確実に使用できることに注意してください(通常、少なくともイベントで何をしている場合でも十分です)。


0

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');

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


3
save_post投稿にたどり着くまでには、既にデータベースに保存されているget_postsはずなので、現在の投稿を返します。
スティーブンハリス

確かに、コーデックスで確認しただけです。ヘッドアップをありがとう。
モラレイダ

0

組み込み関数を使用し、データベースに追加しない別のアプローチには、が含まれ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()および投稿ステータスについてはコーデックスをご覧ください

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

  • 'publish'-公開された投稿またはページ
  • 「保留中」-投稿は審査待ちです
  • 「ドラフト」-ドラフトステータスの投稿
  • 「自動ドラフト」-コンテンツなしの新しく作成された投稿
  • 'future'-将来公開する投稿
  • 「プライベート」-ログインしていないユーザーには表示されません
  • 'inherit'-リビジョン。get_childrenを参照してください。
  • 'trash'-投稿はゴミ箱にあります。バージョン2.9で追加されました。

私はこれが求められたことをしないと思います。新しい投稿を作成してから「公開」を押すとsave_post()、初めて実行されget_post_status()ますが、その実行中に「公開」ではなく「公開」が返されます(公開中のみです)。
cgogolin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.