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

wp-graphql / wp-graphql-woocommerce / 27386231983

12 Jun 2026 12:25AM UTC coverage: 91.791%. Remained the same
27386231983

Pull #1019

github

web-flow
Merge 46a421a18 into 01876f534
Pull Request #1019: fix: address WordPress.org plugin review (rename + prefixing + headers)

1327 of 1584 new or added lines in 200 files covered. (83.78%)

1 existing line in 1 file now uncovered.

18505 of 20160 relevant lines covered (91.79%)

151.6 hits per line

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

98.08
/includes/type/interface/class-product.php
1
<?php
2
/**
3
 * WPInterface Type - Product
4
 *
5
 * Registers Product interface.
6
 *
7
 * @package WPGraphQL\WooCommerce\Type\WPInterface
8
 * @since   0.3.0
9
 */
10

11
namespace WPGraphQL\WooCommerce\Type\WPInterface;
12

13
use GraphQL\Error\UserError;
14
use GraphQLRelay\Relay;
15
use WPGraphQL\AppContext;
16
use WPGraphQL\WooCommerce\Data\Factory;
17

18
/**
19
 * Class - Product
20
 */
21
class Product {
22
        /**
23
         * Registers the "Product" interface.
24
         *
25
         * @return void
26
         */
27
        public static function register_interface() {
28
                // Register the fields to the Product Interface
29
                // the product interface is defined by the post_type registration.
30
                register_graphql_field(
296✔
31
                        'RootQuery',
296✔
32
                        'product',
296✔
33
                        [
296✔
34
                                'type'        => 'Product',
296✔
35
                                'description' => static function () {
296✔
36
                                        return __( 'A product object', 'graphql-for-ecommerce' );
3✔
37
                                },
296✔
38
                                'args'        => [
296✔
39
                                        'id'     => [
296✔
40
                                                'type'        => [ 'non_null' => 'ID' ],
296✔
41
                                                'description' => static function () {
296✔
42
                                                        return __( 'The ID for identifying the product', 'graphql-for-ecommerce' );
3✔
43
                                                },
296✔
44
                                        ],
296✔
45
                                        'idType' => [
296✔
46
                                                'type'        => 'ProductIdTypeEnum',
296✔
47
                                                'description' => static function () {
296✔
48
                                                        return __( 'Type of ID being used identify product', 'graphql-for-ecommerce' );
3✔
49
                                                },
296✔
50
                                        ],
296✔
51
                                ],
296✔
52
                                'resolve'     => static function ( $source, array $args, AppContext $context ) {
296✔
53
                                        $id      = isset( $args['id'] ) ? $args['id'] : null;
35✔
54
                                        $id_type = isset( $args['idType'] ) ? $args['idType'] : 'global_id';
35✔
55

56
                                        $product_id = null;
35✔
57
                                        switch ( $id_type ) {
58
                                                case 'sku':
35✔
59
                                                        $product_id = \wc_get_product_id_by_sku( $id );
1✔
60
                                                        break;
1✔
61
                                                case 'slug':
35✔
62
                                                        $query = new \WP_Query(
2✔
63
                                                                [
2✔
64
                                                                        'name'           => $id,
2✔
65
                                                                        'post_type'      => 'product',
2✔
66
                                                                        'post_status'    => 'publish',
2✔
67
                                                                        'posts_per_page' => 1,
2✔
68
                                                                        'fields'         => 'ids',
2✔
69
                                                                ]
2✔
70
                                                        );
2✔
71
                                                        /** @var int $post_id */
72
                                                        $post_id    = ! empty( $query->posts ) ? $query->posts[0] : 0;
2✔
73
                                                        $product_id = absint( $post_id );
2✔
74
                                                        break;
2✔
75
                                                case 'database_id':
34✔
76
                                                        $product_id = absint( $id );
14✔
77
                                                        break;
14✔
78
                                                case 'global_id':
21✔
79
                                                default:
80
                                                        $id_components = Relay::fromGlobalId( $id );
21✔
81
                                                        if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
21✔
NEW
82
                                                                throw new UserError( __( 'The "global ID" is invalid', 'graphql-for-ecommerce' ) );
×
83
                                                        }
84
                                                        $product_id = absint( $id_components['id'] );
21✔
85
                                                        break;
21✔
86
                                        }
87

88
                                        if ( empty( $product_id ) ) {
35✔
89
                                                /* translators: %1$s: ID type, %2$s: ID value */
NEW
90
                                                throw new UserError( sprintf( __( 'No product ID was found corresponding to the %1$s: %2$s', 'graphql-for-ecommerce' ), $id_type, $id ) );
×
91
                                        }
92
                                        $product = get_post( $product_id );
35✔
93
                                        if ( ! is_object( $product ) || 'product' !== $product->post_type ) {
35✔
94
                                                /* translators: %1$s: ID type, %2$s: ID value */
NEW
95
                                                throw new UserError( sprintf( __( 'No product exists with the %1$s: %2$s', 'graphql-for-ecommerce' ), $id_type, $id ) );
×
96
                                        }
97

98
                                        return Factory::resolve_crud_object( $product_id, $context );
35✔
99
                                },
296✔
100
                        ]
296✔
101
                );
296✔
102
        }
103

104
        /**
105
         * Defines Product fields. All child type must have these fields as well.
106
         *
107
         * @return array
108
         */
109
        public static function get_fields() {
110
                return [
296✔
111
                        'type'              => [
296✔
112
                                'type'        => 'ProductTypesEnum',
296✔
113
                                'description' => static function () {
296✔
114
                                        return __( 'Product type', 'graphql-for-ecommerce' );
3✔
115
                                },
296✔
116
                        ],
296✔
117
                        'name'              => [
296✔
118
                                'type'        => 'String',
296✔
119
                                'description' => static function () {
296✔
120
                                        return __( 'Product name', 'graphql-for-ecommerce' );
3✔
121
                                },
296✔
122
                        ],
296✔
123
                        'featured'          => [
296✔
124
                                'type'        => 'Boolean',
296✔
125
                                'description' => static function () {
296✔
126
                                        return __( 'If the product is featured', 'graphql-for-ecommerce' );
3✔
127
                                },
296✔
128
                        ],
296✔
129
                        'catalogVisibility' => [
296✔
130
                                'type'        => 'CatalogVisibilityEnum',
296✔
131
                                'description' => static function () {
296✔
132
                                        return __( 'Catalog visibility', 'graphql-for-ecommerce' );
3✔
133
                                },
296✔
134
                        ],
296✔
135
                        'description'       => [
296✔
136
                                'type'        => 'String',
296✔
137
                                'description' => static function () {
296✔
138
                                        return __( 'Product description', 'graphql-for-ecommerce' );
3✔
139
                                },
296✔
140
                                'args'        => [
296✔
141
                                        'format' => [
296✔
142
                                                'type'        => 'PostObjectFieldFormatEnum',
296✔
143
                                                'description' => static function () {
296✔
144
                                                        return __( 'Format of the field output', 'graphql-for-ecommerce' );
3✔
145
                                                },
296✔
146
                                        ],
296✔
147
                                ],
296✔
148
                                'resolve'     => static function ( $source, $args ) {
296✔
149
                                        if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
4✔
150
                                                // @codingStandardsIgnoreLine.
151
                                                return $source->descriptionRaw;
2✔
152
                                        }
153
                                        return $source->description;
4✔
154
                                },
296✔
155
                        ],
296✔
156
                        'shortDescription'  => [
296✔
157
                                'type'        => 'String',
296✔
158
                                'description' => static function () {
296✔
159
                                        return __( 'Product short description', 'graphql-for-ecommerce' );
3✔
160
                                },
296✔
161
                                'args'        => [
296✔
162
                                        'format' => [
296✔
163
                                                'type'        => 'PostObjectFieldFormatEnum',
296✔
164
                                                'description' => static function () {
296✔
165
                                                        return __( 'Format of the field output', 'graphql-for-ecommerce' );
3✔
166
                                                },
296✔
167
                                        ],
296✔
168
                                ],
296✔
169
                                'resolve'     => static function ( $source, $args ) {
296✔
170
                                        if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
2✔
171
                                                // @codingStandardsIgnoreLine.
172
                                                return $source->shortDescriptionRaw;
2✔
173
                                        }
174
                                        // @codingStandardsIgnoreLine.
175
                                        return $source->shortDescription;
2✔
176
                                },
296✔
177
                        ],
296✔
178
                        'sku'               => [
296✔
179
                                'type'        => 'String',
296✔
180
                                'description' => static function () {
296✔
181
                                        return __( 'Product SKU', 'graphql-for-ecommerce' );
3✔
182
                                },
296✔
183
                        ],
296✔
184
                        'dateOnSaleFrom'    => [
296✔
185
                                'type'        => 'String',
296✔
186
                                'description' => static function () {
296✔
187
                                        return __( 'Date on sale from', 'graphql-for-ecommerce' );
3✔
188
                                },
296✔
189
                        ],
296✔
190
                        'dateOnSaleTo'      => [
296✔
191
                                'type'        => 'String',
296✔
192
                                'description' => static function () {
296✔
193
                                        return __( 'Date on sale to', 'graphql-for-ecommerce' );
3✔
194
                                },
296✔
195
                        ],
296✔
196
                        'totalSales'        => [
296✔
197
                                'type'        => 'Int',
296✔
198
                                'description' => static function () {
296✔
199
                                        return __( 'Number total of sales', 'graphql-for-ecommerce' );
3✔
200
                                },
296✔
201
                        ],
296✔
202
                        'reviewsAllowed'    => [
296✔
203
                                'type'        => 'Boolean',
296✔
204
                                'description' => static function () {
296✔
205
                                        return __( 'If reviews are allowed', 'graphql-for-ecommerce' );
3✔
206
                                },
296✔
207
                        ],
296✔
208
                        'purchaseNote'      => [
296✔
209
                                'type'        => 'String',
296✔
210
                                'description' => static function () {
296✔
211
                                        return __( 'Purchase note', 'graphql-for-ecommerce' );
3✔
212
                                },
296✔
213
                        ],
296✔
214
                        'menuOrder'         => [
296✔
215
                                'type'        => 'Int',
296✔
216
                                'description' => static function () {
296✔
217
                                        return __( 'Menu order', 'graphql-for-ecommerce' );
3✔
218
                                },
296✔
219
                        ],
296✔
220
                        'averageRating'     => [
296✔
221
                                'type'        => 'Float',
296✔
222
                                'description' => static function () {
296✔
223
                                        return __( 'Product average count', 'graphql-for-ecommerce' );
3✔
224
                                },
296✔
225
                        ],
296✔
226
                        'reviewCount'       => [
296✔
227
                                'type'        => 'Int',
296✔
228
                                'description' => static function () {
296✔
229
                                        return __( 'Product review count', 'graphql-for-ecommerce' );
3✔
230
                                },
296✔
231
                        ],
296✔
232
                        'image'             => [
296✔
233
                                'type'        => 'MediaItem',
296✔
234
                                'description' => static function () {
296✔
235
                                        return __( 'Main image', 'graphql-for-ecommerce' );
3✔
236
                                },
296✔
237
                                'resolve'     => static function ( $source, array $args, AppContext $context ) {
296✔
238
                                        // @codingStandardsIgnoreLine.
239
                                        if ( empty( $source->image_id ) || ! absint( $source->image_id ) ) {
4✔
240
                                                return null;
×
241
                                        }
242
                                        return $context->get_loader( 'post' )->load_deferred( $source->image_id );
4✔
243
                                },
296✔
244
                        ],
296✔
245
                        'onSale'            => [
296✔
246
                                'type'        => 'Boolean',
296✔
247
                                'description' => static function () {
296✔
248
                                        return __( 'Is product on sale?', 'graphql-for-ecommerce' );
3✔
249
                                },
296✔
250
                        ],
296✔
251
                        'purchasable'       => [
296✔
252
                                'type'        => 'Boolean',
296✔
253
                                'description' => static function () {
296✔
254
                                        return __( 'Can product be purchased?', 'graphql-for-ecommerce' );
3✔
255
                                },
296✔
256
                        ],
296✔
257
                        'virtual'           => [
296✔
258
                                'type'        => 'Boolean',
296✔
259
                                'description' => static function () {
296✔
260
                                        return __( 'Is product virtual?', 'graphql-for-ecommerce' );
3✔
261
                                },
296✔
262
                        ],
296✔
263
                        'metaData'          => \WPGraphQL\WooCommerce\Type\WPObject\Meta_Data_Type::get_metadata_field_definition(),
296✔
264
                ];
296✔
265
        }
266
}
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

© 2026 Coveralls, Inc