0

I want to write an import of events (that I had as a text).

The post are inserted, but each post is inserted 3 times!?

I'm running a function on after_setup_theme in my functions.php.

What I do:

  1. I refresh to page to run the function
  2. The post is inserted. Great.

enter image description here

  1. I comment the code and refresh the page again.
  2. Then I see the post being inserted 3 times in total.

enter image description here

Am I using the wrong hook, something wrong with my code, or what am I missing?

Here's the code:

function ekesto_insert_post(){
    $import_array = array();

    $new_post = array(
        'post_title' => 'Test Event',
        'post_status'  => 'publish',
        'post_type'  => 'event'
    );
    $new_post_custom_fields = array(
        'category' => 29,
        'date_start' => '20231101',
        'venue_name' => 'Schloss Glarisegg',
        'location' => 'Steckborn (ZH)',
        'organizer_name' => 'Pathways Courses',
        'organizer_url' => 'https://pathways-courses.org/'
    );
    $import_array[] = array($new_post, $new_post_custom_fields);

    foreach ($import_array as $array) {
        // Insert post into the database
        $post_id = wp_insert_post($array[0], true); // Use $wp_error set to true for error handling
        // update ACF custom fields
        foreach ($array[1] as $key => $value) {
            update_field($key, $value, $post_id);
        }
        // Check if there was an error during post insertion
        if (is_wp_error($post_id)) {
            // Error occurred while inserting the post
            echo "Error: " . $post_id->get_error_message();
        } else {
            // The post was successfully inserted, and $post_id contains the post ID
            echo "Post inserted successfully. New Post ID: " . $post_id;
        }
    }
}
add_action('after_setup_theme', 'ekesto_insert_post');

Eventually there will be more events.

Appreciate any hint!

5
  • you mention this runs on after_theme_setup but there's no code to add to that action in your question, or explanation of what you're trying to do. I can also see there's no code to check if the post already exists before calling wp_insert_post. This means every single request to your site will create the posts, frontend requests, AJAX requests, cron jobs, admin pages, even assets that are generated/processed via plugins will trigger this. There is no de-duplication checking in wp_insert_post as sometimes you want to insert the same thing multiple times
    – Tom J Nowell
    Dec 13, 2023 at 14:31
  • Thanks for your feedback, @TomJNowell! I wanted to simplify the code, that's why I left it.. but I now added the code as it is in my file. Thanks for the hint on checking if the post already exists, I will try to add this check.. This already helps! I somehow sensed that it is fired on multiple requests, but never thought about checking if a post with a specific title already exists. I was kind of hoping that I simply used the wrong action hook.
    – beat
    Dec 14, 2023 at 15:39
  • not multiple requests, but all requests of all types, after_setup_theme runs on every single request, and can even run in CLI contexts if you use WP CLI. At a minimum I'd at least restrict this code to running if is_admin is true, these checks are expensive and you shouldn't be doing DB writes on the frontend if you can avoid it
    – Tom J Nowell
    Dec 14, 2023 at 16:26
  • Thanks for clarifying! I only used the code once to import the posts, now it's disabled.. but I'll add is_admin to the code, for a next time. Thanks again!
    – beat
    Dec 15, 2023 at 18:36
  • in future consider a custom WP CLI command, it'll run faster, bypass time/memory limits and you're guaranteed it will only run when you run it
    – Tom J Nowell
    Dec 17, 2023 at 14:23

1 Answer 1

0

Thanks to @TomJNowell's hint I managed to get it working with a simple check if the post already exists (using the post_exists function). This code is included in the functions.php file.

Additionally, the loop only runs if called from the backend using the is_admin function.

Here's the working example:

function ekesto_insert_post(){

    // config
    $post_type = 'event';
    
    // post_exists() is by default only available in the admin, so let's get it in case the page is loaded on the frontend
    require_once(ABSPATH . 'wp-admin/includes/post.php');

    $import_array = array();

    $new_post = array(
        'post_title' => 'Test Event',
        'post_status'  => 'publish',
        'post_type'  => $post_type
    );
    $new_post_custom_fields = array(
        'category' => 29,
        'date_start' => '20231101',
        'venue_name' => 'Schloss Glarisegg',
        'location' => 'Steckborn (ZH)',
        'organizer_name' => 'Pathways Courses',
        'organizer_url' => 'https://pathways-courses.org/'
    );
    $import_array[] = array($new_post, $new_post_custom_fields);

    // only run code in the backend
    if( is_admin()) {
        foreach ($import_array as $array) {
            // check if post title exists
            $fount_post = post_exists( $array[0]['post_title'],'','',$post_type,'publish');
            // 0 is returned if post doesn't exist yet
            if ($fount_post === 0) {
                // Insert post into the database
                $post_id = wp_insert_post($array[0], true); // Use $wp_error set to true for error handling
                // Fill Advanced Custom Fields (ACF) fields
                foreach ($array[1] as $key => $value) {
                    update_field($key, $value, $post_id);
                }
                // Check if there was an error during post insertion
                if (is_wp_error($post_id)) {
                    // Error occurred while inserting the post
                    echo "Error: " . $post_id->get_error_message();
                } else {
                    // The post was successfully inserted, and $post_id contains the post ID
                    echo "Post inserted successfully. New Post ID: " . $post_id;
                }
            }
        }
    }    
}

add_action('after_setup_theme', 'ekesto_insert_post');

Note: The code also adds Advanced Custom Fields (ACF) data using the ACF function update_field().

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.