Passed
Push — master ( 5bd17a...71a32c )
by Mike
04:53
created

Taxes::get_data_for_response()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 25
nc 4
nop 2
dl 0
loc 37
rs 9.2088
c 0
b 0
f 0
1
<?php
2
/**
3
 * REST API Taxes controller
4
 *
5
 * Handles requests to the /taxes endpoint.
6
 *
7
 * @package WooCommerce/RestApi
8
 */
9
10
namespace WooCommerce\RestApi\Controllers\Version4;
11
12
defined( 'ABSPATH' ) || exit;
13
14
/**
15
 * REST API Taxes controller class.
16
 */
17
class Taxes extends AbstractController {
18
19
	/**
20
	 * Route base.
21
	 *
22
	 * @var string
23
	 */
24
	protected $rest_base = 'taxes';
25
26
	/**
27
	 * Permission to check.
28
	 *
29
	 * @var string
30
	 */
31
	protected $resource_type = 'settings';
32
33
	/**
34
	 * Register the routes for taxes.
35
	 */
36
	public function register_routes() {
37
		register_rest_route(
38
			$this->namespace,
39
			'/' . $this->rest_base,
40
			array(
41
				array(
42
					'methods'             => \WP_REST_Server::READABLE,
43
					'callback'            => array( $this, 'get_items' ),
44
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
45
					'args'                => $this->get_collection_params(),
46
				),
47
				array(
48
					'methods'             => \WP_REST_Server::CREATABLE,
49
					'callback'            => array( $this, 'create_item' ),
50
					'permission_callback' => array( $this, 'create_item_permissions_check' ),
51
					'args'                => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ),
52
				),
53
				'schema' => array( $this, 'get_public_item_schema' ),
54
			),
55
			true
56
		);
57
58
		register_rest_route(
59
			$this->namespace,
60
			'/' . $this->rest_base . '/(?P<id>[\d]+)',
61
			array(
62
				'args' => array(
63
					'id' => array(
64
						'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
65
						'type'        => 'integer',
66
					),
67
				),
68
				array(
69
					'methods'             => \WP_REST_Server::READABLE,
70
					'callback'            => array( $this, 'get_item' ),
71
					'permission_callback' => array( $this, 'get_item_permissions_check' ),
72
					'args'                => array(
73
						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
74
					),
75
				),
76
				array(
77
					'methods'             => \WP_REST_Server::EDITABLE,
78
					'callback'            => array( $this, 'update_item' ),
79
					'permission_callback' => array( $this, 'update_item_permissions_check' ),
80
					'args'                => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
81
				),
82
				array(
83
					'methods'             => \WP_REST_Server::DELETABLE,
84
					'callback'            => array( $this, 'delete_item' ),
85
					'permission_callback' => array( $this, 'delete_item_permissions_check' ),
86
					'args'                => array(
87
						'force' => array(
88
							'default'     => false,
89
							'type'        => 'boolean',
90
							'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ),
91
						),
92
					),
93
				),
94
				'schema' => array( $this, 'get_public_item_schema' ),
95
			),
96
			true
97
		);
98
99
		$this->register_batch_route();
100
	}
101
102
	/**
103
	 * Get all taxes and allow filtering by tax code.
104
	 *
105
	 * @param \WP_REST_Request $request Full details about the request.
106
	 * @return \WP_Error|\WP_REST_Response
107
	 */
108
	public function get_items( $request ) {
109
		global $wpdb;
110
111
		$prepared_args           = array();
112
		$prepared_args['order']  = $request['order'];
113
		$prepared_args['number'] = $request['per_page'];
114
		if ( ! empty( $request['offset'] ) ) {
115
			$prepared_args['offset'] = $request['offset'];
116
		} else {
117
			$prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
118
		}
119
		$orderby_possibles        = array(
120
			'id'    => 'tax_rate_id',
121
			'order' => 'tax_rate_order',
122
		);
123
		$prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ];
124
		$prepared_args['class']   = $request['class'];
125
		$prepared_args['code']    = $request['code'];
126
		$prepared_args['include'] = $request['include'];
127
128
		/**
129
		 * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API.
130
		 *
131
		 * @param array           $prepared_args Array of arguments for $wpdb->get_results().
132
		 * @param \WP_REST_Request $request       The current request.
133
		 */
134
		$prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request );
135
136
		$query = "
137
			SELECT *
138
			FROM {$wpdb->prefix}woocommerce_tax_rates
139
			WHERE 1 = 1
140
		";
141
142
		// Filter by tax class.
143
		if ( ! empty( $prepared_args['class'] ) ) {
144
			$class  = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : '';
145
			$query .= " AND tax_rate_class = '$class'";
146
		}
147
148
		// Filter by tax code.
149
		$tax_code_search = $prepared_args['code'];
150
		if ( $tax_code_search ) {
151
			$tax_code_search = $wpdb->esc_like( $tax_code_search );
152
			$tax_code_search = ' \'%' . $tax_code_search . '%\'';
153
			$query          .= ' AND CONCAT_WS( "-", NULLIF(tax_rate_country, ""), NULLIF(tax_rate_state, ""), NULLIF(tax_rate_name, ""), NULLIF(tax_rate_priority, "") ) LIKE ' . $tax_code_search;
154
		}
155
156
		// Filter by included tax rate IDs.
157
		$included_taxes = $prepared_args['include'];
158
		if ( ! empty( $included_taxes ) ) {
159
			$included_taxes = implode( ',', $prepared_args['include'] );
160
			$query         .= " AND tax_rate_id IN ({$included_taxes})";
161
		}
162
163
		// Order tax rates.
164
		$order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) );
165
166
		// Pagination.
167
		$pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] );
168
169
		// Query taxes.
170
		$results = $wpdb->get_results( $query . $order_by . $pagination ); // @codingStandardsIgnoreLine.
171
172
		$taxes = array();
173
		foreach ( $results as $tax ) {
174
			$data    = $this->prepare_item_for_response( $tax, $request );
175
			$taxes[] = $this->prepare_response_for_collection( $data );
176
		}
177
178
		$response = rest_ensure_response( $taxes );
179
180
		// Store pagination values for headers then unset for count query.
181
		$per_page = (int) $prepared_args['number'];
182
		$page     = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
183
184
		// Query only for ids.
185
		$wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); // @codingStandardsIgnoreLine.
186
187
		// Calculate totals.
188
		$total_taxes = (int) $wpdb->num_rows;
189
		$response->header( 'X-WP-Total', (int) $total_taxes );
190
		$max_pages = ceil( $total_taxes / $per_page );
191
		$response->header( 'X-WP-TotalPages', (int) $max_pages );
192
193
		$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
194
		if ( $page > 1 ) {
195
			$prev_page = $page - 1;
196
			if ( $prev_page > $max_pages ) {
197
				$prev_page = $max_pages;
198
			}
199
			$prev_link = add_query_arg( 'page', $prev_page, $base );
200
			$response->link_header( 'prev', $prev_link );
201
		}
202
		if ( $max_pages > $page ) {
203
			$next_page = $page + 1;
204
			$next_link = add_query_arg( 'page', $next_page, $base );
205
			$response->link_header( 'next', $next_link );
206
		}
207
208
		return $response;
209
	}
210
211
	/**
212
	 * Take tax data from the request and return the updated or newly created rate.
213
	 *
214
	 * @param \WP_REST_Request $request Full details about the request.
215
	 * @param \stdClass|null   $current Existing tax object.
216
	 * @return object
217
	 */
218
	protected function create_or_update_tax( $request, $current = null ) {
219
		$id          = absint( isset( $request['id'] ) ? $request['id'] : 0 );
220
		$data        = array();
221
		$fields      = array(
222
			'tax_rate_country',
223
			'tax_rate_state',
224
			'tax_rate',
225
			'tax_rate_name',
226
			'tax_rate_priority',
227
			'tax_rate_compound',
228
			'tax_rate_shipping',
229
			'tax_rate_order',
230
			'tax_rate_class',
231
		);
232
233
		foreach ( $fields as $field ) {
234
			// Keys via API differ from the stored names returned by _get_tax_rate.
235
			$key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field );
236
237
			// Remove data that was not posted.
238
			if ( ! isset( $request[ $key ] ) ) {
239
				continue;
240
			}
241
242
			// Test new data against current data.
243
			if ( $current && $current->$field === $request[ $key ] ) {
244
				continue;
245
			}
246
247
			// Add to data array.
248
			switch ( $key ) {
249
				case 'tax_rate_priority':
250
				case 'tax_rate_compound':
251
				case 'tax_rate_shipping':
252
				case 'tax_rate_order':
253
					$data[ $field ] = absint( $request[ $key ] );
254
					break;
255
				case 'tax_rate_class':
256
					$data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : '';
257
					break;
258
				default:
259
					$data[ $field ] = wc_clean( $request[ $key ] );
260
					break;
261
			}
262
		}
263
264
		if ( $id ) {
265
			\WC_Tax::_update_tax_rate( $id, $data );
266
		} else {
267
			$id = \WC_Tax::_insert_tax_rate( $data );
268
		}
269
270
		// Add locales.
271
		if ( ! empty( $request['postcode'] ) ) {
272
			\WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) );
0 ignored issues
show
Bug introduced by
It seems like wc_clean($request['postcode']) can also be of type array; however, parameter $postcodes of WC_Tax::_update_tax_rate_postcodes() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

272
			\WC_Tax::_update_tax_rate_postcodes( $id, /** @scrutinizer ignore-type */ wc_clean( $request['postcode'] ) );
Loading history...
273
		}
274
		if ( ! empty( $request['city'] ) ) {
275
			\WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) );
0 ignored issues
show
Bug introduced by
It seems like wc_clean($request['city']) can also be of type array; however, parameter $cities of WC_Tax::_update_tax_rate_cities() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

275
			\WC_Tax::_update_tax_rate_cities( $id, /** @scrutinizer ignore-type */ wc_clean( $request['city'] ) );
Loading history...
276
		}
277
278
		return \WC_Tax::_get_tax_rate( $id, OBJECT );
279
	}
280
281
	/**
282
	 * Create a single tax.
283
	 *
284
	 * @param \WP_REST_Request $request Full details about the request.
285
	 * @return \WP_Error|\WP_REST_Response
286
	 */
287
	public function create_item( $request ) {
288
		if ( ! empty( $request['id'] ) ) {
289
			return new \WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) );
290
		}
291
292
		$tax = $this->create_or_update_tax( $request );
293
294
		$this->update_additional_fields_for_object( $tax, $request );
0 ignored issues
show
Bug introduced by
$tax of type object is incompatible with the type array expected by parameter $object of WP_REST_Controller::upda...nal_fields_for_object(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

294
		$this->update_additional_fields_for_object( /** @scrutinizer ignore-type */ $tax, $request );
Loading history...
295
296
		/**
297
		 * Fires after a tax is created or updated via the REST API.
298
		 *
299
		 * @param \stdClass        $tax       Data used to create the tax.
300
		 * @param \WP_REST_Request $request   Request object.
301
		 * @param boolean         $creating  True when creating tax, false when updating tax.
302
		 */
303
		do_action( 'woocommerce_rest_insert_tax', $tax, $request, true );
304
305
		$request->set_param( 'context', 'edit' );
306
		$response = $this->prepare_item_for_response( $tax, $request );
307
		$response = rest_ensure_response( $response );
308
		$response->set_status( 201 );
309
		$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) );
310
311
		return $response;
312
	}
313
314
	/**
315
	 * Get a single tax.
316
	 *
317
	 * @param \WP_REST_Request $request Full details about the request.
318
	 * @return \WP_Error|\WP_REST_Response
319
	 */
320
	public function get_item( $request ) {
321
		$id      = (int) $request['id'];
322
		$tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT );
323
324
		if ( empty( $id ) || empty( $tax_obj ) ) {
325
			return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) );
326
		}
327
328
		$tax      = $this->prepare_item_for_response( $tax_obj, $request );
329
		$response = rest_ensure_response( $tax );
330
331
		return $response;
332
	}
333
334
	/**
335
	 * Update a single tax.
336
	 *
337
	 * @param \WP_REST_Request $request Full details about the request.
338
	 * @return \WP_Error|\WP_REST_Response
339
	 */
340
	public function update_item( $request ) {
341
		$id      = (int) $request['id'];
342
		$tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT );
343
344
		if ( empty( $id ) || empty( $tax_obj ) ) {
345
			return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) );
346
		}
347
348
		$tax = $this->create_or_update_tax( $request, $tax_obj );
0 ignored issues
show
Bug introduced by
It seems like $tax_obj can also be of type array; however, parameter $current of WooCommerce\RestApi\Cont...:create_or_update_tax() does only seem to accept null|stdClass, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

348
		$tax = $this->create_or_update_tax( $request, /** @scrutinizer ignore-type */ $tax_obj );
Loading history...
349
350
		$this->update_additional_fields_for_object( $tax, $request );
0 ignored issues
show
Bug introduced by
$tax of type object is incompatible with the type array expected by parameter $object of WP_REST_Controller::upda...nal_fields_for_object(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

350
		$this->update_additional_fields_for_object( /** @scrutinizer ignore-type */ $tax, $request );
Loading history...
351
352
		/**
353
		 * Fires after a tax is created or updated via the REST API.
354
		 *
355
		 * @param \stdClass        $tax       Data used to create the tax.
356
		 * @param \WP_REST_Request $request   Request object.
357
		 * @param boolean         $creating  True when creating tax, false when updating tax.
358
		 */
359
		do_action( 'woocommerce_rest_insert_tax', $tax, $request, false );
360
361
		$request->set_param( 'context', 'edit' );
362
		$response = $this->prepare_item_for_response( $tax, $request );
363
		$response = rest_ensure_response( $response );
364
365
		return $response;
366
	}
367
368
	/**
369
	 * Delete a single tax.
370
	 *
371
	 * @param \WP_REST_Request $request Full details about the request.
372
	 * @return \WP_Error|\WP_REST_Response
373
	 */
374
	public function delete_item( $request ) {
375
		global $wpdb;
376
377
		$id    = (int) $request['id'];
378
		$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
379
380
		// We don't support trashing for this type, error out.
381
		if ( ! $force ) {
382
			return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) );
383
		}
384
385
		$tax = \WC_Tax::_get_tax_rate( $id, OBJECT );
386
387
		if ( empty( $id ) || empty( $tax ) ) {
388
			return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) );
389
		}
390
391
		$request->set_param( 'context', 'edit' );
392
		$response = $this->prepare_item_for_response( $tax, $request );
393
394
		\WC_Tax::_delete_tax_rate( $id );
395
396
		if ( 0 === $wpdb->rows_affected ) {
397
			return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) );
398
		}
399
400
		/**
401
		 * Fires after a tax is deleted via the REST API.
402
		 *
403
		 * @param \stdClass         $tax      The tax data.
404
		 * @param \WP_REST_Response $response The response returned from the API.
405
		 * @param \WP_REST_Request  $request  The request sent to the API.
406
		 */
407
		do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request );
408
409
		return $response;
410
	}
411
412
	/**
413
	 * Get data for this object in the format of this endpoint's schema.
414
	 *
415
	 * @param \stdClass        $object Object to prepare.
416
	 * @param \WP_REST_Request $request Request object.
417
	 * @return array Array of data in the correct format.
418
	 */
419
	protected function get_data_for_response( $object, $request ) {
420
		global $wpdb;
421
422
		$id   = (int) $object->tax_rate_id;
423
		$data = array(
424
			'id'       => $id,
425
			'country'  => $object->tax_rate_country,
426
			'state'    => $object->tax_rate_state,
427
			'postcode' => '',
428
			'city'     => '',
429
			'rate'     => $object->tax_rate,
430
			'name'     => $object->tax_rate_name,
431
			'priority' => (int) $object->tax_rate_priority,
432
			'compound' => (bool) $object->tax_rate_compound,
433
			'shipping' => (bool) $object->tax_rate_shipping,
434
			'order'    => (int) $object->tax_rate_order,
435
			'class'    => $object->tax_rate_class ? $object->tax_rate_class : 'standard',
436
		);
437
438
		// Get locales from a tax rate.
439
		$locales = $wpdb->get_results(
440
			$wpdb->prepare(
441
				"
442
				SELECT location_code, location_type
443
				FROM {$wpdb->prefix}woocommerce_tax_rate_locations
444
				WHERE tax_rate_id = %d
445
				",
446
				$id
447
			)
448
		);
449
450
		if ( ! is_wp_error( $locales ) && ! is_null( $locales ) ) {
451
			foreach ( $locales as $locale ) {
452
				$data[ $locale->location_type ] = $locale->location_code;
453
			}
454
		}
455
		return $data;
456
	}
457
458
	/**
459
	 * Prepare links for the request.
460
	 *
461
	 * @param mixed            $item Object to prepare.
462
	 * @param \WP_REST_Request $request Request object.
463
	 * @return array
464
	 */
465
	protected function prepare_links( $item, $request ) {
466
		$links = array(
467
			'self' => array(
468
				'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->tax_rate_id ) ),
469
			),
470
			'collection' => array(
471
				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
472
			),
473
		);
474
475
		return $links;
476
	}
477
478
	/**
479
	 * Get the Taxes schema, conforming to JSON Schema.
480
	 *
481
	 * @return array
482
	 */
483
	public function get_item_schema() {
484
		$schema = array(
485
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
486
			'title'      => 'tax',
487
			'type'       => 'object',
488
			'properties' => array(
489
				'id' => array(
490
					'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
491
					'type'        => 'integer',
492
					'context'     => array( 'view', 'edit' ),
493
					'readonly'    => true,
494
				),
495
				'country' => array(
496
					'description' => __( 'Country ISO 3166 code.', 'woocommerce' ),
497
					'type'        => 'string',
498
					'context'     => array( 'view', 'edit' ),
499
				),
500
				'state' => array(
501
					'description' => __( 'State code.', 'woocommerce' ),
502
					'type'        => 'string',
503
					'context'     => array( 'view', 'edit' ),
504
				),
505
				'postcode' => array(
506
					'description' => __( 'Postcode / ZIP.', 'woocommerce' ),
507
					'type'        => 'string',
508
					'context'     => array( 'view', 'edit' ),
509
				),
510
				'city' => array(
511
					'description' => __( 'City name.', 'woocommerce' ),
512
					'type'        => 'string',
513
					'context'     => array( 'view', 'edit' ),
514
				),
515
				'rate' => array(
516
					'description' => __( 'Tax rate.', 'woocommerce' ),
517
					'type'        => 'string',
518
					'context'     => array( 'view', 'edit' ),
519
				),
520
				'name' => array(
521
					'description' => __( 'Tax rate name.', 'woocommerce' ),
522
					'type'        => 'string',
523
					'context'     => array( 'view', 'edit' ),
524
				),
525
				'priority' => array(
526
					'description' => __( 'Tax priority.', 'woocommerce' ),
527
					'type'        => 'integer',
528
					'default'     => 1,
529
					'context'     => array( 'view', 'edit' ),
530
				),
531
				'compound' => array(
532
					'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ),
533
					'type'        => 'boolean',
534
					'default'     => false,
535
					'context'     => array( 'view', 'edit' ),
536
				),
537
				'shipping' => array(
538
					'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ),
539
					'type'        => 'boolean',
540
					'default'     => true,
541
					'context'     => array( 'view', 'edit' ),
542
				),
543
				'order' => array(
544
					'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ),
545
					'type'        => 'integer',
546
					'context'     => array( 'view', 'edit' ),
547
				),
548
				'class' => array(
549
					'description' => __( 'Tax class.', 'woocommerce' ),
550
					'type'        => 'string',
551
					'default'     => 'standard',
552
					'enum'        => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ),
553
					'context'     => array( 'view', 'edit' ),
554
				),
555
			),
556
		);
557
558
		return $this->add_additional_fields_schema( $schema );
559
	}
560
561
	/**
562
	 * Get the query params for collections.
563
	 *
564
	 * @return array
565
	 */
566
	public function get_collection_params() {
567
		$params                       = array();
568
		$params['context']            = $this->get_context_param();
569
		$params['context']['default'] = 'view';
570
571
		$params['page'] = array(
572
			'description'        => __( 'Current page of the collection.', 'woocommerce' ),
573
			'type'               => 'integer',
574
			'default'            => 1,
575
			'sanitize_callback'  => 'absint',
576
			'validate_callback'  => 'rest_validate_request_arg',
577
			'minimum'            => 1,
578
		);
579
		$params['per_page'] = array(
580
			'description'        => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ),
581
			'type'               => 'integer',
582
			'default'            => 10,
583
			'minimum'            => 1,
584
			'maximum'            => 100,
585
			'sanitize_callback'  => 'absint',
586
			'validate_callback'  => 'rest_validate_request_arg',
587
		);
588
		$params['offset'] = array(
589
			'description'        => __( 'Offset the result set by a specific number of items.', 'woocommerce' ),
590
			'type'               => 'integer',
591
			'sanitize_callback'  => 'absint',
592
			'validate_callback'  => 'rest_validate_request_arg',
593
		);
594
		$params['order'] = array(
595
			'default'            => 'asc',
596
			'description'        => __( 'Order sort attribute ascending or descending.', 'woocommerce' ),
597
			'enum'               => array( 'asc', 'desc' ),
598
			'sanitize_callback'  => 'sanitize_key',
599
			'type'               => 'string',
600
			'validate_callback'  => 'rest_validate_request_arg',
601
		);
602
		$params['orderby'] = array(
603
			'default'            => 'order',
604
			'description'        => __( 'Sort collection by object attribute.', 'woocommerce' ),
605
			'enum'               => array(
606
				'id',
607
				'order',
608
			),
609
			'sanitize_callback'  => 'sanitize_key',
610
			'type'               => 'string',
611
			'validate_callback'  => 'rest_validate_request_arg',
612
		);
613
		$params['class'] = array(
614
			'description'        => __( 'Sort by tax class.', 'woocommerce' ),
615
			'enum'               => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ),
616
			'sanitize_callback'  => 'sanitize_title',
617
			'type'               => 'string',
618
			'validate_callback'  => 'rest_validate_request_arg',
619
		);
620
		$params['code']    = array(
621
			'description'       => __( 'Search by similar tax code.', 'woocommerce' ),
622
			'type'              => 'string',
623
			'validate_callback' => 'rest_validate_request_arg',
624
		);
625
		$params['include'] = array(
626
			'description'       => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce' ),
627
			'type'              => 'array',
628
			'items'             => array(
629
				'type' => 'integer',
630
			),
631
			'default'           => array(),
632
			'validate_callback' => 'rest_validate_request_arg',
633
		);
634
635
		return $params;
636
	}
637
}
638