PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.9
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.9
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / controllers / FrmAddonsController.php

FrmAddonsController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.9, at classes/controllers/FrmAddonsController.php

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