There are, as it happens, a lot of ways to do this. This is a way that I tested and it works, but it’s not the final way I did things. That said, this does work and, if you’re not on a shared server, is just fine.
The Concept
I have (roughly) 2200 posts in a custom post type (post_type_characters
). Each of those posts has a post meta field for actors (lezchars_actor
). The content of the post meta is an array of text fields, that looks something like this:
Array( [0] => "Caity Lotz", [1] => " Jacqueline MacInnes Wood (Arrow 1x01 only)" )
I wanted to take the post meta and split it into a post for each actor, however I wanted to remove any comments in parenthesis. I also wanted to change the content of lezchars_actor
to be the IDs of the new actors pages.
Did I mention I had 2200 posts? And some actors were there multiple times? And I didn’t want to make a lot of duplicate posts.
The Code
If you want to do this with PHP, it’ll look something like this:
<?php /* Plugin Name: Post Bulk Update Description: Change all the actors to Taxonomy */ add_action('wp','post_bulk_update_queers'); function post_bulk_update_queers(){ $char_queery = new WP_Query( array( 'post_type' => 'post_type_characters', 'posts_per_page' => '3000', ) ); if ( $char_queery->have_posts() ) { while ( $char_queery->have_posts() ) { $char_queery->the_post(); $the_ID = get_the_ID(); // Get the post meta for actor: $postmeta_actors = get_post_meta( $the_ID, 'lezchars_actor', true ); if ( !is_array ( $postmeta_actors ) ) { $postmeta_actors = array( get_post_meta( $the_ID, 'lezchars_actor', true ) ); } if ( !empty( $postmeta_actors ) ) { $posts_actors = array(); // Create posts if needed: foreach ( $postmeta_actors as $actor ) { // Make sure the ID isn't numeric as that means we did this... if ( !is_numeric( $actor ) ) { // Remove content in parens... $actor = preg_replace( '/\([^)]+\)/', '', $actor ); $already_post = get_page_by_path( sanitize_title( $actor ), OBJECT, 'post_type_actors' ); if ( !( $already_post ) ) { // Create post object $my_post_args = array( 'post_title' => wp_strip_all_tags( $actor ), 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'post_type_actors', ); // Insert the post into the database $my_post = wp_insert_post( $my_post_args ); // add post to array array_push( $posts_actors, $my_post ); } else { array_push( $posts_actors, $already_post->ID ); } } } // Change the post meta to be numbers update_post_meta( $the_ID, 'lezchars_actor', $posts_actors ); } } } }
Notes
The reason this really works is this:
$already_post = get_page_by_path( sanitize_title( $actor ), OBJECT, 'post_type_actors' );
That actually checks if the page with the slug already exists and if so, uses it to edit the post meta.
If you don’t have robust hosting, or you have a lot of posts, you’ll need to edit the $char_queery
like this:
$char_queery = new WP_Query( array( 'post_type' => 'post_type_characters', 'posts_per_page' => '300', 'offset' => '0', ) );
Run it once, bump the offset from 0 to 300, and repeat until you get through all your posts.