PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.16
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.16
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 +488 -437 6.56.16 View file →
@@ -5,15 +5,93 @@
5 5
6 6 class FrmAddonsController {
7 7
8 8 /**
9 - * @var string $plugin
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 + */
11 26 protected static $plugin;
12 27
13 28 /**
29 + * @since 6.15
30 + */
31 + public static function load_admin_hooks() {
32 + add_action( 'admin_menu', __CLASS__ . '::menu', 100 );
33 + add_filter( 'pre_set_site_transient_update_plugins', __CLASS__ . '::check_update' );
34 +
35 + if ( FrmAppHelper::is_admin_page( 'formidable-addons' ) ) {
36 + self::$request_addon_url = 'https://connect.formidableforms.com/add-on-request/';
37 +
38 + add_action( 'admin_enqueue_scripts', __CLASS__ . '::enqueue_assets', 15 );
39 + add_filter( 'frm_show_footer_links', '__return_false' );
40 + }
41 + }
42 +
43 + /**
44 + * Enqueues the Add-Ons page scripts and styles.
45 + *
46 + * @since 6.15
47 + *
14 48 * @return void
15 49 */
50 + public static function enqueue_assets() {
51 + $plugin_url = FrmAppHelper::plugin_url();
52 + $version = FrmAppHelper::plugin_version();
53 + $js_dependencies = array(
54 + 'wp-i18n',
55 + // This prevents a console error "wp.hooks is undefined" in WP versions older than 5.7.
56 + 'wp-hooks',
57 + 'formidable_dom',
58 + );
59 +
60 + // Enqueue styles that needed.
61 + wp_enqueue_style( 'formidable-admin' );
62 + wp_enqueue_style( 'formidable-grids' );
63 +
64 + // Register and enqueue Add-Ons page style.
65 + wp_register_style( self::SCRIPT_HANDLE, $plugin_url . '/css/admin/addons-page.css', array(), $version );
66 + wp_enqueue_style( self::SCRIPT_HANDLE );
67 +
68 + // Register and enqueue Add-Ons page script.
69 + wp_register_script( self::SCRIPT_HANDLE, $plugin_url . '/js/addons-page.js', $js_dependencies, $version, true );
70 + wp_localize_script( self::SCRIPT_HANDLE, 'frmAddonsVars', self::get_js_variables() );
71 + wp_enqueue_script( self::SCRIPT_HANDLE );
72 + wp_set_script_translations( self::SCRIPT_HANDLE, 'formidable' );
73 +
74 + FrmAppHelper::dequeue_extra_global_scripts();
75 + }
76 +
77 + /**
78 + * Get the Add-Ons page JS variables as an array.
79 + *
80 + * @since 6.15
81 + *
82 + * @return array
83 + */
84 + private static function get_js_variables() {
85 + return array(
86 + 'proIsIncluded' => FrmAppHelper::pro_is_included(),
87 + 'addonRequestURL' => self::$request_addon_url,
88 + );
89 + }
90 +
91 + /**
92 + * @return void
93 + */
16 94 public static function menu() {
17 95 if ( ! current_user_can( 'activate_plugins' ) ) {
18 96 return;
19 97 }
@@ -18,12 +96,15 @@
18 96 return;
19 97 }
20 98
21 99 $label = __( 'Add-Ons', 'formidable' );
22 - $label = '<span style="color:#1da867">' . $label . '</span>';
100 + $label = '<span style="color:#3FCA89">' . $label . '</span>';
23 101
24 102 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
25 103
104 + // remove default created subpage, make the page with highest priority as default.
105 + remove_submenu_page( 'formidable', 'formidable' );
106 +
26 107 if ( ! FrmAppHelper::pro_is_installed() ) {
27 108 add_submenu_page(
28 109 'formidable',
29 110 'Formidable | ' . __( 'Upgrade', 'formidable' ),
@@ -29,9 +110,12 @@
29 110 'Formidable | ' . __( 'Upgrade', 'formidable' ),
30 111 '<span class="frm-upgrade-submenu">' . __( 'Upgrade', 'formidable' ) . '</span>',
31 112 'frm_view_forms',
32 113 'formidable-pro-upgrade',
33 - 'FrmAddonsController::upgrade_to_pro'
114 + function () {
115 + // This function doesn't need to do anything.
116 + // The redirect is handled earlier to avoid issues with the headers being sent.
117 + }
34 118 );
35 119 } elseif ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) ) {
36 120 wp_safe_redirect( admin_url( 'admin.php?page=formidable' ) );
37 121 exit;
@@ -42,28 +126,31 @@
42 126 * @return void
43 127 */
44 128 public static function list_addons() {
45 129 FrmAppHelper::include_svg();
46 - $installed_addons = apply_filters( 'frm_installed_addons', array() );
47 - $license_type = '';
48 130
49 - $addons = self::get_api_addons();
50 - $errors = array();
131 + $view_path = FrmAppHelper::plugin_path() . '/classes/views/addons/';
132 + $installed_addons = apply_filters( 'frm_installed_addons', array() );
133 + $addons = self::get_api_addons();
134 + $errors = array();
135 + $license_type = '';
136 + $request_addon_url = self::$request_addon_url;
51 137
52 138 if ( isset( $addons['error'] ) ) {
53 - $api = new FrmFormApi();
54 - $errors = $api->get_error_from_response( $addons );
139 + $api = new FrmFormApi();
140 + $errors = $api->get_error_from_response( $addons );
55 141 $license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
56 142 unset( $addons['error'] );
57 143 }
58 144
59 - $pro = array(
145 + $pro = array(
60 146 'pro' => array(
61 - 'title' => 'Formidable Forms Pro',
62 - 'slug' => 'formidable-pro',
63 - 'released' => '2011-02-05',
64 - 'docs' => 'knowledgebase/',
65 - 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
147 + 'title' => 'Formidable Forms Pro',
148 + 'slug' => 'formidable-pro',
149 + 'released' => '2011-02-05',
150 + 'docs' => 'knowledgebase/',
151 + 'categories' => array( 'basic', 'plus', 'business', 'elite' ),
152 + 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
66 153 ),
67 154 );
68 155 $addons = $pro + $addons;
69 156 self::prepare_addons( $addons );
@@ -69,14 +156,105 @@
69 156 self::prepare_addons( $addons );
70 157
71 158 $pricing = FrmAppHelper::admin_upgrade_link( 'addons' );
72 159
73 - include( FrmAppHelper::plugin_path() . '/classes/views/addons/list.php' );
160 + self::organize_and_get_categories();
161 + $categories = self::$categories;
162 +
163 + include $view_path . 'index.php';
74 164 }
75 165
76 166 /**
167 + * Organize and set categories.
168 + *
169 + * @since 6.15
170 + *
77 171 * @return void
78 172 */
173 + protected static function organize_and_get_categories() {
174 + unset( self::$categories['strategy11'] );
175 + ksort( self::$categories );
176 +
177 + $bottom_categories = array();
178 + $plans = FrmFormsHelper::get_license_types(
179 + array(
180 + 'include_all' => false,
181 + 'case_lower' => true,
182 + )
183 + );
184 +
185 + // Extract the elements to move
186 + foreach ( $plans as $plan ) {
187 + if ( isset( self::$categories[ $plan ] ) ) {
188 + $bottom_categories[ $plan ] = self::$categories[ $plan ];
189 + unset( self::$categories[ $plan ] );
190 + }
191 + }
192 +
193 + $special_categories = array();
194 + if ( 'elite' !== self::license_type() ) {
195 + $special_categories['available-addons'] = array(
196 + 'name' => __( 'Available', 'formidable' ),
197 + // To be assigned via JavaScript.
198 + 'count' => 0,
199 + );
200 + }
201 +
202 + $special_categories['active-addons'] = array(
203 + 'name' => __( 'Active', 'formidable' ),
204 + // To be assigned via JavaScript.
205 + 'count' => 0,
206 + );
207 +
208 + $special_categories['all-items'] = array(
209 + 'name' => __( 'All Add-Ons', 'formidable' ),
210 + // To be assigned via JavaScript.
211 + 'count' => 0,
212 + );
213 +
214 + self::$categories = array_merge(
215 + $special_categories,
216 + self::$categories,
217 + $bottom_categories
218 + );
219 + }
220 +
221 + /**
222 + * Organize and set categories.
223 + *
224 + * @since 6.15
225 + *
226 + * @param array $addon The addon array that will be modified by reference.
227 + * @return void
228 + */
229 + protected static function set_categories( &$addon ) {
230 + if ( ! isset( $addon['categories'] ) ) {
231 + return;
232 + }
233 +
234 + $addon['category-slugs'] = array();
235 +
236 + foreach ( $addon['categories'] as $category ) {
237 + $category = FrmFormsHelper::convert_legacy_package_names( $category );
238 + $category_slug = sanitize_title( $category );
239 +
240 + // Add the slug to the new array.
241 + $addon['category-slugs'][] = $category_slug;
242 +
243 + if ( ! isset( self::$categories[ $category_slug ] ) ) {
244 + self::$categories[ $category_slug ] = array(
245 + 'name' => $category,
246 + 'count' => 0,
247 + );
248 + }
249 +
250 + ++self::$categories[ $category_slug ]['count'];
251 + }
252 + }
253 +
254 + /**
255 + * @return void
256 + */
79 257 public static function license_settings() {
80 258 $plugins = apply_filters( 'frm_installed_addons', array() );
81 259 if ( empty( $plugins ) ) {
82 260 esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
@@ -85,9 +263,9 @@
85 263 }
86 264
87 265 ksort( $plugins );
88 266
89 - include( FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php' );
267 + include FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php';
90 268 }
91 269
92 270 /**
93 271 * @return array
@@ -109,8 +287,21 @@
109 287 return $addons;
110 288 }
111 289
112 290 /**
291 + * Retrieves the count of available addons.
292 + *
293 + * @since 6.9
294 + *
295 + * @return int Count of addons.
296 + */
297 + public static function get_addons_count() {
298 + $addons = self::get_api_addons();
299 +
300 + return count( $addons );
301 + }
302 +
303 + /**
113 304 * If the API is unable to connect, show something on the addons page
114 305 *
115 306 * @since 3.04.03
116 307 * @return array
@@ -272,8 +463,10 @@
272 463 }
273 464
274 465 /**
275 466 * @since 4.0.01
467 + *
468 + * @return bool
276 469 */
277 470 public static function is_license_expired() {
278 471 $version_info = self::get_primary_license_info();
279 472 if ( ! isset( $version_info['error'] ) ) {
@@ -279,30 +472,29 @@
279 472 if ( ! isset( $version_info['error'] ) ) {
280 473 return false;
281 474 }
282 475
283 - return $version_info['error'];
284 - }
476 + $expires = isset( $version_info['error']['expires'] ) ? $version_info['error']['expires'] : 0;
477 + if ( empty( $expires ) || $expires > time() ) {
478 + return false;
479 + }
285 480
286 - /**
287 - * @since 4.08
288 - *
289 - * @return boolean|int false or the number of days until expiration.
290 - */
291 - public static function is_license_expiring() {
292 - if ( is_callable( 'FrmProAddonsController::is_license_expiring' ) ) {
293 - return FrmProAddonsController::is_license_expiring();
481 + $rate_limited = ! empty( $version_info['response_code'] ) && 429 === (int) $version_info['response_code'];
482 + if ( $rate_limited ) {
483 + // Do not return false positives for rate limited responses.
484 + return false;
294 485 }
295 486
296 - return false;
487 + return $version_info['error'];
297 488 }
298 489
299 490 /**
300 491 * @since 4.08
492 + * @since 6.7 This is public.
301 493 *
302 494 * @return array|false
303 495 */
304 - protected static function get_primary_license_info() {
496 + public static function get_primary_license_info() {
305 497 $installed_addons = apply_filters( 'frm_installed_addons', array() );
306 498 if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
307 499 return false;
308 500 }
@@ -334,9 +526,9 @@
334 526 $version_info = self::fill_update_addon_info( $installed_addons );
335 527 $transient->last_checked = time();
336 528 $wp_plugins = self::get_plugins();
337 529
338 - foreach ( $version_info as $id => $plugin ) {
530 + foreach ( $version_info as $plugin ) {
339 531 $plugin = (object) $plugin;
340 532
341 533 if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
342 534 continue;
@@ -351,20 +543,21 @@
351 543 // don't show an update if the plugin isn't installed
352 544 continue;
353 545 }
354 546
355 - $wp_plugin = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
356 - $wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
547 + $wp_plugin = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
548 + $wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
549 + $plugin->slug = explode( '/', $folder )[0];
357 550
358 551 if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
359 - $slug = explode( '/', $folder );
360 - $plugin->slug = $slug[0];
361 552 $transient->response[ $folder ] = $plugin;
553 + } else {
554 + $transient->no_update[ $folder ] = $plugin;
362 555 }
363 556
364 557 $transient->checked[ $folder ] = $wp_version;
365 558
366 - }
559 + }//end foreach
367 560
368 561 return $transient;
369 562 }
370 563
@@ -387,9 +580,9 @@
387 580 * Check if a plugin is installed before showing an update for it
388 581 *
389 582 * @since 3.05
390 583 *
391 - * @param string $plugin - the folder/filename.php for a plugin
584 + * @param string $plugin The folder/filename.php for a plugin.
392 585 *
393 586 * @return bool - True if installed
394 587 */
395 588 protected static function is_installed( $plugin ) {
@@ -444,9 +637,9 @@
444 637 'code' => $addon_info['error']['code'],
445 638 );
446 639 }
447 640 }
448 - }
641 + }//end foreach
449 642
450 643 return $version_info;
451 644 }
452 645
@@ -453,9 +646,9 @@
453 646 /**
454 647 * Get the action link for an addon that isn't active.
455 648 *
456 649 * @since 3.06.03
457 - * @param string $plugin The plugin slug
650 + * @param string $plugin The plugin slug.
458 651 * @return array
459 652 */
460 653 public static function install_link( $plugin ) {
461 654 $link = array();
@@ -466,14 +659,14 @@
466 659 $link = array(
467 660 'url' => $addon['plugin'],
468 661 'class' => 'frm-activate-addon',
469 662 );
470 - } elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
663 + } elseif ( ! empty( $addon['url'] ) ) {
471 664 $link = array(
472 665 'url' => $addon['url'],
473 666 'class' => 'frm-install-addon',
474 667 );
475 - } elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
668 + } elseif ( ! empty( $addon['categories'] ) ) {
476 669 $link = array(
477 670 'categories' => $addon['categories'],
478 671 );
479 672 }
@@ -485,9 +678,9 @@
485 678 $link = array(
486 679 'url' => 'formidable-' . $plugin . '/formidable-' . $plugin . '.php',
487 680 'class' => 'frm-activate-addon',
488 681 );
489 - }
682 + }//end if
490 683
491 684 return $link;
492 685 }
493 686
@@ -492,12 +685,12 @@
492 685 }
493 686
494 687 /**
495 688 * @since 4.09
496 - * @param string $plugin The plugin slug
689 + * @param string $plugin The plugin slug.
497 690 * @return array|false
498 691 */
499 - protected static function get_addon( $plugin ) {
692 + public static function get_addon( $plugin ) {
500 693 $addons = self::get_api_addons();
501 694 self::prepare_addons( $addons );
502 695 foreach ( $addons as $addon ) {
503 696 $slug = explode( '/', $addon['plugin'] );
@@ -523,10 +716,10 @@
523 716
524 717 /**
525 718 * @since 3.04.03
526 719 *
527 - * @param array $addons
528 - * @param object $license The FrmAddon object
720 + * @param array $addons
721 + * @param object $license The FrmAddon object.
529 722 *
530 723 * @return array
531 724 */
532 725 public static function get_addon_for_license( $addons, $license ) {
@@ -533,9 +726,9 @@
533 726 $download_id = $license->download_id;
534 727 $plugin = array();
535 728 if ( empty( $download_id ) && ! empty( $addons ) ) {
536 729 foreach ( $addons as $addon ) {
537 - if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
730 + if ( strtolower( $license->plugin_name ) === strtolower( $addon['title'] ) ) {
538 731 return $addon;
539 732 }
540 733 }
541 734 } elseif ( isset( $addons[ $download_id ] ) ) {
@@ -599,13 +792,15 @@
599 792
600 793 if ( ! isset( $addon['link'] ) ) {
601 794 $addon['link'] = 'downloads/' . $slug . '/';
602 795 }
796 +
603 797 self::prepare_addon_link( $addon['link'] );
798 + self::set_addon_status( $addon );
799 + self::set_categories( $addon );
604 800
605 - self::set_addon_status( $addon );
606 801 $addons[ $id ] = $addon;
607 - }
802 + }//end foreach
608 803 }
609 804
610 805 /**
611 806 * @return bool
@@ -617,9 +812,9 @@
617 812 return is_plugin_active( $file_name );
618 813 }
619 814
620 815 /**
621 - * @return string|false either 'visual-views' or 'views', false if one is not found.
816 + * @return false|string either 'visual-views' or 'views', false if one is not found.
622 817 */
623 818 private static function get_active_views_version() {
624 819 if ( ! is_callable( 'FrmViewsAppHelper::plugin_version' ) ) {
625 820 return false;
@@ -674,263 +869,64 @@
674 869 }
675 870 }
676 871
677 872 /**
678 - * @return void
873 + * @since 5.5.2
874 + *
875 + * @param string $plugin
876 + * @param string $redirect
877 + * @param bool $network_wide
878 + * @param bool $silent
879 + * @return WP_Error|null Null on success, WP_Error on invalid file.
679 880 */
680 - public static function upgrade_to_pro() {
681 - FrmAppHelper::include_svg();
682 -
683 - $link_parts = array(
684 - 'medium' => 'upgrade',
685 - 'content' => 'button',
686 - );
687 -
688 - $features = array(
689 - 'Display Entries' => array(
690 - array(
691 - 'label' => 'Display form data with virtually limitless views',
692 - 'link' => array(
693 - 'content' => 'views',
694 - 'param' => 'views-display-form-data',
695 - ),
696 - 'lite' => false,
697 - ),
698 - array(
699 - 'label' => 'Generate graphs and stats based on your submitted data',
700 - 'link' => array(
701 - 'content' => 'graphs',
702 - 'param' => 'statistics-graphs-wordpress-forms',
703 - ),
704 - 'lite' => false,
705 - ),
706 - ),
707 - 'Entry Management' => array(
708 - array(
709 - 'label' => 'Import entries from a CSV',
710 - 'link' => array(
711 - 'content' => 'import-entries',
712 - 'param' => 'importing-exporting-wordpress-forms',
713 - ),
714 - 'lite' => false,
715 - ),
716 - array(
717 - 'label' => 'Logged-in users can save drafts and return later',
718 - 'link' => array(
719 - 'content' => 'save-drafts',
720 - 'param' => 'save-drafts-wordpress-form',
721 - ),
722 - 'lite' => false,
723 - ),
724 - array(
725 - 'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
726 - 'link' => array(
727 - 'content' => 'front-edit',
728 - 'param' => 'wordpress-front-end-editing',
729 - ),
730 - 'lite' => false,
731 - ),
732 - array(
733 - 'label' => 'View form submissions from the back-end',
734 - 'lite' => true,
735 - ),
736 - array(
737 - 'label' => 'Export your entries to a CSV',
738 - 'lite' => true,
739 - ),
740 - ),
741 - 'Form Building' => array(
742 - array(
743 - 'label' => 'Save a calculated value into a field',
744 - 'link' => array(
745 - 'content' => 'calculations',
746 - 'param' => 'field-calculations-wordpress-form',
747 - ),
748 - 'lite' => false,
749 - ),
750 - array(
751 - 'label' => 'Allow multiple file uploads',
752 - 'link' => array(
753 - 'content' => 'file-uploads',
754 - 'param' => 'wordpress-multi-file-upload-fields',
755 - ),
756 - 'lite' => false,
757 - ),
758 - array(
759 - 'label' => 'Repeat sections of fields',
760 - 'link' => array(
761 - 'content' => 'repeaters',
762 - 'param' => 'repeatable-sections-forms',
763 - ),
764 - 'lite' => false,
765 - ),
766 - array(
767 - 'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
768 - 'link' => array(
769 - 'content' => 'conditional-logic',
770 - 'param' => 'conditional-logic-wordpress-forms',
771 - ),
772 - 'lite' => false,
773 - ),
774 - array(
775 - 'label' => 'Confirmation fields',
776 - 'link' => array(
777 - 'content' => 'confirmation-fields',
778 - 'param' => 'confirmation-fields-wordpress-forms',
779 - ),
780 - 'lite' => false,
781 - ),
782 - array(
783 - 'label' => 'Multi-paged forms',
784 - 'link' => array(
785 - 'content' => 'page-breaks',
786 - 'param' => 'wordpress-multi-page-forms',
787 - ),
788 - 'lite' => false,
789 - ),
790 - array(
791 - '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.',
792 - 'lite' => false,
793 - ),
794 - array(
795 - 'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
796 - 'lite' => true,
797 - ),
798 - array(
799 - 'label' => 'Drag & Drop Form building',
800 - 'link' => array(
801 - 'content' => 'drag-drop',
802 - 'param' => 'drag-drop-forms',
803 - ),
804 - 'lite' => true,
805 - ),
806 - array(
807 - 'label' => 'Create forms from Templates',
808 - 'link' => array(
809 - 'content' => 'form-templates',
810 - 'param' => 'wordpress-form-templates',
811 - ),
812 - 'lite' => true,
813 - ),
814 - array(
815 - 'label' => 'Import and export forms with XML',
816 - 'link' => array(
817 - 'content' => 'import',
818 - 'param' => 'importing-exporting-wordpress-forms',
819 - ),
820 - 'lite' => true,
821 - ),
822 - array(
823 - 'label' => 'Use input placeholder text in your fields that clear when typing starts.',
824 - 'lite' => true,
825 - ),
826 - ),
827 - 'Form Actions' => array(
828 - array(
829 - 'label' => 'Conditionally send your email notifications based on values in your form',
830 - 'link' => array(
831 - 'content' => 'conditional-emails',
832 - ),
833 - 'lite' => false,
834 - ),
835 - array(
836 - 'label' => 'Create and edit WordPress posts or custom posts from the front-end',
837 - 'link' => array(
838 - 'content' => 'create-posts',
839 - 'param' => 'create-posts-pages-wordpress-forms',
840 - ),
841 - 'lite' => false,
842 - ),
843 - array(
844 - 'label' => 'Send multiple emails and autoresponders',
845 - 'link' => array(
846 - 'content' => 'multiple-emails',
847 - 'param' => 'virtually-unlimited-emails',
848 - ),
849 - 'lite' => true,
850 - ),
851 - ),
852 - 'Form Appearance' => array(
853 - array(
854 - 'label' => 'Create Multiple styles for different forms',
855 - 'link' => array(
856 - 'content' => 'multiple-styles',
857 - 'param' => 'wordpress-visual-form-styler',
858 - ),
859 - 'lite' => false,
860 - ),
861 - array(
862 - 'label' => 'Customizable layout with CSS classes',
863 - 'link' => array(
864 - 'content' => 'form-layout',
865 - 'param' => 'wordpress-mobile-friendly-forms',
866 - ),
867 - 'lite' => true,
868 - ),
869 - array(
870 - 'label' => 'Customize the HTML for your forms',
871 - 'link' => array(
872 - 'content' => 'custom-html',
873 - 'param' => 'customizable-html-wordpress-form',
874 - ),
875 - 'lite' => true,
876 - ),
877 - array(
878 - 'label' => 'Style your form with the Visual Form Styler',
879 - 'lite' => true,
880 - ),
881 - ),
882 - );
883 -
884 - include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
881 + protected static function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
882 + if ( ! function_exists( 'activate_plugin' ) ) {
883 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
884 + }
885 + return activate_plugin( $plugin, $redirect, $network_wide, $silent );
885 886 }
886 887
887 888 /**
888 - * Install Pro after connection with Formidable.
889 + * Deactivate a specified plugin.
889 890 *
890 - * @since 4.02.05
891 + * @since 6.8
891 892 *
893 + * @param string $plugin
894 + * @param bool $silent
892 895 * @return void
893 896 */
894 - public static function connect_pro() {
895 - FrmAppHelper::permission_check( 'install_plugins' );
896 - check_ajax_referer( 'frm_ajax', 'nonce' );
897 -
898 - $url = self::get_current_plugin();
899 - if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
900 - wp_die();
897 + protected static function deactivate_plugin( $plugin, $silent = false ) {
898 + if ( ! function_exists( 'deactivate_plugins' ) ) {
899 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
901 900 }
902 -
903 - $response = array();
904 -
905 - // It's already installed and active.
906 - $active = self::activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
907 - if ( is_wp_error( $active ) ) {
908 - // The plugin was installed, but not active. Download it now.
909 - self::ajax_install_addon();
910 - } else {
911 - $response['active'] = true;
912 - $response['success'] = true;
913 - }
914 -
915 - echo json_encode( $response );
916 - wp_die();
901 + deactivate_plugins( $plugin, $silent );
917 902 }
918 903
919 904 /**
920 - * @since 5.5.2
905 + * Uninstall a specified plugin.
921 906 *
907 + * @since 6.8
908 + *
922 909 * @param string $plugin
923 - * @param string $redirect
924 - * @param bool $network_wide
925 - * @param bool $silent
926 - * @return null|WP_Error Null on success, WP_Error on invalid file.
910 + * @return true|WP_Error True on success, WP_Error on invalid file.
927 911 */
928 - protected static function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
929 - if ( ! function_exists( 'activate_plugin' ) ) {
912 + protected static function uninstall_plugin( $plugin ) {
913 + if ( ! current_user_can( 'delete_plugins' ) ) {
914 + return new WP_Error( 'uninstall_failed', __( 'Current user cannot delete plugins.', 'formidable' ) );
915 + }
916 +
917 + if ( ! function_exists( 'delete_plugins' ) ) {
930 918 require_once ABSPATH . 'wp-admin/includes/plugin.php';
931 919 }
932 - return activate_plugin( $plugin, $redirect, $network_wide, $silent );
920 +
921 + self::deactivate_plugin( $plugin, true );
922 + $result = delete_plugins( array( $plugin ) );
923 +
924 + if ( is_wp_error( $result ) ) {
925 + return $result;
926 + }
927 +
928 + return true;
933 929 }
934 930
935 931 /**
936 932 * @since 5.0.10
@@ -937,9 +933,9 @@
937 933 *
938 934 * @return string
939 935 */
940 936 protected static function get_current_plugin() {
941 - if ( ! isset( self::$plugin ) ) {
937 + if ( empty( self::$plugin ) ) {
942 938 self::$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
943 939 }
944 940 return self::$plugin;
945 941 }
@@ -945,8 +941,10 @@
945 941 }
946 942
947 943 /**
948 944 * @since 4.08
945 + *
946 + * @return array|void
949 947 */
950 948 protected static function download_and_activate() {
951 949 if ( is_admin() ) {
952 950 FrmAppHelper::set_current_screen_and_hook_suffix();
@@ -957,9 +955,9 @@
957 955 $installed = self::install_addon();
958 956 if ( is_array( $installed ) && isset( $installed['message'] ) ) {
959 957 return $installed;
960 958 }
961 - self::maybe_activate_addon( $installed );
959 + self::handle_addon_action( $installed, 'activate' );
962 960 }
963 961
964 962 /**
965 963 * @since 3.04.02
@@ -967,9 +965,9 @@
967 965 * @return void
968 966 */
969 967 protected static function maybe_show_cred_form() {
970 968 if ( ! function_exists( 'request_filesystem_credentials' ) ) {
971 - include_once( ABSPATH . 'wp-admin/includes/file.php' );
969 + include_once ABSPATH . 'wp-admin/includes/file.php';
972 970 }
973 971
974 972 // Start output bufferring to catch the filesystem form if credentials are needed.
975 973 ob_start();
@@ -1011,11 +1009,9 @@
1011 1009 *
1012 1010 * @return bool
1013 1011 */
1014 1012 public static function url_is_allowed( $download_url ) {
1015 - return (
1016 - FrmAppHelper::validate_url_is_in_s3_bucket( $download_url, 'zip' ) || in_array( $download_url, self::allowed_external_urls(), true )
1017 - );
1013 + return FrmAppHelper::validate_url_is_in_s3_bucket( $download_url, 'zip' ) || in_array( $download_url, self::allowed_external_urls(), true );
1018 1014 }
1019 1015
1020 1016 /**
1021 1017 * We do not need any extra credentials if we have gotten this far,
@@ -1023,10 +1019,8 @@
1023 1019 *
1024 1020 * @since 3.04.02
1025 1021 */
1026 1022 protected static function install_addon() {
1027 - FrmAppHelper::permission_check( 'install_plugins' );
1028 -
1029 1023 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1030 1024
1031 1025 $download_url = self::get_current_plugin();
1032 1026
@@ -1054,26 +1048,130 @@
1054 1048 return $plugin;
1055 1049 }
1056 1050
1057 1051 /**
1058 - * @since 3.06.03
1052 + * Handle the AJAX request to activate an add-on.
1059 1053 *
1054 + * @since 6.8
1055 + *
1060 1056 * @return void
1061 1057 */
1062 1058 public static function ajax_activate_addon() {
1059 + self::process_addon_action(
1060 + function ( $plugin ) {
1061 + return self::handle_addon_action( $plugin, 'activate' );
1062 + },
1063 + array( 'FrmAddonsController', 'get_addon_activation_response' )
1064 + );
1065 + }
1063 1066
1067 + /**
1068 + * @since 3.04.02
1069 + *
1070 + * @param string $installed The plugin folder name with file name.
1071 + */
1072 + protected static function maybe_activate_addon( $installed ) {
1073 + self::ajax_activate_addon();
1074 + }
1075 +
1076 + /**
1077 + * Handle the AJAX request to deactivate an add-on.
1078 + *
1079 + * @since 6.8
1080 + *
1081 + * @return void
1082 + */
1083 + public static function ajax_deactivate_addon() {
1084 + self::process_addon_action(
1085 + function ( $plugin ) {
1086 + return self::handle_addon_action( $plugin, 'deactivate' );
1087 + }
1088 + );
1089 + }
1090 +
1091 + /**
1092 + * Handle the AJAX request to uninstall an add-on.
1093 + *
1094 + * @since 6.8
1095 + *
1096 + * @return void
1097 + */
1098 + public static function ajax_uninstall_addon() {
1099 + self::process_addon_action(
1100 + function ( $plugin ) {
1101 + return self::handle_addon_action( $plugin, 'uninstall' );
1102 + }
1103 + );
1104 + }
1105 +
1106 + /**
1107 + * Process a specific action (activate, deactivate, uninstall) on an add-on.
1108 + *
1109 + * @since 6.8
1110 + *
1111 + * @param callable $action_callback The specific add-on action to be executed.
1112 + * @param callable|null $response_callback Optional. The response handling callback. Default null.
1113 + * @return void
1114 + */
1115 + private static function process_addon_action( $action_callback, $response_callback = null ) {
1064 1116 self::install_addon_permissions();
1065 -
1066 1117 FrmAppHelper::set_current_screen_and_hook_suffix();
1067 1118
1068 1119 $plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
1069 - self::maybe_activate_addon( $plugin );
1120 + call_user_func( $action_callback, $plugin );
1070 1121
1071 - echo json_encode( self::get_addon_activation_response() );
1072 - wp_die();
1122 + if ( is_callable( $response_callback ) ) {
1123 + wp_send_json_success( call_user_func( $response_callback ) );
1124 + return;
1125 + }
1126 +
1127 + wp_send_json_success();
1073 1128 }
1074 1129
1075 1130 /**
1131 + * Attempt to perform a specific action (activate, deactivate, uninstall) on an add-on.
1132 + *
1133 + * @since 6.8
1134 + *
1135 + * @param string $installed The plugin folder name with file name.
1136 + * @param string $action The action type ('activate', 'deactivate', 'uninstall').
1137 + * @return array|void
1138 + */
1139 + protected static function handle_addon_action( $installed, $action ) {
1140 + if ( ! $installed || ! $action ) {
1141 + return;
1142 + }
1143 +
1144 + $result = null;
1145 + switch ( $action ) {
1146 + case 'activate':
1147 + $result = self::activate_plugin( $installed );
1148 + break;
1149 + case 'deactivate':
1150 + self::deactivate_plugin( $installed );
1151 + break;
1152 + case 'uninstall':
1153 + $result = self::uninstall_plugin( $installed );
1154 + break;
1155 + }
1156 +
1157 + if ( is_wp_error( $result ) ) {
1158 + // Ignore the invalid header message that shows with nested plugins.
1159 + if ( $result->get_error_code() !== 'no_plugin_header' ) {
1160 + if ( wp_doing_ajax() ) {
1161 + wp_send_json_error( array( 'error' => $result->get_error_message() ) );
1162 + }
1163 + return array(
1164 + 'message' => $result->get_error_message(),
1165 + 'success' => false,
1166 + );
1167 + }
1168 + }
1169 +
1170 + return $result;
1171 + }
1172 +
1173 + /**
1076 1174 * @return array
1077 1175 */
1078 1176 private static function get_addon_activation_response() {
1079 1177 $activating_page = self::get_activating_page();
@@ -1107,34 +1205,8 @@
1107 1205 return '';
1108 1206 }
1109 1207
1110 1208 /**
1111 - * @since 3.04.02
1112 - *
1113 - * @param string $installed The plugin folder name with file name
1114 - */
1115 - protected static function maybe_activate_addon( $installed ) {
1116 - if ( ! $installed ) {
1117 - return;
1118 - }
1119 -
1120 - $activate = self::activate_plugin( $installed );
1121 - if ( is_wp_error( $activate ) ) {
1122 - // Ignore the invalid header message that shows with nested plugins.
1123 - if ( $activate->get_error_code() !== 'no_plugin_header' ) {
1124 - if ( wp_doing_ajax() ) {
1125 - echo json_encode( array( 'error' => $activate->get_error_message() ) );
1126 - wp_die();
1127 - }
1128 - return array(
1129 - 'message' => $activate->get_error_message(),
1130 - 'success' => false,
1131 - );
1132 - }
1133 - }
1134 - }
1135 -
1136 - /**
1137 1209 * Run security checks before installing
1138 1210 *
1139 1211 * @since 3.04.02
1140 1212 *
@@ -1157,15 +1229,18 @@
1157 1229 public static function connect_link() {
1158 1230 $auth = get_option( 'frm_connect_token' );
1159 1231 if ( empty( $auth ) ) {
1160 1232 $auth = hash( 'sha512', wp_rand() );
1161 - update_option( 'frm_connect_token', $auth );
1233 + update_option( 'frm_connect_token', $auth, 'no' );
1162 1234 }
1163 - $link = FrmAppHelper::admin_upgrade_link( 'connect', 'api-connect' );
1235 + $page = FrmAppHelper::simple_get( 'page', 'sanitize_title', 'formidable-settings' );
1236 + $link = 'https://formidableforms.com/api-connect/';
1164 1237 $args = array(
1165 1238 'v' => 2,
1166 1239 'siteurl' => FrmAppHelper::site_url(),
1167 1240 'url' => get_rest_url(),
1241 + 'inst' => (int) FrmAppHelper::pro_is_included(),
1242 + 'return' => $page,
1168 1243 'token' => $auth,
1169 1244 'l' => self::get_pro_license(),
1170 1245 );
1171 1246
@@ -1179,17 +1254,16 @@
1179 1254 *
1180 1255 * @return bool
1181 1256 */
1182 1257 public static function can_install_addon_api() {
1183 - if ( ! current_user_can( 'activate_plugins' ) ) {
1184 - return false;
1185 - }
1186 -
1187 1258 // Verify params present (auth & download link).
1188 1259 $post_auth = FrmAppHelper::get_param( 'token', '', 'request', 'sanitize_text_field' );
1189 1260 $post_url = FrmAppHelper::get_param( 'file_url', '', 'request', 'sanitize_text_field' );
1190 1261
1191 - if ( empty( $post_auth ) || empty( $post_url ) ) {
1262 + // The download link is not required if already installed.
1263 + $is_installed = FrmAppHelper::pro_is_included();
1264 + $file_missing = ! $is_installed && empty( $post_url );
1265 + if ( ! $post_auth || $file_missing ) {
1192 1266 return false;
1193 1267 }
1194 1268
1195 1269 // Verify auth.
@@ -1204,8 +1278,10 @@
1204 1278 /**
1205 1279 * Install and/or activate the add-on file.
1206 1280 *
1207 1281 * @since 4.08
1282 + *
1283 + * @return array
1208 1284 */
1209 1285 public static function install_addon_api() {
1210 1286 self::$plugin = FrmAppHelper::get_param( 'file_url', '', 'request', 'esc_url_raw' );
1211 1287
@@ -1216,11 +1292,11 @@
1216 1292
1217 1293 // It's already installed and active.
1218 1294 $active = self::activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1219 1295 if ( is_wp_error( $active ) ) {
1220 - // Download plugin now.
1221 - $response = self::download_and_activate();
1222 - if ( is_array( $response ) && isset( $response['success'] ) ) {
1296 + $response = self::maybe_download_and_activate();
1297 + if ( is_array( $response ) ) {
1298 + // The download failed.
1223 1299 return $response;
1224 1300 }
1225 1301 }
1226 1302
@@ -1247,22 +1323,58 @@
1247 1323 );
1248 1324 }
1249 1325
1250 1326 /**
1327 + * @since 6.8.3
1328 + *
1329 + * @return array|true
1330 + */
1331 + private static function maybe_download_and_activate() {
1332 + if ( ! self::$plugin ) {
1333 + return array(
1334 + 'success' => false,
1335 + 'message' => __( 'The plugin download was not found.', 'formidable' ),
1336 + );
1337 + }
1338 +
1339 + // Download plugin now.
1340 + $response = self::download_and_activate();
1341 + if ( is_array( $response ) && isset( $response['success'] ) ) {
1342 + // The download failed.
1343 + return $response;
1344 + }
1345 +
1346 + return true;
1347 + }
1348 +
1349 + /**
1251 1350 * Render a conditional action button for a specified plugin
1252 1351 *
1253 - * @param string $plugin
1352 + * @since 4.09
1353 + *
1354 + * @param string $plugin
1254 1355 * @param array|string $upgrade_link_args
1255 - * @since 4.09
1356 + * @return void
1256 1357 */
1257 1358 public static function conditional_action_button( $plugin, $upgrade_link_args ) {
1258 1359 if ( is_callable( 'FrmProAddonsController::conditional_action_button' ) ) {
1259 - return FrmProAddonsController::conditional_action_button( $plugin, $upgrade_link_args );
1360 + FrmProAddonsController::conditional_action_button( $plugin, $upgrade_link_args );
1361 + return;
1260 1362 }
1261 1363
1262 1364 $addon = self::get_addon( $plugin );
1263 1365 $upgrade_link = FrmAppHelper::admin_upgrade_link( $upgrade_link_args );
1264 - self::addon_upgrade_link( $addon, $upgrade_link );
1366 +
1367 + if ( ! is_array( $upgrade_link_args ) ) {
1368 + // A string $upgrade_link_args is used for the utm-medium value when calling
1369 + // FrmAppHelper::admin_upgrade_link above.
1370 + // For self::addon_upgrade_link, we'll pass just an empty array with the link key (set below).
1371 + $upgrade_link_args = array();
1372 + }
1373 +
1374 + $upgrade_link_args['link'] = $upgrade_link;
1375 +
1376 + self::addon_upgrade_link( $addon, $upgrade_link_args );
1265 1377 }
1266 1378
1267 1379 /**
1268 1380 * Render a conditional action button for an add on
@@ -1268,16 +1380,22 @@
1268 1380 * Render a conditional action button for an add on
1269 1381 *
1270 1382 * @since 4.09.01
1271 1383 *
1272 - * @param array $addon
1273 - * @param string|false $license_type
1274 - * @param string $plan_required
1275 - * @param string $upgrade_link
1384 + * @param array $atts {
1385 + * Button attributes.
1386 + *
1387 + * @type array $addon
1388 + * @type false|string $license_type
1389 + * @type string $plan_required
1390 + * @type string $upgrade_link
1391 + * }
1392 + * @return void
1276 1393 */
1277 1394 public static function show_conditional_action_button( $atts ) {
1278 1395 if ( is_callable( 'FrmProAddonsController::show_conditional_action_button' ) ) {
1279 - return FrmProAddonsController::show_conditional_action_button( $atts );
1396 + FrmProAddonsController::show_conditional_action_button( $atts );
1397 + return;
1280 1398 }
1281 1399
1282 1400 self::addon_upgrade_link( $atts['addon'], $atts['upgrade_link'] );
1283 1401 }
@@ -1284,13 +1402,17 @@
1284 1402
1285 1403 /**
1286 1404 * @since 4.09.01
1287 1405 *
1288 - * @param array|false $addon
1406 + * @param array|false $addon
1407 + * @param array|string $upgrade_link
1289 1408 *
1290 1409 * @return void
1291 1410 */
1292 - protected static function addon_upgrade_link( $addon, $upgrade_link ) {
1411 + public static function addon_upgrade_link( $addon, $upgrade_link ) {
1412 + $atts = is_array( $upgrade_link ) ? $upgrade_link : array();
1413 + $upgrade_link = is_array( $upgrade_link ) ? $upgrade_link['link'] : $upgrade_link;
1414 +
1293 1415 if ( $addon ) {
1294 1416 $upgrade_link .= '&utm_content=' . $addon['slug'];
1295 1417 }
1296 1418
@@ -1297,10 +1419,15 @@
1297 1419 if ( $addon && isset( $addon['categories'] ) && in_array( 'Solution', $addon['categories'], true ) ) {
1298 1420 // Solutions will go to a separate page.
1299 1421 $upgrade_link = FrmAppHelper::admin_upgrade_link( 'addons', $addon['link'] );
1300 1422 }
1423 +
1424 + $class = ! empty( $atts['class'] ) ? $atts['class'] : '';
1425 + if ( strpos( $class, 'frm-button' ) === false ) {
1426 + $class .= ' frm-button-secondary frm-button-sm';
1427 + }
1301 1428 ?>
1302 - <a class="install-now button frm-button-secondary frm-button-sm" href="<?php echo esc_url( $upgrade_link ); ?>" target="_blank" rel="noopener" aria-label="<?php esc_attr_e( 'Upgrade Now', 'formidable' ); ?>">
1429 + <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' ); ?>">
1303 1430 <?php esc_html_e( 'Upgrade Now', 'formidable' ); ?>
1304 1431 </a>
1305 1432 <?php
1306 1433 }
@@ -1378,107 +1505,31 @@
1378 1505 return $requires;
1379 1506 }
1380 1507
1381 1508 /**
1382 - * @since 4.06.02
1509 + * @since 4.02.05
1510 + * @deprecated 6.8.3
1383 1511 *
1384 - * @deprecated 4.09.01
1385 - *
1386 - * @return void
1387 - */
1388 - public static function ajax_multiple_addons() {
1389 - FrmDeprecated::ajax_multiple_addons();
1390 - }
1391 -
1392 - /**
1393 - * @since 3.04.03
1394 - * @deprecated 3.06
1395 1512 * @codeCoverageIgnore
1396 - * @return array
1397 - */
1398 - public static function error_for_license( $license ) {
1399 - return FrmDeprecated::error_for_license( $license );
1400 - }
1401 -
1402 - /**
1403 - * @since 3.04.03
1404 - * @deprecated 3.06
1405 - * @codeCoverageIgnore
1406 - */
1407 - public static function get_pro_updater() {
1408 - return FrmDeprecated::get_pro_updater();
1409 - }
1410 -
1411 - /**
1412 - * @since 3.04.03
1413 - * @deprecated 3.06
1414 - * @codeCoverageIgnore
1415 1513 *
1416 - * @return array
1417 - */
1418 - public static function get_addon_info( $license = '' ) {
1419 - return FrmDeprecated::get_addon_info( $license );
1420 - }
1421 -
1422 - /**
1423 - * @since 3.04.03
1424 - * @deprecated 3.06
1425 - * @codeCoverageIgnore
1426 - *
1427 - * @return string
1428 - */
1429 - public static function get_cache_key( $license ) {
1430 - return FrmDeprecated::get_cache_key( $license );
1431 - }
1432 -
1433 - /**
1434 - * @since 3.04.03
1435 - *
1436 - * @deprecated 3.06
1437 - *
1438 - * @codeCoverageIgnore
1439 - *
1440 1514 * @return void
1441 1515 */
1442 - public static function reset_cached_addons( $license = '' ) {
1443 - FrmDeprecated::reset_cached_addons( $license );
1516 + public static function connect_pro() {
1517 + _deprecated_function( __METHOD__, '6.8.3' );
1444 1518 }
1445 1519
1446 1520 /**
1447 - * @since 2.03.08
1448 - * @deprecated 3.04.03
1449 - * @codeCoverageIgnore
1521 + * @since 4.08
1522 + * @deprecated 6.11.1
1450 1523 *
1451 - * @param boolean $return
1452 - * @param string $package
1453 - *
1454 - * @return boolean
1524 + * @return bool|int false or the number of days until expiration.
1455 1525 */
1456 - public static function add_shorten_edd_filename_filter( $return, $package ) {
1457 - return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
1458 - }
1526 + public static function is_license_expiring() {
1527 + _deprecated_function( __METHOD__, '6.11.1', 'FrmProAddonsController::is_license_expiring' );
1459 1528
1460 - /**
1461 - * @since 2.03.08
1462 - * @deprecated 3.04.03
1463 - * @codeCoverageIgnore
1464 - *
1465 - * @param string $filename
1466 - * @param string $ext
1467 - *
1468 - * @return string
1469 - */
1470 - public static function shorten_edd_filename( $filename, $ext ) {
1471 - return FrmDeprecated::shorten_edd_filename( $filename, $ext );
1472 - }
1529 + if ( is_callable( 'FrmProAddonsController::is_license_expiring' ) ) {
1530 + return FrmProAddonsController::is_license_expiring();
1531 + }
1473 1532
1474 - /**
1475 - * @deprecated 3.04.03
1476 - *
1477 - * @codeCoverageIgnore
1478 - *
1479 - * @return void
1480 - */
1481 - public static function get_licenses() {
1482 - FrmDeprecated::get_licenses();
1533 + return false;
1483 1534 }
1484 1535 }