PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/wordpress/wp-content/plugins/woocommerce/classes/class-wc-shortcodes.php

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