@@ -636,6 +636,90 @@ public function recount( $args ) {
636636 }
637637 }
638638
639+ /**
640+ * Migrate a term of a taxonomy to another taxonomy.
641+ *
642+ * ## OPTIONS
643+ *
644+ * <term>
645+ * : Slug or ID of the term to migrate.
646+ *
647+ * [--by=<field>]
648+ * : Explicitly handle the term value as a slug or id.
649+ * ---
650+ * default: id
651+ * options:
652+ * - slug
653+ * - id
654+ * ---
655+ *
656+ * [--from=<taxonomy>]
657+ * : Taxonomy slug of the term to migrate.
658+ *
659+ * [--to=<taxonomy>]
660+ * : Taxonomy slug to migrate to.
661+ *
662+ * ## EXAMPLES
663+ *
664+ * # Migrate a category's term (video) to tag taxonomy.
665+ * $ wp term migrate 9190 --from=category --to=post_tag
666+ * Term '9190' migrated!
667+ * Old instance of term '9190' removed from its original taxonomy.
668+ * Success: Migrated the term '9190' from taxonomy 'category' to taxonomy 'post_tag' for 1 posts
669+ */
670+ public function migrate ( $ args , $ assoc_args ) {
671+ $ clean_term_cache = $ values = array ();
672+ $ term_reference = $ args [0 ];
673+ $ original_taxonomy = Utils \get_flag_value ( $ assoc_args , 'from ' );
674+ $ destination_taxonomy = Utils \get_flag_value ( $ assoc_args , 'to ' );
675+
676+ $ term = get_term_by ( Utils \get_flag_value ( $ assoc_args , 'by ' ), $ term_reference , $ original_taxonomy );
677+
678+ if ( ! $ term ) {
679+ WP_CLI ::error ( "Taxonomy term ' {$ term_reference }' for taxonomy ' {$ original_taxonomy }' doesn't exist. " );
680+ }
681+
682+ $ original_taxonomy = get_taxonomy ( $ original_taxonomy );
683+
684+ $ id = wp_insert_term ( $ term ->name , $ destination_taxonomy , array ( 'slug ' => $ term ->slug , 'parent ' => 0 , 'description ' => $ term ->description ) );
685+
686+ if ( is_wp_error ( $ id ) ) {
687+ WP_CLI ::error ( $ id ->get_error_message () );
688+ }
689+
690+ $ post_ids = get_objects_in_term ( $ term ->term_id , $ original_taxonomy ->name );
691+
692+ foreach ( $ post_ids as $ post_id ) {
693+ $ type = get_post_type ( $ post_id );
694+ if ( in_array ( $ type , $ original_taxonomy ->object_type ) ) {
695+ $ term_taxonomy_id = wp_set_object_terms ( $ post_id , $ id ['term_id ' ], $ destination_taxonomy , true );
696+
697+ if ( is_wp_error ( $ term_taxonomy_id ) ) {
698+ WP_CLI ::error ( "Failed to assign the term ' {$ term ->slug }' to the post {$ post_id }. Reason: " . $ term_taxonomy_id ->get_error_message () );
699+ }
700+
701+ WP_CLI ::log ( "Term ' {$ term ->slug }' assigned to post {$ post_id }. " );
702+ }
703+
704+ clean_post_cache ( $ post_id );
705+ }
706+
707+ clean_term_cache ( $ term ->term_id );
708+
709+ WP_CLI ::log ( "Term ' {$ term ->slug }' migrated. " );
710+
711+ $ del = wp_delete_term ( $ term ->term_id , $ original_taxonomy ->name );
712+
713+ if ( is_wp_error ( $ del ) ) {
714+ WP_CLI ::error ( "Failed to delete the term ' {$ term ->slug }'. Reason: " . $ del ->get_error_message () );
715+ }
716+
717+ WP_CLI ::log ( "Old instance of term ' {$ term ->slug }' removed from its original taxonomy. " );
718+ $ post_count = count ( $ post_ids );
719+ $ post_plural = WP_CLI \Utils \pluralize ( 'post ' , $ post_count );
720+ WP_CLI ::success ( "Migrated the term ' {$ term ->slug }' from taxonomy ' {$ original_taxonomy ->name }' to taxonomy ' {$ destination_taxonomy }' for {$ post_count } {$ post_plural }. " );
721+ }
722+
639723 private function maybe_make_child () {
640724 // 50% chance of making child term
641725 return ( mt_rand (1 , 2 ) == 1 );
0 commit comments