Skip to content

Commit e4760cd

Browse files
committed
- Update Registry.php to track field names and keys that have been registered to the Schema
- Use the registered field names and keys to determine wether or not to resolve the field from the post itself (if revision meta is supported) or the parent (if it's not).
1 parent 114a2fe commit e4760cd

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

src/Registry.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Registry {
2828
*/
2929
protected $type_registry;
3030

31+
3132
/**
3233
* @param \WPGraphQL\Registry\TypeRegistry|null $type_registry
3334
*
@@ -46,6 +47,13 @@ public function __construct( TypeRegistry $type_registry = null ) {
4647
do_action( 'wpgraphql/acf/type_registry/init', $this );
4748
}
4849

50+
/**
51+
* @return array
52+
*/
53+
public function get_registered_fields() {
54+
return $this->registered_fields;
55+
}
56+
4957
/**
5058
* @return \WPGraphQL\Registry\TypeRegistry
5159
*/
@@ -473,7 +481,18 @@ public function get_fields_for_field_group( array $acf_field_group ): array {
473481
* @throws \Exception
474482
*/
475483
public function map_acf_field_to_graphql( array $acf_field, array $acf_field_group ): ?array {
476-
return ( new FieldConfig( $acf_field, $acf_field_group, $this ) )->get_graphql_field_config();
484+
$field_config = ( new FieldConfig( $acf_field, $acf_field_group, $this ) )->get_graphql_field_config();
485+
486+
if ( ! empty( $field_config['acf_field'] ) ) {
487+
if ( isset( $field_config['acf_field']['key'] ) && ! in_array( $field_config['acf_field']['key'], $this->registered_fields, true ) ) {
488+
$this->registered_fields[] = $field_config['acf_field']['key'];
489+
}
490+
if ( isset( $field_config['acf_field']['name'] ) && ! in_array( $field_config['acf_field']['name'], $this->registered_fields, true ) ) {
491+
$this->registered_fields[] = $field_config['acf_field']['name'];
492+
}
493+
}
494+
495+
return $field_config;
477496
}
478497

479498

src/Utils.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public static function should_field_group_show_in_graphql( array $acf_field_grou
284284
if (
285285
( isset( $acf_field_group['is_options_page'] ) && false === $acf_field_group['is_options_page'] ) &&
286286
! isset( $acf_field_group['show_in_graphql'] ) ) {
287-
$acf_field_group['show_in_graphql'] = $show_in_rest ?? false;
287+
$acf_field_group['show_in_graphql'] = $show_in_rest;
288288
}
289289

290290
if ( isset( $acf_field_group['show_in_graphql'] ) && false === $acf_field_group['show_in_graphql'] ) {

src/WPGraphQLAcf.php

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)