PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.21
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.21
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
← All changes | classes/models/FrmFormApi.php +164 -22 6.56.21 View file →
@@ -4,16 +4,27 @@
4 4 }
5 5
6 6 class FrmFormApi {
7 7
8 + /**
9 + * @var string
10 + */
8 11 protected $license = '';
12 +
13 + /**
14 + * @var string
15 + */
9 16 protected $cache_key = '';
17 +
18 + /**
19 + * @var string
20 + */
10 21 protected $cache_timeout = '+6 hours';
11 22
12 23 /**
13 24 * The number of days an add-on is new.
14 25 *
15 - * @var int $new_days
26 + * @var int
16 27 */
17 28 protected $new_days = 90;
18 29
19 30 /**
@@ -78,8 +89,15 @@
78 89 if ( is_array( $addons ) ) {
79 90 return $addons;
80 91 }
81 92
93 + if ( $this->is_running() ) {
94 + // If there's no saved cache, we'll need to wait for the current request to finish.
95 + return array();
96 + }
97 +
98 + $this->set_running();
99 +
82 100 // We need to know the version number to allow different downloads.
83 101 $agent = 'formidable/' . FrmAppHelper::plugin_version();
84 102 if ( class_exists( 'FrmProDb' ) ) {
85 103 $agent = 'formidable-pro/' . FrmProDb::$plug_version;
@@ -100,8 +118,10 @@
100 118 if ( ! is_array( $addons ) ) {
101 119 $addons = array();
102 120 }
103 121
122 + $addons['response_code'] = wp_remote_retrieve_response_code( $response );
123 +
104 124 foreach ( $addons as $k => $addon ) {
105 125 if ( ! is_array( $addon ) ) {
106 126 continue;
107 127 }
@@ -119,18 +139,85 @@
119 139 }
120 140 }
121 141
122 142 $this->set_cached( $addons );
143 + $this->done_running();
123 144
124 145 return $addons;
125 146 }
126 147
127 148 /**
149 + * Prevent multiple requests from running at the same time.
150 + *
151 + * @since 6.8.3
152 + *
153 + * @return bool
154 + */
155 + protected function is_running() {
156 + if ( $this->run_as_multisite() ) {
157 + return get_site_transient( $this->transient_key() );
158 + }
159 + return get_transient( $this->transient_key() );
160 + }
161 +
162 + /**
163 + * @since 6.8.3
164 + *
165 + * @return void
166 + */
167 + protected function set_running() {
168 + $expires = 2 * MINUTE_IN_SECONDS;
169 + if ( $this->run_as_multisite() ) {
170 + set_site_transient( $this->transient_key(), true, $expires );
171 + return;
172 + }
173 +
174 + set_transient( $this->transient_key(), true, $expires );
175 + }
176 +
177 + /**
178 + * @since 6.8.3
179 + *
180 + * @return void
181 + */
182 + protected function done_running() {
183 + if ( $this->run_as_multisite() ) {
184 + delete_site_transient( $this->transient_key() );
185 + }
186 + delete_transient( $this->transient_key() );
187 + }
188 +
189 + /**
190 + * Only allow one site in the network to make the api request at a time.
191 + * If there is a license for the request, run individually.
192 + *
193 + * @since 6.8.3
194 + *
195 + * @return bool
196 + */
197 + protected function run_as_multisite() {
198 + return is_multisite() && empty( $this->license );
199 + }
200 +
201 + /**
202 + * @since 6.8.3
203 + *
204 + * @return string
205 + */
206 + protected function transient_key() {
207 + return strtolower( __CLASS__ ) . '_request_lock';
208 + }
209 +
210 + /**
128 211 * @since 3.06
129 212 *
130 213 * @return string
131 214 */
132 215 protected function api_url() {
216 + if ( empty( $this->license ) ) {
217 + // Direct traffic to Cloudflare worker when there is no license.
218 + return 'https://plapi.formidableforms.com/list/';
219 + }
133 220 return 'https://formidableforms.com/wp-json/s11edd/v1/updates/';
134 221 }
135 222
136 223 /**
@@ -144,10 +231,10 @@
144 231
145 232 /**
146 233 * @since 3.06
147 234 *
148 - * @param object $license_plugin The FrmAddon object
149 - * @param array $addons
235 + * @param object $license_plugin The FrmAddon object.
236 + * @param array $addons
150 237 *
151 238 * @return array
152 239 */
153 240 public function get_addon_for_license( $license_plugin, $addons = array() ) {
@@ -157,9 +244,9 @@
157 244 $download_id = $license_plugin->download_id;
158 245 $plugin = array();
159 246 if ( empty( $download_id ) && ! empty( $addons ) ) {
160 247 foreach ( $addons as $addon ) {
161 - if ( strtolower( $license_plugin->plugin_name ) == strtolower( $addon['title'] ) ) {
248 + if ( is_array( $addon ) && ! empty( $addon['title'] ) && strtolower( $license_plugin->plugin_name ) === strtolower( $addon['title'] ) ) {
162 249 return $addon;
163 250 }
164 251 }
165 252 } elseif ( isset( $addons[ $download_id ] ) ) {
@@ -184,27 +271,53 @@
184 271 }
185 272
186 273 /**
187 274 * @since 3.06
188 - * @return array
275 + *
276 + * @return array|bool
189 277 */
190 278 protected function get_cached() {
191 - $cache = get_option( $this->cache_key );
279 + $cache = $this->get_cached_option();
280 + if ( empty( $cache ) ) {
281 + return false;
282 + }
192 283
193 - FrmAppHelper::filter_gmt_offset();
284 + // If the api call is running, we can use the expired cache.
285 + if ( ! $this->is_running() ) {
286 + if ( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
287 + // Cache is expired.
288 + return false;
289 + }
194 290
195 - if ( empty( $cache ) || empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) {
196 - return false; // Cache is expired
291 + $version = FrmAppHelper::plugin_version();
292 + $for_current = isset( $cache['version'] ) && $cache['version'] == $version;
293 + if ( ! $for_current ) {
294 + // Force a new check.
295 + return false;
296 + }
197 297 }
198 298
199 - $version = FrmAppHelper::plugin_version();
200 - $for_current = isset( $cache['version'] ) && $cache['version'] == $version;
201 - if ( ! $for_current ) {
202 - // Force a new check.
203 - return false;
299 + $values = json_decode( $cache['value'], true );
300 +
301 + return $values;
302 + }
303 +
304 + /**
305 + * Get the cache for the network if multisite.
306 + *
307 + * @since 6.8.3
308 + *
309 + * @return mixed
310 + */
311 + protected function get_cached_option() {
312 + if ( is_multisite() ) {
313 + $cached = get_site_option( $this->cache_key );
314 + if ( $cached ) {
315 + return $cached;
316 + }
204 317 }
205 318
206 - return json_decode( $cache['value'], true );
319 + return get_option( $this->cache_key );
207 320 }
208 321
209 322 /**
210 323 * @since 3.06
@@ -213,26 +326,50 @@
213 326 *
214 327 * @return void
215 328 */
216 329 protected function set_cached( $addons ) {
217 - FrmAppHelper::filter_gmt_offset();
218 -
219 330 $data = array(
220 - 'timeout' => strtotime( $this->cache_timeout, current_time( 'timestamp' ) ),
221 - 'value' => json_encode( $addons ),
331 + 'timeout' => strtotime( $this->get_cache_timeout( $addons ), time() ),
332 + 'value' => wp_json_encode( $addons ),
222 333 'version' => FrmAppHelper::plugin_version(),
223 334 );
224 335
225 - update_option( $this->cache_key, $data, 'no' );
336 + if ( is_multisite() ) {
337 + update_site_option( $this->cache_key, $data );
338 + } else {
339 + update_option( $this->cache_key, $data, 'no' );
340 + }
226 341 }
227 342
228 343 /**
344 + * If the last check was a a rate limit, we'll need to check again sooner.
345 + *
346 + * @since 6.8.3
347 + *
348 + * @param array $addons
349 + *
350 + * @return string
351 + */
352 + protected function get_cache_timeout( $addons ) {
353 + $timeout = $this->cache_timeout;
354 + if ( isset( $addons['response_code'] ) && 429 === $addons['response_code'] ) {
355 + $timeout = '+5 minutes';
356 + }
357 + return $timeout;
358 + }
359 +
360 + /**
229 361 * @since 3.06
230 362 *
231 363 * @return void
232 364 */
233 365 public function reset_cached() {
234 - delete_option( $this->cache_key );
366 + if ( is_multisite() ) {
367 + delete_site_option( $this->cache_key );
368 + } else {
369 + delete_option( $this->cache_key );
370 + }
371 + $this->done_running();
235 372 }
236 373
237 374 /**
238 375 * @since 3.06
@@ -256,9 +393,14 @@
256 393 $addons = $this->get_api_info();
257 394 }
258 395 $errors = array();
259 396 if ( isset( $addons['error'] ) ) {
260 - $errors[] = $addons['error']['message'];
397 + if ( is_string( $addons['error'] ) ) {
398 + $errors[] = $addons['error'];
399 + } elseif ( ! empty( $addons['error']['message'] ) ) {
400 + $errors[] = $addons['error']['message'];
401 + }
402 +
261 403 do_action( 'frm_license_error', $addons['error'] );
262 404 }
263 405
264 406 return $errors;