it-swarm-ja.com

wp_set_object_termsと配列

約2500の投稿にカテゴリを追加する必要があります。また、SQLクエリまたはPHPのwp_set_object_termsを使用する必要があります。カテゴリを追加して現在割り当てられているカテゴリに影響を与えないようにするためにwp_set_object_termsを見ています。

下のwp_set_object_terms'(WordPress Codexから)を使用する関数は、配列からの1つ以上のカテゴリ(この例ではカテゴリ6と8)をIDが42の(この例では)投稿に追加します。

ただし、カテゴリの配列ではなく、投稿IDの配列($object_id)を追加できるようにする必要があります。

https://codex.wordpress.org/Function_Reference/wp_set_object_terms によると、$object_idは単一の整数でなければなりません。

$object_idに最大2500の投稿IDの配列を使用するにはどうすればよいですか。 forループごとに配列を実行し、各投稿IDに追加された各カテゴリを一度に1つずつ処理する必要がありますか。

からhttps://codex.wordpress.org/Function_Reference/wp_set_object_terms

// An array of IDs of categories we to add to this post. (Not using an array)
$cat_ids = array( 6, 8 );

// Add these categories, note the last argument is true.
// (42 is the $object_id; I will hardcode the category ID)
$term_taxonomy_ids = wp_set_object_terms( 42, $cat_ids, 'category', true );

if ( is_wp_error( $term_taxonomy_ids ) ) {
    // There was an error somewhere and the terms couldn't be set.
} else {
    // Success! These categories were added to the post.
}
4
markratledge

私は、2500の投稿に対してカスタムSQLクエリを書く努力を正当化することを正当化しないでしょう。

wp_set_object_terms( $object_id, ... )関数内には、次のものがあります。

$object_id = (int) $object_id;

そのため、入力として1つの投稿IDのみを受け取ることが正しいです。

それで、あなたはあなたの$post_ids配列をループする必要があるでしょう、しかしそれはwp_defer_term_counting()トリックを使うことで十分かもしれません1)

/**
 * Add terms to posts (with debug display)
 */
function wpse_terms_to_posts( $terms, $taxonomy, $append, &$post_ids )
{
    wp_defer_term_counting( true );

    print '<ul>';
    foreach( (array) $post_ids as $post_id )
    {
        $tt_ids = wp_set_object_terms( $post_id, $terms, $taxonomy, $append );

        print '<li>';
        if( is_wp_error( $tt_ids ) )
            printf(
                'Problem adding terms to post_id: %d - Error: %s',
                $post_id,
                $tt_ids->get_error_message()
            );
    else
            print 'Success adding terms to post_id: ' . $post_id ;
        print '</li>';
    }
    print '</ul>';

    wp_defer_term_counting( false );
}

ここでは、非常に大きい場合に備えて$post_idsを参照渡しします。

用法(PHP 5.4以降):

wpse_terms_to_posts(
    $terms     = [ 6, 8 ],
    $taxonomy  = 'category',
    $append    = true,
    $post_ids  = [ 123, 234, 345 ]
);

1回の実行で2500がシステムには多すぎる場合は、$post_ids配列をスライスすることもできます。

以下は、そのような スライス 機能を付けてadmin-ajax.phpで関数を実行する方法の例です。

私たちは自分自身の行動を次のように作り出します。

/**
 * Custom wp ajax action to activate our wpse_terms_to_posts() function
 * 
 * Example: /wp-admin/admin-ajax.php
 *          ?action=wpse-terms-to-posts&wpse_offset=0&wpse_length=500
 */
add_action( 'wp_ajax_wpse-terms-to-posts', function()
{
    $offset = filter_input( INPUT_GET, 'wpse_offset', FILTER_SANITIZE_NUMBER_INT );
    $length = filter_input( INPUT_GET, 'wpse_length', FILTER_SANITIZE_NUMBER_INT );

    // Check for user capability and non empty user input:
    if( current_user_can( 'manage_options' ) && '' !== $offset && '' !== $length  )
    {
        print '<h3>Start:</h3>';      
        $start = microtime( true );

        // Settings - Edit to your needs:
        $terms     = [ 6, 8 ];
        $taxonomy  = 'category';
        $append    = true;
        $post_ids  = [ 123, 234, 345, 456, 567, 678, 789 ];

        // Add terms to posts:
        wpse_terms_to_posts (
            $terms,
            $taxonomy,
            $append,
            array_slice( $post_ids, $offset, $length )
        );

        printf( '<h3>Done in %f seconds</h3>', microtime( true ) - $start );         
        exit();
    }

} );

pOST配列をスライスするためにwpse_offsetおよびwpse_length GETパラメータを使用します。

Post ids配列を500のチャンクにスライスしたい場合は、次のように手動でアクティブにすることができます。

/wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=0&wpse_length=500

/wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=500&wpse_length=500

/wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=1000&wpse_length=500

/wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=1500&wpse_length=500

/wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=2000&wpse_length=500

そうすれば、用語の誤りをチェックすることができます。

あなたがあなたのニーズに合わせてこれを修正できることを願っています。

1) wp_defer_term_counting()は@JanFabryのこの answer でWPSEで最初に言及されました

4
birgire