Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update_field() not working within acf/update_value filter #440

Open
kmcaloon opened this issue Jan 13, 2021 · 6 comments
Open

update_field() not working within acf/update_value filter #440

kmcaloon opened this issue Jan 13, 2021 · 6 comments

Comments

@kmcaloon
Copy link

I've been trying a couple of different things here. Whenever a field prepended with option_ is saved, I would like to not only save it to the post/block where it is being updated, but also save it as a global "acf option". I have a demo set up with a registered gutenberg block with the field option_demo. The following code doesn't seem to do the trick. I even tried to update_field for the first post in my WP install, and it wouldn't save there either:

add_filter( 'acf/update_value', function( $value, $post_id, $field, $original ) {

  if( substr( $field['name'], 0, 7 ) !== 'option_' ) {
    return $value;
  }

  // This is to avoid infinite loops....
  if( stripos( $post_id, 'option' ) !== false || $post_id == 1 ) {
    return $value;
  }
  
  // Neither one of these work
  update_field( $field['key'], $value, 'option' );
  update_field( $field['key'], $value, 1  );

  return $value;

}, 10, 4 );

Could the problem be related to the fact that the update initiating this whole is within a gutenburg block?

@elliotcondon
Copy link
Contributor

Hi @kmcaloon

Thanks for the topic. Yes, this issue is indeed due to the special circumstances of saving a field within the scope of a block.

During this save event, ACF will set up a "net" to capture all save/update requests from the acf_update_value() function (used by update_field()) and prevent these values from being saved to the DB. This net is part of the magic that allows meta to save within the Gutenberg block HTML markup!

The solution is simple. Instead of using the ACF function update_field(), instead use the WP function update_option().

@kmcaloon
Copy link
Author

Thanks @elliotcondon

So actually originally I was using update_option() before trying this, but the catch was I lose a lot of the functionality that comes with get_field(). I was even trying to hack my way through this my saving an option for field_name = value and _field_name = field key to see if that could get ACF to recognize the options as native ACF fields. I also believe just using options will leave them in there indefinitely even if we ever decide so scrap the fields.

There are a couple of use cases here, but the one I am immediately dealing with is trying to set up global/reusable blocks. There are a few reasons why I would like to achieve this in a custom way rather than using the block editors native setup. So basically when an admin is editing the block anywhere within the post type, I need that data to save somewhere where I can reference it globally. Using just options, it gets dicey when needing to use repeaters, groups, and basic any field with formatting options.

I guess there are no other work arounds here and I might have to tru the block editor's reusable blocks?

@elliotcondon
Copy link
Contributor

Thanks for the additional info!

Your solution of saving both the "value" and "reference value" is a good one, and will allow ACF to lookup the related field for that value, which in turn will allow various filters and formatting to run.

On review of our "magic net" logic, I can confirm that we are catching "all" values that are saved during a block update, and not just those related to that block's ID. Perhaps there is an opportunity here to both fix your specific issue and improve the compatibility of our code.

Please leave this with me and I'll add this to our to-do list.

@kmcaloon
Copy link
Author

Thanks @elliotcondon. So I wasn't clear, the value/reference value in the options table actual didn't work for me. The options were saving but get_field() wasn't able to retrieve the value. I might move forward with trying some ugly solutions for this for the time being. Will leave it open and keep a heads up.

Thanks again.

@kmcaloon
Copy link
Author

Quick update, my ugly solution is working.

// Here is the update field function that will run outside of the "net" via a WP cron event
add_action( 'Namespace\update_field', function( $field, $value )  {

  update_field( $field['key'], $value, 'option' );

}, 1, 2 );

// Here is the normal update_value event.
add_filter( 'acf/update_value', function( $value, $post_id, $field, $original ) {

  if( substr( $field['name'], 0, 7 ) !== 'option_' ) {
    return $value;
  }
  if( stripos( $post_id, 'option' ) !== false || $post_id == 1 ) {
    return $value;
  }

  $args = [
    'field'  => $field,
    'value'  => $value,
  ];
  wp_schedule_single_event( time(), 'Namespace\update_field', $args );

  return $value;

}, 20, 4 );

@E-VANCE
Copy link

E-VANCE commented Jun 14, 2023

I've just been hitting this wall for the last couple of hours and just couldn't wrap my head around it...

Maybe the corresponding docs could include a passage that hints at this behaviour? Would be very helpful IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants