1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* WooCommerce Template |
4
|
|
|
* |
5
|
|
|
* Functions for the templating system. |
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
|
|
|
* Handle redirects before content is output - hooked into template_redirect so is_page works. |
19
|
|
|
*/ |
20
|
|
|
function wc_template_redirect() { |
21
|
|
|
global $wp_query, $wp; |
22
|
|
|
|
23
|
|
|
// When default permalinks are enabled, redirect shop page to post type archive url |
24
|
|
|
if ( ! empty( $_GET['page_id'] ) && '' === get_option( 'permalink_structure' ) && $_GET['page_id'] == wc_get_page_id( 'shop' ) ) { |
25
|
|
|
wp_safe_redirect( get_post_type_archive_link('product') ); |
26
|
|
|
exit; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
// When on the checkout with an empty cart, redirect to cart page |
30
|
|
|
elseif ( is_page( wc_get_page_id( 'checkout' ) ) && WC()->cart->is_empty() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ) { |
31
|
|
|
wc_add_notice( __( 'Checkout is not available whilst your cart is empty.', 'woocommerce' ) ); |
32
|
|
|
wp_redirect( wc_get_page_permalink( 'cart' ) ); |
33
|
|
|
exit; |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
// Logout |
37
|
|
|
elseif ( isset( $wp->query_vars['customer-logout'] ) ) { |
38
|
|
|
wp_redirect( str_replace( '&', '&', wp_logout_url( wc_get_page_permalink( 'myaccount' ) ) ) ); |
39
|
|
|
exit; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
// Redirect to the product page if we have a single product |
43
|
|
|
elseif ( is_search() && is_post_type_archive( 'product' ) && apply_filters( 'woocommerce_redirect_single_search_result', true ) && 1 === $wp_query->found_posts ) { |
44
|
|
|
$product = wc_get_product( $wp_query->post ); |
45
|
|
|
|
46
|
|
|
if ( $product && $product->is_visible() ) { |
47
|
|
|
wp_safe_redirect( get_permalink( $product->id ), 302 ); |
48
|
|
|
exit; |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
// Ensure payment gateways are loaded early |
53
|
|
|
elseif ( is_add_payment_method_page() ) { |
54
|
|
|
|
55
|
|
|
WC()->payment_gateways(); |
56
|
|
|
|
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
// Checkout pages handling |
60
|
|
|
elseif ( is_checkout() ) { |
61
|
|
|
// Buffer the checkout page |
62
|
|
|
ob_start(); |
63
|
|
|
|
64
|
|
|
// Ensure gateways and shipping methods are loaded early |
65
|
|
|
WC()->payment_gateways(); |
66
|
|
|
WC()->shipping(); |
67
|
|
|
} |
68
|
|
|
} |
69
|
|
|
add_action( 'template_redirect', 'wc_template_redirect' ); |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* When loading sensitive checkout or account pages, send a HTTP header to limit rendering of pages to same origin iframes for security reasons. |
73
|
|
|
* |
74
|
|
|
* Can be disabled with: remove_action( 'template_redirect', 'wc_send_frame_options_header' ); |
75
|
|
|
* |
76
|
|
|
* @since 2.3.10 |
77
|
|
|
*/ |
78
|
|
|
function wc_send_frame_options_header() { |
79
|
|
|
if ( is_checkout() || is_account_page() ) { |
80
|
|
|
send_frame_options_header(); |
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
add_action( 'template_redirect', 'wc_send_frame_options_header' ); |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* No index our endpoints. |
87
|
|
|
* Prevent indexing pages like order-received. |
88
|
|
|
* |
89
|
|
|
* @since 2.5.3 |
90
|
|
|
*/ |
91
|
|
|
function wc_prevent_endpoint_indexing() { |
92
|
|
|
if ( is_wc_endpoint_url() || isset( $_GET['download_file'] ) ) { |
93
|
|
|
@header( 'X-Robots-Tag: noindex' ); |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
add_action( 'template_redirect', 'wc_prevent_endpoint_indexing' ); |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* When the_post is called, put product data into a global. |
100
|
|
|
* |
101
|
|
|
* @param mixed $post |
102
|
|
|
* @return WC_Product |
103
|
|
|
*/ |
104
|
|
|
function wc_setup_product_data( $post ) { |
105
|
|
|
unset( $GLOBALS['product'] ); |
106
|
|
|
|
107
|
|
|
if ( is_int( $post ) ) |
108
|
|
|
$post = get_post( $post ); |
109
|
|
|
|
110
|
|
|
if ( empty( $post->post_type ) || ! in_array( $post->post_type, array( 'product', 'product_variation' ) ) ) |
111
|
|
|
return; |
112
|
|
|
|
113
|
|
|
$GLOBALS['product'] = wc_get_product( $post ); |
114
|
|
|
|
115
|
|
|
return $GLOBALS['product']; |
116
|
|
|
} |
117
|
|
|
add_action( 'the_post', 'wc_setup_product_data' ); |
118
|
|
|
|
119
|
|
|
if ( ! function_exists( 'woocommerce_reset_loop' ) ) { |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Reset the loop's index and columns when we're done outputting a product loop. |
123
|
|
|
* @subpackage Loop |
124
|
|
|
*/ |
125
|
|
|
function woocommerce_reset_loop() { |
126
|
|
|
$GLOBALS['woocommerce_loop'] = array( |
127
|
|
|
'loop' => '', |
128
|
|
|
'columns' => '', |
129
|
|
|
'name' => '', |
130
|
|
|
); |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
add_filter( 'loop_end', 'woocommerce_reset_loop' ); |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Products RSS Feed. |
137
|
|
|
* |
138
|
|
|
* @access public |
139
|
|
|
*/ |
140
|
|
|
function wc_products_rss_feed() { |
141
|
|
|
// Product RSS |
142
|
|
|
if ( is_post_type_archive( 'product' ) || is_singular( 'product' ) ) { |
143
|
|
|
|
144
|
|
|
$feed = get_post_type_archive_feed_link( 'product' ); |
145
|
|
|
|
146
|
|
|
echo '<link rel="alternate" type="application/rss+xml" title="' . esc_attr__( 'New products', 'woocommerce' ) . '" href="' . esc_url( $feed ) . '" />'; |
147
|
|
|
|
148
|
|
|
} elseif ( is_tax( 'product_cat' ) ) { |
149
|
|
|
|
150
|
|
|
$term = get_term_by( 'slug', esc_attr( get_query_var('product_cat') ), 'product_cat' ); |
151
|
|
|
|
152
|
|
View Code Duplication |
if ( $term ) { |
|
|
|
|
153
|
|
|
$feed = add_query_arg( 'product_cat', $term->slug, get_post_type_archive_feed_link( 'product' ) ); |
154
|
|
|
echo '<link rel="alternate" type="application/rss+xml" title="' . esc_attr( sprintf( __( 'New products added to %s', 'woocommerce' ), $term->name ) ) . '" href="' . esc_url( $feed ) . '" />'; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
} elseif ( is_tax( 'product_tag' ) ) { |
158
|
|
|
|
159
|
|
|
$term = get_term_by('slug', esc_attr( get_query_var('product_tag') ), 'product_tag'); |
160
|
|
|
|
161
|
|
View Code Duplication |
if ( $term ) { |
|
|
|
|
162
|
|
|
$feed = add_query_arg('product_tag', $term->slug, get_post_type_archive_feed_link( 'product' )); |
163
|
|
|
echo '<link rel="alternate" type="application/rss+xml" title="' . sprintf(__( 'New products tagged %s', 'woocommerce' ), urlencode($term->name)) . '" href="' . esc_url( $feed ) . '" />'; |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Output generator tag to aid debugging. |
170
|
|
|
* |
171
|
|
|
* @access public |
172
|
|
|
*/ |
173
|
|
|
function wc_generator_tag( $gen, $type ) { |
174
|
|
|
switch ( $type ) { |
175
|
|
|
case 'html': |
176
|
|
|
$gen .= "\n" . '<meta name="generator" content="WooCommerce ' . esc_attr( WC_VERSION ) . '">'; |
177
|
|
|
break; |
178
|
|
|
case 'xhtml': |
179
|
|
|
$gen .= "\n" . '<meta name="generator" content="WooCommerce ' . esc_attr( WC_VERSION ) . '" />'; |
180
|
|
|
break; |
181
|
|
|
} |
182
|
|
|
return $gen; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Add body classes for WC pages. |
187
|
|
|
* |
188
|
|
|
* @param array $classes |
189
|
|
|
* @return array |
190
|
|
|
*/ |
191
|
|
|
function wc_body_class( $classes ) { |
192
|
|
|
$classes = (array) $classes; |
193
|
|
|
|
194
|
|
|
if ( is_woocommerce() ) { |
195
|
|
|
$classes[] = 'woocommerce'; |
196
|
|
|
$classes[] = 'woocommerce-page'; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
elseif ( is_checkout() ) { |
200
|
|
|
$classes[] = 'woocommerce-checkout'; |
201
|
|
|
$classes[] = 'woocommerce-page'; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
elseif ( is_cart() ) { |
205
|
|
|
$classes[] = 'woocommerce-cart'; |
206
|
|
|
$classes[] = 'woocommerce-page'; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
elseif ( is_account_page() ) { |
210
|
|
|
$classes[] = 'woocommerce-account'; |
211
|
|
|
$classes[] = 'woocommerce-page'; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
if ( is_store_notice_showing() ) { |
215
|
|
|
$classes[] = 'woocommerce-demo-store'; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
foreach ( WC()->query->query_vars as $key => $value ) { |
219
|
|
|
if ( is_wc_endpoint_url( $key ) ) { |
220
|
|
|
$classes[] = 'woocommerce-' . sanitize_html_class( $key ); |
221
|
|
|
} |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
return array_unique( $classes ); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* Display the classes for the product cat div. |
229
|
|
|
* |
230
|
|
|
* @since 2.4.0 |
231
|
|
|
* @param string|array $class One or more classes to add to the class list. |
232
|
|
|
* @param object $category object Optional. |
233
|
|
|
*/ |
234
|
|
|
function wc_product_cat_class( $class = '', $category = null ) { |
235
|
|
|
// Separates classes with a single space, collates classes for post DIV |
236
|
|
|
echo 'class="' . esc_attr( join( ' ', wc_get_product_cat_class( $class, $category ) ) ) . '"'; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Get classname for loops based on $woocommerce_loop global. |
241
|
|
|
* @since 2.6.0 |
242
|
|
|
* @return string |
243
|
|
|
*/ |
244
|
|
|
function wc_get_loop_class() { |
245
|
|
|
global $woocommerce_loop; |
246
|
|
|
|
247
|
|
|
$woocommerce_loop['loop'] = ! empty( $woocommerce_loop['loop'] ) ? $woocommerce_loop['loop'] + 1 : 1; |
248
|
|
|
$woocommerce_loop['columns'] = ! empty( $woocommerce_loop['columns'] ) ? $woocommerce_loop['columns'] : apply_filters( 'loop_shop_columns', 4 ); |
249
|
|
|
|
250
|
|
|
if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) { |
251
|
|
|
return 'first'; |
252
|
|
|
} elseif ( 0 === $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) { |
253
|
|
|
return 'last'; |
254
|
|
|
} else { |
255
|
|
|
return ''; |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Get the classes for the product cat div. |
261
|
|
|
* |
262
|
|
|
* @since 2.4.0 |
263
|
|
|
* @param string|array $class One or more classes to add to the class list. |
264
|
|
|
* @param object $category object Optional. |
265
|
|
|
*/ |
266
|
|
|
function wc_get_product_cat_class( $class = '', $category = null ) { |
267
|
|
|
$classes = is_array( $class ) ? $class : array_map( 'trim', explode( ' ', $class ) ); |
268
|
|
|
$classes[] = 'product-category'; |
269
|
|
|
$classes[] = 'product'; |
270
|
|
|
$classes[] = wc_get_loop_class(); |
271
|
|
|
$classes = apply_filters( 'product_cat_class', $classes, $class, $category ); |
272
|
|
|
|
273
|
|
|
return array_unique( array_filter( $classes ) ); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* Adds extra post classes for products. |
278
|
|
|
* |
279
|
|
|
* @since 2.1.0 |
280
|
|
|
* @param array $classes |
281
|
|
|
* @param string|array $class |
282
|
|
|
* @param int $post_id |
283
|
|
|
* @return array |
284
|
|
|
*/ |
285
|
|
|
function wc_product_post_class( $classes, $class = '', $post_id = '' ) { |
|
|
|
|
286
|
|
|
if ( ! $post_id || 'product' !== get_post_type( $post_id ) ) { |
287
|
|
|
return $classes; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
$product = wc_get_product( $post_id ); |
291
|
|
|
|
292
|
|
|
if ( $product ) { |
293
|
|
|
$classes[] = wc_get_loop_class(); |
294
|
|
|
$classes[] = $product->stock_status; |
295
|
|
|
|
296
|
|
|
if ( $product->is_on_sale() ) { |
297
|
|
|
$classes[] = 'sale'; |
298
|
|
|
} |
299
|
|
|
if ( $product->is_featured() ) { |
300
|
|
|
$classes[] = 'featured'; |
301
|
|
|
} |
302
|
|
|
if ( $product->is_downloadable() ) { |
303
|
|
|
$classes[] = 'downloadable'; |
304
|
|
|
} |
305
|
|
|
if ( $product->is_virtual() ) { |
306
|
|
|
$classes[] = 'virtual'; |
307
|
|
|
} |
308
|
|
|
if ( $product->is_sold_individually() ) { |
309
|
|
|
$classes[] = 'sold-individually'; |
310
|
|
|
} |
311
|
|
|
if ( $product->is_taxable() ) { |
312
|
|
|
$classes[] = 'taxable'; |
313
|
|
|
} |
314
|
|
|
if ( $product->is_shipping_taxable() ) { |
315
|
|
|
$classes[] = 'shipping-taxable'; |
316
|
|
|
} |
317
|
|
|
if ( $product->is_purchasable() ) { |
318
|
|
|
$classes[] = 'purchasable'; |
319
|
|
|
} |
320
|
|
|
if ( $product->get_type() ) { |
321
|
|
|
$classes[] = "product-type-" . $product->get_type(); |
322
|
|
|
} |
323
|
|
|
if ( $product->is_type( 'variable' ) ) { |
324
|
|
|
if ( $product->has_default_attributes() ) { |
325
|
|
|
$classes[] = 'has-default-attributes'; |
326
|
|
|
} |
327
|
|
|
if ( $product->has_child() ) { |
328
|
|
|
$classes[] = 'has-children'; |
329
|
|
|
} |
330
|
|
|
} |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
if ( false !== ( $key = array_search( 'hentry', $classes ) ) ) { |
334
|
|
|
unset( $classes[ $key ] ); |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
return $classes; |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
/** Template pages ********************************************************/ |
341
|
|
|
|
342
|
|
|
if ( ! function_exists( 'woocommerce_content' ) ) { |
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* Output WooCommerce content. |
346
|
|
|
* |
347
|
|
|
* This function is only used in the optional 'woocommerce.php' template. |
348
|
|
|
* which people can add to their themes to add basic woocommerce support. |
349
|
|
|
* without hooks or modifying core templates. |
350
|
|
|
* |
351
|
|
|
*/ |
352
|
|
|
function woocommerce_content() { |
353
|
|
|
|
354
|
|
|
if ( is_singular( 'product' ) ) { |
355
|
|
|
|
356
|
|
|
while ( have_posts() ) : the_post(); |
357
|
|
|
|
358
|
|
|
wc_get_template_part( 'content', 'single-product' ); |
359
|
|
|
|
360
|
|
|
endwhile; |
361
|
|
|
|
362
|
|
|
} else { ?> |
363
|
|
|
|
364
|
|
|
<?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?> |
365
|
|
|
|
366
|
|
|
<h1 class="page-title"><?php woocommerce_page_title(); ?></h1> |
367
|
|
|
|
368
|
|
|
<?php endif; ?> |
369
|
|
|
|
370
|
|
|
<?php do_action( 'woocommerce_archive_description' ); ?> |
371
|
|
|
|
372
|
|
View Code Duplication |
<?php if ( have_posts() ) : ?> |
|
|
|
|
373
|
|
|
|
374
|
|
|
<?php do_action('woocommerce_before_shop_loop'); ?> |
375
|
|
|
|
376
|
|
|
<?php woocommerce_product_loop_start(); ?> |
377
|
|
|
|
378
|
|
|
<?php woocommerce_product_subcategories(); ?> |
379
|
|
|
|
380
|
|
|
<?php while ( have_posts() ) : the_post(); ?> |
381
|
|
|
|
382
|
|
|
<?php wc_get_template_part( 'content', 'product' ); ?> |
383
|
|
|
|
384
|
|
|
<?php endwhile; // end of the loop. ?> |
385
|
|
|
|
386
|
|
|
<?php woocommerce_product_loop_end(); ?> |
387
|
|
|
|
388
|
|
|
<?php do_action('woocommerce_after_shop_loop'); ?> |
389
|
|
|
|
390
|
|
|
<?php elseif ( ! woocommerce_product_subcategories( array( 'before' => woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) : ?> |
391
|
|
|
|
392
|
|
|
<?php wc_get_template( 'loop/no-products-found.php' ); ?> |
393
|
|
|
|
394
|
|
|
<?php endif; |
395
|
|
|
|
396
|
|
|
} |
397
|
|
|
} |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** Global ****************************************************************/ |
401
|
|
|
|
402
|
|
|
if ( ! function_exists( 'woocommerce_output_content_wrapper' ) ) { |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* Output the start of the page wrapper. |
406
|
|
|
* |
407
|
|
|
*/ |
408
|
|
|
function woocommerce_output_content_wrapper() { |
409
|
|
|
wc_get_template( 'global/wrapper-start.php' ); |
410
|
|
|
} |
411
|
|
|
} |
412
|
|
|
if ( ! function_exists( 'woocommerce_output_content_wrapper_end' ) ) { |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* Output the end of the page wrapper. |
416
|
|
|
* |
417
|
|
|
*/ |
418
|
|
|
function woocommerce_output_content_wrapper_end() { |
419
|
|
|
wc_get_template( 'global/wrapper-end.php' ); |
420
|
|
|
} |
421
|
|
|
} |
422
|
|
|
|
423
|
|
|
if ( ! function_exists( 'woocommerce_get_sidebar' ) ) { |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* Get the shop sidebar template. |
427
|
|
|
* |
428
|
|
|
*/ |
429
|
|
|
function woocommerce_get_sidebar() { |
430
|
|
|
wc_get_template( 'global/sidebar.php' ); |
431
|
|
|
} |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
if ( ! function_exists( 'woocommerce_demo_store' ) ) { |
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* Adds a demo store banner to the site if enabled. |
438
|
|
|
* |
439
|
|
|
*/ |
440
|
|
|
function woocommerce_demo_store() { |
441
|
|
|
if ( ! is_store_notice_showing() ) { |
442
|
|
|
return; |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
$notice = get_option( 'woocommerce_demo_store_notice' ); |
446
|
|
|
|
447
|
|
|
if ( empty( $notice ) ) { |
448
|
|
|
$notice = __( 'This is a demo store for testing purposes — no orders shall be fulfilled.', 'woocommerce' ); |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
echo apply_filters( 'woocommerce_demo_store', '<p class="demo_store">' . wp_kses_post( $notice ) . '</p>' ); |
452
|
|
|
} |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** Loop ******************************************************************/ |
456
|
|
|
|
457
|
|
|
if ( ! function_exists( 'woocommerce_page_title' ) ) { |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* woocommerce_page_title function. |
461
|
|
|
* |
462
|
|
|
* @param bool $echo |
463
|
|
|
* @return string |
464
|
|
|
*/ |
465
|
|
|
function woocommerce_page_title( $echo = true ) { |
466
|
|
|
|
467
|
|
|
if ( is_search() ) { |
468
|
|
|
$page_title = sprintf( __( 'Search Results: “%s”', 'woocommerce' ), get_search_query() ); |
469
|
|
|
|
470
|
|
|
if ( get_query_var( 'paged' ) ) |
471
|
|
|
$page_title .= sprintf( __( ' – Page %s', 'woocommerce' ), get_query_var( 'paged' ) ); |
472
|
|
|
|
473
|
|
|
} elseif ( is_tax() ) { |
474
|
|
|
|
475
|
|
|
$page_title = single_term_title( "", false ); |
476
|
|
|
|
477
|
|
|
} else { |
478
|
|
|
|
479
|
|
|
$shop_page_id = wc_get_page_id( 'shop' ); |
480
|
|
|
$page_title = get_the_title( $shop_page_id ); |
481
|
|
|
|
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
$page_title = apply_filters( 'woocommerce_page_title', $page_title ); |
485
|
|
|
|
486
|
|
|
if ( $echo ) |
487
|
|
|
echo $page_title; |
488
|
|
|
else |
489
|
|
|
return $page_title; |
490
|
|
|
} |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
if ( ! function_exists( 'woocommerce_product_loop_start' ) ) { |
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* Output the start of a product loop. By default this is a UL. |
497
|
|
|
* |
498
|
|
|
* @param bool $echo |
499
|
|
|
* @return string |
500
|
|
|
*/ |
501
|
|
|
function woocommerce_product_loop_start( $echo = true ) { |
502
|
|
|
ob_start(); |
503
|
|
|
$GLOBALS['woocommerce_loop']['loop'] = 0; |
504
|
|
|
wc_get_template( 'loop/loop-start.php' ); |
505
|
|
|
if ( $echo ) |
506
|
|
|
echo ob_get_clean(); |
507
|
|
|
else |
508
|
|
|
return ob_get_clean(); |
509
|
|
|
} |
510
|
|
|
} |
511
|
|
|
if ( ! function_exists( 'woocommerce_product_loop_end' ) ) { |
512
|
|
|
|
513
|
|
|
/** |
514
|
|
|
* Output the end of a product loop. By default this is a UL. |
515
|
|
|
* |
516
|
|
|
* @param bool $echo |
517
|
|
|
* @return string |
518
|
|
|
*/ |
519
|
|
|
function woocommerce_product_loop_end( $echo = true ) { |
520
|
|
|
ob_start(); |
521
|
|
|
|
522
|
|
|
wc_get_template( 'loop/loop-end.php' ); |
523
|
|
|
|
524
|
|
|
if ( $echo ) |
525
|
|
|
echo ob_get_clean(); |
526
|
|
|
else |
527
|
|
|
return ob_get_clean(); |
528
|
|
|
} |
529
|
|
|
} |
530
|
|
|
if ( ! function_exists( 'woocommerce_template_loop_product_title' ) ) { |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* Show the product title in the product loop. By default this is an H3. |
534
|
|
|
*/ |
535
|
|
|
function woocommerce_template_loop_product_title() { |
536
|
|
|
echo '<h3>' . get_the_title() . '</h3>'; |
537
|
|
|
} |
538
|
|
|
} |
539
|
|
|
if ( ! function_exists( 'woocommerce_template_loop_category_title' ) ) { |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* Show the subcategory title in the product loop. |
543
|
|
|
*/ |
544
|
|
|
function woocommerce_template_loop_category_title( $category ) { |
545
|
|
|
?> |
546
|
|
|
<h3> |
547
|
|
|
<?php |
548
|
|
|
echo $category->name; |
549
|
|
|
|
550
|
|
|
if ( $category->count > 0 ) |
551
|
|
|
echo apply_filters( 'woocommerce_subcategory_count_html', ' <mark class="count">(' . $category->count . ')</mark>', $category ); |
552
|
|
|
?> |
553
|
|
|
</h3> |
554
|
|
|
<?php |
555
|
|
|
} |
556
|
|
|
} |
557
|
|
|
/** |
558
|
|
|
* Insert the opening anchor tag for products in the loop. |
559
|
|
|
*/ |
560
|
|
|
function woocommerce_template_loop_product_link_open() { |
561
|
|
|
echo '<a href="' . get_the_permalink() . '" class="woocommerce-LoopProduct-link">'; |
562
|
|
|
} |
563
|
|
|
/** |
564
|
|
|
* Insert the opening anchor tag for products in the loop. |
565
|
|
|
*/ |
566
|
|
|
function woocommerce_template_loop_product_link_close() { |
567
|
|
|
echo '</a>'; |
568
|
|
|
} |
569
|
|
|
/** |
570
|
|
|
* Insert the opening anchor tag for categories in the loop. |
571
|
|
|
*/ |
572
|
|
|
function woocommerce_template_loop_category_link_open( $category ) { |
573
|
|
|
echo '<a href="' . get_term_link( $category, 'product_cat' ) . '">'; |
574
|
|
|
} |
575
|
|
|
/** |
576
|
|
|
* Insert the opening anchor tag for categories in the loop. |
577
|
|
|
*/ |
578
|
|
|
function woocommerce_template_loop_category_link_close() { |
579
|
|
|
echo '</a>'; |
580
|
|
|
} |
581
|
|
|
if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) { |
582
|
|
|
|
583
|
|
|
/** |
584
|
|
|
* Show an archive description on taxonomy archives. |
585
|
|
|
* |
586
|
|
|
* @subpackage Archives |
587
|
|
|
*/ |
588
|
|
|
function woocommerce_taxonomy_archive_description() { |
589
|
|
|
if ( is_tax( array( 'product_cat', 'product_tag' ) ) && 0 === absint( get_query_var( 'paged' ) ) ) { |
590
|
|
|
$description = wc_format_content( term_description() ); |
591
|
|
|
if ( $description ) { |
592
|
|
|
echo '<div class="term-description">' . $description . '</div>'; |
593
|
|
|
} |
594
|
|
|
} |
595
|
|
|
} |
596
|
|
|
} |
597
|
|
|
if ( ! function_exists( 'woocommerce_product_archive_description' ) ) { |
598
|
|
|
|
599
|
|
|
/** |
600
|
|
|
* Show a shop page description on product archives. |
601
|
|
|
* |
602
|
|
|
* @subpackage Archives |
603
|
|
|
*/ |
604
|
|
|
function woocommerce_product_archive_description() { |
605
|
|
|
if ( is_post_type_archive( 'product' ) && 0 === absint( get_query_var( 'paged' ) ) ) { |
606
|
|
|
$shop_page = get_post( wc_get_page_id( 'shop' ) ); |
607
|
|
|
if ( $shop_page ) { |
608
|
|
|
$description = wc_format_content( $shop_page->post_content ); |
609
|
|
|
if ( $description ) { |
610
|
|
|
echo '<div class="page-description">' . $description . '</div>'; |
611
|
|
|
} |
612
|
|
|
} |
613
|
|
|
} |
614
|
|
|
} |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
if ( ! function_exists( 'woocommerce_template_loop_add_to_cart' ) ) { |
618
|
|
|
|
619
|
|
|
/** |
620
|
|
|
* Get the add to cart template for the loop. |
621
|
|
|
* |
622
|
|
|
* @subpackage Loop |
623
|
|
|
*/ |
624
|
|
|
function woocommerce_template_loop_add_to_cart( $args = array() ) { |
625
|
|
|
global $product; |
626
|
|
|
|
627
|
|
|
if ( $product ) { |
628
|
|
|
$defaults = array( |
629
|
|
|
'quantity' => 1, |
630
|
|
|
'class' => implode( ' ', array_filter( array( |
631
|
|
|
'button', |
632
|
|
|
'product_type_' . $product->product_type, |
633
|
|
|
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '', |
634
|
|
|
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '' |
635
|
|
|
) ) ) |
636
|
|
|
); |
637
|
|
|
|
638
|
|
|
$args = apply_filters( 'woocommerce_loop_add_to_cart_args', wp_parse_args( $args, $defaults ), $product ); |
639
|
|
|
|
640
|
|
|
wc_get_template( 'loop/add-to-cart.php', $args ); |
641
|
|
|
} |
642
|
|
|
} |
643
|
|
|
} |
644
|
|
|
if ( ! function_exists( 'woocommerce_template_loop_product_thumbnail' ) ) { |
645
|
|
|
|
646
|
|
|
/** |
647
|
|
|
* Get the product thumbnail for the loop. |
648
|
|
|
* |
649
|
|
|
* @subpackage Loop |
650
|
|
|
*/ |
651
|
|
|
function woocommerce_template_loop_product_thumbnail() { |
652
|
|
|
echo woocommerce_get_product_thumbnail(); |
653
|
|
|
} |
654
|
|
|
} |
655
|
|
|
if ( ! function_exists( 'woocommerce_template_loop_price' ) ) { |
656
|
|
|
|
657
|
|
|
/** |
658
|
|
|
* Get the product price for the loop. |
659
|
|
|
* |
660
|
|
|
* @subpackage Loop |
661
|
|
|
*/ |
662
|
|
|
function woocommerce_template_loop_price() { |
663
|
|
|
wc_get_template( 'loop/price.php' ); |
664
|
|
|
} |
665
|
|
|
} |
666
|
|
|
if ( ! function_exists( 'woocommerce_template_loop_rating' ) ) { |
667
|
|
|
|
668
|
|
|
/** |
669
|
|
|
* Display the average rating in the loop. |
670
|
|
|
* |
671
|
|
|
* @subpackage Loop |
672
|
|
|
*/ |
673
|
|
|
function woocommerce_template_loop_rating() { |
674
|
|
|
wc_get_template( 'loop/rating.php' ); |
675
|
|
|
} |
676
|
|
|
} |
677
|
|
|
if ( ! function_exists( 'woocommerce_show_product_loop_sale_flash' ) ) { |
678
|
|
|
|
679
|
|
|
/** |
680
|
|
|
* Get the sale flash for the loop. |
681
|
|
|
* |
682
|
|
|
* @subpackage Loop |
683
|
|
|
*/ |
684
|
|
|
function woocommerce_show_product_loop_sale_flash() { |
685
|
|
|
wc_get_template( 'loop/sale-flash.php' ); |
686
|
|
|
} |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
if ( ! function_exists( 'woocommerce_get_product_schema' ) ) { |
690
|
|
|
|
691
|
|
|
/** |
692
|
|
|
* Get a products Schema. |
693
|
|
|
* @return string |
694
|
|
|
*/ |
695
|
|
|
function woocommerce_get_product_schema() { |
696
|
|
|
global $product; |
697
|
|
|
|
698
|
|
|
$schema = "Product"; |
699
|
|
|
|
700
|
|
|
// Downloadable product schema handling |
701
|
|
|
if ( $product->is_downloadable() ) { |
702
|
|
|
switch ( $product->download_type ) { |
703
|
|
|
case 'application' : |
704
|
|
|
$schema = "SoftwareApplication"; |
705
|
|
|
break; |
706
|
|
|
case 'music' : |
707
|
|
|
$schema = "MusicAlbum"; |
708
|
|
|
break; |
709
|
|
|
default : |
710
|
|
|
$schema = "Product"; |
711
|
|
|
break; |
712
|
|
|
} |
713
|
|
|
} |
714
|
|
|
|
715
|
|
|
return 'http://schema.org/' . $schema; |
716
|
|
|
} |
717
|
|
|
} |
718
|
|
|
|
719
|
|
|
if ( ! function_exists( 'woocommerce_get_product_thumbnail' ) ) { |
720
|
|
|
|
721
|
|
|
/** |
722
|
|
|
* Get the product thumbnail, or the placeholder if not set. |
723
|
|
|
* |
724
|
|
|
* @subpackage Loop |
725
|
|
|
* @param string $size (default: 'shop_catalog') |
726
|
|
|
* @param int $deprecated1 Deprecated since WooCommerce 2.0 (default: 0) |
727
|
|
|
* @param int $deprecated2 Deprecated since WooCommerce 2.0 (default: 0) |
728
|
|
|
* @return string |
729
|
|
|
*/ |
730
|
|
|
function woocommerce_get_product_thumbnail( $size = 'shop_catalog', $deprecated1 = 0, $deprecated2 = 0 ) { |
|
|
|
|
731
|
|
|
global $post; |
732
|
|
|
$image_size = apply_filters( 'single_product_archive_thumbnail_size', $size ); |
733
|
|
|
|
734
|
|
|
if ( has_post_thumbnail() ) { |
735
|
|
|
$props = wc_get_product_attachment_props( get_post_thumbnail_id(), $post ); |
736
|
|
|
return get_the_post_thumbnail( $post->ID, $image_size, array( |
737
|
|
|
'title' => $props['title'], |
738
|
|
|
'alt' => $props['alt'], |
739
|
|
|
) ); |
740
|
|
|
} elseif ( wc_placeholder_img_src() ) { |
741
|
|
|
return wc_placeholder_img( $image_size ); |
742
|
|
|
} |
743
|
|
|
} |
744
|
|
|
} |
745
|
|
|
|
746
|
|
|
if ( ! function_exists( 'woocommerce_result_count' ) ) { |
747
|
|
|
|
748
|
|
|
/** |
749
|
|
|
* Output the result count text (Showing x - x of x results). |
750
|
|
|
* |
751
|
|
|
* @subpackage Loop |
752
|
|
|
*/ |
753
|
|
|
function woocommerce_result_count() { |
754
|
|
|
wc_get_template( 'loop/result-count.php' ); |
755
|
|
|
} |
756
|
|
|
} |
757
|
|
|
|
758
|
|
|
if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) { |
759
|
|
|
|
760
|
|
|
/** |
761
|
|
|
* Output the product sorting options. |
762
|
|
|
* |
763
|
|
|
* @subpackage Loop |
764
|
|
|
*/ |
765
|
|
|
function woocommerce_catalog_ordering() { |
766
|
|
|
global $wp_query; |
767
|
|
|
|
768
|
|
|
if ( 1 === $wp_query->found_posts || ! woocommerce_products_will_display() ) { |
769
|
|
|
return; |
770
|
|
|
} |
771
|
|
|
|
772
|
|
|
$orderby = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); |
773
|
|
|
$show_default_orderby = 'menu_order' === apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); |
774
|
|
|
$catalog_orderby_options = apply_filters( 'woocommerce_catalog_orderby', array( |
775
|
|
|
'menu_order' => __( 'Default sorting', 'woocommerce' ), |
776
|
|
|
'popularity' => __( 'Sort by popularity', 'woocommerce' ), |
777
|
|
|
'rating' => __( 'Sort by average rating', 'woocommerce' ), |
778
|
|
|
'date' => __( 'Sort by newness', 'woocommerce' ), |
779
|
|
|
'price' => __( 'Sort by price: low to high', 'woocommerce' ), |
780
|
|
|
'price-desc' => __( 'Sort by price: high to low', 'woocommerce' ) |
781
|
|
|
) ); |
782
|
|
|
|
783
|
|
|
if ( ! $show_default_orderby ) { |
784
|
|
|
unset( $catalog_orderby_options['menu_order'] ); |
785
|
|
|
} |
786
|
|
|
|
787
|
|
|
if ( 'no' === get_option( 'woocommerce_enable_review_rating' ) ) { |
788
|
|
|
unset( $catalog_orderby_options['rating'] ); |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
wc_get_template( 'loop/orderby.php', array( 'catalog_orderby_options' => $catalog_orderby_options, 'orderby' => $orderby, 'show_default_orderby' => $show_default_orderby ) ); |
792
|
|
|
} |
793
|
|
|
} |
794
|
|
|
|
795
|
|
|
if ( ! function_exists( 'woocommerce_pagination' ) ) { |
796
|
|
|
|
797
|
|
|
/** |
798
|
|
|
* Output the pagination. |
799
|
|
|
* |
800
|
|
|
* @subpackage Loop |
801
|
|
|
*/ |
802
|
|
|
function woocommerce_pagination() { |
803
|
|
|
wc_get_template( 'loop/pagination.php' ); |
804
|
|
|
} |
805
|
|
|
} |
806
|
|
|
|
807
|
|
|
/** Single Product ********************************************************/ |
808
|
|
|
|
809
|
|
|
if ( ! function_exists( 'woocommerce_show_product_images' ) ) { |
810
|
|
|
|
811
|
|
|
/** |
812
|
|
|
* Output the product image before the single product summary. |
813
|
|
|
* |
814
|
|
|
* @subpackage Product |
815
|
|
|
*/ |
816
|
|
|
function woocommerce_show_product_images() { |
817
|
|
|
wc_get_template( 'single-product/product-image.php' ); |
818
|
|
|
} |
819
|
|
|
} |
820
|
|
|
if ( ! function_exists( 'woocommerce_show_product_thumbnails' ) ) { |
821
|
|
|
|
822
|
|
|
/** |
823
|
|
|
* Output the product thumbnails. |
824
|
|
|
* |
825
|
|
|
* @subpackage Product |
826
|
|
|
*/ |
827
|
|
|
function woocommerce_show_product_thumbnails() { |
828
|
|
|
wc_get_template( 'single-product/product-thumbnails.php' ); |
829
|
|
|
} |
830
|
|
|
} |
831
|
|
|
if ( ! function_exists( 'woocommerce_output_product_data_tabs' ) ) { |
832
|
|
|
|
833
|
|
|
/** |
834
|
|
|
* Output the product tabs. |
835
|
|
|
* |
836
|
|
|
* @subpackage Product/Tabs |
837
|
|
|
*/ |
838
|
|
|
function woocommerce_output_product_data_tabs() { |
839
|
|
|
wc_get_template( 'single-product/tabs/tabs.php' ); |
840
|
|
|
} |
841
|
|
|
} |
842
|
|
|
if ( ! function_exists( 'woocommerce_template_single_title' ) ) { |
843
|
|
|
|
844
|
|
|
/** |
845
|
|
|
* Output the product title. |
846
|
|
|
* |
847
|
|
|
* @subpackage Product |
848
|
|
|
*/ |
849
|
|
|
function woocommerce_template_single_title() { |
850
|
|
|
wc_get_template( 'single-product/title.php' ); |
851
|
|
|
} |
852
|
|
|
} |
853
|
|
|
if ( ! function_exists( 'woocommerce_template_single_rating' ) ) { |
854
|
|
|
|
855
|
|
|
/** |
856
|
|
|
* Output the product rating. |
857
|
|
|
* |
858
|
|
|
* @subpackage Product |
859
|
|
|
*/ |
860
|
|
|
function woocommerce_template_single_rating() { |
861
|
|
|
wc_get_template( 'single-product/rating.php' ); |
862
|
|
|
} |
863
|
|
|
} |
864
|
|
|
if ( ! function_exists( 'woocommerce_template_single_price' ) ) { |
865
|
|
|
|
866
|
|
|
/** |
867
|
|
|
* Output the product price. |
868
|
|
|
* |
869
|
|
|
* @subpackage Product |
870
|
|
|
*/ |
871
|
|
|
function woocommerce_template_single_price() { |
872
|
|
|
wc_get_template( 'single-product/price.php' ); |
873
|
|
|
} |
874
|
|
|
} |
875
|
|
|
if ( ! function_exists( 'woocommerce_template_single_excerpt' ) ) { |
876
|
|
|
|
877
|
|
|
/** |
878
|
|
|
* Output the product short description (excerpt). |
879
|
|
|
* |
880
|
|
|
* @subpackage Product |
881
|
|
|
*/ |
882
|
|
|
function woocommerce_template_single_excerpt() { |
883
|
|
|
wc_get_template( 'single-product/short-description.php' ); |
884
|
|
|
} |
885
|
|
|
} |
886
|
|
|
if ( ! function_exists( 'woocommerce_template_single_meta' ) ) { |
887
|
|
|
|
888
|
|
|
/** |
889
|
|
|
* Output the product meta. |
890
|
|
|
* |
891
|
|
|
* @subpackage Product |
892
|
|
|
*/ |
893
|
|
|
function woocommerce_template_single_meta() { |
894
|
|
|
wc_get_template( 'single-product/meta.php' ); |
895
|
|
|
} |
896
|
|
|
} |
897
|
|
|
if ( ! function_exists( 'woocommerce_template_single_sharing' ) ) { |
898
|
|
|
|
899
|
|
|
/** |
900
|
|
|
* Output the product sharing. |
901
|
|
|
* |
902
|
|
|
* @subpackage Product |
903
|
|
|
*/ |
904
|
|
|
function woocommerce_template_single_sharing() { |
905
|
|
|
wc_get_template( 'single-product/share.php' ); |
906
|
|
|
} |
907
|
|
|
} |
908
|
|
|
if ( ! function_exists( 'woocommerce_show_product_sale_flash' ) ) { |
909
|
|
|
|
910
|
|
|
/** |
911
|
|
|
* Output the product sale flash. |
912
|
|
|
* |
913
|
|
|
* @subpackage Product |
914
|
|
|
*/ |
915
|
|
|
function woocommerce_show_product_sale_flash() { |
916
|
|
|
wc_get_template( 'single-product/sale-flash.php' ); |
917
|
|
|
} |
918
|
|
|
} |
919
|
|
|
|
920
|
|
|
if ( ! function_exists( 'woocommerce_template_single_add_to_cart' ) ) { |
921
|
|
|
|
922
|
|
|
/** |
923
|
|
|
* Trigger the single product add to cart action. |
924
|
|
|
* |
925
|
|
|
* @subpackage Product |
926
|
|
|
*/ |
927
|
|
|
function woocommerce_template_single_add_to_cart() { |
928
|
|
|
global $product; |
929
|
|
|
do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' ); |
930
|
|
|
} |
931
|
|
|
} |
932
|
|
|
if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) { |
933
|
|
|
|
934
|
|
|
/** |
935
|
|
|
* Output the simple product add to cart area. |
936
|
|
|
* |
937
|
|
|
* @subpackage Product |
938
|
|
|
*/ |
939
|
|
|
function woocommerce_simple_add_to_cart() { |
940
|
|
|
wc_get_template( 'single-product/add-to-cart/simple.php' ); |
941
|
|
|
} |
942
|
|
|
} |
943
|
|
|
if ( ! function_exists( 'woocommerce_grouped_add_to_cart' ) ) { |
944
|
|
|
|
945
|
|
|
/** |
946
|
|
|
* Output the grouped product add to cart area. |
947
|
|
|
* |
948
|
|
|
* @subpackage Product |
949
|
|
|
*/ |
950
|
|
|
function woocommerce_grouped_add_to_cart() { |
951
|
|
|
global $product; |
952
|
|
|
|
953
|
|
|
wc_get_template( 'single-product/add-to-cart/grouped.php', array( |
954
|
|
|
'grouped_product' => $product, |
955
|
|
|
'grouped_products' => $product->get_children(), |
956
|
|
|
'quantites_required' => false |
957
|
|
|
) ); |
958
|
|
|
} |
959
|
|
|
} |
960
|
|
|
if ( ! function_exists( 'woocommerce_variable_add_to_cart' ) ) { |
961
|
|
|
|
962
|
|
|
/** |
963
|
|
|
* Output the variable product add to cart area. |
964
|
|
|
* |
965
|
|
|
* @subpackage Product |
966
|
|
|
*/ |
967
|
|
|
function woocommerce_variable_add_to_cart() { |
968
|
|
|
global $product; |
969
|
|
|
|
970
|
|
|
// Enqueue variation scripts |
971
|
|
|
wp_enqueue_script( 'wc-add-to-cart-variation' ); |
972
|
|
|
|
973
|
|
|
// Get Available variations? |
974
|
|
|
$get_variations = sizeof( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product ); |
975
|
|
|
|
976
|
|
|
// Load the template |
977
|
|
|
wc_get_template( 'single-product/add-to-cart/variable.php', array( |
978
|
|
|
'available_variations' => $get_variations ? $product->get_available_variations() : false, |
979
|
|
|
'attributes' => $product->get_variation_attributes(), |
980
|
|
|
'selected_attributes' => $product->get_variation_default_attributes() |
981
|
|
|
) ); |
982
|
|
|
} |
983
|
|
|
} |
984
|
|
|
if ( ! function_exists( 'woocommerce_external_add_to_cart' ) ) { |
985
|
|
|
|
986
|
|
|
/** |
987
|
|
|
* Output the external product add to cart area. |
988
|
|
|
* |
989
|
|
|
* @subpackage Product |
990
|
|
|
*/ |
991
|
|
|
function woocommerce_external_add_to_cart() { |
992
|
|
|
global $product; |
993
|
|
|
|
994
|
|
|
if ( ! $product->add_to_cart_url() ) { |
995
|
|
|
return; |
996
|
|
|
} |
997
|
|
|
|
998
|
|
|
wc_get_template( 'single-product/add-to-cart/external.php', array( |
999
|
|
|
'product_url' => $product->add_to_cart_url(), |
1000
|
|
|
'button_text' => $product->single_add_to_cart_text() |
1001
|
|
|
) ); |
1002
|
|
|
} |
1003
|
|
|
} |
1004
|
|
|
|
1005
|
|
|
if ( ! function_exists( 'woocommerce_quantity_input' ) ) { |
1006
|
|
|
|
1007
|
|
|
/** |
1008
|
|
|
* Output the quantity input for add to cart forms. |
1009
|
|
|
* |
1010
|
|
|
* @param array $args Args for the input |
1011
|
|
|
* @param WC_Product|null $product |
1012
|
|
|
* @param boolean $echo Whether to return or echo|string |
1013
|
|
|
*/ |
1014
|
|
|
function woocommerce_quantity_input( $args = array(), $product = null, $echo = true ) { |
1015
|
|
|
if ( is_null( $product ) ) { |
1016
|
|
|
$product = $GLOBALS['product']; |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
$defaults = array( |
1020
|
|
|
'input_name' => 'quantity', |
1021
|
|
|
'input_value' => '1', |
1022
|
|
|
'max_value' => apply_filters( 'woocommerce_quantity_input_max', '', $product ), |
1023
|
|
|
'min_value' => apply_filters( 'woocommerce_quantity_input_min', '', $product ), |
1024
|
|
|
'step' => apply_filters( 'woocommerce_quantity_input_step', '1', $product ), |
1025
|
|
|
'pattern' => apply_filters( 'woocommerce_quantity_input_pattern', has_filter( 'woocommerce_stock_amount', 'intval' ) ? '[0-9]*' : '' ), |
1026
|
|
|
'inputmode' => apply_filters( 'woocommerce_quantity_input_inputmode', has_filter( 'woocommerce_stock_amount', 'intval' ) ? 'numeric' : '' ), |
1027
|
|
|
); |
1028
|
|
|
|
1029
|
|
|
$args = apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product ); |
1030
|
|
|
|
1031
|
|
|
// Apply sanity to min/max args - min cannot be lower than 0 |
1032
|
|
|
if ( '' !== $args['min_value'] && is_numeric( $args['min_value'] ) && $args['min_value'] < 0 ) { |
1033
|
|
|
$args['min_value'] = 0; // Cannot be lower than 0 |
1034
|
|
|
} |
1035
|
|
|
|
1036
|
|
|
// Max cannot be lower than 0 or min |
1037
|
|
|
if ( '' !== $args['max_value'] && is_numeric( $args['max_value'] ) ) { |
1038
|
|
|
$args['max_value'] = $args['max_value'] < 0 ? 0 : $args['max_value']; |
1039
|
|
|
$args['max_value'] = $args['max_value'] < $args['min_value'] ? $args['min_value'] : $args['max_value']; |
1040
|
|
|
} |
1041
|
|
|
|
1042
|
|
|
ob_start(); |
1043
|
|
|
|
1044
|
|
|
wc_get_template( 'global/quantity-input.php', $args ); |
1045
|
|
|
|
1046
|
|
|
if ( $echo ) { |
1047
|
|
|
echo ob_get_clean(); |
1048
|
|
|
} else { |
1049
|
|
|
return ob_get_clean(); |
1050
|
|
|
} |
1051
|
|
|
} |
1052
|
|
|
} |
1053
|
|
|
|
1054
|
|
|
if ( ! function_exists( 'woocommerce_product_description_tab' ) ) { |
1055
|
|
|
|
1056
|
|
|
/** |
1057
|
|
|
* Output the description tab content. |
1058
|
|
|
* |
1059
|
|
|
* @subpackage Product/Tabs |
1060
|
|
|
*/ |
1061
|
|
|
function woocommerce_product_description_tab() { |
1062
|
|
|
wc_get_template( 'single-product/tabs/description.php' ); |
1063
|
|
|
} |
1064
|
|
|
} |
1065
|
|
|
if ( ! function_exists( 'woocommerce_product_additional_information_tab' ) ) { |
1066
|
|
|
|
1067
|
|
|
/** |
1068
|
|
|
* Output the attributes tab content. |
1069
|
|
|
* |
1070
|
|
|
* @subpackage Product/Tabs |
1071
|
|
|
*/ |
1072
|
|
|
function woocommerce_product_additional_information_tab() { |
1073
|
|
|
wc_get_template( 'single-product/tabs/additional-information.php' ); |
1074
|
|
|
} |
1075
|
|
|
} |
1076
|
|
|
if ( ! function_exists( 'woocommerce_product_reviews_tab' ) ) { |
1077
|
|
|
|
1078
|
|
|
/** |
1079
|
|
|
* Output the reviews tab content. |
1080
|
|
|
* @deprecated 2.4.0 Unused |
1081
|
|
|
* @subpackage Product/Tabs |
1082
|
|
|
*/ |
1083
|
|
|
function woocommerce_product_reviews_tab() { |
1084
|
|
|
_deprecated_function( 'woocommerce_product_reviews_tab', '2.4', '' ); |
1085
|
|
|
} |
1086
|
|
|
} |
1087
|
|
|
|
1088
|
|
|
if ( ! function_exists( 'woocommerce_default_product_tabs' ) ) { |
1089
|
|
|
|
1090
|
|
|
/** |
1091
|
|
|
* Add default product tabs to product pages. |
1092
|
|
|
* |
1093
|
|
|
* @param array $tabs |
1094
|
|
|
* @return array |
1095
|
|
|
*/ |
1096
|
|
|
function woocommerce_default_product_tabs( $tabs = array() ) { |
1097
|
|
|
global $product, $post; |
1098
|
|
|
|
1099
|
|
|
// Description tab - shows product content |
1100
|
|
|
if ( $post->post_content ) { |
1101
|
|
|
$tabs['description'] = array( |
1102
|
|
|
'title' => __( 'Description', 'woocommerce' ), |
1103
|
|
|
'priority' => 10, |
1104
|
|
|
'callback' => 'woocommerce_product_description_tab' |
1105
|
|
|
); |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
// Additional information tab - shows attributes |
1109
|
|
|
if ( $product && ( $product->has_attributes() || ( $product->enable_dimensions_display() && ( $product->has_dimensions() || $product->has_weight() ) ) ) ) { |
1110
|
|
|
$tabs['additional_information'] = array( |
1111
|
|
|
'title' => __( 'Additional Information', 'woocommerce' ), |
1112
|
|
|
'priority' => 20, |
1113
|
|
|
'callback' => 'woocommerce_product_additional_information_tab' |
1114
|
|
|
); |
1115
|
|
|
} |
1116
|
|
|
|
1117
|
|
|
// Reviews tab - shows comments |
1118
|
|
|
if ( comments_open() ) { |
1119
|
|
|
$tabs['reviews'] = array( |
1120
|
|
|
'title' => sprintf( __( 'Reviews (%d)', 'woocommerce' ), $product->get_review_count() ), |
1121
|
|
|
'priority' => 30, |
1122
|
|
|
'callback' => 'comments_template' |
1123
|
|
|
); |
1124
|
|
|
} |
1125
|
|
|
|
1126
|
|
|
return $tabs; |
1127
|
|
|
} |
1128
|
|
|
} |
1129
|
|
|
|
1130
|
|
|
if ( ! function_exists( 'woocommerce_sort_product_tabs' ) ) { |
1131
|
|
|
|
1132
|
|
|
/** |
1133
|
|
|
* Sort tabs by priority. |
1134
|
|
|
* |
1135
|
|
|
* @param array $tabs |
1136
|
|
|
* @return array |
1137
|
|
|
*/ |
1138
|
|
|
function woocommerce_sort_product_tabs( $tabs = array() ) { |
1139
|
|
|
|
1140
|
|
|
// Make sure the $tabs parameter is an array |
1141
|
|
|
if ( ! is_array( $tabs ) ) { |
1142
|
|
|
trigger_error( "Function woocommerce_sort_product_tabs() expects an array as the first parameter. Defaulting to empty array." ); |
1143
|
|
|
$tabs = array( ); |
1144
|
|
|
} |
1145
|
|
|
|
1146
|
|
|
// Re-order tabs by priority |
1147
|
|
|
if ( ! function_exists( '_sort_priority_callback' ) ) { |
1148
|
|
|
function _sort_priority_callback( $a, $b ) { |
1149
|
|
|
if ( $a['priority'] === $b['priority'] ) |
1150
|
|
|
return 0; |
1151
|
|
|
return ( $a['priority'] < $b['priority'] ) ? -1 : 1; |
1152
|
|
|
} |
1153
|
|
|
} |
1154
|
|
|
|
1155
|
|
|
uasort( $tabs, '_sort_priority_callback' ); |
1156
|
|
|
|
1157
|
|
|
return $tabs; |
1158
|
|
|
} |
1159
|
|
|
} |
1160
|
|
|
|
1161
|
|
|
if ( ! function_exists( 'woocommerce_comments' ) ) { |
1162
|
|
|
|
1163
|
|
|
/** |
1164
|
|
|
* Output the Review comments template. |
1165
|
|
|
* |
1166
|
|
|
* @subpackage Product |
1167
|
|
|
* @param WP_Comment $comment |
1168
|
|
|
* @param array $args |
1169
|
|
|
* @param int $depth |
1170
|
|
|
*/ |
1171
|
|
|
function woocommerce_comments( $comment, $args, $depth ) { |
1172
|
|
|
$GLOBALS['comment'] = $comment; |
1173
|
|
|
wc_get_template( 'single-product/review.php', array( 'comment' => $comment, 'args' => $args, 'depth' => $depth ) ); |
1174
|
|
|
} |
1175
|
|
|
} |
1176
|
|
|
|
1177
|
|
|
if ( ! function_exists( 'woocommerce_review_display_gravatar' ) ) { |
1178
|
|
|
/** |
1179
|
|
|
* Display the review authors gravatar |
1180
|
|
|
* |
1181
|
|
|
* @param array $comment WP_Comment. |
1182
|
|
|
* @return void |
1183
|
|
|
*/ |
1184
|
|
|
function woocommerce_review_display_gravatar( $comment ) { |
1185
|
|
|
echo get_avatar( $comment, apply_filters( 'woocommerce_review_gravatar_size', '60' ), '' ); |
1186
|
|
|
} |
1187
|
|
|
} |
1188
|
|
|
|
1189
|
|
|
if ( ! function_exists( 'woocommerce_review_display_rating' ) ) { |
1190
|
|
|
/** |
1191
|
|
|
* Display the reviewers star rating |
1192
|
|
|
* |
1193
|
|
|
* @return void |
1194
|
|
|
*/ |
1195
|
|
|
function woocommerce_review_display_rating() { |
1196
|
|
|
wc_get_template( 'single-product/review-rating.php' ); |
1197
|
|
|
} |
1198
|
|
|
} |
1199
|
|
|
|
1200
|
|
|
if ( ! function_exists( 'woocommerce_review_display_meta' ) ) { |
1201
|
|
|
/** |
1202
|
|
|
* Display the review authors meta (name, verified owner, review date) |
1203
|
|
|
* |
1204
|
|
|
* @return void |
1205
|
|
|
*/ |
1206
|
|
|
function woocommerce_review_display_meta() { |
1207
|
|
|
wc_get_template( 'single-product/review-meta.php' ); |
1208
|
|
|
} |
1209
|
|
|
} |
1210
|
|
|
|
1211
|
|
|
if ( ! function_exists( 'woocommerce_review_display_comment_text' ) ) { |
1212
|
|
|
/** |
1213
|
|
|
* Display the review content |
1214
|
|
|
* |
1215
|
|
|
* @return void |
1216
|
|
|
*/ |
1217
|
|
|
function woocommerce_review_display_comment_text() { |
1218
|
|
|
echo '<div itemprop="description" class="description">' . get_comment_text() . '</div>'; |
1219
|
|
|
} |
1220
|
|
|
} |
1221
|
|
|
|
1222
|
|
|
if ( ! function_exists( 'woocommerce_output_related_products' ) ) { |
1223
|
|
|
|
1224
|
|
|
/** |
1225
|
|
|
* Output the related products. |
1226
|
|
|
* |
1227
|
|
|
* @subpackage Product |
1228
|
|
|
*/ |
1229
|
|
|
function woocommerce_output_related_products() { |
1230
|
|
|
|
1231
|
|
|
$args = array( |
1232
|
|
|
'posts_per_page' => 4, |
1233
|
|
|
'columns' => 4, |
1234
|
|
|
'orderby' => 'rand' |
1235
|
|
|
); |
1236
|
|
|
|
1237
|
|
|
woocommerce_related_products( apply_filters( 'woocommerce_output_related_products_args', $args ) ); |
1238
|
|
|
} |
1239
|
|
|
} |
1240
|
|
|
|
1241
|
|
|
if ( ! function_exists( 'woocommerce_related_products' ) ) { |
1242
|
|
|
|
1243
|
|
|
/** |
1244
|
|
|
* Output the related products. |
1245
|
|
|
* |
1246
|
|
|
* @param array Provided arguments |
1247
|
|
|
* @param bool Columns argument for backwards compat |
1248
|
|
|
* @param bool Order by argument for backwards compat |
1249
|
|
|
*/ |
1250
|
|
|
function woocommerce_related_products( $args = array(), $columns = false, $orderby = false ) { |
1251
|
|
|
if ( ! is_array( $args ) ) { |
1252
|
|
|
_deprecated_argument( __FUNCTION__, '2.1', __( 'Use $args argument as an array instead. Deprecated argument will be removed in WC 2.2.', 'woocommerce' ) ); |
1253
|
|
|
|
1254
|
|
|
$argsvalue = $args; |
1255
|
|
|
|
1256
|
|
|
$args = array( |
1257
|
|
|
'posts_per_page' => $argsvalue, |
1258
|
|
|
'columns' => $columns, |
1259
|
|
|
'orderby' => $orderby, |
1260
|
|
|
); |
1261
|
|
|
} |
1262
|
|
|
|
1263
|
|
|
$defaults = array( |
1264
|
|
|
'posts_per_page' => 2, |
1265
|
|
|
'columns' => 2, |
1266
|
|
|
'orderby' => 'rand' |
1267
|
|
|
); |
1268
|
|
|
|
1269
|
|
|
$args = wp_parse_args( $args, $defaults ); |
1270
|
|
|
|
1271
|
|
|
wc_get_template( 'single-product/related.php', $args ); |
1272
|
|
|
} |
1273
|
|
|
} |
1274
|
|
|
|
1275
|
|
|
if ( ! function_exists( 'woocommerce_upsell_display' ) ) { |
1276
|
|
|
|
1277
|
|
|
/** |
1278
|
|
|
* Output product up sells. |
1279
|
|
|
* |
1280
|
|
|
* @param int $posts_per_page (default: -1) |
1281
|
|
|
* @param int $columns (default: 4) |
1282
|
|
|
* @param string $orderby (default: 'rand') |
1283
|
|
|
*/ |
1284
|
|
|
function woocommerce_upsell_display( $posts_per_page = '-1', $columns = 4, $orderby = 'rand' ) { |
1285
|
|
|
$args = apply_filters( 'woocommerce_upsell_display_args', array( |
1286
|
|
|
'posts_per_page' => $posts_per_page, |
1287
|
|
|
'orderby' => apply_filters( 'woocommerce_upsells_orderby', $orderby ), |
1288
|
|
|
'columns' => $columns |
1289
|
|
|
) ); |
1290
|
|
|
|
1291
|
|
|
wc_get_template( 'single-product/up-sells.php', $args ); |
1292
|
|
|
} |
1293
|
|
|
} |
1294
|
|
|
|
1295
|
|
|
/** Cart ******************************************************************/ |
1296
|
|
|
|
1297
|
|
|
if ( ! function_exists( 'woocommerce_shipping_calculator' ) ) { |
1298
|
|
|
|
1299
|
|
|
/** |
1300
|
|
|
* Output the cart shipping calculator. |
1301
|
|
|
* |
1302
|
|
|
* @subpackage Cart |
1303
|
|
|
*/ |
1304
|
|
|
function woocommerce_shipping_calculator() { |
1305
|
|
|
wc_get_template( 'cart/shipping-calculator.php' ); |
1306
|
|
|
} |
1307
|
|
|
} |
1308
|
|
|
|
1309
|
|
|
if ( ! function_exists( 'woocommerce_cart_totals' ) ) { |
1310
|
|
|
|
1311
|
|
|
/** |
1312
|
|
|
* Output the cart totals. |
1313
|
|
|
* |
1314
|
|
|
* @subpackage Cart |
1315
|
|
|
*/ |
1316
|
|
|
function woocommerce_cart_totals() { |
1317
|
|
|
wc_get_template( 'cart/cart-totals.php' ); |
1318
|
|
|
} |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
if ( ! function_exists( 'woocommerce_cross_sell_display' ) ) { |
1322
|
|
|
|
1323
|
|
|
/** |
1324
|
|
|
* Output the cart cross-sells. |
1325
|
|
|
* |
1326
|
|
|
* @param int $posts_per_page (default: 2) |
1327
|
|
|
* @param int $columns (default: 2) |
1328
|
|
|
* @param string $orderby (default: 'rand') |
1329
|
|
|
*/ |
1330
|
|
|
function woocommerce_cross_sell_display( $posts_per_page = 2, $columns = 2, $orderby = 'rand' ) { |
1331
|
|
|
wc_get_template( 'cart/cross-sells.php', array( |
1332
|
|
|
'posts_per_page' => $posts_per_page, |
1333
|
|
|
'orderby' => $orderby, |
1334
|
|
|
'columns' => $columns |
1335
|
|
|
) ); |
1336
|
|
|
} |
1337
|
|
|
} |
1338
|
|
|
|
1339
|
|
|
if ( ! function_exists( 'woocommerce_button_proceed_to_checkout' ) ) { |
1340
|
|
|
|
1341
|
|
|
/** |
1342
|
|
|
* Output the proceed to checkout button. |
1343
|
|
|
* |
1344
|
|
|
* @subpackage Cart |
1345
|
|
|
*/ |
1346
|
|
|
function woocommerce_button_proceed_to_checkout() { |
1347
|
|
|
wc_get_template( 'cart/proceed-to-checkout-button.php' ); |
1348
|
|
|
} |
1349
|
|
|
} |
1350
|
|
|
|
1351
|
|
|
|
1352
|
|
|
|
1353
|
|
|
/** Mini-Cart *************************************************************/ |
1354
|
|
|
|
1355
|
|
|
if ( ! function_exists( 'woocommerce_mini_cart' ) ) { |
1356
|
|
|
|
1357
|
|
|
/** |
1358
|
|
|
* Output the Mini-cart - used by cart widget. |
1359
|
|
|
* |
1360
|
|
|
* @param array $args |
1361
|
|
|
*/ |
1362
|
|
|
function woocommerce_mini_cart( $args = array() ) { |
1363
|
|
|
|
1364
|
|
|
$defaults = array( |
1365
|
|
|
'list_class' => '' |
1366
|
|
|
); |
1367
|
|
|
|
1368
|
|
|
$args = wp_parse_args( $args, $defaults ); |
1369
|
|
|
|
1370
|
|
|
wc_get_template( 'cart/mini-cart.php', $args ); |
1371
|
|
|
} |
1372
|
|
|
} |
1373
|
|
|
|
1374
|
|
|
/** Login *****************************************************************/ |
1375
|
|
|
|
1376
|
|
|
if ( ! function_exists( 'woocommerce_login_form' ) ) { |
1377
|
|
|
|
1378
|
|
|
/** |
1379
|
|
|
* Output the WooCommerce Login Form. |
1380
|
|
|
* |
1381
|
|
|
* @subpackage Forms |
1382
|
|
|
* @param array $args |
1383
|
|
|
*/ |
1384
|
|
|
function woocommerce_login_form( $args = array() ) { |
1385
|
|
|
|
1386
|
|
|
$defaults = array( |
1387
|
|
|
'message' => '', |
1388
|
|
|
'redirect' => '', |
1389
|
|
|
'hidden' => false |
1390
|
|
|
); |
1391
|
|
|
|
1392
|
|
|
$args = wp_parse_args( $args, $defaults ); |
1393
|
|
|
|
1394
|
|
|
wc_get_template( 'global/form-login.php', $args ); |
1395
|
|
|
} |
1396
|
|
|
} |
1397
|
|
|
|
1398
|
|
|
if ( ! function_exists( 'woocommerce_checkout_login_form' ) ) { |
1399
|
|
|
|
1400
|
|
|
/** |
1401
|
|
|
* Output the WooCommerce Checkout Login Form. |
1402
|
|
|
* |
1403
|
|
|
* @subpackage Checkout |
1404
|
|
|
*/ |
1405
|
|
|
function woocommerce_checkout_login_form() { |
1406
|
|
|
wc_get_template( 'checkout/form-login.php', array( 'checkout' => WC()->checkout() ) ); |
1407
|
|
|
} |
1408
|
|
|
} |
1409
|
|
|
|
1410
|
|
|
if ( ! function_exists( 'woocommerce_breadcrumb' ) ) { |
1411
|
|
|
|
1412
|
|
|
/** |
1413
|
|
|
* Output the WooCommerce Breadcrumb. |
1414
|
|
|
* |
1415
|
|
|
* @param array $args |
1416
|
|
|
*/ |
1417
|
|
|
function woocommerce_breadcrumb( $args = array() ) { |
1418
|
|
|
$args = wp_parse_args( $args, apply_filters( 'woocommerce_breadcrumb_defaults', array( |
1419
|
|
|
'delimiter' => ' / ', |
1420
|
|
|
'wrap_before' => '<nav class="woocommerce-breadcrumb" ' . ( is_single() ? 'itemprop="breadcrumb"' : '' ) . '>', |
1421
|
|
|
'wrap_after' => '</nav>', |
1422
|
|
|
'before' => '', |
1423
|
|
|
'after' => '', |
1424
|
|
|
'home' => _x( 'Home', 'breadcrumb', 'woocommerce' ) |
1425
|
|
|
) ) ); |
1426
|
|
|
|
1427
|
|
|
$breadcrumbs = new WC_Breadcrumb(); |
1428
|
|
|
|
1429
|
|
|
if ( $args['home'] ) { |
1430
|
|
|
$breadcrumbs->add_crumb( $args['home'], apply_filters( 'woocommerce_breadcrumb_home_url', home_url() ) ); |
1431
|
|
|
} |
1432
|
|
|
|
1433
|
|
|
$args['breadcrumb'] = $breadcrumbs->generate(); |
1434
|
|
|
|
1435
|
|
|
wc_get_template( 'global/breadcrumb.php', $args ); |
1436
|
|
|
} |
1437
|
|
|
} |
1438
|
|
|
|
1439
|
|
|
if ( ! function_exists( 'woocommerce_order_review' ) ) { |
1440
|
|
|
|
1441
|
|
|
/** |
1442
|
|
|
* Output the Order review table for the checkout. |
1443
|
|
|
* |
1444
|
|
|
* @subpackage Checkout |
1445
|
|
|
*/ |
1446
|
|
|
function woocommerce_order_review( $deprecated = false ) { |
|
|
|
|
1447
|
|
|
wc_get_template( 'checkout/review-order.php', array( 'checkout' => WC()->checkout() ) ); |
1448
|
|
|
} |
1449
|
|
|
} |
1450
|
|
|
|
1451
|
|
|
if ( ! function_exists( 'woocommerce_checkout_payment' ) ) { |
1452
|
|
|
|
1453
|
|
|
/** |
1454
|
|
|
* Output the Payment Methods on the checkout. |
1455
|
|
|
* |
1456
|
|
|
* @subpackage Checkout |
1457
|
|
|
*/ |
1458
|
|
|
function woocommerce_checkout_payment() { |
1459
|
|
|
if ( WC()->cart->needs_payment() ) { |
1460
|
|
|
$available_gateways = WC()->payment_gateways()->get_available_payment_gateways(); |
1461
|
|
|
WC()->payment_gateways()->set_current_gateway( $available_gateways ); |
1462
|
|
|
} else { |
1463
|
|
|
$available_gateways = array(); |
1464
|
|
|
} |
1465
|
|
|
|
1466
|
|
|
wc_get_template( 'checkout/payment.php', array( |
1467
|
|
|
'checkout' => WC()->checkout(), |
1468
|
|
|
'available_gateways' => $available_gateways, |
1469
|
|
|
'order_button_text' => apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ) |
1470
|
|
|
) ); |
1471
|
|
|
} |
1472
|
|
|
} |
1473
|
|
|
|
1474
|
|
|
if ( ! function_exists( 'woocommerce_checkout_coupon_form' ) ) { |
1475
|
|
|
|
1476
|
|
|
/** |
1477
|
|
|
* Output the Coupon form for the checkout. |
1478
|
|
|
* |
1479
|
|
|
* @subpackage Checkout |
1480
|
|
|
*/ |
1481
|
|
|
function woocommerce_checkout_coupon_form() { |
1482
|
|
|
wc_get_template( 'checkout/form-coupon.php', array( 'checkout' => WC()->checkout() ) ); |
1483
|
|
|
} |
1484
|
|
|
} |
1485
|
|
|
|
1486
|
|
|
if ( ! function_exists( 'woocommerce_products_will_display' ) ) { |
1487
|
|
|
|
1488
|
|
|
/** |
1489
|
|
|
* Check if we will be showing products or not (and not sub-categories only). |
1490
|
|
|
* @subpackage Loop |
1491
|
|
|
* @return bool |
1492
|
|
|
*/ |
1493
|
|
|
function woocommerce_products_will_display() { |
1494
|
|
|
global $wpdb; |
1495
|
|
|
|
1496
|
|
|
if ( is_shop() ) { |
1497
|
|
|
return 'subcategories' !== get_option( 'woocommerce_shop_page_display' ) || is_search(); |
1498
|
|
|
} |
1499
|
|
|
|
1500
|
|
|
if ( ! is_product_taxonomy() ) { |
1501
|
|
|
return false; |
1502
|
|
|
} |
1503
|
|
|
|
1504
|
|
|
if ( is_search() || is_filtered() || is_paged() ) { |
1505
|
|
|
return true; |
1506
|
|
|
} |
1507
|
|
|
|
1508
|
|
|
$term = get_queried_object(); |
1509
|
|
|
|
1510
|
|
|
if ( is_product_category() ) { |
1511
|
|
|
switch ( get_woocommerce_term_meta( $term->term_id, 'display_type', true ) ) { |
1512
|
|
|
case 'subcategories' : |
1513
|
|
|
// Nothing - we want to continue to see if there are products/subcats |
1514
|
|
|
break; |
1515
|
|
|
case 'products' : |
1516
|
|
|
case 'both' : |
1517
|
|
|
return true; |
1518
|
|
|
break; |
|
|
|
|
1519
|
|
|
default : |
1520
|
|
|
// Default - no setting |
1521
|
|
|
if ( get_option( 'woocommerce_category_archive_display' ) != 'subcategories' ) { |
1522
|
|
|
return true; |
1523
|
|
|
} |
1524
|
|
|
break; |
1525
|
|
|
} |
1526
|
|
|
} |
1527
|
|
|
|
1528
|
|
|
// Begin subcategory logic |
1529
|
|
|
if ( empty( $term->term_id ) || empty( $term->taxonomy ) ) { |
1530
|
|
|
return true; |
1531
|
|
|
} |
1532
|
|
|
|
1533
|
|
|
$transient_name = 'wc_products_will_display_' . $term->term_id . '_' . WC_Cache_Helper::get_transient_version( 'product_query' ); |
1534
|
|
|
|
1535
|
|
|
if ( false === ( $products_will_display = get_transient( $transient_name ) ) ) { |
1536
|
|
|
$has_children = $wpdb->get_col( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term->term_id, $term->taxonomy ) ); |
1537
|
|
|
|
1538
|
|
|
if ( $has_children ) { |
1539
|
|
|
// Check terms have products inside - parents first. If products are found inside, subcats will be shown instead of products so we can return false. |
1540
|
|
|
if ( sizeof( get_objects_in_term( $has_children, $term->taxonomy ) ) > 0 ) { |
1541
|
|
|
$products_will_display = false; |
1542
|
|
|
} else { |
1543
|
|
|
// If we get here, the parents were empty so we're forced to check children |
1544
|
|
|
foreach ( $has_children as $term_id ) { |
1545
|
|
|
$children = get_term_children( $term_id, $term->taxonomy ); |
1546
|
|
|
|
1547
|
|
|
if ( sizeof( get_objects_in_term( $children, $term->taxonomy ) ) > 0 ) { |
1548
|
|
|
$products_will_display = false; |
1549
|
|
|
break; |
1550
|
|
|
} |
1551
|
|
|
} |
1552
|
|
|
} |
1553
|
|
|
} else { |
1554
|
|
|
$products_will_display = true; |
1555
|
|
|
} |
1556
|
|
|
} |
1557
|
|
|
|
1558
|
|
|
set_transient( $transient_name, $products_will_display, DAY_IN_SECONDS * 30 ); |
1559
|
|
|
|
1560
|
|
|
return $products_will_display; |
1561
|
|
|
} |
1562
|
|
|
} |
1563
|
|
|
|
1564
|
|
|
if ( ! function_exists( 'woocommerce_product_subcategories' ) ) { |
1565
|
|
|
|
1566
|
|
|
/** |
1567
|
|
|
* Display product sub categories as thumbnails. |
1568
|
|
|
* |
1569
|
|
|
* @subpackage Loop |
1570
|
|
|
* @param array $args |
1571
|
|
|
* @return null|boolean |
1572
|
|
|
*/ |
1573
|
|
|
function woocommerce_product_subcategories( $args = array() ) { |
1574
|
|
|
global $wp_query; |
1575
|
|
|
|
1576
|
|
|
$defaults = array( |
1577
|
|
|
'before' => '', |
1578
|
|
|
'after' => '', |
1579
|
|
|
'force_display' => false |
1580
|
|
|
); |
1581
|
|
|
|
1582
|
|
|
$args = wp_parse_args( $args, $defaults ); |
1583
|
|
|
|
1584
|
|
|
extract( $args ); |
1585
|
|
|
|
1586
|
|
|
// Main query only |
1587
|
|
|
if ( ! is_main_query() && ! $force_display ) { |
1588
|
|
|
return; |
1589
|
|
|
} |
1590
|
|
|
|
1591
|
|
|
// Don't show when filtering, searching or when on page > 1 and ensure we're on a product archive |
1592
|
|
|
if ( is_search() || is_filtered() || is_paged() || ( ! is_product_category() && ! is_shop() ) ) { |
1593
|
|
|
return; |
1594
|
|
|
} |
1595
|
|
|
|
1596
|
|
|
// Check categories are enabled |
1597
|
|
|
if ( is_shop() && '' === get_option( 'woocommerce_shop_page_display' ) ) { |
1598
|
|
|
return; |
1599
|
|
|
} |
1600
|
|
|
|
1601
|
|
|
// Find the category + category parent, if applicable |
1602
|
|
|
$term = get_queried_object(); |
1603
|
|
|
$parent_id = empty( $term->term_id ) ? 0 : $term->term_id; |
1604
|
|
|
|
1605
|
|
|
if ( is_product_category() ) { |
1606
|
|
|
$display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true ); |
1607
|
|
|
|
1608
|
|
|
switch ( $display_type ) { |
1609
|
|
|
case 'products' : |
1610
|
|
|
return; |
1611
|
|
|
break; |
|
|
|
|
1612
|
|
|
case '' : |
1613
|
|
|
if ( '' === get_option( 'woocommerce_category_archive_display' ) ) { |
1614
|
|
|
return; |
1615
|
|
|
} |
1616
|
|
|
break; |
1617
|
|
|
} |
1618
|
|
|
} |
1619
|
|
|
|
1620
|
|
|
// NOTE: using child_of instead of parent - this is not ideal but due to a WP bug ( https://core.trac.wordpress.org/ticket/15626 ) pad_counts won't work |
1621
|
|
|
$product_categories = get_categories( apply_filters( 'woocommerce_product_subcategories_args', array( |
1622
|
|
|
'parent' => $parent_id, |
1623
|
|
|
'menu_order' => 'ASC', |
1624
|
|
|
'hide_empty' => 0, |
1625
|
|
|
'hierarchical' => 1, |
1626
|
|
|
'taxonomy' => 'product_cat', |
1627
|
|
|
'pad_counts' => 1 |
1628
|
|
|
) ) ); |
1629
|
|
|
|
1630
|
|
|
if ( ! apply_filters( 'woocommerce_product_subcategories_hide_empty', false ) ) { |
1631
|
|
|
$product_categories = wp_list_filter( $product_categories, array( 'count' => 0 ), 'NOT' ); |
1632
|
|
|
} |
1633
|
|
|
|
1634
|
|
|
if ( $product_categories ) { |
1635
|
|
|
echo $before; |
1636
|
|
|
|
1637
|
|
|
foreach ( $product_categories as $category ) { |
1638
|
|
|
wc_get_template( 'content-product_cat.php', array( |
1639
|
|
|
'category' => $category |
1640
|
|
|
) ); |
1641
|
|
|
} |
1642
|
|
|
|
1643
|
|
|
// If we are hiding products disable the loop and pagination |
1644
|
|
|
if ( is_product_category() ) { |
1645
|
|
|
$display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true ); |
1646
|
|
|
|
1647
|
|
|
switch ( $display_type ) { |
1648
|
|
|
case 'subcategories' : |
1649
|
|
|
$wp_query->post_count = 0; |
1650
|
|
|
$wp_query->max_num_pages = 0; |
1651
|
|
|
break; |
1652
|
|
|
case '' : |
1653
|
|
|
if ( 'subcategories' === get_option( 'woocommerce_category_archive_display' ) ) { |
1654
|
|
|
$wp_query->post_count = 0; |
1655
|
|
|
$wp_query->max_num_pages = 0; |
1656
|
|
|
} |
1657
|
|
|
break; |
1658
|
|
|
} |
1659
|
|
|
} |
1660
|
|
|
|
1661
|
|
|
if ( is_shop() && 'subcategories' === get_option( 'woocommerce_shop_page_display' ) ) { |
1662
|
|
|
$wp_query->post_count = 0; |
1663
|
|
|
$wp_query->max_num_pages = 0; |
1664
|
|
|
} |
1665
|
|
|
|
1666
|
|
|
echo $after; |
1667
|
|
|
|
1668
|
|
|
return true; |
1669
|
|
|
} |
1670
|
|
|
} |
1671
|
|
|
} |
1672
|
|
|
|
1673
|
|
|
if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) { |
1674
|
|
|
|
1675
|
|
|
/** |
1676
|
|
|
* Show subcategory thumbnails. |
1677
|
|
|
* |
1678
|
|
|
* @param mixed $category |
1679
|
|
|
* @subpackage Loop |
1680
|
|
|
*/ |
1681
|
|
|
function woocommerce_subcategory_thumbnail( $category ) { |
1682
|
|
|
$small_thumbnail_size = apply_filters( 'subcategory_archive_thumbnail_size', 'shop_catalog' ); |
1683
|
|
|
$dimensions = wc_get_image_size( $small_thumbnail_size ); |
1684
|
|
|
$thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true ); |
1685
|
|
|
|
1686
|
|
|
if ( $thumbnail_id ) { |
1687
|
|
|
$image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size ); |
1688
|
|
|
$image = $image[0]; |
1689
|
|
|
} else { |
1690
|
|
|
$image = wc_placeholder_img_src(); |
1691
|
|
|
} |
1692
|
|
|
|
1693
|
|
|
if ( $image ) { |
1694
|
|
|
// Prevent esc_url from breaking spaces in urls for image embeds |
1695
|
|
|
// Ref: https://core.trac.wordpress.org/ticket/23605 |
1696
|
|
|
$image = str_replace( ' ', '%20', $image ); |
1697
|
|
|
|
1698
|
|
|
echo '<img src="' . esc_url( $image ) . '" alt="' . esc_attr( $category->name ) . '" width="' . esc_attr( $dimensions['width'] ) . '" height="' . esc_attr( $dimensions['height'] ) . '" />'; |
1699
|
|
|
} |
1700
|
|
|
} |
1701
|
|
|
} |
1702
|
|
|
|
1703
|
|
|
if ( ! function_exists( 'woocommerce_order_details_table' ) ) { |
1704
|
|
|
|
1705
|
|
|
/** |
1706
|
|
|
* Displays order details in a table. |
1707
|
|
|
* |
1708
|
|
|
* @param mixed $order_id |
1709
|
|
|
* @subpackage Orders |
1710
|
|
|
*/ |
1711
|
|
|
function woocommerce_order_details_table( $order_id ) { |
1712
|
|
|
if ( ! $order_id ) return; |
1713
|
|
|
|
1714
|
|
|
wc_get_template( 'order/order-details.php', array( |
1715
|
|
|
'order_id' => $order_id |
1716
|
|
|
) ); |
1717
|
|
|
} |
1718
|
|
|
} |
1719
|
|
|
|
1720
|
|
|
|
1721
|
|
|
if ( ! function_exists( 'woocommerce_order_again_button' ) ) { |
1722
|
|
|
|
1723
|
|
|
/** |
1724
|
|
|
* Display an 'order again' button on the view order page. |
1725
|
|
|
* |
1726
|
|
|
* @param object $order |
1727
|
|
|
* @subpackage Orders |
1728
|
|
|
*/ |
1729
|
|
|
function woocommerce_order_again_button( $order ) { |
1730
|
|
|
if ( ! $order || ! $order->has_status( 'completed' ) || ! is_user_logged_in() ) { |
1731
|
|
|
return; |
1732
|
|
|
} |
1733
|
|
|
|
1734
|
|
|
wc_get_template( 'order/order-again.php', array( |
1735
|
|
|
'order' => $order |
1736
|
|
|
) ); |
1737
|
|
|
} |
1738
|
|
|
} |
1739
|
|
|
|
1740
|
|
|
/** Forms ****************************************************************/ |
1741
|
|
|
|
1742
|
|
|
if ( ! function_exists( 'woocommerce_form_field' ) ) { |
1743
|
|
|
|
1744
|
|
|
/** |
1745
|
|
|
* Outputs a checkout/address form field. |
1746
|
|
|
* |
1747
|
|
|
* @subpackage Forms |
1748
|
|
|
* @param string $key |
1749
|
|
|
* @param mixed $args |
1750
|
|
|
* @param string $value (default: null) |
1751
|
|
|
* @todo This function needs to be broken up in smaller pieces |
1752
|
|
|
*/ |
1753
|
|
|
function woocommerce_form_field( $key, $args, $value = null ) { |
1754
|
|
|
$defaults = array( |
1755
|
|
|
'type' => 'text', |
1756
|
|
|
'label' => '', |
1757
|
|
|
'description' => '', |
1758
|
|
|
'placeholder' => '', |
1759
|
|
|
'maxlength' => false, |
1760
|
|
|
'required' => false, |
1761
|
|
|
'autocomplete' => false, |
1762
|
|
|
'id' => $key, |
1763
|
|
|
'class' => array(), |
1764
|
|
|
'label_class' => array(), |
1765
|
|
|
'input_class' => array(), |
1766
|
|
|
'return' => false, |
1767
|
|
|
'options' => array(), |
1768
|
|
|
'custom_attributes' => array(), |
1769
|
|
|
'validate' => array(), |
1770
|
|
|
'default' => '', |
1771
|
|
|
); |
1772
|
|
|
|
1773
|
|
|
$args = wp_parse_args( $args, $defaults ); |
1774
|
|
|
$args = apply_filters( 'woocommerce_form_field_args', $args, $key, $value ); |
1775
|
|
|
|
1776
|
|
|
if ( $args['required'] ) { |
1777
|
|
|
$args['class'][] = 'validate-required'; |
1778
|
|
|
$required = ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce' ) . '">*</abbr>'; |
1779
|
|
|
} else { |
1780
|
|
|
$required = ''; |
1781
|
|
|
} |
1782
|
|
|
|
1783
|
|
|
$args['maxlength'] = ( $args['maxlength'] ) ? 'maxlength="' . absint( $args['maxlength'] ) . '"' : ''; |
1784
|
|
|
|
1785
|
|
|
$args['autocomplete'] = ( $args['autocomplete'] ) ? 'autocomplete="' . esc_attr( $args['autocomplete'] ) . '"' : ''; |
1786
|
|
|
|
1787
|
|
|
if ( is_string( $args['label_class'] ) ) { |
1788
|
|
|
$args['label_class'] = array( $args['label_class'] ); |
1789
|
|
|
} |
1790
|
|
|
|
1791
|
|
|
if ( is_null( $value ) ) { |
1792
|
|
|
$value = $args['default']; |
1793
|
|
|
} |
1794
|
|
|
|
1795
|
|
|
// Custom attribute handling |
1796
|
|
|
$custom_attributes = array(); |
1797
|
|
|
|
1798
|
|
View Code Duplication |
if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) ) { |
|
|
|
|
1799
|
|
|
foreach ( $args['custom_attributes'] as $attribute => $attribute_value ) { |
1800
|
|
|
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"'; |
1801
|
|
|
} |
1802
|
|
|
} |
1803
|
|
|
|
1804
|
|
|
if ( ! empty( $args['validate'] ) ) { |
1805
|
|
|
foreach( $args['validate'] as $validate ) { |
|
|
|
|
1806
|
|
|
$args['class'][] = 'validate-' . $validate; |
1807
|
|
|
} |
1808
|
|
|
} |
1809
|
|
|
|
1810
|
|
|
$field = ''; |
1811
|
|
|
$label_id = $args['id']; |
1812
|
|
|
$field_container = '<p class="form-row %1$s" id="%2$s">%3$s</p>'; |
1813
|
|
|
|
1814
|
|
|
switch ( $args['type'] ) { |
1815
|
|
|
case 'country' : |
1816
|
|
|
|
1817
|
|
|
$countries = 'shipping_country' === $key ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries(); |
1818
|
|
|
|
1819
|
|
|
if ( 1 === sizeof( $countries ) ) { |
1820
|
|
|
|
1821
|
|
|
$field .= '<strong>' . current( array_values( $countries ) ) . '</strong>'; |
1822
|
|
|
|
1823
|
|
|
$field .= '<input type="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . current( array_keys($countries ) ) . '" ' . implode( ' ', $custom_attributes ) . ' class="country_to_state" />'; |
1824
|
|
|
|
1825
|
|
|
} else { |
1826
|
|
|
|
1827
|
|
|
$field = '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" ' . $args['autocomplete'] . ' class="country_to_state country_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" ' . implode( ' ', $custom_attributes ) . '>' |
1828
|
|
|
. '<option value="">'.__( 'Select a country…', 'woocommerce' ) .'</option>'; |
1829
|
|
|
|
1830
|
|
View Code Duplication |
foreach ( $countries as $ckey => $cvalue ) { |
|
|
|
|
1831
|
|
|
$field .= '<option value="' . esc_attr( $ckey ) . '" '. selected( $value, $ckey, false ) . '>'. __( $cvalue, 'woocommerce' ) .'</option>'; |
1832
|
|
|
} |
1833
|
|
|
|
1834
|
|
|
$field .= '</select>'; |
1835
|
|
|
|
1836
|
|
|
$field .= '<noscript><input type="submit" name="woocommerce_checkout_update_totals" value="' . esc_attr__( 'Update country', 'woocommerce' ) . '" /></noscript>'; |
1837
|
|
|
|
1838
|
|
|
} |
1839
|
|
|
|
1840
|
|
|
break; |
1841
|
|
|
case 'state' : |
1842
|
|
|
|
1843
|
|
|
/* Get Country */ |
1844
|
|
|
$country_key = 'billing_state' === $key ? 'billing_country' : 'shipping_country'; |
1845
|
|
|
$current_cc = WC()->checkout->get_value( $country_key ); |
1846
|
|
|
$states = WC()->countries->get_states( $current_cc ); |
1847
|
|
|
|
1848
|
|
|
if ( is_array( $states ) && empty( $states ) ) { |
1849
|
|
|
|
1850
|
|
|
$field_container = '<p class="form-row %1$s" id="%2$s" style="display: none">%3$s</p>'; |
1851
|
|
|
|
1852
|
|
|
$field .= '<input type="hidden" class="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="" ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '" />'; |
1853
|
|
|
|
1854
|
|
|
} elseif ( is_array( $states ) ) { |
1855
|
|
|
|
1856
|
|
|
$field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="state_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" ' . implode( ' ', $custom_attributes ) . ' data-placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . $args['autocomplete'] . '> |
1857
|
|
|
<option value="">'.__( 'Select a state…', 'woocommerce' ) .'</option>'; |
1858
|
|
|
|
1859
|
|
View Code Duplication |
foreach ( $states as $ckey => $cvalue ) { |
|
|
|
|
1860
|
|
|
$field .= '<option value="' . esc_attr( $ckey ) . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>'; |
1861
|
|
|
} |
1862
|
|
|
|
1863
|
|
|
$field .= '</select>'; |
1864
|
|
|
|
1865
|
|
|
} else { |
1866
|
|
|
|
1867
|
|
|
$field .= '<input type="text" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" value="' . esc_attr( $value ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . $args['autocomplete'] . ' name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" ' . implode( ' ', $custom_attributes ) . ' />'; |
1868
|
|
|
|
1869
|
|
|
} |
1870
|
|
|
|
1871
|
|
|
break; |
1872
|
|
|
case 'textarea' : |
1873
|
|
|
|
1874
|
|
|
$field .= '<textarea name="' . esc_attr( $key ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . $args['maxlength'] . ' ' . $args['autocomplete'] . ' ' . ( empty( $args['custom_attributes']['rows'] ) ? ' rows="2"' : '' ) . ( empty( $args['custom_attributes']['cols'] ) ? ' cols="5"' : '' ) . implode( ' ', $custom_attributes ) . '>'. esc_textarea( $value ) .'</textarea>'; |
1875
|
|
|
|
1876
|
|
|
break; |
1877
|
|
View Code Duplication |
case 'checkbox' : |
|
|
|
|
1878
|
|
|
|
1879
|
|
|
$field = '<label class="checkbox ' . implode( ' ', $args['label_class'] ) .'" ' . implode( ' ', $custom_attributes ) . '> |
1880
|
|
|
<input type="' . esc_attr( $args['type'] ) . '" class="input-checkbox ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="1" '.checked( $value, 1, false ) .' /> ' |
1881
|
|
|
. $args['label'] . $required . '</label>'; |
1882
|
|
|
|
1883
|
|
|
break; |
1884
|
|
|
case 'password' : |
1885
|
|
|
case 'text' : |
1886
|
|
|
case 'email' : |
1887
|
|
|
case 'tel' : |
1888
|
|
View Code Duplication |
case 'number' : |
|
|
|
|
1889
|
|
|
|
1890
|
|
|
$field .= '<input type="' . esc_attr( $args['type'] ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . $args['maxlength'] . ' ' . $args['autocomplete'] . ' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />'; |
1891
|
|
|
|
1892
|
|
|
break; |
1893
|
|
|
case 'select' : |
1894
|
|
|
|
1895
|
|
|
$options = $field = ''; |
1896
|
|
|
|
1897
|
|
|
if ( ! empty( $args['options'] ) ) { |
1898
|
|
|
foreach ( $args['options'] as $option_key => $option_text ) { |
1899
|
|
|
if ( '' === $option_key ) { |
1900
|
|
|
// If we have a blank option, select2 needs a placeholder |
1901
|
|
|
if ( empty( $args['placeholder'] ) ) { |
1902
|
|
|
$args['placeholder'] = $option_text ? $option_text : __( 'Choose an option', 'woocommerce' ); |
1903
|
|
|
} |
1904
|
|
|
$custom_attributes[] = 'data-allow_clear="true"'; |
1905
|
|
|
} |
1906
|
|
|
$options .= '<option value="' . esc_attr( $option_key ) . '" '. selected( $value, $option_key, false ) . '>' . esc_attr( $option_text ) .'</option>'; |
1907
|
|
|
} |
1908
|
|
|
|
1909
|
|
|
$field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="select '. esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . ' data-placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . $args['autocomplete'] . '> |
1910
|
|
|
' . $options . ' |
1911
|
|
|
</select>'; |
1912
|
|
|
} |
1913
|
|
|
|
1914
|
|
|
break; |
1915
|
|
|
case 'radio' : |
1916
|
|
|
|
1917
|
|
|
$label_id = current( array_keys( $args['options'] ) ); |
1918
|
|
|
|
1919
|
|
|
if ( ! empty( $args['options'] ) ) { |
1920
|
|
|
foreach ( $args['options'] as $option_key => $option_text ) { |
|
|
|
|
1921
|
|
|
$field .= '<input type="radio" class="input-radio ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" value="' . esc_attr( $option_key ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '"' . checked( $value, $option_key, false ) . ' />'; |
1922
|
|
|
$field .= '<label for="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '" class="radio ' . implode( ' ', $args['label_class'] ) .'">' . $option_text . '</label>'; |
1923
|
|
|
} |
1924
|
|
|
} |
1925
|
|
|
|
1926
|
|
|
break; |
1927
|
|
|
} |
1928
|
|
|
|
1929
|
|
|
if ( ! empty( $field ) ) { |
1930
|
|
|
$field_html = ''; |
1931
|
|
|
|
1932
|
|
|
if ( $args['label'] && 'checkbox' != $args['type'] ) { |
1933
|
|
|
$field_html .= '<label for="' . esc_attr( $label_id ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) .'">' . $args['label'] . $required . '</label>'; |
1934
|
|
|
} |
1935
|
|
|
|
1936
|
|
|
$field_html .= $field; |
1937
|
|
|
|
1938
|
|
|
if ( $args['description'] ) { |
1939
|
|
|
$field_html .= '<span class="description">' . esc_html( $args['description'] ) . '</span>'; |
1940
|
|
|
} |
1941
|
|
|
|
1942
|
|
|
$container_class = 'form-row ' . esc_attr( implode( ' ', $args['class'] ) ); |
1943
|
|
|
$container_id = esc_attr( $args['id'] ) . '_field'; |
1944
|
|
|
|
1945
|
|
|
$after = ! empty( $args['clear'] ) ? '<div class="clear"></div>' : ''; |
1946
|
|
|
|
1947
|
|
|
$field = sprintf( $field_container, $container_class, $container_id, $field_html ) . $after; |
1948
|
|
|
} |
1949
|
|
|
|
1950
|
|
|
$field = apply_filters( 'woocommerce_form_field_' . $args['type'], $field, $key, $args, $value ); |
1951
|
|
|
|
1952
|
|
|
if ( $args['return'] ) { |
1953
|
|
|
return $field; |
1954
|
|
|
} else { |
1955
|
|
|
echo $field; |
1956
|
|
|
} |
1957
|
|
|
} |
1958
|
|
|
} |
1959
|
|
|
|
1960
|
|
|
if ( ! function_exists( 'get_product_search_form' ) ) { |
1961
|
|
|
|
1962
|
|
|
/** |
1963
|
|
|
* Display product search form. |
1964
|
|
|
* |
1965
|
|
|
* Will first attempt to locate the product-searchform.php file in either the child or. |
1966
|
|
|
* the parent, then load it. If it doesn't exist, then the default search form. |
1967
|
|
|
* will be displayed. |
1968
|
|
|
* |
1969
|
|
|
* The default searchform uses html5. |
1970
|
|
|
* |
1971
|
|
|
* @subpackage Forms |
1972
|
|
|
* @param bool $echo (default: true) |
1973
|
|
|
* @return string |
1974
|
|
|
*/ |
1975
|
|
|
function get_product_search_form( $echo = true ) { |
1976
|
|
|
ob_start(); |
1977
|
|
|
|
1978
|
|
|
do_action( 'pre_get_product_search_form' ); |
1979
|
|
|
|
1980
|
|
|
wc_get_template( 'product-searchform.php' ); |
1981
|
|
|
|
1982
|
|
|
$form = apply_filters( 'get_product_search_form', ob_get_clean() ); |
1983
|
|
|
|
1984
|
|
|
if ( $echo ) { |
1985
|
|
|
echo $form; |
1986
|
|
|
} else { |
1987
|
|
|
return $form; |
1988
|
|
|
} |
1989
|
|
|
} |
1990
|
|
|
} |
1991
|
|
|
|
1992
|
|
|
if ( ! function_exists( 'woocommerce_output_auth_header' ) ) { |
1993
|
|
|
|
1994
|
|
|
/** |
1995
|
|
|
* Output the Auth header. |
1996
|
|
|
*/ |
1997
|
|
|
function woocommerce_output_auth_header() { |
1998
|
|
|
wc_get_template( 'auth/header.php' ); |
1999
|
|
|
} |
2000
|
|
|
} |
2001
|
|
|
|
2002
|
|
|
if ( ! function_exists( 'woocommerce_output_auth_footer' ) ) { |
2003
|
|
|
|
2004
|
|
|
/** |
2005
|
|
|
* Output the Auth footer. |
2006
|
|
|
*/ |
2007
|
|
|
function woocommerce_output_auth_footer() { |
2008
|
|
|
wc_get_template( 'auth/footer.php' ); |
2009
|
|
|
} |
2010
|
|
|
} |
2011
|
|
|
|
2012
|
|
|
if ( ! function_exists( 'woocommerce_single_variation' ) ) { |
2013
|
|
|
|
2014
|
|
|
/** |
2015
|
|
|
* Output placeholders for the single variation. |
2016
|
|
|
*/ |
2017
|
|
|
function woocommerce_single_variation() { |
2018
|
|
|
echo '<div class="woocommerce-variation single_variation"></div>'; |
2019
|
|
|
} |
2020
|
|
|
} |
2021
|
|
|
|
2022
|
|
|
if ( ! function_exists( 'woocommerce_single_variation_add_to_cart_button' ) ) { |
2023
|
|
|
|
2024
|
|
|
/** |
2025
|
|
|
* Output the add to cart button for variations. |
2026
|
|
|
*/ |
2027
|
|
|
function woocommerce_single_variation_add_to_cart_button() { |
2028
|
|
|
wc_get_template( 'single-product/add-to-cart/variation-add-to-cart-button.php' ); |
2029
|
|
|
} |
2030
|
|
|
} |
2031
|
|
|
|
2032
|
|
|
if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) { |
2033
|
|
|
|
2034
|
|
|
/** |
2035
|
|
|
* Output a list of variation attributes for use in the cart forms. |
2036
|
|
|
* |
2037
|
|
|
* @param array $args |
2038
|
|
|
* @since 2.4.0 |
2039
|
|
|
*/ |
2040
|
|
|
function wc_dropdown_variation_attribute_options( $args = array() ) { |
2041
|
|
|
$args = wp_parse_args( apply_filters( 'woocommerce_dropdown_variation_attribute_options_args', $args ), array( |
2042
|
|
|
'options' => false, |
2043
|
|
|
'attribute' => false, |
2044
|
|
|
'product' => false, |
2045
|
|
|
'selected' => false, |
2046
|
|
|
'name' => '', |
2047
|
|
|
'id' => '', |
2048
|
|
|
'class' => '', |
2049
|
|
|
'show_option_none' => __( 'Choose an option', 'woocommerce' ) |
2050
|
|
|
) ); |
2051
|
|
|
|
2052
|
|
|
$options = $args['options']; |
2053
|
|
|
$product = $args['product']; |
2054
|
|
|
$attribute = $args['attribute']; |
2055
|
|
|
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute ); |
2056
|
|
|
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute ); |
2057
|
|
|
$class = $args['class']; |
2058
|
|
|
|
2059
|
|
|
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) { |
2060
|
|
|
$attributes = $product->get_variation_attributes(); |
2061
|
|
|
$options = $attributes[ $attribute ]; |
2062
|
|
|
} |
2063
|
|
|
|
2064
|
|
|
$html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '">'; |
2065
|
|
|
|
2066
|
|
|
if ( $args['show_option_none'] ) { |
2067
|
|
|
$html .= '<option value="">' . esc_html( $args['show_option_none'] ) . '</option>'; |
2068
|
|
|
} |
2069
|
|
|
|
2070
|
|
|
if ( ! empty( $options ) ) { |
2071
|
|
|
if ( $product && taxonomy_exists( $attribute ) ) { |
2072
|
|
|
// Get terms if this is a taxonomy - ordered. We need the names too. |
2073
|
|
|
$terms = wc_get_product_terms( $product->id, $attribute, array( 'fields' => 'all' ) ); |
2074
|
|
|
|
2075
|
|
View Code Duplication |
foreach ( $terms as $term ) { |
|
|
|
|
2076
|
|
|
if ( in_array( $term->slug, $options ) ) { |
2077
|
|
|
$html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . '</option>'; |
2078
|
|
|
} |
2079
|
|
|
} |
2080
|
|
|
} else { |
2081
|
|
|
foreach ( $options as $option ) { |
2082
|
|
|
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized. |
2083
|
|
|
$selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false ); |
2084
|
|
|
$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>'; |
2085
|
|
|
} |
2086
|
|
|
} |
2087
|
|
|
} |
2088
|
|
|
|
2089
|
|
|
$html .= '</select>'; |
2090
|
|
|
|
2091
|
|
|
echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args ); |
2092
|
|
|
} |
2093
|
|
|
} |
2094
|
|
|
|
2095
|
|
|
if ( ! function_exists( 'woocommerce_account_content' ) ) { |
2096
|
|
|
|
2097
|
|
|
/** |
2098
|
|
|
* My Account content output. |
2099
|
|
|
*/ |
2100
|
|
|
function woocommerce_account_content() { |
2101
|
|
|
global $wp; |
2102
|
|
|
|
2103
|
|
View Code Duplication |
foreach ( $wp->query_vars as $key => $value ) { |
|
|
|
|
2104
|
|
|
// Ignore pagename param. |
2105
|
|
|
if ( 'pagename' === $key ) { |
2106
|
|
|
continue; |
2107
|
|
|
} |
2108
|
|
|
|
2109
|
|
|
if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) { |
2110
|
|
|
do_action( 'woocommerce_account_' . $key . '_endpoint', $value ); |
2111
|
|
|
return; |
2112
|
|
|
} |
2113
|
|
|
} |
2114
|
|
|
|
2115
|
|
|
// No endpoint found? Default to dashboard. |
2116
|
|
|
wc_get_template( 'myaccount/dashboard.php', array( |
2117
|
|
|
'current_user' => get_user_by( 'id', get_current_user_id() ), |
2118
|
|
|
) ); |
2119
|
|
|
} |
2120
|
|
|
} |
2121
|
|
|
|
2122
|
|
|
if ( ! function_exists( 'woocommerce_account_navigation' ) ) { |
2123
|
|
|
|
2124
|
|
|
/** |
2125
|
|
|
* My Account navigation template. |
2126
|
|
|
*/ |
2127
|
|
|
function woocommerce_account_navigation() { |
2128
|
|
|
wc_get_template( 'myaccount/navigation.php' ); |
2129
|
|
|
} |
2130
|
|
|
} |
2131
|
|
|
|
2132
|
|
|
if ( ! function_exists( 'woocommerce_account_orders' ) ) { |
2133
|
|
|
|
2134
|
|
|
/** |
2135
|
|
|
* My Account > Orders template. |
2136
|
|
|
* |
2137
|
|
|
* @param int $current_page Current page number. |
2138
|
|
|
*/ |
2139
|
|
|
function woocommerce_account_orders( $current_page ) { |
2140
|
|
|
$current_page = empty( $current_page ) ? 1 : absint( $current_page ); |
2141
|
|
|
$customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array( 'customer' => get_current_user_id(), 'page' => $current_page, 'paginate' => true ) ) ); |
2142
|
|
|
|
2143
|
|
|
wc_get_template( |
2144
|
|
|
'myaccount/orders.php', |
2145
|
|
|
array( |
2146
|
|
|
'current_page' => absint( $current_page ), |
2147
|
|
|
'customer_orders' => $customer_orders, |
2148
|
|
|
'has_orders' => 0 < $customer_orders->total, |
2149
|
|
|
) |
2150
|
|
|
); |
2151
|
|
|
} |
2152
|
|
|
} |
2153
|
|
|
|
2154
|
|
|
if ( ! function_exists( 'woocommerce_account_view_order' ) ) { |
2155
|
|
|
|
2156
|
|
|
/** |
2157
|
|
|
* My Account > View order template. |
2158
|
|
|
* |
2159
|
|
|
* @param int $order_id Order ID. |
2160
|
|
|
*/ |
2161
|
|
|
function woocommerce_account_view_order( $order_id ) { |
2162
|
|
|
WC_Shortcode_My_Account::view_order( absint( $order_id ) ); |
2163
|
|
|
} |
2164
|
|
|
} |
2165
|
|
|
|
2166
|
|
|
if ( ! function_exists( 'woocommerce_account_downloads' ) ) { |
2167
|
|
|
|
2168
|
|
|
/** |
2169
|
|
|
* My Account > Downloads template. |
2170
|
|
|
*/ |
2171
|
|
|
function woocommerce_account_downloads() { |
2172
|
|
|
wc_get_template( 'myaccount/downloads.php' ); |
2173
|
|
|
} |
2174
|
|
|
} |
2175
|
|
|
|
2176
|
|
|
if ( ! function_exists( 'woocommerce_account_edit_address' ) ) { |
2177
|
|
|
|
2178
|
|
|
/** |
2179
|
|
|
* My Account > Edit address template. |
2180
|
|
|
* |
2181
|
|
|
* @param string $type Address type. |
2182
|
|
|
*/ |
2183
|
|
|
function woocommerce_account_edit_address( $type ) { |
2184
|
|
|
$type = wc_edit_address_i18n( sanitize_title( $type ), true ); |
2185
|
|
|
|
2186
|
|
|
WC_Shortcode_My_Account::edit_address( $type ); |
2187
|
|
|
} |
2188
|
|
|
} |
2189
|
|
|
|
2190
|
|
|
if ( ! function_exists( 'woocommerce_account_payment_methods' ) ) { |
2191
|
|
|
|
2192
|
|
|
/** |
2193
|
|
|
* My Account > Downloads template. |
2194
|
|
|
*/ |
2195
|
|
|
function woocommerce_account_payment_methods() { |
2196
|
|
|
wc_get_template( 'myaccount/payment-methods.php' ); |
2197
|
|
|
} |
2198
|
|
|
} |
2199
|
|
|
|
2200
|
|
|
if ( ! function_exists( 'woocommerce_account_add_payment_method' ) ) { |
2201
|
|
|
|
2202
|
|
|
/** |
2203
|
|
|
* My Account > Add payment method template. |
2204
|
|
|
*/ |
2205
|
|
|
function woocommerce_account_add_payment_method() { |
2206
|
|
|
WC_Shortcode_My_Account::add_payment_method(); |
2207
|
|
|
} |
2208
|
|
|
} |
2209
|
|
|
|
2210
|
|
|
if ( ! function_exists( 'woocommerce_account_edit_account' ) ) { |
2211
|
|
|
|
2212
|
|
|
/** |
2213
|
|
|
* My Account > Edit account template. |
2214
|
|
|
*/ |
2215
|
|
|
function woocommerce_account_edit_account() { |
2216
|
|
|
WC_Shortcode_My_Account::edit_account(); |
2217
|
|
|
} |
2218
|
|
|
} |
2219
|
|
|
|
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.