web-dev-qa-db-ja.com

Publish_postからACFカスタムフィールドを返す

投稿が公開され次第、カスタムフィールドを返そうとしています。私はpublish_post(または{status}_{post_type})アクションを使用していますが、カスタムフィールドはフックの後に作成されるように見えます。

functions.phpの私のコード:

function create_recurring_posts( $ID, $post ) {
    logMe(print_r(get_post_custom($ID), true));
}
add_action( 'publish_profile', 'create_recurring_posts', 10, 2 );

logMe()関数は、テスト目的でファイルに出力を記録するだけです。私の問題は、プロフィール投稿を作成したときに返されるカスタムフィールドが_edit_last_edit_lockだけだということです。しかし、後でそのページを表示するときに、同じget_post_custom()関数が実行されているところに、他に必要なカスタムフィールドがあります。

フィールドの作成にAdvanced Custom Fieldsを使用しています。任意の助けは大歓迎です。

1
v0wels

あなたの行動は、wp_transition_post_status()によって呼び出されるwp_insert_post()内で引き起こされます。その前にsave_postというアクションが引き起こされます。 save_postはカスタムフィールドを処理するための典型的なアクションです。 ACFもこれに取り組んでいます。

基本的には、ACFの処理が終わるまで待つ必要があります。つまり、優先度> 10以上でsave_postにフックする必要があるか、wp_insert_postの直後に実行するsave_postを使用する必要があります。

投稿ステータスの遷移を追跡するには、次のようなシンプルな"ログ"を使います。

<?php

namespace WPSE199070;

class PublishedTransitionLog {

    /**
     * @type array
     */
    private $status_log = [];

    /**
     * logs a published post id 
     * 
     * @wp-hook publish_profile
     *
     * @param int $post_id
     */
    public function published_post( $post_id ) {

        $blog_id = get_current_blog_id();
        if ( ! isset( $this->status_log[ $blog_id ] ) )
            $this->status_log[ $blog_id ] = [];

        if ( in_array( $post_id, $this->status_log[ $blog_id ] ) )
            return;

        $this->status_log[ $blog_id ][] = $post_id;
    }

    /**
     * @param int $post_id
     * @return bool
     */
    public function post_published( $post_id ) {

        $blog_id = get_current_blog_id();
        if ( ! isset( $this->status_log[ $blog_id ] ) )
            return FALSE;

        return in_array( $post_id, $this->status_log[ $blog_id ] );
    }
}

class PublishPostHandler {

    /**
     * @type PublishedTransitionLog
     */
    private $log;

    public function __construct( PublishedTransitionLog $log ) {

        $this->log = $log;
    }

    /**
     * @param int $post_id
     * @param \WP_Post $post 
     * @param bool $updated
     */
    public function update( $post_id, \WP_Post $post, $updated ) {

        if ( ! $this->log->post_published( $post_id ) )
            return;

        // do your stuff here
    }
}

$transition_log = new PublishedTransitionLog;
$handler        = new PublisPostHandler( $transition_log );

add_action( 'publish_profile', array( $transition_log, 'published_post' ) );
add_action( 'wp_insert_post', array( $handler, 'update', 10, 3 ) );

これを説明しましょう。最初のクラスPublishedTransitionLogはアクションpublish_profileをリ​​ッスンし、各ブログの公開された各投稿を内部的に格納します。投稿が以前に公開されたかどうかを確認する方法も提供します。

2番目のクラスはあなたの論理を提供するべきであり、最初のクラスに依存します。投稿が公開されていない場合は、何もしません。

この方法であなたは異なるフックを引っ張るために独立して聞くことができます。

3
David

@Davidさんは、あなたのコードがうまくいかない理由を説明し、解決策をスケッチしました(代わりにsave_postを使ってください)。ただし、遷移フィルタを使用して実行を制御できるように、フックを「連鎖」させることができます。

function create_recurring_posts( $ID, $post ) {
  add_action(
    'save_post',
    function() {
      // debug, since I don't have a `logMe()` function :)
      var_dump(print_r(get_post_custom($ID), true));
      die;
    },
    PHP_INT_MAX,
    1
  );   
}
add_action( 'publish_profile', 'create_recurring_posts', 10, 2 );
1
s_ha_dum