Instantly share code, notes, and snippets.
Created
September 13, 2024 15:22
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save pierrerocket/12c0f4c4d10f4a9916c5b9931cfe7018 to your computer and use it in GitHub Desktop.
WP CLI to Migrate Categories to Tags and set a category for Posts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// It's pretty common to be working on sites where clients used categories all wrong and you want to migrate those to tags. | |
// I wrote this for a site with a lot of posts and I didnt want to risk it failing. | |
if (defined('WP_CLI') && WP_CLI) { | |
class Migrate_Categories_To_Tags_Command { | |
/** | |
* Migrate categories to tags, clear existing tags, and update posts. | |
* | |
* ## EXAMPLES | |
* | |
* wp migrate categories-to-tags | |
* | |
* @when after_wp_load | |
*/ | |
public function __invoke() { | |
$target_category_name = 'Category Name'; | |
$posts = get_posts(['post_type' => 'post', 'numberposts' => -1, 'post_status' => 'any']); | |
if (empty($posts)) { | |
WP_CLI::success("No posts found."); | |
return; | |
} | |
// Check if the target category exists, if not create it | |
$target_category = get_term_by('name', $target_category_name, 'category'); | |
if (!$target_category) { | |
$result = wp_insert_term($target_category_name, 'category'); | |
if (is_wp_error($result)) { | |
WP_CLI::error("Failed to create target category '$target_category_name'."); | |
return; | |
} | |
$target_category_id = $result['term_id']; | |
WP_CLI::success("Created target category '$target_category_name'."); | |
} else { | |
$target_category_id = $target_category->term_id; | |
WP_CLI::success("Target category '$target_category_name' already exists."); | |
} | |
$all_categories_verified = true; | |
foreach ($posts as $post) { | |
WP_CLI::line("Processing post: {$post->ID}"); | |
// Read post categories | |
$categories = wp_get_post_categories($post->ID); | |
$category_names = []; | |
foreach ($categories as $category_id) { | |
$category = get_term($category_id, 'category'); | |
if ($category) { | |
$category_names[] = $category->name; | |
} | |
} | |
WP_CLI::line("Categories found for post {$post->ID}: " . implode(', ', $category_names)); | |
// Clear existing tags | |
WP_CLI::line("Clearing existing tags for post {$post->ID}..."); | |
wp_set_post_tags($post->ID, []); | |
// Create tags identical to post categories | |
$tags_created = []; | |
foreach ($category_names as $category_name) { | |
$existing_tag = get_term_by('name', $category_name, 'post_tag'); | |
if (!$existing_tag) { | |
$result = wp_insert_term($category_name, 'post_tag'); | |
if (is_wp_error($result)) { | |
WP_CLI::warning("Failed to create tag '$category_name': " . $result->get_error_message()); | |
continue; // Skip this tag creation due to error | |
} | |
$tags_created[] = $category_name; | |
WP_CLI::line("Tag created: $category_name"); | |
} else { | |
$tags_created[] = $existing_tag->name; | |
WP_CLI::line("Tag already exists: $category_name"); | |
} | |
} | |
WP_CLI::line("Tags Created/Found for post {$post->ID}: " . implode(', ', $tags_created)); | |
// Assign tags to the post | |
wp_set_post_tags($post->ID, $tags_created); | |
// Retrieve and normalize created tags | |
$tags = get_the_tags($post->ID); | |
if ($tags === false) { | |
WP_CLI::line("No tags found for post ID {$post->ID} after creation."); | |
$tag_names = []; | |
} else { | |
$tag_names = array_map(function($tag) { | |
return trim(strtolower($tag->name)); | |
}, $tags); | |
} | |
$normalized_category_names = array_map('trim', array_map('strtolower', $category_names)); | |
// Verify if tags match the post's categories | |
$tags_match = !(array_diff($normalized_category_names, $tag_names) || array_diff($tag_names, $normalized_category_names)); | |
if ($tags_match) { | |
WP_CLI::line("Tags and Categories match for post ID {$post->ID}."); | |
} else { | |
WP_CLI::line("Tags and Categories don't match for post ID {$post->ID}."); | |
WP_CLI::line("Categories: " . implode(', ', $normalized_category_names)); | |
WP_CLI::line("Tags: " . implode(', ', $tag_names)); | |
$missing_tags = array_diff($normalized_category_names, $tag_names); | |
$extra_tags = array_diff($tag_names, $normalized_category_names); | |
if (!empty($missing_tags)) { | |
WP_CLI::line("Missing Tags (should have been created): " . implode(', ', $missing_tags)); | |
} | |
if (!empty($extra_tags)) { | |
WP_CLI::line("Extra Tags (should not exist): " . implode(', ', $extra_tags)); | |
} | |
$all_categories_verified = false; | |
WP_CLI::error("Verification failed for post ID {$post->ID}. Stopping process."); | |
return; | |
} | |
// Finalize by clearing categories and assigning a category to the post | |
wp_set_post_categories($post->ID, [$target_category_id]); | |
WP_CLI::line("Categories Deleted and New Category Assigned to post ID {$post->ID}"); | |
} | |
if ($all_categories_verified) { | |
WP_CLI::success("All tags successfully verified to match categories."); | |
} | |
} | |
} | |
WP_CLI::add_command('migrate categories-to-tags', 'Migrate_Categories_To_Tags_Command'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment