admin管理员组

文章数量:1128196

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.

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

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' => '/'
    );
    $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!

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.

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

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!

Share Improve this question edited Dec 14, 2023 at 16:07 beat asked Dec 13, 2023 at 13:17 beatbeat 436 bronze badges 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 Commented 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 Commented 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 Commented 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 Commented 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 Commented Dec 17, 2023 at 14:23
Add a comment  | 

1 Answer 1

Reset to default 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().

本文标签: functionswpinsertpost inserts 3 posts at once