PluginProbe
WPGraphQL / 2.22.0
WPGraphQL v2.22.0
2.22.3 2.22.2 2.22.1 2.22.0 2.21.1 2.21.0 2.20.0 2.19.0 2.18.0 2.17.0 2.16.0 2.15.1 2.15.0 2.14.1 2.14.0 2.13.0 2.2.0 2.3.0 2.3.3 2.3.6 2.3.8 2.5.0 2.5.1 2.5.2 2.5.3 All 177 releases
wp-graphql / src / Type / WPInputObjectType.php

WPInputObjectType.php in WPGraphQL 2.22.0, at src/Type/WPInputObjectType.php

200 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPGraphQL\Type;
3
4 use GraphQL\Error\InvariantViolation;
5 use GraphQL\Type\Definition\InputObjectField;
6 use GraphQL\Type\Definition\InputObjectType;
7 use GraphQL\Utils\Utils;
8 use WPGraphQL\Registry\TypeRegistry;
9
10 /**
11 * Class WPInputObjectType
12 *
13 * Input types should extend this class to take advantage of the helper methods for formatting
14 * and adding consistent filters.
15 *
16 * @phpstan-import-type InputObjectConfig from \GraphQL\Type\Definition\InputObjectType
17 * @phpstan-import-type FieldConfig from \GraphQL\Type\Definition\InputObjectType
18 *
19 * @package WPGraphQL\Type
20 * @since 0.0.5
21 */
22 class WPInputObjectType extends InputObjectType {
23
24 /**
25 * WPInputObjectType constructor.
26 *
27 * @param InputObjectConfig $config The Config to set up an Input Type
28 * @param \WPGraphQL\Registry\TypeRegistry $type_registry The TypeRegistry instance
29 */
30 public function __construct( array $config, TypeRegistry $type_registry ) {
31 $name = $config['name'] ?? $this->inferName();
32 if ( ! is_string( $name ) ) {
33 $name = '';
34 }
35 /**
36 * Filters the GraphQL type name before the input type is registered.
37 *
38 * @param string $type_name The GraphQL type name.
39 * @param InputObjectConfig $config The input type configuration.
40 * @param \WPGraphQL\Type\WPInputObjectType $wp_input_object_type The input type instance.
41 *
42 * @hookGroup schema-registration
43 * @since 0.0.5
44 */
45 $config['name'] = apply_filters( 'graphql_type_name', $name, $config, $this );
46 $config['fields'] = $this->get_fields( $config, $type_registry );
47
48 parent::__construct( $config );
49 }
50
51 /**
52 * Get the fields for the input type
53 *
54 * @param array<string,mixed> $config
55 * @param \WPGraphQL\Registry\TypeRegistry $type_registry
56 * @return array<string,mixed>
57 *
58 * @since 2.3.0
59 */
60 protected function get_fields( array $config, TypeRegistry $type_registry ): array {
61
62 $fields = [];
63
64 if ( is_callable( $config['fields'] ) ) {
65 $fields = $config['fields']();
66 } elseif ( is_array( $config['fields'] ) ) {
67 $fields = $config['fields'];
68 }
69
70 if ( ! empty( $fields ) && is_array( $fields ) ) {
71 $type_name = $config['name'] ?? '';
72 if ( ! is_string( $type_name ) ) {
73 $type_name = '';
74 }
75 $fields = $this->prepare_fields( $fields, $type_name, $config, $type_registry );
76 $fields = $type_registry->prepare_fields( $fields, $type_name );
77 }
78
79 return $fields;
80 }
81
82 /**
83 * Prepare_fields
84 *
85 * This function sorts the fields and applies a filter to allow for easily
86 * extending/modifying the shape of the Schema for the type.
87 *
88 * @param array<string,array<string,mixed>> $fields
89 * @param string $type_name
90 * @param array<string,mixed> $config
91 * @param \WPGraphQL\Registry\TypeRegistry $type_registry
92 * @return array<string,array<string,mixed>>
93 *
94 * @phpstan-param array<string,FieldConfig> $fields
95 * @phpstan-return array<string,FieldConfig>
96 * @since 0.0.5
97 */
98 public function prepare_fields( array $fields, string $type_name, array $config, TypeRegistry $type_registry ) {
99
100 /**
101 * Filter all object fields, passing the $typename as a param
102 *
103 * This is useful when several different types need to be easily filtered at once. . .for example,
104 * if ALL types with a field of a certain name needed to be adjusted, or something to that tune
105 *
106 * @param array<string,FieldConfig> $fields The array of fields for the object config
107 * @param string $type_name The name of the object type
108 * @param array<string,mixed> $config The type config
109 * @param \WPGraphQL\Registry\TypeRegistry $type_registry The TypeRegistry instance
110 *
111 * @hookGroup schema-registration
112 * @since 0.0.5
113 */
114 $fields = apply_filters( 'graphql_input_fields', $fields, $type_name, $config, $type_registry );
115
116 /**
117 * Filter once with lowercase, once with uppercase for Back Compat.
118 */
119 $lc_type_name = lcfirst( $type_name );
120 $uc_type_name = ucfirst( $type_name );
121
122 /**
123 * Filter the fields with the typename explicitly in the filter name
124 *
125 * This is useful for more targeted filtering, and is applied after the general filter, to allow for
126 * more specific overrides
127 *
128 * @param array<string,FieldConfig> $fields The array of fields for the object config
129 * @param \WPGraphQL\Registry\TypeRegistry $type_registry The TypeRegistry instance
130 *
131 * @hookGroup schema-registration
132 * @since 0.0.5
133 */
134 $fields = apply_filters( "graphql_{$lc_type_name}_fields", $fields, $type_registry );
135
136 /**
137 * Filter the fields with the typename explicitly in the filter name
138 *
139 * This is useful for more targeted filtering, and is applied after the general filter, to allow for
140 * more specific overrides
141 *
142 * @param array<string,FieldConfig> $fields The array of fields for the object config
143 * @param \WPGraphQL\Registry\TypeRegistry $type_registry The TypeRegistry instance
144 *
145 * @hookGroup schema-registration
146 * @since 0.0.5
147 */
148 $fields = apply_filters( "graphql_{$uc_type_name}_fields", $fields, $type_registry );
149
150 /**
151 * Sort the fields alphabetically by key. This makes reading through docs much easier
152 *
153 * @since 0.0.2
154 */
155 ksort( $fields );
156
157 return $fields;
158 }
159
160 /**
161 * Validates type config and throws if one of type options is invalid.
162 *
163 * This method is overridden from the parent GraphQL\Type\Definition\InputObjectType class
164 * to support WPGraphQL's filter system. The parent implementation only accepts iterables
165 * for fields, but WPGraphQL's filters (like graphql_input_fields and graphql_{type}_fields)
166 * might return a single InputObjectField instance. This override allows for both iterables
167 * and single InputObjectField instances to be valid field values.
168 *
169 * @throws \GraphQL\Error\InvariantViolation
170 */
171 public function assertValid(): void {
172 Utils::assertValidName( $this->name );
173
174 $fields = $this->config['fields'] ?? null;
175 if ( is_callable( $fields ) ) {
176 $fields = $fields();
177 }
178
179 // Validate that $fields is either an iterable or an InputObjectField
180 if ( ! is_iterable( $fields ) && ! $fields instanceof InputObjectField ) {
181 $invalidFields = Utils::printSafe( $fields );
182
183 throw new InvariantViolation(
184 sprintf(
185 // translators: %1$s is the name of the type and %2$s is the invalid fields
186 esc_html__( '%1$s fields must be an array, an iterable, or an InputObjectField instance, got: %2$s', 'wp-graphql' ),
187 esc_html( $this->name ),
188 esc_html( $invalidFields )
189 )
190 );
191 }
192
193 $resolvedFields = $this->getFields();
194
195 foreach ( $resolvedFields as $field ) {
196 $field->assertValid( $this );
197 }
198 }
199 }
200