PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.4.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.4.0
2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 All 65 releases
← All changes | includes/Frontend/Product.php +79 -3 1.11.0 → 2.4.0 View file →
@@ -1,5 +1,10 @@
1 1 <?php
2 +/**
3 + * Storefront product handling for subscriptions.
4 + *
5 + * @package SpringDevs\Subscription
6 + */
2 7
3 8 namespace SpringDevs\Subscription\Frontend;
4 9
5 10 use SpringDevs\Subscription\Illuminate\Helper;
@@ -28,9 +33,15 @@
28 33 ),
29 34 10,
30 35 2
31 36 );
32 - add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_single_add_to_cart_text' ), 10, 2 );
37 + add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_loop_add_to_cart_text' ), 10, 2 );
38 + // Plan-tied simple products behave like a variable product on the shop /
39 + // Product Collection loops: a "Select options" link to the product page (so
40 + // the customer picks a plan), never a direct/ajax add-to-cart. These native
41 + // product-method filters drive both the classic loop and the block button.
42 + add_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'plan_loop_add_to_cart_url' ), 10, 2 );
43 + add_filter( 'woocommerce_product_supports', array( $this, 'plan_loop_disable_ajax' ), 10, 3 );
33 44 add_filter( 'woocommerce_get_price_html', array( $this, 'change_price_html' ), 10, 2 );
34 45 add_filter( 'woocommerce_quantity_input_args', array( $this, 'update_input_args' ), 10, 2 );
35 46 add_filter( 'woocommerce_add_to_cart', array( $this, 'update_cart_quantity' ), 10, 3 );
36 47 add_filter(
@@ -164,9 +175,10 @@
164 175 $order_item_id = get_post_meta( $expired, '_subscrpt_order_item_id', true );
165 176 $item_quantity = (int) wc_get_order_item_meta( $order_item_id, '_qty', true );
166 177 if ( $item_quantity !== $quantity ) {
167 178 WC()->cart->set_quantity( $cart_item_key, $item_quantity );
168 - wc_add_notice( 'You can only add ' . $item_quantity . ' ' . ( $item_quantity > 1 ? 'items' : 'item' ) . ' on cart!', 'error' );
179 + /* translators: %d: the number of items allowed in the cart. */
180 + wc_add_notice( sprintf( _n( 'You can only add %d item to the cart.', 'You can only add %d items to the cart.', $item_quantity, 'subscription' ), $item_quantity ), 'error' );
169 181 }
170 182 }
171 183 }
172 184
@@ -205,9 +217,10 @@
205 217 $order_item_id = get_post_meta( $expired, '_subscrpt_order_item_id', true );
206 218 $item_quantity = (int) wc_get_order_item_meta( $order_item_id, '_qty', true );
207 219 if ( $item_quantity !== $quantity ) {
208 220 WC()->cart->set_quantity( $cart_item_key, $item_quantity );
209 - wc_add_notice( 'You can only add ' . $item_quantity . ' ' . ( $item_quantity > 1 ? 'items' : 'item' ) . ' on cart!', 'error' );
221 + /* translators: %d: the number of items allowed in the cart. */
222 + wc_add_notice( sprintf( _n( 'You can only add %d item to the cart.', 'You can only add %d items to the cart.', $item_quantity, 'subscription' ), $item_quantity ), 'error' );
210 223 }
211 224 }
212 225 }
213 226
@@ -252,8 +265,71 @@
252 265 $text = $cart_btn_label;
253 266 }
254 267
255 268 return $text;
269 + }
270 +
271 + /**
272 + * Whether this is a plan-tied simple product that should behave like a
273 + * variable product on the shop / Product Collection loops.
274 + *
275 + * @param mixed $product Product object.
276 + *
277 + * @return bool
278 + */
279 + private function is_plan_loop_product( $product ) {
280 + return $product instanceof \WC_Product
281 + && $product->is_type( 'simple' )
282 + && subscrpt_plan_offered( $product->get_id() );
283 + }
284 +
285 + /**
286 + * Loop / block add-to-cart button text: "Select options" for plan products,
287 + * otherwise the classic label logic.
288 + *
289 + * @param string $text Add-to-cart button text.
290 + * @param \WC_Product $product Product object.
291 + *
292 + * @return string
293 + */
294 + public function change_loop_add_to_cart_text( $text, $product ) {
295 + if ( $this->is_plan_loop_product( $product ) ) {
296 + return __( 'Select options', 'subscription' );
297 + }
298 +
299 + return $this->change_single_add_to_cart_text( $text, $product );
300 + }
301 +
302 + /**
303 + * Loop / block add-to-cart URL: the product page for plan products, so the
304 + * customer lands on the plan selector instead of a bare add-to-cart.
305 + *
306 + * @param string $url Add-to-cart URL.
307 + * @param \WC_Product $product Product object.
308 + *
309 + * @return string
310 + */
311 + public function plan_loop_add_to_cart_url( $url, $product ) {
312 + return $this->is_plan_loop_product( $product ) ? $product->get_permalink() : $url;
313 + }
314 +
315 + /**
316 + * Disable ajax add-to-cart for plan products so their loop / block button
317 + * renders as a "Select options" link (navigates to the product page) rather
318 + * than an ajax add.
319 + *
320 + * @param bool $supports Whether the feature is supported.
321 + * @param string $feature Feature name.
322 + * @param \WC_Product $product Product object.
323 + *
324 + * @return bool
325 + */
326 + public function plan_loop_disable_ajax( $supports, $feature, $product ) {
327 + if ( 'ajax_add_to_cart' === $feature && $this->is_plan_loop_product( $product ) ) {
328 + return false;
329 + }
330 +
331 + return $supports;
256 332 }
257 333
258 334 /**
259 335 * Add trial, signup fee etc. with product price.