Home Forums Backend Issues (wp-admin) update_field is not working in action hook


update_field is not working in action hook

  • i have action hook for draft_to_publish. one of the line is to update a textarea in the custom post type and it doesn’t work. the same block of code copied to page template and execute by accessing the permalink, it works. any one has similar experience?

  • Hooks need to be placed in functions.php, not in specific templates. Template files are not loaded during post saving.

  • it’s inside functions.php and not working.

    when copied to page template, only the code from inside the function, excluding the action hook lines

  • Please provide more details on what you’re trying to accomplish and the code that you’re using.

  • the situation:
    i have a custom post type where fields are created using php (not acf gui). one of the fields, a readonly text area, is supposed to be populated after users save draft then click publish.

    the actual code:
    created a function that do some string generation using while loop. at the last line of the function, update_field the text area. it hooked into draft_to_publish action with priority 10 (tried 5 and 20, same issue)

    the problem:
    all codes in the function are run without error (this is tested and verified) but the field is not updated.

    the test:
    we copied all codes inside the function to a page template, link it with that particular content, visit the permalink to execute the code. it runs fine and updated the textarea field

    hope that’s more clear on the problem

  • update_field(‘talist’, $pcontent, $post->ID);

    this is the code that doesnt run inside the action hook. the ‘talist’ is the field key/name.

    the same line is working inside page template

  • The problem here, I think, is that you’re attempting to update a field that does not exist when you’re trying to update it. Try using the field key instead of the field name. the field key should always be used when saving values that are new.

    Also set the priority > 10. ACF uses the same hooks to update fields that we use and it uses the default priority of 10. If for some reason ACF runs after your filter then it will overwrite whatever you update the field to.

    The final issue could be using the draft_to_publish hook. I don’t know the details this hook, when it is called or how it works. It could be possible that whatever values you’re trying to get to update the value of your field don’t exist, but you said that “all codes in the function are run without error (this is tested and verified)” so I’m guessing that this isn’t the problem.

  • i have the same identification for both key and name. i did tried to differentiate the key and name but didn’t work.

    the field does exist, checked the postmeta table in mysql but there’s no value. tried the page template and it does filled the textarea. tried to switch post status to draft then publish, it does not update the textarea field which was populated using the page template

    the variable $pcontent does has value hence it’s not empty, this is confirmed.

    my guess is the update_field is not working from inside the hook action (btw, it’s not filter). but i can’t think of any reason.

  • Field keys must start with “field_”. Not using this prifix can cause various side effects, for example, when using the field key in update_field(), if the key does not start with “field_” acf does not understand that you are attempting to use a field key. This is covered here

  • under Getting Started, it only says the key must be unique, doesn’t mention it must be started with “field_”. Anyway, i changed the keys to start with “field_”, still same problem

  • If it’s not working with the field key with a priority > 10 then the field is not registered when you are trying to update it.

    “When” are you registering the field? On what hook is your function that creates the field running?

  • currently at priority 20

    i can see this key inside postmeta table in mysql, it should be registered. i tried to access permalink for manual execution, it filled the field then set back to draft then publish again, still doesn’t update the field. it has to be registered, i can see content in it.

    the field is added together with all other fields (total 15 fields) in a separate php file. the php file is loaded in the beginning inside functions.php

    this is the only field that has update_field. the rest of the fields are user input and get_fields are working find from inside action hook function

  • It can be confusing, but just because you see the field in the database does not mean the field is registered when you are trying to update it. I don’t know the entire sequence of events that are fired when you use the draft_to_publish hook or what files may or may not be loaded at the time.

    But that really did not answer my question. Are the fields registered in a function? Is this function run on a hook? Are are the calls to the ACF function just at the top level of the file outside of any functions?

    As a test to see if the field is registered, if you want to do some debugging, just before you try to call update_field() for this update you can try getting the field object.

    $field = get_field_object('field_YOUR-FIELD-KEY');
  • There is another thing I just thought of that could also be a problem. Try supplying the post ID.

    add_action('draft_to_publish', 'your_function_name');
    function your_function_name($post) {
      update_field('your field key', $post->ID);
  • Hello John, was there any more resolution on this?

    I am having the same issue. When I run this code from inside a woocommerce hook it does not work, but when I run the same exact code from inside a function on another page that is not run from inside a woocommerce hook it works fine. The last line of code is not updating that particular meta field that I added with ACF. But again the same exact code is working when run outside of a woocommerce hook. Do you have any guidance on this?

    $user_id = get_current_user_id();
    $user_pickup_location_key = ‘default_pickup_location’;
    $subscription_pickup_location_key = ‘subscription_pickup_location’;
    $user_default_pickup_location = get_field($user_pickup_location_key, “user_{$user_id}”);

    update_field($subscription_pickup_location_key, $user_default_pickup_location, 6369);

    Thank you for your time,

  • This is not a field key

    $subscription_pickup_location_key = ‘subscription_pickup_location’;

    When updating fields that do not yet exist you must use the field key

  • I think I’m having this problem as well. It’s really wierd.

    I’m building a custom WooCommerce-action that does a bunch of stuff for the given order. I initiate the action, by adding this to the functions.php-file:

    function custom_add_order_action( $actions ){
      global $theorder;
      $actions['custom_thing'] = 'My own custom action';
      return $actions;
    add_action( 'woocommerce_order_actions', 'custom_add_order_action' );
    add_action( 'woocommerce_order_action_custom_thing', 'custom_action_content' );
    function custom_action_content( $order ){
      $my_class = new WcActionCustomActionClass( $order );

    … and inside WcActionCustomActionClass a bunch of things happen.

    One of which should be to update the ACF-fields for the WooCommerce order. Let’s say that the order_id is 12345.

    Regardless of what I do, then I can’t get it to update _any_ of the fields, when I run update_field() inside my class, _unless_ if I write die()' afterwards(?!).

    So if I do this:

    update_field( 'test', 'some value', 12345 );

    and run the action, then the value of the test-field hasn’t changed.

    But if do this:

    update_field( 'test', 'some value', 12345 );

    … and then check it in another browser-window, then the value _does_ change. Really wierd!


    ### Solution attempts

    **1. New field**

    I tried creating a new field and trying to update that. Exactly the same bug as described above.

    **2. Updating the field elsewhere**

    I tried updating the field in the init-hook, ensuring that my code actually works:

    function test_init(){
      update_field( 'test', 'another test value', 12345 );
    add_action( 'init', 'test_init' );

    This updates the field (as it should).

    **3. Updating the field before my class is initialized**

    I tried changing my code, so it looks like this instead:

    function custom_action_content( $order ){
      update_field( 'test', 'another another test value', 12345 );
      $my_class = new WcActionCustomActionClass( $order );

    **4. Using the field_key**

    I tried using the field key, like this:

    function custom_action_content( $order ){
      update_field( 'field_603f667437ba9', 'another another another test value', 12345 );
      $my_class = new WcActionCustomActionClass( $order );

    … Same thing. No change.

    And again. If I do this:

    function custom_action_content( $order ){
      update_field( 'field_603f667437ba9', 'another another another test value', 12345 );
      $my_class = new WcActionCustomActionClass( $order );

    … and open the order in a new window, then the value updates(?!). Omg…

    **5. get_the_object**

    Inside my class, I tried getting the field object, ensuring that it was accessible. So I did this:

    $field = get_field_object( 'field_603f667437ba9' );
    vardump( $field );

    and it returns an array of the field:

    array (
      "ID" => 48617
      "key" => "field_603f667437ba9"
      "label" => "Test"
      "name" => "test"
      "prefix" => "acf"
      "type" => "text"

    So it _is_ accessible! Hmm…

    **6. Moving the function up to fire earlier**

    I figured, that maybe something ‘got in the way’ of the ACF-function firing, so by moving it up to be the first thing that runs during that action, then maybe that could make a change.

    … But it was the same result: No change, unless I made it die() just after.

    **7. Moving the function, making it fire later**

    So that means doing this:

    function custom_action_content( $order ){
      $my_class = new WcActionCustomActionClass( $order );
      update_field( 'field_603f667437ba9', 'another another another test value', 12345 );

    … Same thing. Doesn’t change, unless I write die(); after.

    **8. Clear cache and restart Apache/Nginx**

    Didn’t change anything.

    **9. Try using update_post_meta() instead**

    Same result.

    This doesn’t change anything:

    update_post_meta( 12345, 'test', 'Another another another... value' );

    This make the value change:

    update_post_meta( 12345, 'test', 'Another another another... value' );
  • I solved it myself.
    The solution is to add this line:

    wp_safe_redirect( admin_url(‘/post.php?post=’. $post_id .’&action=edit’) );

    after the update_post_meta().

    I think that WooCommerce overwrites the meta-fields as a sort of ‘very-last-thing’, when running those actions.

Viewing 18 posts - 1 through 18 (of 18 total)

The topic ‘update_field is not working in action hook’ is closed to new replies.