PageRenderTime 88ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/woocommerce-template.php

https://github.com/CammoKing/woocommerce
PHP | 1435 lines | 699 code | 258 blank | 478 comment | 162 complexity | c666c9d87699c061b0f9ca585073065a MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * WooCommerce Template Functions
  4. *
  5. * Functions used in the template files to output content - in most cases hooked in via the template actions. All functions are pluggable.
  6. *
  7. * @author WooThemes
  8. * @category Core
  9. * @package WooCommerce/Templates
  10. * @version 1.6.4
  11. */
  12. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  13. /** Template pages ********************************************************/
  14. if ( ! function_exists( 'woocommerce_content' ) ) {
  15. /**
  16. * Output WooCommerce content.
  17. *
  18. * This function is only used in the optional 'woocommerce.php' template
  19. * which people can add to their themes to add basic woocommerce support
  20. * without using hooks or modifying core templates.
  21. *
  22. * @access public
  23. * @return void
  24. */
  25. function woocommerce_content() {
  26. if ( is_singular( 'product' ) ) {
  27. while ( have_posts() ) : the_post();
  28. woocommerce_get_template_part( 'content', 'single-product' );
  29. endwhile;
  30. } else {
  31. ?><h1 class="page-title"><?php woocommerce_page_title(); ?></h1>
  32. <?php do_action( 'woocommerce_archive_description' ); ?>
  33. <?php if ( is_tax() ) : ?>
  34. <?php do_action( 'woocommerce_taxonomy_archive_description' ); ?>
  35. <?php elseif ( ! empty( $shop_page ) && is_object( $shop_page ) ) : ?>
  36. <?php do_action( 'woocommerce_product_archive_description', $shop_page ); ?>
  37. <?php endif; ?>
  38. <?php if ( have_posts() ) : ?>
  39. <?php do_action('woocommerce_before_shop_loop'); ?>
  40. <?php woocommerce_product_loop_start(); ?>
  41. <?php woocommerce_product_subcategories(); ?>
  42. <?php while ( have_posts() ) : the_post(); ?>
  43. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  44. <?php endwhile; // end of the loop. ?>
  45. <?php woocommerce_product_loop_end(); ?>
  46. <?php do_action('woocommerce_after_shop_loop'); ?>
  47. <?php else : ?>
  48. <?php if ( ! woocommerce_product_subcategories( array( 'before' => '<ul class="products">', 'after' => '</ul>' ) ) ) : ?>
  49. <p><?php _e( 'No products found which match your selection.', 'woocommerce' ); ?></p>
  50. <?php endif; ?>
  51. <?php endif; ?>
  52. <div class="clear"></div>
  53. <?php do_action( 'woocommerce_pagination' );
  54. }
  55. }
  56. }
  57. if ( ! function_exists( 'woocommerce_single_product_content' ) ) {
  58. /**
  59. * woocommerce_single_product_content function.
  60. *
  61. * @access public
  62. * @return void
  63. * @deprecated 1.6
  64. */
  65. function woocommerce_single_product_content() {
  66. _deprecated_function( __FUNCTION__, '1.6' );
  67. woocommerce_content();
  68. }
  69. }
  70. if ( ! function_exists( 'woocommerce_archive_product_content' ) ) {
  71. /**
  72. * woocommerce_archive_product_content function.
  73. *
  74. * @access public
  75. * @return void
  76. * @deprecated 1.6
  77. */
  78. function woocommerce_archive_product_content() {
  79. _deprecated_function( __FUNCTION__, '1.6' );
  80. woocommerce_content();
  81. }
  82. }
  83. if ( ! function_exists( 'woocommerce_product_taxonomy_content' ) ) {
  84. /**
  85. * woocommerce_product_taxonomy_content function.
  86. *
  87. * @access public
  88. * @return void
  89. * @deprecated 1.6
  90. */
  91. function woocommerce_product_taxonomy_content() {
  92. _deprecated_function( __FUNCTION__, '1.6' );
  93. woocommerce_content();
  94. }
  95. }
  96. /** Global ****************************************************************/
  97. if ( ! function_exists( 'woocommerce_output_content_wrapper' ) ) {
  98. /**
  99. * Output the start of the page wrapper.
  100. *
  101. * @access public
  102. * @return void
  103. */
  104. function woocommerce_output_content_wrapper() {
  105. woocommerce_get_template( 'shop/wrapper-start.php' );
  106. }
  107. }
  108. if ( ! function_exists( 'woocommerce_output_content_wrapper_end' ) ) {
  109. /**
  110. * Output the end of the page wrapper.
  111. *
  112. * @access public
  113. * @return void
  114. */
  115. function woocommerce_output_content_wrapper_end() {
  116. woocommerce_get_template( 'shop/wrapper-end.php' );
  117. }
  118. }
  119. if ( ! function_exists( 'woocommerce_show_messages' ) ) {
  120. /**
  121. * Show messages on the frontend.
  122. *
  123. * @access public
  124. * @return void
  125. */
  126. function woocommerce_show_messages() {
  127. global $woocommerce;
  128. if ( $woocommerce->error_count() > 0 )
  129. woocommerce_get_template( 'shop/errors.php', array(
  130. 'errors' => $woocommerce->get_errors()
  131. ) );
  132. if ( $woocommerce->message_count() > 0 )
  133. woocommerce_get_template( 'shop/messages.php', array(
  134. 'messages' => $woocommerce->get_messages()
  135. ) );
  136. $woocommerce->clear_messages();
  137. }
  138. }
  139. if ( ! function_exists( 'woocommerce_get_sidebar' ) ) {
  140. /**
  141. * Get the shop sidebar template.
  142. *
  143. * @access public
  144. * @return void
  145. */
  146. function woocommerce_get_sidebar() {
  147. woocommerce_get_template( 'shop/sidebar.php' );
  148. }
  149. }
  150. if ( ! function_exists( 'woocommerce_demo_store' ) ) {
  151. /**
  152. * Adds a demo store banner to the site if enabled
  153. *
  154. * @access public
  155. * @return void
  156. */
  157. function woocommerce_demo_store() {
  158. if ( get_option( 'woocommerce_demo_store' ) == 'no' )
  159. return;
  160. $notice = get_option( 'woocommerce_demo_store_notice' );
  161. if ( empty( $notice ) )
  162. $notice = __( 'This is a demo store for testing purposes &mdash; no orders shall be fulfilled.', 'woocommerce' );
  163. echo apply_filters( 'woocommerce_demo_store', '<p class="demo_store">' . $notice . '</p>' );
  164. }
  165. }
  166. /** Loop ******************************************************************/
  167. if ( ! function_exists( 'woocommerce_page_title' ) ) {
  168. /**
  169. * woocommerce_page_title function.
  170. *
  171. * @access public
  172. * @return void
  173. */
  174. function woocommerce_page_title() {
  175. if ( is_search() ) {
  176. $page_title = sprintf( __( 'Search Results: &ldquo;%s&rdquo;', 'woocommerce' ), get_search_query() );
  177. if ( get_query_var( 'paged' ) )
  178. $page_title .= sprintf( __( '&nbsp;&ndash; Page %s', 'woocommerce' ), get_query_var( 'paged' ) );
  179. } elseif ( is_tax() ) {
  180. $page_title = single_term_title( "", false );
  181. } else {
  182. $shop_page = get_post( woocommerce_get_page_id( 'shop' ) );
  183. $page_title = apply_filters( 'the_title', ( $shop_page_title = get_option( 'woocommerce_shop_page_title' ) ) ? $shop_page_title : $shop_page->post_title, $shop_page->ID );
  184. }
  185. echo apply_filters( 'woocommerce_page_title', $page_title );
  186. }
  187. }
  188. if ( ! function_exists( 'woocommerce_product_loop_start' ) ) {
  189. /**
  190. * Output the start of a product loop. By default this is a UL
  191. *
  192. * @access public
  193. * @return void
  194. */
  195. function woocommerce_product_loop_start( $echo = true ) {
  196. ob_start();
  197. woocommerce_get_template( 'loop/loop-start.php' );
  198. if ( $echo )
  199. echo ob_get_clean();
  200. else
  201. return ob_get_clean();
  202. }
  203. }
  204. if ( ! function_exists( 'woocommerce_product_loop_end' ) ) {
  205. /**
  206. * Output the end of a product loop. By default this is a UL
  207. *
  208. * @access public
  209. * @return void
  210. */
  211. function woocommerce_product_loop_end( $echo = true ) {
  212. ob_start();
  213. woocommerce_get_template( 'loop/loop-end.php' );
  214. if ( $echo )
  215. echo ob_get_clean();
  216. else
  217. return ob_get_clean();
  218. }
  219. }
  220. if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) {
  221. /**
  222. * Show an archive description on taxonomy archives
  223. *
  224. * @access public
  225. * @subpackage Archives
  226. * @return void
  227. */
  228. function woocommerce_taxonomy_archive_description() {
  229. if ( is_tax( array( 'product_cat', 'product_tag' ) ) && get_query_var( 'paged' ) == 0 )
  230. echo '<div class="term-description">' . wpautop( wptexturize( term_description() ) ) . '</div>';
  231. }
  232. }
  233. if ( ! function_exists( 'woocommerce_product_archive_description' ) ) {
  234. /**
  235. * Show a shop page description on product archives
  236. *
  237. * @access public
  238. * @subpackage Archives
  239. * @return void
  240. */
  241. function woocommerce_product_archive_description( $shop_page ) {
  242. if ( get_query_var( 'paged' ) == 0 )
  243. echo '<div class="page-description">' . apply_filters( 'the_content', $shop_page->post_content ) . '</div>';
  244. }
  245. }
  246. if ( ! function_exists( 'woocommerce_template_loop_add_to_cart' ) ) {
  247. /**
  248. * Get the add to cart template for the loop.
  249. *
  250. * @access public
  251. * @subpackage Loop
  252. * @return void
  253. */
  254. function woocommerce_template_loop_add_to_cart() {
  255. woocommerce_get_template( 'loop/add-to-cart.php' );
  256. }
  257. }
  258. if ( ! function_exists( 'woocommerce_template_loop_product_thumbnail' ) ) {
  259. /**
  260. * Get the product thumbnail for the loop.
  261. *
  262. * @access public
  263. * @subpackage Loop
  264. * @return void
  265. */
  266. function woocommerce_template_loop_product_thumbnail() {
  267. echo woocommerce_get_product_thumbnail();
  268. }
  269. }
  270. if ( ! function_exists( 'woocommerce_template_loop_price' ) ) {
  271. /**
  272. * Get the product price for the loop.
  273. *
  274. * @access public
  275. * @subpackage Loop
  276. * @return void
  277. */
  278. function woocommerce_template_loop_price() {
  279. woocommerce_get_template( 'loop/price.php' );
  280. }
  281. }
  282. if ( ! function_exists( 'woocommerce_show_product_loop_sale_flash' ) ) {
  283. /**
  284. * Get the sale flash for the loop.
  285. *
  286. * @access public
  287. * @subpackage Loop
  288. * @return void
  289. */
  290. function woocommerce_show_product_loop_sale_flash() {
  291. woocommerce_get_template( 'loop/sale-flash.php' );
  292. }
  293. }
  294. if ( ! function_exists( 'woocommerce_reset_loop' ) ) {
  295. /**
  296. * Reset the loop's index and columns when we're done outputting a product loop.
  297. *
  298. * @access public
  299. * @subpackage Loop
  300. * @return void
  301. */
  302. function woocommerce_reset_loop() {
  303. global $woocommerce_loop;
  304. // Reset loop/columns globals when starting a new loop
  305. $woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
  306. }
  307. }
  308. add_filter( 'loop_end', 'woocommerce_reset_loop' );
  309. if ( ! function_exists( 'woocommerce_get_product_thumbnail' ) ) {
  310. /**
  311. * Get the product thumbnail, or the placeholder if not set.
  312. *
  313. * @access public
  314. * @subpackage Loop
  315. * @param string $size (default: 'shop_catalog')
  316. * @param int $placeholder_width (default: 0)
  317. * @param int $placeholder_height (default: 0)
  318. * @return string
  319. */
  320. function woocommerce_get_product_thumbnail( $size = 'shop_catalog', $placeholder_width = 0, $placeholder_height = 0 ) {
  321. global $post, $woocommerce;
  322. if ( ! $placeholder_width )
  323. $placeholder_width = $woocommerce->get_image_size( 'shop_catalog_image_width' );
  324. if ( ! $placeholder_height )
  325. $placeholder_height = $woocommerce->get_image_size( 'shop_catalog_image_height' );
  326. if ( has_post_thumbnail() )
  327. return get_the_post_thumbnail( $post->ID, $size );
  328. elseif ( woocommerce_placeholder_img_src() )
  329. return '<img src="'. woocommerce_placeholder_img_src() .'" alt="Placeholder" width="' . $placeholder_width . '" height="' . $placeholder_height . '" />';
  330. }
  331. }
  332. if ( ! function_exists( 'woocommerce_result_count' ) ) {
  333. /**
  334. * Output the result count text (Showing x - x of x results).
  335. *
  336. * @access public
  337. * @subpackage Loop
  338. * @return void
  339. */
  340. function woocommerce_result_count() {
  341. woocommerce_get_template( 'loop/result-count.php' );
  342. }
  343. }
  344. if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
  345. /**
  346. * Output the product sorting options.
  347. *
  348. * @access public
  349. * @subpackage Loop
  350. * @return void
  351. */
  352. function woocommerce_catalog_ordering() {
  353. global $woocommerce;
  354. if ( ! isset( $woocommerce->session->orderby ) )
  355. $woocommerce->session->orderby = apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
  356. woocommerce_get_template( 'loop/sorting.php' );
  357. }
  358. }
  359. if ( ! function_exists( 'woocommerce_pagination' ) ) {
  360. /**
  361. * Output the pagination.
  362. *
  363. * @access public
  364. * @subpackage Loop
  365. * @return void
  366. */
  367. function woocommerce_pagination() {
  368. woocommerce_get_template( 'loop/pagination.php' );
  369. }
  370. }
  371. /** Single Product ********************************************************/
  372. if ( ! function_exists( 'woocommerce_show_product_images' ) ) {
  373. /**
  374. * Output the product image before the single product summary.
  375. *
  376. * @access public
  377. * @subpackage Product
  378. * @return void
  379. */
  380. function woocommerce_show_product_images() {
  381. woocommerce_get_template( 'single-product/product-image.php' );
  382. }
  383. }
  384. if ( ! function_exists( 'woocommerce_show_product_thumbnails' ) ) {
  385. /**
  386. * Output the product thumbnails.
  387. *
  388. * @access public
  389. * @subpackage Product
  390. * @return void
  391. */
  392. function woocommerce_show_product_thumbnails() {
  393. woocommerce_get_template( 'single-product/product-thumbnails.php' );
  394. }
  395. }
  396. if ( ! function_exists( 'woocommerce_output_product_data_tabs' ) ) {
  397. /**
  398. * Output the product tabs.
  399. *
  400. * @access public
  401. * @subpackage Product/Tabs
  402. * @return void
  403. */
  404. function woocommerce_output_product_data_tabs() {
  405. woocommerce_get_template( 'single-product/tabs.php' );
  406. }
  407. }
  408. if ( ! function_exists( 'woocommerce_template_single_title' ) ) {
  409. /**
  410. * Output the product title.
  411. *
  412. * @access public
  413. * @subpackage Product
  414. * @return void
  415. */
  416. function woocommerce_template_single_title() {
  417. woocommerce_get_template( 'single-product/title.php' );
  418. }
  419. }
  420. if ( ! function_exists( 'woocommerce_template_single_price' ) ) {
  421. /**
  422. * Output the product price.
  423. *
  424. * @access public
  425. * @subpackage Product
  426. * @return void
  427. */
  428. function woocommerce_template_single_price() {
  429. woocommerce_get_template( 'single-product/price.php' );
  430. }
  431. }
  432. if ( ! function_exists( 'woocommerce_template_single_excerpt' ) ) {
  433. /**
  434. * Output the product short description (excerpt).
  435. *
  436. * @access public
  437. * @subpackage Product
  438. * @return void
  439. */
  440. function woocommerce_template_single_excerpt() {
  441. woocommerce_get_template( 'single-product/short-description.php' );
  442. }
  443. }
  444. if ( ! function_exists( 'woocommerce_template_single_meta' ) ) {
  445. /**
  446. * Output the product meta.
  447. *
  448. * @access public
  449. * @subpackage Product
  450. * @return void
  451. */
  452. function woocommerce_template_single_meta() {
  453. woocommerce_get_template( 'single-product/meta.php' );
  454. }
  455. }
  456. if ( ! function_exists( 'woocommerce_template_single_sharing' ) ) {
  457. /**
  458. * Output the product sharing.
  459. *
  460. * @access public
  461. * @subpackage Product
  462. * @return void
  463. */
  464. function woocommerce_template_single_sharing() {
  465. woocommerce_get_template( 'single-product/share.php' );
  466. }
  467. }
  468. if ( ! function_exists( 'woocommerce_show_product_sale_flash' ) ) {
  469. /**
  470. * Output the product sale flash.
  471. *
  472. * @access public
  473. * @subpackage Product
  474. * @return void
  475. */
  476. function woocommerce_show_product_sale_flash() {
  477. woocommerce_get_template( 'single-product/sale-flash.php' );
  478. }
  479. }
  480. if ( ! function_exists( 'woocommerce_template_single_add_to_cart' ) ) {
  481. /**
  482. * Trigger the single product add to cart action.
  483. *
  484. * @access public
  485. * @subpackage Product
  486. * @return void
  487. */
  488. function woocommerce_template_single_add_to_cart() {
  489. global $product;
  490. do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' );
  491. }
  492. }
  493. if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) {
  494. /**
  495. * Output the simple product add to cart area.
  496. *
  497. * @access public
  498. * @subpackage Product
  499. * @return void
  500. */
  501. function woocommerce_simple_add_to_cart() {
  502. woocommerce_get_template( 'single-product/add-to-cart/simple.php' );
  503. }
  504. }
  505. if ( ! function_exists( 'woocommerce_grouped_add_to_cart' ) ) {
  506. /**
  507. * Output the grouped product add to cart area.
  508. *
  509. * @access public
  510. * @subpackage Product
  511. * @return void
  512. */
  513. function woocommerce_grouped_add_to_cart() {
  514. woocommerce_get_template( 'single-product/add-to-cart/grouped.php' );
  515. }
  516. }
  517. if ( ! function_exists( 'woocommerce_variable_add_to_cart' ) ) {
  518. /**
  519. * Output the variable product add to cart area.
  520. *
  521. * @access public
  522. * @subpackage Product
  523. * @return void
  524. */
  525. function woocommerce_variable_add_to_cart() {
  526. global $product;
  527. // Enqueue variation scripts
  528. wp_enqueue_script( 'wc-add-to-cart-variation' );
  529. // Load the template
  530. woocommerce_get_template( 'single-product/add-to-cart/variable.php', array(
  531. 'available_variations' => $product->get_available_variations(),
  532. 'attributes' => $product->get_variation_attributes(),
  533. 'selected_attributes' => $product->get_variation_default_attributes()
  534. ) );
  535. }
  536. }
  537. if ( ! function_exists( 'woocommerce_external_add_to_cart' ) ) {
  538. /**
  539. * Output the external product add to cart area.
  540. *
  541. * @access public
  542. * @subpackage Product
  543. * @return void
  544. */
  545. function woocommerce_external_add_to_cart() {
  546. global $product;
  547. $product_url = get_post_meta( $product->id, '_product_url', true );
  548. $button_text = get_post_meta( $product->id, '_button_text', true );
  549. if ( ! $product_url ) return;
  550. woocommerce_get_template( 'single-product/add-to-cart/external.php', array(
  551. 'product_url' => $product_url,
  552. 'button_text' => ( $button_text ) ? $button_text : __( 'Buy product', 'woocommerce' ) ,
  553. ) );
  554. }
  555. }
  556. if ( ! function_exists( 'woocommerce_quantity_input' ) ) {
  557. /**
  558. * Output the quantity input for add to cart forms.
  559. *
  560. * @access public
  561. * @subpackage Product
  562. * @return void
  563. */
  564. function woocommerce_quantity_input( $args = array() ) {
  565. global $product;
  566. $defaults = array(
  567. 'input_name' => 'quantity',
  568. 'input_value' => '1',
  569. 'max_value' => apply_filters( 'woocommerce_quantity_input_max', '', $product ),
  570. 'min_value' => apply_filters( 'woocommerce_quantity_input_min', '', $product ),
  571. 'step' => apply_filters( 'woocommerce_quantity_input_step', '1', $product )
  572. );
  573. $args = apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product );
  574. woocommerce_get_template( 'single-product/add-to-cart/quantity.php', $args );
  575. }
  576. }
  577. if ( ! function_exists( 'woocommerce_product_description_tab' ) ) {
  578. /**
  579. * Output the description tab.
  580. *
  581. * @access public
  582. * @subpackage Product/Tabs
  583. * @return void
  584. */
  585. function woocommerce_product_description_tab() {
  586. woocommerce_get_template( 'single-product/tabs/tab-description.php' );
  587. }
  588. }
  589. if ( ! function_exists( 'woocommerce_product_attributes_tab' ) ) {
  590. /**
  591. * Output the attributes tab.
  592. *
  593. * @access public
  594. * @subpackage Product/Tabs
  595. * @return void
  596. */
  597. function woocommerce_product_attributes_tab() {
  598. woocommerce_get_template( 'single-product/tabs/tab-attributes.php' );
  599. }
  600. }
  601. if ( ! function_exists( 'woocommerce_product_reviews_tab' ) ) {
  602. /**
  603. * Output the reviews tab.
  604. *
  605. * @access public
  606. * @subpackage Product/Tabs
  607. * @return void
  608. */
  609. function woocommerce_product_reviews_tab() {
  610. woocommerce_get_template( 'single-product/tabs/tab-reviews.php' );
  611. }
  612. }
  613. if ( ! function_exists( 'woocommerce_product_description_panel' ) ) {
  614. /**
  615. * Output the description tab content.
  616. *
  617. * @access public
  618. * @subpackage Product/Tabs
  619. * @return void
  620. */
  621. function woocommerce_product_description_panel() {
  622. woocommerce_get_template( 'single-product/tabs/description.php' );
  623. }
  624. }
  625. if ( ! function_exists( 'woocommerce_product_attributes_panel' ) ) {
  626. /**
  627. * Output the attributes tab content.
  628. *
  629. * @access public
  630. * @subpackage Product/Tabs
  631. * @return void
  632. */
  633. function woocommerce_product_attributes_panel() {
  634. woocommerce_get_template( 'single-product/tabs/attributes.php' );
  635. }
  636. }
  637. if ( ! function_exists( 'woocommerce_product_reviews_panel' ) ) {
  638. /**
  639. * Output the reviews tab content.
  640. *
  641. * @access public
  642. * @subpackage Product/Tabs
  643. * @return void
  644. */
  645. function woocommerce_product_reviews_panel() {
  646. woocommerce_get_template( 'single-product/tabs/reviews.php' );
  647. }
  648. }
  649. if ( ! function_exists( 'woocommerce_comments' ) ) {
  650. /**
  651. * Output the Review comments template.
  652. *
  653. * @access public
  654. * @subpackage Product
  655. * @return void
  656. */
  657. function woocommerce_comments( $comment, $args, $depth ) {
  658. $GLOBALS['comment'] = $comment;
  659. woocommerce_get_template( 'single-product/review.php' );
  660. }
  661. }
  662. if ( ! function_exists( 'woocommerce_output_related_products' ) ) {
  663. /**
  664. * Output the related products.
  665. *
  666. * @access public
  667. * @subpackage Product
  668. * @return void
  669. */
  670. function woocommerce_output_related_products() {
  671. woocommerce_related_products( 2, 2 );
  672. }
  673. }
  674. if ( ! function_exists( 'woocommerce_related_products' ) ) {
  675. /**
  676. * Output the related products.
  677. *
  678. * @access public
  679. * @param int $posts_per_page (default: 2)
  680. * @param int $columns (default: 2)
  681. * @param string $orderby (default: 'rand')
  682. * @return void
  683. */
  684. function woocommerce_related_products( $posts_per_page = 2, $columns = 2, $orderby = 'rand' ) {
  685. woocommerce_get_template( 'single-product/related.php', array(
  686. 'posts_per_page' => $posts_per_page,
  687. 'orderby' => $orderby,
  688. 'columns' => $columns
  689. ) );
  690. }
  691. }
  692. if ( ! function_exists( 'woocommerce_upsell_display' ) ) {
  693. /**
  694. * Output product up sells.
  695. *
  696. * @access public
  697. * @param int $posts_per_page (default: -1)
  698. * @param int $columns (default: 2)
  699. * @param string $orderby (default: 'rand')
  700. * @return void
  701. */
  702. function woocommerce_upsell_display( $posts_per_page = '-1', $columns = 2, $orderby = 'rand' ) {
  703. woocommerce_get_template( 'single-product/up-sells.php', array(
  704. 'posts_per_page' => $posts_per_page,
  705. 'orderby' => $orderby,
  706. 'columns' => $columns
  707. ) );
  708. }
  709. }
  710. /** Cart ******************************************************************/
  711. if ( ! function_exists( 'woocommerce_shipping_calculator' ) ) {
  712. /**
  713. * Output the cart shipping calculator.
  714. *
  715. * @access public
  716. * @subpackage Cart
  717. * @return void
  718. */
  719. function woocommerce_shipping_calculator() {
  720. woocommerce_get_template( 'cart/shipping-calculator.php' );
  721. }
  722. }
  723. if ( ! function_exists( 'woocommerce_cart_totals' ) ) {
  724. /**
  725. * Output the cart totals.
  726. *
  727. * @access public
  728. * @subpackage Cart
  729. * @return void
  730. */
  731. function woocommerce_cart_totals() {
  732. woocommerce_get_template( 'cart/totals.php' );
  733. }
  734. }
  735. if ( ! function_exists( 'woocommerce_cross_sell_display' ) ) {
  736. /**
  737. * Output the cart cross-sells.
  738. *
  739. * @access public
  740. * @subpackage Cart
  741. * @return void
  742. */
  743. function woocommerce_cross_sell_display() {
  744. woocommerce_get_template( 'cart/cross-sells.php' );
  745. }
  746. }
  747. /** Mini-Cart *************************************************************/
  748. if ( ! function_exists( 'woocommerce_mini_cart' ) ) {
  749. /**
  750. * Output the Mini-cart - used by cart widget
  751. *
  752. * @access public
  753. * @return void
  754. */
  755. function woocommerce_mini_cart( $args = array() ) {
  756. $defaults = array(
  757. 'list_class' => ''
  758. );
  759. $args = wp_parse_args( $args, $defaults );
  760. woocommerce_get_template( 'cart/mini-cart.php', $args );
  761. }
  762. }
  763. /** Login *****************************************************************/
  764. if ( ! function_exists( 'woocommerce_login_form' ) ) {
  765. /**
  766. * Output the WooCommerce Login Form
  767. *
  768. * @access public
  769. * @subpackage Forms
  770. * @return void
  771. */
  772. function woocommerce_login_form( $args = array() ) {
  773. $defaults = array(
  774. 'message' => '',
  775. 'redirect' => ''
  776. );
  777. $args = wp_parse_args( $args, $defaults );
  778. woocommerce_get_template( 'shop/form-login.php', $args );
  779. }
  780. }
  781. if ( ! function_exists( 'woocommerce_checkout_login_form' ) ) {
  782. /**
  783. * Output the WooCommerce Checkout Login Form
  784. *
  785. * @access public
  786. * @subpackage Checkout
  787. * @return void
  788. */
  789. function woocommerce_checkout_login_form() {
  790. woocommerce_get_template( 'checkout/form-login.php' );
  791. }
  792. }
  793. if ( ! function_exists( 'woocommerce_breadcrumb' ) ) {
  794. /**
  795. * Output the WooCommerce Breadcrumb
  796. *
  797. * @access public
  798. * @return void
  799. */
  800. function woocommerce_breadcrumb( $args = array() ) {
  801. $defaults = array(
  802. 'delimiter' => ' &rsaquo; ',
  803. 'wrap_before' => '<div id="breadcrumb" itemprop="breadcrumb">',
  804. 'wrap_after' => '</div>',
  805. 'before' => '',
  806. 'after' => '',
  807. 'home' => null
  808. );
  809. $args = wp_parse_args( $args, $defaults );
  810. woocommerce_get_template( 'shop/breadcrumb.php', $args );
  811. }
  812. }
  813. if ( ! function_exists( 'woocommerce_order_review' ) ) {
  814. /**
  815. * Output the Order review table for the checkout.
  816. *
  817. * @access public
  818. * @subpackage Checkout
  819. * @return void
  820. */
  821. function woocommerce_order_review() {
  822. woocommerce_get_template( 'checkout/review-order.php' );
  823. }
  824. }
  825. if ( ! function_exists( 'woocommerce_checkout_coupon_form' ) ) {
  826. /**
  827. * Output the Coupon form for the checkout.
  828. *
  829. * @access public
  830. * @subpackage Checkout
  831. * @return void
  832. */
  833. function woocommerce_checkout_coupon_form() {
  834. woocommerce_get_template( 'checkout/form-coupon.php' );
  835. }
  836. }
  837. if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
  838. /**
  839. * Check if we will be showing products or not (and not subcats only)
  840. *
  841. * @access public
  842. * @subpackage Loop
  843. * @return void
  844. */
  845. function woocommerce_products_will_display() {
  846. global $woocommerce, $wpdb;
  847. if ( ! is_product_category() && ! is_shop() )
  848. return false;
  849. if ( is_search() || is_filtered() || is_paged() )
  850. return true;
  851. if ( is_shop() && get_option( 'woocommerce_shop_page_display' ) != 'subcategories' )
  852. return true;
  853. $term = get_queried_object();
  854. if ( is_product_category() ) {
  855. switch ( get_woocommerce_term_meta( $term->term_id, 'display_type', true ) ) {
  856. case 'products' :
  857. case 'both' :
  858. return true;
  859. break;
  860. case '' :
  861. if ( get_option( 'woocommerce_category_archive_display' ) != 'subcategories' )
  862. return true;
  863. break;
  864. }
  865. }
  866. $parent_id = empty( $term->term_id ) ? 0 : $term->term_id;
  867. $has_children = $wpdb->get_col( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE parent = %d", $parent_id ) );
  868. if ( $has_children ) {
  869. // Check terms have products inside
  870. $children = array();
  871. foreach ( $has_children as $term ) {
  872. $children = array_merge( $children, get_term_children( $term, 'product_cat' ) );
  873. $children[] = $term;
  874. }
  875. $objects = get_objects_in_term( $children, 'product_cat' );
  876. if ( sizeof( $objects ) > 0 ) {
  877. return false;
  878. } else {
  879. return true;
  880. }
  881. } else {
  882. return true;
  883. }
  884. }
  885. }
  886. if ( ! function_exists( 'woocommerce_product_subcategories' ) ) {
  887. /**
  888. * Display product sub categories as thumbnails.
  889. *
  890. * @access public
  891. * @subpackage Loop
  892. * @return void
  893. */
  894. function woocommerce_product_subcategories( $args = array() ) {
  895. global $woocommerce, $wp_query;
  896. $defaults = array(
  897. 'before' => '',
  898. 'after' => '',
  899. 'force_display' => false
  900. );
  901. $args = wp_parse_args( $args, $defaults );
  902. extract( $args );
  903. // Main query only
  904. if ( ! is_main_query() && ! $force_display ) return;
  905. // Don't show when filtering, searching or when on page > 1 and ensure we're on a product archive
  906. if ( is_search() || is_filtered() || is_paged() || ( ! is_product_category() && ! is_shop() ) ) return;
  907. // Check categories are enabled
  908. if ( is_shop() && get_option( 'woocommerce_shop_page_display' ) == '' ) return;
  909. // Find the category + category parent, if applicable
  910. $term = get_queried_object();
  911. $parent_id = empty( $term->term_id ) ? 0 : $term->term_id;
  912. if ( is_product_category() ) {
  913. $display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true );
  914. switch ( $display_type ) {
  915. case 'products' :
  916. return;
  917. break;
  918. case '' :
  919. if ( get_option( 'woocommerce_category_archive_display' ) == '' )
  920. return;
  921. break;
  922. }
  923. }
  924. // NOTE: using child_of instead of parent - this is not ideal but due to a WP bug ( http://core.trac.wordpress.org/ticket/15626 ) pad_counts won't work
  925. $args = array(
  926. 'child_of' => $parent_id,
  927. 'menu_order' => 'ASC',
  928. 'hide_empty' => 1,
  929. 'hierarchical' => 1,
  930. 'taxonomy' => 'product_cat',
  931. 'pad_counts' => 1
  932. );
  933. $product_categories = get_categories( $args );
  934. $product_category_found = false;
  935. if ( $product_categories ) {
  936. foreach ( $product_categories as $category ) {
  937. if ( $category->parent != $parent_id )
  938. continue;
  939. if ( ! $product_category_found ) {
  940. // We found a category
  941. $product_category_found = true;
  942. echo esc_html( $before );
  943. }
  944. woocommerce_get_template( 'content-product_cat.php', array(
  945. 'category' => $category
  946. ) );
  947. }
  948. }
  949. // If we are hiding products disable the loop and pagination
  950. if ( $product_category_found ) {
  951. if ( is_product_category() ) {
  952. $display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true );
  953. switch ( $display_type ) {
  954. case 'subcategories' :
  955. $wp_query->post_count = 0;
  956. $wp_query->max_num_pages = 0;
  957. break;
  958. case '' :
  959. if ( get_option( 'woocommerce_category_archive_display' ) == 'subcategories' ) {
  960. $wp_query->post_count = 0;
  961. $wp_query->max_num_pages = 0;
  962. }
  963. break;
  964. }
  965. }
  966. if ( is_shop() && get_option( 'woocommerce_shop_page_display' ) == 'subcategories' ) {
  967. $wp_query->post_count = 0;
  968. $wp_query->max_num_pages = 0;
  969. }
  970. echo esc_html( $after );
  971. return true;
  972. }
  973. }
  974. }
  975. if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) {
  976. /**
  977. * Show subcategory thumbnails.
  978. *
  979. * @access public
  980. * @param mixed $category
  981. * @subpackage Loop
  982. * @return void
  983. */
  984. function woocommerce_subcategory_thumbnail( $category ) {
  985. global $woocommerce;
  986. $small_thumbnail_size = apply_filters( 'single_product_small_thumbnail_size', 'shop_catalog' );
  987. $image_width = $woocommerce->get_image_size( 'shop_catalog_image_width' );
  988. $image_height = $woocommerce->get_image_size( 'shop_catalog_image_height' );
  989. $thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true );
  990. if ( $thumbnail_id ) {
  991. $image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size );
  992. $image = $image[0];
  993. } else {
  994. $image = woocommerce_placeholder_img_src();
  995. }
  996. if ( $image )
  997. echo '<img src="' . $image . '" alt="' . $category->name . '" width="' . $image_width . '" height="' . $image_height . '" />';
  998. }
  999. }
  1000. if ( ! function_exists( 'woocommerce_order_details_table' ) ) {
  1001. /**
  1002. * Displays order details in a table.
  1003. *
  1004. * @access public
  1005. * @param mixed $order_id
  1006. * @subpackage Orders
  1007. * @return void
  1008. */
  1009. function woocommerce_order_details_table( $order_id ) {
  1010. if ( ! $order_id ) return;
  1011. woocommerce_get_template( 'order/order-details.php', array(
  1012. 'order_id' => $order_id
  1013. ) );
  1014. }
  1015. }
  1016. /** Forms ****************************************************************/
  1017. if ( ! function_exists( 'woocommerce_form_field' ) ) {
  1018. /**
  1019. * Outputs a checkout/address form field.
  1020. *
  1021. * @access public
  1022. * @subpackage Forms
  1023. * @param mixed $key
  1024. * @param mixed $args
  1025. * @param string $value (default: '')
  1026. * @return void
  1027. */
  1028. function woocommerce_form_field( $key, $args, $value = '' ) {
  1029. global $woocommerce;
  1030. $defaults = array(
  1031. 'type' => 'text',
  1032. 'label' => '',
  1033. 'placeholder' => '',
  1034. 'maxlength' => false,
  1035. 'required' => false,
  1036. 'class' => array(),
  1037. 'label_class' => array(),
  1038. 'return' => false,
  1039. 'options' => array(),
  1040. 'custom_attributes' => array()
  1041. );
  1042. $args = wp_parse_args( $args, $defaults );
  1043. if ( ( ! empty( $args['clear'] ) ) ) $after = '<div class="clear"></div>'; else $after = '';
  1044. $required = ( $args['required'] ) ? ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce' ) . '">*</abbr>' : '';
  1045. $args['maxlength'] = ( $args['maxlength'] ) ? 'maxlength="' . absint( $args['maxlength'] ) . '"' : '';
  1046. // Custom attribute handling
  1047. $custom_attributes = array();
  1048. if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) )
  1049. foreach ( $args['custom_attributes'] as $attribute => $value )
  1050. $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
  1051. switch ( $args['type'] ) {
  1052. case "country" :
  1053. if ( sizeof( $woocommerce->countries->get_allowed_countries() ) == 1 ) {
  1054. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1055. <label class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . '</label>';
  1056. $field .= '<strong>' . current( array_values( $woocommerce->countries->get_allowed_countries() ) ) . '</strong>';
  1057. $field .= '<input type="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="' . current( array_keys( $woocommerce->countries->get_allowed_countries() ) ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
  1058. $field .= '</p>' . $after;
  1059. } else {
  1060. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1061. <label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>
  1062. <select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="country_to_state country_select" ' . implode( ' ', $custom_attributes ) . '>
  1063. <option value="">'.__( 'Select a country&hellip;', 'woocommerce' ) .'</option>';
  1064. foreach ( $woocommerce->countries->get_allowed_countries() as $ckey => $cvalue )
  1065. $field .= '<option value="' . $ckey . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';
  1066. $field .= '</select>';
  1067. $field .= '<noscript><input type="submit" name="woocommerce_checkout_update_totals" value="' . __( 'Update country', 'woocommerce' ) . '" /></noscript>';
  1068. $field .= '</p>' . $after;
  1069. }
  1070. break;
  1071. case "state" :
  1072. /* Get Country */
  1073. $country_key = $key == 'billing_state'? 'billing_country' : 'shipping_country';
  1074. if ( isset( $_POST[ $country_key ] ) ) {
  1075. $current_cc = woocommerce_clean( $_POST[ $country_key ] );
  1076. } elseif ( is_user_logged_in() ) {
  1077. $current_cc = get_user_meta( get_current_user_id() , $country_key, true );
  1078. } elseif ( $country_key == 'billing_country' ) {
  1079. $current_cc = apply_filters('default_checkout_country', ($woocommerce->customer->get_country()) ? $woocommerce->customer->get_country() : $woocommerce->countries->get_base_country());
  1080. } else {
  1081. $current_cc = apply_filters('default_checkout_country', ($woocommerce->customer->get_shipping_country()) ? $woocommerce->customer->get_shipping_country() : $woocommerce->countries->get_base_country());
  1082. }
  1083. $states = $woocommerce->countries->get_states( $current_cc );
  1084. if ( is_array( $states ) && empty( $states ) ) {
  1085. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field" style="display: none">';
  1086. $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
  1087. $field .= '<input type="hidden" class="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="" ' . implode( ' ', $custom_attributes ) . ' />';
  1088. $field .= '</p>' . $after;
  1089. } elseif ( is_array( $states ) ) {
  1090. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';
  1091. $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
  1092. $field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="state_select" ' . implode( ' ', $custom_attributes ) . '>
  1093. <option value="">'.__( 'Select a state&hellip;', 'woocommerce' ) .'</option>';
  1094. foreach ( $states as $ckey => $cvalue )
  1095. $field .= '<option value="' . $ckey . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';
  1096. $field .= '</select>';
  1097. $field .= '</p>' . $after;
  1098. } else {
  1099. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';
  1100. $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
  1101. $field .= '<input type="text" class="input-text" value="' . $value . '" placeholder="' . $args['placeholder'] . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
  1102. $field .= '</p>' . $after;
  1103. }
  1104. break;
  1105. case "textarea" :
  1106. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1107. <label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>
  1108. <textarea name="' . esc_attr( $key ) . '" class="input-text" id="' . esc_attr( $key ) . '" placeholder="' . $args['placeholder'] . '" cols="5" rows="2" ' . implode( ' ', $custom_attributes ) . '>'. esc_textarea( $value ) .'</textarea>
  1109. </p>' . $after;
  1110. break;
  1111. case "checkbox" :
  1112. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1113. <input type="' . $args['type'] . '" class="input-checkbox" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="1" '.checked( $value, 1, false ) .' />
  1114. <label for="' . esc_attr( $key ) . '" class="checkbox ' . implode( ' ', $args['label_class'] ) .'" ' . implode( ' ', $custom_attributes ) . '>' . $args['label'] . $required . '</label>
  1115. </p>' . $after;
  1116. break;
  1117. case "password" :
  1118. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1119. <label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>
  1120. <input type="password" class="input-text" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" placeholder="' . $args['placeholder'] . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />
  1121. </p>' . $after;
  1122. break;
  1123. case "text" :
  1124. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1125. <label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required . '</label>
  1126. <input type="text" class="input-text" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" placeholder="' . $args['placeholder'] . '" '.$args['maxlength'].' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />
  1127. </p>' . $after;
  1128. break;
  1129. case "select" :
  1130. $options = '';
  1131. if ( ! empty( $args['options'] ) )
  1132. foreach ( $args['options'] as $option_key => $option_text )
  1133. $options .= '<option value="' . esc_attr( $option_key ) . '" '. selected( $value, $option_key, false ) . '>' . esc_attr( $option_text ) .'</option>';
  1134. $field = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
  1135. <label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>
  1136. <select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="select" ' . implode( ' ', $custom_attributes ) . '>
  1137. ' . $options . '
  1138. </select>
  1139. </p>' . $after;
  1140. break;
  1141. default :
  1142. $field = apply_filters( 'woocommerce_form_field_' . $args['type'], '', $key, $args, $value );
  1143. break;
  1144. }
  1145. if ( $args['return'] ) return $field; else echo $field;
  1146. }
  1147. }
  1148. if ( ! function_exists( 'get_product_search_form' ) ) {
  1149. /**
  1150. * Output Product search forms.
  1151. *
  1152. * @access public
  1153. * @subpackage Forms
  1154. * @param bool $echo (default: true)
  1155. * @return void
  1156. */
  1157. function get_product_search_form( $echo = true ) {
  1158. do_action( 'get_product_search_form' );
  1159. $search_form_template = locate_template( 'product-searchform.php' );
  1160. if ( '' != $search_form_template ) {
  1161. require $search_form_template;
  1162. return;
  1163. }
  1164. $form = '<form role="search" method="get" id="searchform" action="' . esc_url( home_url( '/' ) ) . '">
  1165. <div>
  1166. <label class="screen-reader-text" for="s">' . __( 'Search for:', 'woocommerce' ) . '</label>
  1167. <input type="text" value="' . get_search_query() . '" name="s" id="s" placeholder="' . __( 'Search for products', 'woocommerce' ) . '" />
  1168. <input type="submit" id="searchsubmit" value="'. esc_attr__( 'Search', 'woocommerce' ) .'" />
  1169. <input type="hidden" name="post_type" value="product" />
  1170. </div>
  1171. </form>';
  1172. if ( $echo )
  1173. echo apply_filters( 'get_product_search_form', $form );
  1174. else
  1175. return apply_filters( 'get_product_search_form', $form );
  1176. }
  1177. }