wp_set_object_terms e matrizes

4

Eu preciso adicionar uma categoria a cerca de 2.500 postagens, e também preciso usar uma consulta SQL ou wp_set_object_terms com PHP. Estou vendo wp_set_object_terms para adicionar uma categoria e não afetar as categorias atribuídas no momento.

A função abaixo que usa wp_set_object_terms' (do WordPress Codex) adiciona uma ou mais categorias de um array (no caso do exemplo, categorias 6 e 8) ao post com o ID de 42 (no exemplo ).

Mas eu preciso ser capaz de adicionar uma matriz de IDs de postagem ( $object_id ), não uma matriz de categorias.

De acordo com enlace , $object_id tem que ser um único inteiro.

Como posso usar uma matriz de ~ 2500 IDs de postagem para $object_id ? Preciso de um para cada loop e percorrer a matriz e processar cada adição de categoria para cada ID de postagem, um de cada vez?

De enlace :

// 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.
}
    
por markratledge 21.06.2015 / 17:45

1 resposta

4

Eu duvido que justifique o esforço de escrever consultas SQL personalizadas para apenas 2.500 postagens.

Dentro da função wp_set_object_terms( $object_id, ... ) , temos:

$object_id = (int) $object_id;

Por isso, é correto que só seja necessário um único ID de postagem como entrada.

Então, você precisaria fazer um loop na matriz $post_ids , mas pode ser suficiente usar o truque 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 );
}

Aqui passamos $post_ids por referência no caso de ser muito grande.

Uso (PHP 5.4+):

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

Poderíamos dividir a matriz $post_ids , se 2500 for demais para o nosso sistema em uma única execução.

Veja um exemplo de como podemos executar a função com admin-ajax.php com esse recurso slicing :

Criamos nossa própria ação com:

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

} );

em que usamos os parâmetros wpse_offset e wpse_length GET para dividir a matriz de postagens.

Se quisermos dividir a matriz post ids em blocos de 500, podemos ativá-la manualmente com:

/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

Dessa forma, podemos verificar se há algum erro de termo.

Espero que você possa modificar isso de acordo com suas necessidades.

1) wp_defer_term_counting() foi mencionado pela primeira vez no WPSE nesta resposta por @JanFabry

    
por birgire 21.06.2015 / 22:56