From 412cfbd175736b844848dedd7ae3506f0a7e25ee Mon Sep 17 00:00:00 2001 From: Memo Date: Thu, 25 Jan 2024 15:29:55 -0300 Subject: [PATCH 1/2] Cleanup Post Tags --- .../cli/includes/class-pmh-worker.php | 439 ++++++++++++++++++ 1 file changed, 439 insertions(+) diff --git a/wp-content/plugins/pri-migration-helper/cli/includes/class-pmh-worker.php b/wp-content/plugins/pri-migration-helper/cli/includes/class-pmh-worker.php index 7c601fbce..29a02a594 100644 --- a/wp-content/plugins/pri-migration-helper/cli/includes/class-pmh-worker.php +++ b/wp-content/plugins/pri-migration-helper/cli/includes/class-pmh-worker.php @@ -448,4 +448,443 @@ public function single_post_content_media_fix( $a_args ) { // Return. return $updated; } + + /** + * Check each post tag if it is duplicated in other custom taxonomies. + * + * @return void + */ + public function get_duplicated_post_tags_number( $a_args ) { + + // @todo Remove after testing. + ob_start(); + + // Get all post tags. + $a_post_tags = get_terms( array( 'taxonomy' => 'post_tag', 'hide_empty' => false ) ); + + // Get all the public custom taxonomies. + $a_custom_taxonomies = get_taxonomies( array( 'public' => true ), 'objects' ); + + // Get the custom taxonomies that are not post_tag. + $a_custom_taxonomies = array_filter( + $a_custom_taxonomies, + function( $o_custom_taxonomy ) { + return 'post_tag' !== $o_custom_taxonomy->name; + } + ); + + // Get the custom taxonomies slugs. + $a_custom_taxonomies_slugs = array_map( + function( $o_custom_taxonomy ) { + return $o_custom_taxonomy->name; + }, + $a_custom_taxonomies + ); + + // Duplicate container. + $a_duplicates = array(); + + // For each custom taxonomy. + foreach ( $a_custom_taxonomies_slugs as $s_custom_taxonomies_slug ) { + + $a_duplicates[ $s_custom_taxonomies_slug ] = array(); + } + + // For each post_tag. + foreach ( $a_post_tags as $o_post_tag ) { + + // Get the post_tag slug. + $s_post_tag_slug = $o_post_tag->slug; + + // For each custom taxonomy. + foreach ( $a_custom_taxonomies_slugs as $s_custom_taxonomies_slug ) { + + // Get term from custom taxonomy with the same slug as the post_tag. + $o_term = get_term_by( 'slug', $s_post_tag_slug, $s_custom_taxonomies_slug ); + + // If term is found. + if ( $o_term ) { + + // Add post_tag id to the duplicates container. + $a_duplicates[ $s_custom_taxonomies_slug ][] = $o_post_tag->term_id; + } + } + } + + /* Debug: Dump the total duplicate for each custom taxonomy. + */ + foreach ( $a_duplicates as $s_custom_taxonomies_slug => $a_duplicate_ids ) { + + // @todo Remove after testing. + WP_CLI::log( $s_custom_taxonomies_slug . ': ' . count( $a_duplicate_ids ) ); + } + + // @todo Remove after testing. + $log = ob_get_clean(); + + // @todo Remove after testing. + WP_CLI::log( $log ); + } + + /** + * Get all custom taxonomies slugs. + * + * @return array + */ + public function get_custom_taxonomies() { + + global $a_custom_taxonomies_slugs; + + if ( $a_custom_taxonomies_slugs ) { + return $a_custom_taxonomies_slugs; + } + + // Get all custom taxonomy slugs. + $a_custom_taxonomies_slugs = array_map( + function( $o_custom_taxonomy ) { + + // skip post_tag. + if ( 'post_tag' === $o_custom_taxonomy->name ) { + return; + } + + return $o_custom_taxonomy->name; + }, + get_taxonomies( array( 'public' => true ), 'objects' ) + ); + + // Remove empty values. + $a_custom_taxonomies_slugs = array_filter( $a_custom_taxonomies_slugs ); + + return $a_custom_taxonomies_slugs; + } + + /** + * Get all post_tags in a post and compare them with the custom taxonomies. + * + * Example: wp tw-fix cleanup_post_tag 654016 remove + * + * @param [type] $a_args + * @return void + */ + public function cleanup_post_tag( $a_args ) { + + // @todo Remove after testing. + ob_start(); + + // Get post ID. + $i_post_id = isset( $a_args[0] ) ? (int) $a_args[0] : 0; + + // Remove post_tags from the post. + $b_remove_post_tags = isset( $a_args[1] ) && 'remove' === $a_args[1] ? true : false; + + // Get custom taxonomies. + $a_custom_taxonomies = $this->get_custom_taxonomies(); + + // Get post_tags. + $a_post_tags = wp_get_post_tags( $i_post_id ); + + // Begin. + WP_CLI::log( '-------------------------------' ); + + // Foreach post_tags check if that slug exists in the custom taxonomies. + if ( $a_post_tags ) { + + // If post_tags found. + WP_CLI::log( wp_sprintf( 'Post %s contains %s tags:', $i_post_id, count( $a_post_tags ) ) ); + + // List post_tags. + // foreach ( $a_post_tags as $o_post_tag ) { + + // WP_CLI::log( wp_sprintf( '- (%s) %s', $o_post_tag->term_id, $o_post_tag->slug ) ); + // } + + // Separator. + WP_CLI::log( '- - - - - - - - - - - - - - - -' ); + + foreach ( $a_post_tags as $o_post_tag ) { + + // Get post_tag ID. + $i_post_tag_id = $o_post_tag->term_id; + + // Get the post_tag slug. + $s_post_tag_slug = $o_post_tag->slug; + + // Custom taxonomy terms to relate. + $a_custom_taxonomy_terms = array(); + + // Show the post_tag slug. + WP_CLI::log( '' ); + WP_CLI::log( wp_sprintf( 'Working on post_tags: (%s) %s', $i_post_tag_id, $s_post_tag_slug ) ); + + // For each custom taxonomy. + foreach ( $a_custom_taxonomies as $s_custom_taxonomies_slug ) { + + // Get term from custom taxonomy with the same slug as the post_tag. + $o_term = get_term_by( 'slug', $s_post_tag_slug, $s_custom_taxonomies_slug ); + + // If term is found. + if ( $o_term ) { + + // Show the custom taxonomy where the post_tag was found. + WP_CLI::log( wp_sprintf( '- Slug found in custom taxonomy %s with term ID %s.', $s_custom_taxonomies_slug, $o_term->term_id ) ); + + // Add term from custom taxonomy. + $a_custom_taxonomy_terms[ $s_custom_taxonomies_slug ][] = $o_term->term_id; + + // Remove post_tag from the post. + if ( $b_remove_post_tags ) { + // Create the array of the post_tag IDs to be removed from the post. + $a_tags_to_remove[] = $o_post_tag->term_id; + } + } + } + + // Relate the custom taxonomy terms. + if ( $a_custom_taxonomy_terms ) { + + // Show the post ID and the custom taxonomy and terms to relate. + WP_CLI::log( '' ); + WP_CLI::log( 'Relating terms to post ID: ' . $i_post_id ); + + foreach ( $a_custom_taxonomy_terms as $s_custom_taxonomy_slug => $a_custom_term_ids ) { + + // Set custom terms to post. + $terms_related = true; // @todo Remove after testing. Activate the one below + // $terms_related = wp_set_object_terms( $i_post_id, $a_custom_term_ids, $s_custom_taxonomy_slug, true ); + + // Report terms related. + WP_CLI::log( wp_sprintf( '- Add terms from taxonomy %s to post. (%s) | %s', + $s_custom_taxonomy_slug, + $terms_related ? 'success' : 'failed', + implode( ',', $a_custom_term_ids ) + ) ); + + if ( ! is_wp_error( $terms_related ) && $b_remove_post_tags && $a_tags_to_remove ) { + + // Remove the post_tag from the post only if the association to custom taxonomies worked. + $term_removed = true; // @todo Remove after testing. Activate the one below + // $term_removed = wp_remove_object_terms( $i_post_id, $a_tags_to_remove, 'post_tag' ); + + // Report term removed. + WP_CLI::log( wp_sprintf( '- Remove post_tag with term ID %s from post. (%s)', implode( ',', $a_tags_to_remove ), $term_removed ? 'success' : 'failed' ) ); + } + } + } else { + + // Show the post_tag slug. + WP_CLI::log( wp_sprintf( '- No custom taxonomy terms to relate.' ) ); + } + + // Separator. + WP_CLI::log( '- - - - - - - - - - - - - - - -' ); + } + } else { + + // If no post_tags found. + WP_CLI::log( 'Post %s does not contain any post_tags.', $i_post_id ); + } + + /* Debug + echo "
";
+		var_dump( $a_custom_taxonomies );
+		echo "
"; + */ + + // @todo Remove after testing. + $log = ob_get_clean(); + + // @todo Remove after testing. + WP_CLI::log( $log ); + + } + + /** + * Loop through all post_tags, check each term if it is duplicated in other custom taxonomies. + * If it is duplicated, add posts related to the post_tag to the custom taxonomy term. + * + * @param array $args + * @param int $args[0] Start from page number. + * @param int $args[1] Limit. + * + * Example: wp tw-fix post_tags_fix_duplicate 1 10 + */ + public function post_tags_fix_duplicate( $args ) { + + // Get all custom taxonomies. + $a_custom_taxonomies = $this->get_custom_taxonomies(); + + // Get allowed post types. + $a_allowed_post_types = array( 'post', 'episode' ); + + // Start looping. + WP_CLI::log( '' ); + WP_CLI::log( 'Looping post tags with posts related to it.' ); + WP_CLI::log( '-------------------------------' ); + + // If the first argument can be converted to integer, use it as the page number. + $page = isset( $args[0] ) ? (int) $args[0] : 1; + + // If $page is not an integer, use the argument as the post_tag slug. + if ( ! $page ) { + $page = isset( $args[0] ) ? $args[0] : 1; + } + + // Limit if needed. + $i_limit = isset( $args[1] ) ? (int) $args[1] : false; + + do { + + // If $page is not an integer, use the argument as the post_tag slug. + if ( ! is_int( $page ) ) { + + $term = get_term_by( 'slug', $page, 'post_tag' ); + + } else { + + $term = $this->post_tags_fix_duplicate_page( array( $page ) ); + + } + + if ( ! is_null( $term ) ) { + + WP_CLI::log( wp_sprintf( + 'Processing post_tags - (%s) %s', + $term->term_id, + $term->slug + ) ); + + // Get post ids related to the post_tag. + $a_post_ids = get_objects_in_term( $term->term_id, 'post_tag' ); + + // For each custom taxonomy, check if the post_tag is duplicated. + foreach ( $a_custom_taxonomies as $s_custom_taxonomies_slug ) { + + // Get term from custom taxonomy with the same slug as the post_tag. + $o_term = get_term_by( 'slug', $term->slug, $s_custom_taxonomies_slug ); + + // If term is found. + if ( $o_term ) { + + // Show the custom taxonomy where the post_tag was found. + WP_CLI::log( wp_sprintf( '- Slug found in taxonomy %s with term ID %s.', $s_custom_taxonomies_slug, $o_term->term_id ) ); + + // Add posts related to the post_tag to the custom taxonomy term. + $terms_related = false; // @todo Remove after testing. + + // For each post id related to the post_tag. + foreach ( $a_post_ids as $i_post_id ) { + + // Only process post and episode. + $s_post_type = get_post_type( $i_post_id ); + + // Skip if post type is not allowed. + if ( ! in_array( $s_post_type, $a_allowed_post_types ) ) { + + // Report terms related. + WP_CLI::log( wp_sprintf( ' Post ID %s is not a (%s).', $i_post_id, implode( ',', $a_allowed_post_types ) ) ); + + continue; + } + + // Check if the post id is already related to the custom taxonomy term. + $a_post_terms = get_the_terms( $i_post_id, $s_custom_taxonomies_slug ); + + // If the post id is not related to the custom taxonomy term. + if ( ! in_array( $o_term->term_id, wp_list_pluck( $a_post_terms, 'term_id' ) ) ) { + + // Default values. + $terms_related = false; + $term_removed = false; + + // Add the post id to the custom taxonomy term. + // $terms_related = true; // @todo Remove after testing. + $terms_related = wp_set_object_terms( $i_post_id, $o_term->term_id, $s_custom_taxonomies_slug, true ); + + if ( ! is_wp_error( $terms_related ) ) { + // Remove the post_tag from the post. + // $term_removed = true; // @todo Remove after testing. + $term_removed = wp_remove_object_terms( $i_post_id, $term->term_id, 'post_tag' ); + } + + // Report terms related. + WP_CLI::log( wp_sprintf( ' Relate post ID %s to term and remove from post_tag. (%s) (%s)', + $i_post_id, + $terms_related ? 'success' : 'failed', + $term_removed ? 'success' : 'failed', + ) ); + + // If error. + if ( is_wp_error( $terms_related ) ) { + + // Report terms related. + WP_CLI::log( wp_sprintf( ' Error: %s', $terms_related->get_error_message() ) ); + } + if ( is_wp_error( $term_removed ) ) { + + // Report terms related. + WP_CLI::log( wp_sprintf( ' Error: %s', $term_removed->get_error_message() ) ); + } + + } else { + + // Report terms related. + WP_CLI::log( wp_sprintf( ' Post ID %s is already related to term.', $i_post_id ) ); + } + } + } + } + } + + // Separator. + WP_CLI::log( '' ); + WP_CLI::log( wp_sprintf( '- - - - - - - - - - - - - - - - (%s)', $page ) ); + WP_CLI::log( '' ); + WP_CLI::log( '' ); + + // Break if $page is not an integer. + if ( ! is_int( $page ) ) { + $term = null; + break; + } + + // Increment page. + $page++; + + // Reduce limit. + if ( $i_limit ) { + + // Reduce limit. + $i_limit--; + + // Break if limit is 0. + if ( 0 === $i_limit ) { + $term = null; + break; + } + } + + } while ( $term !== null ); + + // Process finished. + WP_CLI::log( '-------------------------------' ); + WP_CLI::log( 'Post tags fix duplicate process finished.' ); + } + + public function post_tags_fix_duplicate_page( $args ) { + + // Get page number. + $number = is_array( $args ) ? $args[0] : 1; + + $a_post_tags = get_terms( array( + 'taxonomy' => 'post_tag', + 'hide_empty' => true, + 'offset' => $number, + 'number' => 1, + ) ); + + // Return false if no post_tags found. + return count( $a_post_tags ) > 0 ? $a_post_tags[0] : null; + } } + From c1df5f123b5f7ab1be8431acb374a5dac0db38f4 Mon Sep 17 00:00:00 2001 From: Memo Date: Tue, 30 Jan 2024 16:30:32 -0300 Subject: [PATCH 2/2] Add docs about wp-cli command --- .../plugins/pri-migration-helper/README.md | 22 +++++++++++++++++++ .../plugins/pri-migration-helper/cli/cli.php | 1 + 2 files changed, 23 insertions(+) create mode 100644 wp-content/plugins/pri-migration-helper/README.md diff --git a/wp-content/plugins/pri-migration-helper/README.md b/wp-content/plugins/pri-migration-helper/README.md new file mode 100644 index 000000000..8121c445a --- /dev/null +++ b/wp-content/plugins/pri-migration-helper/README.md @@ -0,0 +1,22 @@ +# WP CLI module. +**Example:** +`wp tw-fix command_to_run arg1 arg2 ... argN` +## Commands: +**`(base) tw-fix`** +### +`wp tw-fix get_unprocessed_images` +### +`wp tw-fix get_images_count` +### Fix image size values in all images imported +`wp tw-fix image_fix [all|new limit]` +Command used to fix the img sizes (width and height) using drupal metadata for all images imported. +### Fix media element in all posts +`wp tw-fix posts_content_media_fix [limit comma_separated_post_ids(optional)]` +Command used to replace img tags by image blocks in a all posts. +### Fix media element in a single post content +`wp tw-fix single_post_content_media_fix [post_id]` +Used to test the code used to replace img tags by image blocks in a single post. +### Cleanup Post Tags +`wp tw-fix post_tags_fix_duplicate [start_page_number post_per_page]` +Command to loop through all post_tags, check each term if it is duplicated in other custom taxonomies. +If it is duplicated, add posts related to the post_tag to the custom taxonomy term. diff --git a/wp-content/plugins/pri-migration-helper/cli/cli.php b/wp-content/plugins/pri-migration-helper/cli/cli.php index 30e7a6f71..f2dc0f277 100644 --- a/wp-content/plugins/pri-migration-helper/cli/cli.php +++ b/wp-content/plugins/pri-migration-helper/cli/cli.php @@ -8,6 +8,7 @@ * 3. image_fix [all|new, limit] * 4. posts_content_media_fix [limit, comma_separated_post_ids(optional)] * 5. single_post_content_media_fix [post_id] + * 6. post_tags_fix_duplicate [start_page_number post_per_page] */ // Add 'tw-media-fix-all' command to wp-cli.