@@ -21,6 +21,11 @@ class WPGraphQLAcf {
2121 */
2222 protected $ plugin_load_error_messages = [];
2323
24+ /**
25+ * @var \WPGraphQL\Acf\Registry|null
26+ */
27+ protected $ registry ;
28+
2429 /**
2530 * @return void
2631 */
@@ -39,6 +44,8 @@ public function init(): void {
3944 add_action ( 'after_setup_theme ' , [ $ this , 'acf_internal_post_type_support ' ] );
4045 add_action ( 'graphql_register_types ' , [ $ this , 'init_registry ' ] );
4146
47+ add_filter ( 'graphql_resolve_revision_meta_from_parent ' , [ $ this , 'preview_support ' ], 10 , 4 );
48+
4249 add_filter ( 'graphql_data_loaders ' , [ $ this , 'register_loaders ' ], 10 , 2 );
4350 add_filter ( 'graphql_resolve_node_type ' , [ $ this , 'resolve_acf_options_page_node ' ], 10 , 2 );
4451 /**
@@ -93,19 +100,101 @@ public function init_registry( TypeRegistry $type_registry ): void {
93100
94101 // Register general types that should be available to the Schema regardless
95102 // of the specific fields and field groups registered by ACF
96- $ registry = new Registry ( $ type_registry );
97- $ registry ->register_initial_graphql_types ();
98- $ registry ->register_options_pages ();
103+ $ this -> registry = new Registry ( $ type_registry );
104+ $ this -> registry ->register_initial_graphql_types ();
105+ $ this -> registry ->register_options_pages ();
99106
100107 // Get the field groups that should be mapped to the Schema
101- $ acf_field_groups = $ registry ->get_acf_field_groups ();
108+ $ acf_field_groups = $ this -> registry ->get_acf_field_groups ();
102109
103110 // If there are no acf field groups to show in GraphQL, do nothing
104111 if ( empty ( $ acf_field_groups ) ) {
105112 return ;
106113 }
107114
108- $ registry ->register_acf_field_groups_to_graphql ( $ acf_field_groups );
115+ $ this ->registry ->register_acf_field_groups_to_graphql ( $ acf_field_groups );
116+ }
117+
118+ /**
119+ * @param int $post_id The ID of the post to check if it's a preview of another post
120+ *
121+ * @return bool|\WP_Post
122+ */
123+ protected function is_preview_post ( int $ post_id ) {
124+ $ post = get_post ( $ post_id );
125+
126+ if ( ! $ post ) {
127+ return false ; // Post does not exist
128+ }
129+
130+ // Check if it's a revision (autosave)
131+ if ( 'revision ' === $ post ->post_type && 'inherit ' === $ post ->post_status ) {
132+ $ parent_post = get_post ( $ post ->post_parent );
133+
134+ // Check if parent post is either a draft or published
135+ if ( $ parent_post && in_array ( $ parent_post ->post_status , [ 'draft ' , 'publish ' ], true ) ) {
136+ return $ parent_post ; // It's a preview of a draft or published post
137+ }
138+ }
139+
140+ return false ; // Not a preview post
141+ }
142+
143+
144+ /**
145+ * Add support for resolving ACF Fields when queried for asPreview
146+ *
147+ * NOTE: this currently only works if classic editor is not being used
148+ *
149+ * @param bool $should Whether to resolve using the parent object. Default true.
150+ * @param int $object_id The ID of the object to resolve meta for
151+ * @param string $meta_key The key for the meta to resolve
152+ * @param bool $single Whether a single value should be returned
153+ *
154+ * @return bool
155+ */
156+ public function preview_support ( bool $ should , int $ object_id , string $ meta_key , bool $ single ): bool {
157+ if ( ! $ this ->registry instanceof Registry ) {
158+ return (bool ) $ should ;
159+ }
160+
161+ $ preview_post = $ this ->is_preview_post ( $ object_id );
162+ if ( ! $ preview_post instanceof WP_Post ) {
163+ return (bool ) $ should ;
164+ }
165+
166+ // If the block editor is being used for the post, bail early as the Block Editor doesn't
167+ // properly support revisions of post meta
168+ // see: https://github.com/WordPress/gutenberg/issues/16006#issuecomment-657965028
169+ if ( use_block_editor_for_post ( $ preview_post ) ) {
170+ 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 ' ) );
171+ return (bool ) $ should ;
172+ }
173+
174+ $ registered_fields = $ this ->registry ->get_registered_fields ();
175+
176+ if ( in_array ( $ meta_key , $ registered_fields , true ) ) {
177+ return false ;
178+ }
179+
180+ foreach ( $ registered_fields as $ field_name ) {
181+ // For flex fields/repeaters, the meta keys are structured a bit funky.
182+ // This checks to see if the $meta_key starts with the same string as one of the
183+ // acf fields (a flex/repeater field) and then checks if it's preceeded by an underscore and a number.
184+ if ( strpos ( $ meta_key , $ field_name ) === 0 ) {
185+ // match any string that starts with the field name, followed by an underscore, followed by a number, followed by another string
186+ // ex my_flex_field_0_text_field or some_repeater_field_12_25MostPopularDogToys
187+ $ pattern = '/ ' . $ field_name . '_\d+_\w+/m ' ;
188+ preg_match ( $ pattern , $ meta_key , $ matches );
189+
190+ // If the meta key matches the pattern, treat it as a sub-field of an ACF Field Group
191+ if ( null !== $ matches ) {
192+ return false ;
193+ }
194+ }
195+ }
196+
197+ return $ should ;
109198 }
110199
111200 /**
0 commit comments