Completed
Pull Request — master (#10259)
by Mike
08:16
created

WC_Order::get_shipping_city()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
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 18 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
 * Order Class.
9
 *
10
 * These are regular WooCommerce orders, which extend the abstract order class.
11
 *
12
 * @class    WC_Order
13
 * @version  2.2.0
14
 * @package  WooCommerce/Classes
15
 * @category Class
16
 * @author   WooThemes
17
 */
18
class WC_Order extends WC_Abstract_Order {
19
20
	/**
21
	 * Stores data about status changes so relevant hooks can be fired.
22
	 * @var bool|array
23
	 */
24
	protected $_status_transition = false;
25
26
	/**
27
	 * Extend the abstract _data properties and then read the order object.
28
	 *
29
	 * @param  int|object|WC_Order $order Order to init.
30
	 */
31
	public function __construct( $order = 0 ) {
32
		$this->_data = array_merge( $this->_data, array(
33
			'billing'              => array(
34
				'first_name'       => '',
35
				'last_name'        => '',
36
				'company'          => '',
37
				'address_1'        => '',
38
				'address_2'        => '',
39
				'city'             => '',
40
				'state'            => '',
41
				'postcode'         => '',
42
				'country'          => '',
43
				'email'            => '',
44
				'phone'            => '',
45
			),
46
			'shipping'             => array(
47
				'first_name'       => '',
48
				'last_name'        => '',
49
				'company'          => '',
50
				'address_1'        => '',
51
				'address_2'        => '',
52
				'city'             => '',
53
				'state'            => '',
54
				'postcode'         => '',
55
				'country'          => '',
56
			),
57
			'payment_method'       => '',
58
			'payment_method_title' => '',
59
			'transaction_id'       => '',
60
			'customer_ip_address'  => '',
61
			'customer_user_agent'  => '',
62
			'created_via'          => '',
63
			'customer_note'        => '',
64
			'date_completed'       => '',
65
			'date_paid'            => '',
66
			'cart_hash'            => '',
67
		) );
68
		parent::__construct( $order );
69
	}
70
71
	/**
72
	 * When a payment is complete this function is called.
73
	 *
74
	 * Most of the time this should mark an order as 'processing' so that admin can process/post the items.
75
	 * If the cart contains only downloadable items then the order is 'completed' since the admin needs to take no action.
76
	 * Stock levels are reduced at this point.
77
	 * Sales are also recorded for products.
78
	 * Finally, record the date of payment.
79
	 *
80
	 * @param string $transaction_id Optional transaction id to store in post meta.
81
	 */
82
	public function payment_complete( $transaction_id = '' ) {
83
		do_action( 'woocommerce_pre_payment_complete', $this->get_id() );
84
85
		if ( ! empty( WC()->session ) ) {
86
			WC()->session->set( 'order_awaiting_payment', false );
87
		}
88
89
		if ( $this->get_id() && $this->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ) ) ) {
90
			$order_needs_processing = false;
91
92
			if ( sizeof( $this->get_items() ) > 0 ) {
93
				foreach ( $this->get_items() as $item ) {
94
					if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) {
95
						$virtual_downloadable_item = $product->is_downloadable() && $product->is_virtual();
96
97
						if ( apply_filters( 'woocommerce_order_item_needs_processing', ! $virtual_downloadable_item, $product, $this->get_id() ) ) {
98
							$order_needs_processing = true;
99
							break;
100
						}
101
					}
102
				}
103
			}
104
105
			if ( ! empty( $transaction_id ) ) {
106
				$this->set_transaction_id( $transaction_id );
107
			}
108
109
			$this->set_status( apply_filters( 'woocommerce_payment_complete_order_status', $order_needs_processing ? 'processing' : 'completed', $this->get_id() ) );
110
			$this->set_date_paid( current_time( 'timestamp' ) );
111
			$this->save();
112
113
			do_action( 'woocommerce_payment_complete', $this->get_id() );
114
		} else {
115
			do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->get_id() );
116
		}
117
	}
118
119
	/**
120
	 * Gets order total - formatted for display.
121
	 * @return string
122
	 */
123
	public function get_formatted_order_total( $tax_display = '', $display_refunded = true ) {
124
		$formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_currency() ) );
125
		$order_total    = $this->get_total();
126
		$total_refunded = $this->get_total_refunded();
127
		$tax_string     = '';
128
129
		// Tax for inclusive prices
130
		if ( wc_tax_enabled() && 'incl' == $tax_display ) {
131
			$tax_string_array = array();
132
133
			if ( 'itemized' == get_option( 'woocommerce_tax_total_display' ) ) {
134
				foreach ( $this->get_tax_totals() as $code => $tax ) {
135
					$tax_amount         = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_currency() ) ) : $tax->formatted_amount;
136
					$tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label );
137
				}
138
			} else {
139
				$tax_amount         = ( $total_refunded && $display_refunded ) ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax();
140
				$tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_currency() ) ), WC()->countries->tax_or_vat() );
141
			}
142
			if ( ! empty( $tax_string_array ) ) {
143
				$tax_string = ' ' . sprintf( __( '(Includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) );
144
			}
145
		}
146
147
		if ( $total_refunded && $display_refunded ) {
148
			$formatted_total = '<del>' . strip_tags( $formatted_total ) . '</del> <ins>' . wc_price( $order_total - $total_refunded, array( 'currency' => $this->get_currency() ) ) . $tax_string . '</ins>';
149
		} else {
150
			$formatted_total .= $tax_string;
151
		}
152
153
		return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this );
154
	}
155
156
	/*
157
	|--------------------------------------------------------------------------
158
	| CRUD methods
159
	|--------------------------------------------------------------------------
160
	|
161
	| Methods which create, read, update and delete orders from the database.
162
	| Written in abstract fashion so that the way orders are stored can be
163
	| changed more easily in the future.
164
	|
165
	| A save method is included for convenience (chooses update or create based
166
	| on if the order exists yet).
167
	|
168
	*/
169
170
	/**
171
	 * Insert data into the database.
172
	 * @since 2.6.0
173
	 */
174 View Code Duplication
	public function create() {
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...
175
		parent::create();
176
177
		// Store additonal order data
178
		if ( $this->get_id() ) {
179
			$this->update_post_meta( '_billing_first_name', $this->get_billing_first_name() );
180
			$this->update_post_meta( '_billing_last_name', $this->get_billing_last_name() );
181
			$this->update_post_meta( '_billing_company', $this->get_billing_company() );
182
			$this->update_post_meta( '_billing_address_1', $this->get_billing_address_1() );
183
			$this->update_post_meta( '_billing_address_2', $this->get_billing_address_2() );
184
			$this->update_post_meta( '_billing_city', $this->get_billing_city() );
185
			$this->update_post_meta( '_billing_state', $this->get_billing_state() );
186
			$this->update_post_meta( '_billing_postcode', $this->get_billing_postcode() );
187
			$this->update_post_meta( '_billing_country', $this->get_billing_country() );
188
			$this->update_post_meta( '_billing_email', $this->get_billing_email() );
189
			$this->update_post_meta( '_billing_phone', $this->get_billing_phone() );
190
			$this->update_post_meta( '_shipping_first_name', $this->get_shipping_first_name() );
191
			$this->update_post_meta( '_shipping_last_name', $this->get_shipping_last_name() );
192
			$this->update_post_meta( '_shipping_company', $this->get_shipping_company() );
193
			$this->update_post_meta( '_shipping_address_1', $this->get_shipping_address_1() );
194
			$this->update_post_meta( '_shipping_address_2', $this->get_shipping_address_2() );
195
			$this->update_post_meta( '_shipping_city', $this->get_shipping_city() );
196
			$this->update_post_meta( '_shipping_state', $this->get_shipping_state() );
197
			$this->update_post_meta( '_shipping_postcode', $this->get_shipping_postcode() );
198
			$this->update_post_meta( '_shipping_country', $this->get_shipping_country() );
199
			$this->update_post_meta( '_payment_method', $this->get_payment_method() );
200
			$this->update_post_meta( '_payment_method_title', $this->get_payment_method_title() );
201
			$this->update_post_meta( '_transaction_id', $this->get_transaction_id() );
202
			$this->update_post_meta( '_customer_ip_address', $this->get_customer_ip_address() );
203
			$this->update_post_meta( '_customer_user_agent', $this->get_customer_user_agent() );
204
			$this->update_post_meta( '_created_via', $this->get_created_via() );
205
			$this->update_post_meta( '_customer_note', $this->get_customer_note() );
206
			$this->update_post_meta( '_date_completed', $this->get_date_completed() );
207
			$this->update_post_meta( '_date_paid', $this->get_date_paid() );
208
			$this->update_post_meta( '_cart_hash', $this->get_cart_hash() );
209
			do_action( 'woocommerce_new_order', $this->get_id() );
210
		}
211
	}
212
213
	/**
214
	 * Read from the database.
215
	 * @since 2.6.0
216
	 * @param int $id ID of object to read.
217
	 */
218
	public function read( $id ) {
219
		parent::read( $id );
220
221
		// Read additonal order data
222
		if ( $order_id = $this->get_id() ) {
223
			$post_object = get_post( $this->get_id() );
224
			$this->set_billing_first_name( get_post_meta( $order_id, '_billing_first_name', true ) );
225
			$this->set_billing_last_name( get_post_meta( $order_id, '_billing_last_name', true ) );
226
			$this->set_billing_company( get_post_meta( $order_id, '_billing_company', true ) );
227
			$this->set_billing_address_1( get_post_meta( $order_id, '_billing_address_1', true ) );
228
			$this->set_billing_address_2( get_post_meta( $order_id, '_billing_address_2', true ) );
229
			$this->set_billing_city( get_post_meta( $order_id, '_billing_city', true ) );
230
			$this->set_billing_state( get_post_meta( $order_id, '_billing_state', true ) );
231
			$this->set_billing_postcode( get_post_meta( $order_id, '_billing_postcode', true ) );
232
			$this->set_billing_country( get_post_meta( $order_id, '_billing_country', true ) );
233
			$this->set_billing_email( get_post_meta( $order_id, '_billing_email', true ) );
234
			$this->set_billing_phone( get_post_meta( $order_id, '_billing_phone', true ) );
235
			$this->set_shipping_first_name( get_post_meta( $order_id, '_shipping_first_name', true ) );
236
			$this->set_shipping_last_name( get_post_meta( $order_id, '_shipping_last_name', true ) );
237
			$this->set_shipping_company( get_post_meta( $order_id, '_shipping_company', true ) );
238
			$this->set_shipping_address_1( get_post_meta( $order_id, '_shipping_address_1', true ) );
239
			$this->set_shipping_address_2( get_post_meta( $order_id, '_shipping_address_2', true ) );
240
			$this->set_shipping_city( get_post_meta( $order_id, '_shipping_city', true ) );
241
			$this->set_shipping_state( get_post_meta( $order_id, '_shipping_state', true ) );
242
			$this->set_shipping_postcode( get_post_meta( $order_id, '_shipping_postcode', true ) );
243
			$this->set_shipping_country( get_post_meta( $order_id, '_shipping_country', true ) );
244
			$this->set_payment_method( get_post_meta( $order_id, '_payment_method', true ) );
245
			$this->set_payment_method_title( get_post_meta( $order_id, '_payment_method_title', true ) );
246
			$this->set_transaction_id( get_post_meta( $order_id, '_transaction_id', true ) );
247
			$this->set_customer_ip_address( get_post_meta( $order_id, '_customer_ip_address', true ) );
248
			$this->set_customer_user_agent( get_post_meta( $order_id, '_customer_user_agent', true ) );
249
			$this->set_created_via( get_post_meta( $order_id, '_created_via', true ) );
250
			$this->set_customer_note( get_post_meta( $order_id, '_customer_note', true ) );
251
			$this->set_date_completed( get_post_meta( $order_id, '_completed_date', true ) );
252
			$this->set_date_paid( get_post_meta( $order_id, '_paid_date', true ) );
253
			$this->set_cart_hash( get_post_meta( $order_id, '_cart_hash', true ) );
254
			$this->set_customer_note( $post_object->post_excerpt );
255
256
			// Map user data
257
			if ( ! $this->get_billing_email() && ( $user = $this->get_user() ) ) {
258
				$this->set_billing_email( $user->user_email );
259
			}
260
		}
261
	}
262
263
	/**
264
	 * Update data in the database.
265
	 * @since 2.6.0
266
	 */
267 View Code Duplication
	public function update() {
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...
268
		parent::update();
269
270
		// Store additonal order data
271
		$this->update_post_meta( '_billing_first_name', $this->get_billing_first_name() );
272
		$this->update_post_meta( '_billing_last_name', $this->get_billing_last_name() );
273
		$this->update_post_meta( '_billing_company', $this->get_billing_company() );
274
		$this->update_post_meta( '_billing_address_1', $this->get_billing_address_1() );
275
		$this->update_post_meta( '_billing_address_2', $this->get_billing_address_2() );
276
		$this->update_post_meta( '_billing_city', $this->get_billing_city() );
277
		$this->update_post_meta( '_billing_state', $this->get_billing_state() );
278
		$this->update_post_meta( '_billing_postcode', $this->get_billing_postcode() );
279
		$this->update_post_meta( '_billing_country', $this->get_billing_country() );
280
		$this->update_post_meta( '_billing_email', $this->get_billing_email() );
281
		$this->update_post_meta( '_billing_phone', $this->get_billing_phone() );
282
		$this->update_post_meta( '_shipping_first_name', $this->get_shipping_first_name() );
283
		$this->update_post_meta( '_shipping_last_name', $this->get_shipping_last_name() );
284
		$this->update_post_meta( '_shipping_company', $this->get_shipping_company() );
285
		$this->update_post_meta( '_shipping_address_1', $this->get_shipping_address_1() );
286
		$this->update_post_meta( '_shipping_address_2', $this->get_shipping_address_2() );
287
		$this->update_post_meta( '_shipping_city', $this->get_shipping_city() );
288
		$this->update_post_meta( '_shipping_state', $this->get_shipping_state() );
289
		$this->update_post_meta( '_shipping_postcode', $this->get_shipping_postcode() );
290
		$this->update_post_meta( '_shipping_country', $this->get_shipping_country() );
291
		$this->update_post_meta( '_payment_method', $this->get_payment_method() );
292
		$this->update_post_meta( '_payment_method_title', $this->get_payment_method_title() );
293
		$this->update_post_meta( '_transaction_id', $this->get_transaction_id() );
294
		$this->update_post_meta( '_customer_ip_address', $this->get_customer_ip_address() );
295
		$this->update_post_meta( '_customer_user_agent', $this->get_customer_user_agent() );
296
		$this->update_post_meta( '_created_via', $this->get_created_via() );
297
		$this->update_post_meta( '_customer_note', $this->get_customer_note() );
298
		$this->update_post_meta( '_date_completed', $this->get_date_completed() );
299
		$this->update_post_meta( '_date_paid', $this->get_date_paid() );
300
		$this->update_post_meta( '_cart_hash', $this->get_cart_hash() );
301
302
		// Handle status change
303
		$this->status_transition();
304
	}
305
306
	/**
307
	 * Set order status.
308
	 * @since 2.6.0
309
	 * @param string $new_status Status to change the order to. No internal wc- prefix is required.
310
	 * @param string $note (default: '') Optional note to add.
311
	 * @param bool $manual is this a manual order status change?
0 ignored issues
show
Documentation introduced by
There is no parameter named $manual. Did you maybe mean $manual_update?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
312
	 * @param array details of change
313
	 */
314
	public function set_status( $new_status, $note = '', $manual_update = false ) {
315
		$result = parent::set_status( $new_status );
316
317
		if ( ! empty( $result['from'] ) && $result['from'] !== $result['to'] ) {
318
			$this->_status_transition = array(
319
				'from'   => ! empty( $this->_status_transition['from'] ) ? $this->_status_transition['from'] : $result['from'],
320
				'to'     => $result['to'],
321
				'note'   => $note,
322
				'manual' => (bool) $manual_update,
323
			);
324
325
			if ( 'completed' === $result['to'] ) {
326
				$this->set_date_completed( current_time( 'timestamp' ) );
327
			}
328
		}
329
330
		return $result;
331
	}
332
333
	/**
334
	 * Updates status of order immediately.
335
	 * @uses WC_Order::set_status()
336
	 */
337
	public function update_status( $new_status, $note = '', $manual = false ) {
338
		if ( ! $this->get_id() ) {
339
			return false;
340
		}
341
		$this->set_status( $new_status, $note, $manual );
342
		$this->save();
343
		return true;
344
	}
345
346
	/**
347
	 * Handle the status transition.
348
	 */
349
	protected function status_transition() {
350
		if ( $this->_status_transition ) {
351
			if ( ! empty( $this->_status_transition['from'] ) ) {
352
				$transition_note = sprintf( __( 'Order status changed from %s to %s.', 'woocommerce' ), wc_get_order_status_name( $this->_status_transition['from'] ), wc_get_order_status_name( $this->_status_transition['to'] ) );
353
354
				do_action( 'woocommerce_order_status_' . $this->_status_transition['from'] . '_to_' . $this->_status_transition['to'], $this->get_id() );
355
				do_action( 'woocommerce_order_status_changed', $this->get_id(), $this->_status_transition['from'], $this->_status_transition['to'] );
356
			} else {
357
				$transition_note = sprintf( __( 'Order status set to %s.', 'woocommerce' ), wc_get_order_status_name( $this->_status_transition['to'] ) );
358
			}
359
360
			do_action( 'woocommerce_order_status_' . $this->_status_transition['to'], $this->get_id() );
361
362
			// Note the transition occured
363
			$this->add_order_note( trim( $this->_status_transition['note'] . ' ' . $transition_note ), 0, $this->_status_transition['manual'] );
364
365
			// This has ran, so reset status transition variable
366
			$this->_status_transition = false;
367
		}
368
	}
369
370
	/*
371
	|--------------------------------------------------------------------------
372
	| Getters
373
	|--------------------------------------------------------------------------
374
	|
375
	| Methods for getting data from the order object.
376
	|
377
	*/
378
379
	/**
380
	 * Get billing_first_name
381
	 * @return string
382
	 */
383
	public function get_billing_first_name() {
384
		return $this->_data['billing']['first_name'];
385
	}
386
387
	/**
388
	 * Get billing_last_name
389
	 * @return string
390
	 */
391
	public function get_billing_last_name() {
392
		return $this->_data['billing']['last_name'];
393
	}
394
395
	/**
396
	 * Get billing_company
397
	 * @return string
398
	 */
399
	public function get_billing_company() {
400
		return $this->_data['billing']['company'];
401
	}
402
403
	/**
404
	 * Get billing_address_1
405
	 * @return string
406
	 */
407
	public function get_billing_address_1() {
408
		return $this->_data['billing']['address_1'];
409
	}
410
411
	/**
412
	 * Get billing_address_2
413
	 * @return string $value
414
	 */
415
	public function get_billing_address_2() {
416
		return $this->_data['billing']['address_2'];
417
	}
418
419
	/**
420
	 * Get billing_city
421
	 * @return string $value
422
	 */
423
	public function get_billing_city() {
424
		return $this->_data['billing']['city'];
425
	}
426
427
	/**
428
	 * Get billing_state
429
	 * @return string
430
	 */
431
	public function get_billing_state() {
432
		return $this->_data['billing']['state'];
433
	}
434
435
	/**
436
	 * Get billing_postcode
437
	 * @return string
438
	 */
439
	public function get_billing_postcode() {
440
		return $this->_data['billing']['postcode'];
441
	}
442
443
	/**
444
	 * Get billing_country
445
	 * @return string
446
	 */
447
	public function get_billing_country() {
448
		return $this->_data['billing']['country'];
449
	}
450
451
	/**
452
	 * Get billing_email
453
	 * @return string
454
	 */
455
	public function get_billing_email() {
456
		return sanitize_email( $this->_data['billing']['email'] );
457
	}
458
459
	/**
460
	 * Get billing_phone
461
	 * @return string
462
	 */
463
	public function get_billing_phone() {
464
		return $this->_data['billing']['phone'];
465
	}
466
467
	/**
468
	 * Get shipping_first_name
469
	 * @return string
470
	 */
471
	public function get_shipping_first_name() {
472
		return $this->_data['shipping']['first_name'];
473
	}
474
475
	/**
476
	 * Get shipping_last_name
477
	 * @return string
478
	 */
479
	public function get_shipping_last_name() {
480
		 return $this->_data['shipping']['last_name'];
481
	}
482
483
	/**
484
	 * Get shipping_company
485
	 * @return string
486
	 */
487
	public function get_shipping_company() {
488
		return $this->_data['shipping']['company'];
489
	}
490
491
	/**
492
	 * Get shipping_address_1
493
	 * @return string
494
	 */
495
	public function get_shipping_address_1() {
496
		return $this->_data['shipping']['address_1'];
497
	}
498
499
	/**
500
	 * Get shipping_address_2
501
	 * @return string
502
	 */
503
	public function get_shipping_address_2() {
504
		return $this->_data['shipping']['address_2'];
505
	}
506
507
	/**
508
	 * Get shipping_city
509
	 * @return string
510
	 */
511
	public function get_shipping_city() {
512
		return $this->_data['shipping']['city'];
513
	}
514
515
	/**
516
	 * Get shipping_state
517
	 * @return string
518
	 */
519
	public function get_shipping_state() {
520
		return $this->_data['shipping']['state'];
521
	}
522
523
	/**
524
	 * Get shipping_postcode
525
	 * @return string
526
	 */
527
	public function get_shipping_postcode() {
528
		return $this->_data['shipping']['postcode'];
529
	}
530
531
	/**
532
	 * Get shipping_country
533
	 * @return string
534
	 */
535
	public function get_shipping_country() {
536
		return $this->_data['shipping']['country'];
537
	}
538
539
	/**
540
	 * Get the payment method.
541
	 * @return string
542
	 */
543
	public function get_payment_method() {
544
		return $this->_data['payment_method'];
545
	}
546
547
	/**
548
	 * Get payment_method_title
549
	 * @return string
550
	 */
551
	public function get_payment_method_title() {
552
		return $this->_data['payment_method_title'];
553
	}
554
555
	/**
556
	 * Get transaction_id
557
	 * @return string
558
	 */
559
	public function get_transaction_id() {
560
		return $this->_data['transaction_id'];
561
	}
562
563
	/**
564
	 * Get customer_ip_address
565
	 * @return string
566
	 */
567
	public function get_customer_ip_address() {
568
		return $this->_data['customer_ip_address'];
569
	}
570
571
	/**
572
	 * Get customer_user_agent
573
	 * @return string
574
	 */
575
	public function get_customer_user_agent() {
576
		return $this->_data['customer_user_agent'];
577
	}
578
579
	/**
580
	 * Get created_via
581
	 * @return string
582
	 */
583
	public function get_created_via() {
584
		return $this->_data['created_via'];
585
	}
586
587
	/**
588
	 * Get customer_note
589
	 * @return string
590
	 */
591
	public function get_customer_note() {
592
		return $this->_data['customer_note'];
593
	}
594
595
	/**
596
	 * Get date_completed
597
	 * @return int
598
	 */
599
	public function get_date_completed() {
600
		return absint( $this->_data['date_completed'] );
601
	}
602
603
	/**
604
	 * Get date_paid
605
	 * @return int
606
	 */
607
	public function get_date_paid() {
608
		return absint( $this->_data['date_paid'] );
609
	}
610
611
	/**
612
	 * Returns the requested address in raw, non-formatted way.
613
	 * @since  2.4.0
614
	 * @param  string $type Billing or shipping. Anything else besides 'billing' will return shipping address.
615
	 * @return array The stored address after filter.
616
	 */
617
	public function get_address( $type = 'billing' ) {
618
		return apply_filters( 'woocommerce_get_order_address', isset( $this->_data[ $type ] ) ? $this->_data[ $type ] : array(), $type, $this );
619
	}
620
621
	/**
622
	 * Get a formatted shipping address for the order.
623
	 *
624
	 * @return string
625
	 */
626
	public function get_shipping_address_map_url() {
627
		$address = apply_filters( 'woocommerce_shipping_address_map_url_parts', $this->get_address( 'shipping' ), $this );
628
		return apply_filters( 'woocommerce_shipping_address_map_url', 'http://maps.google.com/maps?&q=' . urlencode( implode( ', ', $address ) ) . '&z=16', $this );
629
	}
630
631
	/**
632
	 * Get a formatted billing full name.
633
	 *
634
	 * @since 2.4.0
635
	 *
636
	 * @return string
637
	 */
638
	public function get_formatted_billing_full_name() {
639
		return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_billing_first_name(), $this->get_billing_last_name() );
640
	}
641
642
	/**
643
	 * Get a formatted shipping full name.
644
	 *
645
	 * @since 2.4.0
646
	 *
647
	 * @return string
648
	 */
649
	public function get_formatted_shipping_full_name() {
650
		return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_shipping_first_name(), $this->get_shipping_last_name() );
651
	}
652
653
	/**
654
	 * Get a formatted billing address for the order.
655
	 * @return string
656
	 */
657
	public function get_formatted_billing_address() {
658
		return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_order_formatted_billing_address', $this->get_address( 'billing' ), $this ) );
659
	}
660
661
	/**
662
	 * Get a formatted shipping address for the order.
663
	 * @return string
664
	 */
665
	public function get_formatted_shipping_address() {
666
		if ( $this->get_shipping_address_1() || $this->get_shipping_address_2() ) {
667
			return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_order_formatted_shipping_address', $this->get_address( 'shipping' ), $this ) );
668
		} else {
669
			return '';
670
		}
671
	}
672
673
	/**
674
	 * Get cart hash
675
	 * @return string
676
	 */
677
	public function get_cart_hash() {
678
		return $this->_data['cart_hash'];
679
	}
680
681
	/*
682
	|--------------------------------------------------------------------------
683
	| Setters
684
	|--------------------------------------------------------------------------
685
	|
686
	| Functions for setting order data. These should not update anything in the
687
	| database itself and should only change what is stored in the class
688
	| object. However, for backwards compatibility pre 2.6.0 some of these
689
	| setters may handle both.
690
	|
691
	*/
692
693
	/**
694
	 * Set billing_first_name
695
	 * @param string $value
696
	 */
697
	public function set_billing_first_name( $value ) {
698
		$this->_data['billing']['first_name'] = $value;
699
	}
700
701
	/**
702
	 * Set billing_last_name
703
	 * @param string $value
704
	 */
705
	public function set_billing_last_name( $value ) {
706
		$this->_data['billing']['last_name'] = $value;
707
	}
708
709
	/**
710
	 * Set billing_company
711
	 * @param string $value
712
	 */
713
	public function set_billing_company( $value ) {
714
		$this->_data['billing']['company'] = $value;
715
	}
716
717
	/**
718
	 * Set billing_address_1
719
	 * @param string $value
720
	 */
721
	public function set_billing_address_1( $value ) {
722
		$this->_data['billing']['address_1'] = $value;
723
	}
724
725
	/**
726
	 * Set billing_address_2
727
	 * @param string $value
728
	 */
729
	public function set_billing_address_2( $value ) {
730
		$this->_data['billing']['address_2'] = $value;
731
	}
732
733
	/**
734
	 * Set billing_city
735
	 * @param string $value
736
	 */
737
	public function set_billing_city( $value ) {
738
		$this->_data['billing']['city'] = $value;
739
	}
740
741
	/**
742
	 * Set billing_state
743
	 * @param string $value
744
	 */
745
	public function set_billing_state( $value ) {
746
		$this->_data['billing']['state'] = $value;
747
	}
748
749
	/**
750
	 * Set billing_postcode
751
	 * @param string $value
752
	 */
753
	public function set_billing_postcode( $value ) {
754
		$this->_data['billing']['postcode'] = $value;
755
	}
756
757
	/**
758
	 * Set billing_country
759
	 * @param string $value
760
	 */
761
	public function set_billing_country( $value ) {
762
		$this->_data['billing']['country'] = $value;
763
	}
764
765
	/**
766
	 * Set billing_email
767
	 * @param string $value
768
	 */
769
	public function set_billing_email( $value ) {
770
		$value = sanitize_email( $value );
771
		$this->_data['billing']['email'] = is_email( $value ) ? $value : '';
772
	}
773
774
	/**
775
	 * Set billing_phone
776
	 * @param string $value
777
	 */
778
	public function set_billing_phone( $value ) {
779
		$this->_data['billing']['phone'] = $value;
780
	}
781
782
	/**
783
	 * Set shipping_first_name
784
	 * @param string $value
785
	 */
786
	public function set_shipping_first_name( $value ) {
787
		$this->_data['shipping']['first_name'] = $value;
788
	}
789
790
	/**
791
	 * Set shipping_last_name
792
	 * @param string $value
793
	 */
794
	public function set_shipping_last_name( $value ) {
795
		$this->_data['shipping']['last_name'] = $value;
796
	}
797
798
	/**
799
	 * Set shipping_company
800
	 * @param string $value
801
	 */
802
	public function set_shipping_company( $value ) {
803
		$this->_data['shipping']['company'] = $value;
804
	}
805
806
	/**
807
	 * Set shipping_address_1
808
	 * @param string $value
809
	 */
810
	public function set_shipping_address_1( $value ) {
811
		$this->_data['shipping']['address_1'] = $value;
812
	}
813
814
	/**
815
	 * Set shipping_address_2
816
	 * @param string $value
817
	 */
818
	public function set_shipping_address_2( $value ) {
819
		$this->_data['shipping']['address_2'] = $value;
820
	}
821
822
	/**
823
	 * Set shipping_city
824
	 * @param string $value
825
	 */
826
	public function set_shipping_city( $value ) {
827
		$this->_data['shipping']['city'] = $value;
828
	}
829
830
	/**
831
	 * Set shipping_state
832
	 * @param string $value
833
	 */
834
	public function set_shipping_state( $value ) {
835
		$this->_data['shipping']['state'] = $value;
836
	}
837
838
	/**
839
	 * Set shipping_postcode
840
	 * @param string $value
841
	 */
842
	public function set_shipping_postcode( $value ) {
843
		$this->_data['shipping']['postcode'] = $value;
844
	}
845
846
	/**
847
	 * Set shipping_country
848
	 * @param string $value
849
	 */
850
	public function set_shipping_country( $value ) {
851
		$this->_data['shipping']['country'] = $value;
852
	}
853
854
	/**
855
	 * Set the payment method.
856
	 * @since 2.2.0
857
	 * @param string $value Supports WC_Payment_Gateway for bw compatibility with < 2.6
858
	 */
859
	public function set_payment_method( $value ) {
860
		if ( is_object( $value ) ) {
861
			$this->set_payment_method( $value->id );
862
			$this->set_payment_method_title( $value->get_title() );
863
		} else {
864
			$this->_data['payment_method'] = $value;
865
		}
866
	}
867
868
	/**
869
	 * Set payment_method_title
870
	 * @param string $value
871
	 */
872
	public function set_payment_method_title( $value ) {
873
		$this->_data['payment_method_title'] = $value;
874
	}
875
876
	/**
877
	 * Set transaction_id
878
	 * @param string $value
879
	 */
880
	public function set_transaction_id( $value ) {
881
		$this->_data['transaction_id'] = $value;
882
	}
883
884
	/**
885
	 * Set customer_ip_address
886
	 * @param string $value
887
	 */
888
	public function set_customer_ip_address( $value ) {
889
		$this->_data['customer_ip_address'] = $value;
890
	}
891
892
	/**
893
	 * Set customer_user_agent
894
	 * @param string $value
895
	 */
896
	public function set_customer_user_agent( $value ) {
897
		$this->_data['customer_user_agent'] = $value;
898
	}
899
900
	/**
901
	 * Set created_via
902
	 * @param string $value
903
	 */
904
	public function set_created_via( $value ) {
905
		$this->_data['created_via'] = $value;
906
	}
907
908
	/**
909
	 * Set customer_note
910
	 * @param string $value
911
	 */
912
	public function set_customer_note( $value ) {
913
		$this->_data['customer_note'] = $value;
914
	}
915
916
	/**
917
	 * Set date_completed
918
	 * @param string $timestamp
919
	 */
920
	public function set_date_completed( $timestamp ) {
921
		$this->_data['date_completed'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
922
	}
923
924
	/**
925
	 * Set date_paid
926
	 * @param string $timestamp
927
	 */
928
	public function set_date_paid( $timestamp ) {
929
		$this->_data['date_paid'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
930
	}
931
932
	/**
933
	 * Set cart hash
934
	 * @param string $value
935
	 */
936
	public function set_cart_hash( $value ) {
937
		$this->_data['cart_hash'] = $value;
938
	}
939
940
	/*
941
	|--------------------------------------------------------------------------
942
	| Conditionals
943
	|--------------------------------------------------------------------------
944
	|
945
	| Checks if a condition is true or false.
946
	|
947
	*/
948
949
	/**
950
	 * See if order matches cart_hash.
951
	 * @return bool
952
	 */
953
	public function has_cart_hash( $cart_hash ) {
954
		return hash_equals( $this->get_cart_hash(), $cart_hash );
955
	}
956
957
	/**
958
	 * Checks if an order can be edited, specifically for use on the Edit Order screen.
959
	 * @return bool
960
	 */
961
	public function is_editable() {
962
		return apply_filters( 'wc_order_is_editable', in_array( $this->get_status(), array( 'pending', 'on-hold', 'auto-draft' ) ), $this );
963
	}
964
965
	/**
966
	 * Returns if an order has been paid for based on the order status.
967
	 * @since 2.5.0
968
	 * @return bool
969
	 */
970
	public function is_paid() {
971
		return apply_filters( 'woocommerce_order_is_paid', $this->has_status( apply_filters( 'woocommerce_order_is_paid_statuses', array( 'processing', 'completed' ) ) ), $this );
972
	}
973
974
	/**
975
	 * Checks if product download is permitted.
976
	 *
977
	 * @return bool
978
	 */
979
	public function is_download_permitted() {
980
		return apply_filters( 'woocommerce_order_is_download_permitted', $this->has_status( 'completed' ) || ( 'yes' === get_option( 'woocommerce_downloads_grant_access_after_payment' ) && $this->has_status( 'processing' ) ), $this );
981
	}
982
983
	/**
984
	 * Checks if an order needs display the shipping address, based on shipping method.
985
	 * @return bool
986
	 */
987
	public function needs_shipping_address() {
988
		if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) {
989
			return false;
990
		}
991
992
		$hide  = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this );
993
		$needs_address = false;
994
995
		foreach ( $this->get_shipping_methods() as $shipping_method ) {
996
			if ( ! in_array( $shipping_method['method_id'], $hide ) ) {
997
				$needs_address = true;
998
				break;
999
			}
1000
		}
1001
1002
		return apply_filters( 'woocommerce_order_needs_shipping_address', $needs_address, $hide, $this );
1003
	}
1004
1005
	/**
1006
	 * Returns true if the order contains a downloadable product.
1007
	 * @return bool
1008
	 */
1009
	public function has_downloadable_item() {
1010
		foreach ( $this->get_items() as $item ) {
1011
			if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->is_downloadable() && $product->has_file() ) {
1012
				return true;
1013
			}
1014
		}
1015
		return false;
1016
	}
1017
1018
	/**
1019
	 * Checks if an order needs payment, based on status and order total.
1020
	 *
1021
	 * @return bool
1022
	 */
1023
	public function needs_payment() {
1024
		$valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $this );
1025
		return apply_filters( 'woocommerce_order_needs_payment', ( $this->has_status( $valid_order_statuses ) && $this->get_total() > 0 ), $this, $valid_order_statuses );
1026
	}
1027
1028
	/*
1029
	|--------------------------------------------------------------------------
1030
	| URLs and Endpoints
1031
	|--------------------------------------------------------------------------
1032
	*/
1033
1034
	/**
1035
	 * Generates a URL so that a customer can pay for their (unpaid - pending) order. Pass 'true' for the checkout version which doesn't offer gateway choices.
1036
	 *
1037
	 * @param  bool $on_checkout
1038
	 * @return string
1039
	 */
1040
	public function get_checkout_payment_url( $on_checkout = false ) {
1041
		$pay_url = wc_get_endpoint_url( 'order-pay', $this->get_id(), wc_get_page_permalink( 'checkout' ) );
1042
1043 View Code Duplication
		if ( 'yes' == get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) {
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...
1044
			$pay_url = str_replace( 'http:', 'https:', $pay_url );
1045
		}
1046
1047
		if ( $on_checkout ) {
1048
			$pay_url = add_query_arg( 'key', $this->get_order_key(), $pay_url );
1049
		} else {
1050
			$pay_url = add_query_arg( array( 'pay_for_order' => 'true', 'key' => $this->get_order_key() ), $pay_url );
1051
		}
1052
1053
		return apply_filters( 'woocommerce_get_checkout_payment_url', $pay_url, $this );
1054
	}
1055
1056
	/**
1057
	 * Generates a URL for the thanks page (order received).
1058
	 *
1059
	 * @return string
1060
	 */
1061
	public function get_checkout_order_received_url() {
1062
		$order_received_url = wc_get_endpoint_url( 'order-received', $this->get_id(), wc_get_page_permalink( 'checkout' ) );
1063
1064
		if ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) {
1065
			$order_received_url = str_replace( 'http:', 'https:', $order_received_url );
1066
		}
1067
1068
		$order_received_url = add_query_arg( 'key', $this->get_order_key(), $order_received_url );
1069
1070
		return apply_filters( 'woocommerce_get_checkout_order_received_url', $order_received_url, $this );
1071
	}
1072
1073
	/**
1074
	 * Generates a URL so that a customer can cancel their (unpaid - pending) order.
1075
	 *
1076
	 * @param string $redirect
1077
	 *
1078
	 * @return string
1079
	 */
1080 View Code Duplication
	public function get_cancel_order_url( $redirect = '' ) {
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...
1081
		return apply_filters( 'woocommerce_get_cancel_order_url', wp_nonce_url( add_query_arg( array(
1082
			'cancel_order' => 'true',
1083
			'order'        => $this->get_order_key(),
1084
			'order_id'     => $this->get_id(),
1085
			'redirect'     => $redirect
1086
		), $this->get_cancel_endpoint() ), 'woocommerce-cancel_order' ) );
1087
	}
1088
1089
	/**
1090
	 * Generates a raw (unescaped) cancel-order URL for use by payment gateways.
1091
	 *
1092
	 * @param string $redirect
1093
	 *
1094
	 * @return string The unescaped cancel-order URL.
1095
	 */
1096 View Code Duplication
	public function get_cancel_order_url_raw( $redirect = '' ) {
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...
1097
		return apply_filters( 'woocommerce_get_cancel_order_url_raw', add_query_arg( array(
1098
			'cancel_order' => 'true',
1099
			'order'        => $this->get_order_key(),
1100
			'order_id'     => $this->get_id(),
1101
			'redirect'     => $redirect,
1102
			'_wpnonce'     => wp_create_nonce( 'woocommerce-cancel_order' )
1103
		), $this->get_cancel_endpoint() ) );
1104
	}
1105
1106
	/**
1107
	 * Helper method to return the cancel endpoint.
1108
	 *
1109
	 * @return string the cancel endpoint; either the cart page or the home page.
1110
	 */
1111
	public function get_cancel_endpoint() {
1112
		$cancel_endpoint = wc_get_page_permalink( 'cart' );
1113
		if ( ! $cancel_endpoint ) {
1114
			$cancel_endpoint = home_url();
1115
		}
1116
1117
		if ( false === strpos( $cancel_endpoint, '?' ) ) {
1118
			$cancel_endpoint = trailingslashit( $cancel_endpoint );
1119
		}
1120
1121
		return $cancel_endpoint;
1122
	}
1123
1124
	/**
1125
	 * Generates a URL to view an order from the my account page.
1126
	 *
1127
	 * @return string
1128
	 */
1129
	public function get_view_order_url() {
1130
		return apply_filters( 'woocommerce_get_view_order_url', wc_get_endpoint_url( 'view-order', $this->get_id(), wc_get_page_permalink( 'myaccount' ) ), $this );
1131
	}
1132
1133
	/*
1134
	|--------------------------------------------------------------------------
1135
	| Order notes.
1136
	|--------------------------------------------------------------------------
1137
	*/
1138
1139
	/**
1140
	 * Adds a note (comment) to the order.
1141
	 *
1142
	 * @param string $note Note to add.
1143
	 * @param int $is_customer_note (default: 0) Is this a note for the customer?
1144
	 * @param  bool added_by_user Was the note added by a user?
1145
	 * @return int Comment ID.
1146
	 */
1147
	public function add_order_note( $note, $is_customer_note = 0, $added_by_user = false ) {
1148
		if ( is_user_logged_in() && current_user_can( 'edit_shop_order', $this->get_id() ) && $added_by_user ) {
1149
			$user                 = get_user_by( 'id', get_current_user_id() );
1150
			$comment_author       = $user->display_name;
1151
			$comment_author_email = $user->user_email;
1152
		} else {
1153
			$comment_author       = __( 'WooCommerce', 'woocommerce' );
1154
			$comment_author_email = strtolower( __( 'WooCommerce', 'woocommerce' ) ) . '@';
1155
			$comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com';
1156
			$comment_author_email = sanitize_email( $comment_author_email );
1157
		}
1158
		$commentdata = apply_filters( 'woocommerce_new_order_note_data', array(
1159
			'comment_post_ID'      => $this->get_id(),
1160
			'comment_author'       => $comment_author,
1161
			'comment_author_email' => $comment_author_email,
1162
			'comment_author_url'   => '',
1163
			'comment_content'      => $note,
1164
			'comment_agent'        => 'WooCommerce',
1165
			'comment_type'         => 'order_note',
1166
			'comment_parent'       => 0,
1167
			'comment_approved'     => 1,
1168
		), array( 'order_id' => $this->get_id(), 'is_customer_note' => $is_customer_note ) );
1169
1170
		$comment_id = wp_insert_comment( $commentdata );
1171
1172
		if ( $is_customer_note ) {
1173
			add_comment_meta( $comment_id, 'is_customer_note', 1 );
1174
1175
			do_action( 'woocommerce_new_customer_note', array( 'order_id' => $this->get_id(), 'customer_note' => $commentdata['comment_content'] ) );
1176
		}
1177
1178
		return $comment_id;
1179
	}
1180
1181
	/**
1182
	 * List order notes (public) for the customer.
1183
	 *
1184
	 * @return array
1185
	 */
1186
	public function get_customer_order_notes() {
1187
		$notes = array();
1188
		$args  = array(
1189
			'post_id' => $this->get_id(),
1190
			'approve' => 'approve',
1191
			'type'    => ''
1192
		);
1193
1194
		remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) );
1195
1196
		$comments = get_comments( $args );
1197
1198
		foreach ( $comments as $comment ) {
1199
			if ( ! get_comment_meta( $comment->comment_ID, 'is_customer_note', true ) ) {
1200
				continue;
1201
			}
1202
			$comment->comment_content = make_clickable( $comment->comment_content );
1203
			$notes[] = $comment;
1204
		}
1205
1206
		add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) );
1207
1208
		return $notes;
1209
	}
1210
1211
	/*
1212
	|--------------------------------------------------------------------------
1213
	| Refunds
1214
	|--------------------------------------------------------------------------
1215
	*/
1216
1217
	/**
1218
	 * Get order refunds.
1219
	 * @since 2.2
1220
	 * @return array of WC_Order_Refund objects
1221
	 */
1222
	public function get_refunds() {
1223
		$refunds      = array();
1224
		$refund_items = get_posts(
1225
			array(
1226
				'post_type'      => 'shop_order_refund',
1227
				'post_parent'    => $this->get_id(),
1228
				'posts_per_page' => -1,
1229
				'post_status'    => 'any',
1230
				'fields'         => 'ids'
1231
			)
1232
		);
1233
1234
		foreach ( $refund_items as $refund_id ) {
1235
			$refunds[] = new WC_Order_Refund( $refund_id );
1236
		}
1237
1238
		return $refunds;
1239
	}
1240
1241
	/**
1242
	 * Get amount already refunded.
1243
	 *
1244
	 * @since 2.2
1245
	 * @return string
1246
	 */
1247 View Code Duplication
	public function get_total_refunded() {
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...
1248
		global $wpdb;
1249
1250
		$total = $wpdb->get_var( $wpdb->prepare( "
1251
			SELECT SUM( postmeta.meta_value )
1252
			FROM $wpdb->postmeta AS postmeta
1253
			INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
1254
			WHERE postmeta.meta_key = '_refund_amount'
1255
			AND postmeta.post_id = posts.ID
1256
		", $this->get_id() ) );
1257
1258
		return $total;
1259
	}
1260
1261
	/**
1262
	 * Get the total tax refunded.
1263
	 *
1264
	 * @since  2.3
1265
	 * @return float
1266
	 */
1267 View Code Duplication
	public function get_total_tax_refunded() {
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...
1268
		global $wpdb;
1269
1270
		$total = $wpdb->get_var( $wpdb->prepare( "
1271
			SELECT SUM( order_itemmeta.meta_value )
1272
			FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
1273
			INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
1274
			INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' )
1275
			WHERE order_itemmeta.order_item_id = order_items.order_item_id
1276
			AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount')
1277
		", $this->get_id() ) );
1278
1279
		return abs( $total );
1280
	}
1281
1282
	/**
1283
	 * Get the total shipping refunded.
1284
	 *
1285
	 * @since  2.4
1286
	 * @return float
1287
	 */
1288 View Code Duplication
	public function get_total_shipping_refunded() {
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...
1289
		global $wpdb;
1290
1291
		$total = $wpdb->get_var( $wpdb->prepare( "
1292
			SELECT SUM( order_itemmeta.meta_value )
1293
			FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
1294
			INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
1295
			INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' )
1296
			WHERE order_itemmeta.order_item_id = order_items.order_item_id
1297
			AND order_itemmeta.meta_key IN ('cost')
1298
		", $this->get_id() ) );
1299
1300
		return abs( $total );
1301
	}
1302
1303
	/**
1304
	 * Gets the count of order items of a certain type that have been refunded.
1305
	 * @since  2.4.0
1306
	 * @param string $item_type
1307
	 * @return string
1308
	 */
1309
	public function get_item_count_refunded( $item_type = '' ) {
1310
		if ( empty( $item_type ) ) {
1311
			$item_type = array( 'line_item' );
1312
		}
1313
		if ( ! is_array( $item_type ) ) {
1314
			$item_type = array( $item_type );
1315
		}
1316
		$count = 0;
1317
1318
		foreach ( $this->get_refunds() as $refund ) {
1319
			foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
1320
				$count += $refunded_item->get_qty();
1321
			}
1322
		}
1323
1324
		return apply_filters( 'woocommerce_get_item_count_refunded', $count, $item_type, $this );
1325
	}
1326
1327
	/**
1328
	 * Get the total number of items refunded.
1329
	 *
1330
	 * @since  2.4.0
1331
	 * @param  string $item_type type of the item we're checking, if not a line_item
1332
	 * @return integer
1333
	 */
1334
	public function get_total_qty_refunded( $item_type = 'line_item' ) {
1335
		$qty = 0;
1336
		foreach ( $this->get_refunds() as $refund ) {
1337
			foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
1338
				$qty += $refunded_item->get_qty();
1339
			}
1340
		}
1341
		return $qty;
1342
	}
1343
1344
	/**
1345
	 * Get the refunded amount for a line item.
1346
	 *
1347
	 * @param  int $item_id ID of the item we're checking
1348
	 * @param  string $item_type type of the item we're checking, if not a line_item
1349
	 * @return integer
1350
	 */
1351 View Code Duplication
	public function get_qty_refunded_for_item( $item_id, $item_type = 'line_item' ) {
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...
1352
		$qty = 0;
1353
		foreach ( $this->get_refunds() as $refund ) {
1354
			foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
1355
				if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) {
1356
					$qty += $refunded_item->get_qty();
1357
				}
1358
			}
1359
		}
1360
		return $qty;
1361
	}
1362
1363
	/**
1364
	 * Get the refunded amount for a line item.
1365
	 *
1366
	 * @param  int $item_id ID of the item we're checking
1367
	 * @param  string $item_type type of the item we're checking, if not a line_item
1368
	 * @return integer
1369
	 */
1370 View Code Duplication
	public function get_total_refunded_for_item( $item_id, $item_type = 'line_item' ) {
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...
1371
		$total = 0;
1372
		foreach ( $this->get_refunds() as $refund ) {
1373
			foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
1374
				if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) {
1375
					$total += $refunded_item->get_total();
1376
				}
1377
			}
1378
		}
1379
		return $total * -1;
1380
	}
1381
1382
	/**
1383
	 * Get the refunded amount for a line item.
1384
	 *
1385
	 * @param  int $item_id ID of the item we're checking
1386
	 * @param  int $tax_id ID of the tax we're checking
1387
	 * @param  string $item_type type of the item we're checking, if not a line_item
1388
	 * @return double
1389
	 */
1390 View Code Duplication
	public function get_tax_refunded_for_item( $item_id, $tax_id, $item_type = 'line_item' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $tax_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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...
1391
		$total = 0;
1392
		foreach ( $this->get_refunds() as $refund ) {
1393
			foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
1394
				if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) {
1395
					$total += $refunded_item->get_total_tax();
1396
				}
1397
			}
1398
		}
1399
		return wc_round_tax_total( $total ) * -1;
1400
	}
1401
1402
	/**
1403
	 * Get total tax refunded by rate ID.
1404
	 *
1405
	 * @param  int $rate_id
1406
	 *
1407
	 * @return float
1408
	 */
1409
	public function get_total_tax_refunded_by_rate_id( $rate_id ) {
1410
		$total = 0;
1411
		foreach ( $this->get_refunds() as $refund ) {
1412
			foreach ( $refund->get_items( 'tax' ) as $refunded_item ) {
1413
				if ( absint( $refunded_item->get_rate_id() ) === $rate_id ) {
1414
					$total += abs( $refunded_item->tax_total() ) + abs( $refunded_item->shipping_tax_total() );
1415
				}
1416
			}
1417
		}
1418
1419
		return $total;
1420
	}
1421
1422
	/**
1423
	 * How much money is left to refund?
1424
	 * @return string
1425
	 */
1426
	public function get_remaining_refund_amount() {
1427
		return wc_format_decimal( $this->get_total() - $this->get_total_refunded(), wc_get_price_decimals() );
1428
	}
1429
1430
	/**
1431
	 * How many items are left to refund?
1432
	 * @return int
1433
	 */
1434
	public function get_remaining_refund_items() {
1435
		return absint( $this->get_item_count() - $this->get_item_count_refunded() );
1436
	}
1437
}
1438