0
votes

I'm now using WordPress Advanced Custom Fields Plugin: http://www.advancedcustomfields.com/

And I set a repeater field rows on my custom post_type sales_order:

Then, now insert a post using script:

$post_id = wp_insert_post(array(
    'post_title' => $title,
    'post_name' => $slug,
    'post_content' => $content,
    'post_type' => 'sales_order',
    'post_status' => 'publish',
));

But when I do:

update_field('rows', array(), $post_id);

It has no effect.

But if I manually save the post in the admin panel first, then call the update_field method, it works.


So, I tried to spy the wp_postmeta database table, I found that if I call wp_insert_post using script, that post don't generate the meta

| meta_key | meta_value          |
|----------|---------------------|
| _rows    | field_568e7aeb22714 |

correctly.

But I have to do the import workflow using pure script, how can I work around this?

3

3 Answers

0
votes

You are passing field_name but update_field requires field_key as the documentation says update_field

Consider this example

update_field('field_568e7aeb22714', array(), $post_id);
0
votes

Finally I made a solution according the source.


Reason:

Why the below action fails?

update_field('rows', array(), $post_id);

Now we're using the field name, not the field key.

In this case, ACF would do the follows:

  1. Try to find the current post meta which has a meta_key: _rows, which prepend an under-slash before the field name.
  2. After that, get that meta_value, it should be a field key which has a form like field_XXXXXXX
  3. Update the field with the founded field_key.

Now we know, if we do wp_insert_post in such a way, the _rows meta did not generate the correct meta_value.

So if we update the post in the admin panel, the field key was then submitted and generating the correct meta_value.

Conclusion: Only THAT meta value matters.


Solution:

So, in fact, the only things we should do more is to set that meta_values defined in the ACF field set bound to the specified post_type.

The below routine worked that around:

// The current post_type to search
$post_type = 'sales_order';

$post_id = wp_insert_post(array(
    'post_title' => $title,
    'post_name' => $slug,
    'post_content' => $content,
    'post_type' => $post_type,
    'post_status' => 'publish',
));

foreach (get_posts(array('post_type' => 'acf', 'posts_per_page' => -1)) as $acf) {
    $meta = get_post_meta($acf->ID);
    $rule = unserialize($meta['rule'][0]);
    if($rule['param'] == 'post_type' &&
        $rule['operator'] == '==' &&
        $rule['value'] == $post_type) {
        foreach($meta as $key => $field) {
            if(substr($key, 0, 6) == 'field_') {
                $field = unserialize($field[0]);
                update_post_meta($post_id, '_'.$field['name'], $key);
            }
        }
    }
}

Note that, we loop through all defined ACF posts, and check for the rule meta, to confirm if it was bounded on the specified post_type.

If so, loop all that ACF meta starts with field_, and set the meta on the current post.

All done.

0
votes
$i = 0; //for metakey
$j=0; //files Count

foreach($files as $fileid){
    $j++;
    $meta_key = 'files_'.$i.'_file';
    //"files" repeater main name and "file" subname ;
    update_post_meta($post_id,$meta_key,$fileid);
    $i++;

}
update_post_meta($post_id,'files',$j);