Completed
Push — master ( fc6097...930cc3 )
by Mike
08:01
created

wc-cart-functions.php ➔ wc_get_chosen_shipping_method_ids()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 7
c 1
b 1
f 0
nc 2
nop 0
dl 0
loc 9
rs 9.6666
1
<?php
2
/**
3
 * WooCommerce Cart Functions
4
 *
5
 * Functions for cart specific things.
6
 *
7
 * @author   WooThemes
8
 * @category Core
9
 * @package  WooCommerce/Functions
10
 * @version  2.5.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit; // Exit if accessed directly
15
}
16
17
/**
18
 * Prevent password protected products being added to the cart.
19
 *
20
 * @param  bool $passed
21
 * @param  int $product_id
22
 * @return bool
23
 */
24
function wc_protected_product_add_to_cart( $passed, $product_id ) {
25
	if ( post_password_required( $product_id ) ) {
26
		$passed = false;
27
		wc_add_notice( __( 'This product is protected and cannot be purchased.', 'woocommerce' ), 'error' );
28
	}
29
	return $passed;
30
}
31
add_filter( 'woocommerce_add_to_cart_validation', 'wc_protected_product_add_to_cart', 10, 2 );
32
33
/**
34
 * Clears the cart session when called.
35
 */
36
function wc_empty_cart() {
37
	if ( ! isset( WC()->cart ) || '' === WC()->cart ) {
38
		WC()->cart = new WC_Cart();
39
	}
40
	WC()->cart->empty_cart( false );
41
}
42
43
/**
44
 * Load the persistent cart.
45
 *
46
 * @param string $user_login
47
 * @param WP_User $user
48
 * @deprecated 2.3
49
 */
50
function wc_load_persistent_cart( $user_login, $user ) {
0 ignored issues
show
Unused Code introduced by
The parameter $user_login 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...
51
	if ( ! $user || ! ( $saved_cart = get_user_meta( $user->ID, '_woocommerce_persistent_cart', true ) ) ) {
52
		return;
53
	}
54
55
	if ( empty( WC()->session->cart ) || ! is_array( WC()->session->cart ) || 0 === sizeof( WC()->session->cart ) ) {
56
		WC()->session->cart = $saved_cart['cart'];
57
	}
58
}
59
60
/**
61
 * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
62
 *
63
 * Do not use for redirects, use {@see wp_get_referer()} instead.
64
 *
65
 * @since 2.6.1
66
 * @return string|false Referer URL on success, false on failure.
67
 */
68
function wc_get_raw_referer() {
69
	if ( function_exists( 'wp_get_raw_referer' ) ) {
70
		return wp_get_raw_referer();
71
	}
72
73
    if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
74
        return wp_unslash( $_REQUEST['_wp_http_referer'] );
75
    } else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
76
        return wp_unslash( $_SERVER['HTTP_REFERER'] );
77
    }
78
79
    return false;
80
}
81
82
/**
83
 * Add to cart messages.
84
 *
85
 * @access public
86
 * @param int|array $products
87
 * @param bool $show_qty Should qty's be shown? Added in 2.6.0
88
 */
89
function wc_add_to_cart_message( $products, $show_qty = false ) {
90
	$titles = array();
91
	$count  = 0;
92
93
	if ( ! is_array( $products ) ) {
94
		$products = array( $products );
95
		$show_qty = false;
96
	}
97
98
	if ( ! $show_qty ) {
99
		$products = array_fill_keys( array_values( $products ), 1 );
100
	}
101
102
	foreach ( $products as $product_id => $qty ) {
103
		$titles[] = ( $qty > 1 ? absint( $qty ) . ' &times; ' : '' ) . sprintf( _x( '&ldquo;%s&rdquo;', 'Item name in quotes', 'woocommerce' ), strip_tags( get_the_title( $product_id ) ) );
104
		$count += $qty;
105
	}
106
107
	$titles     = array_filter( $titles );
108
	$added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', $count, 'woocommerce' ), wc_format_list_of_items( $titles ) );
109
110
	// Output success messages
111
	if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
112
		$return_to = apply_filters( 'woocommerce_continue_shopping_redirect', wc_get_raw_referer() ? wp_validate_redirect( wc_get_raw_referer(), false ) : wc_get_page_permalink( 'shop' ) );
113
		$message   = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( $return_to ), esc_html__( 'Continue Shopping', 'woocommerce' ), esc_html( $added_text ) );
114
	} else {
115
		$message   = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( wc_get_page_permalink( 'cart' ) ), esc_html__( 'View Cart', 'woocommerce' ), esc_html( $added_text ) );
116
	}
117
118
	wc_add_notice( apply_filters( 'wc_add_to_cart_message', $message, $product_id ) );
119
}
120
121
/**
122
 * Comma separate a list of item names, and replace final comma with 'and'
123
 * @param  array $items
124
 * @return string
125
 */
126
function wc_format_list_of_items( $items ) {
127
	$item_string = '';
128
129
	foreach ( $items as $key => $item ) {
130
		$item_string .= $item;
131
132
		if ( $key + 2 === sizeof( $items ) ) {
133
			$item_string .= ' ' . __( 'and', 'woocommerce' ) . ' ';
134
		} elseif ( $key + 1 !== sizeof( $items ) ) {
135
			$item_string .= ', ';
136
		}
137
	}
138
139
	return $item_string;
140
}
141
142
/**
143
 * Clear cart after payment.
144
 *
145
 * @access public
146
 */
147
function wc_clear_cart_after_payment() {
148
	global $wp;
149
150
	if ( ! empty( $wp->query_vars['order-received'] ) ) {
151
152
		$order_id  = absint( $wp->query_vars['order-received'] );
153
		$order_key = isset( $_GET['key'] ) ? wc_clean( $_GET['key'] ) : '';
154
155 View Code Duplication
		if ( $order_id > 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
156
			$order = wc_get_order( $order_id );
157
158
			if ( $order->order_key === $order_key ) {
159
				WC()->cart->empty_cart();
160
			}
161
		}
162
	}
163
164
	if ( WC()->session->order_awaiting_payment > 0 ) {
165
		$order = wc_get_order( WC()->session->order_awaiting_payment );
166
167
		if ( $order && $order->id > 0 ) {
168
			// If the order has not failed, or is not pending, the order must have gone through
169
			if ( ! $order->has_status( array( 'failed', 'pending', 'cancelled' ) ) ) {
170
				WC()->cart->empty_cart();
171
			}
172
		}
173
	}
174
}
175
add_action( 'get_header', 'wc_clear_cart_after_payment' );
176
177
/**
178
 * Get the subtotal.
179
 *
180
 * @access public
181
 * @return string
182
 */
183
function wc_cart_totals_subtotal_html() {
184
	echo WC()->cart->get_cart_subtotal();
185
}
186
187
/**
188
 * Get shipping methods.
189
 *
190
 * @access public
191
 */
192
function wc_cart_totals_shipping_html() {
193
	$packages = WC()->shipping->get_packages();
194
195
	foreach ( $packages as $i => $package ) {
196
		$chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : '';
197
		$product_names = array();
198
199
		if ( sizeof( $packages ) > 1 ) {
200
			foreach ( $package['contents'] as $item_id => $values ) {
201
				$product_names[] = $values['data']->get_title() . ' &times;' . $values['quantity'];
202
			}
203
		}
204
205
		wc_get_template( 'cart/cart-shipping.php', array(
206
			'package'              => $package,
207
			'available_methods'    => $package['rates'],
208
			'show_package_details' => sizeof( $packages ) > 1,
209
			'package_details'      => implode( ', ', $product_names ),
210
			'package_name'         => apply_filters( 'woocommerce_shipping_package_name', sprintf( _n( 'Shipping', 'Shipping %d', ( $i + 1 ), 'woocommerce' ), ( $i + 1 ) ), $i, $package ),
211
			'index'                => $i,
212
			'chosen_method'        => $chosen_method
213
		) );
214
	}
215
}
216
217
/**
218
 * Get taxes total.
219
 *
220
 * @access public
221
 */
222
function wc_cart_totals_taxes_total_html() {
223
	echo apply_filters( 'woocommerce_cart_totals_taxes_total_html', wc_price( WC()->cart->get_taxes_total() ) );
224
}
225
226
/**
227
 * Get a coupon label.
228
 *
229
 * @access public
230
 * @param string $coupon
231
 * @param bool $echo or return
232
 */
233
function wc_cart_totals_coupon_label( $coupon, $echo = true ) {
234
	if ( is_string( $coupon ) ) {
235
		$coupon = new WC_Coupon( $coupon );
236
	}
237
238
	$label = apply_filters( 'woocommerce_cart_totals_coupon_label', esc_html( __( 'Coupon:', 'woocommerce' ) . ' ' . $coupon->code ), $coupon );
239
240
	if ( $echo ) {
241
		echo $label;
242
	} else {
243
		return $label;
244
	}
245
}
246
247
/**
248
 * Get a coupon value.
249
 *
250
 * @access public
251
 * @param string $coupon
252
 */
253
function wc_cart_totals_coupon_html( $coupon ) {
254
	if ( is_string( $coupon ) ) {
255
		$coupon = new WC_Coupon( $coupon );
256
	}
257
258
	$value  = array();
259
260
	if ( $amount = WC()->cart->get_coupon_discount_amount( $coupon->code, WC()->cart->display_cart_ex_tax ) ) {
261
		$discount_html = '-' . wc_price( $amount );
262
	} else {
263
		$discount_html = '';
264
	}
265
266
	$value[] = apply_filters( 'woocommerce_coupon_discount_amount_html', $discount_html, $coupon );
267
268
	if ( $coupon->enable_free_shipping() ) {
269
		$value[] = __( 'Free shipping coupon', 'woocommerce' );
270
	}
271
272
	// get rid of empty array elements
273
	$value = array_filter( $value );
274
	$value = implode( ', ', $value ) . ' <a href="' . esc_url( add_query_arg( 'remove_coupon', urlencode( $coupon->code ), defined( 'WOOCOMMERCE_CHECKOUT' ) ? wc_get_checkout_url() : wc_get_cart_url() ) ) . '" class="woocommerce-remove-coupon" data-coupon="' . esc_attr( $coupon->code ) . '">' . __( '[Remove]', 'woocommerce' ) . '</a>';
275
276
	echo apply_filters( 'woocommerce_cart_totals_coupon_html', $value, $coupon );
277
}
278
279
/**
280
 * Get order total html including inc tax if needed.
281
 *
282
 * @access public
283
 */
284
function wc_cart_totals_order_total_html() {
285
	$value = '<strong>' . WC()->cart->get_total() . '</strong> ';
286
287
	// If prices are tax inclusive, show taxes here
288
	if ( wc_tax_enabled() && WC()->cart->tax_display_cart == 'incl' ) {
289
		$tax_string_array = array();
290
291
		if ( get_option( 'woocommerce_tax_total_display' ) == 'itemized' ) {
292
			foreach ( WC()->cart->get_tax_totals() as $code => $tax )
293
				$tax_string_array[] = sprintf( '%s %s', $tax->formatted_amount, $tax->label );
294
		} else {
295
			$tax_string_array[] = sprintf( '%s %s', wc_price( WC()->cart->get_taxes_total( true, true ) ), WC()->countries->tax_or_vat() );
296
		}
297
298
		if ( ! empty( $tax_string_array ) ) {
299
			$taxable_address = WC()->customer->get_taxable_address();
300
			$estimated_text  = WC()->customer->is_customer_outside_base() && ! WC()->customer->has_calculated_shipping()
301
				? sprintf( ' ' . __( 'estimated for %s', 'woocommerce' ), WC()->countries->estimated_for_prefix( $taxable_address[0] ) . WC()->countries->countries[ $taxable_address[0] ] )
302
				: '';
303
			$value .= '<small class="includes_tax">' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) . $estimated_text ) . '</small>';
304
		}
305
	}
306
307
	echo apply_filters( 'woocommerce_cart_totals_order_total_html', $value );
308
}
309
310
/**
311
 * Get the fee value.
312
 *
313
 * @param object $fee
314
 */
315
function wc_cart_totals_fee_html( $fee ) {
316
	$cart_totals_fee_html = ( 'excl' == WC()->cart->tax_display_cart ) ? wc_price( $fee->amount ) : wc_price( $fee->amount + $fee->tax );
317
318
	echo apply_filters( 'woocommerce_cart_totals_fee_html', $cart_totals_fee_html, $fee );
319
}
320
321
/**
322
 * Get a shipping methods full label including price.
323
 * @param  WC_Shipping_Rate $method
324
 * @return string
325
 */
326
function wc_cart_totals_shipping_method_label( $method ) {
327
	$label = $method->get_label();
328
329
	if ( $method->cost > 0 ) {
330
		if ( WC()->cart->tax_display_cart == 'excl' ) {
331
			$label .= ': ' . wc_price( $method->cost );
332
			if ( $method->get_shipping_tax() > 0 && WC()->cart->prices_include_tax ) {
333
				$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
334
			}
335
		} else {
336
			$label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() );
337
			if ( $method->get_shipping_tax() > 0 && ! WC()->cart->prices_include_tax ) {
338
				$label .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
339
			}
340
		}
341
	}
342
343
	return apply_filters( 'woocommerce_cart_shipping_method_full_label', $label, $method );
344
}
345
346
/**
347
 * Round discount.
348
 *
349
 * @param  float $value
350
 * @param  int $precision
351
 * @return float
352
 */
353
function wc_cart_round_discount( $value, $precision ) {
354
	if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) {
355
		return round( $value, $precision, WC_DISCOUNT_ROUNDING_MODE );
356
	} else {
357
		return round( $value, $precision );
358
	}
359
}
360
361
/**
362
 * Gets chosen shipping method IDs from chosen_shipping_methods session, without instance IDs.
363
 * @since  2.6.2
364
 * @return string[]
365
 */
366
function wc_get_chosen_shipping_method_ids() {
367
	$method_ids     = array();
368
	$chosen_methods = WC()->session->get( 'chosen_shipping_methods', array() );
369
	foreach ( $chosen_methods as $chosen_method ) {
0 ignored issues
show
Bug introduced by
The expression $chosen_methods of type array|string is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
370
		$chosen_method = explode( ':', $chosen_method );
371
		$method_ids[]  = current( $chosen_method );
372
	}
373
	return $method_ids;
374
}
375