PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.12
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.12
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 +367 -546 6.356.12 View file →
@@ -7,95 +7,13 @@
7 7
8 8 /**
9 9 * @var string
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 56 $api = new FrmFormApi();
150 57 $errors = $api->get_error_from_response( $addons );
151 - $license_type = $addons['error']['type'] ?? '';
58 + $license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
152 59 unset( $addons['error'] );
153 60 }
154 61
155 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,114 +72,19 @@
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 );
@@ -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;
@@ -309,9 +119,11 @@
309 119 *
310 120 * @return int Count of addons.
311 121 */
312 122 public static function get_addons_count() {
313 - return count( self::get_api_addons() );
123 + $addons = self::get_api_addons();
124 +
125 + return count( $addons );
314 126 }
315 127
316 128 /**
317 129 * If the API is unable to connect, show something on the addons page
@@ -316,9 +128,8 @@
316 128 /**
317 129 * If the API is unable to connect, show something on the addons page
318 130 *
319 131 * @since 3.04.03
320 - *
321 132 * @return array
322 133 */
323 134 protected static function fallback_plugin_list() {
324 135 $list = array(
@@ -329,19 +140,19 @@
329 140 '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 141 ),
331 142 'mailchimp' => array(
332 143 '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
144 + '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 145 ),
335 146 'registration' => array(
336 147 'title' => 'User Registration Forms',
337 148 '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
149 + '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 150 ),
340 151 'paypal' => array(
341 152 'title' => 'PayPal Standard Forms',
342 153 '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
154 + '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 155 ),
345 156 'stripe' => array(
346 157 'title' => 'Stripe Forms',
347 158 'docs' => 'knowledgebase/stripe/',
@@ -373,9 +184,9 @@
373 184 'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
374 185 ),
375 186 'zapier' => array(
376 187 '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
188 + '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 189 ),
379 190 'signature' => array(
380 191 'title' => 'Digital Signature Forms',
381 192 'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
@@ -408,9 +219,8 @@
408 219 foreach ( $list as $k => $info ) {
409 220 $info['slug'] = $k;
410 221 $list[ $k ] = array_merge( $defaults, $info );
411 222 }
412 -
413 223 return $list;
414 224 }
415 225
416 226 /**
@@ -416,28 +226,25 @@
416 226 /**
417 227 * If Pro is missing but has been authenticated, include a download URL
418 228 *
419 229 * @since 3.04.03
420 - *
421 230 * @return string
422 231 */
423 232 public static function get_pro_download_url() {
424 - $api = new FrmFormApi( self::get_pro_license() );
233 + $license = self::get_pro_license();
234 + $api = new FrmFormApi( $license );
425 235 $downloads = $api->get_api_info();
426 236 $pro = self::get_pro_from_addons( $downloads );
427 237
428 - return $pro['url'] ?? '';
238 + return isset( $pro['url'] ) ? $pro['url'] : '';
429 239 }
430 240
431 241 /**
432 242 * @since 4.08
433 - *
434 - * @return string
435 243 */
436 244 public static function get_pro_license() {
437 245 $pro_cred_store = 'frmpro-credentials';
438 246 $pro_wpmu_store = 'frmpro-wpmu-sitewide';
439 -
440 247 if ( is_multisite() && get_site_option( $pro_wpmu_store ) ) {
441 248 $creds = get_site_option( $pro_cred_store );
442 249 } else {
443 250 $creds = get_option( $pro_cred_store );
@@ -447,18 +254,16 @@
447 254 return '';
448 255 }
449 256
450 257 $license = $creds['license'];
451 -
452 - if ( ! $license ) {
258 + if ( empty( $license ) ) {
453 259 return '';
454 260 }
455 261
456 - if ( str_contains( $license, '-' ) ) {
457 - // This is a fix for licenses saved in the past
458 - return strtoupper( $license );
262 + if ( strpos( $license, '-' ) ) {
263 + // this is a fix for licenses saved in the past
264 + $license = strtoupper( $license );
459 265 }
460 -
461 266 return $license;
462 267 }
463 268
464 269 /**
@@ -464,26 +269,20 @@
464 269 /**
465 270 * @since 4.08
466 271 *
467 272 * @param array $addons
468 - *
469 273 * @return array
470 274 */
471 275 protected static function get_pro_from_addons( $addons ) {
472 - return $addons['93790'] ?? array();
276 + return isset( $addons['93790'] ) ? $addons['93790'] : array();
473 277 }
474 278
475 279 /**
476 280 * @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 281 */
483 - public static function license_type( $force_type = false ) {
282 + public static function license_type() {
484 283 if ( is_callable( 'FrmProAddonsController::license_type' ) ) {
485 - return FrmProAddonsController::license_type( $force_type );
284 + return FrmProAddonsController::license_type();
486 285 }
487 286
488 287 return 'free';
489 288 }
@@ -488,122 +287,8 @@
488 287 return 'free';
489 288 }
490 289
491 290 /**
492 - * Determine the license status for payment fee decisions.
493 - *
494 - * Mirrors determine_status_from_license_details in the Stripe Connect service,
495 - * including its 2016-04-26 grandfathered cutoff. Square and PayPal Commerce use a
496 - * later cutoff, so read their fees through payment_fees_apply instead.
497 - *
498 - * @since 6.31
499 - *
500 - * @return string 'active', 'expired', or 'free'.
501 - */
502 - public static function get_payment_license_status() {
503 - $version_info = self::get_primary_license_info();
504 -
505 - if ( ! $version_info ) {
506 - return 'free';
507 - }
508 -
509 - $error = $version_info['error'] ?? array();
510 -
511 - if ( is_array( $error ) && 'expired' === ( $error['code'] ?? '' ) ) {
512 - return 'expired';
513 - }
514 -
515 - if ( self::is_grandfathered_license() ) {
516 - $expires = self::get_grandfathered_expiration( $version_info );
517 -
518 - if ( $expires && gmdate( 'Y-m-d', $expires ) < '2016-04-26' ) {
519 - return 'free';
520 - }
521 - }
522 -
523 - if ( in_array( self::license_type( true ), array( 'elite', 'business' ), true ) ) {
524 - return 'active';
525 - }
526 -
527 - return 'free';
528 - }
529 -
530 - /**
531 - * Check if a connect service charges its per-transaction fee for this license.
532 - *
533 - * Square and PayPal Commerce launched long after lifetime licenses stopped being
534 - * sold, so their services charge every grandfathered license. Stripe's predates
535 - * them and exempts most of them, which get_payment_license_status mirrors.
536 - *
537 - * @since 6.34
538 - *
539 - * @param string $service The connect service: 'stripe', 'square', or 'paypal'.
540 - *
541 - * @return bool
542 - */
543 - public static function payment_fees_apply( $service ) {
544 - if ( 'active' !== self::get_payment_license_status() ) {
545 - return true;
546 - }
547 -
548 - if ( in_array( $service, array( 'square', 'paypal' ), true ) ) {
549 - return self::is_grandfathered_license();
550 - }
551 -
552 - return false;
553 - }
554 -
555 - /**
556 - * Check if the primary license is grandfathered.
557 - *
558 - * The API reports this on the Pro add-on itself, the same place
559 - * FrmProAddonsController::license_type reads it from. Older responses put it
560 - * in the top level error instead, so check both.
561 - *
562 - * @since 6.34
563 - *
564 - * @return bool
565 - */
566 - public static function is_grandfathered_license() {
567 - $version_info = self::get_primary_license_info();
568 -
569 - if ( ! $version_info ) {
570 - return false;
571 - }
572 -
573 - $error = $version_info['error'] ?? array();
574 -
575 - if ( is_array( $error ) && 'grandfathered' === ( $error['code'] ?? '' ) ) {
576 - return true;
577 - }
578 -
579 - $pro = self::get_pro_from_addons( $version_info );
580 -
581 - return 'grandfathered' === ( $pro['code'] ?? '' );
582 - }
583 -
584 - /**
585 - * Get the expiration timestamp reported alongside a grandfathered license.
586 - *
587 - * @since 6.34
588 - *
589 - * @param array $version_info The license info from get_primary_license_info.
590 - *
591 - * @return int
592 - */
593 - private static function get_grandfathered_expiration( $version_info ) {
594 - $error = $version_info['error'] ?? array();
595 -
596 - if ( is_array( $error ) && ! empty( $error['expires'] ) ) {
597 - return (int) $error['expires'];
598 - }
599 -
600 - $pro = self::get_pro_from_addons( $version_info );
601 -
602 - return (int) ( $pro['expires'] ?? 0 );
603 - }
604 -
605 - /**
606 291 * @since 4.0.01
607 292 *
608 293 * @return bool
609 294 */
@@ -608,21 +293,18 @@
608 293 * @return bool
609 294 */
610 295 public static function is_license_expired() {
611 296 $version_info = self::get_primary_license_info();
612 -
613 297 if ( ! isset( $version_info['error'] ) ) {
614 298 return false;
615 299 }
616 300
617 - $expires = $version_info['error']['expires'] ?? 0;
618 -
619 - if ( ! $expires || $expires > time() ) {
301 + $expires = isset( $version_info['error']['expires'] ) ? $version_info['error']['expires'] : 0;
302 + if ( empty( $expires ) || $expires > time() ) {
620 303 return false;
621 304 }
622 305
623 306 $rate_limited = ! empty( $version_info['response_code'] ) && 429 === (int) $version_info['response_code'];
624 -
625 307 if ( $rate_limited ) {
626 308 // Do not return false positives for rate limited responses.
627 309 return false;
628 310 }
@@ -637,13 +319,11 @@
637 319 * @return array|false
638 320 */
639 321 public static function get_primary_license_info() {
640 322 $installed_addons = apply_filters( 'frm_installed_addons', array() );
641 -
642 - if ( ! $installed_addons || ! isset( $installed_addons['formidable_pro'] ) ) {
323 + if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
643 324 return false;
644 325 }
645 -
646 326 $installed_addons = array(
647 327 'formidable_pro' => $installed_addons['formidable_pro'],
648 328 );
649 329
@@ -651,12 +331,8 @@
651 331 }
652 332
653 333 /**
654 334 * @since 3.04.03
655 - *
656 - * @param mixed $transient
657 - *
658 - * @return object
659 335 */
660 336 public static function check_update( $transient ) {
661 337 if ( ! FrmAppHelper::pro_is_installed() ) {
662 338 // Don't make any changes if only Lite is installed.
@@ -667,10 +343,9 @@
667 343 $transient = new stdClass();
668 344 }
669 345
670 346 $installed_addons = apply_filters( 'frm_installed_addons', array() );
671 -
672 - if ( ! $installed_addons ) {
347 + if ( empty( $installed_addons ) ) {
673 348 return $transient;
674 349 }
675 350
676 351 $version_info = self::fill_update_addon_info( $installed_addons );
@@ -684,20 +359,19 @@
684 359 continue;
685 360 }
686 361
687 362 $folder = $plugin->plugin;
688 -
689 - if ( ! $folder ) {
363 + if ( empty( $folder ) ) {
690 364 continue;
691 365 }
692 366
693 367 if ( ! self::is_installed( $folder ) ) {
694 - // Don't show an update if the plugin isn't installed
368 + // don't show an update if the plugin isn't installed
695 369 continue;
696 370 }
697 371
698 - $wp_plugin = $wp_plugins[ $folder ] ?? array();
699 - $wp_version = $wp_plugin['Version'] ?? '1.0';
372 + $wp_plugin = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
373 + $wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
700 374 $plugin->slug = explode( '/', $folder )[0];
701 375
702 376 if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
703 377 $transient->response[ $folder ] = $plugin;
@@ -705,8 +379,9 @@
705 379 $transient->no_update[ $folder ] = $plugin;
706 380 }
707 381
708 382 $transient->checked[ $folder ] = $wp_version;
383 +
709 384 }//end foreach
710 385
711 386 return $transient;
712 387 }
@@ -716,9 +391,8 @@
716 391 * Because this gets called on "pre_set_site_transient_update_plugins" an old version of FrmAppHelper may be loaded on plugin update.
717 392 * This means that trying to access FrmAppHelper::get_plugins when upgrading from a Lite version before v5.5 results in a one-off error.
718 393 *
719 394 * @since 5.5.2
720 - *
721 395 * @return array
722 396 */
723 397 protected static function get_plugins() {
724 398 if ( ! function_exists( 'get_plugins' ) ) {
@@ -753,49 +427,43 @@
753 427 $version_info = array();
754 428
755 429 foreach ( $installed_addons as $addon ) {
756 430 if ( $addon->store_url !== 'https://formidableforms.com' ) {
757 - // Check if this is a third-party addon
431 + // check if this is a third-party addon
758 432 continue;
759 433 }
760 434
761 435 $new_license = $addon->license;
762 -
763 - if ( ! $new_license || in_array( $new_license, $checked_licenses, true ) ) {
436 + if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
764 437 continue;
765 438 }
766 439
767 440 $checked_licenses[] = $new_license;
768 - $api = new FrmFormApi( $new_license );
769 441
770 - if ( ! $version_info ) {
442 + $api = new FrmFormApi( $new_license );
443 + if ( empty( $version_info ) ) {
771 444 $version_info = $api->get_api_info();
772 445 continue;
773 446 }
774 447
775 448 $plugin = $api->get_addon_for_license( $addon, $version_info );
776 -
777 - if ( ! $plugin ) {
449 + if ( empty( $plugin ) ) {
778 450 continue;
779 451 }
780 452
781 - $download_id = $plugin['id'] ?? 0;
453 + $download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
454 + if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
455 + // if this addon is using its own license, get the update url
456 + $addon_info = $api->get_api_info();
782 457
783 - if ( ! $download_id || isset( $version_info[ $download_id ]['package'] ) ) {
784 - continue;
458 + $version_info[ $download_id ] = $addon_info[ $download_id ];
459 + if ( isset( $addon_info['error'] ) ) {
460 + $version_info[ $download_id ]['error'] = array(
461 + 'message' => $addon_info['error']['message'],
462 + 'code' => $addon_info['error']['code'],
463 + );
464 + }
785 465 }
786 -
787 - // If this addon is using its own license, get the update url
788 - $addon_info = $api->get_api_info();
789 -
790 - $version_info[ $download_id ] = $addon_info[ $download_id ];
791 -
792 - if ( isset( $addon_info['error'] ) ) {
793 - $version_info[ $download_id ]['error'] = array(
794 - 'message' => $addon_info['error']['message'],
795 - 'code' => $addon_info['error']['code'],
796 - );
797 - }
798 466 }//end foreach
799 467
800 468 return $version_info;
801 469 }
@@ -803,11 +471,9 @@
803 471 /**
804 472 * Get the action link for an addon that isn't active.
805 473 *
806 474 * @since 3.06.03
807 - *
808 475 * @param string $plugin The plugin slug.
809 - *
810 476 * @return array
811 477 */
812 478 public static function install_link( $plugin ) {
813 479 $link = array();
@@ -829,9 +495,9 @@
829 495 'categories' => $addon['categories'],
830 496 );
831 497 }
832 498
833 - if ( $link ) {
499 + if ( ! empty( $link ) ) {
834 500 $link['status'] = $addon['status']['type'];
835 501 }
836 502 } elseif ( current_user_can( 'activate_plugins' ) && self::is_installed( 'formidable-' . $plugin . '/formidable-' . $plugin . '.php' ) ) {
837 503 $link = array(
@@ -843,81 +509,34 @@
843 509 return $link;
844 510 }
845 511
846 512 /**
847 - * Get the JSON-encoded install data for a plugin update.
848 - *
849 - * @since 6.29
850 - *
851 - * @param string $addon_slug The addon slug (e.g. 'pro', 'dates').
852 - *
853 - * @return string JSON-encoded install data, or empty string if no URL is available.
854 - */
855 - public static function get_update_install_data( $addon_slug ) {
856 - $upgrading = self::install_link( $addon_slug );
857 -
858 - if ( isset( $upgrading['class'] ) && 'frm-install-addon' === $upgrading['class'] ) {
859 - return (string) json_encode( $upgrading );
860 - }
861 -
862 - if ( 'pro' === $addon_slug ) {
863 - $download_url = self::get_pro_download_url();
864 - $plugin_file = 'formidable-pro/formidable-pro.php';
865 - } else {
866 - $addon_data = self::get_addon( $addon_slug );
867 - $download_url = $addon_data && ! empty( $addon_data['url'] ) ? $addon_data['url'] : '';
868 - $plugin_file = $addon_data && ! empty( $addon_data['plugin'] ) ? $addon_data['plugin'] : 'formidable-' . $addon_slug . '/formidable-' . $addon_slug . '.php';
869 - }
870 -
871 - if ( ! $download_url ) {
872 - $update_plugins = get_site_transient( 'update_plugins' );
873 - $plugin_update = $update_plugins->response[ $plugin_file ] ?? null;
874 - $download_url = $plugin_update && ! empty( $plugin_update->package ) ? $plugin_update->package : '';
875 - }
876 -
877 - return $download_url ? (string) json_encode(
878 - array(
879 - 'url' => $download_url,
880 - 'class' => 'frm-install-addon',
881 - )
882 - ) : '';
883 - }
884 -
885 - /**
886 513 * @since 4.09
887 - *
888 514 * @param string $plugin The plugin slug.
889 - *
890 515 * @return array|false
891 516 */
892 517 public static function get_addon( $plugin ) {
893 518 $addons = self::get_api_addons();
894 519 self::prepare_addons( $addons );
895 -
896 520 foreach ( $addons as $addon ) {
897 521 $slug = explode( '/', $addon['plugin'] );
898 -
899 522 if ( $slug[0] === 'formidable-' . $plugin ) {
900 523 return $addon;
901 524 }
902 525 }
903 -
904 526 return false;
905 527 }
906 528
907 529 /**
908 530 * @since 4.09
909 - *
910 531 * @return string
911 532 */
912 533 protected static function get_license_type() {
913 534 $license_type = '';
914 535 $addons = self::get_api_addons();
915 -
916 536 if ( isset( $addons['error'] ) && isset( $addons['error']['type'] ) ) {
917 - return $addons['error']['type'];
537 + $license_type = $addons['error']['type'];
918 538 }
919 -
920 539 return $license_type;
921 540 }
922 541
923 542 /**
@@ -930,12 +549,11 @@
930 549 */
931 550 public static function get_addon_for_license( $addons, $license ) {
932 551 $download_id = $license->download_id;
933 552 $plugin = array();
934 -
935 - if ( ! $download_id && $addons ) {
553 + if ( empty( $download_id ) && ! empty( $addons ) ) {
936 554 foreach ( $addons as $addon ) {
937 - if ( 0 === strcasecmp( $license->plugin_name, $addon['title'] ) ) {
555 + if ( strtolower( $license->plugin_name ) === strtolower( $addon['title'] ) ) {
938 556 return $addon;
939 557 }
940 558 }
941 559 } elseif ( isset( $addons[ $download_id ] ) ) {
@@ -945,33 +563,29 @@
945 563 return $plugin;
946 564 }
947 565
948 566 /**
949 - * @param array $addons
950 - *
951 567 * @return void
952 568 */
953 569 protected static function prepare_addons( &$addons ) {
954 - // Reset categories to prevent count accumulation across multiple calls.
955 - self::$categories = array();
956 -
957 570 $activate_url = '';
958 -
959 571 if ( current_user_can( 'activate_plugins' ) ) {
960 572 $activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
961 573 }
962 574
963 575 $loop_addons = $addons;
964 -
965 576 foreach ( $loop_addons as $id => $addon ) {
966 577 if ( is_numeric( $id ) ) {
967 578 $slug = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
968 579 $file_name = $addon['plugin'];
969 580 } else {
970 - $slug = $id;
971 - $base_file = $addon['file'] ?? 'formidable-' . $slug;
581 + $slug = $id;
582 + if ( isset( $addon['file'] ) ) {
583 + $base_file = $addon['file'];
584 + } else {
585 + $base_file = 'formidable-' . $slug;
586 + }
972 587 $file_name = $base_file . '/' . $base_file . '.php';
973 -
974 588 if ( ! isset( $addon['plugin'] ) ) {
975 589 $addon['plugin'] = $file_name;
976 590 }
977 591 }
@@ -976,17 +590,10 @@
976 590 }
977 591 }
978 592
979 593 $addon['installed'] = self::is_installed( $file_name );
980 -
981 - if ( 'highrise' === $slug && ! $addon['installed'] ) {
982 - unset( $addons[ $id ] );
983 - continue;
984 - }
985 -
986 594 if ( $addon['installed'] && 'formidable-views/formidable-views.php' === $file_name ) {
987 595 $active_views_version = self::get_active_views_version();
988 -
989 596 if ( false !== $active_views_version && $slug !== $active_views_version ) {
990 597 $addon['installed'] = false;
991 598 }
992 599 }
@@ -992,9 +599,9 @@
992 599 }
993 600
994 601 $addon['activate_url'] = '';
995 602
996 - if ( $addon['installed'] && $activate_url && ! self::is_plugin_active( $file_name, $slug ) ) {
603 + if ( $addon['installed'] && ! empty( $activate_url ) && ! self::is_plugin_active( $file_name, $slug ) ) {
997 604 $addon['activate_url'] = add_query_arg(
998 605 array(
999 606 '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
1000 607 'plugin' => $file_name,
@@ -1010,21 +617,16 @@
1010 617
1011 618 if ( ! isset( $addon['link'] ) ) {
1012 619 $addon['link'] = 'downloads/' . $slug . '/';
1013 620 }
621 + self::prepare_addon_link( $addon['link'] );
1014 622
1015 - self::prepare_addon_link( $addon['link'] );
1016 623 self::set_addon_status( $addon );
1017 - self::set_categories( $addon );
1018 -
1019 624 $addons[ $id ] = $addon;
1020 625 }//end foreach
1021 626 }
1022 627
1023 628 /**
1024 - * @param string $file_name
1025 - * @param string $slug
1026 - *
1027 629 * @return bool
1028 630 */
1029 631 private static function is_plugin_active( $file_name, $slug ) {
1030 632 if ( 'formidable-views/formidable-views.php' === $file_name ) {
@@ -1039,9 +641,8 @@
1039 641 private static function get_active_views_version() {
1040 642 if ( ! is_callable( 'FrmViewsAppHelper::plugin_version' ) ) {
1041 643 return false;
1042 644 }
1043 -
1044 645 $plugin_version = FrmViewsAppHelper::plugin_version();
1045 646 return version_compare( $plugin_version, '5.0', '>=' ) ? 'visual-views' : 'views';
1046 647 }
1047 648
@@ -1047,25 +648,22 @@
1047 648
1048 649 /**
1049 650 * @since 3.04.02
1050 651 *
1051 - * @param string $link
1052 - *
1053 652 * @return void
1054 653 */
1055 654 protected static function prepare_addon_link( &$link ) {
1056 655 $site_url = 'https://formidableforms.com/';
1057 -
1058 - if ( ! str_starts_with( $link, 'http' ) ) {
656 + if ( strpos( $link, 'http' ) !== 0 ) {
1059 657 $link = $site_url . $link;
1060 658 }
1061 -
1062 - $link = FrmAppHelper::make_affiliate_url( $link );
1063 -
1064 - $utm = array(
1065 - 'campaign' => 'addons',
659 + $link = FrmAppHelper::make_affiliate_url( $link );
660 + $query_args = array(
661 + 'utm_source' => 'WordPress',
662 + 'utm_medium' => 'addons',
663 + 'utm_campaign' => 'liteplugin',
1066 664 );
1067 - $link = FrmAppHelper::maybe_add_missing_utm( $link, $utm );
665 + $link = add_query_arg( $query_args, $link );
1068 666 }
1069 667
1070 668 /**
1071 669 * Add the status to the addon array. Status options are:
@@ -1072,10 +670,8 @@
1072 670 * installed, active, not installed
1073 671 *
1074 672 * @since 3.04.02
1075 673 *
1076 - * @param array $addon
1077 - *
1078 674 * @return void
1079 675 */
1080 676 protected static function set_addon_status( &$addon ) {
1081 677 if ( ! empty( $addon['activate_url'] ) ) {
@@ -1096,8 +692,218 @@
1096 692 }
1097 693 }
1098 694
1099 695 /**
696 + * @return void
697 + */
698 + public static function upgrade_to_pro() {
699 + FrmAppHelper::include_svg();
700 +
701 + $link_parts = array(
702 + 'medium' => 'upgrade',
703 + 'content' => 'button',
704 + );
705 +
706 + $features = array(
707 + 'Display Entries' => array(
708 + array(
709 + 'label' => 'Display form data with virtually limitless views',
710 + 'link' => array(
711 + 'content' => 'views',
712 + 'param' => 'views-display-form-data',
713 + ),
714 + 'lite' => false,
715 + ),
716 + array(
717 + 'label' => 'Generate graphs and stats based on your submitted data',
718 + 'link' => array(
719 + 'content' => 'graphs',
720 + 'param' => 'statistics-graphs-wordpress-forms',
721 + ),
722 + 'lite' => false,
723 + ),
724 + ),
725 + 'Entry Management' => array(
726 + array(
727 + 'label' => 'Import entries from a CSV',
728 + 'link' => array(
729 + 'content' => 'import-entries',
730 + 'param' => 'importing-exporting-wordpress-forms',
731 + ),
732 + 'lite' => false,
733 + ),
734 + array(
735 + 'label' => 'Logged-in users can save drafts and return later',
736 + 'link' => array(
737 + 'content' => 'save-drafts',
738 + 'param' => 'save-drafts-wordpress-form',
739 + ),
740 + 'lite' => false,
741 + ),
742 + array(
743 + 'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
744 + 'link' => array(
745 + 'content' => 'front-edit',
746 + 'param' => 'wordpress-front-end-editing',
747 + ),
748 + 'lite' => false,
749 + ),
750 + array(
751 + 'label' => 'View form submissions from the back-end',
752 + 'lite' => true,
753 + ),
754 + array(
755 + 'label' => 'Export your entries to a CSV',
756 + 'lite' => true,
757 + ),
758 + ),
759 + 'Form Building' => array(
760 + array(
761 + 'label' => 'Save a calculated value into a field',
762 + 'link' => array(
763 + 'content' => 'calculations',
764 + 'param' => 'field-calculations-wordpress-form',
765 + ),
766 + 'lite' => false,
767 + ),
768 + array(
769 + 'label' => 'Allow multiple file uploads',
770 + 'link' => array(
771 + 'content' => 'file-uploads',
772 + 'param' => 'wordpress-multi-file-upload-fields',
773 + ),
774 + 'lite' => false,
775 + ),
776 + array(
777 + 'label' => 'Repeat sections of fields',
778 + 'link' => array(
779 + 'content' => 'repeaters',
780 + 'param' => 'repeatable-sections-forms',
781 + ),
782 + 'lite' => false,
783 + ),
784 + array(
785 + 'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
786 + 'link' => array(
787 + 'content' => 'conditional-logic',
788 + 'param' => 'conditional-logic-wordpress-forms',
789 + ),
790 + 'lite' => false,
791 + ),
792 + array(
793 + 'label' => 'Confirmation fields',
794 + 'link' => array(
795 + 'content' => 'confirmation-fields',
796 + 'param' => 'confirmation-fields-wordpress-forms',
797 + ),
798 + 'lite' => false,
799 + ),
800 + array(
801 + 'label' => 'Multi-paged forms',
802 + 'link' => array(
803 + 'content' => 'page-breaks',
804 + 'param' => 'wordpress-multi-page-forms',
805 + ),
806 + 'lite' => false,
807 + ),
808 + array(
809 + '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.',
810 + 'lite' => false,
811 + ),
812 + array(
813 + 'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
814 + 'lite' => true,
815 + ),
816 + array(
817 + 'label' => 'Drag & Drop Form building',
818 + 'link' => array(
819 + 'content' => 'drag-drop',
820 + 'param' => 'drag-drop-forms',
821 + ),
822 + 'lite' => true,
823 + ),
824 + array(
825 + 'label' => 'Create forms from Templates',
826 + 'link' => array(
827 + 'content' => 'form-templates',
828 + 'param' => 'wordpress-form-templates',
829 + ),
830 + 'lite' => true,
831 + ),
832 + array(
833 + 'label' => 'Import and export forms with XML',
834 + 'link' => array(
835 + 'content' => 'import',
836 + 'param' => 'importing-exporting-wordpress-forms',
837 + ),
838 + 'lite' => true,
839 + ),
840 + array(
841 + 'label' => 'Use input placeholder text in your fields that clear when typing starts.',
842 + 'lite' => true,
843 + ),
844 + ),
845 + 'Form Actions' => array(
846 + array(
847 + 'label' => 'Conditionally send your email notifications based on values in your form',
848 + 'link' => array(
849 + 'content' => 'conditional-emails',
850 + ),
851 + 'lite' => false,
852 + ),
853 + array(
854 + 'label' => 'Create and edit WordPress posts or custom posts from the front-end',
855 + 'link' => array(
856 + 'content' => 'create-posts',
857 + 'param' => 'create-posts-pages-wordpress-forms',
858 + ),
859 + 'lite' => false,
860 + ),
861 + array(
862 + 'label' => 'Send multiple emails and autoresponders',
863 + 'link' => array(
864 + 'content' => 'multiple-emails',
865 + 'param' => 'virtually-unlimited-emails',
866 + ),
867 + 'lite' => true,
868 + ),
869 + ),
870 + 'Form Appearance' => array(
871 + array(
872 + 'label' => 'Create Multiple styles for different forms',
873 + 'link' => array(
874 + 'content' => 'multiple-styles',
875 + 'param' => 'wordpress-visual-form-styler',
876 + ),
877 + 'lite' => false,
878 + ),
879 + array(
880 + 'label' => 'Customizable layout with CSS classes',
881 + 'link' => array(
882 + 'content' => 'form-layout',
883 + 'param' => 'wordpress-mobile-friendly-forms',
884 + ),
885 + 'lite' => true,
886 + ),
887 + array(
888 + 'label' => 'Customize the HTML for your forms',
889 + 'link' => array(
890 + 'content' => 'custom-html',
891 + 'param' => 'customizable-html-wordpress-form',
892 + ),
893 + 'lite' => true,
894 + ),
895 + array(
896 + 'label' => 'Style your form with the Visual Form Styler',
897 + 'lite' => true,
898 + ),
899 + ),
900 + );
901 +
902 + include FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php';
903 + }
904 +
905 + /**
1100 906 * @since 5.5.2
1101 907 *
1102 908 * @param string $plugin
1103 909 * @param string $redirect
@@ -1102,9 +908,8 @@
1102 908 * @param string $plugin
1103 909 * @param string $redirect
1104 910 * @param bool $network_wide
1105 911 * @param bool $silent
1106 - *
1107 912 * @return WP_Error|null Null on success, WP_Error on invalid file.
1108 913 */
1109 914 protected static function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
1110 915 if ( ! function_exists( 'activate_plugin' ) ) {
@@ -1119,9 +924,8 @@
1119 924 * @since 6.8
1120 925 *
1121 926 * @param string $plugin
1122 927 * @param bool $silent
1123 - *
1124 928 * @return void
1125 929 */
1126 930 protected static function deactivate_plugin( $plugin, $silent = false ) {
1127 931 if ( ! function_exists( 'deactivate_plugins' ) ) {
@@ -1135,9 +939,8 @@
1135 939 *
1136 940 * @since 6.8
1137 941 *
1138 942 * @param string $plugin
1139 - *
1140 943 * @return true|WP_Error True on success, WP_Error on invalid file.
1141 944 */
1142 945 protected static function uninstall_plugin( $plugin ) {
1143 946 if ( ! current_user_can( 'delete_plugins' ) ) {
@@ -1150,9 +953,13 @@
1150 953
1151 954 self::deactivate_plugin( $plugin, true );
1152 955 $result = delete_plugins( array( $plugin ) );
1153 956
1154 - return is_wp_error( $result ) ? $result : true;
957 + if ( is_wp_error( $result ) ) {
958 + return $result;
959 + }
960 +
961 + return true;
1155 962 }
1156 963
1157 964 /**
1158 965 * @since 5.0.10
@@ -1159,9 +966,9 @@
1159 966 *
1160 967 * @return string
1161 968 */
1162 969 protected static function get_current_plugin() {
1163 - if ( ! self::$plugin ) {
970 + if ( empty( self::$plugin ) ) {
1164 971 self::$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
1165 972 }
1166 973 return self::$plugin;
1167 974 }
@@ -1168,9 +975,9 @@
1168 975
1169 976 /**
1170 977 * @since 4.08
1171 978 *
1172 - * @return mixed[]|null
979 + * @return array|void
1173 980 */
1174 981 protected static function download_and_activate() {
1175 982 if ( is_admin() ) {
1176 983 FrmAppHelper::set_current_screen_and_hook_suffix();
@@ -1178,14 +985,12 @@
1178 985
1179 986 self::maybe_show_cred_form();
1180 987
1181 988 $installed = self::install_addon();
1182 -
1183 989 if ( is_array( $installed ) && isset( $installed['message'] ) ) {
1184 990 return $installed;
1185 991 }
1186 992 self::handle_addon_action( $installed, 'activate' );
1187 - return null;
1188 993 }
1189 994
1190 995 /**
1191 996 * @since 3.04.02
@@ -1196,9 +1001,9 @@
1196 1001 if ( ! function_exists( 'request_filesystem_credentials' ) ) {
1197 1002 include_once ABSPATH . 'wp-admin/includes/file.php';
1198 1003 }
1199 1004
1200 - // Start output buffering to catch the filesystem form if credentials are needed.
1005 + // Start output bufferring to catch the filesystem form if credentials are needed.
1201 1006 ob_start();
1202 1007
1203 1008 $show_form = false;
1204 1009 $method = '';
@@ -1215,8 +1020,9 @@
1215 1020
1216 1021 if ( $show_form ) {
1217 1022 $form = ob_get_clean();
1218 1023 $message = __( 'Sorry, your site requires FTP authentication. Please download plugins from FormidableForms.com and install them manually.', 'formidable' );
1024 + $data = $form;
1219 1025 $response = array(
1220 1026 'success' => false,
1221 1027 'message' => $message,
1222 1028 'form' => $form,
@@ -1244,10 +1050,8 @@
1244 1050 * We do not need any extra credentials if we have gotten this far,
1245 1051 * so let's install the plugin.
1246 1052 *
1247 1053 * @since 3.04.02
1248 - *
1249 - * @return array|string
1250 1054 */
1251 1055 protected static function install_addon() {
1252 1056 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1253 1057
@@ -1261,15 +1065,14 @@
1261 1065 }
1262 1066
1263 1067 // Create the plugin upgrader with our custom skin.
1264 1068 $installer = new Plugin_Upgrader( new FrmInstallerSkin() );
1265 - $installer->install( $download_url, array( 'overwrite_package' => true ) );
1069 + $installer->install( $download_url );
1266 1070
1267 1071 // Flush the cache and return the newly installed plugin basename.
1268 1072 wp_cache_flush();
1269 1073
1270 1074 $plugin = $installer->plugin_info();
1271 -
1272 1075 if ( ! $plugin ) {
1273 1076 return array(
1274 1077 'message' => 'Plugin was not installed. ' . $installer->result,
1275 1078 'success' => false,
@@ -1274,9 +1077,8 @@
1274 1077 'message' => 'Plugin was not installed. ' . $installer->result,
1275 1078 'success' => false,
1276 1079 );
1277 1080 }
1278 -
1279 1081 return $plugin;
1280 1082 }
1281 1083
1282 1084 /**
@@ -1340,9 +1142,8 @@
1340 1142 * @since 6.8
1341 1143 *
1342 1144 * @param callable $action_callback The specific add-on action to be executed.
1343 1145 * @param callable|null $response_callback Optional. The response handling callback. Default null.
1344 - *
1345 1146 * @return void
1346 1147 */
1347 1148 private static function process_addon_action( $action_callback, $response_callback = null ) {
1348 1149 self::install_addon_permissions();
@@ -1365,14 +1166,13 @@
1365 1166 * @since 6.8
1366 1167 *
1367 1168 * @param string $installed The plugin folder name with file name.
1368 1169 * @param string $action The action type ('activate', 'deactivate', 'uninstall').
1369 - *
1370 - * @return mixed[]|null
1170 + * @return array|void
1371 1171 */
1372 1172 protected static function handle_addon_action( $installed, $action ) {
1373 1173 if ( ! $installed || ! $action ) {
1374 - return null;
1174 + return;
1375 1175 }
1376 1176
1377 1177 $result = null;
1378 1178 switch ( $action ) {
@@ -1392,9 +1192,8 @@
1392 1192 if ( $result->get_error_code() !== 'no_plugin_header' ) {
1393 1193 if ( wp_doing_ajax() ) {
1394 1194 wp_send_json_error( array( 'error' => $result->get_error_message() ) );
1395 1195 }
1396 -
1397 1196 return array(
1398 1197 'message' => $result->get_error_message(),
1399 1198 'success' => false,
1400 1199 );
@@ -1408,14 +1207,17 @@
1408 1207 * @return array
1409 1208 */
1410 1209 private static function get_addon_activation_response() {
1411 1210 $activating_page = self::get_activating_page();
1412 - $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
1413 1211
1414 - return array(
1212 + $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' );
1213 +
1214 + $response = array(
1415 1215 'message' => $message,
1416 1216 'saveAndReload' => $activating_page,
1417 1217 );
1218 +
1219 + return $response;
1418 1220 }
1419 1221
1420 1222 /**
1421 1223 * Return a string that reflects the page from which the addon is being activated on,
@@ -1424,14 +1226,17 @@
1424 1226 * @return string
1425 1227 */
1426 1228 private static function get_activating_page() {
1427 1229 $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
1230 + if ( false !== strpos( $referer, 'frm_action=settings' ) ) {
1231 + return 'settings';
1232 + }
1428 1233
1429 - if ( str_contains( $referer, 'frm_action=settings' ) ) {
1430 - return 'settings';
1234 + if ( false !== strpos( $referer, 'frm_action=edit' ) ) {
1235 + return 'form_builder';
1431 1236 }
1432 1237
1433 - return str_contains( $referer, 'frm_action=edit' ) ? 'form_builder' : '';
1238 + return '';
1434 1239 }
1435 1240
1436 1241 /**
1437 1242 * Run security checks before installing
@@ -1442,14 +1247,12 @@
1442 1247 */
1443 1248 protected static function install_addon_permissions() {
1444 1249 check_ajax_referer( 'frm_ajax', 'nonce' );
1445 1250
1446 - if ( current_user_can( 'activate_plugins' ) && self::get_current_plugin() ) {
1447 - return;
1251 + if ( ! current_user_can( 'activate_plugins' ) || ! self::get_current_plugin() ) {
1252 + echo json_encode( true );
1253 + wp_die();
1448 1254 }
1449 -
1450 - echo json_encode( true );
1451 - wp_die();
1452 1255 }
1453 1256
1454 1257 /**
1455 1258 * @since 4.08
@@ -1457,14 +1260,12 @@
1457 1260 * @return string
1458 1261 */
1459 1262 public static function connect_link() {
1460 1263 $auth = get_option( 'frm_connect_token' );
1461 -
1462 - if ( ! $auth ) {
1264 + if ( empty( $auth ) ) {
1463 1265 $auth = hash( 'sha512', wp_rand() );
1464 - update_option( 'frm_connect_token', $auth, false );
1266 + update_option( 'frm_connect_token', $auth, 'no' );
1465 1267 }
1466 -
1467 1268 $page = FrmAppHelper::simple_get( 'page', 'sanitize_title', 'formidable-settings' );
1468 1269 $link = 'https://formidableforms.com/api-connect/';
1469 1270 $args = array(
1470 1271 'v' => 2,
@@ -1492,10 +1293,9 @@
1492 1293 $post_url = FrmAppHelper::get_param( 'file_url', '', 'request', 'sanitize_text_field' );
1493 1294
1494 1295 // The download link is not required if already installed.
1495 1296 $is_installed = FrmAppHelper::pro_is_included();
1496 - $file_missing = ! $is_installed && ! $post_url;
1497 -
1297 + $file_missing = ! $is_installed && empty( $post_url );
1498 1298 if ( ! $post_auth || $file_missing ) {
1499 1299 return false;
1500 1300 }
1501 1301
@@ -1500,9 +1300,13 @@
1500 1300 }
1501 1301
1502 1302 // Verify auth.
1503 1303 $auth = get_option( 'frm_connect_token' );
1504 - return $auth && hash_equals( $auth, $post_auth );
1304 + if ( empty( $auth ) || ! hash_equals( $auth, $post_auth ) ) {
1305 + return false;
1306 + }
1307 +
1308 + return true;
1505 1309 }
1506 1310
1507 1311 /**
1508 1312 * Install and/or activate the add-on file.
@@ -1513,17 +1317,17 @@
1513 1317 */
1514 1318 public static function install_addon_api() {
1515 1319 self::$plugin = FrmAppHelper::get_param( 'file_url', '', 'request', 'esc_url_raw' );
1516 1320
1321 + $error = esc_html__( 'Could not install an upgrade. Please download from formidableforms.com and install manually.', 'formidable' );
1322 +
1517 1323 // Delete so cannot replay.
1518 1324 delete_option( 'frm_connect_token' );
1519 1325
1520 1326 // It's already installed and active.
1521 1327 $active = self::activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1522 -
1523 1328 if ( is_wp_error( $active ) ) {
1524 1329 $response = self::maybe_download_and_activate();
1525 -
1526 1330 if ( is_array( $response ) ) {
1527 1331 // The download failed.
1528 1332 return $response;
1529 1333 }
@@ -1529,12 +1333,11 @@
1529 1333 }
1530 1334 }
1531 1335
1532 1336 // If empty license, save it now.
1533 - if ( ! self::get_pro_license() && function_exists( 'load_formidable_pro' ) ) {
1337 + if ( empty( self::get_pro_license() ) && function_exists( 'load_formidable_pro' ) ) {
1534 1338 load_formidable_pro();
1535 1339 $license = stripslashes( FrmAppHelper::get_param( 'key', '', 'request', 'sanitize_text_field' ) );
1536 -
1537 1340 if ( ! $license ) {
1538 1341 return array(
1539 1342 'success' => false,
1540 1343 'error' => 'That site does not have a valid license key.',
@@ -1541,9 +1344,8 @@
1541 1344 );
1542 1345 }
1543 1346
1544 1347 $response = FrmAddon::activate_license_for_plugin( $license, 'formidable_pro' );
1545 -
1546 1348 if ( ! $response['success'] ) {
1547 1349 // Could not activate license.
1548 1350 return $response;
1549 1351 }
@@ -1568,9 +1370,8 @@
1568 1370 }
1569 1371
1570 1372 // Download plugin now.
1571 1373 $response = self::download_and_activate();
1572 -
1573 1374 if ( is_array( $response ) && isset( $response['success'] ) ) {
1574 1375 // The download failed.
1575 1376 return $response;
1576 1377 }
@@ -1584,9 +1385,8 @@
1584 1385 * @since 4.09
1585 1386 *
1586 1387 * @param string $plugin
1587 1388 * @param array|string $upgrade_link_args
1588 - *
1589 1389 * @return void
1590 1390 */
1591 1391 public static function conditional_action_button( $plugin, $upgrade_link_args ) {
1592 1392 if ( is_callable( 'FrmProAddonsController::conditional_action_button' ) ) {
@@ -1621,9 +1421,8 @@
1621 1421 * @type false|string $license_type
1622 1422 * @type string $plan_required
1623 1423 * @type string $upgrade_link
1624 1424 * }
1625 - *
1626 1425 * @return void
1627 1426 */
1628 1427 public static function show_conditional_action_button( $atts ) {
1629 1428 if ( is_callable( 'FrmProAddonsController::show_conditional_action_button' ) ) {
@@ -1641,12 +1440,11 @@
1641 1440 * @param array|string $upgrade_link
1642 1441 *
1643 1442 * @return void
1644 1443 */
1645 - public static function addon_upgrade_link( $addon, $upgrade_link ) {
1444 + protected static function addon_upgrade_link( $addon, $upgrade_link ) {
1646 1445 $atts = is_array( $upgrade_link ) ? $upgrade_link : array();
1647 1446 $upgrade_link = is_array( $upgrade_link ) ? $upgrade_link['link'] : $upgrade_link;
1648 - $text = ! empty( $atts['text'] ) ? $atts['text'] : __( 'Upgrade Now', 'formidable' );
1649 1447
1650 1448 if ( $addon ) {
1651 1449 $upgrade_link .= '&utm_content=' . $addon['slug'];
1652 1450 }
@@ -1656,19 +1454,16 @@
1656 1454 $upgrade_link = FrmAppHelper::admin_upgrade_link( 'addons', $addon['link'] );
1657 1455 }
1658 1456
1659 1457 $class = ! empty( $atts['class'] ) ? $atts['class'] : '';
1660 -
1661 - if ( ! str_contains( $class, 'frm-button' ) ) {
1458 + if ( strpos( $class, 'frm-button' ) === false ) {
1662 1459 $class .= ' frm-button-secondary frm-button-sm';
1663 1460 }
1664 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1665 1461 ?>
1666 - <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 ?>
1667 - <?php echo esc_html( $text ); ?>
1462 + <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' ); ?>">
1463 + <?php esc_html_e( 'Upgrade Now', 'formidable' ); ?>
1668 1464 </a>
1669 1465 <?php
1670 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1671 1466 }
1672 1467
1673 1468 /**
1674 1469 * @since 3.04.02
@@ -1678,9 +1473,8 @@
1678 1473 public static function ajax_install_addon() {
1679 1474 self::install_addon_permissions();
1680 1475
1681 1476 $result = self::download_and_activate();
1682 -
1683 1477 if ( isset( $result['success'] ) && ! $result['success'] ) {
1684 1478 echo json_encode( $result );
1685 1479 wp_die();
1686 1480 }
@@ -1713,8 +1507,9 @@
1713 1507 $allowed_url_list = apply_filters( 'frm_allowed_external_urls', $allowed_url_list );
1714 1508
1715 1509 if ( ! is_array( $allowed_url_list ) ) {
1716 1510 _doing_it_wrong( __METHOD__, 'Only an array of URLs could be used within this filter.', '6.3.1' );
1511 +
1717 1512 return array();
1718 1513 }
1719 1514
1720 1515 return $allowed_url_list;
@@ -1724,10 +1519,8 @@
1724 1519 * Gets required plan for an addon.
1725 1520 *
1726 1521 * @since 6.4.2
1727 1522 *
1728 - * @param int|string $addon_id
1729 - *
1730 1523 * @return string Empty string if no plan is required for active license.
1731 1524 */
1732 1525 public static function get_addon_required_plan( $addon_id ) {
1733 1526 $api = new FrmFormApi();
@@ -1738,10 +1531,38 @@
1738 1531 $requires = FrmFormsHelper::get_plan_required( $dates );
1739 1532 }
1740 1533
1741 1534 if ( ! isset( $requires ) || ! is_string( $requires ) ) {
1742 - return '';
1535 + $requires = '';
1743 1536 }
1744 1537
1745 1538 return $requires;
1539 + }
1540 +
1541 + /**
1542 + * @since 4.02.05
1543 + * @deprecated 6.8.3
1544 + *
1545 + * @codeCoverageIgnore
1546 + *
1547 + * @return void
1548 + */
1549 + public static function connect_pro() {
1550 + _deprecated_function( __METHOD__, '6.8.3' );
1551 + }
1552 +
1553 + /**
1554 + * @since 4.08
1555 + * @deprecated 6.11.1
1556 + *
1557 + * @return bool|int false or the number of days until expiration.
1558 + */
1559 + public static function is_license_expiring() {
1560 + _deprecated_function( __METHOD__, '6.11.1', 'FrmProAddonsController::is_license_expiring' );
1561 +
1562 + if ( is_callable( 'FrmProAddonsController::is_license_expiring' ) ) {
1563 + return FrmProAddonsController::is_license_expiring();
1564 + }
1565 +
1566 + return false;
1746 1567 }
1747 1568 }