J'ai besoin d'ajouter une catégorie à environ 2 500 articles et j'ai besoin d'utiliser une requête SQL ou wp_set_object_terms
avec PHP. Je regarde wp_set_object_terms
pour pouvoir ajouter une catégorie sans affecter les catégories actuellement assignées.
La fonction ci-dessous qui utilise wp_set_object_terms'
(à partir du Codex WordPress) ajoute une ou plusieurs catégories d'un tableau (dans le cas de l'exemple, catégories 6 et 8) à la publication avec l'ID de 42 (dans l'exemple).
Mais je dois pouvoir ajouter un tableau d'identifiants de publication ($object_id
), pas un tableau de catégories.
Selon https://codex.wordpress.org/Function_Reference/wp_set_object_terms , $object_id
doit être un entier unique.
Comment utiliser un tableau de ~ 2500 identifiants postaux pour $object_id
? Dois-je effectuer une boucle pour chaque boucle, parcourir le tableau et traiter chaque ajout de catégorie à chaque ID de publication, un à la fois?
De 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.
}
Je doute que cela justifie l’effort d’écriture de requêtes SQL personnalisées pour seulement 2500 publications.
Dans la fonction wp_set_object_terms( $object_id, ... )
, nous avons:
$object_id = (int) $object_id;
il est donc exact qu’il ne faut entrer qu’un seul identifiant de poste.
Donc, vous auriez besoin de boucler sur votre tableau $post_ids
mais il pourrait suffire d'utiliser l'astuce 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 );
}
Ici, nous passons $post_ids
par référence au cas où il serait très volumineux.
Utilisation (PHP 5.4+):
wpse_terms_to_posts(
$terms = [ 6, 8 ],
$taxonomy = 'category',
$append = true,
$post_ids = [ 123, 234, 345 ]
);
Nous pourrions même découper le tableau $post_ids
si 2500 est trop pour notre système en une seule exécution.
Voici un exemple d'utilisation de la fonction avec admin-ajax.php
avec une telle fonctionnalité découpée en tranches:
Nous créons notre propre action avec:
/**
* 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();
}
} );
où nous utilisons les paramètres wpse_offset
et wpse_length
GET pour découper le tableau posts.
Si nous voulons découper le tableau post ids en morceaux de 500, nous pouvons l’activer manuellement avec:
/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
De cette façon, nous pouvons vérifier les erreurs de terme.
J'espère que vous pourrez le modifier selon vos besoins.
1) wp_defer_term_counting()
a été mentionné pour la première fois sur WPSE dans ce answer by @JanFabry