PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.8
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.8
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/controllers/FrmAddonsController.php +504 -542 6.33.16.8 View file →
@@ -5,97 +5,15 @@
5 5
6 6 class FrmAddonsController {
7 7
8 8 /**
9 - * @var string
9 + * @var string $plugin
10 10 */
11 - const SCRIPT_HANDLE = 'frm-addons-page';
12 -
13 - /**
14 - * @var array
15 - */
16 - private static $categories = array();
17 -
18 - /**
19 - * @var string
20 - */
21 - private static $request_addon_url;
22 -
23 - /**
24 - * @var string
25 - */
26 11 protected static $plugin;
27 12
28 13 /**
29 - * @since 6.15
30 - *
31 14 * @return void
32 15 */
33 - public static function load_admin_hooks() {
34 - add_action( 'admin_menu', self::class . '::menu', 100 );
35 - add_filter( 'pre_set_site_transient_update_plugins', self::class . '::check_update' );
36 -
37 - if ( ! FrmAppHelper::is_admin_page( 'formidable-addons' ) ) {
38 - return;
39 - }
40 -
41 - self::$request_addon_url = 'https://connect.formidableforms.com/add-on-request/';
42 -
43 - add_action( 'admin_enqueue_scripts', self::class . '::enqueue_assets', 15 );
44 - add_filter( 'frm_show_footer_links', '__return_false' );
45 - }
46 -
47 - /**
48 - * Enqueues the Add-Ons page scripts and styles.
49 - *
50 - * @since 6.15
51 - *
52 - * @return void
53 - */
54 - public static function enqueue_assets() {
55 - $plugin_url = FrmAppHelper::plugin_url();
56 - $version = FrmAppHelper::plugin_version();
57 - $js_dependencies = array(
58 - 'wp-i18n',
59 - // This prevents a console error "wp.hooks is undefined" in WP versions older than 5.7.
60 - 'wp-hooks',
61 - 'formidable_dom',
62 - );
63 -
64 - // Enqueue styles that needed.
65 - wp_enqueue_style( 'formidable-admin' );
66 - wp_enqueue_style( 'formidable-grids' );
67 -
68 - // Register and enqueue Add-Ons page style.
69 - wp_register_style( self::SCRIPT_HANDLE, $plugin_url . '/css/admin/addons-page.css', array(), $version );
70 - wp_enqueue_style( self::SCRIPT_HANDLE );
71 -
72 - // Register and enqueue Add-Ons page script.
73 - wp_register_script( self::SCRIPT_HANDLE, $plugin_url . '/js/addons-page.js', $js_dependencies, $version, true );
74 - wp_localize_script( self::SCRIPT_HANDLE, 'frmAddonsVars', self::get_js_variables() );
75 - wp_enqueue_script( self::SCRIPT_HANDLE );
76 - wp_set_script_translations( self::SCRIPT_HANDLE, 'formidable' );
77 -
78 - FrmAppHelper::dequeue_extra_global_scripts();
79 - }
80 -
81 - /**
82 - * Get the Add-Ons page JS variables as an array.
83 - *
84 - * @since 6.15
85 - *
86 - * @return array
87 - */
88 - private static function get_js_variables() {
89 - return array(
90 - 'proIsIncluded' => FrmAppHelper::pro_is_included(),
91 - 'addonRequestURL' => self::$request_addon_url,
92 - );
93 - }
94 -
95 - /**
96 - * @return void
97 - */
98 16 public static function menu() {
99 17 if ( ! current_user_can( 'activate_plugins' ) ) {
100 18 return;
101 19 }
@@ -100,37 +18,28 @@
100 18 return;
101 19 }
102 20
103 21 $label = __( 'Add-Ons', 'formidable' );
104 - $label = '<span style="color:#3FCA89">' . esc_html( $label ) . '</span>';
22 + $label = '<span style="color:#1da867">' . $label . '</span>';
105 23
106 24 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
107 25
108 - // Remove default created subpage, make the page with highest priority as default.
26 + // remove default created subpage, make the page with highest priority as default.
109 27 remove_submenu_page( 'formidable', 'formidable' );
110 28
111 29 if ( ! FrmAppHelper::pro_is_installed() ) {
112 - $cta_text = FrmSalesApi::get_best_sale_value( 'menu_cta_text' );
113 -
114 - if ( ! $cta_text ) {
115 - $cta_text = __( 'Upgrade', 'formidable' );
116 - }
117 -
118 30 add_submenu_page(
119 31 'formidable',
120 32 'Formidable | ' . __( 'Upgrade', 'formidable' ),
121 - '<span class="frm-upgrade-submenu">' . esc_html( $cta_text ) . '</span>',
33 + '<span class="frm-upgrade-submenu">' . __( 'Upgrade', 'formidable' ) . '</span>',
122 34 'frm_view_forms',
123 35 'formidable-pro-upgrade',
124 - function () {
125 - // This function doesn't need to do anything.
126 - // The redirect is handled earlier to avoid issues with the headers being sent.
127 - }
36 + 'FrmAddonsController::upgrade_to_pro'
128 37 );
129 38 } elseif ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) ) {
130 39 wp_safe_redirect( admin_url( 'admin.php?page=formidable' ) );
131 40 exit;
132 - }//end if
41 + }
133 42 }
134 43
135 44 /**
136 45 * @return void
@@ -136,32 +45,28 @@
136 45 * @return void
137 46 */
138 47 public static function list_addons() {
139 48 FrmAppHelper::include_svg();
49 + $installed_addons = apply_filters( 'frm_installed_addons', array() );
50 + $license_type = '';
140 51
141 - $view_path = FrmAppHelper::plugin_path() . '/classes/views/addons/';
142 - $installed_addons = apply_filters( 'frm_installed_addons', array() );
143 - $addons = self::get_api_addons();
144 - $errors = array();
145 - $license_type = '';
146 - $request_addon_url = self::$request_addon_url;
52 + $addons = self::get_api_addons();
53 + $errors = array();
147 54
148 55 if ( isset( $addons['error'] ) ) {
149 - $api = new FrmFormApi();
150 - $errors = $api->get_error_from_response( $addons );
151 - $license_type = $addons['error']['type'] ?? '';
56 + $api = new FrmFormApi();
57 + $errors = $api->get_error_from_response( $addons );
58 + $license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
152 59 unset( $addons['error'] );
153 60 }
154 61
155 - $pro = array(
62 + $pro = array(
156 63 'pro' => array(
157 - 'title' => 'Formidable Forms Pro',
158 - 'slug' => 'formidable-pro',
159 - 'released' => '2011-02-05',
160 - 'docs' => 'knowledgebase/what-is-the-difference-between-the-lite-free-and-pro-version/',
161 - 'docs_label' => __( 'Why Upgrade', 'formidable' ),
162 - 'categories' => array( 'basic', 'plus', 'business', 'elite' ),
163 - 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
64 + 'title' => 'Formidable Forms Pro',
65 + 'slug' => 'formidable-pro',
66 + 'released' => '2011-02-05',
67 + 'docs' => 'knowledgebase/',
68 + 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
164 69 ),
165 70 );
166 71 $addons = $pro + $addons;
167 72 self::prepare_addons( $addons );
@@ -167,120 +72,25 @@
167 72 self::prepare_addons( $addons );
168 73
169 74 $pricing = FrmAppHelper::admin_upgrade_link( 'addons' );
170 75
171 - self::organize_and_get_categories();
172 - $categories = self::$categories;
173 -
174 - include $view_path . 'index.php';
76 + include( FrmAppHelper::plugin_path() . '/classes/views/addons/list.php' );
175 77 }
176 78
177 79 /**
178 - * Organize and set categories.
179 - *
180 - * @since 6.15
181 - *
182 80 * @return void
183 81 */
184 - protected static function organize_and_get_categories() {
185 - unset( self::$categories['strategy11'] );
186 - ksort( self::$categories );
187 -
188 - $bottom_categories = array();
189 - $plans = FrmFormsHelper::get_license_types(
190 - array(
191 - 'include_all' => false,
192 - 'case_lower' => true,
193 - )
194 - );
195 -
196 - // Extract the elements to move
197 - foreach ( $plans as $plan ) {
198 - if ( ! isset( self::$categories[ $plan ] ) ) {
199 - continue;
200 - }
201 -
202 - $bottom_categories[ $plan ] = self::$categories[ $plan ];
203 - unset( self::$categories[ $plan ] );
204 - }
205 -
206 - $special_categories = array();
207 -
208 - if ( 'elite' !== self::license_type() ) {
209 - $special_categories['available-addons'] = array(
210 - 'name' => __( 'Available', 'formidable' ),
211 - // To be assigned via JavaScript.
212 - 'count' => 0,
213 - );
214 - }
215 -
216 - $special_categories['active-addons'] = array(
217 - 'name' => __( 'Active', 'formidable' ),
218 - // To be assigned via JavaScript.
219 - 'count' => 0,
220 - );
221 -
222 - $special_categories['all-items'] = array(
223 - 'name' => __( 'All Add-Ons', 'formidable' ),
224 - // To be assigned via JavaScript.
225 - 'count' => 0,
226 - );
227 -
228 - self::$categories = array_merge(
229 - $special_categories,
230 - self::$categories,
231 - $bottom_categories
232 - );
233 - }
234 -
235 - /**
236 - * Organize and set categories.
237 - *
238 - * @since 6.15
239 - *
240 - * @param array $addon The addon array that will be modified by reference.
241 - *
242 - * @return void
243 - */
244 - protected static function set_categories( &$addon ) {
245 - if ( ! isset( $addon['categories'] ) ) {
246 - return;
247 - }
248 -
249 - $addon['category-slugs'] = array();
250 -
251 - foreach ( $addon['categories'] as $category ) {
252 - $category = FrmFormsHelper::convert_legacy_package_names( $category );
253 - $category_slug = sanitize_title( $category );
254 -
255 - // Add the slug to the new array.
256 - $addon['category-slugs'][] = $category_slug;
257 -
258 - if ( ! isset( self::$categories[ $category_slug ] ) ) {
259 - self::$categories[ $category_slug ] = array(
260 - 'name' => $category,
261 - 'count' => 0,
262 - );
263 - }
264 -
265 - ++self::$categories[ $category_slug ]['count'];
266 - }
267 - }
268 -
269 - /**
270 - * @return void
271 - */
272 82 public static function license_settings() {
273 83 $plugins = apply_filters( 'frm_installed_addons', array() );
84 + if ( empty( $plugins ) ) {
85 + esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
274 86
275 - if ( ! $plugins ) {
276 - esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
277 87 return;
278 88 }
279 89
280 90 ksort( $plugins );
281 91
282 - include FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php';
92 + include( FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php' );
283 93 }
284 94
285 95 /**
286 96 * @return array
@@ -288,15 +98,15 @@
288 98 protected static function get_api_addons() {
289 99 $api = new FrmFormApi();
290 100 $addons = $api->get_api_info();
291 101
292 - if ( ! $addons ) {
293 - return self::fallback_plugin_list();
294 - }
295 -
296 - foreach ( $addons as $k => $addon ) {
297 - if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
298 - unset( $addons[ $k ] );
102 + if ( empty( $addons ) ) {
103 + $addons = self::fallback_plugin_list();
104 + } else {
105 + foreach ( $addons as $k => $addon ) {
106 + if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
107 + unset( $addons[ $k ] );
108 + }
299 109 }
300 110 }
301 111
302 112 return $addons;
@@ -302,23 +112,11 @@
302 112 return $addons;
303 113 }
304 114
305 115 /**
306 - * Retrieves the count of available addons.
307 - *
308 - * @since 6.9
309 - *
310 - * @return int Count of addons.
311 - */
312 - public static function get_addons_count() {
313 - return count( self::get_api_addons() );
314 - }
315 -
316 - /**
317 116 * If the API is unable to connect, show something on the addons page
318 117 *
319 118 * @since 3.04.03
320 - *
321 119 * @return array
322 120 */
323 121 protected static function fallback_plugin_list() {
324 122 $list = array(
@@ -329,19 +127,19 @@
329 127 'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
330 128 ),
331 129 'mailchimp' => array(
332 130 'title' => 'Mailchimp Forms',
333 - 'excerpt' => 'Get on the path to more sales and leads in a matter of minutes. Add leads to a Mailchimp mailing list when they submit forms and update their information along with the entry.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
131 + 'excerpt' => 'Get on the path to more sales and leads in a matter of minutes. Add leads to a Mailchimp mailing list when they submit forms and update their information along with the entry.',
334 132 ),
335 133 'registration' => array(
336 134 'title' => 'User Registration Forms',
337 135 'link' => 'downloads/user-registration/',
338 - 'excerpt' => 'Give new users access to your site as quickly and painlessly as possible. Allow users to register, edit and be able to login to their profiles on your site from the front end in a clean, customized registration form.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
136 + 'excerpt' => 'Give new users access to your site as quickly and painlessly as possible. Allow users to register, edit and be able to login to their profiles on your site from the front end in a clean, customized registration form.',
339 137 ),
340 138 'paypal' => array(
341 139 'title' => 'PayPal Standard Forms',
342 140 'link' => 'downloads/paypal-standard/',
343 - 'excerpt' => 'Automate your business by collecting instant payments from your clients. Collect information, calculate a total, and send them on to PayPal. Require a payment before publishing content on your site.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
141 + 'excerpt' => 'Automate your business by collecting instant payments from your clients. Collect information, calculate a total, and send them on to PayPal. Require a payment before publishing content on your site.',
344 142 ),
345 143 'stripe' => array(
346 144 'title' => 'Stripe Forms',
347 145 'docs' => 'knowledgebase/stripe/',
@@ -373,9 +171,9 @@
373 171 'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
374 172 ),
375 173 'zapier' => array(
376 174 'title' => 'Zapier Forms',
377 - 'excerpt' => 'Connect with hundreds of different applications through Zapier. Insert a new row in a Google docs spreadsheet, post on Twitter, or add a new Dropbox file with your form.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
175 + 'excerpt' => 'Connect with hundreds of different applications through Zapier. Insert a new row in a Google docs spreadsheet, post on Twitter, or add a new Dropbox file with your form.',
378 176 ),
379 177 'signature' => array(
380 178 'title' => 'Digital Signature Forms',
381 179 'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
@@ -408,9 +206,8 @@
408 206 foreach ( $list as $k => $info ) {
409 207 $info['slug'] = $k;
410 208 $list[ $k ] = array_merge( $defaults, $info );
411 209 }
412 -
413 210 return $list;
414 211 }
415 212
416 213 /**
@@ -416,28 +213,25 @@
416 213 /**
417 214 * If Pro is missing but has been authenticated, include a download URL
418 215 *
419 216 * @since 3.04.03
420 - *
421 217 * @return string
422 218 */
423 219 public static function get_pro_download_url() {
424 - $api = new FrmFormApi( self::get_pro_license() );
220 + $license = self::get_pro_license();
221 + $api = new FrmFormApi( $license );
425 222 $downloads = $api->get_api_info();
426 223 $pro = self::get_pro_from_addons( $downloads );
427 224
428 - return $pro['url'] ?? '';
225 + return isset( $pro['url'] ) ? $pro['url'] : '';
429 226 }
430 227
431 228 /**
432 229 * @since 4.08
433 - *
434 - * @return string
435 230 */
436 231 public static function get_pro_license() {
437 232 $pro_cred_store = 'frmpro-credentials';
438 233 $pro_wpmu_store = 'frmpro-wpmu-sitewide';
439 -
440 234 if ( is_multisite() && get_site_option( $pro_wpmu_store ) ) {
441 235 $creds = get_site_option( $pro_cred_store );
442 236 } else {
443 237 $creds = get_option( $pro_cred_store );
@@ -447,18 +241,16 @@
447 241 return '';
448 242 }
449 243
450 244 $license = $creds['license'];
451 -
452 - if ( ! $license ) {
245 + if ( empty( $license ) ) {
453 246 return '';
454 247 }
455 248
456 - if ( str_contains( $license, '-' ) ) {
457 - // This is a fix for licenses saved in the past
458 - return strtoupper( $license );
249 + if ( strpos( $license, '-' ) ) {
250 + // this is a fix for licenses saved in the past
251 + $license = strtoupper( $license );
459 252 }
460 -
461 253 return $license;
462 254 }
463 255
464 256 /**
@@ -464,26 +256,20 @@
464 256 /**
465 257 * @since 4.08
466 258 *
467 259 * @param array $addons
468 - *
469 260 * @return array
470 261 */
471 262 protected static function get_pro_from_addons( $addons ) {
472 - return $addons['93790'] ?? array();
263 + return isset( $addons['93790'] ) ? $addons['93790'] : array();
473 264 }
474 265
475 266 /**
476 267 * @since 4.06
477 - * @since 6.31 Added the $force_type param.
478 - *
479 - * @param bool $force_type Whether to resolve grandfathered licenses to their real license type.
480 - *
481 - * @return string
482 268 */
483 - public static function license_type( $force_type = false ) {
269 + public static function license_type() {
484 270 if ( is_callable( 'FrmProAddonsController::license_type' ) ) {
485 - return FrmProAddonsController::license_type( $force_type );
271 + return FrmProAddonsController::license_type();
486 272 }
487 273
488 274 return 'free';
489 275 }
@@ -488,70 +274,30 @@
488 274 return 'free';
489 275 }
490 276
491 277 /**
492 - * Determine the license status for payment fee decisions.
493 - *
494 - * Mirrors the API's determine_status_from_license_details logic.
495 - *
496 - * @since 6.31
497 - *
498 - * @return string 'active', 'expired', or 'free'.
278 + * @since 4.0.01
499 279 */
500 - public static function get_payment_license_status() {
280 + public static function is_license_expired() {
501 281 $version_info = self::get_primary_license_info();
502 -
503 - if ( ! $version_info ) {
504 - return 'free';
282 + if ( ! isset( $version_info['error'] ) ) {
283 + return false;
505 284 }
506 285
507 - $error = $version_info['error'] ?? array();
508 -
509 - if ( is_array( $error ) ) {
510 - $code = $error['code'] ?? '';
511 -
512 - if ( 'expired' === $code ) {
513 - return 'expired';
514 - }
515 -
516 - if ( 'grandfathered' === $code && isset( $error['expires'] ) && gmdate( 'Y-m-d', $error['expires'] ) < '2016-04-26' ) {
517 - return 'free';
518 - }
519 - }
520 -
521 - if ( in_array( self::license_type( true ), array( 'elite', 'business' ), true ) ) {
522 - return 'active';
523 - }
524 -
525 - return 'free';
286 + return $version_info['error'];
526 287 }
527 288
528 289 /**
529 - * @since 4.0.01
290 + * @since 4.08
530 291 *
531 - * @return bool
292 + * @return boolean|int false or the number of days until expiration.
532 293 */
533 - public static function is_license_expired() {
534 - $version_info = self::get_primary_license_info();
535 -
536 - if ( ! isset( $version_info['error'] ) ) {
537 - return false;
294 + public static function is_license_expiring() {
295 + if ( is_callable( 'FrmProAddonsController::is_license_expiring' ) ) {
296 + return FrmProAddonsController::is_license_expiring();
538 297 }
539 298
540 - $expires = $version_info['error']['expires'] ?? 0;
541 -
542 - if ( ! $expires || $expires > time() ) {
543 - return false;
544 - }
545 -
546 - $rate_limited = ! empty( $version_info['response_code'] ) && 429 === (int) $version_info['response_code'];
547 -
548 - if ( $rate_limited ) {
549 - // Do not return false positives for rate limited responses.
550 - return false;
551 - }
552 -
553 - return $version_info['error'];
299 + return false;
554 300 }
555 301
556 302 /**
557 303 * @since 4.08
@@ -560,13 +306,11 @@
560 306 * @return array|false
561 307 */
562 308 public static function get_primary_license_info() {
563 309 $installed_addons = apply_filters( 'frm_installed_addons', array() );
564 -
565 - if ( ! $installed_addons || ! isset( $installed_addons['formidable_pro'] ) ) {
310 + if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
566 311 return false;
567 312 }
568 -
569 313 $installed_addons = array(
570 314 'formidable_pro' => $installed_addons['formidable_pro'],
571 315 );
572 316
@@ -574,12 +318,8 @@
574 318 }
575 319
576 320 /**
577 321 * @since 3.04.03
578 - *
579 - * @param mixed $transient
580 - *
581 - * @return object
582 322 */
583 323 public static function check_update( $transient ) {
584 324 if ( ! FrmAppHelper::pro_is_installed() ) {
585 325 // Don't make any changes if only Lite is installed.
@@ -590,10 +330,9 @@
590 330 $transient = new stdClass();
591 331 }
592 332
593 333 $installed_addons = apply_filters( 'frm_installed_addons', array() );
594 -
595 - if ( ! $installed_addons ) {
334 + if ( empty( $installed_addons ) ) {
596 335 return $transient;
597 336 }
598 337
599 338 $version_info = self::fill_update_addon_info( $installed_addons );
@@ -599,9 +338,9 @@
599 338 $version_info = self::fill_update_addon_info( $installed_addons );
600 339 $transient->last_checked = time();
601 340 $wp_plugins = self::get_plugins();
602 341
603 - foreach ( $version_info as $plugin ) {
342 + foreach ( $version_info as $id => $plugin ) {
604 343 $plugin = (object) $plugin;
605 344
606 345 if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
607 346 continue;
@@ -607,20 +346,19 @@
607 346 continue;
608 347 }
609 348
610 349 $folder = $plugin->plugin;
611 -
612 - if ( ! $folder ) {
350 + if ( empty( $folder ) ) {
613 351 continue;
614 352 }
615 353
616 354 if ( ! self::is_installed( $folder ) ) {
617 - // Don't show an update if the plugin isn't installed
355 + // don't show an update if the plugin isn't installed
618 356 continue;
619 357 }
620 358
621 - $wp_plugin = $wp_plugins[ $folder ] ?? array();
622 - $wp_version = $wp_plugin['Version'] ?? '1.0';
359 + $wp_plugin = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
360 + $wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
623 361 $plugin->slug = explode( '/', $folder )[0];
624 362
625 363 if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
626 364 $transient->response[ $folder ] = $plugin;
@@ -628,8 +366,9 @@
628 366 $transient->no_update[ $folder ] = $plugin;
629 367 }
630 368
631 369 $transient->checked[ $folder ] = $wp_version;
370 +
632 371 }//end foreach
633 372
634 373 return $transient;
635 374 }
@@ -639,9 +378,8 @@
639 378 * Because this gets called on "pre_set_site_transient_update_plugins" an old version of FrmAppHelper may be loaded on plugin update.
640 379 * This means that trying to access FrmAppHelper::get_plugins when upgrading from a Lite version before v5.5 results in a one-off error.
641 380 *
642 381 * @since 5.5.2
643 - *
644 382 * @return array
645 383 */
646 384 protected static function get_plugins() {
647 385 if ( ! function_exists( 'get_plugins' ) ) {
@@ -676,49 +414,43 @@
676 414 $version_info = array();
677 415
678 416 foreach ( $installed_addons as $addon ) {
679 417 if ( $addon->store_url !== 'https://formidableforms.com' ) {
680 - // Check if this is a third-party addon
418 + // check if this is a third-party addon
681 419 continue;
682 420 }
683 421
684 422 $new_license = $addon->license;
685 -
686 - if ( ! $new_license || in_array( $new_license, $checked_licenses, true ) ) {
423 + if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
687 424 continue;
688 425 }
689 426
690 427 $checked_licenses[] = $new_license;
691 - $api = new FrmFormApi( $new_license );
692 428
693 - if ( ! $version_info ) {
429 + $api = new FrmFormApi( $new_license );
430 + if ( empty( $version_info ) ) {
694 431 $version_info = $api->get_api_info();
695 432 continue;
696 433 }
697 434
698 435 $plugin = $api->get_addon_for_license( $addon, $version_info );
699 -
700 - if ( ! $plugin ) {
436 + if ( empty( $plugin ) ) {
701 437 continue;
702 438 }
703 439
704 - $download_id = $plugin['id'] ?? 0;
440 + $download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
441 + if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
442 + // if this addon is using its own license, get the update url
443 + $addon_info = $api->get_api_info();
705 444
706 - if ( ! $download_id || isset( $version_info[ $download_id ]['package'] ) ) {
707 - continue;
445 + $version_info[ $download_id ] = $addon_info[ $download_id ];
446 + if ( isset( $addon_info['error'] ) ) {
447 + $version_info[ $download_id ]['error'] = array(
448 + 'message' => $addon_info['error']['message'],
449 + 'code' => $addon_info['error']['code'],
450 + );
451 + }
708 452 }
709 -
710 - // If this addon is using its own license, get the update url
711 - $addon_info = $api->get_api_info();
712 -
713 - $version_info[ $download_id ] = $addon_info[ $download_id ];
714 -
715 - if ( isset( $addon_info['error'] ) ) {
716 - $version_info[ $download_id ]['error'] = array(
717 - 'message' => $addon_info['error']['message'],
718 - 'code' => $addon_info['error']['code'],
719 - );
720 - }
721 453 }//end foreach
722 454
723 455 return $version_info;
724 456 }
@@ -726,11 +458,9 @@
726 458 /**
727 459 * Get the action link for an addon that isn't active.
728 460 *
729 461 * @since 3.06.03
730 - *
731 462 * @param string $plugin The plugin slug.
732 - *
733 463 * @return array
734 464 */
735 465 public static function install_link( $plugin ) {
736 466 $link = array();
@@ -741,20 +471,20 @@
741 471 $link = array(
742 472 'url' => $addon['plugin'],
743 473 'class' => 'frm-activate-addon',
744 474 );
745 - } elseif ( ! empty( $addon['url'] ) ) {
475 + } elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
746 476 $link = array(
747 477 'url' => $addon['url'],
748 478 'class' => 'frm-install-addon',
749 479 );
750 - } elseif ( ! empty( $addon['categories'] ) ) {
480 + } elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
751 481 $link = array(
752 482 'categories' => $addon['categories'],
753 483 );
754 484 }
755 485
756 - if ( $link ) {
486 + if ( ! empty( $link ) ) {
757 487 $link['status'] = $addon['status']['type'];
758 488 }
759 489 } elseif ( current_user_can( 'activate_plugins' ) && self::is_installed( 'formidable-' . $plugin . '/formidable-' . $plugin . '.php' ) ) {
760 490 $link = array(
@@ -766,81 +496,34 @@
766 496 return $link;
767 497 }
768 498
769 499 /**
770 - * Get the JSON-encoded install data for a plugin update.
771 - *
772 - * @since 6.29
773 - *
774 - * @param string $addon_slug The addon slug (e.g. 'pro', 'dates').
775 - *
776 - * @return string JSON-encoded install data, or empty string if no URL is available.
777 - */
778 - public static function get_update_install_data( $addon_slug ) {
779 - $upgrading = self::install_link( $addon_slug );
780 -
781 - if ( isset( $upgrading['class'] ) && 'frm-install-addon' === $upgrading['class'] ) {
782 - return (string) json_encode( $upgrading );
783 - }
784 -
785 - if ( 'pro' === $addon_slug ) {
786 - $download_url = self::get_pro_download_url();
787 - $plugin_file = 'formidable-pro/formidable-pro.php';
788 - } else {
789 - $addon_data = self::get_addon( $addon_slug );
790 - $download_url = $addon_data && ! empty( $addon_data['url'] ) ? $addon_data['url'] : '';
791 - $plugin_file = $addon_data && ! empty( $addon_data['plugin'] ) ? $addon_data['plugin'] : 'formidable-' . $addon_slug . '/formidable-' . $addon_slug . '.php';
792 - }
793 -
794 - if ( ! $download_url ) {
795 - $update_plugins = get_site_transient( 'update_plugins' );
796 - $plugin_update = $update_plugins->response[ $plugin_file ] ?? null;
797 - $download_url = $plugin_update && ! empty( $plugin_update->package ) ? $plugin_update->package : '';
798 - }
799 -
800 - return $download_url ? (string) json_encode(
801 - array(
802 - 'url' => $download_url,
803 - 'class' => 'frm-install-addon',
804 - )
805 - ) : '';
806 - }
807 -
808 - /**
809 500 * @since 4.09
810 - *
811 501 * @param string $plugin The plugin slug.
812 - *
813 502 * @return array|false
814 503 */
815 - public static function get_addon( $plugin ) {
504 + protected static function get_addon( $plugin ) {
816 505 $addons = self::get_api_addons();
817 506 self::prepare_addons( $addons );
818 -
819 507 foreach ( $addons as $addon ) {
820 508 $slug = explode( '/', $addon['plugin'] );
821 -
822 509 if ( $slug[0] === 'formidable-' . $plugin ) {
823 510 return $addon;
824 511 }
825 512 }
826 -
827 513 return false;
828 514 }
829 515
830 516 /**
831 517 * @since 4.09
832 - *
833 518 * @return string
834 519 */
835 520 protected static function get_license_type() {
836 521 $license_type = '';
837 522 $addons = self::get_api_addons();
838 -
839 523 if ( isset( $addons['error'] ) && isset( $addons['error']['type'] ) ) {
840 - return $addons['error']['type'];
524 + $license_type = $addons['error']['type'];
841 525 }
842 -
843 526 return $license_type;
844 527 }
845 528
846 529 /**
@@ -853,12 +536,11 @@
853 536 */
854 537 public static function get_addon_for_license( $addons, $license ) {
855 538 $download_id = $license->download_id;
856 539 $plugin = array();
857 -
858 - if ( ! $download_id && $addons ) {
540 + if ( empty( $download_id ) && ! empty( $addons ) ) {
859 541 foreach ( $addons as $addon ) {
860 - if ( 0 === strcasecmp( $license->plugin_name, $addon['title'] ) ) {
542 + if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
861 543 return $addon;
862 544 }
863 545 }
864 546 } elseif ( isset( $addons[ $download_id ] ) ) {
@@ -868,33 +550,29 @@
868 550 return $plugin;
869 551 }
870 552
871 553 /**
872 - * @param array $addons
873 - *
874 554 * @return void
875 555 */
876 556 protected static function prepare_addons( &$addons ) {
877 - // Reset categories to prevent count accumulation across multiple calls.
878 - self::$categories = array();
879 -
880 557 $activate_url = '';
881 -
882 558 if ( current_user_can( 'activate_plugins' ) ) {
883 559 $activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
884 560 }
885 561
886 562 $loop_addons = $addons;
887 -
888 563 foreach ( $loop_addons as $id => $addon ) {
889 564 if ( is_numeric( $id ) ) {
890 565 $slug = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
891 566 $file_name = $addon['plugin'];
892 567 } else {
893 - $slug = $id;
894 - $base_file = $addon['file'] ?? 'formidable-' . $slug;
568 + $slug = $id;
569 + if ( isset( $addon['file'] ) ) {
570 + $base_file = $addon['file'];
571 + } else {
572 + $base_file = 'formidable-' . $slug;
573 + }
895 574 $file_name = $base_file . '/' . $base_file . '.php';
896 -
897 575 if ( ! isset( $addon['plugin'] ) ) {
898 576 $addon['plugin'] = $file_name;
899 577 }
900 578 }
@@ -899,17 +577,10 @@
899 577 }
900 578 }
901 579
902 580 $addon['installed'] = self::is_installed( $file_name );
903 -
904 - if ( 'highrise' === $slug && ! $addon['installed'] ) {
905 - unset( $addons[ $id ] );
906 - continue;
907 - }
908 -
909 581 if ( $addon['installed'] && 'formidable-views/formidable-views.php' === $file_name ) {
910 582 $active_views_version = self::get_active_views_version();
911 -
912 583 if ( false !== $active_views_version && $slug !== $active_views_version ) {
913 584 $addon['installed'] = false;
914 585 }
915 586 }
@@ -915,9 +586,9 @@
915 586 }
916 587
917 588 $addon['activate_url'] = '';
918 589
919 - if ( $addon['installed'] && $activate_url && ! self::is_plugin_active( $file_name, $slug ) ) {
590 + if ( $addon['installed'] && ! empty( $activate_url ) && ! self::is_plugin_active( $file_name, $slug ) ) {
920 591 $addon['activate_url'] = add_query_arg(
921 592 array(
922 593 '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
923 594 'plugin' => $file_name,
@@ -933,21 +604,16 @@
933 604
934 605 if ( ! isset( $addon['link'] ) ) {
935 606 $addon['link'] = 'downloads/' . $slug . '/';
936 607 }
608 + self::prepare_addon_link( $addon['link'] );
937 609
938 - self::prepare_addon_link( $addon['link'] );
939 610 self::set_addon_status( $addon );
940 - self::set_categories( $addon );
941 -
942 611 $addons[ $id ] = $addon;
943 612 }//end foreach
944 613 }
945 614
946 615 /**
947 - * @param string $file_name
948 - * @param string $slug
949 - *
950 616 * @return bool
951 617 */
952 618 private static function is_plugin_active( $file_name, $slug ) {
953 619 if ( 'formidable-views/formidable-views.php' === $file_name ) {
@@ -956,15 +622,14 @@
956 622 return is_plugin_active( $file_name );
957 623 }
958 624
959 625 /**
960 - * @return false|string either 'visual-views' or 'views', false if one is not found.
626 + * @return string|false either 'visual-views' or 'views', false if one is not found.
961 627 */
962 628 private static function get_active_views_version() {
963 629 if ( ! is_callable( 'FrmViewsAppHelper::plugin_version' ) ) {
964 630 return false;
965 631 }
966 -
967 632 $plugin_version = FrmViewsAppHelper::plugin_version();
968 633 return version_compare( $plugin_version, '5.0', '>=' ) ? 'visual-views' : 'views';
969 634 }
970 635
@@ -970,25 +635,22 @@
970 635
971 636 /**
972 637 * @since 3.04.02
973 638 *
974 - * @param string $link
975 - *
976 639 * @return void
977 640 */
978 641 protected static function prepare_addon_link( &$link ) {
979 642 $site_url = 'https://formidableforms.com/';
980 -
981 - if ( ! str_starts_with( $link, 'http' ) ) {
643 + if ( strpos( $link, 'http' ) !== 0 ) {
982 644 $link = $site_url . $link;
983 645 }
984 -
985 - $link = FrmAppHelper::make_affiliate_url( $link );
986 -
987 - $utm = array(
988 - 'campaign' => 'addons',
646 + $link = FrmAppHelper::make_affiliate_url( $link );
647 + $query_args = array(
648 + 'utm_source' => 'WordPress',
649 + 'utm_medium' => 'addons',
650 + 'utm_campaign' => 'liteplugin',
989 651 );
990 - $link = FrmAppHelper::maybe_add_missing_utm( $link, $utm );
652 + $link = add_query_arg( $query_args, $link );
991 653 }
992 654
993 655 /**
994 656 * Add the status to the addon array. Status options are:
@@ -995,10 +657,8 @@
995 657 * installed, active, not installed
996 658 *
997 659 * @since 3.04.02
998 660 *
999 - * @param array $addon
1000 - *
1001 661 * @return void
1002 662 */
1003 663 protected static function set_addon_status( &$addon ) {
1004 664 if ( ! empty( $addon['activate_url'] ) ) {
@@ -1019,8 +679,250 @@
1019 679 }
1020 680 }
1021 681
1022 682 /**
683 + * @return void
684 + */
685 + public static function upgrade_to_pro() {
686 + FrmAppHelper::include_svg();
687 +
688 + $link_parts = array(
689 + 'medium' => 'upgrade',
690 + 'content' => 'button',
691 + );
692 +
693 + $features = array(
694 + 'Display Entries' => array(
695 + array(
696 + 'label' => 'Display form data with virtually limitless views',
697 + 'link' => array(
698 + 'content' => 'views',
699 + 'param' => 'views-display-form-data',
700 + ),
701 + 'lite' => false,
702 + ),
703 + array(
704 + 'label' => 'Generate graphs and stats based on your submitted data',
705 + 'link' => array(
706 + 'content' => 'graphs',
707 + 'param' => 'statistics-graphs-wordpress-forms',
708 + ),
709 + 'lite' => false,
710 + ),
711 + ),
712 + 'Entry Management' => array(
713 + array(
714 + 'label' => 'Import entries from a CSV',
715 + 'link' => array(
716 + 'content' => 'import-entries',
717 + 'param' => 'importing-exporting-wordpress-forms',
718 + ),
719 + 'lite' => false,
720 + ),
721 + array(
722 + 'label' => 'Logged-in users can save drafts and return later',
723 + 'link' => array(
724 + 'content' => 'save-drafts',
725 + 'param' => 'save-drafts-wordpress-form',
726 + ),
727 + 'lite' => false,
728 + ),
729 + array(
730 + 'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
731 + 'link' => array(
732 + 'content' => 'front-edit',
733 + 'param' => 'wordpress-front-end-editing',
734 + ),
735 + 'lite' => false,
736 + ),
737 + array(
738 + 'label' => 'View form submissions from the back-end',
739 + 'lite' => true,
740 + ),
741 + array(
742 + 'label' => 'Export your entries to a CSV',
743 + 'lite' => true,
744 + ),
745 + ),
746 + 'Form Building' => array(
747 + array(
748 + 'label' => 'Save a calculated value into a field',
749 + 'link' => array(
750 + 'content' => 'calculations',
751 + 'param' => 'field-calculations-wordpress-form',
752 + ),
753 + 'lite' => false,
754 + ),
755 + array(
756 + 'label' => 'Allow multiple file uploads',
757 + 'link' => array(
758 + 'content' => 'file-uploads',
759 + 'param' => 'wordpress-multi-file-upload-fields',
760 + ),
761 + 'lite' => false,
762 + ),
763 + array(
764 + 'label' => 'Repeat sections of fields',
765 + 'link' => array(
766 + 'content' => 'repeaters',
767 + 'param' => 'repeatable-sections-forms',
768 + ),
769 + 'lite' => false,
770 + ),
771 + array(
772 + 'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
773 + 'link' => array(
774 + 'content' => 'conditional-logic',
775 + 'param' => 'conditional-logic-wordpress-forms',
776 + ),
777 + 'lite' => false,
778 + ),
779 + array(
780 + 'label' => 'Confirmation fields',
781 + 'link' => array(
782 + 'content' => 'confirmation-fields',
783 + 'param' => 'confirmation-fields-wordpress-forms',
784 + ),
785 + 'lite' => false,
786 + ),
787 + array(
788 + 'label' => 'Multi-paged forms',
789 + 'link' => array(
790 + 'content' => 'page-breaks',
791 + 'param' => 'wordpress-multi-page-forms',
792 + ),
793 + 'lite' => false,
794 + ),
795 + array(
796 + 'label' => 'Include section headings, page breaks, rich text, dates, times, scales, star ratings, sliders, toggles, dynamic fields populated from other forms, passwords, and tags in advanced forms.',
797 + 'lite' => false,
798 + ),
799 + array(
800 + 'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
801 + 'lite' => true,
802 + ),
803 + array(
804 + 'label' => 'Drag & Drop Form building',
805 + 'link' => array(
806 + 'content' => 'drag-drop',
807 + 'param' => 'drag-drop-forms',
808 + ),
809 + 'lite' => true,
810 + ),
811 + array(
812 + 'label' => 'Create forms from Templates',
813 + 'link' => array(
814 + 'content' => 'form-templates',
815 + 'param' => 'wordpress-form-templates',
816 + ),
817 + 'lite' => true,
818 + ),
819 + array(
820 + 'label' => 'Import and export forms with XML',
821 + 'link' => array(
822 + 'content' => 'import',
823 + 'param' => 'importing-exporting-wordpress-forms',
824 + ),
825 + 'lite' => true,
826 + ),
827 + array(
828 + 'label' => 'Use input placeholder text in your fields that clear when typing starts.',
829 + 'lite' => true,
830 + ),
831 + ),
832 + 'Form Actions' => array(
833 + array(
834 + 'label' => 'Conditionally send your email notifications based on values in your form',
835 + 'link' => array(
836 + 'content' => 'conditional-emails',
837 + ),
838 + 'lite' => false,
839 + ),
840 + array(
841 + 'label' => 'Create and edit WordPress posts or custom posts from the front-end',
842 + 'link' => array(
843 + 'content' => 'create-posts',
844 + 'param' => 'create-posts-pages-wordpress-forms',
845 + ),
846 + 'lite' => false,
847 + ),
848 + array(
849 + 'label' => 'Send multiple emails and autoresponders',
850 + 'link' => array(
851 + 'content' => 'multiple-emails',
852 + 'param' => 'virtually-unlimited-emails',
853 + ),
854 + 'lite' => true,
855 + ),
856 + ),
857 + 'Form Appearance' => array(
858 + array(
859 + 'label' => 'Create Multiple styles for different forms',
860 + 'link' => array(
861 + 'content' => 'multiple-styles',
862 + 'param' => 'wordpress-visual-form-styler',
863 + ),
864 + 'lite' => false,
865 + ),
866 + array(
867 + 'label' => 'Customizable layout with CSS classes',
868 + 'link' => array(
869 + 'content' => 'form-layout',
870 + 'param' => 'wordpress-mobile-friendly-forms',
871 + ),
872 + 'lite' => true,
873 + ),
874 + array(
875 + 'label' => 'Customize the HTML for your forms',
876 + 'link' => array(
877 + 'content' => 'custom-html',
878 + 'param' => 'customizable-html-wordpress-form',
879 + ),
880 + 'lite' => true,
881 + ),
882 + array(
883 + 'label' => 'Style your form with the Visual Form Styler',
884 + 'lite' => true,
885 + ),
886 + ),
887 + );
888 +
889 + include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
890 + }
891 +
892 + /**
893 + * Install Pro after connection with Formidable.
894 + *
895 + * @since 4.02.05
896 + *
897 + * @return void
898 + */
899 + public static function connect_pro() {
900 + FrmAppHelper::permission_check( 'install_plugins' );
901 + check_ajax_referer( 'frm_ajax', 'nonce' );
902 +
903 + $url = self::get_current_plugin();
904 + if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
905 + wp_die();
906 + }
907 +
908 + $response = array();
909 +
910 + // It's already installed and active.
911 + $active = self::activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
912 + if ( is_wp_error( $active ) ) {
913 + // The plugin was installed, but not active. Download it now.
914 + self::ajax_install_addon();
915 + } else {
916 + $response['active'] = true;
917 + $response['success'] = true;
918 + }
919 +
920 + echo json_encode( $response );
921 + wp_die();
922 + }
923 +
924 + /**
1023 925 * @since 5.5.2
1024 926 *
1025 927 * @param string $plugin
1026 928 * @param string $redirect
@@ -1025,10 +927,9 @@
1025 927 * @param string $plugin
1026 928 * @param string $redirect
1027 929 * @param bool $network_wide
1028 930 * @param bool $silent
1029 - *
1030 - * @return WP_Error|null Null on success, WP_Error on invalid file.
931 + * @return null|WP_Error Null on success, WP_Error on invalid file.
1031 932 */
1032 933 protected static function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
1033 934 if ( ! function_exists( 'activate_plugin' ) ) {
1034 935 require_once ABSPATH . 'wp-admin/includes/plugin.php';
@@ -1042,9 +943,8 @@
1042 943 * @since 6.8
1043 944 *
1044 945 * @param string $plugin
1045 946 * @param bool $silent
1046 - *
1047 947 * @return void
1048 948 */
1049 949 protected static function deactivate_plugin( $plugin, $silent = false ) {
1050 950 if ( ! function_exists( 'deactivate_plugins' ) ) {
@@ -1058,9 +958,8 @@
1058 958 *
1059 959 * @since 6.8
1060 960 *
1061 961 * @param string $plugin
1062 - *
1063 962 * @return true|WP_Error True on success, WP_Error on invalid file.
1064 963 */
1065 964 protected static function uninstall_plugin( $plugin ) {
1066 965 if ( ! current_user_can( 'delete_plugins' ) ) {
@@ -1073,9 +972,13 @@
1073 972
1074 973 self::deactivate_plugin( $plugin, true );
1075 974 $result = delete_plugins( array( $plugin ) );
1076 975
1077 - return is_wp_error( $result ) ? $result : true;
976 + if ( is_wp_error( $result ) ) {
977 + return $result;
978 + }
979 +
980 + return true;
1078 981 }
1079 982
1080 983 /**
1081 984 * @since 5.0.10
@@ -1082,9 +985,9 @@
1082 985 *
1083 986 * @return string
1084 987 */
1085 988 protected static function get_current_plugin() {
1086 - if ( ! self::$plugin ) {
989 + if ( empty( self::$plugin ) ) {
1087 990 self::$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
1088 991 }
1089 992 return self::$plugin;
1090 993 }
@@ -1090,10 +993,8 @@
1090 993 }
1091 994
1092 995 /**
1093 996 * @since 4.08
1094 - *
1095 - * @return mixed[]|null
1096 997 */
1097 998 protected static function download_and_activate() {
1098 999 if ( is_admin() ) {
1099 1000 FrmAppHelper::set_current_screen_and_hook_suffix();
@@ -1101,14 +1002,12 @@
1101 1002
1102 1003 self::maybe_show_cred_form();
1103 1004
1104 1005 $installed = self::install_addon();
1105 -
1106 1006 if ( is_array( $installed ) && isset( $installed['message'] ) ) {
1107 1007 return $installed;
1108 1008 }
1109 1009 self::handle_addon_action( $installed, 'activate' );
1110 - return null;
1111 1010 }
1112 1011
1113 1012 /**
1114 1013 * @since 3.04.02
@@ -1116,12 +1015,12 @@
1116 1015 * @return void
1117 1016 */
1118 1017 protected static function maybe_show_cred_form() {
1119 1018 if ( ! function_exists( 'request_filesystem_credentials' ) ) {
1120 - include_once ABSPATH . 'wp-admin/includes/file.php';
1019 + include_once( ABSPATH . 'wp-admin/includes/file.php' );
1121 1020 }
1122 1021
1123 - // Start output buffering to catch the filesystem form if credentials are needed.
1022 + // Start output bufferring to catch the filesystem form if credentials are needed.
1124 1023 ob_start();
1125 1024
1126 1025 $show_form = false;
1127 1026 $method = '';
@@ -1138,8 +1037,9 @@
1138 1037
1139 1038 if ( $show_form ) {
1140 1039 $form = ob_get_clean();
1141 1040 $message = __( 'Sorry, your site requires FTP authentication. Please download plugins from FormidableForms.com and install them manually.', 'formidable' );
1041 + $data = $form;
1142 1042 $response = array(
1143 1043 'success' => false,
1144 1044 'message' => $message,
1145 1045 'form' => $form,
@@ -1159,9 +1059,11 @@
1159 1059 *
1160 1060 * @return bool
1161 1061 */
1162 1062 public static function url_is_allowed( $download_url ) {
1163 - return FrmAppHelper::validate_url_is_in_s3_bucket( $download_url, 'zip' ) || in_array( $download_url, self::allowed_external_urls(), true );
1063 + return (
1064 + FrmAppHelper::validate_url_is_in_s3_bucket( $download_url, 'zip' ) || in_array( $download_url, self::allowed_external_urls(), true )
1065 + );
1164 1066 }
1165 1067
1166 1068 /**
1167 1069 * We do not need any extra credentials if we have gotten this far,
@@ -1167,10 +1069,8 @@
1167 1069 * We do not need any extra credentials if we have gotten this far,
1168 1070 * so let's install the plugin.
1169 1071 *
1170 1072 * @since 3.04.02
1171 - *
1172 - * @return array|string
1173 1073 */
1174 1074 protected static function install_addon() {
1175 1075 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1176 1076
@@ -1184,15 +1084,14 @@
1184 1084 }
1185 1085
1186 1086 // Create the plugin upgrader with our custom skin.
1187 1087 $installer = new Plugin_Upgrader( new FrmInstallerSkin() );
1188 - $installer->install( $download_url, array( 'overwrite_package' => true ) );
1088 + $installer->install( $download_url );
1189 1089
1190 1090 // Flush the cache and return the newly installed plugin basename.
1191 1091 wp_cache_flush();
1192 1092
1193 1093 $plugin = $installer->plugin_info();
1194 -
1195 1094 if ( ! $plugin ) {
1196 1095 return array(
1197 1096 'message' => 'Plugin was not installed. ' . $installer->result,
1198 1097 'success' => false,
@@ -1197,9 +1096,8 @@
1197 1096 'message' => 'Plugin was not installed. ' . $installer->result,
1198 1097 'success' => false,
1199 1098 );
1200 1099 }
1201 -
1202 1100 return $plugin;
1203 1101 }
1204 1102
1205 1103 /**
@@ -1210,9 +1108,9 @@
1210 1108 * @return void
1211 1109 */
1212 1110 public static function ajax_activate_addon() {
1213 1111 self::process_addon_action(
1214 - function ( $plugin ) {
1112 + function( $plugin ) {
1215 1113 return self::handle_addon_action( $plugin, 'activate' );
1216 1114 },
1217 1115 array( 'FrmAddonsController', 'get_addon_activation_response' )
1218 1116 );
@@ -1235,9 +1133,9 @@
1235 1133 * @return void
1236 1134 */
1237 1135 public static function ajax_deactivate_addon() {
1238 1136 self::process_addon_action(
1239 - function ( $plugin ) {
1137 + function( $plugin ) {
1240 1138 return self::handle_addon_action( $plugin, 'deactivate' );
1241 1139 }
1242 1140 );
1243 1141 }
@@ -1250,9 +1148,9 @@
1250 1148 * @return void
1251 1149 */
1252 1150 public static function ajax_uninstall_addon() {
1253 1151 self::process_addon_action(
1254 - function ( $plugin ) {
1152 + function( $plugin ) {
1255 1153 return self::handle_addon_action( $plugin, 'uninstall' );
1256 1154 }
1257 1155 );
1258 1156 }
@@ -1263,9 +1161,8 @@
1263 1161 * @since 6.8
1264 1162 *
1265 1163 * @param callable $action_callback The specific add-on action to be executed.
1266 1164 * @param callable|null $response_callback Optional. The response handling callback. Default null.
1267 - *
1268 1165 * @return void
1269 1166 */
1270 1167 private static function process_addon_action( $action_callback, $response_callback = null ) {
1271 1168 self::install_addon_permissions();
@@ -1288,14 +1185,13 @@
1288 1185 * @since 6.8
1289 1186 *
1290 1187 * @param string $installed The plugin folder name with file name.
1291 1188 * @param string $action The action type ('activate', 'deactivate', 'uninstall').
1292 - *
1293 - * @return mixed[]|null
1189 + * @return void|array
1294 1190 */
1295 1191 protected static function handle_addon_action( $installed, $action ) {
1296 1192 if ( ! $installed || ! $action ) {
1297 - return null;
1193 + return;
1298 1194 }
1299 1195
1300 1196 $result = null;
1301 1197 switch ( $action ) {
@@ -1315,9 +1211,8 @@
1315 1211 if ( $result->get_error_code() !== 'no_plugin_header' ) {
1316 1212 if ( wp_doing_ajax() ) {
1317 1213 wp_send_json_error( array( 'error' => $result->get_error_message() ) );
1318 1214 }
1319 -
1320 1215 return array(
1321 1216 'message' => $result->get_error_message(),
1322 1217 'success' => false,
1323 1218 );
@@ -1331,14 +1226,17 @@
1331 1226 * @return array
1332 1227 */
1333 1228 private static function get_addon_activation_response() {
1334 1229 $activating_page = self::get_activating_page();
1335 - $message = $activating_page ? __( 'Your plugin has been activated. Would you like to save and reload the page now?', 'formidable' ) : __( 'Your plugin has been activated.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
1336 1230
1337 - return array(
1231 + $message = $activating_page ? __( 'Your plugin has been activated. Would you like to save and reload the page now?', 'formidable' ) : __( 'Your plugin has been activated.', 'formidable' );
1232 +
1233 + $response = array(
1338 1234 'message' => $message,
1339 1235 'saveAndReload' => $activating_page,
1340 1236 );
1237 +
1238 + return $response;
1341 1239 }
1342 1240
1343 1241 /**
1344 1242 * Return a string that reflects the page from which the addon is being activated on,
@@ -1347,14 +1245,17 @@
1347 1245 * @return string
1348 1246 */
1349 1247 private static function get_activating_page() {
1350 1248 $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
1249 + if ( false !== strpos( $referer, 'frm_action=settings' ) ) {
1250 + return 'settings';
1251 + }
1351 1252
1352 - if ( str_contains( $referer, 'frm_action=settings' ) ) {
1353 - return 'settings';
1253 + if ( false !== strpos( $referer, 'frm_action=edit' ) ) {
1254 + return 'form_builder';
1354 1255 }
1355 1256
1356 - return str_contains( $referer, 'frm_action=edit' ) ? 'form_builder' : '';
1257 + return '';
1357 1258 }
1358 1259
1359 1260 /**
1360 1261 * Run security checks before installing
@@ -1365,14 +1266,12 @@
1365 1266 */
1366 1267 protected static function install_addon_permissions() {
1367 1268 check_ajax_referer( 'frm_ajax', 'nonce' );
1368 1269
1369 - if ( current_user_can( 'activate_plugins' ) && self::get_current_plugin() ) {
1370 - return;
1270 + if ( ! current_user_can( 'activate_plugins' ) || ! self::get_current_plugin() ) {
1271 + echo json_encode( true );
1272 + wp_die();
1371 1273 }
1372 -
1373 - echo json_encode( true );
1374 - wp_die();
1375 1274 }
1376 1275
1377 1276 /**
1378 1277 * @since 4.08
@@ -1380,22 +1279,17 @@
1380 1279 * @return string
1381 1280 */
1382 1281 public static function connect_link() {
1383 1282 $auth = get_option( 'frm_connect_token' );
1384 -
1385 - if ( ! $auth ) {
1283 + if ( empty( $auth ) ) {
1386 1284 $auth = hash( 'sha512', wp_rand() );
1387 - update_option( 'frm_connect_token', $auth, false );
1285 + update_option( 'frm_connect_token', $auth, 'no' );
1388 1286 }
1389 -
1390 - $page = FrmAppHelper::simple_get( 'page', 'sanitize_title', 'formidable-settings' );
1391 - $link = 'https://formidableforms.com/api-connect/';
1287 + $link = FrmAppHelper::admin_upgrade_link( 'connect', 'api-connect' );
1392 1288 $args = array(
1393 1289 'v' => 2,
1394 1290 'siteurl' => FrmAppHelper::site_url(),
1395 1291 'url' => get_rest_url(),
1396 - 'inst' => (int) FrmAppHelper::pro_is_included(),
1397 - 'return' => $page,
1398 1292 'token' => $auth,
1399 1293 'l' => self::get_pro_license(),
1400 1294 );
1401 1295
@@ -1413,19 +1307,19 @@
1413 1307 // Verify params present (auth & download link).
1414 1308 $post_auth = FrmAppHelper::get_param( 'token', '', 'request', 'sanitize_text_field' );
1415 1309 $post_url = FrmAppHelper::get_param( 'file_url', '', 'request', 'sanitize_text_field' );
1416 1310
1417 - // The download link is not required if already installed.
1418 - $is_installed = FrmAppHelper::pro_is_included();
1419 - $file_missing = ! $is_installed && ! $post_url;
1420 -
1421 - if ( ! $post_auth || $file_missing ) {
1311 + if ( ! $post_auth || ! $post_url ) {
1422 1312 return false;
1423 1313 }
1424 1314
1425 1315 // Verify auth.
1426 1316 $auth = get_option( 'frm_connect_token' );
1427 - return $auth && hash_equals( $auth, $post_auth );
1317 + if ( empty( $auth ) || ! hash_equals( $auth, $post_auth ) ) {
1318 + return false;
1319 + }
1320 +
1321 + return true;
1428 1322 }
1429 1323
1430 1324 /**
1431 1325 * Install and/or activate the add-on file.
@@ -1430,34 +1324,31 @@
1430 1324 /**
1431 1325 * Install and/or activate the add-on file.
1432 1326 *
1433 1327 * @since 4.08
1434 - *
1435 - * @return array
1436 1328 */
1437 1329 public static function install_addon_api() {
1438 1330 self::$plugin = FrmAppHelper::get_param( 'file_url', '', 'request', 'esc_url_raw' );
1439 1331
1332 + $error = esc_html__( 'Could not install an upgrade. Please download from formidableforms.com and install manually.', 'formidable' );
1333 +
1440 1334 // Delete so cannot replay.
1441 1335 delete_option( 'frm_connect_token' );
1442 1336
1443 1337 // It's already installed and active.
1444 1338 $active = self::activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1445 -
1446 1339 if ( is_wp_error( $active ) ) {
1447 - $response = self::maybe_download_and_activate();
1448 -
1449 - if ( is_array( $response ) ) {
1450 - // The download failed.
1340 + // Download plugin now.
1341 + $response = self::download_and_activate();
1342 + if ( is_array( $response ) && isset( $response['success'] ) ) {
1451 1343 return $response;
1452 1344 }
1453 1345 }
1454 1346
1455 1347 // If empty license, save it now.
1456 - if ( ! self::get_pro_license() && function_exists( 'load_formidable_pro' ) ) {
1348 + if ( empty( self::get_pro_license() ) && function_exists( 'load_formidable_pro' ) ) {
1457 1349 load_formidable_pro();
1458 1350 $license = stripslashes( FrmAppHelper::get_param( 'key', '', 'request', 'sanitize_text_field' ) );
1459 -
1460 1351 if ( ! $license ) {
1461 1352 return array(
1462 1353 'success' => false,
1463 1354 'error' => 'That site does not have a valid license key.',
@@ -1464,9 +1355,8 @@
1464 1355 );
1465 1356 }
1466 1357
1467 1358 $response = FrmAddon::activate_license_for_plugin( $license, 'formidable_pro' );
1468 -
1469 1359 if ( ! $response['success'] ) {
1470 1360 // Could not activate license.
1471 1361 return $response;
1472 1362 }
@@ -1477,32 +1367,8 @@
1477 1367 );
1478 1368 }
1479 1369
1480 1370 /**
1481 - * @since 6.8.3
1482 - *
1483 - * @return array|true
1484 - */
1485 - private static function maybe_download_and_activate() {
1486 - if ( ! self::$plugin ) {
1487 - return array(
1488 - 'success' => false,
1489 - 'message' => __( 'The plugin download was not found.', 'formidable' ),
1490 - );
1491 - }
1492 -
1493 - // Download plugin now.
1494 - $response = self::download_and_activate();
1495 -
1496 - if ( is_array( $response ) && isset( $response['success'] ) ) {
1497 - // The download failed.
1498 - return $response;
1499 - }
1500 -
1501 - return true;
1502 - }
1503 -
1504 - /**
1505 1371 * Render a conditional action button for a specified plugin
1506 1372 *
1507 1373 * @since 4.09
1508 1374 *
@@ -1507,9 +1373,8 @@
1507 1373 * @since 4.09
1508 1374 *
1509 1375 * @param string $plugin
1510 1376 * @param array|string $upgrade_link_args
1511 - *
1512 1377 * @return void
1513 1378 */
1514 1379 public static function conditional_action_button( $plugin, $upgrade_link_args ) {
1515 1380 if ( is_callable( 'FrmProAddonsController::conditional_action_button' ) ) {
@@ -1540,13 +1405,12 @@
1540 1405 * @param array $atts {
1541 1406 * Button attributes.
1542 1407 *
1543 1408 * @type array $addon
1544 - * @type false|string $license_type
1409 + * @type string|false $license_type
1545 1410 * @type string $plan_required
1546 1411 * @type string $upgrade_link
1547 1412 * }
1548 - *
1549 1413 * @return void
1550 1414 */
1551 1415 public static function show_conditional_action_button( $atts ) {
1552 1416 if ( is_callable( 'FrmProAddonsController::show_conditional_action_button' ) ) {
@@ -1560,16 +1424,15 @@
1560 1424 /**
1561 1425 * @since 4.09.01
1562 1426 *
1563 1427 * @param array|false $addon
1564 - * @param array|string $upgrade_link
1428 + * @param string|array $upgrade_link
1565 1429 *
1566 1430 * @return void
1567 1431 */
1568 - public static function addon_upgrade_link( $addon, $upgrade_link ) {
1432 + protected static function addon_upgrade_link( $addon, $upgrade_link ) {
1569 1433 $atts = is_array( $upgrade_link ) ? $upgrade_link : array();
1570 1434 $upgrade_link = is_array( $upgrade_link ) ? $upgrade_link['link'] : $upgrade_link;
1571 - $text = ! empty( $atts['text'] ) ? $atts['text'] : __( 'Upgrade Now', 'formidable' );
1572 1435
1573 1436 if ( $addon ) {
1574 1437 $upgrade_link .= '&utm_content=' . $addon['slug'];
1575 1438 }
@@ -1579,19 +1442,16 @@
1579 1442 $upgrade_link = FrmAppHelper::admin_upgrade_link( 'addons', $addon['link'] );
1580 1443 }
1581 1444
1582 1445 $class = ! empty( $atts['class'] ) ? $atts['class'] : '';
1583 -
1584 - if ( ! str_contains( $class, 'frm-button' ) ) {
1446 + if ( strpos( $class, 'frm-button' ) === false ) {
1585 1447 $class .= ' frm-button-secondary frm-button-sm';
1586 1448 }
1587 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1588 1449 ?>
1589 - <a class="install-now button <?php echo esc_attr( $class ); ?>" href="<?php echo esc_url( $upgrade_link ); ?>" target="_blank" rel="noopener" aria-label="<?php esc_attr_e( 'Upgrade Now', 'formidable' ); ?>"><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1590 - <?php echo esc_html( $text ); ?>
1450 + <a class="install-now button <?php echo esc_attr( $class ); ?>" href="<?php echo esc_url( $upgrade_link ); ?>" target="_blank" rel="noopener" aria-label="<?php esc_attr_e( 'Upgrade Now', 'formidable' ); ?>">
1451 + <?php esc_html_e( 'Upgrade Now', 'formidable' ); ?>
1591 1452 </a>
1592 1453 <?php
1593 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1594 1454 }
1595 1455
1596 1456 /**
1597 1457 * @since 3.04.02
@@ -1601,9 +1461,8 @@
1601 1461 public static function ajax_install_addon() {
1602 1462 self::install_addon_permissions();
1603 1463
1604 1464 $result = self::download_and_activate();
1605 -
1606 1465 if ( isset( $result['success'] ) && ! $result['success'] ) {
1607 1466 echo json_encode( $result );
1608 1467 wp_die();
1609 1468 }
@@ -1636,8 +1495,9 @@
1636 1495 $allowed_url_list = apply_filters( 'frm_allowed_external_urls', $allowed_url_list );
1637 1496
1638 1497 if ( ! is_array( $allowed_url_list ) ) {
1639 1498 _doing_it_wrong( __METHOD__, 'Only an array of URLs could be used within this filter.', '6.3.1' );
1499 +
1640 1500 return array();
1641 1501 }
1642 1502
1643 1503 return $allowed_url_list;
@@ -1647,10 +1507,8 @@
1647 1507 * Gets required plan for an addon.
1648 1508 *
1649 1509 * @since 6.4.2
1650 1510 *
1651 - * @param int|string $addon_id
1652 - *
1653 1511 * @return string Empty string if no plan is required for active license.
1654 1512 */
1655 1513 public static function get_addon_required_plan( $addon_id ) {
1656 1514 $api = new FrmFormApi();
@@ -1661,10 +1519,114 @@
1661 1519 $requires = FrmFormsHelper::get_plan_required( $dates );
1662 1520 }
1663 1521
1664 1522 if ( ! isset( $requires ) || ! is_string( $requires ) ) {
1665 - return '';
1523 + $requires = '';
1666 1524 }
1667 1525
1668 1526 return $requires;
1527 + }
1528 +
1529 + /**
1530 + * @since 4.06.02
1531 + *
1532 + * @deprecated 4.09.01
1533 + *
1534 + * @return void
1535 + */
1536 + public static function ajax_multiple_addons() {
1537 + FrmDeprecated::ajax_multiple_addons();
1538 + }
1539 +
1540 + /**
1541 + * @since 3.04.03
1542 + * @deprecated 3.06
1543 + * @codeCoverageIgnore
1544 + * @return array
1545 + */
1546 + public static function error_for_license( $license ) {
1547 + return FrmDeprecated::error_for_license( $license );
1548 + }
1549 +
1550 + /**
1551 + * @since 3.04.03
1552 + * @deprecated 3.06
1553 + * @codeCoverageIgnore
1554 + */
1555 + public static function get_pro_updater() {
1556 + return FrmDeprecated::get_pro_updater();
1557 + }
1558 +
1559 + /**
1560 + * @since 3.04.03
1561 + * @deprecated 3.06
1562 + * @codeCoverageIgnore
1563 + *
1564 + * @return array
1565 + */
1566 + public static function get_addon_info( $license = '' ) {
1567 + return FrmDeprecated::get_addon_info( $license );
1568 + }
1569 +
1570 + /**
1571 + * @since 3.04.03
1572 + * @deprecated 3.06
1573 + * @codeCoverageIgnore
1574 + *
1575 + * @return string
1576 + */
1577 + public static function get_cache_key( $license ) {
1578 + return FrmDeprecated::get_cache_key( $license );
1579 + }
1580 +
1581 + /**
1582 + * @since 3.04.03
1583 + *
1584 + * @deprecated 3.06
1585 + *
1586 + * @codeCoverageIgnore
1587 + *
1588 + * @return void
1589 + */
1590 + public static function reset_cached_addons( $license = '' ) {
1591 + FrmDeprecated::reset_cached_addons( $license );
1592 + }
1593 +
1594 + /**
1595 + * @since 2.03.08
1596 + * @deprecated 3.04.03
1597 + * @codeCoverageIgnore
1598 + *
1599 + * @param boolean $return
1600 + * @param string $package
1601 + *
1602 + * @return boolean
1603 + */
1604 + public static function add_shorten_edd_filename_filter( $return, $package ) {
1605 + return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
1606 + }
1607 +
1608 + /**
1609 + * @since 2.03.08
1610 + * @deprecated 3.04.03
1611 + * @codeCoverageIgnore
1612 + *
1613 + * @param string $filename
1614 + * @param string $ext
1615 + *
1616 + * @return string
1617 + */
1618 + public static function shorten_edd_filename( $filename, $ext ) {
1619 + return FrmDeprecated::shorten_edd_filename( $filename, $ext );
1620 + }
1621 +
1622 + /**
1623 + * @deprecated 3.04.03
1624 + *
1625 + * @codeCoverageIgnore
1626 + *
1627 + * @return void
1628 + */
1629 + public static function get_licenses() {
1630 + FrmDeprecated::get_licenses();
1669 1631 }
1670 1632 }