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 ) { |
|
|
|
|
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
|
|
|
* Add to cart messages. |
62
|
|
|
* |
63
|
|
|
* @access public |
64
|
|
|
* @param int|array $products |
65
|
|
|
* @param bool $show_qty Should qty's be shown? Added in 2.6.0 |
66
|
|
|
*/ |
67
|
|
|
function wc_add_to_cart_message( $products, $show_qty = false ) { |
68
|
|
|
$titles = array(); |
69
|
|
|
$count = 0; |
70
|
|
|
|
71
|
|
|
if ( ! is_array( $products ) ) { |
72
|
|
|
$products = array( $products ); |
73
|
|
|
$show_qty = false; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
if ( ! $show_qty && ! is_array( $products ) ) { |
77
|
|
|
$products = array_fill_keys( array_values( $products ), 1 ); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
foreach ( $products as $product_id => $qty ) { |
81
|
|
|
$titles[] = ( $qty > 1 ? absint( $qty ) . ' × ' : '' ) . sprintf( _x( '“%s”', 'Item name in quotes', 'woocommerce' ), strip_tags( get_the_title( $product_id ) ) ); |
82
|
|
|
$count += $qty; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$titles = array_filter( $titles ); |
86
|
|
|
$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 ) ); |
87
|
|
|
|
88
|
|
|
// Output success messages |
89
|
|
|
if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) { |
90
|
|
|
$return_to = apply_filters( 'woocommerce_continue_shopping_redirect', wp_get_raw_referer() ? wp_validate_redirect( wp_get_raw_referer(), false ) : wc_get_page_permalink( 'shop' ) ); |
91
|
|
|
$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 ) ); |
92
|
|
|
} else { |
93
|
|
|
$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 ) ); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
wc_add_notice( apply_filters( 'wc_add_to_cart_message', $message, $product_id ) ); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Comma separate a list of item names, and replace final comma with 'and' |
101
|
|
|
* @param array $items |
102
|
|
|
* @return string |
103
|
|
|
*/ |
104
|
|
|
function wc_format_list_of_items( $items ) { |
105
|
|
|
$item_string = ''; |
106
|
|
|
|
107
|
|
|
foreach ( $items as $key => $item ) { |
108
|
|
|
$item_string .= $item; |
109
|
|
|
|
110
|
|
|
if ( $key + 2 === sizeof( $items ) ) { |
111
|
|
|
$item_string .= ' ' . __( 'and', 'woocommerce' ) . ' '; |
112
|
|
|
} elseif ( $key + 1 !== sizeof( $items ) ) { |
113
|
|
|
$item_string .= ', '; |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return $item_string; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Clear cart after payment. |
122
|
|
|
* |
123
|
|
|
* @access public |
124
|
|
|
*/ |
125
|
|
|
function wc_clear_cart_after_payment() { |
126
|
|
|
global $wp; |
127
|
|
|
|
128
|
|
|
if ( ! empty( $wp->query_vars['order-received'] ) ) { |
129
|
|
|
|
130
|
|
|
$order_id = absint( $wp->query_vars['order-received'] ); |
131
|
|
|
$order_key = isset( $_GET['key'] ) ? wc_clean( $_GET['key'] ) : ''; |
132
|
|
|
|
133
|
|
View Code Duplication |
if ( $order_id > 0 ) { |
|
|
|
|
134
|
|
|
$order = wc_get_order( $order_id ); |
135
|
|
|
|
136
|
|
|
if ( $order->order_key === $order_key ) { |
137
|
|
|
WC()->cart->empty_cart(); |
138
|
|
|
} |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
if ( WC()->session->order_awaiting_payment > 0 ) { |
143
|
|
|
$order = wc_get_order( WC()->session->order_awaiting_payment ); |
144
|
|
|
|
145
|
|
|
if ( $order && $order->id > 0 ) { |
146
|
|
|
// If the order has not failed, or is not pending, the order must have gone through |
147
|
|
|
if ( ! $order->has_status( array( 'failed', 'pending', 'cancelled' ) ) ) { |
148
|
|
|
WC()->cart->empty_cart(); |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
add_action( 'get_header', 'wc_clear_cart_after_payment' ); |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Get the subtotal. |
157
|
|
|
* |
158
|
|
|
* @access public |
159
|
|
|
* @return string |
160
|
|
|
*/ |
161
|
|
|
function wc_cart_totals_subtotal_html() { |
162
|
|
|
echo WC()->cart->get_cart_subtotal(); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Get shipping methods. |
167
|
|
|
* |
168
|
|
|
* @access public |
169
|
|
|
*/ |
170
|
|
|
function wc_cart_totals_shipping_html() { |
171
|
|
|
$packages = WC()->shipping->get_packages(); |
172
|
|
|
|
173
|
|
|
foreach ( $packages as $i => $package ) { |
174
|
|
|
$chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : ''; |
175
|
|
|
$product_names = array(); |
176
|
|
|
|
177
|
|
|
if ( sizeof( $packages ) > 1 ) { |
178
|
|
|
foreach ( $package['contents'] as $item_id => $values ) { |
179
|
|
|
$product_names[] = $values['data']->get_title() . ' ×' . $values['quantity']; |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
wc_get_template( 'cart/cart-shipping.php', array( |
184
|
|
|
'package' => $package, |
185
|
|
|
'available_methods' => $package['rates'], |
186
|
|
|
'show_package_details' => sizeof( $packages ) > 1, |
187
|
|
|
'package_details' => implode( ', ', $product_names ), |
188
|
|
|
'package_name' => apply_filters( 'woocommerce_shipping_package_name', sprintf( _n( 'Shipping', 'Shipping %d', ( $i + 1 ), 'woocommerce' ), ( $i + 1 ) ), $i, $package ), |
189
|
|
|
'index' => $i, |
190
|
|
|
'chosen_method' => $chosen_method |
191
|
|
|
) ); |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Get taxes total. |
197
|
|
|
* |
198
|
|
|
* @access public |
199
|
|
|
*/ |
200
|
|
|
function wc_cart_totals_taxes_total_html() { |
201
|
|
|
echo apply_filters( 'woocommerce_cart_totals_taxes_total_html', wc_price( WC()->cart->get_taxes_total() ) ); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Get a coupon label. |
206
|
|
|
* |
207
|
|
|
* @access public |
208
|
|
|
* @param string $coupon |
209
|
|
|
* @param bool $echo or return |
210
|
|
|
*/ |
211
|
|
|
function wc_cart_totals_coupon_label( $coupon, $echo = true ) { |
212
|
|
|
if ( is_string( $coupon ) ) { |
213
|
|
|
$coupon = new WC_Coupon( $coupon ); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
$label = apply_filters( 'woocommerce_cart_totals_coupon_label', esc_html( __( 'Coupon:', 'woocommerce' ) . ' ' . $coupon->code ), $coupon ); |
217
|
|
|
|
218
|
|
|
if ( $echo ) { |
219
|
|
|
echo $label; |
220
|
|
|
} else { |
221
|
|
|
return $label; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Get a coupon value. |
227
|
|
|
* |
228
|
|
|
* @access public |
229
|
|
|
* @param string $coupon |
230
|
|
|
*/ |
231
|
|
|
function wc_cart_totals_coupon_html( $coupon ) { |
232
|
|
|
if ( is_string( $coupon ) ) { |
233
|
|
|
$coupon = new WC_Coupon( $coupon ); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
$value = array(); |
237
|
|
|
|
238
|
|
|
if ( $amount = WC()->cart->get_coupon_discount_amount( $coupon->code, WC()->cart->display_cart_ex_tax ) ) { |
239
|
|
|
$discount_html = '-' . wc_price( $amount ); |
240
|
|
|
} else { |
241
|
|
|
$discount_html = ''; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
$value[] = apply_filters( 'woocommerce_coupon_discount_amount_html', $discount_html, $coupon ); |
245
|
|
|
|
246
|
|
|
if ( $coupon->enable_free_shipping() ) { |
247
|
|
|
$value[] = __( 'Free shipping coupon', 'woocommerce' ); |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
// get rid of empty array elements |
251
|
|
|
$value = array_filter( $value ); |
252
|
|
|
$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>'; |
253
|
|
|
|
254
|
|
|
echo apply_filters( 'woocommerce_cart_totals_coupon_html', $value, $coupon ); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Get order total html including inc tax if needed. |
259
|
|
|
* |
260
|
|
|
* @access public |
261
|
|
|
*/ |
262
|
|
|
function wc_cart_totals_order_total_html() { |
263
|
|
|
$value = '<strong>' . WC()->cart->get_total() . '</strong> '; |
264
|
|
|
|
265
|
|
|
// If prices are tax inclusive, show taxes here |
266
|
|
|
if ( wc_tax_enabled() && WC()->cart->tax_display_cart == 'incl' ) { |
267
|
|
|
$tax_string_array = array(); |
268
|
|
|
|
269
|
|
|
if ( get_option( 'woocommerce_tax_total_display' ) == 'itemized' ) { |
270
|
|
|
foreach ( WC()->cart->get_tax_totals() as $code => $tax ) |
271
|
|
|
$tax_string_array[] = sprintf( '%s %s', $tax->formatted_amount, $tax->label ); |
272
|
|
|
} else { |
273
|
|
|
$tax_string_array[] = sprintf( '%s %s', wc_price( WC()->cart->get_taxes_total( true, true ) ), WC()->countries->tax_or_vat() ); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
if ( ! empty( $tax_string_array ) ) { |
277
|
|
|
$taxable_address = WC()->customer->get_taxable_address(); |
278
|
|
|
$estimated_text = WC()->customer->is_customer_outside_base() && ! WC()->customer->has_calculated_shipping() |
279
|
|
|
? sprintf( ' ' . __( 'estimated for %s', 'woocommerce' ), WC()->countries->estimated_for_prefix( $taxable_address[0] ) . WC()->countries->countries[ $taxable_address[0] ] ) |
280
|
|
|
: ''; |
281
|
|
|
$value .= '<small class="includes_tax">' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) . $estimated_text ) . '</small>'; |
282
|
|
|
} |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
echo apply_filters( 'woocommerce_cart_totals_order_total_html', $value ); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Get the fee value. |
290
|
|
|
* |
291
|
|
|
* @param object $fee |
292
|
|
|
*/ |
293
|
|
|
function wc_cart_totals_fee_html( $fee ) { |
294
|
|
|
$cart_totals_fee_html = ( 'excl' == WC()->cart->tax_display_cart ) ? wc_price( $fee->amount ) : wc_price( $fee->amount + $fee->tax ); |
295
|
|
|
|
296
|
|
|
echo apply_filters( 'woocommerce_cart_totals_fee_html', $cart_totals_fee_html, $fee ); |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* Get a shipping methods full label including price. |
301
|
|
|
* @param WC_Shipping_Rate $method |
302
|
|
|
* @return string |
303
|
|
|
*/ |
304
|
|
|
function wc_cart_totals_shipping_method_label( $method ) { |
305
|
|
|
$label = $method->get_label(); |
306
|
|
|
|
307
|
|
|
if ( $method->cost > 0 ) { |
308
|
|
|
if ( WC()->cart->tax_display_cart == 'excl' ) { |
309
|
|
|
$label .= ': ' . wc_price( $method->cost ); |
310
|
|
|
if ( $method->get_shipping_tax() > 0 && WC()->cart->prices_include_tax ) { |
311
|
|
|
$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>'; |
312
|
|
|
} |
313
|
|
|
} else { |
314
|
|
|
$label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() ); |
315
|
|
|
if ( $method->get_shipping_tax() > 0 && ! WC()->cart->prices_include_tax ) { |
316
|
|
|
$label .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>'; |
317
|
|
|
} |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
return apply_filters( 'woocommerce_cart_shipping_method_full_label', $label, $method ); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** |
325
|
|
|
* Round discount. |
326
|
|
|
* |
327
|
|
|
* @param float $value |
328
|
|
|
* @param int $precision |
329
|
|
|
* @return float |
330
|
|
|
*/ |
331
|
|
|
function wc_cart_round_discount( $value, $precision ) { |
332
|
|
|
if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) { |
333
|
|
|
return round( $value, $precision, WC_DISCOUNT_ROUNDING_MODE ); |
334
|
|
|
} else { |
335
|
|
|
return round( $value, $precision ); |
336
|
|
|
} |
337
|
|
|
} |
338
|
|
|
|
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.