• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wp-graphql / wp-graphql / 14716683875

28 Apr 2025 07:58PM UTC coverage: 84.287% (+1.6%) from 82.648%
14716683875

push

github

actions-user
release: merge develop into master for v2.3.0

15905 of 18870 relevant lines covered (84.29%)

257.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.56
/src/Type/WPInputObjectType.php
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 ) {
425✔
31
                $name = $config['name'] ?? $this->inferName();
425✔
32
                if ( ! is_string( $name ) ) {
425✔
33
                        $name = '';
×
34
                }
35
                $config['name']   = apply_filters( 'graphql_type_name', $name, $config, $this );
425✔
36
                $config['fields'] = $this->get_fields( $config, $type_registry );
425✔
37

38
                parent::__construct( $config );
425✔
39
        }
40

41
        /**
42
         * Get the fields for the input type
43
         *
44
         * @param array<string,mixed>              $config
45
         * @param \WPGraphQL\Registry\TypeRegistry $type_registry
46
         * @return array<string,mixed>
47
         *
48
         * @since next-version
49
         */
50
        protected function get_fields( array $config, TypeRegistry $type_registry ): array {
425✔
51

52
                $fields = [];
425✔
53

54
                if ( is_callable( $config['fields'] ) ) {
425✔
55
                        $fields = $config['fields']();
168✔
56
                } elseif ( is_array( $config['fields'] ) ) {
424✔
57
                        $fields = $config['fields'];
424✔
58
                }
59

60
                if ( ! empty( $fields ) && is_array( $fields ) ) {
425✔
61
                        $type_name = $config['name'] ?? '';
425✔
62
                        if ( ! is_string( $type_name ) ) {
425✔
63
                                $type_name = '';
×
64
                        }
65
                        $fields = $this->prepare_fields( $fields, $type_name, $config, $type_registry );
425✔
66
                        $fields = $type_registry->prepare_fields( $fields, $type_name );
425✔
67
                }
68

69
                return $fields;
425✔
70
        }
71

72
        /**
73
         * Prepare_fields
74
         *
75
         * This function sorts the fields and applies a filter to allow for easily
76
         * extending/modifying the shape of the Schema for the type.
77
         *
78
         * @param array<string,array<string,mixed>> $fields
79
         * @param string                            $type_name
80
         * @param array<string,mixed>               $config
81
         * @param \WPGraphQL\Registry\TypeRegistry  $type_registry
82
         * @return array<string,array<string,mixed>>
83
         *
84
         * @phpstan-param array<string,FieldConfig> $fields
85
         * @phpstan-return array<string,FieldConfig>
86
         * @since 0.0.5
87
         */
88
        public function prepare_fields( array $fields, string $type_name, array $config, TypeRegistry $type_registry ) {
425✔
89

90
                /**
91
                 * Filter all object fields, passing the $typename as a param
92
                 *
93
                 * This is useful when several different types need to be easily filtered at once. . .for example,
94
                 * if ALL types with a field of a certain name needed to be adjusted, or something to that tune
95
                 *
96
                 * @param array<string,FieldConfig>         $fields        The array of fields for the object config
97
                 * @param string                            $type_name     The name of the object type
98
                 * @param array<string,mixed>               $config        The type config
99
                 * @param \WPGraphQL\Registry\TypeRegistry  $type_registry The TypeRegistry instance
100
                 */
101
                $fields = apply_filters( 'graphql_input_fields', $fields, $type_name, $config, $type_registry );
425✔
102

103
                /**
104
                 * Filter once with lowercase, once with uppercase for Back Compat.
105
                 */
106
                $lc_type_name = lcfirst( $type_name );
425✔
107
                $uc_type_name = ucfirst( $type_name );
425✔
108

109
                /**
110
                 * Filter the fields with the typename explicitly in the filter name
111
                 *
112
                 * This is useful for more targeted filtering, and is applied after the general filter, to allow for
113
                 * more specific overrides
114
                 *
115
                 * @param array<string,FieldConfig> $fields        The array of fields for the object config
116
                 * @param \WPGraphQL\Registry\TypeRegistry  $type_registry The TypeRegistry instance
117
                 */
118
                $fields = apply_filters( "graphql_{$lc_type_name}_fields", $fields, $type_registry );
425✔
119

120
                /**
121
                 * Filter the fields with the typename explicitly in the filter name
122
                 *
123
                 * This is useful for more targeted filtering, and is applied after the general filter, to allow for
124
                 * more specific overrides
125
                 *
126
                 * @param array<string,FieldConfig>            $fields        The array of fields for the object config
127
                 * @param \WPGraphQL\Registry\TypeRegistry $type_registry The TypeRegistry instance
128
                 */
129
                $fields = apply_filters( "graphql_{$uc_type_name}_fields", $fields, $type_registry );
425✔
130

131
                /**
132
                 * Sort the fields alphabetically by key. This makes reading through docs much easier
133
                 *
134
                 * @since 0.0.2
135
                 */
136
                ksort( $fields );
425✔
137

138
                return $fields;
425✔
139
        }
140

141
        /**
142
         * Validates type config and throws if one of type options is invalid.
143
         *
144
         * This method is overridden from the parent GraphQL\Type\Definition\InputObjectType class
145
         * to support WPGraphQL's filter system. The parent implementation only accepts iterables
146
         * for fields, but WPGraphQL's filters (like graphql_input_fields and graphql_{type}_fields)
147
         * might return a single InputObjectField instance. This override allows for both iterables
148
         * and single InputObjectField instances to be valid field values.
149
         *
150
         * @throws \GraphQL\Error\InvariantViolation
151
         */
152
        public function assertValid(): void {
9✔
153
                Utils::assertValidName( $this->name );
9✔
154

155
                $fields = $this->config['fields'] ?? null;
9✔
156
                if ( is_callable( $fields ) ) {
9✔
157
                        $fields = $fields();
×
158
                }
159

160
                // Validate that $fields is either an iterable or an InputObjectField
161
                if ( ! is_iterable( $fields ) && ! $fields instanceof InputObjectField ) {
9✔
162
                        $invalidFields = Utils::printSafe( $fields );
×
163

164
                        throw new InvariantViolation(
×
165
                                sprintf(
×
166
                                        // translators: %1$s is the name of the type and %2$s is the invalid fields
167
                                        esc_html__( '%1$s fields must be an array, an iterable, or an InputObjectField instance, got: %2$s', 'wp-graphql' ),
×
168
                                        esc_html( $this->name ),
×
169
                                        esc_html( $invalidFields )
×
170
                                )
×
171
                        );
×
172
                }
173

174
                $resolvedFields = $this->getFields();
9✔
175

176
                foreach ( $resolvedFields as $field ) {
9✔
177
                        $field->assertValid( $this );
9✔
178
                }
179
        }
180
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc