Support

Account

Home Forums Bug Reports Programmatically inserting field with update_field() does not at _field_key meta

Solved

Programmatically inserting field with update_field() does not at _field_key meta

  • Hi John, thanks for your answer!

    I use only field keys and I use several levels of nested fields, for example:

    `
    const ACF_ID_COMPANY_IDENTITY = ‘field_5d5e603dbfb7b’;
    const ACF_ID_COMPANY_IDENTITY_LOGO = ‘field_5d5e60cbbfb7d’;
    const ACF_ID_COMPANY_IDENTITY_CREATION_YEAR = ‘field_5d5e6279bfb80’;
    const ACF_ID_COMPANY_IDENTITY_HEADER_ILLU = ‘field_5d5e612abfb7e’;
    const ACF_ID_COMPANY_IDENTITY_MAIN_ILLU = ‘field_5d5e61e3bfb7f’;
    const ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA = ‘field_5dc95f49358a6’ . ‘_’ . ACF_ID_GLOBAL_MEDIA;
    const ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_TYPE = ACF_ID_GLOBAL_MEDIA_TYPE;
    const ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_IMAGE = ACF_ID_GLOBAL_MEDIA_IMAGE;
    const ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_VIDEO = ACF_ID_GLOBAL_MEDIA_VIDEO;

    // Logo
    if ($company->hasLogo() && $company->getLogo()->hasId()) {
    $identity[ACF_ID_COMPANY_IDENTITY_LOGO] = $company->getLogo()->getId();
    }

    // Creation Year
    if ($company->hasCreationYear()) {
    $identity[ACF_ID_COMPANY_IDENTITY_CREATION_YEAR] = $company->getCreationYear();
    }

    // — /General

    // — Illustrations
    // Header Illustration
    if ($company->hasHeaderMedia() && $company->getHeaderMedia()->hasId()) {
    $identity[ACF_ID_COMPANY_IDENTITY_HEADER_ILLU] = $company->getHeaderMedia()->getId();
    }

    // Main Illustration
    if ($company->hasMainMedia() && ($company->getMainMedia()->hasId() || $company->getMainMedia()->hasSrc())) {
    $mainMedia = [];

    if ($company->getMainMedia()->isImage()) {
    $mainMedia[ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_TYPE] = Media::ACF_IS_IMAGE;
    $mainMedia[ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_IMAGE] = $company->getMainMedia()->getId();
    }

    if ($company->getMainMedia()->isVideo()) {
    $mainMedia[ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_ TYPE] = Media::ACF_IS_VIDEO;
    $mainMedia[ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_VIDEO] = $company->getMainMedia()->getSrc();
    }

    $identity[ACF_ID_COMPANY_IDENTITY_MAIN_ILLU][ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA] = $mainMedia;
    }
    // — /Illustrations

    // Update IDENTITY
    if (!empty($identity)) {
    update_field(ACF_ID_COMPANY_IDENTITY, $identity, $postId);
    }
    `

    So here what do you think I should do? Use add_row() instead of arrays? Use update_sub_field() instead of update_field() on all $identity variable?

    I admit that I don’t understand why this is a problem… Is it really impossible to take the problem the other way by forcing ACF to retrieve the data in the database that was just put in? Because they are present in the database, these data, and we can see them clearly in the backoffice, why we don’t retrieved them in the frontoffice via get_field()? I do not understand… :/

  • Ok I just searched in ACF code and I can see that acf_get_valid_post_id() executed in get_field() function to get the Post ID return a revision of the post, not the real ID… I don’t understand why but there must be a good reason ^^

    I continue my research…

  • Sooooo I have a workaround:

    remove_action('post_updated', 'wp_save_post_revision');
    
    ...
    wp_update_post($postData);
    ...
    update_field('field_XYZ123', $value, $post_id);
    ...
    
    add_action('post_updated', 'wp_save_post_revision');

    And it works apparently, on the other hand we have no revision during the post update…

    So the real question (I think) is the following:

    Why get_field() called in WP theme doesn’t retrieve the same Post ID than the one retrieved from the Back Office?

  • I cannot honestly say without more understanding of the entire code that is being executed when the post is saved. Looking at the functions you’re calling I’m assuming that it would likely take me hours to get this level of understanding. Things can get quite complicated.

    Here is a simple example. You submit a post, on the front end 2 things happens. First is that acf runs the acf/pre_save_post hook that gets the post ID. Next the post is saved and following that acf saves the fields, acf/save_post runs.

    If you call get_field() during this process ACF will not know what the post ID is that it’s supposed to get the field for because it does not know the post ID. You must supply the correct post ID. The global post ID, if any, will be the post ID where the acf form appears. This is why acf passes the post ID to all acf/save_post actions. You need to pass this ID to any function that will need to get a value from the post that was just saved.

    Then there is the issue of calling wp_update_post() inside of an acf/save_post action. What happes is that you cause acf/save_post to run again because this action is tied to WP’s updating of any post. Usually this causes an infinite loop.

  • Thanks for your explanation John!

    However I think it’s not my problem: I never call get_field() on update/create post process, I call get_field() on page reload AFTER the process is completely finished (after several seconds, and after several reloads ^^). And I call wp_post_update() BEFORE any ACF update_field() (but there are ACF get_field() calling before wp_post_update() to populate data).

    To briefly explain:
    1. I call Airtable API (a Database/Excel like) to retrieve new data
    2. Retrieve the WP Post from WP ID stored in Airtable
    3. Populate Company PHP Object with existing data in WP (use get_field())
    4. Update data in Company PHP Object with new data retrieved in Airtable (custom PHP)
    5. Commit data in WP from new Company PHP Object with wp_update_post() and (only after) update_field().
    6. I go to the Company Page Edition in WP Back Office: All data are updated!
    7. I check in database with an SQL Query: All data are updated correctly
    8. I go to the Company Page in Front End to view modifications (so the PHP process is completely finished) by page reload (several reloads to be sure ^^), but nothing changed, old data are displayed :'( (no cache issue).

    I think my issue doesn’t covered by your explanation, but I could be wrong 😶

    I am currently developing a new getField() function, but if you have a secret sauce… 😁

  • Sorry, I went off on a tangent with my last post. Not saying it was an issue, just that the issues can get complex depending on the interaction filters and actions.

    I really can’t explain why the data is not showing up on the front end but it is in the admin and shows after you do an update. The only thing that I know of that will cause this is that the field key reference for the field is not saved correctly. Or it could be that the data is not saved in the field correctly and ACF is somehow correcting this on the admin page load (although I can’t think of any instance where this could happen.) And I can’t tell from the code you’ve supplied what could be causing this to happen.

    I would look at a specific field that is not showing on the front end. I would look in the database and record all of the DB entries for that field, sub fields, etc. Then I’d save the post so that the data appears and then look for specific differences.

  • Did you find a solution to this @killianleroux ? I’m having the same issue and just can’t understand what’s wrong…

  • Hi @wimellwebb, sorry for the delay :/

    Have you found a solution for you?

  • @killianleroux a couple things:

    1. There’s a space in one of your constants:

    $mainMedia[ACF_ID_COMPANY_IDENTITY_MAIN_ILLU_MEDIA_ TYPE]

    If you haven’t already, you might consider setting WP_DEBUG_LOG to true and checking debug.log when running this.

    2. Revision checks

    Not sure if this will help and I don’t know the full scope of what you’re doing but regarding your remove_action('post_updated', 'wp_save_post_revision'); step, if you’re not familiar you might find these guard clauses helpful, which can be run on the save_post filter (and probably others) if you’ve got a post revisions-related conflict going on:

    	
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    	return $post_id;
    }
    
    if ( wp_is_post_revision($post_id) ) {
    	return $post_id;
    }
    
Viewing 9 posts - 26 through 34 (of 34 total)

The topic ‘Programmatically inserting field with update_field() does not at _field_key meta’ is closed to new replies.