Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pierrerocket/d4bf4136f8e29c0182f48dab88679840 to your computer and use it in GitHub Desktop.
Save pierrerocket/d4bf4136f8e29c0182f48dab88679840 to your computer and use it in GitHub Desktop.
Migrate Wordpress Terms and Tags from one taxonomy to another.
/**
* WP-CLI command to move terms associated with a specific custom post type from one taxonomy to another.
*
* Usage: wp move-terms --source=old_taxonomy --target=new_taxonomy --post_type=my_custom_post_type
*/
/**
* Moves terms from one taxonomy to another for a specific custom post type.
*
* ## OPTIONS
*
* --source=<source_taxonomy>
* : The source taxonomy slug.
*
* --target=<target_taxonomy>
* : The target taxonomy slug.
*
* --post_type=<post_type>
* : The custom post type slug.
*
* ## EXAMPLES
*
* wp move-terms --source=old_taxonomy --target=new_taxonomy --post_type=my_custom_post_type
*
* @when after_wp_load
*/
function wpcli_move_terms( $args, $assoc_args ) {
$source_taxonomy = $assoc_args['source'];
$target_taxonomy = $assoc_args['target'];
$post_type = $assoc_args['post_type'];
// Get all terms from the source taxonomy.
$terms = get_terms( array(
'taxonomy' => $source_taxonomy,
'hide_empty' => false,
) );
// If no terms found, display a message and exit.
if ( is_wp_error( $terms ) || empty( $terms ) ) {
WP_CLI::warning( 'No terms found in the source taxonomy.' );
return;
}
$term_mapping = array();
foreach ( $terms as $term ) {
// Get all posts of the specific post type associated with the current term in the source taxonomy.
$posts = get_posts( array(
'post_type' => $post_type,
'numberposts' => -1,
'tax_query' => array(
array(
'taxonomy' => $source_taxonomy,
'field' => 'term_id',
'terms' => $term->term_id,
),
),
) );
// If no posts found for this term, skip to the next term.
if ( empty( $posts ) ) {
continue;
}
// Check if the term already exists in the target taxonomy.
$target_term = term_exists( $term->name, $target_taxonomy );
// If the term doesn't exist in the target taxonomy, create it.
if ( !$target_term ) {
$new_term = wp_insert_term(
$term->name,
$target_taxonomy,
array(
'description' => $term->description,
'slug' => $term->slug,
'parent' => $term->parent,
)
);
if ( is_wp_error( $new_term ) ) {
WP_CLI::warning( "Failed to create term '{$term->name}' in the target taxonomy." );
continue;
}
$target_term_id = $new_term['term_id'];
} else {
$target_term_id = $target_term['term_id'];
}
// Map source term ID to target term ID.
$term_mapping[$term->term_id] = $target_term_id;
// Assign the posts to the term in the target taxonomy.
foreach ( $posts as $post ) {
wp_set_post_terms( $post->ID, $target_term_id, $target_taxonomy, true );
}
// Optional: Delete the term from the source taxonomy.
wp_delete_term( $term->term_id, $source_taxonomy );
WP_CLI::success( "Term '{$term->name}' moved from '{$source_taxonomy}' to '{$target_taxonomy}' for post type '{$post_type}'." );
}
WP_CLI::success( "Terms successfully moved from '{$source_taxonomy}' to '{$target_taxonomy}' for post type '{$post_type}'." );
}
// Register the WP-CLI command.
if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'move-terms', 'wpcli_move_terms' );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment