web-dev-qa-db-ja.com

投稿を保存するときにプログラムでカスタム分類基準用語をカスタムタイプの投稿に追加する方法を教えてください。

シナリオ: 'book'カスタム投稿タイプおよび'author'カスタム分類法を使用する '推奨書籍'セクションがWebサイトにあります。書籍データとカバーを取得するためにAmazon Product Advertising APIを使用しています。 WordPressに新しい「本」を追加するとき、ユーザーはその書籍ID(ASIN)を投稿編集フィールドにコピーして、「公開」をクリックします。次に、投稿を保存するときに、投稿のタイトル(本のタイトル)と著者の分類用語をAmazonでプログラム的に入力する必要があります。 (これらはフロントエンドで 'Order by'機能を提供するために使用されます。)

現在私はwp_insert_post_dataを使って 'book'保存プロセスにフックし、wp_set_object_terms関数を使って 'book'にカスタム分類用語を追加しようとしています。

問題は次のとおりです。 wp_set_object_terms関数は機能しないようです。それは何も追加しません、それでも、Codexによれば、成功を意味するべきである配列を返します。返される配列は奇妙ですが(私の知る限りでは)。投稿ID 107と期間ID 3を使用する場合(テスト目的で、作成者文字列の代わりに)、返される配列はprint_rとともに次のように表示します。

Array
(
[0] => 3
)

wp_set_post_termsでも試してみて、違いはありません。)

私の完全な機能:

// Function to automatically retrieve and store Amazon Book data (title and author) when adding 'book' type posts
if( function_exists('asa_item') ) {
    add_filter( 'wp_insert_post_data', 'filter_handler', '99', 2 );
    function filter_handler( $data , $postarr ) {

        // Proceed only if book is added/edited
        if ( $postarr['post_type'] !== 'book')
            return $data;

        // Try to Extract ASIN from post body; ignore everything else
        if ( preg_match( '/([0-9A-Z]{10})/', $data['post_content'],  $matches) ) {
            // Successful, store ASIN
            $book_asin = $matches[0];
            // Wrap ASIN in AmazonSimpleAdmin shortcode (with 'cover' template) automatically for user convenience
            $data['post_content'] = '[asa cover]' . $matches[0] . '[/asa]';
        } else {
            // Unsuccessful: set to draft, return and show error message
            $data['post_status'] = 'draft';
            add_filter('redirect_post_location', 'my_redirect_post_location_filter_1', 99);
            return $data;
        }

        // Retrieve and store book data from Amazon with AmazonSimpleAdmin plugin
        $book_data = explode( "<sep>", asa_get_item( $book_asin, 'book_data' ) );
        /******************
         * index 0 = title
         * index 1 = author
         ******************/

        // Check data; if no data, set to draft, return and show error message
        if ( $book_data[0] == '' ) {
            $data['post_status'] = 'draft';
            add_filter('redirect_post_location', 'my_redirect_post_location_filter_2', 99);
            return $data;
        }

        // Fill in Post Title with Amazon data if empty
        if ( $data['post_title'] == '' )
            $data['post_title'] = $book_data[0];

        // Fill in Author tag with Amazon data if missing
        if ( ! has_term( $book_data[1], 'author', $postarr['ID'] ) ) {
            wp_set_object_terms( $postarr['ID'], $book_data[1], 'author' );
        }

        return $data;
    }
}
3
MrValueType

それで、私自身の質問に答えるために:

wp_insert_post_data内に解決策が見つかりませんでした。私は問題がwp_insert_post_dataが実行されるとき問題のポストがまだデータベースにないという事実に関連していると思う。 taxonomy.phpで見つけられなかったにもかかわらず、wp_set_post_terms関数には、任意の/存在しない投稿IDとの単語関係の挿入を避けるための何らかのチェックメカニズムがあると仮定するのは論理的です。

とにかく、wp_insert_post_dataでは、(ローカルに追加するのではなく)追加する必要がある課税期間を格納するためのグローバル変数を定義しました。それから、投稿が保存された後に実行されるsave_postにフックして、そこから用語を取得/挿入しました。

ちょうどうまく動作するようです。

wp_insert_post_dataの関連コード部分

...

// Fill in Author tag with Amazon data if missing
if ( ! has_term( $book_data[1], 'author', $postarr['ID'] ) ) {
    global $add_this_tax_term_to_book;
    $add_this_tax_term_to_book[] = $book_data[1];
    $add_this_tax_term_to_book[] = 'author';
}

...

そしてsave_postのコード:

add_action('save_post', 'add_my_tax_term');
function add_my_tax_term( $post_id ) {
    global $add_this_tax_term_to_book;

    if ( !(empty( $add_this_tax_term_to_book )) ) {
        wp_set_object_terms( $post_id, $add_this_tax_term_to_book[0], $add_this_tax_term_to_book[1] );
}
3
MrValueType