Issues (1182)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/cli/class-wc-cli-tax.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Manage Taxes.
5
 *
6
 * @since    2.5.0
7
 * @package  WooCommerce/CLI
8
 * @category CLI
9
 * @author   WooThemes
10
 */
11
class WC_CLI_Tax extends WC_CLI_Command {
12
13
	/**
14
	 * Create a tax rate.
15
	 *
16
	 * ## OPTIONS
17
	 *
18
	 * [--<field>=<value>]
19
	 * : Associative args for the new tax rate.
20
	 *
21
	 * [--porcelain]
22
	 * : Outputs just the new tax rate id.
23
	 *
24
	 * ## AVAILABLE FIELDS
25
	 *
26
	 * These fields are available for create command:
27
	 *
28
	 * * country
29
	 * * state
30
	 * * postcode
31
	 * * city
32
	 * * rate
33
	 * * name
34
	 * * priority
35
	 * * compound
36
	 * * shipping
37
	 * * class
38
	 * * order
39
	 *
40
	 * ## EXAMPLES
41
	 *
42
	 *     wp wc tax create --country=US --rate=5 --class=standard --type=percent
43
	 *
44
	 * @since 2.5.0
45
	 */
46
	public function create( $__, $assoc_args ) {
47
		$porcelain = isset( $assoc_args['porcelain'] );
48
		unset( $assoc_args['porcelain'] );
49
50
		$assoc_args = apply_filters( 'woocommerce_cli_create_tax_rate_data', $assoc_args );
51
52
		$tax_data = array(
53
			'tax_rate_country'  => '',
54
			'tax_rate_state'    => '',
55
			'tax_rate'          => '',
56
			'tax_rate_name'     => '',
57
			'tax_rate_priority' => 1,
58
			'tax_rate_compound' => 0,
59
			'tax_rate_shipping' => 1,
60
			'tax_rate_order'    => 0,
61
			'tax_rate_class'    => '',
62
		);
63
64
		foreach ( $tax_data as $key => $value ) {
65
			$new_key = str_replace( 'tax_rate_', '', $key );
66
			$new_key = 'tax_rate' === $new_key ? 'rate' : $new_key;
67
68
			if ( isset( $assoc_args[ $new_key ] ) ) {
69
				if ( in_array( $new_key, array( 'compound', 'shipping' ) ) ) {
70
					$tax_data[ $key ] = $assoc_args[ $new_key ] ? 1 : 0;
71
				} else {
72
					$tax_data[ $key ] = $assoc_args[ $new_key ];
73
				}
74
			}
75
		}
76
77
		// Create tax rate.
78
		$id = WC_Tax::_insert_tax_rate( $tax_data );
79
80
		// Add locales.
81
		if ( ! empty( $assoc_args['postcode'] ) ) {
82
			WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $assoc_args['postcode'] ) );
83
		}
84
85
		if ( ! empty( $assoc_args['city'] ) ) {
86
			WC_Tax::_update_tax_rate_cities( $id, wc_clean( $assoc_args['city'] ) );
87
		}
88
89
		do_action( 'woocommerce_cli_create_tax_rate', $id, $tax_data );
90
91
		if ( $porcelain ) {
92
			WP_CLI::line( $id );
93
		} else {
94
			WP_CLI::success( "Created tax rate $id." );
95
		}
96
	}
97
98
	/**
99
	 * Create a tax class.
100
	 *
101
	 * ## OPTIONS
102
	 *
103
	 * [--<field>=<value>]
104
	 * : Associative args for the new tax class.
105
	 *
106
	 * [--porcelain]
107
	 * : Outputs just the new tax class slug.
108
	 *
109
	 * ## AVAILABLE FIELDS
110
	 *
111
	 * These fields are available for create command:
112
	 *
113
	 * * name
114
	 *
115
	 * ## EXAMPLES
116
	 *
117
	 *     wp wc tax create_class --name="Reduced Rate"
118
	 *
119
	 * @since 2.5.0
120
	 */
121
	public function create_class( $__, $assoc_args ) {
122
		try {
123
			$porcelain = isset( $assoc_args['porcelain'] );
124
			unset( $assoc_args['porcelain'] );
125
126
			$assoc_args = apply_filters( 'woocommerce_cli_create_tax_class_data', $assoc_args );
127
128
			// Check if name is specified.
129 View Code Duplication
			if ( ! isset( $assoc_args['name'] ) ) {
0 ignored issues
show
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...
130
				throw new WC_CLI_Exception( 'woocommerce_cli_missing_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ) );
131
			}
132
133
			$name    = sanitize_text_field( $assoc_args['name'] );
134
			$slug    = sanitize_title( $name );
135
			$classes = WC_Tax::get_tax_classes();
136
			$exists  = false;
137
138
			// Check if class exists.
139
			foreach ( $classes as $key => $class ) {
140
				if ( sanitize_title( $class ) === $slug ) {
141
					$exists = true;
142
					break;
143
				}
144
			}
145
146
			// Return error if tax class already exists.
147
			if ( $exists ) {
148
				throw new WC_CLI_Exception( 'woocommerce_cli_cannot_create_tax_class', __( 'Tax class already exists', 'woocommerce' ) );
149
			}
150
151
			// Add the new class
152
			$classes[] = $name;
153
154
			update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) );
155
156
			do_action( 'woocommerce_cli_create_tax_class', $slug, array( 'name' => $name ) );
157
158
			if ( $porcelain ) {
159
				WP_CLI::line( $slug );
160
			} else {
161
				WP_CLI::success( "Created tax class $slug." );
162
			}
163
		} catch ( WC_CLI_Exception $e ) {
164
			WP_CLI::error( $e->getMessage() );
165
		}
166
	}
167
168
	/**
169
	 * Delete one or more tax rates.
170
	 *
171
	 * ## OPTIONS
172
	 *
173
	 * <id>...
174
	 * : The tax rate ID to delete.
175
	 *
176
	 * ## EXAMPLES
177
	 *
178
	 *     wp wc tax delete 123
179
	 *
180
	 *     wp wc tax delete $(wp wc tax list --format=ids)
181
	 *
182
	 * @since 2.5.0
183
	 */
184
	public function delete( $args, $assoc_args ) {
185
		$exit_code = 0;
186
187
		foreach ( $args as $tax_id ) {
188
			$tax_id = absint( $tax_id );
189
			$tax    = WC_Tax::_get_tax_rate( $tax_id );
190
191
			if ( is_null( $tax ) ) {
192
				$exit_code += 1;
193
				WP_CLI::warning( "Failed deleting tax rate {$tax_id}." );
194
				continue;
195
			}
196
197
			do_action( 'woocommerce_cli_delete_tax_rate', $tax_id );
198
199
			WC_Tax::_delete_tax_rate( $tax_id );
200
			WP_CLI::success( "Deleted tax rate {$tax_id}." );
201
		}
202
		exit( $exit_code ? 1 : 0 );
203
	}
204
205
	/**
206
	 * Delete one or more tax classes.
207
	 *
208
	 * ## OPTIONS
209
	 *
210
	 * <slug>...
211
	 * : The tax class slug to delete.
212
	 *
213
	 * ## EXAMPLES
214
	 *
215
	 *     wp wc tax delete_class reduced-rate
216
	 *
217
	 *     wp wc tax delete_class $(wp wc tax list_class --format=ids)
218
	 *
219
	 * @since 2.5.0
220
	 */
221
	public function delete_class( $args, $assoc_args ) {
222
		$classes   = WC_Tax::get_tax_classes();
223
		$exit_code = 0;
224
225
		foreach ( $args as $slug ) {
226
			$slug    = sanitize_title( $slug );
227
			$deleted = false;
228
229
			foreach ( $classes as $key => $class ) {
230
				if ( sanitize_title( $class ) === $slug ) {
231
					unset( $classes[ $key ] );
232
					$deleted = true;
233
					break;
234
				}
235
			}
236
237
			if ( $deleted ) {
238
				WP_CLI::success( "Deleted tax class {$slug}." );
239
			} else {
240
				$exit_code += 1;
241
				WP_CLI::warning( "Failed deleting tax class {$slug}." );
242
			}
243
		}
244
245
		update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) );
246
247
		exit( $exit_code ? 1 : 0 );
248
	}
249
250
	/**
251
	 * Get a tax rate.
252
	 *
253
	 * ## OPTIONS
254
	 *
255
	 * <id>
256
	 * : Tax rate ID
257
	 *
258
	 * [--field=<field>]
259
	 * : Instead of returning the whole tax rate fields, returns the value of a single fields.
260
	 *
261
	 * [--fields=<fields>]
262
	 * : Get a specific subset of the tax rates fields.
263
	 *
264
	 * [--format=<format>]
265
	 * : Accepted values: table, json, csv. Default: table.
266
	 *
267
	 * ## AVAILABLE FIELDS
268
	 *
269
	 * These fields are available for get command:
270
	 *
271
	 * * id
272
	 * * country
273
	 * * state
274
	 * * postcode
275
	 * * city
276
	 * * rate
277
	 * * name
278
	 * * priority
279
	 * * compound
280
	 * * shipping
281
	 * * order
282
	 * * class
283
	 *
284
	 * ## EXAMPLES
285
	 *
286
	 *     wp wc tax get 123 --field=rate
287
	 *
288
	 *     wp wc tax get 321 --format=json > rate321.json
289
	 *
290
	 * @since 2.5.0
291
	 */
292
	public function get( $args, $assoc_args ) {
293
		global $wpdb;
294
295
		try {
296
297
			$tax_data = $this->format_taxes_to_items( array( $args[0] ) );
298
299 View Code Duplication
			if ( empty( $tax_data ) ) {
0 ignored issues
show
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...
300
				throw new WC_CLI_Exception( 'woocommerce_cli_invalid_tax_rate', sprintf( __( 'Invalid tax rate ID: %s', 'woocommerce' ), $args[0] ) );
301
			}
302
303
			$tax_data = apply_filters( 'woocommerce_cli_get_tax_rate', $tax_data[0] );
304
305
			if ( empty( $assoc_args['fields'] ) ) {
306
				$assoc_args['fields'] = array_keys( $tax_data );
307
			}
308
309
			$formatter = $this->get_formatter( $assoc_args );
310
			$formatter->display_item( $tax_data );
311
		} catch ( WC_CLI_Exception $e ) {
312
			WP_CLI::error( $e->getMessage() );
313
		}
314
	}
315
316
	/**
317
	 * List taxes.
318
	 *
319
	 * ## OPTIONS
320
	 *
321
	 * [--<field>=<value>]
322
	 * : Filter tax based on tax property.
323
	 *
324
	 * [--field=<field>]
325
	 * : Prints the value of a single field for each tax.
326
	 *
327
	 * [--fields=<fields>]
328
	 * : Limit the output to specific tax fields.
329
	 *
330
	 * [--format=<format>]
331
	 * : Acceptec values: table, csv, json, count, ids. Default: table.
332
	 *
333
	 * ## AVAILABLE FIELDS
334
	 *
335
	 * These fields will be displayed by default for each tax:
336
	 *
337
	 * * id
338
	 * * country
339
	 * * state
340
	 * * postcode
341
	 * * city
342
	 * * rate
343
	 * * name
344
	 * * priority
345
	 * * compound
346
	 * * shipping
347
	 * * class
348
	 *
349
	 * These fields are optionally available:
350
	 *
351
	 * * order
352
	 *
353
	 * Fields for filtering query result also available:
354
	 *
355
	 * * class Sort by tax class.
356
	 * * page  Page number.
357
	 *
358
	 * ## EXAMPLES
359
	 *
360
	 *     wp wc tax list
361
	 *
362
	 *     wp wc tax list --field=id
363
	 *
364
	 *     wp wc tax list --fields=id,rate,class --format=json
365
	 *
366
	 * @since      2.5.0
367
	 * @subcommand list
368
	 */
369
	public function list_( $__, $assoc_args ) {
370
		$query_args = $this->merge_tax_query_args( array(), $assoc_args );
371
		$formatter  = $this->get_formatter( $assoc_args );
372
373
		$taxes = $this->query_tax_rates( $query_args );
374
375
		if ( 'ids' === $formatter->format ) {
376
			$_taxes = array();
377
			foreach ( $taxes as $tax ) {
378
				$_taxes[] = $tax->tax_rate_id;
379
			}
380
			echo implode( ' ', $_taxes );
381
		} else {
382
			$items = $this->format_taxes_to_items( $taxes );
383
			$formatter->display_items( $items );
384
		}
385
	}
386
387
	/**
388
	 * List tax classes.
389
	 *
390
	 * ## OPTIONS
391
	 *
392
	 * [--<field>=<value>]
393
	 * : Filter tax class based on tax class property.
394
	 *
395
	 * [--field=<field>]
396
	 * : Prints the value of a single field for each tax class.
397
	 *
398
	 * [--fields=<fields>]
399
	 * : Limit the output to specific tax class fields.
400
	 *
401
	 * [--format=<format>]
402
	 * : Acceptec values: table, csv, json, count, ids. Default: table.
403
	 *
404
	 * ## AVAILABLE FIELDS
405
	 *
406
	 * These fields will be displayed by default for each tax class:
407
	 *
408
	 * * slug
409
	 * * name
410
	 *
411
	 * ## EXAMPLES
412
	 *
413
	 *     wp wc tax list_class
414
	 *
415
	 *     wp wc tax list_class --field=slug
416
	 *
417
	 *     wp wc tax list_class --format=json
418
	 *
419
	 * @since      2.5.0
420
	 * @subcommand list_class
421
	 */
422
	public function list_class( $__, $assoc_args ) {
423
		// Set default fields for tax classes
424
		if ( empty( $assoc_args['fields'] ) ) {
425
			$assoc_args['fields'] = 'slug,name';
426
		}
427
428
		$formatter = $this->get_formatter( $assoc_args );
429
		$items     = array();
430
431
		// Add standard class
432
		$items[] = array(
433
			'slug' => 'standard',
434
			'name' => __( 'Standard Rate', 'woocommerce' )
435
		);
436
437
		$classes = WC_Tax::get_tax_classes();
438
439
		foreach ( $classes as $class ) {
440
			$items[] = apply_filters( 'woocommerce_cli_tax_class_response', array(
441
				'slug' => sanitize_title( $class ),
442
				'name' => $class
443
			), $class, $assoc_args, $this );
444
		}
445
446
		if ( 'ids' === $formatter->format ) {
447
			$_slugs = array();
448
			foreach ( $items as $item ) {
449
				$_slugs[] = $item['slug'];
450
			}
451
			echo implode( ' ', $_slugs );
452
		} else {
453
			$formatter->display_items( $items );
454
		}
455
	}
456
457
	/**
458
	 * Update a tax rate.
459
	 *
460
	 * ## OPTIONS
461
	 *
462
	 * <id>
463
	 * : The ID of the tax rate to update.
464
	 *
465
	 * [--<field>=<value>]
466
	 * : One or more fields to update.
467
	 *
468
	 * ## AVAILABLE FIELDS
469
	 *
470
	 * These fields are available for update command:
471
	 *
472
	 * * country
473
	 * * state
474
	 * * postcode
475
	 * * city
476
	 * * rate
477
	 * * name
478
	 * * priority
479
	 * * compound
480
	 * * shipping
481
	 * * class
482
	 *
483
	 * ## EXAMPLES
484
	 *
485
	 *     wp wc tax update 123 --rate=5
486
	 *
487
	 * @since 2.5.0
488
	 */
489
	public function update( $args, $assoc_args ) {
490
		try {
491
			// Get current tax rate data
492
			$tax_data = $this->format_taxes_to_items( array( $args[0] ) );
493
494 View Code Duplication
			if ( empty( $tax_data ) ) {
0 ignored issues
show
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...
495
				throw new WC_CLI_Exception( 'woocommerce_cli_invalid_tax_rate', sprintf( __( 'Invalid tax rate ID: %s', 'woocommerce' ), $args[0] ) );
496
			}
497
498
			$current_data   = $tax_data[0];
499
			$id             = $current_data['id'];
500
			$data           = apply_filters( 'woocommerce_cli_update_tax_rate_data', $assoc_args, $id );
501
			$new_data       = array();
502
			$default_fields = array(
503
				'tax_rate_country',
504
				'tax_rate_state',
505
				'tax_rate',
506
				'tax_rate_name',
507
				'tax_rate_priority',
508
				'tax_rate_compound',
509
				'tax_rate_shipping',
510
				'tax_rate_order',
511
				'tax_rate_class'
512
			);
513
514
			foreach ( $data as $key => $value ) {
515
				$new_key = 'rate' === $key ? 'tax_rate' : 'tax_rate_' . $key;
516
517
				// Check if the key is valid
518
				if ( ! in_array( $new_key, $default_fields ) ) {
519
					continue;
520
				}
521
522
				// Test new data against current data
523
				if ( $value === $current_data[ $key ] ) {
524
					continue;
525
				}
526
527
				// Fix compund and shipping values
528
				if ( in_array( $key, array( 'compound', 'shipping' ) ) ) {
529
					$value = $value ? 1 : 0;
530
				}
531
532
				$new_data[ $new_key ] = $value;
533
			}
534
535
			// Update tax rate
536
			WC_Tax::_update_tax_rate( $id, $new_data );
537
538
			// Update locales
539 View Code Duplication
			if ( ! empty( $data['postcode'] ) && $current_data['postcode'] != $data['postcode'] ) {
0 ignored issues
show
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...
540
				WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $data['postcode'] ) );
541
			}
542
543 View Code Duplication
			if ( ! empty( $data['city'] ) && $current_data['city'] != $data['city'] ) {
0 ignored issues
show
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...
544
				WC_Tax::_update_tax_rate_cities( $id, wc_clean( $data['city'] ) );
545
			}
546
547
			do_action( 'woocommerce_cli_update_tax_rate', $id, $data );
548
549
			WP_CLI::success( "Updated tax rate $id." );
550
		} catch ( WC_CLI_Exception $e ) {
551
			WP_CLI::error( $e->getMessage() );
552
		}
553
	}
554
555
	/**
556
	 * Add common cli arguments to argument list before $wpdb->get_results() is run.
557
	 *
558
	 * @since  2.5.0
559
	 * @param  array $base_args  Required arguments for the query (e.g. `limit`, etc)
560
	 * @param  array $assoc_args Arguments provided in when invoking the command
561
	 * @return array
562
	 */
563
	protected function merge_tax_query_args( $base_args, $assoc_args ) {
564
		$args = array();
565
566
		if ( ! empty( $assoc_args['class'] ) ) {
567
			$args['class'] = $assoc_args['class'];
568
		}
569
570
		// Number of post to show per page.
571
		if ( ! empty( $assoc_args['limit'] ) ) {
572
			$args['posts_per_page'] = $assoc_args['limit'];
573
		}
574
575
		// posts page.
576
		$args['paged'] = ( isset( $assoc_args['page'] ) ) ? absint( $assoc_args['page'] ) : 1;
577
578
		$args = apply_filters( 'woocommerce_cli_tax_query_args', $args, $assoc_args );
579
580
		return array_merge( $base_args, $args );
581
	}
582
583
	/**
584
	 * Helper method to get tax rates objects
585
	 *
586
	 * @since 2.5.0
587
	 *
588
	 * @param  array $args
589
	 *
590
	 * @return array
591
	 */
592
	protected function query_tax_rates( $args ) {
593
		global $wpdb;
594
595
		$query = "
596
			SELECT tax_rate_id
597
			FROM {$wpdb->prefix}woocommerce_tax_rates
598
			WHERE 1 = 1
599
		";
600
601
		// Filter by tax class
602 View Code Duplication
		if ( ! empty( $args['class'] ) ) {
0 ignored issues
show
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...
603
			$class = 'standard' !== $args['class'] ? sanitize_title( $args['class'] ) : '';
604
			$query .= " AND tax_rate_class = '$class'";
605
		}
606
607
		// Order tax rates
608
		$order_by = ' ORDER BY tax_rate_order';
609
610
		// Pagination
611
		$per_page   = isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : get_option( 'posts_per_page' );
612
		$offset     = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $per_page : 0;
613
		$pagination = sprintf( ' LIMIT %d, %d', $offset, $per_page );
614
615
		return $wpdb->get_results( $query . $order_by . $pagination );
616
	}
617
618
	/**
619
	 * Get default format fields that will be used in `list` and `get` subcommands.
620
	 *
621
	 * @since  2.5.0
622
	 * @return string
623
	 */
624
	protected function get_default_format_fields() {
625
		return 'id,country,state,postcode,city,rate,name,priority,compound,shipping,class';
626
	}
627
628
	/**
629
	 * Format taxes from query result to items in which each item contain
630
	 * common properties of item, for instance `tax_rate_id` will be `id`.
631
	 *
632
	 * @since  2.5.0
633
	 * @param  array $taxes Array of tax rate.
634
	 * @return array Items
635
	 */
636
	protected function format_taxes_to_items( $taxes ) {
637
		global $wpdb;
638
639
		$items = array();
640
641
		foreach ( $taxes as $tax_id ) {
642
			$id = is_object( $tax_id ) ? $tax_id->tax_rate_id : $tax_id;
643
			$id = absint( $id );
644
645
			// Get tax rate details
646
			$tax = WC_Tax::_get_tax_rate( $id );
647
648
			if ( is_wp_error( $tax ) || empty( $tax ) ) {
649
				continue;
650
			}
651
652
			$tax_data = array(
653
				'id'       => $tax['tax_rate_id'],
654
				'country'  => $tax['tax_rate_country'],
655
				'state'    => $tax['tax_rate_state'],
656
				'postcode' => '',
657
				'city'     => '',
658
				'rate'     => $tax['tax_rate'],
659
				'name'     => $tax['tax_rate_name'],
660
				'priority' => (int) $tax['tax_rate_priority'],
661
				'compound' => (bool) $tax['tax_rate_compound'],
662
				'shipping' => (bool) $tax['tax_rate_shipping'],
663
				'order'    => (int) $tax['tax_rate_order'],
664
				'class'    => $tax['tax_rate_class'] ? $tax['tax_rate_class'] : 'standard'
665
			);
666
667
			// Get locales from a tax rate
668
			$locales = $wpdb->get_results( $wpdb->prepare( "
669
				SELECT location_code, location_type
670
				FROM {$wpdb->prefix}woocommerce_tax_rate_locations
671
				WHERE tax_rate_id = %d
672
			", $id ) );
673
674 View Code Duplication
			if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) {
0 ignored issues
show
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...
675
				foreach ( $locales as $locale ) {
676
					$tax_data[ $locale->location_type ] = $locale->location_code;
677
				}
678
			}
679
680
			$items[] = $tax_data;
681
		}
682
683
		return $items;
684
	}
685
}
686