Solved: Update and Save Advance Custom Fields data within a WordPress Loop

I was using an old WordPress theme which generates a custom post meta for each post. Those meta keys are tied up with the old theme wherein the functionality will be lost when migrating to another WP theme.

So before switching to the new theme, I decided to use Advance Custom Fields plugin and created fields equivalent for each meta keys used by the old theme. I was able to retrieve the key-values from the old theme and saved the values to the newly created ACF fields by iterating over each post using the following snippet.

foreach($posts as $post) {
       update_field('is_post_review', 'yes', $post->ID);
}

The above code updates the values which can be verified in the backend by looking at the Advance Custom Fields’ Metabox of each post. But I always get a null result when trying to retrieve the value in the front-end using get_field(‘is_post_review’) in the template.

I discovered that when I manually click the Update button in each post that’s the only time that the value of the ACF field becomes available for access in the Front-end.

So, what’s going on here?

I did a quick research and found that Advance Custom Fields’ values are mapped into a unique field keys. So what I was doing earlier is that I was trying to get the value by its field name. It’s quite tricky because the field’s value can also be accessed by its key. The array structure is something like the following:

$field = array(
   'name' => 'is_post_review',
   'key' => 'field_jkh123j123g',
   // ...and so on...	
);

How the issue was resolved?

First, I applied a filter to the ACF get fields hook by also passing the Group ID of the fields I want to access which will create an array of key-values.

$fields = apply_filters('acf/field_group/get_fields', $fields, $group_ID);

Second, iterate over each field and create another array of keys.

foreach( $fields as $field ) {
         $keys[$field['name']] = $field['key'];
}

The above code will result to the following.

$keys['is_post_review'] = 'field_jkh123j123g';

Finally, to make everything work. I updated my original snippet to the following.

foreach($posts as $post) {
        update_field($keys['is_post_review'], 'yes', $post->ID);
        // The above line simply means the following
        //update_field('field_jkh123j123g', 'yes', $post->ID);
}

Here’s the following full code which does the trick.

// You can change the $group_ID to your actual ACF group ID
$group_ID = 6776;
$fields = array();
$fields = apply_filters('acf/field_group/get_fields', $fields, $group_ID);
$keys = array();

if( $fields )
   {
      // Build an array of keys having the field's name as index key
      foreach( $fields as $field )
   {
      $keys[$field['name']] = $field['key'];
   }
}

$posts = query_posts( 
   array(
      'post_type' => 'post',
      'posts_per_page' => 500
   )
);

foreach($posts as $post) {
       update_field($keys['is_post_review'], 'yes', $post->ID);
}

The Advance Custom Fields’ value can now be accessed in the front-end using the get_field(‘is_post_review’) function.

Cromwell Bayon

He is a self-tutored programmer and a Full-Stack Developer. He strives to excel in the newest technology as possible. He has a very high sense of technicality and analytical skills which allows him to resolve any kind of issues related to technology. He also loves woodworking. Read more about him here...

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.