• 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

95.5
/includes/connection/class-orders.php
1
<?php
2
/**
3
 * Connection - Orders
4
 *
5
 * Registers connections to Order
6
 *
7
 * @package WPGraphQL\WooCommerce\Connection
8
 */
9

10
namespace WPGraphQL\WooCommerce\Connection;
11

12
use GraphQL\Type\Definition\ResolveInfo;
13
use WPGraphQL\AppContext;
14
use WPGraphQL\WooCommerce\Data\Connection\Order_Connection_Resolver;
15
use WPGraphQL\WooCommerce\Model\Customer;
16

17
/**
18
 * Class - Orders
19
 */
20
class Orders {
21
        /**
22
         * Registers the various connections from other Types to Customer
23
         *
24
         * @return void
25
         */
26
        public static function register_connections() {
27
                // From RootQuery To Orders.
28
                register_graphql_connection(
296✔
29
                        self::get_connection_config()
296✔
30
                );
296✔
31

32
                // From Customer To Orders.
33
                register_graphql_connection(
296✔
34
                        self::get_connection_config(
296✔
35
                                [
296✔
36
                                        'fromType'      => 'Customer',
296✔
37
                                        'fromFieldName' => 'orders',
296✔
38
                                        'resolve'       => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
296✔
39
                                                $resolver = new Order_Connection_Resolver( $source, $args, $context, $info );
5✔
40

41
                                                return self::get_customer_order_connection( $resolver, $source );
5✔
42
                                        },
296✔
43
                                ]
296✔
44
                        )
296✔
45
                );
296✔
46

47
                // From RootQuery To Refunds.
48
                register_graphql_connection(
296✔
49
                        self::get_connection_config(
296✔
50
                                [
296✔
51
                                        'toType'         => 'Refund',
296✔
52
                                        'fromFieldName'  => 'refunds',
296✔
53
                                        'connectionArgs' => self::get_refund_connection_args(),
296✔
54
                                ],
296✔
55
                                'shop_order_refund'
296✔
56
                        )
296✔
57
                );
296✔
58
                // From Order To Refunds.
59
                register_graphql_connection(
296✔
60
                        self::get_connection_config(
296✔
61
                                [
296✔
62
                                        'fromType'       => 'Order',
296✔
63
                                        'toType'         => 'Refund',
296✔
64
                                        'fromFieldName'  => 'refunds',
296✔
65
                                        'connectionArgs' => self::get_refund_connection_args(),
296✔
66
                                        'resolve'        => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
296✔
67
                                                $resolver = new Order_Connection_Resolver( $source, $args, $context, $info, 'shop_order_refund' );
2✔
68

69
                                                $resolver->set_should_execute( true );
2✔
70
                                                $resolver->set_query_arg( 'parent', $source->ID );
2✔
71

72
                                                return $resolver->get_connection();
2✔
73
                                        },
296✔
74
                                ],
296✔
75
                                'shop_order_refund'
296✔
76
                        )
296✔
77
                );
296✔
78
                // From Customer To Refunds.
79
                register_graphql_connection(
296✔
80
                        self::get_connection_config(
296✔
81
                                [
296✔
82
                                        'fromType'       => 'Customer',
296✔
83
                                        'toType'         => 'Refund',
296✔
84
                                        'fromFieldName'  => 'refunds',
296✔
85
                                        'connectionArgs' => self::get_refund_connection_args(),
296✔
86
                                        'resolve'        => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
296✔
87
                                                $resolver = new Order_Connection_Resolver( $source, $args, $context, $info, 'shop_order_refund' );
2✔
88

89
                                                return self::get_customer_refund_connection( $resolver, $source );
2✔
90
                                        },
296✔
91
                                ],
296✔
92
                                'shop_order_refund'
296✔
93
                        )
296✔
94
                );
296✔
95
        }
96

97
        /**
98
         * Given an array of $args, this returns the connection config, merging the provided args
99
         * with the defaults.
100
         *
101
         * @param array  $args       Connection configuration.
102
         * @param string $post_type  Connection resolving post-type.
103
         *
104
         * @return array
105
         */
106
        public static function get_connection_config( $args = [], $post_type = 'shop_order' ): array {
107
                // Get Post type object for use in connection resolve function.
108
                /**
109
                 * Get connection post type.
110
                 *
111
                 * @var \WP_Post_Type $post_object
112
                 */
113
                $post_object = get_post_type_object( $post_type );
296✔
114

115
                return array_merge(
296✔
116
                        [
296✔
117
                                'fromType'       => 'RootQuery',
296✔
118
                                'toType'         => 'Order',
296✔
119
                                'fromFieldName'  => 'orders',
296✔
120
                                'connectionArgs' => self::get_connection_args( 'private' ),
296✔
121
                                'resolve'        => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) use ( $post_object ) {
296✔
122
                                        // Check if user shop manager.
123
                                        $not_manager = ! current_user_can( $post_object->cap->edit_posts );
16✔
124

125
                                        // Remove any where arguments that require querying user to have "shop manager" role.
126
                                        if ( $not_manager && 'shop_order' === $post_object->name && isset( $args['where'] ) ) {
16✔
127
                                                $args['where'] = \array_intersect_key( $args['where'], self::get_connection_args( 'public' ) );
3✔
128
                                        }
129

130
                                        // Initialize connection resolver.
131
                                        $resolver = new Order_Connection_Resolver( $source, $args, $context, $info, $post_object->name );
16✔
132

133
                                        /**
134
                                         * If not shop manager, restrict results to orders/refunds owned by querying user
135
                                         * and return the connection.
136
                                         */
137
                                        if ( $not_manager ) {
16✔
138
                                                return 'shop_order_refund' === $post_object->name
5✔
139
                                                        ? self::get_customer_refund_connection( $resolver, new Customer( 'session', ! is_user_logged_in() ) )
1✔
140
                                                        : self::get_customer_order_connection( $resolver, new Customer( 'session', ! is_user_logged_in() ) );
5✔
141
                                        }
142

143
                                        return $resolver->get_connection();
13✔
144
                                },
296✔
145
                        ],
296✔
146
                        $args
296✔
147
                );
296✔
148
        }
149

150
        /**
151
         * Returns array of where args.
152
         *
153
         * @param string $access Connection argument access-level.
154
         * @return array
155
         */
156
        public static function get_connection_args( $access = 'public' ): array {
157
                switch ( $access ) {
158
                        case 'private':
296✔
159
                                return array_merge(
296✔
160
                                        get_wc_cpt_connection_args(),
296✔
161
                                        [
296✔
162
                                                'statuses'     => [
296✔
163
                                                        'type'        => [ 'list_of' => 'OrderStatusEnum' ],
296✔
164
                                                        'description' => static function () {
296✔
165
                                                                return __( 'Limit result set to orders assigned a specific status.', 'graphql-for-ecommerce' );
2✔
166
                                                        },
296✔
167
                                                ],
296✔
168
                                                'customerId'   => [
296✔
169
                                                        'type'        => 'Int',
296✔
170
                                                        'description' => static function () {
296✔
171
                                                                return __( 'Limit result set to orders assigned a specific customer.', 'graphql-for-ecommerce' );
2✔
172
                                                        },
296✔
173
                                                ],
296✔
174
                                                'customersIn'  => [
296✔
175
                                                        'type'        => [ 'list_of' => 'Int' ],
296✔
176
                                                        'description' => static function () {
296✔
177
                                                                return __( 'Limit result set to orders assigned a specific group of customers.', 'graphql-for-ecommerce' );
2✔
178
                                                        },
296✔
179
                                                ],
296✔
180
                                                'productId'    => [
296✔
181
                                                        'type'        => 'Int',
296✔
182
                                                        'description' => static function () {
296✔
183
                                                                return __( 'Limit result set to orders assigned a specific product.', 'graphql-for-ecommerce' );
2✔
184
                                                        },
296✔
185
                                                ],
296✔
186
                                                'orderby'      => [
296✔
187
                                                        'type'        => [ 'list_of' => 'OrdersOrderbyInput' ],
296✔
188
                                                        'description' => static function () {
296✔
189
                                                                return __( 'What paramater to use to order the objects by.', 'graphql-for-ecommerce' );
2✔
190
                                                        },
296✔
191
                                                ],
296✔
192
                                                'billingEmail' => [
296✔
193
                                                        'type'        => 'String',
296✔
194
                                                        'description' => static function () {
296✔
195
                                                                return __( 'Limit result set to orders assigned a specific billing email.', 'graphql-for-ecommerce' );
2✔
196
                                                        },
296✔
197
                                                ],
296✔
198
                                        ]
296✔
199
                                );
296✔
200

201
                        case 'public':
3✔
202
                        default:
203
                                return array_merge(
3✔
204
                                        get_wc_cpt_connection_args(),
3✔
205
                                        [
3✔
206
                                                'statuses'  => [
3✔
207
                                                        'type'        => [ 'list_of' => 'OrderStatusEnum' ],
3✔
208
                                                        'description' => static function () {
3✔
NEW
209
                                                                return __( 'Limit result set to orders assigned a specific status.', 'graphql-for-ecommerce' );
×
210
                                                        },
3✔
211
                                                ],
3✔
212
                                                'productId' => [
3✔
213
                                                        'type'        => 'Int',
3✔
214
                                                        'description' => static function () {
3✔
NEW
215
                                                                return __( 'Limit result set to orders assigned a specific product.', 'graphql-for-ecommerce' );
×
216
                                                        },
3✔
217
                                                ],
3✔
218
                                                'orderby'   => [
3✔
219
                                                        'type'        => [ 'list_of' => 'OrdersOrderbyInput' ],
3✔
220
                                                        'description' => static function () {
3✔
NEW
221
                                                                return __( 'What paramater to use to order the objects by.', 'graphql-for-ecommerce' );
×
222
                                                        },
3✔
223
                                                ],
3✔
224
                                                'search'    => [
3✔
225
                                                        'type'        => 'String',
3✔
226
                                                        'description' => static function () {
3✔
NEW
227
                                                                return __( 'Limit results to those matching a string.', 'graphql-for-ecommerce' );
×
228
                                                        },
3✔
229
                                                ],
3✔
230
                                                'dateQuery' => [
3✔
231
                                                        'type'        => 'DateQueryInput',
3✔
232
                                                        'description' => static function () {
3✔
NEW
233
                                                                return __( 'Filter the connection based on dates.', 'graphql-for-ecommerce' );
×
234
                                                        },
3✔
235
                                                ],
3✔
236
                                        ]
3✔
237
                                );
3✔
238
                }//end switch
239
        }
240

241
        /**
242
         * Returns array of where args.
243
         *
244
         * @return array
245
         */
246
        public static function get_refund_connection_args(): array {
247
                return array_merge(
296✔
248
                        get_wc_cpt_connection_args(),
296✔
249
                        [
296✔
250
                                'statuses' => [
296✔
251
                                        'type'        => [ 'list_of' => 'String' ],
296✔
252
                                        'description' => static function () {
296✔
253
                                                return __( 'Limit result set to refunds assigned a specific status.', 'graphql-for-ecommerce' );
2✔
254
                                        },
296✔
255
                                ],
296✔
256
                                'orderIn'  => [
296✔
257
                                        'type'        => [ 'list_of' => 'Int' ],
296✔
258
                                        'description' => static function () {
296✔
259
                                                return __( 'Limit result set to refunds from a specific group of order IDs.', 'graphql-for-ecommerce' );
2✔
260
                                        },
296✔
261
                                ],
296✔
262
                        ]
296✔
263
                );
296✔
264
        }
265

266
        /**
267
         * Returns order connection filter by customer.
268
         *
269
         * @param \WPGraphQL\WooCommerce\Data\Connection\Order_Connection_Resolver $resolver  Connection resolver.
270
         * @param \WPGraphQL\WooCommerce\Model\Customer                            $customer  Customer object of querying user.
271
         *
272
         * @return array|\GraphQL\Deferred
273
         */
274
        private static function get_customer_order_connection( $resolver, Customer $customer ) {
275
                // If not "billing email" or "ID" set bail early by returning an empty connection.
276
                if ( empty( $customer->billing['email'] ) && ( empty( absint( $customer->ID ) ) ) ) {
9✔
277
                        return [
×
278
                                'nodes' => [],
×
279
                                'edges' => [],
×
280
                        ];
×
281
                }
282

283
                $target_customer_id  = absint( $customer->ID );
9✔
284
                $current_customer_id = absint( \WC()->customer->get_id() );
9✔
285
                if ( ! empty( $target_customer_id ) ) {
9✔
286
                        $resolver->set_query_arg( 'customer_id', $target_customer_id );
9✔
287
                        $resolver->set_should_execute( $current_customer_id === $target_customer_id );
9✔
288
                } elseif ( ! empty( $customer->billing['email'] ) ) {
1✔
289
                        $resolver->set_query_arg( 'billing_email', $customer->billing['email'] );
1✔
290
                        $resolver->set_should_execute( \WC()->customer->get_billing_email() === $customer->billing['email'] );
1✔
291
                }
292

293
                return $resolver->get_connection();
9✔
294
        }
295

296
        /**
297
         * Returns refund connection filter by customer.
298
         *
299
         * @param \WPGraphQL\WooCommerce\Data\Connection\Order_Connection_Resolver $resolver  Connection resolver.
300
         * @param \WPGraphQL\WooCommerce\Model\Customer                            $customer  Customer object of querying user.
301
         *
302
         * @return array|\GraphQL\Deferred
303
         */
304
        private static function get_customer_refund_connection( Order_Connection_Resolver $resolver, Customer $customer ) {
305
                $empty_results = [
3✔
306
                        'pageInfo' => null,
3✔
307
                        'nodes'    => [],
3✔
308
                        'edges'    => [],
3✔
309
                ];
3✔
310
                // If not "billing email" or "ID" set bail early by returning an empty connection.
311
                if ( empty( $customer->billing['email'] ) && empty( $customer->ID ) ) {
3✔
312
                        return $empty_results;
×
313
                }
314

315
                $order_ids     = [];
3✔
316
                $customer_id   = $customer->ID;
3✔
317
                $billing_email = $customer->billing['email'];
3✔
318
                if ( ! empty( $customer_id ) ) {
3✔
319
                        $args = [
3✔
320
                                'customer_id' => $customer_id,
3✔
321
                                'return'      => 'ids',
3✔
322
                        ];
3✔
323
                        /** @var array<int> $order_ids_by_customer_id */
324
                        $order_ids_by_customer_id = wc_get_orders( $args );
3✔
325

326
                        if ( is_array( $order_ids_by_customer_id ) ) {
3✔
327
                                $order_ids = $order_ids_by_customer_id;
3✔
328
                        }
329
                }
330

331
                if ( ! empty( $billing_email ) ) {
3✔
332
                        $args = [
3✔
333
                                'billing_email' => $billing_email,
3✔
334
                                'return'        => 'ids',
3✔
335
                        ];
3✔
336
                        /** @var array<int> $order_ids_by_email */
337
                        $order_ids_by_email = wc_get_orders( $args );
3✔
338
                        // Merge the arrays of order IDs.
339
                        if ( is_array( $order_ids_by_email ) ) {
3✔
340
                                $order_ids = array_merge( $order_ids, $order_ids_by_email );
3✔
341
                        }
342
                }
343

344
                // If no orders found, return empty connection.
345
                if ( empty( $order_ids ) ) {
3✔
346
                        return $empty_results;
1✔
347
                }
348

349
                // Remove duplicates.
350
                $order_ids = array_unique( $order_ids );
2✔
351

352
                // Set connection args.
353
                $resolver->set_should_execute(
2✔
354
                        ( 0 !== $customer_id && \WC()->customer->get_id() === $customer_id )
2✔
355
                                || \WC()->customer->get_billing_email() === $billing_email
2✔
356
                );
2✔
357

358
                $resolver->set_query_arg( 'post_parent__in', array_map( 'absint', $order_ids ) );
2✔
359

360
                // Execute and return connection.
361
                return $resolver->get_connection();
2✔
362
        }
363
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc