Skip to content

Commit 7eb9bea

Browse files
committed
- add clone fields to the "should_format" logic
- add missing translators comment - remove some debug code - move logic for clone field interfaces out of the Registry and into the CloneField.php - modify logic for how flex field layouts are mapped to the schema
1 parent 238d702 commit 7eb9bea

File tree

5 files changed

+113
-175
lines changed

5 files changed

+113
-175
lines changed

composer.lock

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/FieldConfig.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public function get_field_description(): string {
144144
// Fallback description
145145
// translators: %s is the name of the ACF Field Group
146146
$description = sprintf(
147+
// translators: %1$s is the ACF Field Type and %2$s is the name of the ACF Field Group
147148
__( 'Field of the "%1$s" Field Type added to the schema as part of the "%2$s" Field Group', 'wp-graphql-acf' ),
148149
$this->acf_field['type'] ?? '',
149150
$this->registry->get_field_group_graphql_type_name( $this->acf_field_group )
@@ -305,6 +306,7 @@ public function should_format_field_value( string $field_type ): bool {
305306
'repeater',
306307
'flexible_content',
307308
'oembed',
309+
'clone',
308310
];
309311

310312
return in_array( $field_type, $types_to_format, true );
@@ -364,10 +366,9 @@ public function resolve_field( $root, array $args, AppContext $context, ResolveI
364366
} elseif ( ! empty( $field_config['__key'] ) ) {
365367
$field_key = $field_config['__key'];
366368
}
367-
$cloned_field_config = acf_get_field( $field_key );
368-
$field_config = ! empty( $cloned_field_config ) ? $cloned_field_config : $field_config;
369369
}
370370

371+
371372
$should_format_value = false;
372373

373374
if ( ! empty( $field_config['type'] ) && $this->should_format_field_value( $field_config['type'] ) ) {
@@ -379,7 +380,7 @@ public function resolve_field( $root, array $args, AppContext $context, ResolveI
379380
}
380381

381382
// if the field_config is empty or not an array, set it as an empty array as a fallback
382-
$field_config = ! empty( $field_config ) && is_array( $field_config ) ? $field_config : [];
383+
$field_config = ! empty( $field_config ) ? $field_config : [];
383384

384385
// If the root being passed down already has a value
385386
// for the field key, let's use it to resolve
@@ -408,6 +409,7 @@ public function resolve_field( $root, array $args, AppContext $context, ResolveI
408409
return $pre_value;
409410
}
410411

412+
$parent_field = null;
411413
$parent_field_name = null;
412414
if ( ! empty( $field_config['parent'] ) ) {
413415
$parent_field = acf_get_field( $field_config['parent'] );
@@ -436,6 +438,8 @@ public function resolve_field( $root, array $args, AppContext $context, ResolveI
436438
}
437439
}
438440

441+
442+
439443
// If there's no node_id at this point, we can return null
440444
if ( empty( $return_value ) && empty( $node_id ) ) {
441445
return null;
@@ -446,7 +450,6 @@ public function resolve_field( $root, array $args, AppContext $context, ResolveI
446450
$return_value = $this->get_field( $field_key, $parent_field_name, $node_id, $should_format_value );
447451
}
448452

449-
450453
// Prepare the value for response
451454
$prepared_value = $this->prepare_acf_field_value( $return_value, $root, $node_id, $field_config );
452455
// Empty values are set to null

src/FieldType/CloneField.php

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use WPGraphQL\Acf\AcfGraphQLFieldType;
55
use WPGraphQL\Acf\FieldConfig;
6-
use WPGraphQL\AppContext;
76
use WPGraphQL\Utils\Utils;
87

98
class CloneField {
@@ -16,8 +15,7 @@ public static function register_field_type():void {
1615
'clone',
1716
[
1817
'graphql_type' => static function ( FieldConfig $field_config, AcfGraphQLFieldType $acf_field_type ) {
19-
20-
$sub_field_group = $field_config->get_acf_field();
18+
$sub_field_group = $field_config->get_raw_acf_field();
2119
$parent_type = $field_config->get_parent_graphql_type_name( $sub_field_group );
2220
$field_name = $field_config->get_graphql_field_name();
2321

@@ -35,29 +33,48 @@ public static function register_field_type():void {
3533
}
3634
}
3735

38-
if ( ! empty( $cloned_groups ) && false === (bool) $sub_field_group['prefix_name'] ) {
39-
$parent_group = acf_get_field_group( $sub_field_group['parent'] );
40-
$cloned_group_interfaces = [];
41-
foreach( $cloned_groups as $cloned_group ) {
36+
$cloned_group_interfaces = [];
37+
38+
if ( ! empty( $cloned_groups ) ) {
39+
foreach ( $cloned_groups as $cloned_group ) {
4240
$cloned_group_interfaces[] = $field_config->get_registry()->get_field_group_graphql_type_name( $cloned_group ) . '_Fields';
4341
}
44-
// wp_send_json( [
45-
// '$clone' => $sub_field_group['clone'],
46-
// '$cloned_groups' => $cloned_groups,
47-
// '$cloned_group_interfaces' => $cloned_group_interfaces,
48-
// 'parent_field_group' => $parent_group,
49-
// '$sub_field_group' => $sub_field_group,
50-
// '$parent_graphql_type_name' => $parent_group_type_name
51-
// ] );
52-
5342
}
5443

55-
if ( ! empty( $cloned_group_interfaces ) && ! empty( $parent_group ) ) {
56-
$parent_group_type_name = $field_config->get_registry()->get_field_group_graphql_type_name( $parent_group );
57-
register_graphql_interfaces_to_types( $cloned_group_interfaces, [ $parent_group_type_name ] );
58-
return 'connection';
44+
if ( ! empty( $cloned_group_interfaces ) ) {
45+
46+
// If a clone field clones all fields from another field group,
47+
// but has "prefix_name" false, implement the Interface on the parent group
48+
if ( false === (bool) $sub_field_group['prefix_name'] ) {
49+
$parent_group = acf_get_field_group( $sub_field_group['parent'] );
50+
51+
if ( empty( $parent_group ) ) {
52+
$parent_field = acf_get_field( $sub_field_group['parent'] );
53+
$parent_group = ! empty( $parent_field ) ? acf_get_field_group( $parent_field['parent'] ) : false;
54+
}
55+
56+
if ( ! empty( $parent_group ) ) {
57+
$parent_group_type_name = $field_config->get_registry()->get_field_group_graphql_type_name( $parent_group );
58+
59+
if ( isset( $sub_field_group['isFlexLayoutField'] ) && true === (bool) $sub_field_group['isFlexLayoutField'] ) {
60+
$parent_type_name = $field_config->get_registry()->get_field_group_graphql_type_name( $sub_field_group['parent_layout_group'] ) ?? $type_name;
61+
register_graphql_interfaces_to_types( $cloned_group_interfaces, [ $parent_type_name ] );
62+
} else {
63+
register_graphql_interfaces_to_types( $cloned_group_interfaces, [ $parent_group_type_name ] );
64+
}
65+
return 'connection';
66+
}
67+
// If "prefix_name" is true, nest the cloned field group within another GraphQL object type to avoid
68+
// collisions with multiple instances of the field group being cloned
69+
} else {
70+
if ( ! empty( $type_name ) ) {
71+
// Register the cloned group interfaces to the type representing the cloned fields
72+
register_graphql_interfaces_to_types( $cloned_group_interfaces, [ $type_name ] );
73+
}
74+
}
5975
}
6076

77+
6178
$sub_field_group['graphql_type_name'] = $type_name;
6279
$sub_field_group['graphql_field_name'] = $type_name;
6380
$sub_field_group['parent'] = $sub_field_group['key'];
@@ -70,12 +87,6 @@ public static function register_field_type():void {
7087

7188
return $type_name;
7289
},
73-
'resolve' => static function ( $root, $args, AppContext $context, $info, $field_type, FieldConfig $field_config ) {
74-
$value = $field_config->resolve_field( $root, $args, $context, $info );
75-
$root['value'] = $value;
76-
$root['acf_field_group'] = $field_config->get_acf_field_group();
77-
return $root;
78-
},
7990
// The clone field adds its own settings field to display
8091
'admin_fields' => static function ( $default_admin_settings, $field, $config, \WPGraphQL\Acf\Admin\Settings $settings ) {
8192

src/FieldType/FlexibleContent.php

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ public static function register_field_type(): void {
2121
$layout_interface_prefix = Utils::format_type_name( $parent_type . ' ' . $field_name );
2222
$layout_interface_name = $layout_interface_prefix . '_Layout';
2323

24-
$flex_field_raw_sub_fields = acf_get_raw_fields( $acf_field['key'] );
25-
2624
if ( ! $field_config->get_registry()->has_registered_field_group( $layout_interface_name ) ) {
2725
register_graphql_interface_type(
2826
$layout_interface_name,
@@ -33,13 +31,16 @@ public static function register_field_type(): void {
3331
'fields' => [
3432
'fieldGroupName' => [
3533
'type' => 'String',
34+
'resolve' => static function ( $object ) use ( $layout_interface_prefix ) {
35+
$layout = $object['acf_fc_layout'] ?? null;
36+
return Utils::format_type_name( $layout_interface_prefix . ' ' . $layout ) . 'Layout';
37+
},
3638
'description' => __( 'The name of the ACF Flex Field Layout', 'wp-graphql-acf' ),
37-
'deprecationReason' => __( 'Use __typename instead', 'wp-graphql-acf' ),
3839
],
3940
],
4041
'resolveType' => static function ( $object ) use ( $layout_interface_prefix ) {
4142
$layout = $object['acf_fc_layout'] ?? null;
42-
return Utils::format_type_name( $layout_interface_prefix . ' ' . $layout );
43+
return Utils::format_type_name( $layout_interface_prefix . ' ' . $layout ) . 'Layout';
4344
},
4445
]
4546
);
@@ -48,43 +49,29 @@ public static function register_field_type(): void {
4849
}
4950

5051
$layouts = [];
51-
if ( ! empty( $acf_field['layouts'] ) ) {
52-
foreach ( $acf_field['layouts'] as $layout ) {
53-
54-
// Format the name of the group using the layout prefix + the layout name
55-
$layout_name = Utils::format_type_name( $layout_interface_prefix . ' ' . $field_config->get_registry()->get_field_group_graphql_type_name( $layout ) );
56-
57-
// set the graphql_field_name using the $layout_name
58-
$layout['graphql_field_name'] = $layout_name;
59-
60-
// Pass that the layout is a flexLayout (compared to a standard field group)
61-
$layout['isFlexLayout'] = true;
62-
63-
$layout['parent'] = $acf_field['key'];
64-
$layout['raw_fields'] = array_filter(
65-
$flex_field_raw_sub_fields,
52+
foreach ( $acf_field['layouts'] as $layout ) {
53+
$layout_type_name = Utils::format_type_name( $layout_interface_prefix . ' ' . $field_config->get_registry()->get_field_group_graphql_type_name( $layout ) ) . 'Layout';
54+
$layout['interfaces'] = [ $layout_interface_name ];
55+
$layout['eagerlyLoadType'] = true;
56+
$layout['isFlexLayout'] = true;
57+
$layout['parent_layout_group'] = $layout;
58+
$layout['graphql_type_name'] = $layout_type_name;
59+
60+
$sub_fields = array_filter(
61+
array_map(
6662
static function ( $field ) use ( $layout ) {
67-
return isset( $field['parent_layout'] ) && $field['parent_layout'] === $layout['key'] ? $layout : null;
68-
}
69-
);
63+
$field['graphql_types'] = [];
64+
$field['parent_layout_group'] = $layout;
65+
$field['isFlexLayoutField'] = true;
66+
return isset( $field['parent_layout'] ) && $layout['key'] === $field['parent_layout'] ? $field : null;
67+
},
68+
acf_get_raw_fields( $layout['key'] )
69+
)
70+
);
7071

71-
// Get interfaces, including cloned field groups, for the layout
72-
$interfaces = $field_config->get_registry()->get_field_group_interfaces( $layout );
72+
$layout['sub_fields'] = array_merge( $sub_fields, $layout['sub_fields'] );
7373

74-
// Add the layout interface name as an interface. This is the type that is returned as a list of for accessing all layouts of the flex field
75-
$interfaces[] = $layout_interface_name;
76-
$layout['eagerlyLoadType'] = true;
77-
$layout['graphql_field_name'] = $layout_name;
78-
$layout['fields'] = [
79-
'fieldGroupName' => [
80-
'type' => 'String',
81-
'description' => __( 'The name of the ACF Flex Field Layout', 'wp-graphql-acf' ),
82-
'deprecationReason' => __( 'Use __typename instead', 'wp-graphql-acf' ),
83-
],
84-
];
85-
$layout['interfaces'] = $interfaces;
86-
$layouts[ $layout_name ] = $layout;
87-
}
74+
$layouts[] = $layout;
8875
}
8976

9077
if ( ! empty( $layouts ) ) {

0 commit comments

Comments
 (0)