PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.33
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.33
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.33, at stripe/helpers/FrmStrpLiteSubscriptionHelper.php

261 lines 7.6 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 *
18 * @param object $subscription A Stripe Subscription object.
19 * @param string $amount
20 *
21 * @return stdClass
22 */
23 public static function prepare_charge_object_for_subscription( $subscription, $amount ) {
24 $charge_object = new stdClass();
25 $charge_object->sub_id = $subscription->id;
26 $charge_object->id = null;
27 $charge_object->amount = $amount;
28 $charge_object->current_period_start = $subscription->current_period_start;
29 $charge_object->current_period_end = $subscription->current_period_end;
30 return $charge_object;
31 }
32
33 /**
34 * Create a Formidable subscription object with the nested payments submodule.
35 *
36 * @since 6.5
37 *
38 * @param array $atts
39 *
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' => $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
65 if ( is_int( $end_count ) ) {
66 $new_values['end_count'] = $end_count;
67 }
68 }
69
70 $frm_sub = new FrmTransLiteSubscription();
71 return $frm_sub->create( $new_values );
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 *
86 * @return false|string Plan id.
87 */
88 public static function get_plan_from_atts( $atts ) {
89 $action = $atts['action'];
90 $action->post_content['amount'] = $atts['amount'];
91 return self::get_plan_for_action( $action );
92 }
93
94 /**
95 * @since 6.5
96 *
97 * @param WP_Post $action
98 *
99 * @return false|string
100 */
101 private static function get_plan_for_action( $action ) {
102 $plan_id = $action->post_content['plan_id'];
103
104 if ( $plan_id ) {
105 return $plan_id;
106 }
107
108 // The amount has already been formatted, so add the decimal back in.
109 $amount = $action->post_content['amount'];
110 $action->post_content['amount'] = number_format( $amount / 100, 2, '.', '' );
111 $plan_opts = self::prepare_plan_options( $action->post_content );
112 return self::maybe_create_plan( $plan_opts );
113 }
114
115 /**
116 * @since 6.5
117 *
118 * @param array $settings
119 *
120 * @return array
121 */
122 public static function prepare_plan_options( $settings ) {
123 $amount = FrmStrpLiteActionsController::prepare_amount( $settings['amount'], $settings );
124 $default_description = number_format( $amount / 100, 2 ) . '/' . $settings['interval'];
125 $plan_opts = array(
126 'amount' => $amount,
127 'interval' => $settings['interval'],
128 'interval_count' => $settings['interval_count'],
129 'currency' => $settings['currency'],
130 'name' => ! empty( $settings['description'] ) ? $settings['description'] : $default_description,
131 );
132
133 if ( ! empty( $settings['trial_interval_count'] ) ) {
134 $plan_opts['trial_period_days'] = self::get_trial_with_default( $settings['trial_interval_count'] );
135 }
136
137 $plan_opts['id'] = FrmStrpLiteActionsController::create_plan_id( $settings );
138
139 return $plan_opts;
140 }
141
142 /**
143 * @since 3.0 This was moved from FrmStrpLiteActionsController.
144 *
145 * @param array $plan
146 *
147 * @return mixed
148 */
149 public static function maybe_create_plan( $plan ) {
150 FrmStrpLiteAppHelper::call_stripe_helper_class( 'initialize_api' );
151 return FrmStrpLiteAppHelper::call_stripe_helper_class( 'maybe_create_plan', $plan );
152 }
153
154 /**
155 * Since the trial period can come from an entry, use a default value
156 * when creating the plan. This is overridden when the subscription
157 * is created.
158 *
159 * @since 6.5
160 *
161 * @param mixed $trial
162 *
163 * @return int
164 */
165 private static function get_trial_with_default( $trial ) {
166 if ( ! is_numeric( $trial ) ) {
167 // Use 0 as this is only ever overwritten when it is non-zero.
168 $trial = 0;
169 }
170 return absint( $trial );
171 }
172
173 /**
174 * If a subscription fails because the plan does not exist, create the plan and try again.
175 *
176 * @since 6.5.1
177 *
178 * @param false|object|string $subscription
179 * @param array $charge_data
180 * @param WP_Post $action
181 * @param int $amount
182 *
183 * @return false|object|string
184 */
185 public static function maybe_create_missing_plan_and_create_subscription( $subscription, $charge_data, $action, $amount ) {
186 if ( ! is_string( $subscription ) || ! str_starts_with( $subscription, 'No such plan: ' ) ) {
187 // Only retry when there is a No such plan string error.
188 return $subscription;
189 }
190
191 // The full error message looks like "No such plan: '_399_1month_usd".
192 $action->post_content['plan_id'] = '';
193 $charge_data['plan'] = self::get_plan_from_atts( compact( 'action', 'amount' ) );
194 return FrmStrpLiteAppHelper::call_stripe_helper_class( 'create_subscription', $charge_data );
195 }
196
197 /**
198 * When this is filtered and returns false, the subscription will be canceled immediately instead.
199 *
200 * @since 6.8
201 *
202 * @return bool
203 */
204 public static function should_cancel_at_period_end() {
205 /**
206 * @param bool $cancel_at_period_end
207 */
208 return (bool) apply_filters( 'frm_stripe_cancel_subscription_at_period_end', true );
209 }
210
211 /**
212 * Get an end_count value to use for our subscription.
213 *
214 * @since 6.11
215 *
216 * @param string $payment_limit The raw payment value string. It is not empty.
217 * @param int $form_id Required for processing shortcodes.
218 * @param int $entry_id Required for processing shortcodes.
219 *
220 * @return int|WP_Error
221 */
222 public static function prepare_payment_limit( $payment_limit, $form_id, $entry_id ) {
223 if ( is_numeric( $payment_limit ) ) {
224 return (int) $payment_limit;
225 }
226
227 if ( ! str_contains( $payment_limit, '[' ) ) {
228 return self::get_invalid_payment_limit_error( $payment_limit );
229 }
230
231 $payment_limit = FrmTransLiteAppHelper::process_shortcodes(
232 array(
233 'value' => $payment_limit,
234 'form' => $form_id,
235 'entry' => $entry_id,
236 )
237 );
238
239 if ( ! is_numeric( $payment_limit ) ) {
240 return self::get_invalid_payment_limit_error( $payment_limit );
241 }
242
243 return (int) $payment_limit;
244 }
245
246 /**
247 * @since 6.11
248 *
249 * @param string $payment_limit
250 *
251 * @return WP_Error
252 */
253 private static function get_invalid_payment_limit_error( $payment_limit ) {
254 return new WP_Error(
255 'invalid_payment_limit',
256 /* translators: %s: Invalid payment limit value title */
257 sprintf( __( 'Invalid payment limit value %s', 'formidable' ), $payment_limit )
258 );
259 }
260 }
261