Test Failed
Push — master ( a5e4c3...7495fa )
by Mike
43:00
created

WC_REST_Orders_V2_Controller::update_address()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 3
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * REST API Orders controller
4
 *
5
 * Handles requests to the /orders endpoint.
6
 *
7
 * @package WooCommerce/RestApi
8
 * @since    2.6.0
9
 */
10
11
defined( 'ABSPATH' ) || exit;
12
13
/**
14
 * REST API Orders controller class.
15
 *
16
 * @package WooCommerce/RestApi
17
 * @extends WC_REST_CRUD_Controller
18
 */
19
class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller {
20
21
	/**
22
	 * Endpoint namespace.
23
	 *
24
	 * @var string
25
	 */
26
	protected $namespace = 'wc/v2';
27
28
	/**
29
	 * Route base.
30
	 *
31
	 * @var string
32
	 */
33
	protected $rest_base = 'orders';
34
35
	/**
36
	 * Post type.
37
	 *
38
	 * @var string
39
	 */
40
	protected $post_type = 'shop_order';
41
42
	/**
43
	 * If object is hierarchical.
44
	 *
45
	 * @var bool
46
	 */
47
	protected $hierarchical = true;
48
49
	/**
50
	 * Stores the request.
51
	 *
52
	 * @var array
53
	 */
54
	protected $request = array();
55
56
	/**
57
	 * Register the routes for orders.
58
	 */
59
	public function register_routes() {
60
		register_rest_route(
61
			$this->namespace,
62
			'/' . $this->rest_base,
63
			array(
64
				array(
65
					'methods'             => WP_REST_Server::READABLE,
0 ignored issues
show
Bug introduced by
The type WP_REST_Server was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
66
					'callback'            => array( $this, 'get_items' ),
67
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
68
					'args'                => $this->get_collection_params(),
69
				),
70
				array(
71
					'methods'             => WP_REST_Server::CREATABLE,
72
					'callback'            => array( $this, 'create_item' ),
73
					'permission_callback' => array( $this, 'create_item_permissions_check' ),
74
					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
75
				),
76
				'schema' => array( $this, 'get_public_item_schema' ),
77
			)
78
		);
79
80
		register_rest_route(
81
			$this->namespace,
82
			'/' . $this->rest_base . '/(?P<id>[\d]+)',
83
			array(
84
				'args'   => array(
85
					'id' => array(
86
						'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
87
						'type'        => 'integer',
88
					),
89
				),
90
				array(
91
					'methods'             => WP_REST_Server::READABLE,
92
					'callback'            => array( $this, 'get_item' ),
93
					'permission_callback' => array( $this, 'get_item_permissions_check' ),
94
					'args'                => array(
95
						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
96
					),
97
				),
98
				array(
99
					'methods'             => WP_REST_Server::EDITABLE,
100
					'callback'            => array( $this, 'update_item' ),
101
					'permission_callback' => array( $this, 'update_item_permissions_check' ),
102
					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
103
				),
104
				array(
105
					'methods'             => WP_REST_Server::DELETABLE,
106
					'callback'            => array( $this, 'delete_item' ),
107
					'permission_callback' => array( $this, 'delete_item_permissions_check' ),
108
					'args'                => array(
109
						'force' => array(
110
							'default'     => false,
111
							'type'        => 'boolean',
112
							'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
113
						),
114
					),
115
				),
116
				'schema' => array( $this, 'get_public_item_schema' ),
117
			)
118
		);
119
120
		register_rest_route(
121
			$this->namespace,
122
			'/' . $this->rest_base . '/batch',
123
			array(
124
				array(
125
					'methods'             => WP_REST_Server::EDITABLE,
126
					'callback'            => array( $this, 'batch_items' ),
127
					'permission_callback' => array( $this, 'batch_items_permissions_check' ),
128
					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
129
				),
130
				'schema' => array( $this, 'get_public_batch_schema' ),
131
			)
132
		);
133
	}
134
135
	/**
136
	 * Get object. Return false if object is not of required type.
137
	 *
138
	 * @since  3.0.0
139
	 * @param  int $id Object ID.
140
	 * @return WC_Data|bool
0 ignored issues
show
Bug introduced by
The type WC_Data was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
141
	 */
142
	protected function get_object( $id ) {
143
		$order = wc_get_order( $id );
144
		// In case id is a refund's id (or it's not an order at all), don't expose it via /orders/ path.
145
		if ( ! $order || 'shop_order_refund' === $order->get_type() ) {
146
			return false;
147
		}
148
149
		return $order;
150
	}
151
152
	/**
153
	 * Expands an order item to get its data.
154
	 *
155
	 * @param WC_Order_item $item Order item data.
0 ignored issues
show
Bug introduced by
The type WC_Order_item was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
156
	 * @return array
157
	 */
158
	protected function get_order_item_data( $item ) {
159
		$data           = $item->get_data();
160
		$format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' );
161
162
		// Format decimal values.
163
		foreach ( $format_decimal as $key ) {
164
			if ( isset( $data[ $key ] ) ) {
165
				$data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] );
166
			}
167
		}
168
169
		// Add SKU and PRICE to products.
170
		if ( is_callable( array( $item, 'get_product' ) ) ) {
171
			$data['sku']   = $item->get_product() ? $item->get_product()->get_sku() : null;
172
			$data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0;
173
		}
174
175
		// Format taxes.
176
		if ( ! empty( $data['taxes']['total'] ) ) {
177
			$taxes = array();
178
179
			foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) {
180
				$taxes[] = array(
181
					'id'       => $tax_rate_id,
182
					'total'    => $tax,
183
					'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '',
184
				);
185
			}
186
			$data['taxes'] = $taxes;
187
		} elseif ( isset( $data['taxes'] ) ) {
188
			$data['taxes'] = array();
189
		}
190
191
		// Remove names for coupons, taxes and shipping.
192
		if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) {
193
			unset( $data['name'] );
194
		}
195
196
		// Remove props we don't want to expose.
197
		unset( $data['order_id'] );
198
		unset( $data['type'] );
199
200
		return $data;
201
	}
202
203
	/**
204
	 * Get formatted item data.
205
	 *
206
	 * @since  3.0.0
207
	 * @param  WC_Data $object WC_Data instance.
208
	 * @return array
209
	 */
210
	protected function get_formatted_item_data( $object ) {
211
		$data              = $object->get_data();
212
		$format_decimal    = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' );
213
		$format_date       = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' );
214
		$format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' );
215
216
		// Format decimal values.
217
		foreach ( $format_decimal as $key ) {
218
			$data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] );
219
		}
220
221
		// Format date values.
222
		foreach ( $format_date as $key ) {
223
			$datetime              = $data[ $key ];
224
			$data[ $key ]          = wc_rest_prepare_date_response( $datetime, false );
225
			$data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime );
226
		}
227
228
		// Format the order status.
229
		$data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status'];
230
231
		// Format line items.
232
		foreach ( $format_line_items as $key ) {
233
			$data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) );
234
		}
235
236
		// Refunds.
237
		$data['refunds'] = array();
238
		foreach ( $object->get_refunds() as $refund ) {
239
			$data['refunds'][] = array(
240
				'id'     => $refund->get_id(),
241
				'reason' => $refund->get_reason() ? $refund->get_reason() : '',
242
				'total'  => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ),
243
			);
244
		}
245
246
		return array(
247
			'id'                   => $object->get_id(),
248
			'parent_id'            => $data['parent_id'],
249
			'number'               => $data['number'],
250
			'order_key'            => $data['order_key'],
251
			'created_via'          => $data['created_via'],
252
			'version'              => $data['version'],
253
			'status'               => $data['status'],
254
			'currency'             => $data['currency'],
255
			'date_created'         => $data['date_created'],
256
			'date_created_gmt'     => $data['date_created_gmt'],
257
			'date_modified'        => $data['date_modified'],
258
			'date_modified_gmt'    => $data['date_modified_gmt'],
259
			'discount_total'       => $data['discount_total'],
260
			'discount_tax'         => $data['discount_tax'],
261
			'shipping_total'       => $data['shipping_total'],
262
			'shipping_tax'         => $data['shipping_tax'],
263
			'cart_tax'             => $data['cart_tax'],
264
			'total'                => $data['total'],
265
			'total_tax'            => $data['total_tax'],
266
			'prices_include_tax'   => $data['prices_include_tax'],
267
			'customer_id'          => $data['customer_id'],
268
			'customer_ip_address'  => $data['customer_ip_address'],
269
			'customer_user_agent'  => $data['customer_user_agent'],
270
			'customer_note'        => $data['customer_note'],
271
			'billing'              => $data['billing'],
272
			'shipping'             => $data['shipping'],
273
			'payment_method'       => $data['payment_method'],
274
			'payment_method_title' => $data['payment_method_title'],
275
			'transaction_id'       => $data['transaction_id'],
276
			'date_paid'            => $data['date_paid'],
277
			'date_paid_gmt'        => $data['date_paid_gmt'],
278
			'date_completed'       => $data['date_completed'],
279
			'date_completed_gmt'   => $data['date_completed_gmt'],
280
			'cart_hash'            => $data['cart_hash'],
281
			'meta_data'            => $data['meta_data'],
282
			'line_items'           => $data['line_items'],
283
			'tax_lines'            => $data['tax_lines'],
284
			'shipping_lines'       => $data['shipping_lines'],
285
			'fee_lines'            => $data['fee_lines'],
286
			'coupon_lines'         => $data['coupon_lines'],
287
			'refunds'              => $data['refunds'],
288
		);
289
	}
290
291
	/**
292
	 * Prepare a single order output for response.
293
	 *
294
	 * @since  3.0.0
295
	 * @param  WC_Data         $object  Object data.
296
	 * @param  WP_REST_Request $request Request object.
0 ignored issues
show
Bug introduced by
The type WP_REST_Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
297
	 * @return WP_REST_Response
0 ignored issues
show
Bug introduced by
The type WP_REST_Response was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
298
	 */
299
	public function prepare_object_for_response( $object, $request ) {
300
		$this->request       = $request;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request of type WP_REST_Request is incompatible with the declared type array of property $request.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
301
		$this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] );
302
		$data                = $this->get_formatted_item_data( $object );
303
		$context             = ! empty( $request['context'] ) ? $request['context'] : 'view';
304
		$data                = $this->add_additional_fields_to_object( $data, $request );
305
		$data                = $this->filter_response_by_context( $data, $context );
306
		$response            = rest_ensure_response( $data );
307
		$response->add_links( $this->prepare_links( $object, $request ) );
308
309
		/**
310
		 * Filter the data for a response.
311
		 *
312
		 * The dynamic portion of the hook name, $this->post_type,
313
		 * refers to object type being prepared for the response.
314
		 *
315
		 * @param WP_REST_Response $response The response object.
316
		 * @param WC_Data          $object   Object data.
317
		 * @param WP_REST_Request  $request  Request object.
318
		 */
319
		return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request );
320
	}
321
322
	/**
323
	 * Prepare links for the request.
324
	 *
325
	 * @param WC_Data         $object  Object data.
326
	 * @param WP_REST_Request $request Request object.
327
	 * @return array                   Links for the given post.
328
	 */
329
	protected function prepare_links( $object, $request ) {
330
		$links = array(
331
			'self'       => array(
332
				'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ),
333
			),
334
			'collection' => array(
335
				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
336
			),
337
		);
338
339
		if ( 0 !== (int) $object->get_customer_id() ) {
340
			$links['customer'] = array(
341
				'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->get_customer_id() ) ),
342
			);
343
		}
344
345
		if ( 0 !== (int) $object->get_parent_id() ) {
346
			$links['up'] = array(
347
				'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ),
348
			);
349
		}
350
351
		return $links;
352
	}
353
354
	/**
355
	 * Prepare objects query.
356
	 *
357
	 * @since  3.0.0
358
	 * @param  WP_REST_Request $request Full details about the request.
359
	 * @return array
360
	 */
361
	protected function prepare_objects_query( $request ) {
362
		global $wpdb;
363
364
		$args = parent::prepare_objects_query( $request );
365
366
		// Set post_status.
367
		if ( in_array( $request['status'], $this->get_order_statuses(), true ) ) {
368
			$args['post_status'] = 'wc-' . $request['status'];
369
		} elseif ( 'any' === $request['status'] ) {
370
			$args['post_status'] = 'any';
371
		} else {
372
			$args['post_status'] = $request['status'];
373
		}
374
375
		if ( isset( $request['customer'] ) ) {
376
			if ( ! empty( $args['meta_query'] ) ) {
377
				$args['meta_query'] = array(); // WPCS: slow query ok.
378
			}
379
380
			$args['meta_query'][] = array(
381
				'key'   => '_customer_user',
382
				'value' => $request['customer'],
383
				'type'  => 'NUMERIC',
384
			);
385
		}
386
387
		// Search by product.
388
		if ( ! empty( $request['product'] ) ) {
389
			$order_ids = $wpdb->get_col(
390
				$wpdb->prepare(
391
					"SELECT order_id
392
					FROM {$wpdb->prefix}woocommerce_order_items
393
					WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d )
394
					AND order_item_type = 'line_item'",
395
					$request['product']
396
				)
397
			);
398
399
			// Force WP_Query return empty if don't found any order.
400
			$order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 );
401
402
			$args['post__in'] = $order_ids;
403
		}
404
405
		// Search.
406
		if ( ! empty( $args['s'] ) ) {
407
			$order_ids = wc_order_search( $args['s'] );
408
409
			if ( ! empty( $order_ids ) ) {
410
				unset( $args['s'] );
411
				$args['post__in'] = array_merge( $order_ids, array( 0 ) );
412
			}
413
		}
414
415
		/**
416
		 * Filter the query arguments for a request.
417
		 *
418
		 * Enables adding extra arguments or setting defaults for an order collection request.
419
		 *
420
		 * @param array           $args    Key value array of query var to query value.
421
		 * @param WP_REST_Request $request The request used.
422
		 */
423
		$args = apply_filters( 'woocommerce_rest_orders_prepare_object_query', $args, $request );
424
425
		return $args;
426
	}
427
428
	/**
429
	 * Only return writable props from schema.
430
	 *
431
	 * @param  array $schema Schema.
432
	 * @return bool
433
	 */
434
	protected function filter_writable_props( $schema ) {
435
		return empty( $schema['readonly'] );
436
	}
437
438
	/**
439
	 * Prepare a single order for create or update.
440
	 *
441
	 * @param  WP_REST_Request $request Request object.
442
	 * @param  bool            $creating If is creating a new object.
443
	 * @return WP_Error|WC_Data
0 ignored issues
show
Bug introduced by
The type WP_Error was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
444
	 */
445
	protected function prepare_object_for_database( $request, $creating = false ) {
446
		$id        = isset( $request['id'] ) ? absint( $request['id'] ) : 0;
447
		$order     = new WC_Order( $id );
0 ignored issues
show
Bug introduced by
The type WC_Order was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
448
		$schema    = $this->get_item_schema();
449
		$data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) );
450
451
		// Handle all writable props.
452
		foreach ( $data_keys as $key ) {
453
			$value = $request[ $key ];
454
455
			if ( ! is_null( $value ) ) {
456
				switch ( $key ) {
457
					case 'status':
458
						// Status change should be done later so transitions have new data.
459
						break;
460
					case 'billing':
461
					case 'shipping':
462
						$this->update_address( $order, $value, $key );
463
						break;
464
					case 'line_items':
465
					case 'shipping_lines':
466
					case 'fee_lines':
467
					case 'coupon_lines':
468
						if ( is_array( $value ) ) {
469
							foreach ( $value as $item ) {
470
								if ( is_array( $item ) ) {
471
									if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) {
472
										$order->remove_item( $item['id'] );
473
									} else {
474
										$this->set_item( $order, $key, $item );
475
									}
476
								}
477
							}
478
						}
479
						break;
480
					case 'meta_data':
481
						if ( is_array( $value ) ) {
482
							foreach ( $value as $meta ) {
483
								$order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
484
							}
485
						}
486
						break;
487
					default:
488
						if ( is_callable( array( $order, "set_{$key}" ) ) ) {
489
							$order->{"set_{$key}"}( $value );
490
						}
491
						break;
492
				}
493
			}
494
		}
495
496
		/**
497
		 * Filters an object before it is inserted via the REST API.
498
		 *
499
		 * The dynamic portion of the hook name, `$this->post_type`,
500
		 * refers to the object type slug.
501
		 *
502
		 * @param WC_Data         $order    Object object.
503
		 * @param WP_REST_Request $request  Request object.
504
		 * @param bool            $creating If is creating a new object.
505
		 */
506
		return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating );
507
	}
508
509
	/**
510
	 * Save an object data.
511
	 *
512
	 * @since  3.0.0
513
	 * @throws WC_REST_Exception But all errors are validated before returning any data.
514
	 * @param  WP_REST_Request $request  Full details about the request.
515
	 * @param  bool            $creating If is creating a new object.
516
	 * @return WC_Data|WP_Error
517
	 */
518
	protected function save_object( $request, $creating = false ) {
519
		try {
520
			$object = $this->prepare_object_for_database( $request, $creating );
521
522
			if ( is_wp_error( $object ) ) {
523
				return $object;
524
			}
525
526
			// Make sure gateways are loaded so hooks from gateways fire on save/create.
527
			WC()->payment_gateways();
528
529
			if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) {
530
				// Make sure customer exists.
531
				if ( false === get_user_by( 'id', $request['customer_id'] ) ) {
532
					throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 );
0 ignored issues
show
Bug introduced by
The type WC_REST_Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
533
				}
534
535
				// Make sure customer is part of blog.
536
				if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) {
537
					add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' );
538
				}
539
			}
540
541
			if ( $creating ) {
542
				$object->set_created_via( 'rest-api' );
543
				$object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
544
				$object->calculate_totals();
545
			} else {
546
				// If items have changed, recalculate order totals.
547
				if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) {
548
					$object->calculate_totals( true );
549
				}
550
			}
551
552
			// Set status.
553
			if ( ! empty( $request['status'] ) ) {
554
				$object->set_status( $request['status'] );
555
			}
556
557
			$object->save();
558
559
			// Actions for after the order is saved.
560
			if ( true === $request['set_paid'] ) {
561
				if ( $creating || $object->needs_payment() ) {
562
					$object->payment_complete( $request['transaction_id'] );
563
				}
564
			}
565
566
			return $this->get_object( $object->get_id() );
567
		} catch ( WC_Data_Exception $e ) {
0 ignored issues
show
Bug introduced by
The type WC_Data_Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
568
			return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() );
569
		} catch ( WC_REST_Exception $e ) {
570
			return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
571
		}
572
	}
573
574
	/**
575
	 * Update address.
576
	 *
577
	 * @param WC_Order $order  Order data.
578
	 * @param array    $posted Posted data.
579
	 * @param string   $type   Address type.
580
	 */
581
	protected function update_address( $order, $posted, $type = 'billing' ) {
582
		foreach ( $posted as $key => $value ) {
583
			if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) {
584
				$order->{"set_{$type}_{$key}"}( $value );
585
			}
586
		}
587
	}
588
589
	/**
590
	 * Gets the product ID from the SKU or posted ID.
591
	 *
592
	 * @throws WC_REST_Exception When SKU or ID is not valid.
593
	 * @param array $posted Request data.
594
	 * @return int
595
	 */
596
	protected function get_product_id( $posted ) {
597
		if ( ! empty( $posted['sku'] ) ) {
598
			$product_id = (int) wc_get_product_id_by_sku( $posted['sku'] );
599
		} elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) {
600
			$product_id = (int) $posted['product_id'];
601
		} elseif ( ! empty( $posted['variation_id'] ) ) {
602
			$product_id = (int) $posted['variation_id'];
603
		} else {
604
			throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 );
605
		}
606
		return $product_id;
607
	}
608
609
	/**
610
	 * Maybe set an item prop if the value was posted.
611
	 *
612
	 * @param WC_Order_Item $item   Order item.
0 ignored issues
show
Bug introduced by
The type WC_Order_Item was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
613
	 * @param string        $prop   Order property.
614
	 * @param array         $posted Request data.
615
	 */
616
	protected function maybe_set_item_prop( $item, $prop, $posted ) {
617
		if ( isset( $posted[ $prop ] ) ) {
618
			$item->{"set_$prop"}( $posted[ $prop ] );
619
		}
620
	}
621
622
	/**
623
	 * Maybe set item props if the values were posted.
624
	 *
625
	 * @param WC_Order_Item $item   Order item data.
626
	 * @param string[]      $props  Properties.
627
	 * @param array         $posted Request data.
628
	 */
629
	protected function maybe_set_item_props( $item, $props, $posted ) {
630
		foreach ( $props as $prop ) {
631
			$this->maybe_set_item_prop( $item, $prop, $posted );
632
		}
633
	}
634
635
	/**
636
	 * Maybe set item meta if posted.
637
	 *
638
	 * @param WC_Order_Item $item   Order item data.
639
	 * @param array         $posted Request data.
640
	 */
641
	protected function maybe_set_item_meta_data( $item, $posted ) {
642
		if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) {
643
			foreach ( $posted['meta_data'] as $meta ) {
644
				if ( isset( $meta['key'] ) ) {
645
					$value = isset( $meta['value'] ) ? $meta['value'] : null;
646
					$item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' );
647
				}
648
			}
649
		}
650
	}
651
652
	/**
653
	 * Create or update a line item.
654
	 *
655
	 * @param array  $posted Line item data.
656
	 * @param string $action 'create' to add line item or 'update' to update it.
657
	 * @param object $item Passed when updating an item. Null during creation.
658
	 * @return WC_Order_Item_Product
659
	 * @throws WC_REST_Exception Invalid data, server error.
660
	 */
661
	protected function prepare_line_items( $posted, $action = 'create', $item = null ) {
662
		$item    = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
0 ignored issues
show
Bug introduced by
The type WC_Order_Item_Product was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
663
		$product = wc_get_product( $this->get_product_id( $posted ) );
664
665
		if ( $product !== $item->get_product() ) {
666
			$item->set_product( $product );
667
668
			if ( 'create' === $action ) {
669
				$quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1;
670
				$total    = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) );
671
				$item->set_total( $total );
672
				$item->set_subtotal( $total );
673
			}
674
		}
675
676
		$this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted );
677
		$this->maybe_set_item_meta_data( $item, $posted );
678
679
		return $item;
680
	}
681
682
	/**
683
	 * Create or update an order shipping method.
684
	 *
685
	 * @param array  $posted $shipping Item data.
686
	 * @param string $action 'create' to add shipping or 'update' to update it.
687
	 * @param object $item Passed when updating an item. Null during creation.
688
	 * @return WC_Order_Item_Shipping
689
	 * @throws WC_REST_Exception Invalid data, server error.
690
	 */
691
	protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) {
692
		$item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
0 ignored issues
show
Bug introduced by
The type WC_Order_Item_Shipping was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
693
694
		if ( 'create' === $action ) {
695
			if ( empty( $posted['method_id'] ) ) {
696
				throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 );
697
			}
698
		}
699
700
		$this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted );
701
		$this->maybe_set_item_meta_data( $item, $posted );
702
703
		return $item;
704
	}
705
706
	/**
707
	 * Create or update an order fee.
708
	 *
709
	 * @param array  $posted Item data.
710
	 * @param string $action 'create' to add fee or 'update' to update it.
711
	 * @param object $item Passed when updating an item. Null during creation.
712
	 * @return WC_Order_Item_Fee
713
	 * @throws WC_REST_Exception Invalid data, server error.
714
	 */
715
	protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) {
716
		$item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
0 ignored issues
show
Bug introduced by
The type WC_Order_Item_Fee was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
717
718
		if ( 'create' === $action ) {
719
			if ( empty( $posted['name'] ) ) {
720
				throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 );
721
			}
722
		}
723
724
		$this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted );
725
		$this->maybe_set_item_meta_data( $item, $posted );
726
727
		return $item;
728
	}
729
730
	/**
731
	 * Create or update an order coupon.
732
	 *
733
	 * @param array  $posted Item data.
734
	 * @param string $action 'create' to add coupon or 'update' to update it.
735
	 * @param object $item Passed when updating an item. Null during creation.
736
	 * @return WC_Order_Item_Coupon
737
	 * @throws WC_REST_Exception Invalid data, server error.
738
	 */
739
	protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) {
740
		$item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
0 ignored issues
show
Bug introduced by
The type WC_Order_Item_Coupon was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
741
742
		if ( 'create' === $action ) {
743
			if ( empty( $posted['code'] ) ) {
744
				throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 );
745
			}
746
		}
747
748
		$this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted );
749
		$this->maybe_set_item_meta_data( $item, $posted );
750
751
		return $item;
752
	}
753
754
	/**
755
	 * Wrapper method to create/update order items.
756
	 * When updating, the item ID provided is checked to ensure it is associated
757
	 * with the order.
758
	 *
759
	 * @param WC_Order $order order object.
760
	 * @param string   $item_type The item type.
761
	 * @param array    $posted item provided in the request body.
762
	 * @throws WC_REST_Exception If item ID is not associated with order.
763
	 */
764
	protected function set_item( $order, $item_type, $posted ) {
765
		global $wpdb;
766
767
		if ( ! empty( $posted['id'] ) ) {
768
			$action = 'update';
769
		} else {
770
			$action = 'create';
771
		}
772
773
		$method = 'prepare_' . $item_type;
774
		$item   = null;
775
776
		// Verify provided line item ID is associated with order.
777
		if ( 'update' === $action ) {
778
			$item = $order->get_item( absint( $posted['id'] ), false );
779
780
			if ( ! $item ) {
781
				throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 );
782
			}
783
		}
784
785
		// Prepare item data.
786
		$item = $this->$method( $posted, $action, $item );
787
788
		do_action( 'woocommerce_rest_set_order_item', $item, $posted );
789
790
		// If creating the order, add the item to it.
791
		if ( 'create' === $action ) {
792
			$order->add_item( $item );
793
		} else {
794
			$item->save();
795
		}
796
	}
797
798
	/**
799
	 * Helper method to check if the resource ID associated with the provided item is null.
800
	 * Items can be deleted by setting the resource ID to null.
801
	 *
802
	 * @param array $item Item provided in the request body.
803
	 * @return bool True if the item resource ID is null, false otherwise.
804
	 */
805
	protected function item_is_null( $item ) {
806
		$keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' );
807
808
		foreach ( $keys as $key ) {
809
			if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) {
810
				return true;
811
			}
812
		}
813
814
		return false;
815
	}
816
817
	/**
818
	 * Get order statuses without prefixes.
819
	 *
820
	 * @return array
821
	 */
822
	protected function get_order_statuses() {
823
		$order_statuses = array();
824
825
		foreach ( array_keys( wc_get_order_statuses() ) as $status ) {
826
			$order_statuses[] = str_replace( 'wc-', '', $status );
827
		}
828
829
		return $order_statuses;
830
	}
831
832
	/**
833
	 * Get the Order's schema, conforming to JSON Schema.
834
	 *
835
	 * @return array
836
	 */
837
	public function get_item_schema() {
838
		$schema = array(
839
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
840
			'title'      => $this->post_type,
841
			'type'       => 'object',
842
			'properties' => array(
843
				'id'                   => array(
844
					'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
845
					'type'        => 'integer',
846
					'context'     => array( 'view', 'edit' ),
847
					'readonly'    => true,
848
				),
849
				'parent_id'            => array(
850
					'description' => __( 'Parent order ID.', 'woocommerce' ),
851
					'type'        => 'integer',
852
					'context'     => array( 'view', 'edit' ),
853
				),
854
				'number'               => array(
855
					'description' => __( 'Order number.', 'woocommerce' ),
856
					'type'        => 'string',
857
					'context'     => array( 'view', 'edit' ),
858
					'readonly'    => true,
859
				),
860
				'order_key'            => array(
861
					'description' => __( 'Order key.', 'woocommerce' ),
862
					'type'        => 'string',
863
					'context'     => array( 'view', 'edit' ),
864
					'readonly'    => true,
865
				),
866
				'created_via'          => array(
867
					'description' => __( 'Shows where the order was created.', 'woocommerce' ),
868
					'type'        => 'string',
869
					'context'     => array( 'view', 'edit' ),
870
					'readonly'    => true,
871
				),
872
				'version'              => array(
873
					'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ),
874
					'type'        => 'integer',
875
					'context'     => array( 'view', 'edit' ),
876
					'readonly'    => true,
877
				),
878
				'status'               => array(
879
					'description' => __( 'Order status.', 'woocommerce' ),
880
					'type'        => 'string',
881
					'default'     => 'pending',
882
					'enum'        => $this->get_order_statuses(),
883
					'context'     => array( 'view', 'edit' ),
884
				),
885
				'currency'             => array(
886
					'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ),
887
					'type'        => 'string',
888
					'default'     => get_woocommerce_currency(),
889
					'enum'        => array_keys( get_woocommerce_currencies() ),
890
					'context'     => array( 'view', 'edit' ),
891
				),
892
				'date_created'         => array(
893
					'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ),
894
					'type'        => 'date-time',
895
					'context'     => array( 'view', 'edit' ),
896
					'readonly'    => true,
897
				),
898
				'date_created_gmt'     => array(
899
					'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ),
900
					'type'        => 'date-time',
901
					'context'     => array( 'view', 'edit' ),
902
					'readonly'    => true,
903
				),
904
				'date_modified'        => array(
905
					'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ),
906
					'type'        => 'date-time',
907
					'context'     => array( 'view', 'edit' ),
908
					'readonly'    => true,
909
				),
910
				'date_modified_gmt'    => array(
911
					'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ),
912
					'type'        => 'date-time',
913
					'context'     => array( 'view', 'edit' ),
914
					'readonly'    => true,
915
				),
916
				'discount_total'       => array(
917
					'description' => __( 'Total discount amount for the order.', 'woocommerce' ),
918
					'type'        => 'string',
919
					'context'     => array( 'view', 'edit' ),
920
					'readonly'    => true,
921
				),
922
				'discount_tax'         => array(
923
					'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ),
924
					'type'        => 'string',
925
					'context'     => array( 'view', 'edit' ),
926
					'readonly'    => true,
927
				),
928
				'shipping_total'       => array(
929
					'description' => __( 'Total shipping amount for the order.', 'woocommerce' ),
930
					'type'        => 'string',
931
					'context'     => array( 'view', 'edit' ),
932
					'readonly'    => true,
933
				),
934
				'shipping_tax'         => array(
935
					'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ),
936
					'type'        => 'string',
937
					'context'     => array( 'view', 'edit' ),
938
					'readonly'    => true,
939
				),
940
				'cart_tax'             => array(
941
					'description' => __( 'Sum of line item taxes only.', 'woocommerce' ),
942
					'type'        => 'string',
943
					'context'     => array( 'view', 'edit' ),
944
					'readonly'    => true,
945
				),
946
				'total'                => array(
947
					'description' => __( 'Grand total.', 'woocommerce' ),
948
					'type'        => 'string',
949
					'context'     => array( 'view', 'edit' ),
950
					'readonly'    => true,
951
				),
952
				'total_tax'            => array(
953
					'description' => __( 'Sum of all taxes.', 'woocommerce' ),
954
					'type'        => 'string',
955
					'context'     => array( 'view', 'edit' ),
956
					'readonly'    => true,
957
				),
958
				'prices_include_tax'   => array(
959
					'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ),
960
					'type'        => 'boolean',
961
					'context'     => array( 'view', 'edit' ),
962
					'readonly'    => true,
963
				),
964
				'customer_id'          => array(
965
					'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ),
966
					'type'        => 'integer',
967
					'default'     => 0,
968
					'context'     => array( 'view', 'edit' ),
969
				),
970
				'customer_ip_address'  => array(
971
					'description' => __( "Customer's IP address.", 'woocommerce' ),
972
					'type'        => 'string',
973
					'context'     => array( 'view', 'edit' ),
974
					'readonly'    => true,
975
				),
976
				'customer_user_agent'  => array(
977
					'description' => __( 'User agent of the customer.', 'woocommerce' ),
978
					'type'        => 'string',
979
					'context'     => array( 'view', 'edit' ),
980
					'readonly'    => true,
981
				),
982
				'customer_note'        => array(
983
					'description' => __( 'Note left by customer during checkout.', 'woocommerce' ),
984
					'type'        => 'string',
985
					'context'     => array( 'view', 'edit' ),
986
				),
987
				'billing'              => array(
988
					'description' => __( 'Billing address.', 'woocommerce' ),
989
					'type'        => 'object',
990
					'context'     => array( 'view', 'edit' ),
991
					'properties'  => array(
992
						'first_name' => array(
993
							'description' => __( 'First name.', 'woocommerce' ),
994
							'type'        => 'string',
995
							'context'     => array( 'view', 'edit' ),
996
						),
997
						'last_name'  => array(
998
							'description' => __( 'Last name.', 'woocommerce' ),
999
							'type'        => 'string',
1000
							'context'     => array( 'view', 'edit' ),
1001
						),
1002
						'company'    => array(
1003
							'description' => __( 'Company name.', 'woocommerce' ),
1004
							'type'        => 'string',
1005
							'context'     => array( 'view', 'edit' ),
1006
						),
1007
						'address_1'  => array(
1008
							'description' => __( 'Address line 1', 'woocommerce' ),
1009
							'type'        => 'string',
1010
							'context'     => array( 'view', 'edit' ),
1011
						),
1012
						'address_2'  => array(
1013
							'description' => __( 'Address line 2', 'woocommerce' ),
1014
							'type'        => 'string',
1015
							'context'     => array( 'view', 'edit' ),
1016
						),
1017
						'city'       => array(
1018
							'description' => __( 'City name.', 'woocommerce' ),
1019
							'type'        => 'string',
1020
							'context'     => array( 'view', 'edit' ),
1021
						),
1022
						'state'      => array(
1023
							'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ),
1024
							'type'        => 'string',
1025
							'context'     => array( 'view', 'edit' ),
1026
						),
1027
						'postcode'   => array(
1028
							'description' => __( 'Postal code.', 'woocommerce' ),
1029
							'type'        => 'string',
1030
							'context'     => array( 'view', 'edit' ),
1031
						),
1032
						'country'    => array(
1033
							'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ),
1034
							'type'        => 'string',
1035
							'context'     => array( 'view', 'edit' ),
1036
						),
1037
						'email'      => array(
1038
							'description' => __( 'Email address.', 'woocommerce' ),
1039
							'type'        => 'string',
1040
							'format'      => 'email',
1041
							'context'     => array( 'view', 'edit' ),
1042
						),
1043
						'phone'      => array(
1044
							'description' => __( 'Phone number.', 'woocommerce' ),
1045
							'type'        => 'string',
1046
							'context'     => array( 'view', 'edit' ),
1047
						),
1048
					),
1049
				),
1050
				'shipping'             => array(
1051
					'description' => __( 'Shipping address.', 'woocommerce' ),
1052
					'type'        => 'object',
1053
					'context'     => array( 'view', 'edit' ),
1054
					'properties'  => array(
1055
						'first_name' => array(
1056
							'description' => __( 'First name.', 'woocommerce' ),
1057
							'type'        => 'string',
1058
							'context'     => array( 'view', 'edit' ),
1059
						),
1060
						'last_name'  => array(
1061
							'description' => __( 'Last name.', 'woocommerce' ),
1062
							'type'        => 'string',
1063
							'context'     => array( 'view', 'edit' ),
1064
						),
1065
						'company'    => array(
1066
							'description' => __( 'Company name.', 'woocommerce' ),
1067
							'type'        => 'string',
1068
							'context'     => array( 'view', 'edit' ),
1069
						),
1070
						'address_1'  => array(
1071
							'description' => __( 'Address line 1', 'woocommerce' ),
1072
							'type'        => 'string',
1073
							'context'     => array( 'view', 'edit' ),
1074
						),
1075
						'address_2'  => array(
1076
							'description' => __( 'Address line 2', 'woocommerce' ),
1077
							'type'        => 'string',
1078
							'context'     => array( 'view', 'edit' ),
1079
						),
1080
						'city'       => array(
1081
							'description' => __( 'City name.', 'woocommerce' ),
1082
							'type'        => 'string',
1083
							'context'     => array( 'view', 'edit' ),
1084
						),
1085
						'state'      => array(
1086
							'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ),
1087
							'type'        => 'string',
1088
							'context'     => array( 'view', 'edit' ),
1089
						),
1090
						'postcode'   => array(
1091
							'description' => __( 'Postal code.', 'woocommerce' ),
1092
							'type'        => 'string',
1093
							'context'     => array( 'view', 'edit' ),
1094
						),
1095
						'country'    => array(
1096
							'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ),
1097
							'type'        => 'string',
1098
							'context'     => array( 'view', 'edit' ),
1099
						),
1100
					),
1101
				),
1102
				'payment_method'       => array(
1103
					'description' => __( 'Payment method ID.', 'woocommerce' ),
1104
					'type'        => 'string',
1105
					'context'     => array( 'view', 'edit' ),
1106
				),
1107
				'payment_method_title' => array(
1108
					'description' => __( 'Payment method title.', 'woocommerce' ),
1109
					'type'        => 'string',
1110
					'context'     => array( 'view', 'edit' ),
1111
					'arg_options' => array(
1112
						'sanitize_callback' => 'sanitize_text_field',
1113
					),
1114
				),
1115
				'transaction_id'       => array(
1116
					'description' => __( 'Unique transaction ID.', 'woocommerce' ),
1117
					'type'        => 'string',
1118
					'context'     => array( 'view', 'edit' ),
1119
				),
1120
				'date_paid'            => array(
1121
					'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ),
1122
					'type'        => 'date-time',
1123
					'context'     => array( 'view', 'edit' ),
1124
					'readonly'    => true,
1125
				),
1126
				'date_paid_gmt'        => array(
1127
					'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ),
1128
					'type'        => 'date-time',
1129
					'context'     => array( 'view', 'edit' ),
1130
					'readonly'    => true,
1131
				),
1132
				'date_completed'       => array(
1133
					'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ),
1134
					'type'        => 'date-time',
1135
					'context'     => array( 'view', 'edit' ),
1136
					'readonly'    => true,
1137
				),
1138
				'date_completed_gmt'   => array(
1139
					'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ),
1140
					'type'        => 'date-time',
1141
					'context'     => array( 'view', 'edit' ),
1142
					'readonly'    => true,
1143
				),
1144
				'cart_hash'            => array(
1145
					'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ),
1146
					'type'        => 'string',
1147
					'context'     => array( 'view', 'edit' ),
1148
					'readonly'    => true,
1149
				),
1150
				'meta_data'            => array(
1151
					'description' => __( 'Meta data.', 'woocommerce' ),
1152
					'type'        => 'array',
1153
					'context'     => array( 'view', 'edit' ),
1154
					'items'       => array(
1155
						'type'       => 'object',
1156
						'properties' => array(
1157
							'id'    => array(
1158
								'description' => __( 'Meta ID.', 'woocommerce' ),
1159
								'type'        => 'integer',
1160
								'context'     => array( 'view', 'edit' ),
1161
								'readonly'    => true,
1162
							),
1163
							'key'   => array(
1164
								'description' => __( 'Meta key.', 'woocommerce' ),
1165
								'type'        => 'string',
1166
								'context'     => array( 'view', 'edit' ),
1167
							),
1168
							'value' => array(
1169
								'description' => __( 'Meta value.', 'woocommerce' ),
1170
								'type'        => 'mixed',
1171
								'context'     => array( 'view', 'edit' ),
1172
							),
1173
						),
1174
					),
1175
				),
1176
				'line_items'           => array(
1177
					'description' => __( 'Line items data.', 'woocommerce' ),
1178
					'type'        => 'array',
1179
					'context'     => array( 'view', 'edit' ),
1180
					'items'       => array(
1181
						'type'       => 'object',
1182
						'properties' => array(
1183
							'id'           => array(
1184
								'description' => __( 'Item ID.', 'woocommerce' ),
1185
								'type'        => 'integer',
1186
								'context'     => array( 'view', 'edit' ),
1187
								'readonly'    => true,
1188
							),
1189
							'name'         => array(
1190
								'description' => __( 'Product name.', 'woocommerce' ),
1191
								'type'        => 'mixed',
1192
								'context'     => array( 'view', 'edit' ),
1193
							),
1194
							'product_id'   => array(
1195
								'description' => __( 'Product ID.', 'woocommerce' ),
1196
								'type'        => 'mixed',
1197
								'context'     => array( 'view', 'edit' ),
1198
							),
1199
							'variation_id' => array(
1200
								'description' => __( 'Variation ID, if applicable.', 'woocommerce' ),
1201
								'type'        => 'integer',
1202
								'context'     => array( 'view', 'edit' ),
1203
							),
1204
							'quantity'     => array(
1205
								'description' => __( 'Quantity ordered.', 'woocommerce' ),
1206
								'type'        => 'integer',
1207
								'context'     => array( 'view', 'edit' ),
1208
							),
1209
							'tax_class'    => array(
1210
								'description' => __( 'Tax class of product.', 'woocommerce' ),
1211
								'type'        => 'string',
1212
								'context'     => array( 'view', 'edit' ),
1213
							),
1214
							'subtotal'     => array(
1215
								'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ),
1216
								'type'        => 'string',
1217
								'context'     => array( 'view', 'edit' ),
1218
							),
1219
							'subtotal_tax' => array(
1220
								'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ),
1221
								'type'        => 'string',
1222
								'context'     => array( 'view', 'edit' ),
1223
								'readonly'    => true,
1224
							),
1225
							'total'        => array(
1226
								'description' => __( 'Line total (after discounts).', 'woocommerce' ),
1227
								'type'        => 'string',
1228
								'context'     => array( 'view', 'edit' ),
1229
							),
1230
							'total_tax'    => array(
1231
								'description' => __( 'Line total tax (after discounts).', 'woocommerce' ),
1232
								'type'        => 'string',
1233
								'context'     => array( 'view', 'edit' ),
1234
								'readonly'    => true,
1235
							),
1236
							'taxes'        => array(
1237
								'description' => __( 'Line taxes.', 'woocommerce' ),
1238
								'type'        => 'array',
1239
								'context'     => array( 'view', 'edit' ),
1240
								'readonly'    => true,
1241
								'items'       => array(
1242
									'type'       => 'object',
1243
									'properties' => array(
1244
										'id'       => array(
1245
											'description' => __( 'Tax rate ID.', 'woocommerce' ),
1246
											'type'        => 'integer',
1247
											'context'     => array( 'view', 'edit' ),
1248
										),
1249
										'total'    => array(
1250
											'description' => __( 'Tax total.', 'woocommerce' ),
1251
											'type'        => 'string',
1252
											'context'     => array( 'view', 'edit' ),
1253
										),
1254
										'subtotal' => array(
1255
											'description' => __( 'Tax subtotal.', 'woocommerce' ),
1256
											'type'        => 'string',
1257
											'context'     => array( 'view', 'edit' ),
1258
										),
1259
									),
1260
								),
1261
							),
1262
							'meta_data'    => array(
1263
								'description' => __( 'Meta data.', 'woocommerce' ),
1264
								'type'        => 'array',
1265
								'context'     => array( 'view', 'edit' ),
1266
								'items'       => array(
1267
									'type'       => 'object',
1268
									'properties' => array(
1269
										'id'    => array(
1270
											'description' => __( 'Meta ID.', 'woocommerce' ),
1271
											'type'        => 'integer',
1272
											'context'     => array( 'view', 'edit' ),
1273
											'readonly'    => true,
1274
										),
1275
										'key'   => array(
1276
											'description' => __( 'Meta key.', 'woocommerce' ),
1277
											'type'        => 'string',
1278
											'context'     => array( 'view', 'edit' ),
1279
										),
1280
										'value' => array(
1281
											'description' => __( 'Meta value.', 'woocommerce' ),
1282
											'type'        => 'mixed',
1283
											'context'     => array( 'view', 'edit' ),
1284
										),
1285
									),
1286
								),
1287
							),
1288
							'sku'          => array(
1289
								'description' => __( 'Product SKU.', 'woocommerce' ),
1290
								'type'        => 'string',
1291
								'context'     => array( 'view', 'edit' ),
1292
								'readonly'    => true,
1293
							),
1294
							'price'        => array(
1295
								'description' => __( 'Product price.', 'woocommerce' ),
1296
								'type'        => 'number',
1297
								'context'     => array( 'view', 'edit' ),
1298
								'readonly'    => true,
1299
							),
1300
						),
1301
					),
1302
				),
1303
				'tax_lines'            => array(
1304
					'description' => __( 'Tax lines data.', 'woocommerce' ),
1305
					'type'        => 'array',
1306
					'context'     => array( 'view', 'edit' ),
1307
					'readonly'    => true,
1308
					'items'       => array(
1309
						'type'       => 'object',
1310
						'properties' => array(
1311
							'id'                 => array(
1312
								'description' => __( 'Item ID.', 'woocommerce' ),
1313
								'type'        => 'integer',
1314
								'context'     => array( 'view', 'edit' ),
1315
								'readonly'    => true,
1316
							),
1317
							'rate_code'          => array(
1318
								'description' => __( 'Tax rate code.', 'woocommerce' ),
1319
								'type'        => 'string',
1320
								'context'     => array( 'view', 'edit' ),
1321
								'readonly'    => true,
1322
							),
1323
							'rate_id'            => array(
1324
								'description' => __( 'Tax rate ID.', 'woocommerce' ),
1325
								'type'        => 'string',
1326
								'context'     => array( 'view', 'edit' ),
1327
								'readonly'    => true,
1328
							),
1329
							'label'              => array(
1330
								'description' => __( 'Tax rate label.', 'woocommerce' ),
1331
								'type'        => 'string',
1332
								'context'     => array( 'view', 'edit' ),
1333
								'readonly'    => true,
1334
							),
1335
							'compound'           => array(
1336
								'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ),
1337
								'type'        => 'boolean',
1338
								'context'     => array( 'view', 'edit' ),
1339
								'readonly'    => true,
1340
							),
1341
							'tax_total'          => array(
1342
								'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ),
1343
								'type'        => 'string',
1344
								'context'     => array( 'view', 'edit' ),
1345
								'readonly'    => true,
1346
							),
1347
							'shipping_tax_total' => array(
1348
								'description' => __( 'Shipping tax total.', 'woocommerce' ),
1349
								'type'        => 'string',
1350
								'context'     => array( 'view', 'edit' ),
1351
								'readonly'    => true,
1352
							),
1353
							'meta_data'          => array(
1354
								'description' => __( 'Meta data.', 'woocommerce' ),
1355
								'type'        => 'array',
1356
								'context'     => array( 'view', 'edit' ),
1357
								'items'       => array(
1358
									'type'       => 'object',
1359
									'properties' => array(
1360
										'id'    => array(
1361
											'description' => __( 'Meta ID.', 'woocommerce' ),
1362
											'type'        => 'integer',
1363
											'context'     => array( 'view', 'edit' ),
1364
											'readonly'    => true,
1365
										),
1366
										'key'   => array(
1367
											'description' => __( 'Meta key.', 'woocommerce' ),
1368
											'type'        => 'string',
1369
											'context'     => array( 'view', 'edit' ),
1370
										),
1371
										'value' => array(
1372
											'description' => __( 'Meta value.', 'woocommerce' ),
1373
											'type'        => 'mixed',
1374
											'context'     => array( 'view', 'edit' ),
1375
										),
1376
									),
1377
								),
1378
							),
1379
						),
1380
					),
1381
				),
1382
				'shipping_lines'       => array(
1383
					'description' => __( 'Shipping lines data.', 'woocommerce' ),
1384
					'type'        => 'array',
1385
					'context'     => array( 'view', 'edit' ),
1386
					'items'       => array(
1387
						'type'       => 'object',
1388
						'properties' => array(
1389
							'id'           => array(
1390
								'description' => __( 'Item ID.', 'woocommerce' ),
1391
								'type'        => 'integer',
1392
								'context'     => array( 'view', 'edit' ),
1393
								'readonly'    => true,
1394
							),
1395
							'method_title' => array(
1396
								'description' => __( 'Shipping method name.', 'woocommerce' ),
1397
								'type'        => 'mixed',
1398
								'context'     => array( 'view', 'edit' ),
1399
							),
1400
							'method_id'    => array(
1401
								'description' => __( 'Shipping method ID.', 'woocommerce' ),
1402
								'type'        => 'mixed',
1403
								'context'     => array( 'view', 'edit' ),
1404
							),
1405
							'instance_id'  => array(
1406
								'description' => __( 'Shipping instance ID.', 'woocommerce' ),
1407
								'type'        => 'string',
1408
								'context'     => array( 'view', 'edit' ),
1409
							),
1410
							'total'        => array(
1411
								'description' => __( 'Line total (after discounts).', 'woocommerce' ),
1412
								'type'        => 'string',
1413
								'context'     => array( 'view', 'edit' ),
1414
							),
1415
							'total_tax'    => array(
1416
								'description' => __( 'Line total tax (after discounts).', 'woocommerce' ),
1417
								'type'        => 'string',
1418
								'context'     => array( 'view', 'edit' ),
1419
								'readonly'    => true,
1420
							),
1421
							'taxes'        => array(
1422
								'description' => __( 'Line taxes.', 'woocommerce' ),
1423
								'type'        => 'array',
1424
								'context'     => array( 'view', 'edit' ),
1425
								'readonly'    => true,
1426
								'items'       => array(
1427
									'type'       => 'object',
1428
									'properties' => array(
1429
										'id'    => array(
1430
											'description' => __( 'Tax rate ID.', 'woocommerce' ),
1431
											'type'        => 'integer',
1432
											'context'     => array( 'view', 'edit' ),
1433
											'readonly'    => true,
1434
										),
1435
										'total' => array(
1436
											'description' => __( 'Tax total.', 'woocommerce' ),
1437
											'type'        => 'string',
1438
											'context'     => array( 'view', 'edit' ),
1439
											'readonly'    => true,
1440
										),
1441
									),
1442
								),
1443
							),
1444
							'meta_data'    => array(
1445
								'description' => __( 'Meta data.', 'woocommerce' ),
1446
								'type'        => 'array',
1447
								'context'     => array( 'view', 'edit' ),
1448
								'items'       => array(
1449
									'type'       => 'object',
1450
									'properties' => array(
1451
										'id'    => array(
1452
											'description' => __( 'Meta ID.', 'woocommerce' ),
1453
											'type'        => 'integer',
1454
											'context'     => array( 'view', 'edit' ),
1455
											'readonly'    => true,
1456
										),
1457
										'key'   => array(
1458
											'description' => __( 'Meta key.', 'woocommerce' ),
1459
											'type'        => 'string',
1460
											'context'     => array( 'view', 'edit' ),
1461
										),
1462
										'value' => array(
1463
											'description' => __( 'Meta value.', 'woocommerce' ),
1464
											'type'        => 'mixed',
1465
											'context'     => array( 'view', 'edit' ),
1466
										),
1467
									),
1468
								),
1469
							),
1470
						),
1471
					),
1472
				),
1473
				'fee_lines'            => array(
1474
					'description' => __( 'Fee lines data.', 'woocommerce' ),
1475
					'type'        => 'array',
1476
					'context'     => array( 'view', 'edit' ),
1477
					'items'       => array(
1478
						'type'       => 'object',
1479
						'properties' => array(
1480
							'id'         => array(
1481
								'description' => __( 'Item ID.', 'woocommerce' ),
1482
								'type'        => 'integer',
1483
								'context'     => array( 'view', 'edit' ),
1484
								'readonly'    => true,
1485
							),
1486
							'name'       => array(
1487
								'description' => __( 'Fee name.', 'woocommerce' ),
1488
								'type'        => 'mixed',
1489
								'context'     => array( 'view', 'edit' ),
1490
							),
1491
							'tax_class'  => array(
1492
								'description' => __( 'Tax class of fee.', 'woocommerce' ),
1493
								'type'        => 'string',
1494
								'context'     => array( 'view', 'edit' ),
1495
							),
1496
							'tax_status' => array(
1497
								'description' => __( 'Tax status of fee.', 'woocommerce' ),
1498
								'type'        => 'string',
1499
								'context'     => array( 'view', 'edit' ),
1500
								'enum'        => array( 'taxable', 'none' ),
1501
							),
1502
							'total'      => array(
1503
								'description' => __( 'Line total (after discounts).', 'woocommerce' ),
1504
								'type'        => 'string',
1505
								'context'     => array( 'view', 'edit' ),
1506
							),
1507
							'total_tax'  => array(
1508
								'description' => __( 'Line total tax (after discounts).', 'woocommerce' ),
1509
								'type'        => 'string',
1510
								'context'     => array( 'view', 'edit' ),
1511
								'readonly'    => true,
1512
							),
1513
							'taxes'      => array(
1514
								'description' => __( 'Line taxes.', 'woocommerce' ),
1515
								'type'        => 'array',
1516
								'context'     => array( 'view', 'edit' ),
1517
								'readonly'    => true,
1518
								'items'       => array(
1519
									'type'       => 'object',
1520
									'properties' => array(
1521
										'id'       => array(
1522
											'description' => __( 'Tax rate ID.', 'woocommerce' ),
1523
											'type'        => 'integer',
1524
											'context'     => array( 'view', 'edit' ),
1525
											'readonly'    => true,
1526
										),
1527
										'total'    => array(
1528
											'description' => __( 'Tax total.', 'woocommerce' ),
1529
											'type'        => 'string',
1530
											'context'     => array( 'view', 'edit' ),
1531
											'readonly'    => true,
1532
										),
1533
										'subtotal' => array(
1534
											'description' => __( 'Tax subtotal.', 'woocommerce' ),
1535
											'type'        => 'string',
1536
											'context'     => array( 'view', 'edit' ),
1537
											'readonly'    => true,
1538
										),
1539
									),
1540
								),
1541
							),
1542
							'meta_data'  => array(
1543
								'description' => __( 'Meta data.', 'woocommerce' ),
1544
								'type'        => 'array',
1545
								'context'     => array( 'view', 'edit' ),
1546
								'items'       => array(
1547
									'type'       => 'object',
1548
									'properties' => array(
1549
										'id'    => array(
1550
											'description' => __( 'Meta ID.', 'woocommerce' ),
1551
											'type'        => 'integer',
1552
											'context'     => array( 'view', 'edit' ),
1553
											'readonly'    => true,
1554
										),
1555
										'key'   => array(
1556
											'description' => __( 'Meta key.', 'woocommerce' ),
1557
											'type'        => 'string',
1558
											'context'     => array( 'view', 'edit' ),
1559
										),
1560
										'value' => array(
1561
											'description' => __( 'Meta value.', 'woocommerce' ),
1562
											'type'        => 'mixed',
1563
											'context'     => array( 'view', 'edit' ),
1564
										),
1565
									),
1566
								),
1567
							),
1568
						),
1569
					),
1570
				),
1571
				'coupon_lines'         => array(
1572
					'description' => __( 'Coupons line data.', 'woocommerce' ),
1573
					'type'        => 'array',
1574
					'context'     => array( 'view', 'edit' ),
1575
					'items'       => array(
1576
						'type'       => 'object',
1577
						'properties' => array(
1578
							'id'           => array(
1579
								'description' => __( 'Item ID.', 'woocommerce' ),
1580
								'type'        => 'integer',
1581
								'context'     => array( 'view', 'edit' ),
1582
								'readonly'    => true,
1583
							),
1584
							'code'         => array(
1585
								'description' => __( 'Coupon code.', 'woocommerce' ),
1586
								'type'        => 'mixed',
1587
								'context'     => array( 'view', 'edit' ),
1588
							),
1589
							'discount'     => array(
1590
								'description' => __( 'Discount total.', 'woocommerce' ),
1591
								'type'        => 'string',
1592
								'context'     => array( 'view', 'edit' ),
1593
							),
1594
							'discount_tax' => array(
1595
								'description' => __( 'Discount total tax.', 'woocommerce' ),
1596
								'type'        => 'string',
1597
								'context'     => array( 'view', 'edit' ),
1598
								'readonly'    => true,
1599
							),
1600
							'meta_data'    => array(
1601
								'description' => __( 'Meta data.', 'woocommerce' ),
1602
								'type'        => 'array',
1603
								'context'     => array( 'view', 'edit' ),
1604
								'items'       => array(
1605
									'type'       => 'object',
1606
									'properties' => array(
1607
										'id'    => array(
1608
											'description' => __( 'Meta ID.', 'woocommerce' ),
1609
											'type'        => 'integer',
1610
											'context'     => array( 'view', 'edit' ),
1611
											'readonly'    => true,
1612
										),
1613
										'key'   => array(
1614
											'description' => __( 'Meta key.', 'woocommerce' ),
1615
											'type'        => 'string',
1616
											'context'     => array( 'view', 'edit' ),
1617
										),
1618
										'value' => array(
1619
											'description' => __( 'Meta value.', 'woocommerce' ),
1620
											'type'        => 'mixed',
1621
											'context'     => array( 'view', 'edit' ),
1622
										),
1623
									),
1624
								),
1625
							),
1626
						),
1627
					),
1628
				),
1629
				'refunds'              => array(
1630
					'description' => __( 'List of refunds.', 'woocommerce' ),
1631
					'type'        => 'array',
1632
					'context'     => array( 'view', 'edit' ),
1633
					'readonly'    => true,
1634
					'items'       => array(
1635
						'type'       => 'object',
1636
						'properties' => array(
1637
							'id'     => array(
1638
								'description' => __( 'Refund ID.', 'woocommerce' ),
1639
								'type'        => 'integer',
1640
								'context'     => array( 'view', 'edit' ),
1641
								'readonly'    => true,
1642
							),
1643
							'reason' => array(
1644
								'description' => __( 'Refund reason.', 'woocommerce' ),
1645
								'type'        => 'string',
1646
								'context'     => array( 'view', 'edit' ),
1647
								'readonly'    => true,
1648
							),
1649
							'total'  => array(
1650
								'description' => __( 'Refund total.', 'woocommerce' ),
1651
								'type'        => 'string',
1652
								'context'     => array( 'view', 'edit' ),
1653
								'readonly'    => true,
1654
							),
1655
						),
1656
					),
1657
				),
1658
				'set_paid'             => array(
1659
					'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ),
1660
					'type'        => 'boolean',
1661
					'default'     => false,
1662
					'context'     => array( 'edit' ),
1663
				),
1664
			),
1665
		);
1666
1667
		return $this->add_additional_fields_schema( $schema );
1668
	}
1669
1670
	/**
1671
	 * Get the query params for collections.
1672
	 *
1673
	 * @return array
1674
	 */
1675
	public function get_collection_params() {
1676
		$params = parent::get_collection_params();
1677
1678
		$params['status']   = array(
1679
			'default'           => 'any',
1680
			'description'       => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ),
1681
			'type'              => 'string',
1682
			'enum'              => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ),
1683
			'sanitize_callback' => 'sanitize_key',
1684
			'validate_callback' => 'rest_validate_request_arg',
1685
		);
1686
		$params['customer'] = array(
1687
			'description'       => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ),
1688
			'type'              => 'integer',
1689
			'sanitize_callback' => 'absint',
1690
			'validate_callback' => 'rest_validate_request_arg',
1691
		);
1692
		$params['product']  = array(
1693
			'description'       => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ),
1694
			'type'              => 'integer',
1695
			'sanitize_callback' => 'absint',
1696
			'validate_callback' => 'rest_validate_request_arg',
1697
		);
1698
		$params['dp']       = array(
1699
			'default'           => wc_get_price_decimals(),
1700
			'description'       => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
1701
			'type'              => 'integer',
1702
			'sanitize_callback' => 'absint',
1703
			'validate_callback' => 'rest_validate_request_arg',
1704
		);
1705
1706
		return $params;
1707
	}
1708
}
1709