• 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.36
/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

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

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

146
        /**
147
         * Defines the mutation output field configuration
148
         *
149
         * @return array
150
         */
151
        public static function get_output_fields() {
152
                return [
296✔
153
                        'order'   => [
296✔
154
                                'type'    => 'Order',
296✔
155
                                'resolve' => static function ( $payload ) {
296✔
156
                                        return new Order( $payload['id'] );
6✔
157
                                },
296✔
158
                        ],
296✔
159
                        'orderId' => [
296✔
160
                                'type'    => 'Int',
296✔
161
                                'resolve' => static function ( $payload ) {
296✔
162
                                        return $payload['id'];
×
163
                                },
296✔
164
                        ],
296✔
165
                ];
296✔
166
        }
167

168
        /**
169
         * Defines the mutation data modification closure.
170
         *
171
         * @return callable
172
         */
173
        public static function mutate_and_get_payload() {
174
                return static function ( $input, AppContext $context, ResolveInfo $info ) {
296✔
175
                        // Check if authorized to create this order.
176
                        if ( ! Order_Mutation::authorized( $input, $context, $info, 'create', null ) ) {
6✔
177
                                throw new UserError( __( 'User does not have the capabilities necessary to create an order.', 'graphql-for-ecommerce' ) );
1✔
178
                        }
179

180
                        // Create order.
181
                        $order = null;
6✔
182
                        try {
183
                                $order_id = Order_Mutation::create_order( $input, $context, $info );
6✔
184
                                $order    = WC_Order_Factory::get_order( $order_id );
6✔
185

186
                                if ( ! is_object( $order ) ) {
6✔
NEW
187
                                        throw new UserError( __( 'Order could not be created.', 'graphql-for-ecommerce' ) );
×
188
                                }
189

190
                                // Make sure gateways are loaded so hooks from gateways fire on save/create.
191
                                WC()->payment_gateways();
6✔
192

193
                                // Validate customer ID, if set.
194
                                if ( ! empty( $input['customerId'] ) && ! Order_Mutation::validate_customer( $input['customerId'] ) ) {
6✔
NEW
195
                                        throw new UserError( __( 'Customer ID is invalid.', 'graphql-for-ecommerce' ) );
×
196
                                }
197

198
                                // Set all props, address, items, and meta on the order and save once.
199
                                Order_Mutation::prepare_order( $order, $input, $context, $info );
6✔
200

201
                                // Apply coupons.
202
                                if ( ! empty( $input['coupons'] ) ) {
6✔
203
                                        Order_Mutation::apply_coupons( $order, $input['coupons'] );
4✔
204
                                }
205

206
                                $order->set_created_via( 'graphql-api' );
6✔
207
                                $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
6✔
208
                                $order->calculate_totals( true );
6✔
209

210
                                // Set status.
211
                                if ( ! empty( $input['status'] ) ) {
6✔
212
                                        $order->set_status( $input['status'] );
1✔
213
                                }
214

215
                                // Actions for after the order is saved.
216
                                if ( ! empty( $input['isPaid'] ) ) {
6✔
217
                                        $transaction_id = ! empty( $input['transactionId'] ) ? $input['transactionId'] : '';
2✔
218
                                        $order->payment_complete(
2✔
219
                                                apply_filters( 'graphql_woocommerce_order_pre_validate_transaction_id', $transaction_id, $order, $input )
2✔
220
                                        );
2✔
221
                                }
222

223
                                /**
224
                                 * Action called after order is created.
225
                                 *
226
                                 * @param \WC_Order    $order   WC_Order instance.
227
                                 * @param array       $input   Input data describing order.
228
                                 * @param \WPGraphQL\AppContext  $context Request AppContext instance.
229
                                 * @param \GraphQL\Type\Definition\ResolveInfo $info    Request ResolveInfo instance.
230
                                 */
231
                                do_action( 'graphql_woocommerce_after_order_create', $order, $input, $context, $info );
6✔
232

233
                                return [ 'id' => $order->get_id() ];
6✔
234
                        } catch ( \Throwable $e ) {
×
235
                                // Delete order if it was created.
236
                                if ( is_object( $order ) ) {
×
237
                                        Order_Mutation::purge( $order );
×
238
                                }
239

240
                                // Throw error.
241
                                throw new UserError( $e->getMessage() );
×
242
                        }//end try
243
                };
296✔
244
        }
245
}
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