0

I am trying to add posts of a custom post-type in bulk from a .csv file. Everything works except that it adds the post twice. They are exactly the same in the database except one has author 1 and the other has author 2. Also it appends a '-2' to post_name. Here is what I have:

add_action('wp_loaded', 'add_from_csv', 10);
function add_from_csv() {
    if (($handle = fopen(dirname(__FILE__) . "/posts.csv", "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $term_1 = $data[0];
            $term_2 = $data[1];
            $term_3 = $data[2];
            $term_4 = $data[3];
            $term_5 = $data[4];
            $meta_1 = $data[5];
            $meta_2 = $data[6];
            $meta_3 = $data[7];
            $meta_4 = $data[8];
            $meta_5 = $data[9];
            $meta_6 = isset($data[10]) ? $data[10] : '';

            $post_id = wp_insert_post( 
                array(
                    'post_title' => $meta_1 . ' ' . $meta_2 . ' ' . $meta_3 . ': ' . $meta_4,
                    'post_type' => 'custom_type',
                    'post_status' => 'publish',
                )
            );

            if(!is_wp_error($post_id) || $post_id != 0) {
                $tax_1_terms = array($term_1, $term_2, $term_3, $term_4);
                wp_set_object_terms( $post_id, $tax_1_terms, 'tax_1' );
                wp_set_object_terms( $post_id, $term_5, 'tax_2' );

                update_post_meta($post_id, 'meta-1', $meta_1);
                update_post_meta($post_id, 'meta-2', $meta_2);
                update_post_meta($post_id, 'meta-3', $meta_3);
                update_post_meta($post_id, 'meta-4', $meta_4);
                update_post_meta($post_id, 'meta-5', $meta_5);
                update_post_meta($post_id, 'meta-6', $meta_6);
            } else {
                echo 'There was a WP_Error when loading posts from csv!';
                break;
            }
        }
        fclose($handle);
    }
}

I have this in a plugin by itself. If I don't set 'post_status', and it uses the default status of 'draft' then there are no duplicates. but when I set 'post_status' => 'publish' then it inserts the post twice. Both of the duplicates have status of publish. Can someone help me resolve this please? Thanks

4
  • 1
    wp_loaded is a very generic hook that fires on every page ( including WP Crong which is loaded at the end of the page load ), you also never specify the post author, or check for duplicates
    – Tom J Nowell
    Commented Dec 3, 2017 at 1:20
  • Also have you considered WP CLI?
    – Tom J Nowell
    Commented Dec 3, 2017 at 1:28
  • So that's why I'm getting 2 then? One when wp_loaded fires on the normal page load, and one when wp_cron.php is loaded at the end of the normal page load?
    – Trevor M
    Commented Dec 3, 2017 at 1:34
  • I saw other answers to similar questions saying to check for duplicates but since I knew there weren't duplicates in the database and in the csv file I was wondering what the root problem was. I am new to WordPress, I was just looking at WP CLI for the first time yesterday. I will try that in the future. Any commands you can lead me to for bulk inserting posts?
    – Trevor M
    Commented Dec 3, 2017 at 1:38

1 Answer 1

0

I took your code an minimized it, and made a .csv with 3 rows, and was able to get the same error as you.

However, I got three instances of the same post. No coincidence that I have 3 rows in my csv. Your insert code is right, so it has to be the hook being re-called each time the insert is fired.

I changed the hook to something seemingly random, but very specific for being user-end and admin-only, the admin_notices hook, and it worked, no duplicate/triplicate entries made for the one page-load I enabled the code.

Although I don't have documentation to prove this, I believe that many of the Wordpress hooks re-fire with the wp_insert_post call, and thats your problem.

 // causes duplicates ---
//add_action('wp_loaded', 'add_from_csv', 10);

// no duplicates ---
//add_action('admin_notices', 'add_from_csv', 10);

function add_from_csv() {
    if (($handle = fopen(dirname(__FILE__) . "/posts.csv", "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $post_id = wp_insert_post( 
                array(
                    'post_title' => $data[0],
                    'post_type' => 'post',
                    'post_status' => 'publish',
                )
            );
            if(!is_wp_error($post_id) || $post_id != 0)
                echo "<pre>Added {$data[0]}</pre>";

        }
        fclose($handle);
    }
}

I would recommend creating a very simple admin settings/options page instead to house your code, and make the code fire from a form submit button, verified with nonce.

2
  • That makes sense and looks promising. I will try it later and give an update. Thanks for your help!
    – Trevor M
    Commented Dec 3, 2017 at 0:16
  • Tried it and it worked great except it seems to create one extra entry at the very end of post_type 'post'. Not sure why but I just deleted it manually which was fine. Now I will work on moving it to an options page. That seems like the best idea, especially for reusability.
    – Trevor M
    Commented Dec 3, 2017 at 2:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.