PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.19
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.19
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / stripe / helpers / FrmStrpLiteSubscriptionHelper.php

FrmStrpLiteSubscriptionHelper.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.19, at stripe/helpers/FrmStrpLiteSubscriptionHelper.php

250 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 /**
7 * Handles shared Stripe subscription logic between FrmStrpLiteActionsController and FrmStrpLiteLinkController.
8 *
9 * @since 6.5, introduced in v3.0 of the Stripe add on.
10 */
11 class FrmStrpLiteSubscriptionHelper {
12
13 /**
14 * Prepare a charge object for a Stripe subscription.
15 *
16 * @since 6.5, introduced in v3.0 of the Stripe add on.
17 * @todo I removed the $charge_object->paid = false; line from here is it isn't required for Stripe link.
18 * Make sure that if/when we re-use this in Stripe that we still include that.
19 *
20 * @param object $subscription A Stripe Subscription object.
21 * @param string $amount
22 * @return stdClass
23 */
24 public static function prepare_charge_object_for_subscription( $subscription, $amount ) {
25 $charge_object = new stdClass();
26 $charge_object->sub_id = $subscription->id;
27 $charge_object->id = null;
28 $charge_object->amount = $amount;
29 $charge_object->current_period_start = $subscription->current_period_start;
30 $charge_object->current_period_end = $subscription->current_period_end;
31 return $charge_object;
32 }
33
34 /**
35 * Create a Formidable subscription object with the nested payments submodule.
36 *
37 * @since 6.5
38 *
39 * @param array $atts
40 * @return int|string $sub_id
41 */
42 public static function create_new_subscription( $atts ) {
43 $atts['charge'] = (object) $atts['charge'];
44
45 $new_values = array(
46 'amount' => FrmTransLiteAppHelper::get_formatted_amount_for_currency( $atts['charge']->amount, $atts['action'] ),
47 'paysys' => 'stripe',
48 'item_id' => $atts['entry']->id,
49 'action_id' => $atts['action']->ID,
50 'sub_id' => isset( $atts['charge']->sub_id ) ? $atts['charge']->sub_id : '',
51 'interval_count' => $atts['action']->post_content['interval_count'],
52 'time_interval' => $atts['action']->post_content['interval'],
53 'status' => 'active',
54 'next_bill_date' => gmdate( 'Y-m-d' ),
55 'test' => 'test' === FrmStrpLiteAppHelper::active_mode() ? 1 : 0,
56 );
57
58 if ( ! empty( $atts['action']->post_content['payment_limit'] ) ) {
59 $end_count = self::prepare_payment_limit(
60 $atts['action']->post_content['payment_limit'],
61 (int) $atts['entry']->form_id,
62 (int) $atts['entry']->id
63 );
64 if ( is_int( $end_count ) ) {
65 $new_values['end_count'] = $end_count;
66 }
67 }
68
69 $frm_sub = new FrmTransLiteSubscription();
70 $sub_id = $frm_sub->create( $new_values );
71 return $sub_id;
72 }
73
74 /**
75 * Get a plan for Stripe subscription.
76 *
77 * @since 6.5, introduced in v3.0 of the Stripe add on.
78 *
79 * @param array $atts {
80 * The plan details.
81 *
82 * @type WP_Post $action
83 * @type string $amount
84 * }
85 * @return string Plan id.
86 */
87 public static function get_plan_from_atts( $atts ) {
88 $action = $atts['action'];
89 $action->post_content['amount'] = $atts['amount'];
90 return self::get_plan_for_action( $action );
91 }
92
93 /**
94 * @since 6.5
95 *
96 * @param WP_Post $action
97 * @return false|string
98 */
99 private static function get_plan_for_action( $action ) {
100 $plan_id = $action->post_content['plan_id'];
101 if ( ! $plan_id ) {
102 // The amount has already been formatted, so add the decimal back in.
103 $amount = $action->post_content['amount'];
104 $action->post_content['amount'] = number_format( $amount / 100, 2, '.', '' );
105 $plan_opts = self::prepare_plan_options( $action->post_content );
106 $plan_id = self::maybe_create_plan( $plan_opts );
107 }
108 return $plan_id;
109 }
110
111 /**
112 * @since 6.5
113 *
114 * @param array $settings
115 * @return array
116 */
117 public static function prepare_plan_options( $settings ) {
118 $amount = FrmStrpLiteActionsController::prepare_amount( $settings['amount'], $settings );
119 $default_description = number_format( $amount / 100, 2 ) . '/' . $settings['interval'];
120 $plan_opts = array(
121 'amount' => $amount,
122 'interval' => $settings['interval'],
123 'interval_count' => $settings['interval_count'],
124 'currency' => $settings['currency'],
125 'name' => empty( $settings['description'] ) ? $default_description : $settings['description'],
126 );
127
128 if ( ! empty( $settings['trial_interval_count'] ) ) {
129 $plan_opts['trial_period_days'] = self::get_trial_with_default( $settings['trial_interval_count'] );
130 }
131
132 $plan_opts['id'] = FrmStrpLiteActionsController::create_plan_id( $settings );
133
134 return $plan_opts;
135 }
136
137 /**
138 * @since 3.0 This was moved from FrmStrpLiteActionsController.
139 *
140 * @param array $plan
141 * @return mixed
142 */
143 public static function maybe_create_plan( $plan ) {
144 FrmStrpLiteAppHelper::call_stripe_helper_class( 'initialize_api' );
145 return FrmStrpLiteAppHelper::call_stripe_helper_class( 'maybe_create_plan', $plan );
146 }
147
148 /**
149 * Since the trial period can come from an entry, use a default value
150 * when creating the plan. This is overridden when the subscription
151 * is created.
152 *
153 * @since 6.5
154 *
155 * @param mixed $trial
156 * @return int
157 */
158 private static function get_trial_with_default( $trial ) {
159 if ( ! is_numeric( $trial ) ) {
160 $trial = 1;
161 }
162 return absint( $trial );
163 }
164
165 /**
166 * If a subscription fails because the plan does not exist, create the plan and try again.
167 *
168 * @since 6.5.1
169 *
170 * @param false|object|string $subscription
171 * @param array $charge_data
172 * @param WP_Post $action
173 * @param int $amount
174 * @return false|object|string
175 */
176 public static function maybe_create_missing_plan_and_create_subscription( $subscription, $charge_data, $action, $amount ) {
177 if ( ! is_string( $subscription ) || 0 !== strpos( $subscription, 'No such plan: ' ) ) {
178 // Only retry when there is a No such plan string error.
179 return $subscription;
180 }
181
182 // The full error message looks like "No such plan: '_399_1month_usd".
183 $action->post_content['plan_id'] = '';
184 $charge_data['plan'] = self::get_plan_from_atts( compact( 'action', 'amount' ) );
185 $subscription = FrmStrpLiteAppHelper::call_stripe_helper_class( 'create_subscription', $charge_data );
186 return $subscription;
187 }
188
189 /**
190 * When this is filtered and returns false, the subscription will be canceled immediately instead.
191 *
192 * @since 6.8
193 *
194 * @return bool
195 */
196 public static function should_cancel_at_period_end() {
197 /**
198 * @param bool $cancel_at_period_end
199 */
200 return (bool) apply_filters( 'frm_stripe_cancel_subscription_at_period_end', true );
201 }
202
203 /**
204 * Get an end_count value to use for our subscription.
205 *
206 * @since 6.11
207 *
208 * @param string $payment_limit The raw payment value string. It is not empty.
209 * @param int $form_id Required for processing shortcodes.
210 * @param int $entry_id Required for processing shortcodes.
211 * @return int|WP_Error
212 */
213 public static function prepare_payment_limit( $payment_limit, $form_id, $entry_id ) {
214 if ( is_numeric( $payment_limit ) ) {
215 return (int) $payment_limit;
216 }
217
218 if ( false === strpos( $payment_limit, '[' ) ) {
219 return self::get_invalid_payment_limit_error( $payment_limit );
220 }
221
222 $payment_limit = FrmTransLiteAppHelper::process_shortcodes(
223 array(
224 'value' => $payment_limit,
225 'form' => $form_id,
226 'entry' => $entry_id,
227 )
228 );
229 if ( ! is_numeric( $payment_limit ) ) {
230 return self::get_invalid_payment_limit_error( $payment_limit );
231 }
232
233 return (int) $payment_limit;
234 }
235
236 /**
237 * @since 6.11
238 *
239 * @param string $payment_limit
240 * @return WP_Error
241 */
242 private static function get_invalid_payment_limit_error( $payment_limit ) {
243 return new WP_Error(
244 'invalid_payment_limit',
245 /* translators: %s: Invalid payment limit value title */
246 sprintf( __( 'Invalid payment limit value %s', 'formidable' ), $payment_limit )
247 );
248 }
249 }
250