web-dev-qa-db-ja.com

wp_set_object_terms()が用語の設定に失敗する

わかりました、シナリオはここにあります。

私は、(公開されたときに)自動的に別の投稿タイプに投稿を複製する機能を設定しようとしています。そのため、通常のブログ投稿が公開され、公開されると、そのすべての情報がカスタム投稿タイプ(WP ECommerce用)にコピーされ、そのブログ投稿のストアエントリが自動的に作成されます。

Wp_insert_post()を使用して、すべての情報を取得し、それを新しい投稿に挿入する処理を行う関数を作成しました。 1つのことを除けば、すべてうまくいきます。私はwp_set_object_terms()を使用して、ブログ投稿のタグに基づいて新製品の店舗カテゴリIDを設定します。ただし、何らかの理由で、wp_set_object_terms()が機能しません。

今、これがキャッチです。私はマルチサイトインストールでこれらすべてを実行していて、投稿をクロスパブリッシュできるように threeWP_Broadcast を使用しています。ブログの投稿(店舗にコピーする必要があります)はサブサイトから公開され、メインサイトにブロードキャストされます。店はメインサイトにあります。

そのため、私のカスタム機能をブロードキャストプラグインにフックして、投稿がサブサイトからメインサイトにブロードキャストされたときに起動されるようにしました。

Wp_set_object_terms()を除いて、私の関数はすべてうまくいきます。

これが機能です:

function copy_post_to_store_product() {

global $blog_id;
global $wpdb;

// only copy the post over if on main site, not subsites
if ($blog_id == 1) {

    $args = array('numberposts' => 1);
    $latest = get_posts($args);
    foreach($latest as $post) : setup_postdata($post);

        // if NOT Tip and NOT source avail, create product
        // if source, price is ALWAYS $4
        // auto create for source files only -- regular post type

        $custom_meta = get_post_custom($post->ID);

        // what kind of post is this?
        $post_type = $custom_meta['cgc_post_type'][0];
        // does this post have a source file product associated with it?
        $source_avail = $custom_meta['cgc_source_avail'][0];

        // source file price
        $price = '4';


        $product_info = array(
            'post_title'    => $post->post_title,
            'post_type'     => 'wpsc-product',
            'post_content'  => $post->post_content,
            'post_author'   => $post->post_author,
            'post_status'   => 'draft', 
        );


        if($post_type == 'Regular' && $source_avail == true) {
            // only auto create product for Regular posts that have source files for sale
            $product_id = wp_insert_post($product_info);
            update_post_meta($product_id, '_wpsc_price', $price);

            if (has_tag('blender', $post->ID)) 
            { 
                $product_cats = array(23,32);
            }
            elseif (has_tag('max', $post->ID)) {
                $product_cats = array(23,34);
            }
            elseif (has_tag('modo', $post->ID)) {
                $product_cats = array(23,19);
            }

            // set the product categories
            wp_set_object_terms($product_id, $product_cats, 'wpsc_product_category' );

        }


    endforeach;
}

}

この関数はメインサイト($ blog_id == 1)から最新の投稿を取得し、そのすべての情報をwp_insert_post()の変数にコピーすることによって機能します。

さて、本当に面白いことは、この関数をpublish_postフックにアタッチすれば完璧に機能することですが、残念ながら、投稿がブロードキャストされたときにそのフックが起動しないため、それができません。

任意のアイデアは非常に高く評価されるでしょう。

2
Pippin

解決策はありませんが、Make WordPress Coreに チケット#20541 があります。

どうやらswitch_to_blog()への呼び出しは$wp_taxomiesを再投入しないでしょう。

0
Nick Budden

私はちょうど同じ問題に出くわし、 Patriekの答え の助けを借りて解決策を見つけました。カスタム分類法が登録された後にwp_set_object_terms()が実行されることを確認する必要があるだけです。 register_taxonomy()は通常initで実行されるので、initアクションフックで関数を実行することもできますが、優先順位を低くして後で実行します。

add_action( 'init', 'register_custom_taxonomies', 0 );

function register_custom_taxonomies() {
    // register your taxonomies here    
}

add_action( 'init', 'copy_post_to_store_product', 10)

function copy_post_to_store_product() {
    // your function that runs wp_set_object_terms() here
}

このようにして、分類法はあなたの関数が実行されたときに利用可能であることが保証されます。

2
Dalton

前の答えについては忘れてください、publish_postフックでうまく動作するとあなたはあなたのmu-plugins(“ must-use”プラグイン)にプラグインを作成し、それを挿入して更新する前にswitch_to_blogを追加することができます。データベース内のものを削除してからrestore_current_blog()を使用して元に戻します。

switch_to_blog($main_blog_id); //usually 1
...
//your function
...
restore_current_blog();
1
Bainternet

これをただ投げ出すだけです:私の関数が実行されていた時に分類法が利用できなかったとき、私は同じ問題を一度抱えていました。これは、wp eコマースまたはブロードキャストプラグインに問題がある可能性があります。

Wp eコマースプラグインが分類法の登録にこの構文を使用しているかどうかを確認してください

add_action( 'init', 'taxonomy_function_name', 0 );

彼らは、0を追加したかどうかを確認してください。これにより、分類機能の優先順位が0に設定されます。これはできるだけ早く行われます。

ブロードキャストフックに優先順位を設定することは可能ですか?

1
Patriek

私は解決策を得ました、

私はtaxonomy.phpファイルを調査しました、そして、私は問題が関数taxonomy_exists()にあることがわかりました。 switch_to_blog()関数はテーマとプラグインコードを読み取らないので、他のブログで登録された分類法を検出しません。そのため、taxonomy_exists()関数の直前にinitというマニュアルを作成する必要があります

このコードをwp_set_object_terms()関数の前に置きます。

global $wp_taxonomies;
$wp_taxonomies['your_blog_taxonomy'] = array();
0
harisrozak

それほど多くの試行錯誤を試みた後、私は本当の問題はあなたが低い優先順位でInitでCTPのために分類法を設定するあなたの機能を設定する必要があるということであるとわかりました。

add_action( 'init', 'your_function_product', 20 );

0
gurcharan

ありがとうございました、あなたは私の命を救った:)
投稿を挿入する機能の優先順位が低い(20)と、うまくいきます。これは wp_insert_post() functions.php:へのアプローチです。

function insert_db_posts() {
        $thepost = wp_insert_post(array(
                'post_type'         =>  'art',
                'post_title'        =>  'Try hard',
                ));
        wp_set_object_terms( $thepost, 37, 'artist');
}
add_action( 'init', 'insert_db_posts', 20 ); // this will fire very late so everything else is already initialized before this!!!
0
Alex DS