PageRenderTime 71ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/class-wc-shortcodes.php

https://github.com/alexcsandru/woocommerce
PHP | 956 lines | 538 code | 235 blank | 183 comment | 51 complexity | ec090bdfe129dea78597a6d48b6eaa6e MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * WC_Shortcodes class.
  4. *
  5. * @class WC_Shortcodes
  6. * @version 2.0.0
  7. * @package WooCommerce/Classes
  8. * @category Class
  9. * @author WooThemes
  10. */
  11. class WC_Shortcodes {
  12. public function __construct() {
  13. // Regular shortcodes
  14. add_shortcode( 'product', array( $this, 'product' ) );
  15. add_shortcode( 'product_page', array( $this, 'product_page_shortcode' ) );
  16. add_shortcode( 'product_category', array( $this, 'product_category' ) );
  17. add_shortcode( 'product_categories', array( $this, 'product_categories' ) );
  18. add_shortcode( 'add_to_cart', array( $this, 'product_add_to_cart' ) );
  19. add_shortcode( 'add_to_cart_url', array( $this, 'product_add_to_cart_url' ) );
  20. add_shortcode( 'products', array( $this, 'products' ) );
  21. add_shortcode( 'recent_products', array( $this, 'recent_products' ) );
  22. add_shortcode( 'sale_products', array( $this, 'sale_products' ) );
  23. add_shortcode( 'best_selling_products', array( $this, 'best_selling_products' ) );
  24. add_shortcode( 'top_rated_products', array( $this, 'top_rated_products' ) );
  25. add_shortcode( 'featured_products', array( $this, 'featured_products' ) );
  26. add_shortcode( 'woocommerce_messages', array( $this, 'messages_shortcode' ) );
  27. // Pages
  28. add_shortcode( 'woocommerce_cart', array( $this, 'cart' ) );
  29. add_shortcode( 'woocommerce_checkout', array( $this, 'checkout' ) );
  30. add_shortcode( 'woocommerce_order_tracking', array( $this, 'order_tracking' ) );
  31. add_shortcode( 'woocommerce_my_account', array( $this, 'my_account' ) );
  32. add_shortcode( 'woocommerce_edit_address', array( $this, 'edit_address' ) );
  33. add_shortcode( 'woocommerce_change_password', array( $this, 'change_password' ) );
  34. add_shortcode( 'woocommerce_lost_password', array( $this, 'lost_password' ) );
  35. add_shortcode( 'woocommerce_view_order', array( $this, 'view_order' ) );
  36. add_shortcode( 'woocommerce_pay', array( $this, 'pay' ) );
  37. add_shortcode( 'woocommerce_thankyou', array( $this, 'thankyou' ) );
  38. }
  39. /**
  40. * Cart page shortcode.
  41. *
  42. * @access public
  43. * @param mixed $atts
  44. * @return string
  45. */
  46. public function cart( $atts ) {
  47. global $woocommerce;
  48. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Cart', 'output' ), $atts );
  49. }
  50. /**
  51. * Checkout page shortcode.
  52. *
  53. * @access public
  54. * @param mixed $atts
  55. * @return string
  56. */
  57. public function checkout( $atts ) {
  58. global $woocommerce;
  59. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Checkout', 'output' ), $atts );
  60. }
  61. /**
  62. * Order tracking page shortcode.
  63. *
  64. * @access public
  65. * @param mixed $atts
  66. * @return string
  67. */
  68. public function order_tracking( $atts ) {
  69. global $woocommerce;
  70. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Order_Tracking', 'output' ), $atts );
  71. }
  72. /**
  73. * Cart shortcode.
  74. *
  75. * @access public
  76. * @param mixed $atts
  77. * @return string
  78. */
  79. public function my_account( $atts ) {
  80. global $woocommerce;
  81. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_My_Account', 'output' ), $atts );
  82. }
  83. /**
  84. * Edit address page shortcode.
  85. *
  86. * @access public
  87. * @param mixed $atts
  88. * @return string
  89. */
  90. public function edit_address( $atts ) {
  91. global $woocommerce;
  92. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Edit_Address', 'output' ), $atts );
  93. }
  94. /**
  95. * Change password page shortcode.
  96. *
  97. * @access public
  98. * @param mixed $atts
  99. * @return string
  100. */
  101. public function change_password( $atts ) {
  102. global $woocommerce;
  103. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Change_Password', 'output' ), $atts );
  104. }
  105. /**
  106. * Lost password page shortcode.
  107. *
  108. * @access public
  109. * @param mixed $atts
  110. * @return string
  111. */
  112. public function lost_password( $atts ) {
  113. global $woocommerce;
  114. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Lost_Password', 'output' ), $atts );
  115. }
  116. /**
  117. * View order page shortcode.
  118. *
  119. * @access public
  120. * @param mixed $atts
  121. * @return string
  122. */
  123. public function view_order( $atts ) {
  124. global $woocommerce;
  125. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_View_Order', 'output' ), $atts );
  126. }
  127. /**
  128. * Pay page shortcode.
  129. *
  130. * @access public
  131. * @param mixed $atts
  132. * @return string
  133. */
  134. public function pay( $atts ) {
  135. global $woocommerce;
  136. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Pay', 'output' ), $atts );
  137. }
  138. /**
  139. * Thankyou page shortcode.
  140. *
  141. * @access public
  142. * @param mixed $atts
  143. * @return string
  144. */
  145. public function thankyou( $atts ) {
  146. global $woocommerce;
  147. return $woocommerce->shortcode_wrapper( array( 'WC_Shortcode_Thankyou', 'output' ), $atts );
  148. }
  149. /**
  150. * List products in a category shortcode
  151. *
  152. * @access public
  153. * @param array $atts
  154. * @return string
  155. */
  156. public function product_category( $atts ){
  157. global $woocommerce, $woocommerce_loop;
  158. if ( empty( $atts ) ) return;
  159. extract( shortcode_atts( array(
  160. 'per_page' => '12',
  161. 'columns' => '4',
  162. 'orderby' => 'title',
  163. 'order' => 'desc',
  164. 'category' => ''
  165. ), $atts ) );
  166. if ( ! $category ) return;
  167. // Default ordering args
  168. $ordering_args = $woocommerce->query->get_catalog_ordering_args( $orderby, $order );
  169. $args = array(
  170. 'post_type' => 'product',
  171. 'post_status' => 'publish',
  172. 'ignore_sticky_posts' => 1,
  173. 'orderby' => $ordering_args['orderby'],
  174. 'order' => $ordering_args['order'],
  175. 'posts_per_page' => $per_page,
  176. 'meta_query' => array(
  177. array(
  178. 'key' => '_visibility',
  179. 'value' => array('catalog', 'visible'),
  180. 'compare' => 'IN'
  181. )
  182. ),
  183. 'tax_query' => array(
  184. array(
  185. 'taxonomy' => 'product_cat',
  186. 'terms' => array( esc_attr($category) ),
  187. 'field' => 'slug',
  188. 'operator' => 'IN'
  189. )
  190. )
  191. );
  192. if ( isset( $ordering_args['meta_key'] ) ) {
  193. $args['meta_key'] = $ordering_args['meta_key'];
  194. }
  195. ob_start();
  196. $products = new WP_Query( $args );
  197. $woocommerce_loop['columns'] = $columns;
  198. if ( $products->have_posts() ) : ?>
  199. <?php woocommerce_product_loop_start(); ?>
  200. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  201. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  202. <?php endwhile; // end of the loop. ?>
  203. <?php woocommerce_product_loop_end(); ?>
  204. <?php endif;
  205. wp_reset_postdata();
  206. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  207. }
  208. /**
  209. * List all (or limited) product categories
  210. *
  211. * @access public
  212. * @param array $atts
  213. * @return string
  214. */
  215. public function product_categories( $atts ) {
  216. global $woocommerce_loop;
  217. extract( shortcode_atts( array (
  218. 'number' => null,
  219. 'orderby' => 'name',
  220. 'order' => 'ASC',
  221. 'columns' => '4',
  222. 'hide_empty' => 1,
  223. 'parent' => ''
  224. ), $atts ) );
  225. if ( isset( $atts[ 'ids' ] ) ) {
  226. $ids = explode( ',', $atts[ 'ids' ] );
  227. $ids = array_map( 'trim', $ids );
  228. } else {
  229. $ids = array();
  230. }
  231. $hide_empty = ( $hide_empty == true || $hide_empty == 1 ) ? 1 : 0;
  232. // get terms and workaround WP bug with parents/pad counts
  233. $args = array(
  234. 'orderby' => $orderby,
  235. 'order' => $order,
  236. 'hide_empty' => $hide_empty,
  237. 'include' => $ids,
  238. 'pad_counts' => true,
  239. 'child_of' => $parent
  240. );
  241. $product_categories = get_terms( 'product_cat', $args );
  242. if ( $parent !== "" )
  243. $product_categories = wp_list_filter( $product_categories, array( 'parent' => $parent ) );
  244. if ( $number )
  245. $product_categories = array_slice( $product_categories, 0, $number );
  246. $woocommerce_loop['columns'] = $columns;
  247. ob_start();
  248. // Reset loop/columns globals when starting a new loop
  249. $woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
  250. if ( $product_categories ) {
  251. woocommerce_product_loop_start();
  252. foreach ( $product_categories as $category ) {
  253. woocommerce_get_template( 'content-product_cat.php', array(
  254. 'category' => $category
  255. ) );
  256. }
  257. woocommerce_product_loop_end();
  258. }
  259. woocommerce_reset_loop();
  260. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  261. }
  262. /**
  263. * Recent Products shortcode
  264. *
  265. * @access public
  266. * @param array $atts
  267. * @return string
  268. */
  269. public function recent_products( $atts ) {
  270. global $woocommerce_loop, $woocommerce;
  271. extract(shortcode_atts(array(
  272. 'per_page' => '12',
  273. 'columns' => '4',
  274. 'orderby' => 'date',
  275. 'order' => 'desc'
  276. ), $atts));
  277. $meta_query = array();
  278. $meta_query[] = $woocommerce->query->visibility_meta_query();
  279. $meta_query[] = $woocommerce->query->stock_status_meta_query();
  280. $args = array(
  281. 'post_type' => 'product',
  282. 'post_status' => 'publish',
  283. 'ignore_sticky_posts' => 1,
  284. 'posts_per_page' => $per_page,
  285. 'orderby' => $orderby,
  286. 'order' => $order,
  287. 'meta_query' => $meta_query
  288. );
  289. ob_start();
  290. $products = new WP_Query( $args );
  291. $woocommerce_loop['columns'] = $columns;
  292. if ( $products->have_posts() ) : ?>
  293. <?php woocommerce_product_loop_start(); ?>
  294. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  295. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  296. <?php endwhile; // end of the loop. ?>
  297. <?php woocommerce_product_loop_end(); ?>
  298. <?php endif;
  299. wp_reset_postdata();
  300. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  301. }
  302. /**
  303. * List multiple products shortcode
  304. *
  305. * @access public
  306. * @param array $atts
  307. * @return string
  308. */
  309. public function products( $atts ) {
  310. global $woocommerce_loop;
  311. if (empty($atts)) return;
  312. extract(shortcode_atts(array(
  313. 'columns' => '4',
  314. 'orderby' => 'title',
  315. 'order' => 'asc'
  316. ), $atts));
  317. $args = array(
  318. 'post_type' => 'product',
  319. 'post_status' => 'publish',
  320. 'ignore_sticky_posts' => 1,
  321. 'orderby' => $orderby,
  322. 'order' => $order,
  323. 'posts_per_page' => -1,
  324. 'meta_query' => array(
  325. array(
  326. 'key' => '_visibility',
  327. 'value' => array('catalog', 'visible'),
  328. 'compare' => 'IN'
  329. )
  330. )
  331. );
  332. if(isset($atts['skus'])){
  333. $skus = explode(',', $atts['skus']);
  334. $skus = array_map('trim', $skus);
  335. $args['meta_query'][] = array(
  336. 'key' => '_sku',
  337. 'value' => $skus,
  338. 'compare' => 'IN'
  339. );
  340. }
  341. if(isset($atts['ids'])){
  342. $ids = explode(',', $atts['ids']);
  343. $ids = array_map('trim', $ids);
  344. $args['post__in'] = $ids;
  345. }
  346. ob_start();
  347. $products = new WP_Query( $args );
  348. $woocommerce_loop['columns'] = $columns;
  349. if ( $products->have_posts() ) : ?>
  350. <?php woocommerce_product_loop_start(); ?>
  351. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  352. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  353. <?php endwhile; // end of the loop. ?>
  354. <?php woocommerce_product_loop_end(); ?>
  355. <?php endif;
  356. wp_reset_postdata();
  357. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  358. }
  359. /**
  360. * Display a single prodcut
  361. *
  362. * @access public
  363. * @param array $atts
  364. * @return string
  365. */
  366. public function product( $atts ) {
  367. if (empty($atts)) return;
  368. $args = array(
  369. 'post_type' => 'product',
  370. 'posts_per_page' => 1,
  371. 'no_found_rows' => 1,
  372. 'post_status' => 'publish',
  373. 'meta_query' => array(
  374. array(
  375. 'key' => '_visibility',
  376. 'value' => array('catalog', 'visible'),
  377. 'compare' => 'IN'
  378. )
  379. )
  380. );
  381. if(isset($atts['sku'])){
  382. $args['meta_query'][] = array(
  383. 'key' => '_sku',
  384. 'value' => $atts['sku'],
  385. 'compare' => '='
  386. );
  387. }
  388. if(isset($atts['id'])){
  389. $args['p'] = $atts['id'];
  390. }
  391. ob_start();
  392. $products = new WP_Query( $args );
  393. if ( $products->have_posts() ) : ?>
  394. <?php woocommerce_product_loop_start(); ?>
  395. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  396. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  397. <?php endwhile; // end of the loop. ?>
  398. <?php woocommerce_product_loop_end(); ?>
  399. <?php endif;
  400. wp_reset_postdata();
  401. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  402. }
  403. /**
  404. * Display a single prodcut price + cart button
  405. *
  406. * @access public
  407. * @param array $atts
  408. * @return string
  409. */
  410. public function product_add_to_cart( $atts ) {
  411. global $wpdb, $woocommerce;
  412. if ( empty( $atts ) ) return;
  413. if ( ! isset( $atts['style'] ) ) $atts['style'] = 'border:4px solid #ccc; padding: 12px;';
  414. if ( isset( $atts['id'] ) ) {
  415. $product_data = get_post( $atts['id'] );
  416. } elseif ( isset( $atts['sku'] ) ) {
  417. $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $atts['sku'] ) );
  418. $product_data = get_post( $product_id );
  419. } else {
  420. return;
  421. }
  422. if ( 'product' == $product_data->post_type ) {
  423. $product = $woocommerce->setup_product_data( $product_data );
  424. ob_start();
  425. ?>
  426. <p class="product woocommerce" style="<?php echo $atts['style']; ?>">
  427. <?php echo $product->get_price_html(); ?>
  428. <?php woocommerce_template_loop_add_to_cart(); ?>
  429. </p><?php
  430. wp_reset_postdata();
  431. return ob_get_clean();
  432. } elseif ( 'product_variation' == $product_data->post_type ) {
  433. $product = get_product( $product_data->post_parent );
  434. $GLOBALS['product'] = $product;
  435. $variation = get_product( $product_data );
  436. ob_start();
  437. ?>
  438. <p class="product product-variation" style="<?php echo $atts['style']; ?>">
  439. <?php echo $product->get_price_html(); ?>
  440. <?php
  441. $link = $product->add_to_cart_url();
  442. $label = apply_filters('add_to_cart_text', __( 'Add to cart', 'woocommerce' ));
  443. $link = add_query_arg( 'variation_id', $variation->variation_id, $link );
  444. foreach ($variation->variation_data as $key => $data) {
  445. if ($data) $link = add_query_arg( $key, $data, $link );
  446. }
  447. printf('<a href="%s" rel="nofollow" data-product_id="%s" class="button add_to_cart_button product_type_%s">%s</a>', esc_url( $link ), $product->id, $product->product_type, $label);
  448. ?>
  449. </p><?php
  450. wp_reset_postdata();
  451. return ob_get_clean();
  452. }
  453. }
  454. /**
  455. * Get the add to cart URL for a product
  456. *
  457. * @access public
  458. * @param array $atts
  459. * @return string
  460. */
  461. public function product_add_to_cart_url( $atts ) {
  462. global $wpdb;
  463. if ( empty( $atts ) ) return;
  464. if ( isset( $atts['id'] ) ) {
  465. $product_data = get_post( $atts['id'] );
  466. } elseif ( isset( $atts['sku'] ) ) {
  467. $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $atts['sku'] ) );
  468. $product_data = get_post( $product_id );
  469. } else {
  470. return;
  471. }
  472. if ( 'product' !== $product_data->post_type ) return;
  473. $_product = get_product( $product_data );
  474. return esc_url( $_product->add_to_cart_url() );
  475. }
  476. /**
  477. * List all products on sale
  478. *
  479. * @access public
  480. * @param array $atts
  481. * @return string
  482. */
  483. public function sale_products( $atts ){
  484. global $woocommerce_loop, $woocommerce;
  485. extract( shortcode_atts( array(
  486. 'per_page' => '12',
  487. 'columns' => '4',
  488. 'orderby' => 'title',
  489. 'order' => 'asc'
  490. ), $atts ) );
  491. // Get products on sale
  492. $product_ids_on_sale = woocommerce_get_product_ids_on_sale();
  493. $meta_query = array();
  494. $meta_query[] = $woocommerce->query->visibility_meta_query();
  495. $meta_query[] = $woocommerce->query->stock_status_meta_query();
  496. $args = array(
  497. 'posts_per_page'=> $per_page,
  498. 'orderby' => $orderby,
  499. 'order' => $order,
  500. 'no_found_rows' => 1,
  501. 'post_status' => 'publish',
  502. 'post_type' => 'product',
  503. 'orderby' => 'date',
  504. 'order' => 'ASC',
  505. 'meta_query' => $meta_query,
  506. 'post__in' => $product_ids_on_sale
  507. );
  508. ob_start();
  509. $products = new WP_Query( $args );
  510. $woocommerce_loop['columns'] = $columns;
  511. if ( $products->have_posts() ) : ?>
  512. <?php woocommerce_product_loop_start(); ?>
  513. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  514. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  515. <?php endwhile; // end of the loop. ?>
  516. <?php woocommerce_product_loop_end(); ?>
  517. <?php endif;
  518. wp_reset_postdata();
  519. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  520. }
  521. /**
  522. * List best selling products on sale
  523. *
  524. * @access public
  525. * @param array $atts
  526. * @return string
  527. */
  528. public function best_selling_products( $atts ){
  529. global $woocommerce_loop;
  530. extract( shortcode_atts( array(
  531. 'per_page' => '12',
  532. 'columns' => '4'
  533. ), $atts ) );
  534. $args = array(
  535. 'post_type' => 'product',
  536. 'post_status' => 'publish',
  537. 'ignore_sticky_posts' => 1,
  538. 'posts_per_page' => $per_page,
  539. 'meta_key' => 'total_sales',
  540. 'orderby' => 'meta_value',
  541. 'meta_query' => array(
  542. array(
  543. 'key' => '_visibility',
  544. 'value' => array( 'catalog', 'visible' ),
  545. 'compare' => 'IN'
  546. )
  547. )
  548. );
  549. ob_start();
  550. $products = new WP_Query( $args );
  551. $woocommerce_loop['columns'] = $columns;
  552. if ( $products->have_posts() ) : ?>
  553. <?php woocommerce_product_loop_start(); ?>
  554. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  555. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  556. <?php endwhile; // end of the loop. ?>
  557. <?php woocommerce_product_loop_end(); ?>
  558. <?php endif;
  559. wp_reset_postdata();
  560. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  561. }
  562. /**
  563. * List top rated products on sale
  564. *
  565. * @access public
  566. * @param array $atts
  567. * @return string
  568. */
  569. public function top_rated_products( $atts ){
  570. global $woocommerce_loop;
  571. extract( shortcode_atts( array(
  572. 'per_page' => '12',
  573. 'columns' => '4',
  574. 'orderby' => 'title',
  575. 'order' => 'asc'
  576. ), $atts ) );
  577. $args = array(
  578. 'post_type' => 'product',
  579. 'post_status' => 'publish',
  580. 'ignore_sticky_posts' => 1,
  581. 'orderby' => $orderby,
  582. 'order' => $order,
  583. 'posts_per_page' => $per_page,
  584. 'meta_query' => array(
  585. array(
  586. 'key' => '_visibility',
  587. 'value' => array('catalog', 'visible'),
  588. 'compare' => 'IN'
  589. )
  590. )
  591. );
  592. ob_start();
  593. add_filter( 'posts_clauses', array( &$this, 'order_by_rating_post_clauses' ) );
  594. $products = new WP_Query( $args );
  595. remove_filter( 'posts_clauses', array( &$this, 'order_by_rating_post_clauses' ) );
  596. $woocommerce_loop['columns'] = $columns;
  597. if ( $products->have_posts() ) : ?>
  598. <?php woocommerce_product_loop_start(); ?>
  599. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  600. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  601. <?php endwhile; // end of the loop. ?>
  602. <?php woocommerce_product_loop_end(); ?>
  603. <?php endif;
  604. wp_reset_postdata();
  605. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  606. }
  607. /**
  608. * Output featured products
  609. *
  610. * @access public
  611. * @param array $atts
  612. * @return string
  613. */
  614. public function featured_products( $atts ) {
  615. global $woocommerce_loop;
  616. extract(shortcode_atts(array(
  617. 'per_page' => '12',
  618. 'columns' => '4',
  619. 'orderby' => 'date',
  620. 'order' => 'desc'
  621. ), $atts));
  622. $args = array(
  623. 'post_type' => 'product',
  624. 'post_status' => 'publish',
  625. 'ignore_sticky_posts' => 1,
  626. 'posts_per_page' => $per_page,
  627. 'orderby' => $orderby,
  628. 'order' => $order,
  629. 'meta_query' => array(
  630. array(
  631. 'key' => '_visibility',
  632. 'value' => array('catalog', 'visible'),
  633. 'compare' => 'IN'
  634. ),
  635. array(
  636. 'key' => '_featured',
  637. 'value' => 'yes'
  638. )
  639. )
  640. );
  641. ob_start();
  642. $products = new WP_Query( $args );
  643. $woocommerce_loop['columns'] = $columns;
  644. if ( $products->have_posts() ) : ?>
  645. <?php woocommerce_product_loop_start(); ?>
  646. <?php while ( $products->have_posts() ) : $products->the_post(); ?>
  647. <?php woocommerce_get_template_part( 'content', 'product' ); ?>
  648. <?php endwhile; // end of the loop. ?>
  649. <?php woocommerce_product_loop_end(); ?>
  650. <?php endif;
  651. wp_reset_postdata();
  652. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  653. }
  654. /**
  655. * Show a single product page
  656. *
  657. * @access public
  658. * @param array $atts
  659. * @return string
  660. */
  661. public function product_page_shortcode( $atts ) {
  662. if ( empty( $atts ) ) return;
  663. if ( ! isset( $atts['id'] ) && ! isset( $atts['sku'] ) ) return;
  664. $args = array(
  665. 'posts_per_page' => 1,
  666. 'post_type' => 'product',
  667. 'post_status' => 'publish',
  668. 'ignore_sticky_posts' => 1,
  669. 'no_found_rows' => 1
  670. );
  671. if ( isset( $atts['sku'] ) ) {
  672. $args['meta_query'][] = array(
  673. 'key' => '_sku',
  674. 'value' => $atts['sku'],
  675. 'compare' => '='
  676. );
  677. }
  678. if ( isset( $atts['id'] ) ) {
  679. $args['p'] = $atts['id'];
  680. }
  681. $single_product = new WP_Query( $args );
  682. ob_start();
  683. while ( $single_product->have_posts() ) : $single_product->the_post(); wp_enqueue_script( 'wc-single-product' ); ?>
  684. <div class="single-product">
  685. <?php woocommerce_get_template_part( 'content', 'single-product' ); ?>
  686. </div>
  687. <?php endwhile; // end of the loop.
  688. wp_reset_postdata();
  689. return '<div class="woocommerce">' . ob_get_clean() . '</div>';
  690. }
  691. /**
  692. * Show messages
  693. *
  694. * @access public
  695. * @param array $atts
  696. * @return string
  697. */
  698. public function messages_shortcode() {
  699. ob_start();
  700. woocommerce_show_messages();
  701. return ob_get_clean();
  702. }
  703. /**
  704. * woocommerce_order_by_rating_post_clauses function.
  705. *
  706. * @access public
  707. * @param mixed $args
  708. * @return void
  709. */
  710. public function order_by_rating_post_clauses( $args ) {
  711. global $wpdb;
  712. $args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' ";
  713. $args['join'] .= "
  714. LEFT JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
  715. LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
  716. ";
  717. $args['orderby'] = "$wpdb->commentmeta.meta_value DESC";
  718. $args['groupby'] = "$wpdb->posts.ID";
  719. return $args;
  720. }
  721. }