Duplicating custom post type and its posts

I have a custom post type with over 100 posts. I want to create another custom post type and have the same posts with the same post titles. Is there a simple DB query that will allow me to do this, or am i stuck with having to re-create each post?

Related posts

Leave a Reply

1 comment

  1. Backup your database

    You can do this pretty easily. I created a proof-of-concept for you to try out. I would backup the database before running this.

    Run the plugin

    Configure the plugin by setting $post_type_1 and $post_type_2 variables to your source and destination post types.

    To run this plugin, you need to be logged in as an administrator. Then, visit:

    http://yourdomain.com/wp-admin/?duplicate-posts=magic-password

    /*
    Plugin Name: Post Duplicator
    Description: Duplicate posts to a new post type
    Version: 0.1
    Author: WPSE
    Author URI: http://wordpress.stackexchange.com
    License: GPL2
    */
    
    add_action('admin_init', 'foo_duplicate_posts', 99999);
    function foo_duplicate_posts(){
    
        # Only allow admins to run the script
        if(!current_user_can('manage_options'))
            return;
    
        # Check if keyword is set
        if(!isset($_GET['duplicate-posts']))
            return;
    
        # Check if keyword matches
        if($_GET['duplicate-posts'] !== 'magic-password')
            return;
    
        global $wpdb;
    
        # Configure post types
        $post_type_1 = 'foo';
        $post_type_2 = 'bar';
    
        $query = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_type = '%s'", $post_type_1);
        $posts = $wpdb->get_results($query, ARRAY_A);
        foreach($posts as $post){
    
            # Post info is already stored in an array
            # Set the post_type to the new post type
            $post['post_type'] = $post_type_2;
    
            # Insert new post
            $new_post = wp_insert_post($post);
    
            # Proceed if new post was created
            if($new_post){
                # Print a success message to the screen
                show_message("{$post['post_title']} was duplicated from #$post['ID'] to #$new_post");
    
                # Get source post's post meta
                $post_meta = get_post_custom($post['ID']);
    
                # Convert all postmeta to new post
                if(is_array($post_meta))
                    foreach($post_meta as $k => $v)
                        update_post_meta($new_post, $k, $v[0]);
            }
            else
                # Print an error message to the screen
                show_message("{$post['post_title']} was not duplicated.");
        }
        # Stop the admin area from loading to get a clean reading of our output messages
        exit;
    }
    

    This plugin accounts for the basic post information and its postmeta. It does not account for revisions, auto-drafts, or attachments. You can run similar loops within the foreach loop to duplicate those sub post types.