Classic Editor preview shows published field values on every other click when the post has `_acf_changed` saved in its meta

未关闭
#1,052 1 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
45/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
php, wordpress
领域
backend

调研方向

Start with includes/revisions.php, especially acf_revisions::wp_preview_post_fields() and the _acf_changed revision registration described in the report. Trace how WordPress creates and restores Classic Editor autosaves, then reproduce the alternating preview behavior with a published post whose _acf_changed meta is 1. Done means repeated previews keep showing the current unsaved field values without leaving the request flag on the parent post.

由索引模型根据 Issue 内容生成。

描述

Describe the bug

In the Classic Editor, on a published post, if the post's own meta contains _acf_changed with a value of 1, then previewing a change to an ACF field only works on every other click. On alternate clicks WordPress deletes the autosave, and the preview shows the published values.

This came to us through a WPGraphQL for ACF report (https://github.com/wp-graphql/wp-graphql/issues/4529), but it reproduces in WordPress's own front-end preview with only ACF PRO and the Classic Editor plugin active.

The cause, as far as I can tell:

  • acf_revisions::wp_preview_post_fields() (revisions.php#L150-L163) adds _acf_changed to the revision fields on a preview request, so that wp_create_post_autosave() sees the autosave as different from the post and updates it rather than deleting it.
  • wp_create_post_autosave() compares the posted _acf_changed ('1') against $post->_acf_changed, which WP_Post::__get() reads from the post's meta. Normally that's empty, so the values differ and the autosave is kept.
  • Since 6.2.6, _acf_changed is registered with revisions_enabled (revisions.php#L52-L78), so restoring an autosave from the Revisions screen copies _acf_changed = 1 onto the post itself, and later updates don't remove it.
  • Once the post has 1 saved, the comparison matches. If title, content and excerpt are unchanged too, WordPress decides the autosave is identical to the post and deletes it. The next click creates a fresh autosave, the one after deletes it again, and so on.

To Reproduce

  1. Activate ACF PRO and the Classic Editor plugin.
  2. Create a field group with a Text field, shown on Pages.
  3. Create a page, set the field to A, and publish it. Render the field in the template, or use any other way to view the preview.
  4. Change the title and set the field to B, click Preview, then leave the editor without updating.
  5. Go to the page's Revisions screen and click "Restore This Autosave".
  6. wp post meta get <page-id> _acf_changed now returns 1. Clicking Update in the editor afterwards doesn't clear it.
  7. In the editor, change only the field to C and click Preview: the preview shows C.
  8. Click Preview again without changing anything: the preview shows the published value, and the autosave has been deleted.
  9. Keep clicking: it alternates between the two.

Deleting the meta (wp post meta delete <page-id> _acf_changed) makes every click work again. Changing the title or content along with the field also avoids it.

Expected behavior

Every preview click shows the current unsaved field values. _acf_changed is a request flag, so it shouldn't end up persisted on the parent post, or the comparison shouldn't depend on what's stored there.

Possible fixes, in case they're useful:

  • don't restore _acf_changed onto the parent post in wp_restore_post_revision (or delete it from the parent afterwards)
  • in wp_preview_post_fields(), set a value that can't match stored meta, for example a timestamp or a random string, rather than relying on the post not having 1 saved

The block editor isn't affected, because the REST autosave controller compares meta strictly and always sees a difference.

Version Information:

  • WordPress 7.0
  • PHP 8.3.35
  • ACF PRO 6.8.4 (the original report was on 6.3.8, which has the same revisions code)
  • Classic Editor 1.7.0
  • Chromium (headless, driven by Playwright)

Additional context

AdvancedCustomFields/acf#903 covers block editor previews and is a different problem.

主要语言
PHP
星标
947
派生
198
PR 合并指标
30 天内没有已合并 PR

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

AdvancedCustomFields/acf 的其他 Issue

查看 AdvancedCustomFields/acf 的全部 Issue

相似的 Issue

更多 PHP Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。