PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 8.9.3
WooCommerce v8.9.3
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / class-wc-shortcodes.php
woocommerce / includes Last commit date
abstracts 1 year ago admin 1 year ago blocks 1 year ago cli 1 year ago customizer 1 year ago data-stores 1 year ago emails 1 year ago export 1 year ago gateways 1 year ago import 1 year ago integrations 1 year ago interfaces 1 year ago legacy 1 year ago libraries 1 year ago log-handlers 1 year ago payment-tokens 1 year ago queue 1 year ago react-admin 1 year ago rest-api 1 year ago shipping 1 year ago shortcodes 1 year ago theme-support 1 year ago tracks 1 year ago traits 1 year ago walkers 1 year ago wccom-site 1 year ago widgets 1 year ago class-wc-ajax.php 1 year ago class-wc-api.php 1 year ago class-wc-auth.php 1 year ago class-wc-autoloader.php 1 year ago class-wc-background-emailer.php 1 year ago class-wc-background-updater.php 1 year ago class-wc-breadcrumb.php 1 year ago class-wc-cache-helper.php 1 year ago class-wc-cart-fees.php 1 year ago class-wc-cart-session.php 1 year ago class-wc-cart-totals.php 1 year ago class-wc-cart.php 1 year ago class-wc-checkout.php 1 year ago class-wc-cli.php 1 year ago class-wc-comments.php 1 year ago class-wc-countries.php 1 year ago class-wc-coupon.php 1 year ago class-wc-customer-download-log.php 1 year ago class-wc-customer-download.php 1 year ago class-wc-customer.php 1 year ago class-wc-data-exception.php 1 year ago class-wc-data-store.php 1 year ago class-wc-datetime.php 1 year ago class-wc-deprecated-action-hooks.php 1 year ago class-wc-deprecated-filter-hooks.php 1 year ago class-wc-discounts.php 1 year ago class-wc-download-handler.php 1 year ago class-wc-emails.php 1 year ago class-wc-embed.php 1 year ago class-wc-form-handler.php 1 year ago class-wc-frontend-scripts.php 1 year ago class-wc-geo-ip.php 1 year ago class-wc-geolite-integration.php 1 year ago class-wc-geolocation.php 1 year ago class-wc-https.php 1 year ago class-wc-install.php 1 year ago class-wc-integrations.php 1 year ago class-wc-log-levels.php 1 year ago class-wc-logger.php 1 year ago class-wc-meta-data.php 1 year ago class-wc-order-factory.php 1 year ago class-wc-order-item-coupon.php 1 year ago class-wc-order-item-fee.php 1 year ago class-wc-order-item-meta.php 1 year ago class-wc-order-item-product.php 1 year ago class-wc-order-item-shipping.php 1 year ago class-wc-order-item-tax.php 1 year ago class-wc-order-item.php 1 year ago class-wc-order-query.php 1 year ago class-wc-order-refund.php 1 year ago class-wc-order.php 1 year ago class-wc-payment-gateways.php 1 year ago class-wc-payment-tokens.php 1 year ago class-wc-post-data.php 1 year ago class-wc-post-types.php 1 year ago class-wc-privacy-background-process.php 1 year ago class-wc-privacy-erasers.php 1 year ago class-wc-privacy-exporters.php 1 year ago class-wc-privacy.php 1 year ago class-wc-product-attribute.php 1 year ago class-wc-product-download.php 1 year ago class-wc-product-external.php 1 year ago class-wc-product-factory.php 1 year ago class-wc-product-grouped.php 1 year ago class-wc-product-query.php 1 year ago class-wc-product-simple.php 1 year ago class-wc-product-variable.php 1 year ago class-wc-product-variation.php 1 year ago class-wc-query.php 1 year ago class-wc-rate-limiter.php 1 year ago class-wc-regenerate-images-request.php 1 year ago class-wc-regenerate-images.php 1 year ago class-wc-register-wp-admin-settings.php 1 year ago class-wc-rest-authentication.php 1 year ago class-wc-rest-exception.php 1 year ago class-wc-session-handler.php 1 year ago class-wc-shipping-rate.php 1 year ago class-wc-shipping-zone.php 1 year ago class-wc-shipping-zones.php 1 year ago class-wc-shipping.php 1 year ago class-wc-shortcodes.php 1 year ago class-wc-structured-data.php 1 year ago class-wc-tax.php 1 year ago class-wc-template-loader.php 1 year ago class-wc-tracker.php 1 year ago class-wc-validation.php 1 year ago class-wc-webhook.php 1 year ago class-woocommerce.php 1 year ago wc-account-functions.php 1 year ago wc-attribute-functions.php 1 year ago wc-cart-functions.php 1 year ago wc-conditional-functions.php 1 year ago wc-core-functions.php 1 year ago wc-coupon-functions.php 1 year ago wc-deprecated-functions.php 1 year ago wc-formatting-functions.php 1 year ago wc-notice-functions.php 1 year ago wc-order-functions.php 1 year ago wc-order-item-functions.php 1 year ago wc-page-functions.php 1 year ago wc-product-functions.php 1 year ago wc-rest-functions.php 1 year ago wc-stock-functions.php 1 year ago wc-template-functions.php 1 year ago wc-template-hooks.php 1 year ago wc-term-functions.php 1 year ago wc-update-functions.php 1 year ago wc-user-functions.php 1 year ago wc-webhook-functions.php 1 year ago wc-widget-functions.php 1 year ago
class-wc-shortcodes.php
740 lines
1 <?php
2 /**
3 * Shortcodes
4 *
5 * @package WooCommerce\Classes
6 * @version 3.2.0
7 */
8
9 defined( 'ABSPATH' ) || exit;
10
11 /**
12 * WooCommerce Shortcodes class.
13 */
14 class WC_Shortcodes {
15
16 /**
17 * Init shortcodes.
18 */
19 public static function init() {
20 $shortcodes = array(
21 'product' => __CLASS__ . '::product',
22 'product_page' => __CLASS__ . '::product_page',
23 'product_category' => __CLASS__ . '::product_category',
24 'product_categories' => __CLASS__ . '::product_categories',
25 'add_to_cart' => __CLASS__ . '::product_add_to_cart',
26 'add_to_cart_url' => __CLASS__ . '::product_add_to_cart_url',
27 'products' => __CLASS__ . '::products',
28 'recent_products' => __CLASS__ . '::recent_products',
29 'sale_products' => __CLASS__ . '::sale_products',
30 'best_selling_products' => __CLASS__ . '::best_selling_products',
31 'top_rated_products' => __CLASS__ . '::top_rated_products',
32 'featured_products' => __CLASS__ . '::featured_products',
33 'product_attribute' => __CLASS__ . '::product_attribute',
34 'related_products' => __CLASS__ . '::related_products',
35 'shop_messages' => __CLASS__ . '::shop_messages',
36 'woocommerce_order_tracking' => __CLASS__ . '::order_tracking',
37 'woocommerce_cart' => __CLASS__ . '::cart',
38 'woocommerce_checkout' => __CLASS__ . '::checkout',
39 'woocommerce_my_account' => __CLASS__ . '::my_account',
40 );
41
42 foreach ( $shortcodes as $shortcode => $function ) {
43 add_shortcode( apply_filters( "{$shortcode}_shortcode_tag", $shortcode ), $function );
44 }
45
46 // Alias for pre 2.1 compatibility.
47 add_shortcode( 'woocommerce_messages', __CLASS__ . '::shop_messages' );
48 }
49
50 /**
51 * Shortcode Wrapper.
52 *
53 * @param string[] $function Callback function.
54 * @param array $atts Attributes. Default to empty array.
55 * @param array $wrapper Customer wrapper data.
56 *
57 * @return string
58 */
59 public static function shortcode_wrapper(
60 $function,
61 $atts = array(),
62 $wrapper = array(
63 'class' => 'woocommerce',
64 'before' => null,
65 'after' => null,
66 )
67 ) {
68 ob_start();
69
70 // @codingStandardsIgnoreStart
71 echo empty( $wrapper['before'] ) ? '<div class="' . esc_attr( $wrapper['class'] ) . '">' : $wrapper['before'];
72 call_user_func( $function, $atts );
73 echo empty( $wrapper['after'] ) ? '</div>' : $wrapper['after'];
74 // @codingStandardsIgnoreEnd
75
76 return ob_get_clean();
77 }
78
79 /**
80 * Cart page shortcode.
81 *
82 * @return string
83 */
84 public static function cart() {
85 return is_null( WC()->cart ) ? '' : self::shortcode_wrapper( array( 'WC_Shortcode_Cart', 'output' ) );
86 }
87
88 /**
89 * Checkout page shortcode.
90 *
91 * @param array $atts Attributes.
92 * @return string
93 */
94 public static function checkout( $atts ) {
95 return self::shortcode_wrapper( array( 'WC_Shortcode_Checkout', 'output' ), $atts );
96 }
97
98 /**
99 * Order tracking page shortcode.
100 *
101 * @param array $atts Attributes.
102 * @return string
103 */
104 public static function order_tracking( $atts ) {
105 return self::shortcode_wrapper( array( 'WC_Shortcode_Order_Tracking', 'output' ), $atts );
106 }
107
108 /**
109 * My account page shortcode.
110 *
111 * @param array $atts Attributes.
112 * @return string
113 */
114 public static function my_account( $atts ) {
115 return self::shortcode_wrapper( array( 'WC_Shortcode_My_Account', 'output' ), $atts );
116 }
117
118 /**
119 * List products in a category shortcode.
120 *
121 * @param array $atts Attributes.
122 * @return string
123 */
124 public static function product_category( $atts ) {
125 if ( empty( $atts['category'] ) ) {
126 return '';
127 }
128
129 $atts = array_merge(
130 array(
131 'limit' => '12',
132 'columns' => '4',
133 'orderby' => 'menu_order title',
134 'order' => 'ASC',
135 'category' => '',
136 'cat_operator' => 'IN',
137 ),
138 (array) $atts
139 );
140
141 $shortcode = new WC_Shortcode_Products( $atts, 'product_category' );
142
143 return $shortcode->get_content();
144 }
145
146 /**
147 * List all (or limited) product categories.
148 *
149 * @param array $atts Attributes.
150 * @return string
151 */
152 public static function product_categories( $atts ) {
153 if ( isset( $atts['number'] ) ) {
154 $atts['limit'] = $atts['number'];
155 }
156
157 $atts = shortcode_atts(
158 array(
159 'limit' => '-1',
160 'orderby' => 'name',
161 'order' => 'ASC',
162 'columns' => '4',
163 'hide_empty' => 1,
164 'parent' => '',
165 'ids' => '',
166 ),
167 $atts,
168 'product_categories'
169 );
170
171 $ids = array_filter( array_map( 'trim', explode( ',', $atts['ids'] ) ) );
172 $hide_empty = ( true === $atts['hide_empty'] || 'true' === $atts['hide_empty'] || 1 === $atts['hide_empty'] || '1' === $atts['hide_empty'] ) ? 1 : 0;
173
174 // Get terms and workaround WP bug with parents/pad counts.
175 $args = array(
176 'orderby' => $atts['orderby'],
177 'order' => $atts['order'],
178 'hide_empty' => $hide_empty,
179 'include' => $ids,
180 'pad_counts' => true,
181 'child_of' => $atts['parent'],
182 );
183
184 $product_categories = apply_filters(
185 'woocommerce_product_categories',
186 get_terms( 'product_cat', $args )
187 );
188
189 if ( '' !== $atts['parent'] ) {
190 $product_categories = wp_list_filter(
191 $product_categories,
192 array(
193 'parent' => $atts['parent'],
194 )
195 );
196 }
197
198 if ( $hide_empty ) {
199 foreach ( $product_categories as $key => $category ) {
200 if ( 0 === $category->count ) {
201 unset( $product_categories[ $key ] );
202 }
203 }
204 }
205
206 $atts['limit'] = '-1' === $atts['limit'] ? null : intval( $atts['limit'] );
207 if ( $atts['limit'] ) {
208 $product_categories = array_slice( $product_categories, 0, $atts['limit'] );
209 }
210
211 $columns = absint( $atts['columns'] );
212
213 wc_set_loop_prop( 'columns', $columns );
214 wc_set_loop_prop( 'is_shortcode', true );
215
216 ob_start();
217
218 if ( $product_categories ) {
219 woocommerce_product_loop_start();
220
221 foreach ( $product_categories as $category ) {
222 wc_get_template(
223 'content-product_cat.php',
224 array(
225 'category' => $category,
226 )
227 );
228 }
229
230 woocommerce_product_loop_end();
231 }
232
233 wc_reset_loop();
234
235 return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
236 }
237
238 /**
239 * Recent Products shortcode.
240 *
241 * @param array $atts Attributes.
242 * @return string
243 */
244 public static function recent_products( $atts ) {
245 $atts = array_merge(
246 array(
247 'limit' => '12',
248 'columns' => '4',
249 'orderby' => 'date',
250 'order' => 'DESC',
251 'category' => '',
252 'cat_operator' => 'IN',
253 ),
254 (array) $atts
255 );
256
257 $shortcode = new WC_Shortcode_Products( $atts, 'recent_products' );
258
259 return $shortcode->get_content();
260 }
261
262 /**
263 * List multiple products shortcode.
264 *
265 * @param array $atts Attributes.
266 * @return string
267 */
268 public static function products( $atts ) {
269 $atts = (array) $atts;
270 $type = 'products';
271
272 // Allow list product based on specific cases.
273 if ( isset( $atts['on_sale'] ) && wc_string_to_bool( $atts['on_sale'] ) ) {
274 $type = 'sale_products';
275 } elseif ( isset( $atts['best_selling'] ) && wc_string_to_bool( $atts['best_selling'] ) ) {
276 $type = 'best_selling_products';
277 } elseif ( isset( $atts['top_rated'] ) && wc_string_to_bool( $atts['top_rated'] ) ) {
278 $type = 'top_rated_products';
279 }
280
281 $shortcode = new WC_Shortcode_Products( $atts, $type );
282
283 return $shortcode->get_content();
284 }
285
286 /**
287 * Display a single product.
288 *
289 * @param array $atts Attributes.
290 * @return string
291 */
292 public static function product( $atts ) {
293 if ( empty( $atts ) ) {
294 return '';
295 }
296
297 $atts['skus'] = isset( $atts['sku'] ) ? $atts['sku'] : '';
298 $atts['ids'] = isset( $atts['id'] ) ? $atts['id'] : '';
299 $atts['limit'] = '1';
300 $shortcode = new WC_Shortcode_Products( (array) $atts, 'product' );
301
302 return $shortcode->get_content();
303 }
304
305 /**
306 * Display a single product price + cart button.
307 *
308 * @param array $atts Attributes.
309 * @return string
310 */
311 public static function product_add_to_cart( $atts ) {
312 global $post;
313
314 if ( empty( $atts ) ) {
315 return '';
316 }
317
318 $atts = shortcode_atts(
319 array(
320 'id' => '',
321 'class' => '',
322 'quantity' => '1',
323 'sku' => '',
324 'style' => 'border:4px solid #ccc; padding: 12px;',
325 'show_price' => 'true',
326 ),
327 $atts,
328 'product_add_to_cart'
329 );
330
331 if ( ! empty( $atts['id'] ) ) {
332 $product_data = get_post( $atts['id'] );
333 } elseif ( ! empty( $atts['sku'] ) ) {
334 $product_id = wc_get_product_id_by_sku( $atts['sku'] );
335 $product_data = get_post( $product_id );
336 } else {
337 return '';
338 }
339
340 $product = is_object( $product_data ) && in_array( $product_data->post_type, array( 'product', 'product_variation' ), true ) ? wc_setup_product_data( $product_data ) : false;
341
342 if ( ! $product ) {
343 return '';
344 }
345
346 ob_start();
347
348 echo '<p class="product woocommerce add_to_cart_inline ' . esc_attr( $atts['class'] ) . '" style="' . ( empty( $atts['style'] ) ? '' : esc_attr( $atts['style'] ) ) . '">';
349
350 if ( wc_string_to_bool( $atts['show_price'] ) ) {
351 // @codingStandardsIgnoreStart
352 echo $product->get_price_html();
353 // @codingStandardsIgnoreEnd
354 }
355
356 woocommerce_template_loop_add_to_cart(
357 array(
358 'quantity' => $atts['quantity'],
359 )
360 );
361
362 echo '</p>';
363
364 // Restore Product global in case this is shown inside a product post.
365 wc_setup_product_data( $post );
366
367 return ob_get_clean();
368 }
369
370 /**
371 * Get the add to cart URL for a product.
372 *
373 * @param array $atts Attributes.
374 * @return string
375 */
376 public static function product_add_to_cart_url( $atts ) {
377 if ( empty( $atts ) ) {
378 return '';
379 }
380
381 if ( isset( $atts['id'] ) ) {
382 $product_data = get_post( $atts['id'] );
383 } elseif ( isset( $atts['sku'] ) ) {
384 $product_id = wc_get_product_id_by_sku( $atts['sku'] );
385 $product_data = get_post( $product_id );
386 } else {
387 return '';
388 }
389
390 $product = is_object( $product_data ) && in_array( $product_data->post_type, array( 'product', 'product_variation' ), true ) ? wc_setup_product_data( $product_data ) : false;
391
392 if ( ! $product ) {
393 return '';
394 }
395
396 $_product = wc_get_product( $product_data );
397
398 return esc_url( $_product->add_to_cart_url() );
399 }
400
401 /**
402 * List all products on sale.
403 *
404 * @param array $atts Attributes.
405 * @return string
406 */
407 public static function sale_products( $atts ) {
408 $atts = array_merge(
409 array(
410 'limit' => '12',
411 'columns' => '4',
412 'orderby' => 'title',
413 'order' => 'ASC',
414 'category' => '',
415 'cat_operator' => 'IN',
416 ),
417 (array) $atts
418 );
419
420 $shortcode = new WC_Shortcode_Products( $atts, 'sale_products' );
421
422 return $shortcode->get_content();
423 }
424
425 /**
426 * List best selling products on sale.
427 *
428 * @param array $atts Attributes.
429 * @return string
430 */
431 public static function best_selling_products( $atts ) {
432 $atts = array_merge(
433 array(
434 'limit' => '12',
435 'columns' => '4',
436 'category' => '',
437 'cat_operator' => 'IN',
438 ),
439 (array) $atts
440 );
441
442 $shortcode = new WC_Shortcode_Products( $atts, 'best_selling_products' );
443
444 return $shortcode->get_content();
445 }
446
447 /**
448 * List top rated products on sale.
449 *
450 * @param array $atts Attributes.
451 * @return string
452 */
453 public static function top_rated_products( $atts ) {
454 $atts = array_merge(
455 array(
456 'limit' => '12',
457 'columns' => '4',
458 'orderby' => 'title',
459 'order' => 'ASC',
460 'category' => '',
461 'cat_operator' => 'IN',
462 ),
463 (array) $atts
464 );
465
466 $shortcode = new WC_Shortcode_Products( $atts, 'top_rated_products' );
467
468 return $shortcode->get_content();
469 }
470
471 /**
472 * Output featured products.
473 *
474 * @param array $atts Attributes.
475 * @return string
476 */
477 public static function featured_products( $atts ) {
478 $atts = array_merge(
479 array(
480 'limit' => '12',
481 'columns' => '4',
482 'orderby' => 'date',
483 'order' => 'DESC',
484 'category' => '',
485 'cat_operator' => 'IN',
486 ),
487 (array) $atts
488 );
489
490 $atts['visibility'] = 'featured';
491
492 $shortcode = new WC_Shortcode_Products( $atts, 'featured_products' );
493
494 return $shortcode->get_content();
495 }
496
497 /**
498 * Show a single product page.
499 *
500 * @param array $atts Attributes.
501 * @return string
502 */
503 public static function product_page( $atts ) {
504 if ( empty( $atts ) ) {
505 return '';
506 }
507
508 if ( ! isset( $atts['id'] ) && ! isset( $atts['sku'] ) ) {
509 return '';
510 }
511
512 $product_id = isset( $atts['id'] ) ? absint( $atts['id'] ) : 0;
513 if ( ! $product_id && isset( $atts['sku'] ) ) {
514 $product_id = wc_get_product_id_by_sku( $atts['sku'] );
515 }
516
517 $product_status = empty( $atts['status'] ) ? 'publish' : $atts['status'];
518 /**
519 * Filters the list of invalid statuses for the `product_page` shortcode.
520 *
521 * @since 8.6.0
522 * @param array $invalid_statuses List of invalid statuses.
523 * @param int $product_id Product ID.
524 * @return array
525 */
526 $invalid_statuses = apply_filters( 'woocommerce_shortcode_product_page_invalid_statuses', array( 'trash' ), $product_id );
527 if ( in_array( $product_status, $invalid_statuses, true ) ) {
528 return '';
529 }
530 /**
531 * Filters whether to override read permissions for unpublished products.
532 *
533 * @since 8.6.0
534 * @param bool $force_rendering Whether to override read permissions for unpublished products. `true` to force rendering the product page, `false` to block rendering, or `null` to use the default behavior.
535 * @param int $product_id Product ID.
536 * @return bool
537 */
538 $force_rendering = apply_filters( 'woocommerce_shortcode_product_page_force_rendering', null, $product_id );
539 if ( isset( $force_rendering ) && ! $force_rendering ) {
540 return '';
541 }
542
543 $args = array(
544 'posts_per_page' => 1,
545 'post_type' => 'product',
546 'post_status' => $product_status,
547 'ignore_sticky_posts' => 1,
548 'no_found_rows' => 1,
549 );
550
551 if ( isset( $atts['sku'] ) ) {
552 $args['meta_query'][] = array(
553 'key' => '_sku',
554 'value' => sanitize_text_field( $atts['sku'] ),
555 'compare' => '=',
556 );
557
558 $args['post_type'] = array( 'product', 'product_variation' );
559 }
560
561 if ( isset( $atts['id'] ) ) {
562 $args['p'] = absint( $atts['id'] );
563 }
564
565 // Don't render titles if desired.
566 if ( isset( $atts['show_title'] ) && ! $atts['show_title'] ) {
567 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 );
568 }
569
570 // Change form action to avoid redirect.
571 add_filter( 'woocommerce_add_to_cart_form_action', '__return_empty_string' );
572
573 $single_product = new WP_Query( $args );
574
575 if (
576 ! isset( $force_rendering ) &&
577 $single_product->have_posts() &&
578 'publish' !== $single_product->post->post_status &&
579 ! current_user_can( 'read_product', $single_product->post->ID )
580 ) {
581 return '';
582 }
583
584 $preselected_id = '0';
585
586 // Check if sku is a variation.
587 if ( isset( $atts['sku'] ) && $single_product->have_posts() && 'product_variation' === $single_product->post->post_type ) {
588
589 $variation = wc_get_product_object( 'variation', $single_product->post->ID );
590 $attributes = $variation->get_attributes();
591
592 // Set preselected id to be used by JS to provide context.
593 $preselected_id = $single_product->post->ID;
594
595 // Get the parent product object.
596 $args = array(
597 'posts_per_page' => 1,
598 'post_type' => 'product',
599 'post_status' => 'publish',
600 'ignore_sticky_posts' => 1,
601 'no_found_rows' => 1,
602 'p' => $single_product->post->post_parent,
603 );
604
605 $single_product = new WP_Query( $args );
606 ?>
607 <script type="text/javascript">
608 jQuery( function( $ ) {
609 var $variations_form = $( '[data-product-page-preselected-id="<?php echo esc_attr( $preselected_id ); ?>"]' ).find( 'form.variations_form' );
610
611 <?php foreach ( $attributes as $attr => $value ) { ?>
612 $variations_form.find( 'select[name="<?php echo esc_attr( $attr ); ?>"]' ).val( '<?php echo esc_js( $value ); ?>' );
613 <?php } ?>
614 });
615 </script>
616 <?php
617 }
618
619 // For "is_single" to always make load comments_template() for reviews.
620 $single_product->is_single = true;
621
622 ob_start();
623
624 global $wp_query;
625
626 // Backup query object so following loops think this is a product page.
627 $previous_wp_query = $wp_query;
628 // @codingStandardsIgnoreStart
629 $wp_query = $single_product;
630 // @codingStandardsIgnoreEnd
631
632 wp_enqueue_script( 'wc-single-product' );
633
634 while ( $single_product->have_posts() ) {
635 $single_product->the_post()
636 ?>
637 <div class="single-product" data-product-page-preselected-id="<?php echo esc_attr( $preselected_id ); ?>">
638 <?php wc_get_template_part( 'content', 'single-product' ); ?>
639 </div>
640 <?php
641 }
642
643 // Restore $previous_wp_query and reset post data.
644 // @codingStandardsIgnoreStart
645 $wp_query = $previous_wp_query;
646 // @codingStandardsIgnoreEnd
647 wp_reset_postdata();
648
649 // Re-enable titles if they were removed.
650 if ( isset( $atts['show_title'] ) && ! $atts['show_title'] ) {
651 add_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 );
652 }
653
654 remove_filter( 'woocommerce_add_to_cart_form_action', '__return_empty_string' );
655
656 return '<div class="woocommerce">' . ob_get_clean() . '</div>';
657 }
658
659 /**
660 * Show messages.
661 *
662 * @return string
663 */
664 public static function shop_messages() {
665 if ( ! function_exists( 'wc_print_notices' ) ) {
666 return '';
667 }
668 return '<div class="woocommerce">' . wc_print_notices( true ) . '</div>';
669 }
670
671 /**
672 * Order by rating.
673 *
674 * @deprecated 3.2.0 Use WC_Shortcode_Products::order_by_rating_post_clauses().
675 * @param array $args Query args.
676 * @return array
677 */
678 public static function order_by_rating_post_clauses( $args ) {
679 return WC_Shortcode_Products::order_by_rating_post_clauses( $args );
680 }
681
682 /**
683 * List products with an attribute shortcode.
684 * Example [product_attribute attribute="color" filter="black"].
685 *
686 * @param array $atts Attributes.
687 * @return string
688 */
689 public static function product_attribute( $atts ) {
690 $atts = array_merge(
691 array(
692 'limit' => '12',
693 'columns' => '4',
694 'orderby' => 'title',
695 'order' => 'ASC',
696 'attribute' => '',
697 'terms' => '',
698 ),
699 (array) $atts
700 );
701
702 if ( empty( $atts['attribute'] ) ) {
703 return '';
704 }
705
706 $shortcode = new WC_Shortcode_Products( $atts, 'product_attribute' );
707
708 return $shortcode->get_content();
709 }
710
711 /**
712 * List related products.
713 *
714 * @param array $atts Attributes.
715 * @return string
716 */
717 public static function related_products( $atts ) {
718 if ( isset( $atts['per_page'] ) ) {
719 $atts['limit'] = $atts['per_page'];
720 }
721
722 // @codingStandardsIgnoreStart
723 $atts = shortcode_atts( array(
724 'limit' => '4',
725 'columns' => '4',
726 'orderby' => 'rand',
727 ), $atts, 'related_products' );
728 // @codingStandardsIgnoreEnd
729
730 ob_start();
731
732 // Rename arg.
733 $atts['posts_per_page'] = absint( $atts['limit'] );
734
735 woocommerce_related_products( $atts );
736
737 return ob_get_clean();
738 }
739 }
740