Support

Account

Home Forums General Issues Insert a new Custom Post Type with populated ACF fields via code

Solving

Insert a new Custom Post Type with populated ACF fields via code

  • Hi Elliot, thanks for a fantastic plugin.

    I’ve got a Custom Post Type (well a few actually) that have been extended by your great plugin to add a variety of custom fields to them – for this thread let’s call this CPT ‘Ideas’.

    Everything works fine using the WP Admin interface automatically created by your plugin and WordPress to add new Ideas and to edit the Ideas custom fields.

    We have written some custom code so that the submission of a ‘Contact Form 7’ form creates a new record in our Ideas Custom Post Type. We use the add_action('wpcf7_before_send_mail', '[name of our function]', 1); to do the insert, which fires the CPT insert function using $post_id = wp_insert_post($newpost);. This all works fine.

    Based on the ACF documentation on this site though, subsequent to the CTP insert, we also want to populate some ACF fields for the CPT with data from the CF7 form. We tried using the update_field function to add data to custom fields for the Ideas CPT, however there were problems with using this function alone:
    1) if we used the $field_name in the update_field() function, then (if I recall correctly), the WP Admin interface does *not* show the inserted value, however outputting the data via get_field() DOES work
    2) if we used $field_key in the update_field() function, as is suggested we always should, then the WP Admin interface *does* show the inserted value, however outputting the data via get_field() get_field() does *not* work

    (NOTE: I could have got $field_key and $field_name back-to-front in the above – I am still confused about it in fact! – but it was definitely both end results depending on what I used for the first parameter for update_field()).

    Googling the issue I notice that a number of other people are having similar problems, and after much further Googling, I found a post here that says that for inserting CPTs and then adding data for ACF fields you need to use *both* the WordPress add_post_meta() function and the ACF update_field() function (using $field_key) .

    However I’m very surprised that this is not mentioned in the ACF documentation anywhere, that I could see, and as a result I’m wondering whether:
    a) The documentation for ACF’s update_field() should have some documentation written about creating CPTs via code and populating ACF Custom Field data and using WP’s add_post_meta() function *as well*.
    b) Or is there is a serious bug in ACF (ie. if the update_field() function is supposed to take care of all of this (and add_post_meta() should not actually be used?) but in fact it doesn’t work properly for the use case of creating a new CPT via code).

    Using both functions I notice that in the WP database in the ‘wp_postmeta’ table that as a result there seems to be 3 records per ‘key/name’ – eg. for an Ideas email address, there are three rows:
    email_address
    idea_email_address
    _idea_email_address.

    (It probably doesn’t help that before we realised too late to change it, we edited our ‘keys’ to have a readable name – so for example, in a field group, the ’email address field has name email_address and the key is idea_email_address. Perhaps that is why the update_field() function didn’t work as we expected? Or doesn’t it matter, as long as the ACF field keys are unique?).

    I would be very pleased if you could clear any of this up!

    Thanks from a fellow Melburnian!

    Cheers
    Matt

  • Ok thanks wube – interesting reading. Seems to be a common problem, would be great if there was a function as you say (seems crazy that you can have keys with duplicate names in WordPress; also, not sure why performance is such a concern – things are fast as they are, it’s only relevant on inserts that happen infrequently and once-off, and if people want it fast then they should be fully hand-coding it – apart from anything else, as I see it this plugin is a massive development time saver).

    The burning ‘issue’ then in my opinion is that some documentation of an actual working example of how to do this would be super useful, and save a lot of people a lot of headaches.

    I have read the documentation multiple times but still not clear what I’m doing different. I will have to thus keep using the add_post_meta() function as well, because I can’t otherwise tell the client that each time someone submits an Idea that their Admins have to go to the WP Dashboard, edit the new Idea, and hit the ‘Update’ button just for it to appear properly on the website.

    Perhaps it’s because the field ‘keys’ were named similarly (but not identical) to the field ‘names’ (as I mentioned in my first post).

  • Here is an example function that will search fields and return a field key that matches the field name.

    Please note:

    1) This will only search top level fields, so no fields inside of repeaters or flex fields will be looked at.

    2) It will return the first field key where the field name matches. I think the field groups are search according to the order values of the field groups. This means that if you have two top level fields with the same name it will always return the same field key, the first one it finds. Having multiple field groups using the same field names is not uncommon, I do this all the time so that I can use the same code to get a field used for the same purpose for multiple locations. I create multiple field groups where a few fields are the same but the majority of field are different.

    3) Using this function might have unforeseen side effects depending on where it’s used that has to do with the way that ACF caches field groups and fields.

    
    <?php 
      
      function acf_field_name_to_key($field_name, $post_id=false) {
        $field_key = false;
        $post_id = acf_get_valid_post_id($post_id);
        $args = array();
        if ($post_id) {
          $args = array('post_id' => $post_id);
        }
        $field_groups = acf_get_field_groups($args);
        if (!count($field_groups)) {
          return $field_key;
        }
        foreach ($field_groups as $group) {
          $fields = acf_get_fields($group['key']);
          if (!count($fields)) {
            // no fields
            break;
          }
          foreach ($fields as $field) {
            if ($field['name'] == $name) {
              return $field['key'];
            }
          } // end foreach $fields
        } // end foreach $group
        return $field_key;
      } // end function acf_field_name_to_key
      
    ?>
    
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.