PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.8.3
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.8.3
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 / classes / models / FrmFormApi.php

FrmFormApi.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.8.3, at classes/models/FrmFormApi.php

405 lines 8.2 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 class FrmFormApi {
7
8 protected $license = '';
9 protected $cache_key = '';
10 protected $cache_timeout = '+6 hours';
11
12 /**
13 * The number of days an add-on is new.
14 *
15 * @var int $new_days
16 */
17 protected $new_days = 90;
18
19 /**
20 * @since 3.06
21 */
22 public function __construct( $license = null ) {
23 $this->set_license( $license );
24 $this->set_cache_key();
25 }
26
27 /**
28 * @since 3.06
29 *
30 * @return void
31 */
32 private function set_license( $license ) {
33 if ( $license === null ) {
34 $edd_update = $this->get_pro_updater();
35 if ( ! empty( $edd_update ) ) {
36 $license = $edd_update->license;
37 }
38 }
39 $this->license = $license;
40 }
41
42 /**
43 * @since 3.06
44 * @return string
45 */
46 public function get_license() {
47 return $this->license;
48 }
49
50 /**
51 * @since 3.06
52 *
53 * @return void
54 */
55 protected function set_cache_key() {
56 $this->cache_key = 'frm_addons_l' . ( empty( $this->license ) ? '' : md5( $this->license ) );
57 }
58
59 /**
60 * @since 3.06
61 * @return string
62 */
63 public function get_cache_key() {
64 return $this->cache_key;
65 }
66
67 /**
68 * @since 3.06
69 * @return array
70 */
71 public function get_api_info() {
72 $url = $this->api_url();
73 if ( ! empty( $this->license ) ) {
74 $url .= '?l=' . urlencode( base64_encode( $this->license ) );
75 }
76
77 $addons = $this->get_cached();
78 if ( is_array( $addons ) ) {
79 return $addons;
80 }
81
82 if ( $this->is_running() ) {
83 // If there's no saved cache, we'll need to wait for the current request to finish.
84 return array();
85 }
86
87 $this->set_running();
88
89 // We need to know the version number to allow different downloads.
90 $agent = 'formidable/' . FrmAppHelper::plugin_version();
91 if ( class_exists( 'FrmProDb' ) ) {
92 $agent = 'formidable-pro/' . FrmProDb::$plug_version;
93 }
94
95 $response = wp_remote_get(
96 $url,
97 array(
98 'timeout' => 25,
99 'user-agent' => $agent . '; ' . get_bloginfo( 'url' ),
100 )
101 );
102
103 if ( is_array( $response ) && ! is_wp_error( $response ) ) {
104 $addons = $response['body'] ? json_decode( $response['body'], true ) : array();
105 }
106
107 if ( ! is_array( $addons ) ) {
108 $addons = array();
109 }
110
111 $addons['response_code'] = wp_remote_retrieve_response_code( $response );
112
113 foreach ( $addons as $k => $addon ) {
114 if ( ! is_array( $addon ) ) {
115 continue;
116 }
117
118 if ( isset( $addon['categories'] ) ) {
119 $cats = array_intersect( $this->skip_categories(), $addon['categories'] );
120 if ( ! empty( $cats ) ) {
121 unset( $addons[ $k ] );
122 continue;
123 }
124 }
125
126 if ( ! array_key_exists( 'is_new', $addon ) && array_key_exists( 'released', $addon ) ) {
127 $addons[ $k ]['is_new'] = $this->is_new( $addon );
128 }
129 }
130
131 $this->set_cached( $addons );
132 $this->done_running();
133
134 return $addons;
135 }
136
137 /**
138 * Prevent multiple requests from running at the same time.
139 *
140 * @since 6.8.3
141 *
142 * @return bool
143 */
144 protected function is_running() {
145 if ( $this->run_as_multisite() ) {
146 return get_site_transient( $this->transient_key() );
147 }
148 return get_transient( $this->transient_key() );
149 }
150
151 /**
152 * @since 6.8.3
153 *
154 * @return void
155 */
156 protected function set_running() {
157 $expires = 2 * MINUTE_IN_SECONDS;
158 if ( $this->run_as_multisite() ) {
159 set_site_transient( $this->transient_key(), true, $expires );
160 return;
161 }
162
163 set_transient( $this->transient_key(), true, $expires );
164 }
165
166 /**
167 * @since 6.8.3
168 *
169 * @return void
170 */
171 protected function done_running() {
172 if ( $this->run_as_multisite() ) {
173 delete_site_transient( $this->transient_key() );
174 }
175 delete_transient( $this->transient_key() );
176 }
177
178 /**
179 * Only allow one site in the network to make the api request at a time.
180 * If there is a license for the request, run individually.
181 *
182 * @since 6.8.3
183 *
184 * @return bool
185 */
186 protected function run_as_multisite() {
187 return is_multisite() && empty( $this->license );
188 }
189
190 /**
191 * @since 6.8.3
192 *
193 * @return string
194 */
195 protected function transient_key() {
196 return strtolower( __CLASS__ ) . '_request_lock';
197 }
198
199 /**
200 * @since 3.06
201 *
202 * @return string
203 */
204 protected function api_url() {
205 return 'https://formidableforms.com/wp-json/s11edd/v1/updates/';
206 }
207
208 /**
209 * @since 3.06
210 *
211 * @return string[]
212 */
213 protected function skip_categories() {
214 return array( 'WordPress Form Templates', 'WordPress Form Style Templates' );
215 }
216
217 /**
218 * @since 3.06
219 *
220 * @param object $license_plugin The FrmAddon object.
221 * @param array $addons
222 *
223 * @return array
224 */
225 public function get_addon_for_license( $license_plugin, $addons = array() ) {
226 if ( empty( $addons ) ) {
227 $addons = $this->get_api_info();
228 }
229 $download_id = $license_plugin->download_id;
230 $plugin = array();
231 if ( empty( $download_id ) && ! empty( $addons ) ) {
232 foreach ( $addons as $addon ) {
233 if ( is_array( $addon ) && ! empty( $addon['title'] ) && strtolower( $license_plugin->plugin_name ) === strtolower( $addon['title'] ) ) {
234 return $addon;
235 }
236 }
237 } elseif ( isset( $addons[ $download_id ] ) ) {
238 $plugin = $addons[ $download_id ];
239 }
240
241 return $plugin;
242 }
243
244 /**
245 * @since 3.06
246 */
247 public function get_pro_updater() {
248 if ( FrmAppHelper::pro_is_installed() && is_callable( 'FrmProAppHelper::get_updater' ) ) {
249 $updater = FrmProAppHelper::get_updater();
250 $this->set_license( $updater->license );
251
252 return $updater;
253 }
254
255 return false;
256 }
257
258 /**
259 * @since 3.06
260 *
261 * @return array|bool
262 */
263 protected function get_cached() {
264 $cache = $this->get_cached_option();
265 if ( empty( $cache ) ) {
266 return false;
267 }
268
269 // If the api call is running, we can use the expired cache.
270 if ( ! $this->is_running() ) {
271 if ( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
272 // Cache is expired.
273 return false;
274 }
275
276 $version = FrmAppHelper::plugin_version();
277 $for_current = isset( $cache['version'] ) && $cache['version'] == $version;
278 if ( ! $for_current ) {
279 // Force a new check.
280 return false;
281 }
282 }
283
284 $values = json_decode( $cache['value'], true );
285
286 return $values;
287 }
288
289 /**
290 * Get the cache for the network if multisite.
291 *
292 * @since 6.8.3
293 *
294 * @return mixed
295 */
296 protected function get_cached_option() {
297 if ( is_multisite() ) {
298 $cached = get_site_option( $this->cache_key );
299 if ( $cached ) {
300 return $cached;
301 }
302 }
303
304 return get_option( $this->cache_key );
305 }
306
307 /**
308 * @since 3.06
309 *
310 * @param array $addons
311 *
312 * @return void
313 */
314 protected function set_cached( $addons ) {
315 $data = array(
316 'timeout' => strtotime( $this->get_cache_timeout( $addons ), time() ),
317 'value' => wp_json_encode( $addons ),
318 'version' => FrmAppHelper::plugin_version(),
319 );
320
321 if ( is_multisite() ) {
322 update_site_option( $this->cache_key, $data );
323 } else {
324 update_option( $this->cache_key, $data, 'no' );
325 }
326 }
327
328 /**
329 * If the last check was a a rate limit, we'll need to check again sooner.
330 *
331 * @since 6.8.3
332 *
333 * @param array $addons
334 *
335 * @return string
336 */
337 protected function get_cache_timeout( $addons ) {
338 $timeout = $this->cache_timeout;
339 if ( isset( $addons['response_code'] ) && 429 === $addons['response_code'] ) {
340 $timeout = '+5 minutes';
341 }
342 return $timeout;
343 }
344
345 /**
346 * @since 3.06
347 *
348 * @return void
349 */
350 public function reset_cached() {
351 if ( is_multisite() ) {
352 delete_site_option( $this->cache_key );
353 } else {
354 delete_option( $this->cache_key );
355 }
356 }
357
358 /**
359 * @since 3.06
360 * @return array
361 */
362 public function error_for_license() {
363 $errors = array();
364 if ( ! empty( $this->license ) ) {
365 $errors = $this->get_error_from_response();
366 }
367
368 return $errors;
369 }
370
371 /**
372 * @since 3.06
373 * @return array
374 */
375 public function get_error_from_response( $addons = array() ) {
376 if ( empty( $addons ) ) {
377 $addons = $this->get_api_info();
378 }
379 $errors = array();
380 if ( isset( $addons['error'] ) ) {
381 if ( is_string( $addons['error'] ) ) {
382 $errors[] = $addons['error'];
383 } elseif ( ! empty( $addons['error']['message'] ) ) {
384 $errors[] = $addons['error']['message'];
385 }
386
387 do_action( 'frm_license_error', $addons['error'] );
388 }
389
390 return $errors;
391 }
392
393 /**
394 * Check if a template is new.
395 *
396 * @since 6.0
397 *
398 * @param array $addon
399 * @return bool
400 */
401 protected function is_new( $addon ) {
402 return strtotime( $addon['released'] ) > strtotime( '-' . $this->new_days . ' days' );
403 }
404 }
405