@@ -21,6 +21,12 @@ class WPGraphQLAcf {
2121 protected $ plugin_load_error_messages = [];
2222
2323 /**
24+ * @var \WPGraphQL\Acf\Registry|null
25+ */
26+ protected $ registry ;
27+
28+ /**
29+ * @return void
2430 * Initialize the plugin
2531 */
2632 public function init (): void {
@@ -38,6 +44,8 @@ public function init(): void {
3844 add_action ( 'after_setup_theme ' , [ $ this , 'acf_internal_post_type_support ' ] );
3945 add_action ( 'graphql_register_types ' , [ $ this , 'init_registry ' ] );
4046
47+ add_filter ( 'graphql_resolve_revision_meta_from_parent ' , [ $ this , 'preview_support ' ], 10 , 4 );
48+
4149 add_filter ( 'graphql_data_loaders ' , [ $ this , 'register_loaders ' ], 10 , 2 );
4250 add_filter ( 'graphql_resolve_node_type ' , [ $ this , 'resolve_acf_options_page_node ' ], 10 , 2 );
4351 /**
@@ -89,19 +97,99 @@ public function init_registry( TypeRegistry $type_registry ): void {
8997
9098 // Register general types that should be available to the Schema regardless
9199 // of the specific fields and field groups registered by ACF
92- $ registry = new Registry ( $ type_registry );
93- $ registry ->register_initial_graphql_types ();
94- $ registry ->register_options_pages ();
100+ $ this -> registry = new Registry ( $ type_registry );
101+ $ this -> registry ->register_initial_graphql_types ();
102+ $ this -> registry ->register_options_pages ();
95103
96104 // Get the field groups that should be mapped to the Schema
97- $ acf_field_groups = $ registry ->get_acf_field_groups ();
105+ $ acf_field_groups = $ this -> registry ->get_acf_field_groups ();
98106
99107 // If there are no acf field groups to show in GraphQL, do nothing
100108 if ( empty ( $ acf_field_groups ) ) {
101109 return ;
102110 }
103111
104- $ registry ->register_acf_field_groups_to_graphql ( $ acf_field_groups );
112+ $ this ->registry ->register_acf_field_groups_to_graphql ( $ acf_field_groups );
113+ }
114+
115+ /**
116+ * @param int $post_id The ID of the post to check if it's a preview of another post
117+ *
118+ * @return bool|\WP_Post
119+ */
120+ protected function is_preview_post ( int $ post_id ) {
121+ $ post = get_post ( $ post_id );
122+
123+ if ( ! $ post ) {
124+ return false ; // Post does not exist
125+ }
126+
127+ // Check if it's a revision (autosave)
128+ if ( 'revision ' === $ post ->post_type && 'inherit ' === $ post ->post_status ) {
129+ $ parent_post = get_post ( $ post ->post_parent );
130+
131+ // Check if parent post is either a draft or published
132+ if ( $ parent_post && in_array ( $ parent_post ->post_status , [ 'draft ' , 'publish ' ], true ) ) {
133+ return $ parent_post ; // It's a preview of a draft or published post
134+ }
135+ }
136+
137+ return false ; // Not a preview post
138+ }
139+
140+
141+ /**
142+ * Add support for resolving ACF Fields when queried for asPreview
143+ *
144+ * NOTE: this currently only works if classic editor is not being used
145+ *
146+ * @param bool $should Whether to resolve using the parent object. Default true.
147+ * @param int $object_id The ID of the object to resolve meta for
148+ * @param string $meta_key The key for the meta to resolve
149+ * @param bool $single Whether a single value should be returned
150+ */
151+ public function preview_support ( bool $ should , int $ object_id , string $ meta_key , bool $ single ): bool {
152+ if ( ! $ this ->registry instanceof Registry ) {
153+ return (bool ) $ should ;
154+ }
155+
156+ $ preview_post = $ this ->is_preview_post ( $ object_id );
157+ if ( ! $ preview_post instanceof WP_Post ) {
158+ return (bool ) $ should ;
159+ }
160+
161+ // If the block editor is being used for the post, bail early as the Block Editor doesn't
162+ // properly support revisions of post meta
163+ // see: https://github.com/WordPress/gutenberg/issues/16006#issuecomment-657965028
164+ if ( use_block_editor_for_post ( $ preview_post ) ) {
165+ graphql_debug ( __ ( 'The post you are querying as a preview uses the Block Editor and saving & previewing meta is not fully supported by the block editor. This is a WordPress block editor bug. See: https://github.com/WordPress/gutenberg/issues/16006#issuecomment-657965028 ' , 'wpgraphql-acf ' ) );
166+ return (bool ) $ should ;
167+ }
168+
169+ $ registered_fields = $ this ->registry ->get_registered_fields ();
170+
171+ if ( in_array ( $ meta_key , $ registered_fields , true ) ) {
172+ return false ;
173+ }
174+
175+ foreach ( $ registered_fields as $ field_name ) {
176+ // For flex fields/repeaters, the meta keys are structured a bit funky.
177+ // This checks to see if the $meta_key starts with the same string as one of the
178+ // acf fields (a flex/repeater field) and then checks if it's preceeded by an underscore and a number.
179+ if ( strpos ( $ meta_key , $ field_name ) === 0 ) {
180+ // match any string that starts with the field name, followed by an underscore, followed by a number, followed by another string
181+ // ex my_flex_field_0_text_field or some_repeater_field_12_25MostPopularDogToys
182+ $ pattern = '/ ' . $ field_name . '_\d+_\w+/m ' ;
183+ preg_match ( $ pattern , $ meta_key , $ matches );
184+
185+ // If the meta key matches the pattern, treat it as a sub-field of an ACF Field Group
186+ if ( null !== $ matches ) {
187+ return false ;
188+ }
189+ }
190+ }
191+
192+ return $ should ;
105193 }
106194
107195 /**
0 commit comments