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

wp-graphql / wp-graphql-woocommerce / 27448609176

12 Jun 2026 11:18PM UTC coverage: 91.8% (+0.009%) from 91.791%
27448609176

Pull #1019

github

web-flow
Merge 6a53d4c6b into 2ce9424e1
Pull Request #1019: fix: address WordPress.org plugin review (rename + prefixing + headers)

1327 of 1579 new or added lines in 200 files covered. (84.04%)

35 existing lines in 5 files now uncovered.

18528 of 20183 relevant lines covered (91.8%)

152.68 hits per line

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

95.6
/includes/mutation/class-order-create.php
1
<?php
2
/**
3
 * Mutation - createOrder
4
 *
5
 * Registers mutation for creating an order.
6
 *
7
 * @package WPGraphQL\WooCommerce\Mutation
8
 * @since 0.2.0
9
 */
10

11
namespace WPGraphQL\WooCommerce\Mutation;
12

13
use GraphQL\Error\UserError;
14
use GraphQL\Type\Definition\ResolveInfo;
15
use WC_Order_Factory;
16
use WPGraphQL\AppContext;
17
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
18
use WPGraphQL\WooCommerce\Model\Order;
19
use WPGraphQL\WooCommerce\WooCommerce;
20

21
/**
22
 * Class Order_Create
23
 */
24
class Order_Create {
25
        /**
26
         * Registers mutation
27
         *
28
         * @return void
29
         */
30
        public static function register_mutation() {
31
                register_graphql_mutation(
298✔
32
                        'createOrder',
298✔
33
                        [
298✔
34
                                'inputFields'         => self::get_input_fields(),
298✔
35
                                'outputFields'        => self::get_output_fields(),
298✔
36
                                'mutateAndGetPayload' => self::mutate_and_get_payload(),
298✔
37
                        ]
298✔
38
                );
298✔
39
        }
40

41
        /**
42
         * Defines the mutation input field configuration
43
         *
44
         * @return array
45
         */
46
        public static function get_input_fields() {
47
                return [
298✔
48
                        'parentId'           => [
298✔
49
                                'type'        => 'Int',
298✔
50
                                'description' => static function () {
298✔
51
                                        return __( 'Parent order ID.', 'graphql-for-ecommerce' );
2✔
52
                                },
298✔
53
                        ],
298✔
54
                        'currency'           => [
298✔
55
                                'type'        => 'CurrencyEnum',
298✔
56
                                'description' => static function () {
298✔
57
                                        return __( 'Currency the order was created with, in ISO format.', 'graphql-for-ecommerce' );
2✔
58
                                },
298✔
59
                        ],
298✔
60
                        'customerId'         => [
298✔
61
                                'type'        => 'Int',
298✔
62
                                'description' => static function () {
298✔
63
                                        return __( 'Order customer ID', 'graphql-for-ecommerce' );
2✔
64
                                },
298✔
65
                        ],
298✔
66
                        'customerNote'       => [
298✔
67
                                'type'        => 'String',
298✔
68
                                'description' => static function () {
298✔
69
                                        return __( 'Note left by customer during checkout.', 'graphql-for-ecommerce' );
2✔
70
                                },
298✔
71
                        ],
298✔
72
                        'coupons'            => [
298✔
73
                                'type'        => [ 'list_of' => 'String' ],
298✔
74
                                'description' => static function () {
298✔
75
                                        return __( 'Coupons codes to be applied to order', 'graphql-for-ecommerce' );
2✔
76
                                },
298✔
77
                        ],
298✔
78
                        'status'             => [
298✔
79
                                'type'        => 'OrderStatusEnum',
298✔
80
                                'description' => static function () {
298✔
81
                                        return __( 'Order status', 'graphql-for-ecommerce' );
2✔
82
                                },
298✔
83
                        ],
298✔
84
                        'paymentMethod'      => [
298✔
85
                                'type'        => 'String',
298✔
86
                                'description' => static function () {
298✔
87
                                        return __( 'Payment method ID.', 'graphql-for-ecommerce' );
2✔
88
                                },
298✔
89
                        ],
298✔
90
                        'paymentMethodTitle' => [
298✔
91
                                'type'        => 'String',
298✔
92
                                'description' => static function () {
298✔
93
                                        return __( 'Payment method title.', 'graphql-for-ecommerce' );
2✔
94
                                },
298✔
95
                        ],
298✔
96
                        'transactionId'      => [
298✔
97
                                'type'        => 'String',
298✔
98
                                'description' => static function () {
298✔
99
                                        return __( 'Order transaction ID', 'graphql-for-ecommerce' );
2✔
100
                                },
298✔
101
                        ],
298✔
102
                        'billing'            => [
298✔
103
                                'type'        => 'CustomerAddressInput',
298✔
104
                                'description' => static function () {
298✔
105
                                        return __( 'Order billing address', 'graphql-for-ecommerce' );
2✔
106
                                },
298✔
107
                        ],
298✔
108
                        'shipping'           => [
298✔
109
                                'type'        => 'CustomerAddressInput',
298✔
110
                                'description' => static function () {
298✔
111
                                        return __( 'Order shipping address', 'graphql-for-ecommerce' );
2✔
112
                                },
298✔
113
                        ],
298✔
114
                        'lineItems'          => [
298✔
115
                                'type'        => [ 'list_of' => 'LineItemInput' ],
298✔
116
                                'description' => static function () {
298✔
117
                                        return __( 'Order line items', 'graphql-for-ecommerce' );
2✔
118
                                },
298✔
119
                        ],
298✔
120
                        'shippingLines'      => [
298✔
121
                                'type'        => [ 'list_of' => 'ShippingLineInput' ],
298✔
122
                                'description' => static function () {
298✔
123
                                        return __( 'Order shipping lines', 'graphql-for-ecommerce' );
2✔
124
                                },
298✔
125
                        ],
298✔
126
                        'feeLines'           => [
298✔
127
                                'type'        => [ 'list_of' => 'FeeLineInput' ],
298✔
128
                                'description' => static function () {
298✔
129
                                        return __( 'Order shipping lines', 'graphql-for-ecommerce' );
2✔
130
                                },
298✔
131
                        ],
298✔
132
                        'metaData'           => [
298✔
133
                                'type'        => [ 'list_of' => 'MetaDataInput' ],
298✔
134
                                'description' => static function () {
298✔
135
                                        return __( 'Order meta data', 'graphql-for-ecommerce' );
2✔
136
                                },
298✔
137
                        ],
298✔
138
                        'isPaid'             => [
298✔
139
                                'type'        => 'Boolean',
298✔
140
                                'description' => static function () {
298✔
141
                                        return __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'graphql-for-ecommerce' );
2✔
142
                                },
298✔
143
                        ],
298✔
144
                        'createdVia'         => [
298✔
145
                                'type'        => 'String',
298✔
146
                                'description' => static function () {
298✔
147
                                        return __( 'Source of the order. Useful when WooCommerce is driven from multiple sources. Defaults to "graphql-api".', 'wp-graphql-woocommerce' );
2✔
148
                                },
298✔
149
                        ],
298✔
150
                ];
298✔
151
        }
152

153
        /**
154
         * Defines the mutation output field configuration
155
         *
156
         * @return array
157
         */
158
        public static function get_output_fields() {
159
                return [
298✔
160
                        'order'   => [
298✔
161
                                'type'    => 'Order',
298✔
162
                                'resolve' => static function ( $payload ) {
298✔
163
                                        return new Order( $payload['id'] );
7✔
164
                                },
298✔
165
                        ],
298✔
166
                        'orderId' => [
298✔
167
                                'type'    => 'Int',
298✔
168
                                'resolve' => static function ( $payload ) {
298✔
UNCOV
169
                                        return $payload['id'];
×
170
                                },
298✔
171
                        ],
298✔
172
                ];
298✔
173
        }
174

175
        /**
176
         * Defines the mutation data modification closure.
177
         *
178
         * @return callable
179
         */
180
        public static function mutate_and_get_payload() {
181
                return static function ( $input, AppContext $context, ResolveInfo $info ) {
298✔
182
                        // Check if authorized to create this order.
183
                        if ( ! Order_Mutation::authorized( $input, $context, $info, 'create', null ) ) {
7✔
184
                                throw new UserError( __( 'User does not have the capabilities necessary to create an order.', 'graphql-for-ecommerce' ) );
1✔
185
                        }
186

187
                        // Create order.
188
                        $order = null;
7✔
189
                        try {
190
                                $order_id = Order_Mutation::create_order( $input, $context, $info );
7✔
191
                                $order    = WC_Order_Factory::get_order( $order_id );
7✔
192

193
                                if ( ! is_object( $order ) ) {
7✔
UNCOV
194
                                        throw new UserError( __( 'Order could not be created.', 'graphql-for-ecommerce' ) );
×
195
                                }
196

197
                                // Make sure gateways are loaded so hooks from gateways fire on save/create.
198
                                WC()->payment_gateways();
7✔
199

200
                                // Validate customer ID, if set.
201
                                if ( ! empty( $input['customerId'] ) && ! Order_Mutation::validate_customer( $input['customerId'] ) ) {
7✔
UNCOV
202
                                        throw new UserError( __( 'Customer ID is invalid.', 'graphql-for-ecommerce' ) );
×
203
                                }
204

205
                                // Set all props, address, items, and meta on the order and save once.
206
                                Order_Mutation::prepare_order( $order, $input, $context, $info );
7✔
207

208
                                // Apply coupons.
209
                                if ( ! empty( $input['coupons'] ) ) {
7✔
210
                                        Order_Mutation::apply_coupons( $order, $input['coupons'] );
4✔
211
                                }
212

213
                                $created_via = ! empty( $input['createdVia'] ) ? $input['createdVia'] : WooCommerce::get_order_attribution_source_type();
7✔
214
                                $order->set_created_via( $created_via );
7✔
215
                                $order->add_meta_data( '_wc_order_attribution_source_type', $created_via, true );
7✔
216
                                $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
7✔
217
                                $order->calculate_totals( true );
7✔
218

219
                                // Set status.
220
                                if ( ! empty( $input['status'] ) ) {
7✔
221
                                        $order->set_status( $input['status'] );
1✔
222
                                }
223

224
                                // Actions for after the order is saved.
225
                                if ( ! empty( $input['isPaid'] ) ) {
7✔
226
                                        $transaction_id = ! empty( $input['transactionId'] ) ? $input['transactionId'] : '';
2✔
227
                                        $order->payment_complete(
2✔
228
                                                apply_filters( 'graphql_woocommerce_order_pre_validate_transaction_id', $transaction_id, $order, $input )
2✔
229
                                        );
2✔
230
                                }
231

232
                                /**
233
                                 * Action called after order is created.
234
                                 *
235
                                 * @param \WC_Order    $order   WC_Order instance.
236
                                 * @param array       $input   Input data describing order.
237
                                 * @param \WPGraphQL\AppContext  $context Request AppContext instance.
238
                                 * @param \GraphQL\Type\Definition\ResolveInfo $info    Request ResolveInfo instance.
239
                                 */
240
                                do_action( 'graphql_woocommerce_after_order_create', $order, $input, $context, $info );
7✔
241

242
                                return [ 'id' => $order->get_id() ];
7✔
UNCOV
243
                        } catch ( \Throwable $e ) {
×
244
                                // Delete order if it was created.
UNCOV
245
                                if ( is_object( $order ) ) {
×
UNCOV
246
                                        Order_Mutation::purge( $order );
×
247
                                }
248

249
                                // Throw error.
UNCOV
250
                                throw new UserError( $e->getMessage() );
×
251
                        }//end try
252
                };
298✔
253
        }
254
}
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