Completed
Pull Request — master (#11858)
by
unknown
19:45
created

WC_Product_Variation::set_stock()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 51
Code Lines 25

Duplication

Lines 11
Ratio 21.57 %

Importance

Changes 0
Metric Value
cc 7
eloc 25
nc 6
nop 2
dl 11
loc 51
rs 6.9743
c 0
b 0
f 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
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	exit; // Exit if accessed directly
5
}
6
7
/**
8
 * Product Variation Class.
9
 *
10
 * The WooCommerce product variation class handles product variation data.
11
 *
12
 * @class       WC_Product_Variation
13
 * @version     2.2.0
14
 * @package     WooCommerce/Classes
15
 * @category    Class
16
 * @author      WooThemes
17
 */
18
class WC_Product_Variation extends WC_Product {
19
20
	/** @public int ID of the variation itself. */
21
	public $variation_id;
22
23
	/** @public object Parent Variable product object. */
24
	public $parent;
25
26
	/** @public string Stores the shipping class of the variation. */
27
	public $variation_shipping_class         = '';
28
29
	/** @public int Stores the shipping class ID of the variation. */
30
	public $variation_shipping_class_id      = 0;
31
32
	/** @public unused vars @deprecated in 2.2 */
33
	public $variation_has_sku                = true;
34
	public $variation_has_length             = true;
35
	public $variation_has_width              = true;
36
	public $variation_has_height             = true;
37
	public $variation_has_weight             = true;
38
	public $variation_has_tax_class          = true;
39
	public $variation_has_downloadable_files = true;
40
41
	/** @private array Data which is only at variation level - no inheritance plus their default values if left blank. */
42
	protected $variation_level_meta_data = array(
43
		'downloadable'          => 'no',
44
		'virtual'               => 'no',
45
		'manage_stock'          => 'no',
46
		'sale_price_dates_from' => '',
47
		'sale_price_dates_to'   => '',
48
		'price'                 => '',
49
		'regular_price'         => '',
50
		'sale_price'            => '',
51
		'stock'                 => 0,
52
		'stock_status'          => 'instock',
53
		'downloadable_files'    => array(),
54
	);
55
56
	/** @private array Data which can be at variation level, otherwise fallback to parent if not set. */
57
	protected $variation_inherited_meta_data = array(
58
		'tax_class'  => '',
59
		'backorders' => 'no',
60
		'sku'        => '',
61
		'weight'     => '',
62
		'length'     => '',
63
		'width'      => '',
64
		'height'     => '',
65
	);
66
67
	/**
68
	 * Loads required variation data.
69
	 *
70
	 * @param int $variation ID of the variation to load
71
	 * @param array $args Array of the arguments containing parent product data
72
	 */
73
	public function __construct( $variation, $args = array() ) {
74
		if ( is_object( $variation ) ) {
75
			$this->variation_id = absint( $variation->ID );
76
		} else {
77
			$this->variation_id = absint( $variation );
78
		}
79
80
		/* Get main product data from parent (args) */
81
		$this->id = ! empty( $args['parent_id'] ) ? intval( $args['parent_id'] ) : wp_get_post_parent_id( $this->variation_id );
82
83
		// The post doesn't have a parent id, therefore its invalid and we should prevent this being created.
84
		if ( empty( $this->id ) ) {
85
			throw new Exception( sprintf( 'No parent product set for variation #%d', $this->variation_id ), 422 );
86
		}
87
88
		$this->product_type = 'variation';
89
		$this->parent       = ! empty( $args['parent'] ) ? $args['parent'] : wc_get_product( $this->id );
90
		$this->post         = ! empty( $this->parent->post ) ? $this->parent->post : array();
91
92
		// The post parent is not a valid variable product so we should prevent this being created.
93
		if ( ! is_a( $this->parent, 'WC_Product' ) ) {
94
			throw new Exception( sprintf( 'Invalid parent for variation #%d', $this->variation_id ), 422 );
95
		}
96
	}
97
98
	/**
99
	 * __isset function.
100
	 *
101
	 * @param mixed $key
102
	 * @return bool
103
	 */
104
	public function __isset( $key ) {
105
		if ( in_array( $key, array_keys( $this->variation_level_meta_data ) ) ) {
106
			return metadata_exists( 'post', $this->variation_id, '_' . $key );
107
		} elseif ( in_array( $key, array_keys( $this->variation_inherited_meta_data ) ) ) {
108
			return metadata_exists( 'post', $this->variation_id, '_' . $key ) || metadata_exists( 'post', $this->id, '_' . $key );
109
		} else {
110
			return metadata_exists( 'post', $this->id, '_' . $key );
111
		}
112
	}
113
114
	/**
115
	 * Get method returns variation meta data if set, otherwise in most cases the data from the parent.
116
	 *
117
	 * @param string $key
118
	 * @return mixed
119
	 */
120
	public function __get( $key ) {
121
		if ( in_array( $key, array_keys( $this->variation_level_meta_data ) ) ) {
122
123
			$value = get_post_meta( $this->variation_id, '_' . $key, true );
124
125
			if ( '' === $value ) {
126
				$value = $this->variation_level_meta_data[ $key ];
127
			}
128
		} elseif ( in_array( $key, array_keys( $this->variation_inherited_meta_data ) ) ) {
129
130
			$value = metadata_exists( 'post', $this->variation_id, '_' . $key ) ? get_post_meta( $this->variation_id, '_' . $key, true ) : get_post_meta( $this->id, '_' . $key, true );
131
132
			// Handle meta data keys which can be empty at variation level to cause inheritance
133
			if ( '' === $value && in_array( $key, array( 'sku', 'weight', 'length', 'width', 'height' ) ) ) {
134
				$value = get_post_meta( $this->id, '_' . $key, true );
135
			}
136
137
			if ( '' === $value ) {
138
				$value = $this->variation_inherited_meta_data[ $key ];
139
			}
140
		} elseif ( 'variation_data' === $key ) {
141
			return $this->variation_data = wc_get_product_variation_attributes( $this->variation_id );
142
143
		} elseif ( 'variation_has_stock' === $key ) {
144
			return $this->managing_stock();
145
146
		} else {
147
			$value = metadata_exists( 'post', $this->variation_id, '_' . $key ) ? get_post_meta( $this->variation_id, '_' . $key, true ) : parent::__get( $key );
148
		}
149
150
		return $value;
151
	}
152
153
	/**
154
	 * Return the variation ID
155
	 *
156
	 * @since 2.5.0
157
	 * @return int variation (post) ID
158
	 */
159
	public function get_id() {
160
		return $this->variation_id;
161
	}
162
163
	/**
164
	 * Returns whether or not the product post exists.
165
	 *
166
	 * @return bool
167
	 */
168
	public function exists() {
169
		return ! empty( $this->id );
170
	}
171
172
	/**
173
	 * Wrapper for get_permalink. Adds this variations attributes to the URL.
174
	 *
175
	 * @param  $item_object item array If a cart or order item is passed, we can get a link containing the exact attributes selected for the variation, rather than the default attributes.
176
	 * @return string
177
	 */
178
	public function get_permalink( $item_object = null ) {
179
		if ( ! empty( $item_object['variation'] ) ) {
180
			$data = $item_object['variation'];
181
		} elseif ( ! empty( $item_object['item_meta_array'] ) ) {
182
			$data_keys    = array_map( 'wc_variation_attribute_name', wp_list_pluck( $item_object['item_meta_array'], 'key' ) );
183
			$data_values  = wp_list_pluck( $item_object['item_meta_array'], 'value' );
184
			$data         = array_intersect_key( array_combine( $data_keys, $data_values ), $this->variation_data );
185
		} else {
186
			$data = $this->variation_data;
187
		}
188
		return add_query_arg( array_map( 'urlencode', array_filter( $data ) ), get_permalink( $this->id ) );
189
	}
190
191
	/**
192
	 * Get the add to url used mainly in loops.
193
	 *
194
	 * @return string
195
	 */
196
	public function add_to_cart_url() {
197
		$variation_data = array_map( 'urlencode', $this->variation_data );
198
		$url            = $this->is_purchasable() && $this->is_in_stock() ? remove_query_arg( 'added-to-cart', add_query_arg( array_merge( array( 'variation_id' => $this->variation_id, 'add-to-cart' => $this->id ), $variation_data ) ) ) : get_permalink( $this->id );
199
200
		return apply_filters( 'woocommerce_product_add_to_cart_url', $url, $this );
201
	}
202
203
	/**
204
	 * Get the add to cart button text.
205
	 *
206
	 * @return string
207
	 */
208
	public function add_to_cart_text() {
209
		$text = $this->is_purchasable() && $this->is_in_stock() ? __( 'Add to cart', 'woocommerce' ) : __( 'Read more', 'woocommerce' );
210
211
		return apply_filters( 'woocommerce_product_add_to_cart_text', $text, $this );
212
	}
213
214
	/**
215
	 * Checks if this particular variation is visible. Invisible variations are enabled and can be selected, but no price / stock info is displayed.
216
	 * Instead, a suitable 'unavailable' message is displayed.
217
	 * Invisible by default: Disabled variations and variations with an empty price.
218
	 *
219
	 * @return bool
220
	 */
221
	public function variation_is_visible() {
222
		$visible = true;
223
224
		if ( get_post_status( $this->variation_id ) != 'publish' ) {
225
226
			// Published == enabled checkbox
227
			$visible = false;
228
229
		} elseif ( $this->get_price() === "" ) {
230
231
			// Price not set
232
			$visible = false;
233
234
		}
235
236
		return apply_filters( 'woocommerce_variation_is_visible', $visible, $this->variation_id, $this->id, $this );
237
	}
238
239
	/**
240
	 * Controls whether this particular variation will appear greyed-out (inactive) or not (active).
241
	 * Used by extensions to make incompatible variations appear greyed-out, etc.
242
	 * Other possible uses: prevent out-of-stock variations from being selected.
243
	 *
244
	 * @return bool
245
	 */
246
	public function variation_is_active() {
247
		return apply_filters( 'woocommerce_variation_is_active', true, $this );
248
	}
249
250
	/**
251
	 * Returns false if the product cannot be bought.
252
	 * Override abstract method so that: i) Disabled variations are not be purchasable by admins. ii) Enabled variations are not purchasable if the parent product is not purchasable.
253
	 *
254
	 * @return bool
255
	 */
256
	public function is_purchasable() {
257
		// Published == enabled checkbox
258
		if ( get_post_status( $this->variation_id ) != 'publish' ) {
259
			$purchasable = false;
260
		} else {
261
			$purchasable = parent::is_purchasable();
262
		}
263
		return apply_filters( 'woocommerce_variation_is_purchasable', $purchasable, $this );
264
	}
265
266
	/**
267
	 * Returns whether or not the variations parent is visible.
268
	 *
269
	 * @return bool
270
	 */
271
	public function parent_is_visible() {
272
		return $this->is_visible();
273
	}
274
275
	/**
276
	 * Get variation ID.
277
	 *
278
	 * @return int
279
	 */
280
	public function get_variation_id() {
281
		return absint( $this->variation_id );
282
	}
283
284
	/**
285
	 * Get variation attribute values.
286
	 *
287
	 * @return array of attributes and their values for this variation
288
	 */
289
	public function get_variation_attributes() {
290
		return $this->variation_data;
291
	}
292
293
	/**
294
	 * Check if all variation's attributes are set.
295
	 *
296
	 * @return boolean
297
	 */
298
	public function has_all_attributes_set() {
299
300
		$set = true;
301
302
		// undefined attributes have null strings as array values
303
		foreach ( $this->get_variation_attributes() as $att ) {
304
			if ( ! $att ) {
305
				$set = false;
306
				break;
307
			}
308
		}
309
310
		return $set;
311
312
	}
313
314
	/**
315
	 * Get variation price HTML. Prices are not inherited from parents.
316
	 *
317
	 * @return string containing the formatted price
318
	 */
319
	public function get_price_html( $price = '' ) {
320
321
		$display_price         = $this->get_display_price();
322
		$display_regular_price = $this->get_display_price( $this->get_regular_price() );
323
		$display_sale_price    = $this->get_display_price( $this->get_sale_price() );
324
325
		if ( $this->get_price() !== '' ) {
326
			if ( $this->is_on_sale() ) {
327
				$price = apply_filters( 'woocommerce_variation_sale_price_html', '<del>' . wc_price( $display_regular_price ) . '</del> <ins>' . wc_price( $display_sale_price ) . '</ins>' . $this->get_price_suffix(), $this );
328
			} elseif ( $this->get_price() > 0 ) {
329
				$price = apply_filters( 'woocommerce_variation_price_html', wc_price( $display_price ) . $this->get_price_suffix(), $this );
330
			} else {
331
				$price = apply_filters( 'woocommerce_variation_free_price_html', __( 'Free!', 'woocommerce' ), $this );
332
			}
333
		} else {
334
			$price = apply_filters( 'woocommerce_variation_empty_price_html', '', $this );
335
		}
336
337
		return apply_filters( 'woocommerce_get_variation_price_html', $price, $this );
338
	}
339
340
	/**
341
	 * Gets the main product image ID.
342
	 *
343
	 * @return int
344
	 */
345
	public function get_image_id() {
346
		if ( $this->variation_id && has_post_thumbnail( $this->variation_id ) ) {
347
			$image_id = get_post_thumbnail_id( $this->variation_id );
348
		} elseif ( has_post_thumbnail( $this->id ) ) {
349
			$image_id = get_post_thumbnail_id( $this->id );
350 View Code Duplication
		} elseif ( ( $parent_id = wp_get_post_parent_id( $this->id ) ) && has_post_thumbnail( $parent_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...
351
			$image_id = get_post_thumbnail_id( $parent_id );
352
		} else {
353
			$image_id = 0;
354
		}
355
		return $image_id;
356
	}
357
358
	/**
359
	 * Gets the main product image.
360
	 *
361
	 * @param string $size (default: 'shop_thumbnail')
362
	 * @param bool True to return $placeholder if no image is found, or false to return an empty string.
363
	 * @return string
364
	 */
365
	public function get_image( $size = 'shop_thumbnail', $attr = array(), $placeholder = true ) {
366
		if ( $this->variation_id && has_post_thumbnail( $this->variation_id ) ) {
367
			$image = get_the_post_thumbnail( $this->variation_id, $size, $attr );
368
		} elseif ( has_post_thumbnail( $this->id ) ) {
369
			$image = get_the_post_thumbnail( $this->id, $size, $attr );
370 View Code Duplication
		} elseif ( ( $parent_id = wp_get_post_parent_id( $this->id ) ) && has_post_thumbnail( $parent_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...
371
			$image = get_the_post_thumbnail( $parent_id, $size , $attr );
372
		} elseif ( $placeholder ) {
373
			$image = wc_placeholder_img( $size );
374
		} else {
375
			$image = '';
376
		}
377
		return $image;
378
	}
379
380
	/**
381
	 * Returns whether or not the product (or variation) is stock managed.
382
	 *
383
	 * @return bool|string Bool if managed at variation level, 'parent' if managed by the parent.
384
	 */
385
	public function managing_stock() {
386
		if ( 'yes' === get_option( 'woocommerce_manage_stock', 'yes' ) ) {
387
			if ( 'no' === $this->manage_stock ) {
388
				if ( $this->parent && $this->parent->managing_stock() ) {
389
					return 'parent';
390
				}
391
			} else {
392
				return true;
393
			}
394
		}
395
		return false;
396
	}
397
398
	/**
399
	 * Returns number of items available for sale from the variation, or parent.
400
	 *
401
	 * @return int
402
	 */
403
	public function get_stock_quantity() {
404
		return apply_filters( 'woocommerce_variation_get_stock_quantity', true === $this->managing_stock() ? wc_stock_amount( $this->stock ) : $this->parent->get_stock_quantity(), $this );
405
	}
406
407
	/**
408
	 * Get total stock - This is the stock of parent and children combined.
409
	 *
410
	 * @return int
411
	 */
412
	public function get_total_stock() {
413
		return $this->get_stock_quantity();
414
	}
415
416
	/**
417
	 * Returns the tax status. Always use parent data.
418
	 *
419
	 * @return string
420
	 */
421
	public function get_tax_status() {
422
		return $this->parent->get_tax_status();
423
	}
424
425
	/**
426
	 * Returns whether or not the product is in stock.
427
	 *
428
	 * @return bool
429
	 */
430
	public function is_in_stock() {
431
		return apply_filters( 'woocommerce_variation_is_in_stock', 'instock' === $this->stock_status, $this );
432
	}
433
434
	/**
435
	 * Set stock level of the product variation.
436
	 *
437
	 * Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues).
438
	 * We cannot rely on the original loaded value in case another order was made since then.
439
	 *
440
	 * @param  int     $amount
441
	 * @param  string  $mode    can be set, add, or subtract
442
	 * @return int              new stock level
443
	 */
444
	public function set_stock( $amount = null, $mode = 'set' ) {
445
		global $wpdb;
446
447
		if ( ! is_null( $amount ) && true === $this->managing_stock() ) {
448
449
			// Ensure key exists
450
			add_post_meta( $this->variation_id, '_stock', 0, true );
451
452
			// Update stock in DB directly
453 View Code Duplication
			switch ( $mode ) {
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...
454
				case 'add' :
455
					$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = meta_value + %f WHERE post_id = %d AND meta_key='_stock'", $amount, $this->variation_id ) );
456
				break;
457
				case 'subtract' :
458
					$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = meta_value - %f WHERE post_id = %d AND meta_key='_stock'", $amount, $this->variation_id ) );
459
				break;
460
				default :
461
					$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'", $amount, $this->variation_id ) );
462
				break;
463
			}
464
465
			// Clear caches
466
			wp_cache_delete( $this->variation_id, 'post_meta' );
467
468
			// Clear total stock transient
469
			delete_transient( 'wc_product_total_stock_' . $this->id . WC_Cache_Helper::get_transient_version( 'product' ) );
470
471
			// Stock status
472
			$this->check_stock_status();
473
474
			// Sync the parent
475
			WC_Product_Variable::sync( $this->id );
476
477
			// Trigger action
478
			do_action( 'woocommerce_variation_set_stock', $this );
479
480
		// If not managing stock and clearing the stock meta, trigger action to indicate that stock has changed (infinite stock)
481
		} elseif ( '' === $amount ) {
482
483
			delete_post_meta( $this->variation_id, '_stock' );
484
485
			// Trigger action
486
			do_action( 'woocommerce_variation_set_stock', $this );
487
488
		// If not managing stock and setting stock, apply changes to the parent
489
		} elseif ( ! is_null( $amount ) ) {
490
			return $this->parent->set_stock( $amount, $mode );
491
		}
492
493
		return $this->get_stock_quantity();
494
	}
495
496
	/**
497
	 * Set stock status.
498
	 *
499
	 * @param string $status
500
	 */
501
	public function set_stock_status( $status ) {
502
		$status = 'outofstock' === $status ? 'outofstock' : 'instock';
503
504
		// Sanity check
505
		if ( true === $this->managing_stock() ) {
506
			if ( ! $this->backorders_allowed() && $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
507
				$status = 'outofstock';
508
			}
509
		} elseif ( 'parent' === $this->managing_stock() ) {
510 View Code Duplication
			if ( ! $this->parent->backorders_allowed() && $this->parent->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
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...
511
				$status = 'outofstock';
512
			}
513
		}
514
515
		if ( update_post_meta( $this->variation_id, '_stock_status', $status ) ) {
516
			do_action( 'woocommerce_variation_set_stock_status', $this->variation_id, $status );
517
518
			WC_Product_Variable::sync_stock_status( $this->id );
519
		}
520
	}
521
522
	/**
523
	 * Reduce stock level of the product.
524
	 *
525
	 * @param int $amount (default: 1) Amount to reduce by
526
	 * @return int stock level
527
	 */
528
	public function reduce_stock( $amount = 1 ) {
529
		if ( true === $this->managing_stock() ) {
530
			return $this->set_stock( $amount, 'subtract' );
531
		} else {
532
			return $this->parent->reduce_stock( $amount );
533
		}
534
	}
535
536
	/**
537
	 * Increase stock level of the product.
538
	 *
539
	 * @param int $amount (default: 1) Amount to increase by
540
	 * @return int stock level
541
	 */
542
	public function increase_stock( $amount = 1 ) {
543
		if ( true === $this->managing_stock() ) {
544
			return $this->set_stock( $amount, 'add' );
545
		} else {
546
			return $this->parent->increase_stock( $amount );
547
		}
548
	}
549
550
	/**
551
	 * Returns whether or not the product needs to notify the customer on backorder.
552
	 *
553
	 * @return bool
554
	 */
555
	public function backorders_require_notification() {
556
		if ( true === $this->managing_stock() ) {
557
			return parent::backorders_require_notification();
558
		} else {
559
			return $this->parent->backorders_require_notification();
560
		}
561
	}
562
563
	/**
564
	 * Is on backorder?
565
	 *
566
	 * @param int $qty_in_cart (default: 0)
567
	 * @return bool
568
	 */
569
	public function is_on_backorder( $qty_in_cart = 0 ) {
570
		if ( true === $this->managing_stock() ) {
571
			return parent::is_on_backorder( $qty_in_cart );
572
		} else {
573
			return $this->parent->is_on_backorder( $qty_in_cart );
574
		}
575
	}
576
577
	/**
578
	 * Returns whether or not the product has enough stock for the order.
579
	 *
580
	 * @param mixed $quantity
581
	 * @return bool
582
	 */
583
	public function has_enough_stock( $quantity ) {
584
		if ( true === $this->managing_stock() ) {
585
			return parent::has_enough_stock( $quantity );
586
		} else {
587
			return $this->parent->has_enough_stock( $quantity );
588
		}
589
	}
590
591
	/**
592
	 * Get the shipping class, and if not set, get the shipping class of the parent.
593
	 *
594
	 * @return string
595
	 */
596 View Code Duplication
	public function get_shipping_class() {
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...
597
		if ( ! $this->variation_shipping_class ) {
598
			$classes = get_the_terms( $this->variation_id, 'product_shipping_class' );
599
600
			if ( $classes && ! is_wp_error( $classes ) ) {
601
				$this->variation_shipping_class = current( $classes )->slug;
602
			} else {
603
				$this->variation_shipping_class = parent::get_shipping_class();
604
			}
605
		}
606
		return $this->variation_shipping_class;
607
	}
608
609
	/**
610
	 * Returns the product shipping class ID.
611
	 *
612
	 * @return int
613
	 */
614 View Code Duplication
	public function get_shipping_class_id() {
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...
615
		if ( ! $this->variation_shipping_class_id ) {
616
			$classes = get_the_terms( $this->variation_id, 'product_shipping_class' );
617
618
			if ( $classes && ! is_wp_error( $classes ) ) {
619
				$this->variation_shipping_class_id = current( $classes )->term_id;
620
			} else {
621
				$this->variation_shipping_class_id = parent::get_shipping_class_id();
622
			}
623
		}
624
		return absint( $this->variation_shipping_class_id );
625
	}
626
627
	/**
628
	 * Get formatted variation data with WC < 2.4 back compat and proper formatting of text-based attribute names.
629
	 *
630
	 * @return string
631
	 */
632
	public function get_formatted_variation_attributes( $flat = false ) {
633
		$variation_data = $this->get_variation_attributes();
634
		$attributes     = $this->parent->get_attributes();
635
		$description    = array();
636
		$return         = '';
637
638
		if ( is_array( $variation_data ) ) {
639
640
			if ( ! $flat ) {
641
				$return = '<dl class="variation">';
642
			}
643
644
			foreach ( $attributes as $attribute ) {
645
646
				// Only deal with attributes that are variations
647
				if ( ! $attribute['is_variation'] ) {
648
					continue;
649
				}
650
651
				$variation_selected_value = isset( $variation_data[ 'attribute_' . sanitize_title( $attribute['name'] ) ] ) ? $variation_data[ 'attribute_' . sanitize_title( $attribute['name'] ) ] : '';
652
				$description_name         = esc_html( wc_attribute_label( $attribute['name'] ) );
653
				$description_value        = __( 'Any', 'woocommerce' );
654
655
				// Get terms for attribute taxonomy or value if its a custom attribute
656
				if ( $attribute['is_taxonomy'] ) {
657
658
					$post_terms = get_the_terms( $this->id, $attribute['name'] );
659
660
					foreach ( $post_terms as $term ) {
661
						if ( $variation_selected_value === $term->slug ) {
662
							$description_value = esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) );
663
						}
664
					}
665
				} else {
666
667
					$options = wc_get_text_attributes( $attribute['value'] );
668
669
					foreach ( $options as $option ) {
670
671
						if ( sanitize_title( $variation_selected_value ) === $variation_selected_value ) {
672
							if ( sanitize_title( $option ) !== $variation_selected_value ) {
673
								continue;
674
							}
675
						} else {
676
							if ( $variation_selected_value !== $option ) {
677
								continue;
678
							}
679
						}
680
681
						$description_value = esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) );
682
					}
683
				}
684
685
				if ( $flat ) {
686
					$description[] = $description_name . ': ' . rawurldecode( $description_value );
687
				} else {
688
					$description[] = '<dt>' . $description_name . ':</dt><dd>' . rawurldecode( $description_value ) . '</dd>';
689
				}
690
			}
691
692
			if ( $flat ) {
693
				$return .= implode( ', ', $description );
694
			} else {
695
				$return .= implode( '', $description );
696
			}
697
698
			if ( ! $flat ) {
699
				$return .= '</dl>';
700
			}
701
		}
702
703
		return $return;
704
	}
705
706
	/**
707
	 * Get product name with extra details such as SKU, price and attributes. Used within admin.
708
	 *
709
	 * @return string Formatted product name, including attributes and price
710
	 */
711
	public function get_formatted_name() {
712
		if ( $this->get_sku() ) {
713
			$identifier = $this->get_sku();
714
		} else {
715
			$identifier = '#' . $this->variation_id;
716
		}
717
718
		$formatted_attributes = $this->get_formatted_variation_attributes( true );
719
		$extra_data           = ' &ndash; ' . $formatted_attributes . ' &ndash; ' . wc_price( $this->get_price() );
720
721
		return sprintf( __( '%1$s &ndash; %2$s%3$s', 'woocommerce' ), $identifier, $this->get_title(), $extra_data );
722
	}
723
724
	/**
725
	 * Get product variation description.
726
	 *
727
	 * @return string
728
	 */
729
	public function get_variation_description() {
730
		return wpautop( do_shortcode( wp_kses_post( get_post_meta( $this->variation_id, '_variation_description', true ) ) ) );
731
	}
732
}
733