PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.0.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.0.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 1.4.1 1.4.2 1.5.0 1.5.1 All 61 releases
← All changes | includes/Frontend/Checkout.php +83 -26 1.3.12.0.0 View file →
@@ -1,9 +1,15 @@
1 1 <?php
2 +/**
3 + * Checkout handlers for subscription plugin.
4 + *
5 + * @package wp_subscription
6 + */
2 7
3 8 namespace SpringDevs\Subscription\Frontend;
4 9
5 10 use SpringDevs\Subscription\Illuminate\Helper;
11 +use SpringDevs\Subscription\Illuminate\Subscription\Subscription;
6 12
7 13 /**
8 14 * Checkout class
9 15 */
@@ -12,12 +18,16 @@
12 18 /**
13 19 * Initialize the class
14 20 */
15 21 public function __construct() {
16 - add_action( 'woocommerce_checkout_order_processed', array( $this, 'create_subscription_after_checkout' ) );
17 - add_action( 'woocommerce_store_api_checkout_order_processed', array( $this, 'create_subscription_after_checkout_storeapi' ) );
18 - add_action( 'woocommerce_resume_order', array( $this, 'remove_subscriptions' ) );
19 - add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'save_order_item_product_meta' ), 10, 3 );
22 + // Subscription upgrade/downgrade order created hook.
23 + add_action( 'woocommerce_checkout_order_processed', [ $this, 'trigger_subscription_switch_order_created' ] );
24 + add_action( 'woocommerce_store_api_checkout_order_processed', [ $this, 'trigger_subscription_switch_order_created_storeapi' ] );
25 +
26 + add_action( 'woocommerce_checkout_order_processed', [ $this, 'create_subscription_after_checkout' ] );
27 + add_action( 'woocommerce_store_api_checkout_order_processed', [ $this, 'create_subscription_after_checkout_storeapi' ] );
28 + add_action( 'woocommerce_resume_order', [ $this, 'remove_subscriptions' ] );
29 + add_action( 'woocommerce_checkout_create_order_line_item', [ $this, 'save_order_item_product_meta' ], 10, 3 );
20 30 }
21 31
22 32 /**
23 33 * Create subscription during checkout on storeAPI.
@@ -55,26 +65,24 @@
55 65
56 66 // Create subscription for order items.
57 67 $order_items = $order->get_items();
58 68 foreach ( $order_items as $order_item ) {
59 - $product = wc_get_product( $order_item['product_id'] );
69 + $product = Subscription::get_subs_product( $order_item['product_id'] );
60 70
61 - if ( $product->is_type( 'simple' ) && ! subscrpt_pro_activated() ) {
62 - $enabled = $product->get_meta( '_subscrpt_enabled' );
71 + // Plan items are created by Frontend\PlanCheckout on `subscrpt_product_checkout`
72 + // below (resolution order: tied plan first, else classic meta). Skipping
73 + // them here keeps the classic path from creating a second subscription.
74 + if ( $product->is_type( 'simple' ) && ! subscrpt_pro_activated() && ! $order_item->get_meta( '_subscrpt_plan_id' ) ) {
75 + // A plan product bought as One-Time carries no plan id — it is not a
76 + // subscription, so never record one for it.
77 + $is_one_time = function_exists( 'subscrpt_product_has_plan' ) && subscrpt_product_has_plan( $product->get_id() );
63 78
64 - if ( $enabled ) {
79 + if ( $product->is_enabled() && ! $is_one_time ) {
65 80 $is_renew = isset( $order_item['renew_subscrpt'] );
66 81
67 - $timing_option = $product->get_meta( '_subscrpt_timing_option' );
68 - $trial = null;
69 - $has_trial = Helper::check_trial( $product->get_id() );
82 + $timing_option = $product->get_timing_option();
83 + $trial = $product->get_trial();
70 84
71 - $trial_per = $product->get_meta( '_subscrpt_trial_timing_per' );
72 - $trial_option = $product->get_meta( '_subscrpt_trial_timing_option' );
73 - if ( ! empty( $trial_per ) && $trial_per > 0 && ! $is_renew && $has_trial ) {
74 - $trial = $trial_per . ' ' . Helper::get_typos( $trial_per, $trial_option );
75 - }
76 -
77 85 wc_update_order_item_meta(
78 86 $order_item->get_id(),
79 87 '_subscrpt_meta',
80 88 array(
@@ -88,13 +96,9 @@
88 96 $renew_subscription_id = Helper::subscription_exists( $product->get_id(), 'expired' );
89 97 $selected_subscription_id = null;
90 98 if ( $is_renew && $renew_subscription_id && 'cancelled' !== $post_status ) {
91 99 $selected_subscription_id = $renew_subscription_id;
92 - Helper::process_order_renewal(
93 - $selected_subscription_id,
94 - $order_id,
95 - $order_item->get_id()
96 - );
100 + Helper::process_order_renewal( $selected_subscription_id, $order_id, $order_item->get_id() );
97 101 } else {
98 102 $selected_subscription_id = Helper::process_new_subscription_order( $order_item, $post_status, $product );
99 103 }
100 104
@@ -100,9 +104,9 @@
100 104
101 105 if ( $selected_subscription_id ) {
102 106 // product related.
103 107 update_post_meta( $selected_subscription_id, '_subscrpt_timing_option', $timing_option );
104 - update_post_meta( $selected_subscription_id, '_subscrpt_price', $product->get_price() * $order_item['quantity'] );
108 + update_post_meta( $selected_subscription_id, '_subscrpt_price', $product->get_price() );
105 109 update_post_meta( $selected_subscription_id, '_subscrpt_user_cancel', $product->get_meta( '_subscrpt_user_cancel' ) );
106 110
107 111 // order related.
108 112 update_post_meta( $selected_subscription_id, '_subscrpt_order_id', $order_id );
@@ -150,14 +154,67 @@
150 154
151 155 /**
152 156 * Save renew meta
153 157 *
154 - * @param Object $item Item.
155 - * @param String $cart_item_key Cart Item Key.
156 - * @param Array $cart_item Cart Item.
158 + * @param object $item Item.
159 + * @param string $cart_item_key Cart Item Key.
160 + * @param array $cart_item Cart Item.
157 161 */
158 162 public function save_order_item_product_meta( $item, $cart_item_key, $cart_item ) {
159 163 if ( isset( $cart_item['renew_subscrpt'] ) ) {
160 164 $item->update_meta_data( '_renew_subscrpt', $cart_item['renew_subscrpt'] );
165 + }
166 +
167 + if ( ! empty( $cart_item['wp_subs_switch'] ?? null ) && ! empty( $cart_item['switch_context'] ?? null ) ) {
168 + $switch_context = $cart_item['switch_context'];
169 +
170 + // Add switch context data to order item meta.
171 + $item->update_meta_data( '_wp_subs_switch', true, true );
172 + $item->update_meta_data( '_wp_subs_switch_context', $switch_context, true );
173 + }
174 + }
175 +
176 + /**
177 + * Trigger subscription switch order created store API.
178 + *
179 + * @param \WC_Order $order Order.
180 + */
181 + public function trigger_subscription_switch_order_created_storeapi( $order ) {
182 + $this->trigger_subscription_switch_order_created( $order->get_id() ?? 0 );
183 + }
184 +
185 + /**
186 + * Trigger subscription switch order created.
187 + *
188 + * @param int $order_id Order ID.
189 + */
190 + public function trigger_subscription_switch_order_created( $order_id ) {
191 + if ( ! $order_id || ! subscrpt_pro_activated() ) {
192 + return;
193 + }
194 +
195 + $order = wc_get_order( $order_id );
196 + $order_items = $order->get_items();
197 +
198 + foreach ( $order_items as $order_item ) {
199 + $is_switch = in_array( $order_item->get_meta( '_wp_subs_switch' ), [ true, 1, '1' ], true );
200 + $switch_context = $order_item->get_meta( '_wp_subs_switch_context' );
201 +
202 + if ( $is_switch ) {
203 + $switch_type = $switch_context['switch_type'] ?? 'upgrade';
204 +
205 + unset( $switch_context['nonce'] );
206 + unset( $switch_context['redirect_back_url'] );
207 +
208 + /**
209 + * Action fired when subscription switch order is created.
210 + *
211 + * @param string $switch_type Switch type (upgrade/downgrade).
212 + * @param \WC_Order $order Order object.
213 + * @param \WC_Order_Item_Product $order_item Order Item object.
214 + * @param array $switch_context Switch context data. [ 'switch_type', 'subscription_id', 'order_id', 'product_id', 'old_variation_id', 'new_variation_id' ]
215 + */
216 + do_action( 'subscrpt_switch_order_created', $switch_type, $order, $order_item, $switch_context );
217 + }
161 218 }
162 219 }
163 220 }