I am working on the below function which will eventually create a set of posts based on meta data entered into a "parent" post. I'm running into an infinite loop when hitting the save button, which I know is often caused by using wp_update_post or wp_save_post while hooking into save_post action. I've removed the action temporarily at the top of the function, and re-added it at the end in the hopes of preventing that, but it doesn't seem to have done so.

Can anyone see where I'm causing an infinite loop below?

function my_acf_save_post( $post_id ) {
    remove_action('acf/save_post', 'my_acf_save_post'); //remove action temporarily to prevent infinite loops!

    //All the dates saved in the repeater field
    $chosenDates = get_field('add_dates_and_times', $post_id); //timestamp

    //Get duration of event and multiply by 60 to get seconds
    $duration = get_field('event_duration', $post_id); //duration in minutes
    $duration = ($duration * 60); //duration in seconds

    //Get any event posts that have the ac_parent_id that matches the current parent post
    $currentChildEvents = get_posts(array(
        'post_type' => 'tribe_events',
        'meta_query' => array(
                'meta_key' => 'ac_parent_post',
                'meta_value' => $post_id,
    $hasChildren = have_posts($currentChildEvents); //true/false
    if ($hasChildren) {
            $existingDates = array();
        while($hasChildren) {
            $existingDate = get_post_meta(get_the_ID(), '_EventStartDate', true);
            $existingDates[] = strtotime($existingDate['0']); //timestamp

    $datesNeedEvents = array_diff($chosenDates, $existingDates); //All the timestamps that need events created for them

    //check if the repeater has any values entered
    if (have_rows('add_dates_and_times', $post_id)) {
            update_post_meta($post_id, 'is_ac_parent_event', true); //Since we have some dates, make this event a parent
            update_post_meta($post_id, 'ac_child_dates', $chosenDates); //Set the array of child dates as a meta value in the parent post
            $count = 0;
        while (have_rows('add_dates_and_times', $post_id)) { //Loop through each date in repeater

            $dateTime = get_sub_field('date_and_time'); //timestamp
            $startDate = date('Y-m-d', $dateTime);

            $startHour = date('h', $dateTime);
            $startMinute = date('i', $dateTime);
            $startMeridian = date('a', $dateTime);

            $endStamp = ($dateTime+$duration);
            $endDate = date('Y-m-d', $endStamp);
            $endHour = date('h', $endStamp);
            $endMinute = date('i', $endStamp);
            $endMeridian = date('a', $endStamp);
            if ($count == 1) { //This is the first date listed, so we update the parent post with its info
                $updateCurrent = array (
                    'post_title' => get_the_title($post_id),
                    //'post_content' => ac_get_the_content($post_id),
                    'EventStartDate' => $startDate,
                   'EventEndDate' => $endDate,
                   'EventStartHour' => $startHour,
                   'EventStartMinute' => $startMinute,
                   'EventStartMeridian' => $startMeridian,
                   'EventEndHour' => $endHour,
                   'EventEndMinute' => $endMinute,
                   'EventEndMeridian' => $endMeridian,
                tribe_update_event($post_id, $updateCurrent);
            } else {
                if (in_array($dateTime, $datesNeedEvents)) {
                    $newEvent = array(
                        'post_title' => get_the_title($post_id),
                        //'post_content' => ac_get_the_content($post_id),
                        'EventStartDate' => $startDate,
                       'EventEndDate' => $endDate,
                       'EventStartHour' => $startHour,
                       'EventStartMinute' => $startMinute,
                       'EventStartMeridian' => $startMeridian,
                       'EventEndHour' => $endHour,
                       'EventEndMinute' => $endMinute,
                       'EventEndMeridian' => $endMeridian,
                       //'Venue' => array(
                        //'Venue' => 'Some Place',
                        //  'Country' => 'US',
                        //  'Address' => '1 W. Washington Ave.',
                        //  'City' => 'Madison',
                        //  'State' => 'WI'     
                    $newEvent = tribe_create_event($newEvent);
                    update_post_meta($newEvent, 'ac_parent_event', $post_id);
    } else { //No dates present in repeater
        update_post_meta($post_id, 'ac_parent_event', false); //We set this to false, just in case it was true before
    add_action('acf/save_post', 'my_acf_save_post'); //re-add action to continue
    if (!is_admin) {
        wp_redirect(get_bloginfo('url').'/events/community/edit/event/'.$post_id); exit;
add_action('acf/save_post', 'my_acf_save_post', 20);
  • if $hasChildren is true, while($hasChildren) will never evaluate to false and you'll never exit that loop, the value is never changed. refer to the loop example on WP_Query for correct use. – Milo Jan 16 '16 at 16:59
  • And, to clarify: tribe_update_event() and tribe_create_event() are basically the same as wp_update_post() and wp_insert_post(), they are just wrappers for those functions that do a few extra things with meta fields before saving/creating the post – Eckstein Jan 16 '16 at 16:59
  • Ah, I see now. I was jumbling up get_posts and wp_query usage! Thank you. – Eckstein Jan 16 '16 at 17:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.