PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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 / FrmStrpLiteLinkRedirectHelper.php

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

209 lines 5.1 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 * @since 6.5, introduced in v3.0 of the Stripe add on.
8 */
9 class FrmStrpLiteLinkRedirectHelper {
10
11 /**
12 * @var string Either a Payment Intent ID (prefixed with pi_) or a Setup Intent ID (prefixed with seti_).
13 */
14 private $stripe_id;
15
16 /**
17 * @var string
18 */
19 private $client_secret;
20
21 /**
22 * @var int|null The entry ID associated with the payment being handled.
23 */
24 private $entry_id;
25
26 /**
27 * @param string $stripe_id either a Payment Intent ID (prefixed with pi_) or a Setup Intent ID (prefixed with seti_).
28 * @param string $client_secret
29 *
30 * @return void
31 */
32 public function __construct( $stripe_id, $client_secret ) {
33 $this->stripe_id = $stripe_id;
34 $this->client_secret = $client_secret;
35 }
36
37 /**
38 * Set the entry ID to pull referer data from.
39 * This is separate from the constructor as the entry ID isn't known for some error cases.
40 *
41 * @param int|string $entry_id
42 *
43 * @return void
44 */
45 public function set_entry_id( $entry_id ) {
46 $this->entry_id = absint( $entry_id );
47 }
48
49 /**
50 * @param string $error_code
51 * @param string $charge_id
52 *
53 * @return void
54 */
55 public function handle_error( $error_code, $charge_id = '' ) {
56 if ( $this->entry_id ) {
57 $referer = FrmStrpLiteAuth::get_referer_url( $this->entry_id );
58 }
59
60 if ( empty( $referer ) ) {
61 $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
62 }
63
64 $args = array(
65 'frm_link_error' => $error_code,
66 );
67
68 if ( $charge_id ) {
69 $args['charge'] = $charge_id;
70 }
71
72 $this->add_intent_info_and_redirect(
73 add_query_arg( $args, $referer )
74 );
75 }
76
77 /**
78 * Redirect to handle the form's on success condition similar to how 3D secure is handled after being redirected.
79 *
80 * @param stdClass $entry
81 * @param string $charge_id
82 *
83 * @return void
84 */
85 public function handle_success( $entry, $charge_id ) {
86 $form = FrmForm::getOne( $entry->form_id );
87
88 // Let a stripe link success message get handled the same as a 3D secure redirect.
89 // When it shows a message, it adds a &frmstrp= param to the URL.
90 $redirect = FrmStrpLiteAuth::return_url( compact( 'form', 'entry' ) );
91 $is_message_redirect = str_contains( $redirect, 'frmstrp=' );
92
93 // Call this before all redirects so the referer is always deleted.
94 $referer_url = $this->get_referer_url( $entry->id );
95
96 if ( $this->url_is_external( $redirect ) || ! $is_message_redirect ) {
97 wp_redirect( $redirect );
98 die();
99 }
100
101 // $redirect may not include the whole link to the form, breaking the redirect as iDEAL/Sofort have an additional redirect.
102 if ( is_string( $referer_url ) ) {
103 $parts = explode( '?', $redirect, 2 );
104
105 if ( 2 === count( $parts ) ) {
106 $redirect = $parts[1];
107 }
108
109 $redirect = $referer_url . '?' . $redirect;
110 }
111
112 if ( $charge_id ) {
113 $redirect .= '&charge=' . $charge_id;
114 }
115
116 $this->add_intent_info_and_redirect( $redirect );
117 }
118
119 /**
120 * Determine if a redirect URL is going to an external site or not.
121 *
122 * @param string $url
123 *
124 * @return bool
125 */
126 private function url_is_external( $url ) {
127 if ( ! str_contains( $url, 'http' ) ) {
128 return false;
129 }
130
131 $home_url = home_url();
132 $parsed = parse_url( $home_url );
133
134 if ( is_array( $parsed ) ) {
135 $home_url = $parsed['scheme'] . '://' . $parsed['host'];
136 }
137
138 return ! str_starts_with( $url, $home_url );
139 }
140
141 /**
142 * Try to get the referer URL from the entry meta.
143 * If it is found, it will also be deleted as it is only required once.
144 *
145 * @param int|string $entry_id
146 *
147 * @return false|string
148 */
149 private function get_referer_url( $entry_id ) {
150 $row = FrmDb::get_row(
151 'frm_item_metas',
152 array(
153 'field_id' => 0,
154 'item_id' => $entry_id,
155 'meta_value LIKE' => '{"referer":',
156 ),
157 'id, meta_value'
158 );
159
160 if ( ! $row ) {
161 return false;
162 }
163
164 $meta = $row->meta_value;
165 $meta = json_decode( $meta, true );
166
167 if ( ! is_array( $meta ) || empty( $meta['referer'] ) ) {
168 return false;
169 }
170
171 self::delete_temporary_referer_meta( (int) $row->id );
172 return $meta['referer'];
173 }
174
175 /**
176 * Delete the referer meta as we'll no longer need it.
177 *
178 * @param int $row_id
179 *
180 * @return void
181 */
182 private static function delete_temporary_referer_meta( $row_id ) {
183 global $wpdb;
184 $wpdb->delete( $wpdb->prefix . 'frm_item_metas', array( 'id' => $row_id ) );
185 }
186
187 /**
188 * Redirect, have FrmStrpLiteAuth::maybe_show_message handle it similar to 3D secure.
189 *
190 * @param string $url
191 */
192 private function add_intent_info_and_redirect( $url ) {
193 if ( str_starts_with( $this->stripe_id, 'pi_' ) ) {
194 $url = add_query_arg( 'payment_intent', $this->stripe_id, $url );
195 $url = add_query_arg( 'payment_intent_client_secret', $this->client_secret, $url );
196 } else {
197 $url = add_query_arg( 'setup_intent', $this->stripe_id, $url );
198 $url = add_query_arg( 'setup_intent_client_secret', $this->client_secret, $url );
199 }
200
201 // iDeal redirects URLs are incorrectly encoded.
202 // This str_replace reverts that encoding issue.
203 $url = str_replace( '%3Ffrmstrp%3D', '&frmstrp=', $url );
204
205 wp_redirect( $url );
206 die();
207 }
208 }
209