Completed
Push — master ( f47a1d...37f03f )
by Claudio
28:06
created

WC_REST_Terms_Controller::get_collection_params()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 87
Code Lines 68

Duplication

Lines 16
Ratio 18.39 %
Metric Value
dl 16
loc 87
rs 8.4157
nc 8
cc 4
eloc 68
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 15 and the first side effect is on line 4.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	exit;
5
}
6
7
/**
8
 * Abstract Rest Terms Controler Class
9
 *
10
 * @author   WooThemes
11
 * @category API
12
 * @package  WooCommerce/Abstracts
13
 * @version  2.6.0
14
 */
15
abstract class WC_REST_Terms_Controller extends WP_REST_Controller {
16
17
	/**
18
	 * Route base.
19
	 *
20
	 * @var string
21
	 */
22
	protected $rest_base = '';
23
24
	/**
25
	 * Taxonomy.
26
	 *
27
	 * @var string
28
	 */
29
	protected $taxonomy = '';
30
31
	/**
32
	 * Register the routes for terms.
33
	 */
34
	public function register_routes() {
35
		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
36
			array(
37
				'methods'             => WP_REST_Server::READABLE,
38
				'callback'            => array( $this, 'get_items' ),
39
				'permission_callback' => array( $this, 'get_items_permissions_check' ),
40
				'args'                => $this->get_collection_params(),
41
			),
42
			array(
43
				'methods'             => WP_REST_Server::CREATABLE,
44
				'callback'            => array( $this, 'create_item' ),
45
				'permission_callback' => array( $this, 'create_item_permissions_check' ),
46
				'args'                => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
47
					'name' => array(
48
						'required' => true,
49
					),
50
				) ),
51
			),
52
			'schema' => array( $this, 'get_public_item_schema' ),
53
		));
54
55
		register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
56
			array(
57
				'methods'             => WP_REST_Server::READABLE,
58
				'callback'            => array( $this, 'get_item' ),
59
				'permission_callback' => array( $this, 'get_item_permissions_check' ),
60
				'args'                => array(
61
					'context'         => $this->get_context_param( array( 'default' => 'view' ) ),
62
				),
63
			),
64
			array(
65
				'methods'             => WP_REST_Server::EDITABLE,
66
				'callback'            => array( $this, 'update_item' ),
67
				'permission_callback' => array( $this, 'update_item_permissions_check' ),
68
				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
69
			),
70
			array(
71
				'methods'             => WP_REST_Server::DELETABLE,
72
				'callback'            => array( $this, 'delete_item' ),
73
				'permission_callback' => array( $this, 'delete_item_permissions_check' ),
74
				'args'                => array(
75
					'force' => array(
76
						'default'     => false,
77
						'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ),
78
					),
79
				),
80
			),
81
			'schema' => array( $this, 'get_public_item_schema' ),
82
		) );
83
	}
84
85
	/**
86
	 * Check if a given request has access to read the terms.
87
	 *
88
	 * @param  WP_REST_Request $request Full details about the request.
89
	 * @return WP_Error|boolean
90
	 */
91 View Code Duplication
	public function get_items_permissions_check( $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...
92
		$permissions = $this->check_permissions( $request, 'read' );
93
		if ( is_wp_error( $permissions ) ) {
94
			return $permissions;
95
		}
96
97
		if ( ! $permissions ) {
98
			return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
99
		}
100
101
		return true;
102
	}
103
104
	/**
105
	 * Check if a given request has access to create a term.
106
	 *
107
	 * @param  WP_REST_Request $request Full details about the request.
108
	 * @return WP_Error|boolean
109
	 */
110 View Code Duplication
	public function create_item_permissions_check( $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...
111
		$permissions = $this->check_permissions( $request, 'create' );
112
		if ( is_wp_error( $permissions ) ) {
113
			return $permissions;
114
		}
115
116
		if ( ! $permissions ) {
117
			return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
118
		}
119
120
		return true;
121
	}
122
123
	/**
124
	 * Check if a given request has access to read a term.
125
	 *
126
	 * @param  WP_REST_Request $request Full details about the request.
127
	 * @return WP_Error|boolean
128
	 */
129 View Code Duplication
	public function get_item_permissions_check( $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...
130
		$permissions = $this->check_permissions( $request, 'read' );
131
		if ( is_wp_error( $permissions ) ) {
132
			return $permissions;
133
		}
134
135
		if ( ! $permissions ) {
136
			return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
137
		}
138
139
		return true;
140
	}
141
142
	/**
143
	 * Check if a given request has access to update a term.
144
	 *
145
	 * @param  WP_REST_Request $request Full details about the request.
146
	 * @return WP_Error|boolean
147
	 */
148 View Code Duplication
	public function update_item_permissions_check( $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...
149
		$permissions = $this->check_permissions( $request, 'edit' );
150
		if ( is_wp_error( $permissions ) ) {
151
			return $permissions;
152
		}
153
154
		if ( ! $permissions ) {
155
			return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
156
		}
157
158
		return true;
159
	}
160
161
	/**
162
	 * Check if a given request has access to delete a term.
163
	 *
164
	 * @param  WP_REST_Request $request Full details about the request.
165
	 * @return WP_Error|boolean
166
	 */
167 View Code Duplication
	public function delete_item_permissions_check( $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...
168
		$permissions = $this->check_permissions( $request, 'delete' );
169
		if ( is_wp_error( $permissions ) ) {
170
			return $permissions;
171
		}
172
173
		if ( ! $permissions ) {
174
			return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you cannot delete resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
175
		}
176
177
		return true;
178
	}
179
180
	/**
181
	 * Check permissions.
182
	 *
183
	 * @param WP_REST_Request $request Full details about the request.
184
	 * @param string $context Request context.
185
	 * @return bool|WP_Error
186
	 */
187
	protected function check_permissions( $request, $context = 'read' ) {
188
		// Get taxonomy.
189
		$taxonomy = $this->get_taxonomy( $request );
190
		if ( ! $taxonomy ) {
191
			return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( "Taxonomy doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) );
192
		}
193
194
		// Check permissions for a single term.
195
		if ( $id = intval( $request['id'] ) ) {
196
			$term = get_term( $id, $taxonomy );
197
198
			if ( ! $term || $term->taxonomy !== $taxonomy ) {
199
				return new WP_Error( 'woocommerce_rest_term_invalid', __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) );
200
			}
201
202
			return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id );
203
		}
204
205
		return wc_rest_check_product_term_permissions( $taxonomy, $context );
206
	}
207
208
	/**
209
	 * Get terms associated with a taxonomy.
210
	 *
211
	 * @param WP_REST_Request $request Full details about the request.
212
	 * @return WP_REST_Response|WP_Error
213
	 */
214
	public function get_items( $request ) {
215
		$taxonomy      = $this->get_taxonomy( $request );
216
		$prepared_args = array(
217
			'exclude'    => $request['exclude'],
218
			'include'    => $request['include'],
219
			'order'      => $request['order'],
220
			'orderby'    => $request['orderby'],
221
			'product'    => $request['product'],
222
			'hide_empty' => $request['hide_empty'],
223
			'number'     => $request['per_page'],
224
			'search'     => $request['search'],
225
			'slug'       => $request['slug'],
226
		);
227
228 View Code Duplication
		if ( ! empty( $request['offset'] ) ) {
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...
229
			$prepared_args['offset'] = $request['offset'];
230
		} else {
231
			$prepared_args['offset']  = ( $request['page'] - 1 ) * $prepared_args['number'];
232
		}
233
234
		$taxonomy_obj = get_taxonomy( $taxonomy );
235
236
		if ( $taxonomy_obj->hierarchical && isset( $request['parent'] ) ) {
237
			if ( 0 === $request['parent'] ) {
238
				// Only query top-level terms.
239
				$prepared_args['parent'] = 0;
240
			} else {
241
				if ( $request['parent'] ) {
242
					$prepared_args['parent'] = $request['parent'];
243
				}
244
			}
245
		}
246
247
		/**
248
		 * Filter the query arguments, before passing them to `get_terms()`.
249
		 *
250
		 * Enables adding extra arguments or setting defaults for a terms
251
		 * collection request.
252
		 *
253
		 * @see https://developer.wordpress.org/reference/functions/get_terms/
254
		 *
255
		 * @param array           $prepared_args Array of arguments to be
256
		 *                                       passed to get_terms.
257
		 * @param WP_REST_Request $request       The current request.
258
		 */
259
		$prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request );
260
261
		if ( ! empty( $prepared_args['product'] )  ) {
262
			$query_result = $this->get_terms_for_product( $prepared_args );
263
			$total_terms = $this->total_terms;
264
		} else {
265
			$query_result = get_terms( $taxonomy, $prepared_args );
266
267
			$count_args = $prepared_args;
268
			unset( $count_args['number'] );
269
			unset( $count_args['offset'] );
270
			$total_terms = wp_count_terms( $taxonomy, $count_args );
271
272
			// Ensure we don't return results when offset is out of bounds.
273
			// See https://core.trac.wordpress.org/ticket/35935
274
			if ( $prepared_args['offset'] >= $total_terms ) {
275
				$query_result = array();
276
			}
277
278
			// wp_count_terms can return a falsy value when the term has no children.
279
			if ( ! $total_terms ) {
280
				$total_terms = 0;
281
			}
282
		}
283
		$response = array();
284
		foreach ( $query_result as $term ) {
285
			$data = $this->prepare_item_for_response( $term, $request );
286
			$response[] = $this->prepare_response_for_collection( $data );
287
		}
288
289
		$response = rest_ensure_response( $response );
290
291
		// Store pagation values for headers then unset for count query.
292
		$per_page = (int) $prepared_args['number'];
293
		$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
294
295
		$response->header( 'X-WP-Total', (int) $total_terms );
296
		$max_pages = ceil( $total_terms / $per_page );
297
		$response->header( 'X-WP-TotalPages', (int) $max_pages );
298
299
		$base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $this->rest_base ) );
300 View Code Duplication
		if ( $page > 1 ) {
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...
301
			$prev_page = $page - 1;
302
			if ( $prev_page > $max_pages ) {
303
				$prev_page = $max_pages;
304
			}
305
			$prev_link = add_query_arg( 'page', $prev_page, $base );
306
			$response->link_header( 'prev', $prev_link );
307
		}
308 View Code Duplication
		if ( $max_pages > $page ) {
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...
309
			$next_page = $page + 1;
310
			$next_link = add_query_arg( 'page', $next_page, $base );
311
			$response->link_header( 'next', $next_link );
312
		}
313
314
		return $response;
315
	}
316
317
	/**
318
	 * Create a single term for a taxonomy.
319
	 *
320
	 * @param WP_REST_Request $request Full details about the request.
321
	 * @return WP_REST_Request|WP_Error
322
	 */
323
	public function create_item( $request ) {
324
		$taxonomy = $this->get_taxonomy( $request );
325
		$name     = $request['name'];
326
		$args     = array();
327
		$schema   = $this->get_item_schema();
328
329 View Code Duplication
		if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) {
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...
330
			$args['description'] = $request['description'];
331
		}
332
		if ( isset( $request['slug'] ) ) {
333
			$args['slug'] = $request['slug'];
334
		}
335
336 View Code Duplication
		if ( isset( $request['parent'] ) ) {
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...
337
			if ( ! is_taxonomy_hierarchical( $taxonomy ) ) {
338
				return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) );
339
			}
340
341
			$parent = get_term( (int) $request['parent'], $taxonomy );
342
343
			if ( ! $parent ) {
344
				return new WP_Error( 'woocommerce_rest_term_invalid', __( "Parent resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) );
345
			}
346
347
			$args['parent'] = $parent->term_id;
348
		}
349
350
		$term = wp_insert_term( $name, $taxonomy, $args );
351
		if ( is_wp_error( $term ) ) {
352
353
			// If we're going to inform the client that the term exists, give them the identifier
354
			// they can actually use.
355
			if ( ( $term_id = $term->get_error_data( 'term_exists' ) ) ) {
356
				$existing_term = get_term( $term_id, $taxonomy );
357
				$term->add_data( $existing_term->term_id, 'term_exists' );
358
			}
359
360
			return $term;
361
		}
362
363
		$term = get_term( $term['term_id'], $taxonomy );
364
365
		$this->update_additional_fields_for_object( $term, $request );
366
367
		// Add term data.
368
		$meta_fields = $this->update_term_meta_fields( $term, $request );
369
		if ( is_wp_error( $meta_fields ) ) {
370
			return $meta_fields;
371
		}
372
373
		/**
374
		 * Fires after a single term is created or updated via the REST API.
375
		 *
376
		 * @param WP_Term         $term      Inserted Term object.
377
		 * @param WP_REST_Request $request   Request object.
378
		 * @param boolean         $creating  True when creating term, false when updating.
379
		 */
380
		do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true );
381
382
		$request->set_param( 'context', 'edit' );
383
		$response = $this->prepare_item_for_response( $term, $request );
384
		$response = rest_ensure_response( $response );
385
		$response->set_status( 201 );
386
387
		$base = '/' . $this->namespace . '/' . $this->rest_base;
388 View Code Duplication
		if ( ! empty( $request['attribute_id'] ) ) {
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...
389
			$base = str_replace( '(?P<attribute_id>[\d]+)', (int) $request['attribute_id'], $base );
390
		}
391
392
		$response->header( 'Location', rest_url( $base . '/' . $term->term_id ) );
393
394
		return $response;
395
	}
396
397
	/**
398
	 * Get a single term from a taxonomy.
399
	 *
400
	 * @param WP_REST_Request $request Full details about the request.
401
	 * @return WP_REST_Request|WP_Error
402
	 */
403
	public function get_item( $request ) {
404
		$taxonomy = $this->get_taxonomy( $request );
405
		$term     = get_term( (int) $request['id'], $taxonomy );
406
407
		if ( is_wp_error( $term ) ) {
408
			return $term;
409
		}
410
411
		$response = $this->prepare_item_for_response( $term, $request );
412
413
		return rest_ensure_response( $response );
414
	}
415
416
	/**
417
	 * Update a single term from a taxonomy.
418
	 *
419
	 * @param WP_REST_Request $request Full details about the request.
420
	 * @return WP_REST_Request|WP_Error
421
	 */
422
	public function update_item( $request ) {
423
		$taxonomy      = $this->get_taxonomy( $request );
424
		$term          = get_term( (int) $request['id'], $taxonomy );
425
		$schema        = $this->get_item_schema();
426
		$prepared_args = array();
427
428
		if ( isset( $request['name'] ) ) {
429
			$prepared_args['name'] = $request['name'];
430
		}
431 View Code Duplication
		if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) {
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...
432
			$prepared_args['description'] = $request['description'];
433
		}
434
		if ( isset( $request['slug'] ) ) {
435
			$prepared_args['slug'] = $request['slug'];
436
		}
437
438 View Code Duplication
		if ( isset( $request['parent'] ) ) {
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...
439
			if ( ! is_taxonomy_hierarchical( $taxonomy ) ) {
440
				return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) );
441
			}
442
443
			$parent = get_term( (int) $request['parent'], $taxonomy );
444
445
			if ( ! $parent ) {
446
				return new WP_Error( 'woocommerce_rest_term_invalid', __( "Parent resource doesn't exist.", 'woocommerce' ), array( 'status' => 400 ) );
447
			}
448
449
			$prepared_args['parent'] = $parent->term_id;
450
		}
451
452
		// Only update the term if we haz something to update.
453
		if ( ! empty( $prepared_args ) ) {
454
			$update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args );
455
			if ( is_wp_error( $update ) ) {
456
				return $update;
457
			}
458
		}
459
460
		$term = get_term( (int) $request['id'], $taxonomy );
461
462
		$this->update_additional_fields_for_object( $term, $request );
463
464
		// Update term data.
465
		$meta_fields = $this->update_term_meta_fields( $term, $request );
466
		if ( is_wp_error( $meta_fields ) ) {
467
			return $meta_fields;
468
		}
469
470
		/**
471
		 * Fires after a single term is created or updated via the REST API.
472
		 *
473
		 * @param WP_Term         $term      Inserted Term object.
474
		 * @param WP_REST_Request $request   Request object.
475
		 * @param boolean         $creating  True when creating term, false when updating.
476
		 */
477
		do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false );
478
479
		$request->set_param( 'context', 'edit' );
480
		$response = $this->prepare_item_for_response( $term, $request );
481
		return rest_ensure_response( $response );
482
	}
483
484
	/**
485
	 * Delete a single term from a taxonomy.
486
	 *
487
	 * @param WP_REST_Request $request Full details about the request.
488
	 * @return WP_REST_Response|WP_Error
489
	 */
490
	public function delete_item( $request ) {
491
		$taxonomy = $this->get_taxonomy( $request );
492
		$term     = get_term( (int) $request['id'], $taxonomy );
0 ignored issues
show
Unused Code introduced by
$term is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
493
		$force    = isset( $request['force'] ) ? (bool) $request['force'] : false;
494
495
		// We don't support trashing for this type, error out.
496
		if ( ! $force ) {
497
			return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) );
498
		}
499
500
		$term = get_term( (int) $request['id'], $taxonomy );
501
		$request->set_param( 'context', 'edit' );
502
		$response = $this->prepare_item_for_response( $term, $request );
503
504
		$retval = wp_delete_term( $term->term_id, $term->taxonomy );
505
		if ( ! $retval ) {
506
			return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) );
507
		}
508
509
		/**
510
		 * Fires after a single term is deleted via the REST API.
511
		 *
512
		 * @param WP_Term          $term     The deleted term.
513
		 * @param WP_REST_Response $response The response data.
514
		 * @param WP_REST_Request  $request  The request sent to the API.
515
		 */
516
		do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request );
517
518
		return $response;
519
	}
520
521
	/**
522
	 * Prepare links for the request.
523
	 *
524
	 * @param object $term Term object.
525
	 * @param WP_REST_Request $request Full details about the request.
526
	 * @return array Links for the given term.
527
	 */
528
	protected function prepare_links( $term, $request ) {
529
		$base = '/' . $this->namespace . '/' . $this->rest_base;
530
531 View Code Duplication
		if ( ! empty( $request['attribute_id'] ) ) {
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...
532
			$base = str_replace( '(?P<attribute_id>[\d]+)', (int) $request['attribute_id'], $base );
533
		}
534
535
		$links = array(
536
			'self' => array(
537
				'href' => rest_url( trailingslashit( $base ) . $term->term_id ),
538
			),
539
			'collection' => array(
540
				'href' => rest_url( $base ),
541
			),
542
		);
543
544
		if ( $term->parent ) {
545
			$parent_term = get_term( (int) $term->parent, $term->taxonomy );
546
			if ( $parent_term ) {
547
				$links['up'] = array(
548
					'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ),
549
				);
550
			}
551
		}
552
553
		return $links;
554
	}
555
556
	/**
557
	 * Update term meta fields.
558
	 *
559
	 * @param WP_Term $term
560
	 * @param WP_REST_Request $request
561
	 * @return bool|WP_Error
562
	 */
563
	protected function update_term_meta_fields( $term, $request ) {
564
		return true;
565
	}
566
567
	/**
568
	 * Get the terms attached to a product.
569
	 *
570
	 * This is an alternative to `get_terms()` that uses `get_the_terms()`
571
	 * instead, which hits the object cache. There are a few things not
572
	 * supported, notably `include`, `exclude`. In `self::get_items()` these
573
	 * are instead treated as a full query.
574
	 *
575
	 * @param array $prepared_args Arguments for `get_terms()`.
576
	 * @return array List of term objects. (Total count in `$this->total_terms`).
577
	 */
578
	protected function get_terms_for_product( $prepared_args ) {
579
		$taxonomy = $this->get_taxonomy( $request );
580
581
		$query_result = get_the_terms( $prepared_args['product'], $taxonomy );
582
		if ( empty( $query_result ) ) {
583
			$this->total_terms = 0;
584
			return array();
585
		}
586
587
		// get_items() verifies that we don't have `include` set, and default.
588
		// ordering is by `name`.
589
		if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ) ) ) {
590
			switch ( $prepared_args['orderby'] ) {
591
				case 'id' :
592
					$this->sort_column = 'term_id';
593
					break;
594
595
				case 'slug' :
596
				case 'term_group' :
597
				case 'description' :
598
				case 'count' :
599
					$this->sort_column = $prepared_args['orderby'];
600
					break;
601
			}
602
			usort( $query_result, array( $this, 'compare_terms' ) );
603
		}
604
		if ( strtolower( $prepared_args['order'] ) !== 'asc' ) {
605
			$query_result = array_reverse( $query_result );
606
		}
607
608
		// Pagination.
609
		$this->total_terms = count( $query_result );
610
		$query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] );
611
612
		return $query_result;
613
	}
614
615
	/**
616
	 * Comparison function for sorting terms by a column.
617
	 *
618
	 * Uses `$this->sort_column` to determine field to sort by.
619
	 *
620
	 * @param stdClass $left Term object.
621
	 * @param stdClass $right Term object.
622
	 * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left.
623
	 */
624
	protected function compare_terms( $left, $right ) {
625
		$col       = $this->sort_column;
626
		$left_val  = $left->$col;
627
		$right_val = $right->$col;
628
629
		if ( is_int( $left_val ) && is_int( $right_val ) ) {
630
			return $left_val - $right_val;
631
		}
632
633
		return strcmp( $left_val, $right_val );
634
	}
635
636
	/**
637
	 * Get the query params for collections
638
	 *
639
	 * @return array
640
	 */
641
	public function get_collection_params() {
642
		$params = parent::get_collection_params();
643
644
		if ( '' !== $this->taxonomy ) {
645
			$taxonomy = get_taxonomy( $this->taxonomy );
646
		} else {
647
			$taxonomy = new stdClass();
648
			$taxonomy->hierarchical = true;
649
		}
650
651
		$params['context']['default'] = 'view';
652
653
		$params['exclude'] = array(
654
			'description'        => __( 'Ensure result set excludes specific ids.', 'woocommerce' ),
655
			'type'               => 'array',
656
			'default'            => array(),
657
			'sanitize_callback'  => 'wp_parse_id_list',
658
		);
659
		$params['include'] = array(
660
			'description'        => __( 'Limit result set to specific ids.', 'woocommerce' ),
661
			'type'               => 'array',
662
			'default'            => array(),
663
			'sanitize_callback'  => 'wp_parse_id_list',
664
		);
665 View Code Duplication
		if ( ! $taxonomy->hierarchical ) {
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...
666
			$params['offset'] = array(
667
				'description'        => __( 'Offset the result set by a specific number of items.', 'woocommerce' ),
668
				'type'               => 'integer',
669
				'sanitize_callback'  => 'absint',
670
				'validate_callback'  => 'rest_validate_request_arg',
671
			);
672
		}
673
		$params['order']      = array(
674
			'description'           => __( 'Order sort attribute ascending or descending.', 'woocommerce' ),
675
			'type'                  => 'string',
676
			'sanitize_callback'     => 'sanitize_key',
677
			'default'               => 'asc',
678
			'enum'                  => array(
679
				'asc',
680
				'desc',
681
			),
682
			'validate_callback'     => 'rest_validate_request_arg',
683
		);
684
		$params['orderby']    = array(
685
			'description'           => __( 'Sort collection by resource attribute.', 'woocommerce' ),
686
			'type'                  => 'string',
687
			'sanitize_callback'     => 'sanitize_key',
688
			'default'               => 'name',
689
			'enum'                  => array(
690
				'id',
691
				'include',
692
				'name',
693
				'slug',
694
				'term_group',
695
				'description',
696
				'count',
697
			),
698
			'validate_callback'     => 'rest_validate_request_arg',
699
		);
700
		$params['hide_empty'] = array(
701
			'description'           => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ),
702
			'type'                  => 'boolean',
703
			'default'               => false,
704
			'validate_callback'     => 'rest_validate_request_arg',
705
		);
706 View Code Duplication
		if ( $taxonomy->hierarchical ) {
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...
707
			$params['parent'] = array(
708
				'description'        => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ),
709
				'type'               => 'integer',
710
				'sanitize_callback'  => 'absint',
711
				'validate_callback'  => 'rest_validate_request_arg',
712
			);
713
		}
714
		$params['product'] = array(
715
			'description'           => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ),
716
			'type'                  => 'integer',
717
			'default'               => null,
718
			'validate_callback'     => 'rest_validate_request_arg',
719
		);
720
		$params['slug']    = array(
721
			'description'        => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ),
722
			'type'               => 'string',
723
			'validate_callback'  => 'rest_validate_request_arg',
724
		);
725
726
		return $params;
727
	}
728
729
	/**
730
	 * Get taxonomy.
731
	 *
732
	 * @param WP_REST_Request $request Full details about the request.
733
	 * @return int|WP_Error
734
	 */
735
	protected function get_taxonomy( $request ) {
736
		// Check if taxonomy is defined.
737
		// Prevents check for attribute taxonomy more than one time for each query.
738
		if ( '' !== $this->taxonomy ) {
739
			return $this->taxonomy;
740
		}
741
742
		if ( ! empty( $request['attribute_id'] ) ) {
743
			$taxonomy = wc_attribute_taxonomy_name_by_id( (int) $request['attribute_id'] );
744
745
			$this->taxonomy = $taxonomy;
746
		}
747
748
		return $this->taxonomy;
749
	}
750
}
751