PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/controllers/FrmAddonsController.php +218 -49 6.27 → trunk View file →
@@ -33,14 +33,16 @@
33 33 public static function load_admin_hooks() {
34 34 add_action( 'admin_menu', self::class . '::menu', 100 );
35 35 add_filter( 'pre_set_site_transient_update_plugins', self::class . '::check_update' );
36 36
37 - if ( FrmAppHelper::is_admin_page( 'formidable-addons' ) ) {
38 - self::$request_addon_url = 'https://connect.formidableforms.com/add-on-request/';
37 + if ( ! FrmAppHelper::is_admin_page( 'formidable-addons' ) ) {
38 + return;
39 + }
39 40
40 - add_action( 'admin_enqueue_scripts', self::class . '::enqueue_assets', 15 );
41 - add_filter( 'frm_show_footer_links', '__return_false' );
42 - }
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' );
43 45 }
44 46
45 47 /**
46 48 * Enqueues the Add-Ons page scripts and styles.
@@ -102,9 +104,9 @@
102 104 $label = '<span style="color:#3FCA89">' . esc_html( $label ) . '</span>';
103 105
104 106 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
105 107
106 - // remove default created subpage, make the page with highest priority as default.
108 + // Remove default created subpage, make the page with highest priority as default.
107 109 remove_submenu_page( 'formidable', 'formidable' );
108 110
109 111 if ( ! FrmAppHelper::pro_is_installed() ) {
110 112 $cta_text = FrmSalesApi::get_best_sale_value( 'menu_cta_text' );
@@ -154,9 +156,10 @@
154 156 'pro' => array(
155 157 'title' => 'Formidable Forms Pro',
156 158 'slug' => 'formidable-pro',
157 159 'released' => '2011-02-05',
158 - 'docs' => 'knowledgebase/',
160 + 'docs' => 'knowledgebase/what-is-the-difference-between-the-lite-free-and-pro-version/',
161 + 'docs_label' => __( 'Why Upgrade', 'formidable' ),
159 162 'categories' => array( 'basic', 'plus', 'business', 'elite' ),
160 163 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
161 164 ),
162 165 );
@@ -191,12 +194,14 @@
191 194 );
192 195
193 196 // Extract the elements to move
194 197 foreach ( $plans as $plan ) {
195 - if ( isset( self::$categories[ $plan ] ) ) {
196 - $bottom_categories[ $plan ] = self::$categories[ $plan ];
197 - unset( self::$categories[ $plan ] );
198 + if ( ! isset( self::$categories[ $plan ] ) ) {
199 + continue;
198 200 }
201 +
202 + $bottom_categories[ $plan ] = self::$categories[ $plan ];
203 + unset( self::$categories[ $plan ] );
199 204 }
200 205
201 206 $special_categories = array();
202 207
@@ -284,14 +289,14 @@
284 289 $api = new FrmFormApi();
285 290 $addons = $api->get_api_info();
286 291
287 292 if ( ! $addons ) {
288 - $addons = self::fallback_plugin_list();
289 - } else {
290 - foreach ( $addons as $k => $addon ) {
291 - if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
292 - unset( $addons[ $k ] );
293 - }
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 ] );
294 299 }
295 300 }
296 301
297 302 return $addons;
@@ -304,10 +309,9 @@
304 309 *
305 310 * @return int Count of addons.
306 311 */
307 312 public static function get_addons_count() {
308 - $addons = self::get_api_addons();
309 - return count( $addons );
313 + return count( self::get_api_addons() );
310 314 }
311 315
312 316 /**
313 317 * If the API is unable to connect, show something on the addons page
@@ -416,10 +420,9 @@
416 420 *
417 421 * @return string
418 422 */
419 423 public static function get_pro_download_url() {
420 - $license = self::get_pro_license();
421 - $api = new FrmFormApi( $license );
424 + $api = new FrmFormApi( self::get_pro_license() );
422 425 $downloads = $api->get_api_info();
423 426 $pro = self::get_pro_from_addons( $downloads );
424 427
425 428 return $pro['url'] ?? '';
@@ -450,10 +453,10 @@
450 453 return '';
451 454 }
452 455
453 456 if ( str_contains( $license, '-' ) ) {
454 - // this is a fix for licenses saved in the past
455 - $license = strtoupper( $license );
457 + // This is a fix for licenses saved in the past
458 + return strtoupper( $license );
456 459 }
457 460
458 461 return $license;
459 462 }
@@ -470,14 +473,17 @@
470 473 }
471 474
472 475 /**
473 476 * @since 4.06
477 + * @since 6.31 Added the $force_type param.
474 478 *
479 + * @param bool $force_type Whether to resolve grandfathered licenses to their real license type.
480 + *
475 481 * @return string
476 482 */
477 - public static function license_type() {
483 + public static function license_type( $force_type = false ) {
478 484 if ( is_callable( 'FrmProAddonsController::license_type' ) ) {
479 - return FrmProAddonsController::license_type();
485 + return FrmProAddonsController::license_type( $force_type );
480 486 }
481 487
482 488 return 'free';
483 489 }
@@ -482,8 +488,122 @@
482 488 return 'free';
483 489 }
484 490
485 491 /**
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 + /**
486 606 * @since 4.0.01
487 607 *
488 608 * @return bool
489 609 */
@@ -570,9 +690,9 @@
570 690 continue;
571 691 }
572 692
573 693 if ( ! self::is_installed( $folder ) ) {
574 - // don't show an update if the plugin isn't installed
694 + // Don't show an update if the plugin isn't installed
575 695 continue;
576 696 }
577 697
578 698 $wp_plugin = $wp_plugins[ $folder ] ?? array();
@@ -585,9 +705,8 @@
585 705 $transient->no_update[ $folder ] = $plugin;
586 706 }
587 707
588 708 $transient->checked[ $folder ] = $wp_version;
589 -
590 709 }//end foreach
591 710
592 711 return $transient;
593 712 }
@@ -634,9 +753,9 @@
634 753 $version_info = array();
635 754
636 755 foreach ( $installed_addons as $addon ) {
637 756 if ( $addon->store_url !== 'https://formidableforms.com' ) {
638 - // check if this is a third-party addon
757 + // Check if this is a third-party addon
639 758 continue;
640 759 }
641 760
642 761 $new_license = $addon->license;
@@ -647,9 +766,9 @@
647 766
648 767 $checked_licenses[] = $new_license;
649 768 $api = new FrmFormApi( $new_license );
650 769
651 - if ( empty( $version_info ) ) {
770 + if ( ! $version_info ) {
652 771 $version_info = $api->get_api_info();
653 772 continue;
654 773 }
655 774
@@ -660,20 +779,22 @@
660 779 }
661 780
662 781 $download_id = $plugin['id'] ?? 0;
663 782
664 - if ( $download_id && ! isset( $version_info[ $download_id ]['package'] ) ) {
665 - // if this addon is using its own license, get the update url
666 - $addon_info = $api->get_api_info();
783 + if ( ! $download_id || isset( $version_info[ $download_id ]['package'] ) ) {
784 + continue;
785 + }
667 786
668 - $version_info[ $download_id ] = $addon_info[ $download_id ];
787 + // If this addon is using its own license, get the update url
788 + $addon_info = $api->get_api_info();
669 789
670 - if ( isset( $addon_info['error'] ) ) {
671 - $version_info[ $download_id ]['error'] = array(
672 - 'message' => $addon_info['error']['message'],
673 - 'code' => $addon_info['error']['code'],
674 - );
675 - }
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 + );
676 797 }
677 798 }//end foreach
678 799
679 800 return $version_info;
@@ -722,8 +843,47 @@
722 843 return $link;
723 844 }
724 845
725 846 /**
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 + /**
726 886 * @since 4.09
727 887 *
728 888 * @param string $plugin The plugin slug.
729 889 *
@@ -753,9 +913,9 @@
753 913 $license_type = '';
754 914 $addons = self::get_api_addons();
755 915
756 916 if ( isset( $addons['error'] ) && isset( $addons['error']['type'] ) ) {
757 - $license_type = $addons['error']['type'];
917 + return $addons['error']['type'];
758 918 }
759 919
760 920 return $license_type;
761 921 }
@@ -771,11 +931,11 @@
771 931 public static function get_addon_for_license( $addons, $license ) {
772 932 $download_id = $license->download_id;
773 933 $plugin = array();
774 934
775 - if ( ! $download_id && ! empty( $addons ) ) {
935 + if ( ! $download_id && $addons ) {
776 936 foreach ( $addons as $addon ) {
777 - if ( strtolower( $license->plugin_name ) === strtolower( $addon['title'] ) ) {
937 + if ( 0 === strcasecmp( $license->plugin_name, $addon['title'] ) ) {
778 938 return $addon;
779 939 }
780 940 }
781 941 } elseif ( isset( $addons[ $download_id ] ) ) {
@@ -817,8 +977,13 @@
817 977 }
818 978
819 979 $addon['installed'] = self::is_installed( $file_name );
820 980
981 + if ( 'highrise' === $slug && ! $addon['installed'] ) {
982 + unset( $addons[ $id ] );
983 + continue;
984 + }
985 +
821 986 if ( $addon['installed'] && 'formidable-views/formidable-views.php' === $file_name ) {
822 987 $active_views_version = self::get_active_views_version();
823 988
824 989 if ( false !== $active_views_version && $slug !== $active_views_version ) {
@@ -994,9 +1159,9 @@
994 1159 *
995 1160 * @return string
996 1161 */
997 1162 protected static function get_current_plugin() {
998 - if ( empty( self::$plugin ) ) {
1163 + if ( ! self::$plugin ) {
999 1164 self::$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
1000 1165 }
1001 1166 return self::$plugin;
1002 1167 }
@@ -1096,9 +1261,9 @@
1096 1261 }
1097 1262
1098 1263 // Create the plugin upgrader with our custom skin.
1099 1264 $installer = new Plugin_Upgrader( new FrmInstallerSkin() );
1100 - $installer->install( $download_url );
1265 + $installer->install( $download_url, array( 'overwrite_package' => true ) );
1101 1266
1102 1267 // Flush the cache and return the newly installed plugin basename.
1103 1268 wp_cache_flush();
1104 1269
@@ -1277,12 +1442,14 @@
1277 1442 */
1278 1443 protected static function install_addon_permissions() {
1279 1444 check_ajax_referer( 'frm_ajax', 'nonce' );
1280 1445
1281 - if ( ! current_user_can( 'activate_plugins' ) || ! self::get_current_plugin() ) {
1282 - echo json_encode( true );
1283 - wp_die();
1446 + if ( current_user_can( 'activate_plugins' ) && self::get_current_plugin() ) {
1447 + return;
1284 1448 }
1449 +
1450 + echo json_encode( true );
1451 + wp_die();
1285 1452 }
1286 1453
1287 1454 /**
1288 1455 * @since 4.08
@@ -1293,9 +1460,9 @@
1293 1460 $auth = get_option( 'frm_connect_token' );
1294 1461
1295 1462 if ( ! $auth ) {
1296 1463 $auth = hash( 'sha512', wp_rand() );
1297 - update_option( 'frm_connect_token', $auth, 'no' );
1464 + update_option( 'frm_connect_token', $auth, false );
1298 1465 }
1299 1466
1300 1467 $page = FrmAppHelper::simple_get( 'page', 'sanitize_title', 'formidable-settings' );
1301 1468 $link = 'https://formidableforms.com/api-connect/';
@@ -1362,9 +1529,9 @@
1362 1529 }
1363 1530 }
1364 1531
1365 1532 // If empty license, save it now.
1366 - if ( empty( self::get_pro_license() ) && function_exists( 'load_formidable_pro' ) ) {
1533 + if ( ! self::get_pro_license() && function_exists( 'load_formidable_pro' ) ) {
1367 1534 load_formidable_pro();
1368 1535 $license = stripslashes( FrmAppHelper::get_param( 'key', '', 'request', 'sanitize_text_field' ) );
1369 1536
1370 1537 if ( ! $license ) {
@@ -1493,13 +1660,15 @@
1493 1660
1494 1661 if ( ! str_contains( $class, 'frm-button' ) ) {
1495 1662 $class .= ' frm-button-secondary frm-button-sm';
1496 1663 }
1664 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
1497 1665 ?>
1498 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 ?>
1499 1667 <?php echo esc_html( $text ); ?>
1500 1668 </a>
1501 1669 <?php
1670 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
1502 1671 }
1503 1672
1504 1673 /**
1505 1674 * @since 3.04.02
@@ -1569,9 +1738,9 @@
1569 1738 $requires = FrmFormsHelper::get_plan_required( $dates );
1570 1739 }
1571 1740
1572 1741 if ( ! isset( $requires ) || ! is_string( $requires ) ) {
1573 - $requires = '';
1742 + return '';
1574 1743 }
1575 1744
1576 1745 return $requires;
1577 1746 }