Completed
Pull Request — master (#11785)
by Mike
09:49
created

WC_REST_Coupons_Controller   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 489
Duplicated Lines 29.45 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 7
Bugs 2 Features 1
Metric Value
dl 144
loc 489
rs 8.3999
c 7
b 2
f 1
wmc 38
lcom 1
cbo 4

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A register_routes() 60 60 1
B create_item() 31 31 3
A query_args() 0 10 2
B prepare_item_for_response() 3 35 5
A filter_writable_props() 0 3 1
C prepare_item_for_database() 7 69 15
B update_item() 32 32 5
A save_coupon() 0 11 3
B get_item_schema() 0 135 1
A get_collection_params() 10 10 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * REST API Coupons controller
4
 *
5
 * Handles requests to the /coupons endpoint.
6
 *
7
 * @author   WooThemes
8
 * @category API
9
 * @package  WooCommerce/API
10
 * @since    2.6.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * REST API Coupons controller class.
19
 *
20
 * @package WooCommerce/API
21
 * @extends WC_REST_Posts_Controller
22
 */
23
class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller {
24
25
	/**
26
	 * Endpoint namespace.
27
	 *
28
	 * @var string
29
	 */
30
	protected $namespace = 'wc/v1';
31
32
	/**
33
	 * Route base.
34
	 *
35
	 * @var string
36
	 */
37
	protected $rest_base = 'coupons';
38
39
	/**
40
	 * Post type.
41
	 *
42
	 * @var string
43
	 */
44
	protected $post_type = 'shop_coupon';
45
46
	/**
47
	 * Order refunds actions.
48
	 */
49
	public function __construct() {
50
		add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 );
51
	}
52
53
	/**
54
	 * Register the routes for coupons.
55
	 */
56 View Code Duplication
	public function register_routes() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
57
		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
58
			array(
59
				'methods'             => WP_REST_Server::READABLE,
60
				'callback'            => array( $this, 'get_items' ),
61
				'permission_callback' => array( $this, 'get_items_permissions_check' ),
62
				'args'                => $this->get_collection_params(),
63
			),
64
			array(
65
				'methods'             => WP_REST_Server::CREATABLE,
66
				'callback'            => array( $this, 'create_item' ),
67
				'permission_callback' => array( $this, 'create_item_permissions_check' ),
68
				'args'                => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
69
					'code' => array(
70
						'required' => true,
71
					),
72
				) ),
73
			),
74
			'schema' => array( $this, 'get_public_item_schema' ),
75
		) );
76
77
		register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
78
			array(
79
				'methods'             => WP_REST_Server::READABLE,
80
				'callback'            => array( $this, 'get_item' ),
81
				'permission_callback' => array( $this, 'get_item_permissions_check' ),
82
				'args'                => array(
83
					'context'         => $this->get_context_param( array( 'default' => 'view' ) ),
84
				),
85
			),
86
			array(
87
				'methods'         => WP_REST_Server::EDITABLE,
88
				'callback'        => array( $this, 'update_item' ),
89
				'permission_callback' => array( $this, 'update_item_permissions_check' ),
90
				'args'            => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
91
			),
92
			array(
93
				'methods'             => WP_REST_Server::DELETABLE,
94
				'callback'            => array( $this, 'delete_item' ),
95
				'permission_callback' => array( $this, 'delete_item_permissions_check' ),
96
				'args'                => array(
97
					'force' => array(
98
						'default'     => false,
99
						'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
100
					),
101
				),
102
			),
103
			'schema' => array( $this, 'get_public_item_schema' ),
104
		) );
105
106
		register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array(
107
			array(
108
				'methods'             => WP_REST_Server::EDITABLE,
109
				'callback'            => array( $this, 'batch_items' ),
110
				'permission_callback' => array( $this, 'batch_items_permissions_check' ),
111
				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
112
			),
113
			'schema' => array( $this, 'get_public_batch_schema' ),
114
		) );
115
	}
116
117
	/**
118
	 * Query args.
119
	 *
120
	 * @param array $args
121
	 * @param WP_REST_Request $request
122
	 * @return array
123
	 */
124
	public function query_args( $args, $request ) {
125
		global $wpdb;
126
127
		if ( ! empty( $request['code'] ) ) {
128
			$id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $request['code'] ) );
129
			$args['post__in'] = array( $id );
130
		}
131
132
		return $args;
133
	}
134
135
	/**
136
	 * Prepare a single coupon output for response.
137
	 *
138
	 * @param WP_Post $post Post object.
139
	 * @param WP_REST_Request $request Request object.
140
	 * @return WP_REST_Response $data
141
	 */
142
	public function prepare_item_for_response( $post, $request ) {
143
		$code           = wc_get_coupon_code_by_id( $post->ID );
144
		$coupon         = new WC_Coupon( $code );
145
		$data           = $coupon->get_data();
146
		$format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' );
147
		$format_date    = array( 'date_created', 'date_modified', 'date_expires' );
148
149
		// Format decimal values.
150
		foreach ( $format_decimal as $key ) {
151
			$data[ $key ] = wc_format_decimal( $data[ $key ], 2 );
152
		}
153
154
		// Format date values.
155 View Code Duplication
		foreach ( $format_date as $key ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
			$data[ $key ] = $data[ $key ] ? wc_rest_prepare_date_response( get_gmt_from_date( date( 'Y-m-d H:i:s', $data[ $key ] ) ) ) : false;
157
		}
158
159
		$context  = ! empty( $request['context'] ) ? $request['context'] : 'view';
160
		$data     = $this->add_additional_fields_to_object( $data, $request );
161
		$data     = $this->filter_response_by_context( $data, $context );
162
		$response = rest_ensure_response( $data );
163
		$response->add_links( $this->prepare_links( $post ) );
164
165
		/**
166
		 * Filter the data for a response.
167
		 *
168
		 * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
169
		 * prepared for the response.
170
		 *
171
		 * @param WP_REST_Response   $response   The response object.
172
		 * @param WP_Post            $post       Post object.
173
		 * @param WP_REST_Request    $request    Request object.
174
		 */
175
		return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request );
176
	}
177
178
	/**
179
	 * Only reutrn writeable props from schema.
180
	 * @param  array $schema
181
	 * @return bool
182
	 */
183
	protected function filter_writable_props( $schema ) {
184
		return empty( $schema['readonly'] );
185
	}
186
187
	/**
188
	 * Prepare a single coupon for create or update.
189
	 *
190
	 * @param WP_REST_Request $request Request object.
191
	 * @return WP_Error|stdClass $data Post object.
192
	 */
193
	protected function prepare_item_for_database( $request ) {
194
		$id        = isset( $request['id'] ) ? absint( $request['id'] ) : 0;
195
		$coupon    = new WC_Coupon( $id );
196
		$schema    = $this->get_item_schema();
197
		$data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) );
198
199
		// Validate required POST fields.
200
		if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) {
201
			if ( empty( $request['code'] ) ) {
202
				return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) );
203
			}
204
		}
205
206
		// Handle all writable props
207
		foreach ( $data_keys as $key ) {
208
			$value = $request[ $key ];
209
210
			if ( ! is_null( $value ) ) {
211
				switch ( $key ) {
212
					case 'code' :
213
						$coupon_code = apply_filters( 'woocommerce_coupon_code', $value );
214
						$id          = $coupon->get_id() ? $coupon->get_id() : 0;
215
216
						// Check for duplicate coupon codes.
217
						$coupon_found = $wpdb->get_var( $wpdb->prepare( "
218
							SELECT $wpdb->posts.ID
219
							FROM $wpdb->posts
220
							WHERE $wpdb->posts.post_type = 'shop_coupon'
221
							AND $wpdb->posts.post_status = 'publish'
222
							AND $wpdb->posts.post_title = %s
223
							AND $wpdb->posts.ID != %s
224
						 ", $coupon_code, $id ) );
225
226
						if ( $coupon_found ) {
227
							return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) );
228
						}
229
230
						$coupon->set_code( $coupon_code );
231
						break;
232 View Code Duplication
					case 'meta_data' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
233
						if ( is_array( $value ) ) {
234
							foreach ( $value as $meta ) {
235
								$coupon->update_meta_data( $meta['key'], $meta['value'], $meta['id'] );
236
							}
237
						}
238
						break;
239
					case 'description' :
240
						$coupon->set_description( wp_filter_post_kses( $value ) );
241
						break;
242
					default :
243
						if ( is_callable( array( $coupon, "set_{$key}" ) ) ) {
244
							$coupon->{"set_{$key}"}( $value );
245
						}
246
						break;
247
				}
248
			}
249
		}
250
251
		/**
252
		 * Filter the query_vars used in `get_items` for the constructed query.
253
		 *
254
		 * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
255
		 * prepared for insertion.
256
		 *
257
		 * @param WC_Coupon       $coupon        The coupon object.
258
		 * @param WP_REST_Request $request       Request object.
259
		 */
260
		return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request );
261
	}
262
263
	/**
264
	 * Create a single item.
265
	 *
266
	 * @param WP_REST_Request $request Full details about the request.
267
	 * @return WP_Error|WP_REST_Response
268
	 */
269 View Code Duplication
	public function create_item( $request ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
		if ( ! empty( $request['id'] ) ) {
271
			return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) );
272
		}
273
274
		$coupon_id = $this->save_coupon( $request );
275
		if ( is_wp_error( $coupon_id ) ) {
276
			return $coupon_id;
277
		}
278
279
		$post = get_post( $coupon_id );
280
		$this->update_additional_fields_for_object( $post, $request );
281
282
		$this->add_post_meta_fields( $post, $request );
0 ignored issues
show
Unused Code introduced by
The call to the method WC_REST_Coupons_Controller::add_post_meta_fields() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
283
284
		/**
285
		 * Fires after a single item is created or updated via the REST API.
286
		 *
287
		 * @param object          $post      Inserted object (not a WP_Post object).
288
		 * @param WP_REST_Request $request   Request object.
289
		 * @param boolean         $creating  True when creating item, false when updating.
290
		 */
291
		do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true );
292
		$request->set_param( 'context', 'edit' );
293
		$response = $this->prepare_item_for_response( $post, $request );
294
		$response = rest_ensure_response( $response );
295
		$response->set_status( 201 );
296
		$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) );
297
298
		return $response;
299
	}
300
301
	/**
302
	 * Update a single coupon.
303
	 *
304
	 * @param WP_REST_Request $request Full details about the request.
305
	 * @return WP_Error|WP_REST_Response
306
	 */
307 View Code Duplication
	public function update_item( $request ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
		try {
309
			$post_id = (int) $request['id'];
310
311
			if ( empty( $post_id ) || $this->post_type !== get_post_type( $post_id ) ) {
312
				return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) );
313
			}
314
315
			$coupon_id = $this->save_coupon( $request );
316
			if ( is_wp_error( $coupon_id ) ) {
317
				return $coupon_id;
318
			}
319
320
			$post = get_post( $coupon_id );
321
			$this->update_additional_fields_for_object( $post, $request );
322
323
			/**
324
			 * Fires after a single item is created or updated via the REST API.
325
			 *
326
			 * @param object          $post      Inserted object (not a WP_Post object).
327
			 * @param WP_REST_Request $request   Request object.
328
			 * @param boolean         $creating  True when creating item, false when updating.
329
			 */
330
			do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false );
331
			$request->set_param( 'context', 'edit' );
332
			$response = $this->prepare_item_for_response( $post, $request );
333
			return rest_ensure_response( $response );
334
335
		} catch ( Exception $e ) {
336
			return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Exception as the method getErrorCode() does only exist in the following sub-classes of Exception: WC_CLI_Exception, WC_Data_Exception, WC_REST_Exception. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
337
		}
338
	}
339
340
	/**
341
	 * Saves a coupon to the database.
342
	 */
343
	public function save_coupon( $request ) {
344
		try {
345
			$coupon = $this->prepare_item_for_database( $request );
346
			$coupon->save();
347
			return $coupon->get_id();
348
		} catch ( WC_Data_Exception $e ) {
349
			return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
350
		} catch ( WC_REST_Exception $e ) {
351
			return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
352
		}
353
	}
354
355
	/**
356
	 * Get the Coupon's schema, conforming to JSON Schema.
357
	 *
358
	 * @return array
359
	 */
360
	public function get_item_schema() {
361
		$schema = array(
362
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
363
			'title'      => $this->post_type,
364
			'type'       => 'object',
365
			'properties' => array(
366
				'id' => array(
367
					'description' => __( 'Unique identifier for the object.', 'woocommerce' ),
368
					'type'        => 'integer',
369
					'context'     => array( 'view', 'edit' ),
370
					'readonly'    => true,
371
				),
372
				'code' => array(
373
					'description' => __( 'Coupon code.', 'woocommerce' ),
374
					'type'        => 'string',
375
					'context'     => array( 'view', 'edit' ),
376
				),
377
				'date_created' => array(
378
					'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ),
379
					'type'        => 'date-time',
380
					'context'     => array( 'view', 'edit' ),
381
					'readonly'    => true,
382
				),
383
				'date_modified' => array(
384
					'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ),
385
					'type'        => 'date-time',
386
					'context'     => array( 'view', 'edit' ),
387
					'readonly'    => true,
388
				),
389
				'description' => array(
390
					'description' => __( 'Coupon description.', 'woocommerce' ),
391
					'type'        => 'string',
392
					'context'     => array( 'view', 'edit' ),
393
				),
394
				'discount_type' => array(
395
					'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ),
396
					'type'        => 'string',
397
					'default'     => 'fixed_cart',
398
					'enum'        => array_keys( wc_get_coupon_types() ),
399
					'context'     => array( 'view', 'edit' ),
400
				),
401
				'amount' => array(
402
					'description' => __( 'The amount of discount.', 'woocommerce' ),
403
					'type'        => 'string',
404
					'context'     => array( 'view', 'edit' ),
405
				),
406
				'date_expires' => array(
407
					'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce' ),
408
					'type'        => 'string',
409
					'context'     => array( 'view', 'edit' ),
410
				),
411
				'usage_count' => array(
412
					'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ),
413
					'type'        => 'integer',
414
					'context'     => array( 'view', 'edit' ),
415
					'readonly'    => true,
416
				),
417
				'individual_use' => array(
418
					'description' => __( 'Whether coupon can only be used individually.', 'woocommerce' ),
419
					'type'        => 'boolean',
420
					'default'     => false,
421
					'context'     => array( 'view', 'edit' ),
422
				),
423
				'product_ids' => array(
424
					'description' => __( "List of product ID's the coupon can be used on.", 'woocommerce' ),
425
					'type'        => 'array',
426
					'context'     => array( 'view', 'edit' ),
427
				),
428
				'exclude_product_ids' => array(
429
					'description' => __( "List of product ID's the coupon cannot be used on.", 'woocommerce' ),
430
					'type'        => 'array',
431
					'context'     => array( 'view', 'edit' ),
432
				),
433
				'usage_limit' => array(
434
					'description' => __( 'How many times the coupon can be used.', 'woocommerce' ),
435
					'type'        => 'integer',
436
					'context'     => array( 'view', 'edit' ),
437
				),
438
				'usage_limit_per_user' => array(
439
					'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ),
440
					'type'        => 'integer',
441
					'context'     => array( 'view', 'edit' ),
442
				),
443
				'limit_usage_to_x_items' => array(
444
					'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ),
445
					'type'        => 'integer',
446
					'context'     => array( 'view', 'edit' ),
447
				),
448
				'free_shipping' => array(
449
					'description' => __( 'Define if can be applied for free shipping.', 'woocommerce' ),
450
					'type'        => 'boolean',
451
					'default'     => false,
452
					'context'     => array( 'view', 'edit' ),
453
				),
454
				'product_categories' => array(
455
					'description' => __( "List of category ID's the coupon applies to.", 'woocommerce' ),
456
					'type'        => 'array',
457
					'context'     => array( 'view', 'edit' ),
458
				),
459
				'excluded_product_categories' => array(
460
					'description' => __( "List of category ID's the coupon does not apply to.", 'woocommerce' ),
461
					'type'        => 'array',
462
					'context'     => array( 'view', 'edit' ),
463
				),
464
				'exclude_sale_items' => array(
465
					'description' => __( 'Define if should not apply when have sale items.', 'woocommerce' ),
466
					'type'        => 'boolean',
467
					'default'     => false,
468
					'context'     => array( 'view', 'edit' ),
469
				),
470
				'minimum_amount' => array(
471
					'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ),
472
					'type'        => 'string',
473
					'context'     => array( 'view', 'edit' ),
474
				),
475
				'maximum_amount' => array(
476
					'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ),
477
					'type'        => 'string',
478
					'context'     => array( 'view', 'edit' ),
479
				),
480
				'email_restrictions' => array(
481
					'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ),
482
					'type'        => 'array',
483
					'context'     => array( 'view', 'edit' ),
484
				),
485
				'used_by' => array(
486
					'description' => __( 'List of user IDs who have used the coupon.', 'woocommerce' ),
487
					'type'        => 'array',
488
					'context'     => array( 'view', 'edit' ),
489
					'readonly'    => true,
490
				),
491
			),
492
		);
493
		return $this->add_additional_fields_schema( $schema );
494
	}
495
496
	/**
497
	 * Get the query params for collections of attachments.
498
	 *
499
	 * @return array
500
	 */
501 View Code Duplication
	public function get_collection_params() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
502
		$params = parent::get_collection_params();
503
		$params['code'] = array(
504
			'description'       => __( 'Limit result set to resources with a specific code.', 'woocommerce' ),
505
			'type'              => 'string',
506
			'sanitize_callback' => 'sanitize_text_field',
507
			'validate_callback' => 'rest_validate_request_arg',
508
		);
509
		return $params;
510
	}
511
}
512