AdvancedCustomFields / acf

Advanced Custom Fields
http://advancedcustomfields.com/
833 stars 169 forks source link

Custom Fields do not save when creating a new page #653

Open willrowe opened 2 years ago

willrowe commented 2 years ago

I have a custom field group that conditionally appears for pages that use a specific template. I do the following:

  1. Create a new page.
  2. Set the title.
  3. Set the template to the one set for the custom field group
  4. Set the value of one of the fields in the field group after it appears.
  5. Publish the page.

If I then refresh the editor page or view the published page, the value set in the field has not been saved.

I dug into this a bit and discovered that WordPress caches the added metaboxes on initial page load and does not check again when publishing. So, if there were no metaboxes when first creating the page, it will not attempt to save any metaboxes when publishing. ACF appears to do the correct thing and register the metaboxes when the conditions are met, but a bug in WordPress (which they may or may not want to fix) does not detect the newly added metaboxes.


To work around this for right now, I basically duplicated the code from WordPress and updated it to check if there are metaboxes every time it detects a save was just requested:

(function (
    external_wp_data_,
    external_wp_editor_
) {
/*
CUSTOMIZATION: MODIFICATION
ORIGINAL:
  let wasSavingPost = yield external_wp_data_["controls"].select(external_wp_editor_["store"], 'isSavingPost');
  let wasAutosavingPost = yield external_wp_data_["controls"].select(external_wp_editor_["store"], 'isAutosavingPost');
  const hasMetaBoxes = yield external_wp_data_["controls"].select(store, 'hasMetaBoxes'); // Save metaboxes when performing a full save on the post.
NEW:
*/
  let wasSavingPost = Object(external_wp_data_["select"])(external_wp_editor_["store"]).isSavingPost();
  let wasAutosavingPost = Object(external_wp_data_["select"])(external_wp_editor_["store"]).isAutosavingPost();
/* CUSTOMIZATION: END */

  Object(external_wp_data_["subscribe"])(() => {
    const isSavingPost = Object(external_wp_data_["select"])(external_wp_editor_["store"]).isSavingPost();
    const isAutosavingPost = Object(external_wp_data_["select"])(external_wp_editor_["store"]).isAutosavingPost(); // Save metaboxes on save completion, except for autosaves that are not a post preview.
    //
    // Meta boxes are initialized once at page load. It is not necessary to
    // account for updates on each state change.
    //
    // See: https://github.com/WordPress/WordPress/blob/5.1.1/wp-admin/includes/post.php#L2307-L2309

/*
CUSTOMIZATION: MODIFICATION
ORIGINAL:
    const shouldTriggerMetaboxesSave = hasMetaBoxes && wasSavingPost && !isSavingPost && !wasAutosavingPost; // Save current state for next inspection.
NEW:
*/
    const shouldTriggerMetaboxesSave = (
      wasSavingPost
        &&
      !isSavingPost
        &&
      !wasAutosavingPost
        &&
      Object(external_wp_data_["select"])(wp.editPost["store"]).hasMetaBoxes()
    );
/* CUSTOMIZATION: END */

    wasSavingPost = isSavingPost;
    wasAutosavingPost = isAutosavingPost;

    if (shouldTriggerMetaboxesSave) {
      Object(external_wp_data_["dispatch"])(wp.editPost["store"]).requestMetaBoxUpdates();
    }
  });
})(
    window.wp.data,
    window.wp.editor
);
lgladdy commented 2 years ago

@willrowe Hey Will,

We're aware of this issue and it's on our fix list for the next release. You're right it seems to happen when there are no meta boxes at page load, but when they're injected in by changing template or some other property that causes it to be shown.

We suspect this was broken in a recent WordPress release.

willrowe commented 2 years ago

Ok, good to know. I was not sure if I had never encountered this specific situation before, or if something changed recently. Do you know if it is an issue known to WordPress? I could not find any matching issues in WordPress/gutenberg.

hristoaleksandrov commented 2 years ago

Hey, has this been resolved, as we are experiencing the same issue?

lgladdy commented 2 years ago

@hristoaleksandrov Unfortunately not yet. This is actually a WordPress bug we're working to resolve. They're no longer correctly firing the save event for meta boxes that are added to the page after initial load - which is why it needs to be saved one before the meta box values will save.

To make it harder - they don't provide us any way to trigger that save manually, so we're likely going to need to contribute upstream to Gutenberg a fix, and wait for it to be released into a future WordPress version.

lgladdy commented 1 year ago

Hey everyone,

Just to update you here - this was fixed and merged upstream in Gutenberg this morning.

It looks like it's scheduled to be included in Gutenberg 14.5, and I suspect will be included in WordPress 6.2.