webdev_wp
webdev_wp

Reputation: 33

Using wp_insert_post() - creates duplicates

I am adding one CPT to another CPT dynmaically. When using wp_insert_post() it creates duplicates when I add_action('init', 'function_name'); Any idea what hook to use to simply add them:

function cpt_to_cpt(){    
// Grab posts
    $args =  array(
        'post_type'     => ' custom_type1 ',
        'order'         =>  'ASC',
        'post_status'   =>  'publish',
        'numberposts'   => -1,
        );

    $posts = get_posts($args);

    foreach ( $posts as $post ) {  
        wp_insert_post(array(
            'post_type'     =>  'custom_type2',
            'post_title'    =>  $post->post_title,
            'post_date'     =>  $post->post_date,
            'post_author'   =>  $post->post->author,
            'post_status'   =>  'publish',
            )
         );
      }
add_action('init', 'cpt_to_cpt');

Upvotes: 1

Views: 1884

Answers (2)

Thiago Santos
Thiago Santos

Reputation: 413

WordPress init and wp_loaded hooks fire on the "loading" stage. It means they both can fire more than one time when refreshing the page.

Solution 1

You can use another hook that fires later.

wp hook, for instance, fires on the "processing" stage and should run only once.

add_action('wp', 'cpt_to_cpt');

Order of precedence: init 🠆 wp_loaded 🠆 wp

Solution 2

If you really want to use init hook and make sure it will run one time. You can use the snippet below.

function cpt_to_cpt() {
    $runtime = 'run_only_01;
    if (get_option('my_run_only_once_option') != $runtime) {
        $updated = update_option('my_run_only_once_option', $runtime);
        if ($updated === true) {
            // do some stuff
        }
    }
}
add_action('init', 'cpt_to_cpt');

It will create an option on your wp_option table. In the end, you need to delete the option manually (on your database) or in your code.

delete_option('my_run_only_once_option');

Solution 3

Maybe the best professional solution to create multiple posts or CPTs (custom post types) should be using wp-cli (command line interface for WordPress).

Please take a look in the documentation here: https://developer.wordpress.org/cli/commands/post/

Upvotes: 0

Michael Doye
Michael Doye

Reputation: 8171

Try using:

wp_loaded

add_action('wp_loaded', 'cpt_to_cpt');

or

wp

add_action('wp', 'cpt_to_cpt')

Upvotes: 1

Related Questions