PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0.03
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0.03
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 5.0.03, at classes/controllers/FrmAddonsController.php

1,265 lines 34.5 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 public static function menu() {
9 if ( ! current_user_can( 'activate_plugins' ) ) {
10 return;
11 }
12
13 $label = __( 'Add-Ons', 'formidable' );
14 $label = '<span style="color:#fe5a1d">' . $label . '</span>';
15
16 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
17
18 if ( ! FrmAppHelper::pro_is_installed() ) {
19 add_submenu_page(
20 'formidable',
21 'Formidable | ' . __( 'Upgrade', 'formidable' ),
22 '<span class="frm-upgrade-submenu">' . __( 'Upgrade', 'formidable' ) . '</span>',
23 'frm_view_forms',
24 'formidable-pro-upgrade',
25 'FrmAddonsController::upgrade_to_pro'
26 );
27 } elseif ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) ) {
28 wp_safe_redirect( admin_url( 'admin.php?page=formidable' ) );
29 exit;
30 }
31 }
32
33 public static function list_addons() {
34 FrmAppHelper::include_svg();
35 $installed_addons = apply_filters( 'frm_installed_addons', array() );
36 $license_type = '';
37
38 $addons = self::get_api_addons();
39 $errors = array();
40
41 if ( isset( $addons['error'] ) ) {
42 $api = new FrmFormApi();
43 $errors = $api->get_error_from_response( $addons );
44 $license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
45 unset( $addons['error'] );
46 }
47
48 $pro = array(
49 'pro' => array(
50 'title' => 'Formidable Forms Pro',
51 'slug' => 'formidable-pro',
52 'released' => '2011-02-05',
53 'docs' => 'knowledgebase/',
54 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
55 ),
56 );
57 $addons = $pro + $addons;
58 self::prepare_addons( $addons );
59
60 $pricing = FrmAppHelper::admin_upgrade_link( 'addons' );
61
62 include( FrmAppHelper::plugin_path() . '/classes/views/addons/list.php' );
63 }
64
65 public static function license_settings() {
66 $plugins = apply_filters( 'frm_installed_addons', array() );
67 if ( empty( $plugins ) ) {
68 esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
69
70 return;
71 }
72
73 ksort( $plugins );
74
75 include( FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php' );
76 }
77
78 protected static function get_api_addons() {
79 $api = new FrmFormApi();
80 $addons = $api->get_api_info();
81
82 if ( empty( $addons ) ) {
83 $addons = self::fallback_plugin_list();
84 } else {
85 foreach ( $addons as $k => $addon ) {
86 if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
87 unset( $addons[ $k ] );
88 }
89 }
90 }
91
92 return $addons;
93 }
94
95 /**
96 * If the API is unable to connect, show something on the addons page
97 *
98 * @since 3.04.03
99 * @return array
100 */
101 protected static function fallback_plugin_list() {
102 $list = array(
103 'formidable-pro' => array(
104 'title' => 'Formidable Forms Pro',
105 'link' => 'pricing/',
106 'docs' => '',
107 'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
108 ),
109 'mailchimp' => array(
110 'title' => 'MailChimp Forms',
111 '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.',
112 ),
113 'registration' => array(
114 'title' => 'User Registration Forms',
115 'link' => 'downloads/user-registration/',
116 '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.',
117 ),
118 'paypal' => array(
119 'title' => 'PayPal Standard Forms',
120 'link' => 'downloads/paypal-standard/',
121 '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.',
122 ),
123 'stripe' => array(
124 'title' => 'Stripe Forms',
125 'docs' => 'knowledgebase/stripe/',
126 'excerpt' => 'Any Formidable forms on your site can accept credit card payments without users ever leaving your site.',
127 ),
128 'authorize-net' => array(
129 'title' => 'Authorize.net AIM Forms',
130 'link' => 'downloads/authorize-net-aim/',
131 'docs' => 'knowledgebase/authorize-net-aim/',
132 'excerpt' => 'Accept one-time payments directly on your site, using Authorize.net AIM.',
133 ),
134 'woocommerce' => array(
135 'title' => 'WooCommerce Forms',
136 'excerpt' => 'Use a Formidable form on your WooCommerce product pages.',
137 ),
138 'autoresponder' => array(
139 'title' => 'Form Action Automation',
140 'docs' => 'knowledgebase/schedule-autoresponder/',
141 'excerpt' => 'Schedule email notifications, SMS messages, and API actions.',
142 ),
143 'modal' => array(
144 'title' => 'Bootstrap Modal Forms',
145 'link' => 'downloads/bootstrap-modal/',
146 'docs' => 'knowledgebase/bootstrap-modal/',
147 'excerpt' => 'Open a view or form in a Bootstrap popup.',
148 ),
149 'bootstrap' => array(
150 'title' => 'Bootstrap Style Forms',
151 'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
152 ),
153 'zapier' => array(
154 'title' => 'Zapier Forms',
155 '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.',
156 ),
157 'signature' => array(
158 'title' => 'Digital Signature Forms',
159 'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
160 ),
161 'api' => array(
162 'title' => 'Formidable Forms API',
163 'link' => 'downloads/formidable-api/',
164 '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.',
165 ),
166 'twilio' => array(
167 'title' => 'Twilio SMS Forms',
168 'docs' => 'knowledgebase/twilio-add-on/',
169 'excerpt' => 'Allow users to text their votes for polls created by Formidable Forms, or send SMS notifications when entries are submitted or updated.',
170 ),
171 'views' => array(
172 'title' => 'Formidable Views',
173 'excerpt' => 'Add the power of views to your Formidable Forms to display your form submissions in listings, tables, calendars, and more.',
174 ),
175 );
176
177 $defaults = array(
178 'released' => '',
179 );
180
181 foreach ( $list as $k => $info ) {
182 $info['slug'] = $k;
183 $list[ $k ] = array_merge( $defaults, $info );
184 }
185 return $list;
186 }
187
188 /**
189 * If Pro is missing but has been authenticated, include a download URL
190 *
191 * @since 3.04.03
192 * @return string
193 */
194 public static function get_pro_download_url() {
195 $license = self::get_pro_license();
196 $api = new FrmFormApi( $license );
197 $downloads = $api->get_api_info();
198 $pro = self::get_pro_from_addons( $downloads );
199
200 return isset( $pro['url'] ) ? $pro['url'] : '';
201 }
202
203 /**
204 * @since 4.08
205 */
206 public static function get_pro_license() {
207 $pro_cred_store = 'frmpro-credentials';
208 $pro_wpmu_store = 'frmpro-wpmu-sitewide';
209 if ( is_multisite() && get_site_option( $pro_wpmu_store ) ) {
210 $creds = get_site_option( $pro_cred_store );
211 } else {
212 $creds = get_option( $pro_cred_store );
213 }
214
215 if ( empty( $creds ) || ! is_array( $creds ) || ! isset( $creds['license'] ) ) {
216 return '';
217 }
218
219 $license = $creds['license'];
220 if ( empty( $license ) ) {
221 return '';
222 }
223
224 if ( strpos( $license, '-' ) ) {
225 // this is a fix for licenses saved in the past
226 $license = strtoupper( $license );
227 }
228 return $license;
229 }
230
231 /**
232 * @since 4.08
233 */
234 protected static function get_pro_from_addons( $addons ) {
235 return isset( $addons['93790'] ) ? $addons['93790'] : array();
236 }
237
238 /**
239 * @since 4.06
240 */
241 public static function license_type() {
242 if ( is_callable( 'FrmProAddonsController::license_type' ) ) {
243 return FrmProAddonsController::license_type();
244 }
245
246 return 'free';
247 }
248
249 /**
250 * @since 4.0.01
251 */
252 public static function is_license_expired() {
253 $version_info = self::get_primary_license_info();
254 if ( ! isset( $version_info['error'] ) ) {
255 return false;
256 }
257
258 return $version_info['error'];
259 }
260
261 /**
262 * @since 4.08
263 *
264 * @return boolean|int false or the number of days until expiration.
265 */
266 public static function is_license_expiring() {
267 if ( is_callable( 'FrmProAddonsController::is_license_expiring' ) ) {
268 return FrmProAddonsController::is_license_expiring();
269 }
270
271 return false;
272 }
273
274 /**
275 * @since 4.08
276 */
277 protected static function get_primary_license_info() {
278 $installed_addons = apply_filters( 'frm_installed_addons', array() );
279 if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
280 return false;
281 }
282 $installed_addons = array(
283 'formidable_pro' => $installed_addons['formidable_pro'],
284 );
285
286 return self::fill_update_addon_info( $installed_addons );
287 }
288
289 /**
290 * @since 3.04.03
291 */
292 public static function check_update( $transient ) {
293 if ( ! FrmAppHelper::pro_is_installed() ) {
294 // Don't make any changes if only Lite is installed.
295 return $transient;
296 }
297
298 if ( ! is_object( $transient ) ) {
299 $transient = new stdClass();
300 }
301
302 $installed_addons = apply_filters( 'frm_installed_addons', array() );
303 if ( empty( $installed_addons ) ) {
304 return $transient;
305 }
306
307 $version_info = self::fill_update_addon_info( $installed_addons );
308
309 $transient->last_checked = time();
310
311 if ( ! function_exists( 'get_plugins' ) ) {
312 require_once ABSPATH . 'wp-admin/includes/plugin.php';
313 }
314 $wp_plugins = get_plugins();
315
316 foreach ( $version_info as $id => $plugin ) {
317 $plugin = (object) $plugin;
318
319 if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
320 continue;
321 }
322
323 $folder = $plugin->plugin;
324 if ( empty( $folder ) ) {
325 continue;
326 }
327
328 if ( ! self::is_installed( $folder ) ) {
329 // don't show an update if the plugin isn't installed
330 continue;
331 }
332
333 $wp_plugin = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
334 $wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
335
336 if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
337 $slug = explode( '/', $folder );
338 $plugin->slug = $slug[0];
339 $transient->response[ $folder ] = $plugin;
340 }
341
342 $transient->checked[ $folder ] = $wp_version;
343
344 }
345
346 return $transient;
347 }
348
349 /**
350 * Check if a plugin is installed before showing an update for it
351 *
352 * @since 3.05
353 *
354 * @param string $plugin - the folder/filename.php for a plugin
355 *
356 * @return bool - True if installed
357 */
358 protected static function is_installed( $plugin ) {
359 if ( ! function_exists( 'get_plugins' ) ) {
360 require_once ABSPATH . 'wp-admin/includes/plugin.php';
361 }
362
363 $all_plugins = get_plugins();
364
365 return isset( $all_plugins[ $plugin ] );
366 }
367
368 /**
369 * @since 3.04.03
370 *
371 * @param array $installed_addons
372 *
373 * @return array
374 */
375 protected static function fill_update_addon_info( $installed_addons ) {
376 $checked_licenses = array();
377 $version_info = array();
378
379 foreach ( $installed_addons as $addon ) {
380 if ( $addon->store_url !== 'https://formidableforms.com' ) {
381 // check if this is a third-party addon
382 continue;
383 }
384
385 $new_license = $addon->license;
386 if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
387 continue;
388 }
389
390 $checked_licenses[] = $new_license;
391
392 $api = new FrmFormApi( $new_license );
393 if ( empty( $version_info ) ) {
394 $version_info = $api->get_api_info();
395 continue;
396 }
397
398 $plugin = $api->get_addon_for_license( $addon, $version_info );
399 if ( empty( $plugin ) ) {
400 continue;
401 }
402
403 $download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
404 if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
405 // if this addon is using its own license, get the update url
406 $addon_info = $api->get_api_info();
407
408 $version_info[ $download_id ] = $addon_info[ $download_id ];
409 if ( isset( $addon_info['error'] ) ) {
410 $version_info[ $download_id ]['error'] = array(
411 'message' => $addon_info['error']['message'],
412 'code' => $addon_info['error']['code'],
413 );
414 }
415 }
416 }
417
418 return $version_info;
419 }
420
421 /**
422 * Get the action link for an addon that isn't active.
423 *
424 * @since 3.06.03
425 * @param string $plugin The plugin slug
426 * @return array
427 */
428 public static function install_link( $plugin ) {
429 $link = array();
430 $addon = self::get_addon( $plugin );
431
432 if ( $addon ) {
433 if ( $addon['status']['type'] === 'installed' && ! empty( $addon['activate_url'] ) ) {
434 $link = array(
435 'url' => $addon['plugin'],
436 'class' => 'frm-activate-addon',
437 );
438 } elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
439 $link = array(
440 'url' => $addon['url'],
441 'class' => 'frm-install-addon',
442 );
443 } elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
444 $link = array(
445 'categories' => $addon['categories'],
446 );
447 }
448
449 if ( ! empty( $link ) ) {
450 $link['status'] = $addon['status']['type'];
451 }
452 }
453
454 return $link;
455 }
456
457 /**
458 * @since 4.09
459 * @param string $plugin The plugin slug
460 * @return array|false
461 */
462 protected static function get_addon( $plugin ) {
463 $addons = self::get_api_addons();
464 self::prepare_addons( $addons );
465 foreach ( $addons as $addon ) {
466 $slug = explode( '/', $addon['plugin'] );
467 if ( $slug[0] === 'formidable-' . $plugin ) {
468 return $addon;
469 }
470 }
471 return false;
472 }
473
474 /**
475 * @since 4.09
476 * @return string
477 */
478 protected static function get_license_type() {
479 $license_type = '';
480 $addons = self::get_api_addons();
481 if ( isset( $addons['error'] ) && isset( $addons['error']['type'] ) ) {
482 $license_type = $addons['error']['type'];
483 }
484 return $license_type;
485 }
486
487 /**
488 * @since 3.04.03
489 *
490 * @param array $addons
491 * @param object $license The FrmAddon object
492 *
493 * @return array
494 */
495 public static function get_addon_for_license( $addons, $license ) {
496 $download_id = $license->download_id;
497 $plugin = array();
498 if ( empty( $download_id ) && ! empty( $addons ) ) {
499 foreach ( $addons as $addon ) {
500 if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
501 return $addon;
502 }
503 }
504 } elseif ( isset( $addons[ $download_id ] ) ) {
505 $plugin = $addons[ $download_id ];
506 }
507
508 return $plugin;
509 }
510
511 protected static function prepare_addons( &$addons ) {
512 $activate_url = '';
513 if ( current_user_can( 'activate_plugins' ) ) {
514 $activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
515 }
516
517 $loop_addons = $addons;
518 foreach ( $loop_addons as $id => $addon ) {
519 if ( is_numeric( $id ) ) {
520 $slug = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
521 $file_name = $addon['plugin'];
522 } else {
523 $slug = $id;
524 if ( isset( $addon['file'] ) ) {
525 $base_file = $addon['file'];
526 } else {
527 $base_file = 'formidable-' . $slug;
528 }
529 $file_name = $base_file . '/' . $base_file . '.php';
530 if ( ! isset( $addon['plugin'] ) ) {
531 $addon['plugin'] = $file_name;
532 }
533 }
534
535 $addon['installed'] = self::is_installed( $file_name );
536 if ( $addon['installed'] && 'formidable-views/formidable-views.php' === $file_name ) {
537 $active_views_version = self::get_active_views_version();
538 if ( false !== $active_views_version && $slug !== $active_views_version ) {
539 $addon['installed'] = false;
540 }
541 }
542
543 $addon['activate_url'] = '';
544
545 if ( $addon['installed'] && ! empty( $activate_url ) && ! self::is_plugin_active( $file_name, $slug ) ) {
546 $addon['activate_url'] = add_query_arg(
547 array(
548 '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
549 'plugin' => $file_name,
550 ),
551 $activate_url
552 );
553 }
554
555 if ( ! isset( $addon['docs'] ) ) {
556 $addon['docs'] = 'knowledgebase/formidable-' . $slug . '/';
557 }
558 self::prepare_addon_link( $addon['docs'] );
559
560 if ( ! isset( $addon['link'] ) ) {
561 $addon['link'] = 'downloads/' . $slug . '/';
562 }
563 self::prepare_addon_link( $addon['link'] );
564
565 self::set_addon_status( $addon );
566 $addons[ $id ] = $addon;
567 }
568 }
569
570 private static function is_plugin_active( $file_name, $slug ) {
571 if ( 'formidable-views/formidable-views.php' === $file_name ) {
572 return self::get_active_views_version() === $slug;
573 }
574 return is_plugin_active( $file_name );
575 }
576
577 /**
578 * @return string|false either 'visual-views' or 'views', false if one is not found.
579 */
580 private static function get_active_views_version() {
581 if ( ! is_callable( 'FrmViewsAppHelper::plugin_version' ) ) {
582 return false;
583 }
584 $plugin_version = FrmViewsAppHelper::plugin_version();
585 return version_compare( $plugin_version, '5.0', '>=' ) ? 'visual-views' : 'views';
586 }
587
588 /**
589 * @since 3.04.02
590 */
591 protected static function prepare_addon_link( &$link ) {
592 $site_url = 'https://formidableforms.com/';
593 if ( strpos( $link, 'http' ) !== 0 ) {
594 $link = $site_url . $link;
595 }
596 $link = FrmAppHelper::make_affiliate_url( $link );
597 $query_args = array(
598 'utm_source' => 'WordPress',
599 'utm_medium' => 'addons',
600 'utm_campaign' => 'liteplugin',
601 );
602 $link = add_query_arg( $query_args, $link );
603 }
604
605 /**
606 * Add the status to the addon array. Status options are:
607 * installed, active, not installed
608 *
609 * @since 3.04.02
610 */
611 protected static function set_addon_status( &$addon ) {
612 if ( ! empty( $addon['activate_url'] ) ) {
613 $addon['status'] = array(
614 'type' => 'installed',
615 'label' => __( 'Installed', 'formidable' ),
616 );
617 } elseif ( $addon['installed'] ) {
618 $addon['status'] = array(
619 'type' => 'active',
620 'label' => __( 'Active', 'formidable' ),
621 );
622 } else {
623 $addon['status'] = array(
624 'type' => 'not-installed',
625 'label' => __( 'Not Installed', 'formidable' ),
626 );
627 }
628 }
629
630 public static function upgrade_to_pro() {
631 FrmAppHelper::include_svg();
632
633 $link_parts = array(
634 'medium' => 'upgrade',
635 'content' => 'button',
636 );
637
638 $features = array(
639 'Display Entries' => array(
640 array(
641 'label' => 'Display form data with virtually limitless views',
642 'link' => array(
643 'content' => 'views',
644 'param' => 'views-display-form-data',
645 ),
646 'lite' => false,
647 ),
648 array(
649 'label' => 'Generate graphs and stats based on your submitted data',
650 'link' => array(
651 'content' => 'graphs',
652 'param' => 'statistics-graphs-wordpress-forms',
653 ),
654 'lite' => false,
655 ),
656 ),
657 'Entry Management' => array(
658 array(
659 'label' => 'Import entries from a CSV',
660 'link' => array(
661 'content' => 'import-entries',
662 'param' => 'importing-exporting-wordpress-forms',
663 ),
664 'lite' => false,
665 ),
666 array(
667 'label' => 'Logged-in users can save drafts and return later',
668 'link' => array(
669 'content' => 'save-drafts',
670 'param' => 'save-drafts-wordpress-form',
671 ),
672 'lite' => false,
673 ),
674 array(
675 'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
676 'link' => array(
677 'content' => 'front-edit',
678 'param' => 'wordpress-front-end-editing',
679 ),
680 'lite' => false,
681 ),
682 array(
683 'label' => 'View form submissions from the back-end',
684 'lite' => true,
685 ),
686 array(
687 'label' => 'Export your entries to a CSV',
688 'lite' => true,
689 ),
690 ),
691 'Form Building' => array(
692 array(
693 'label' => 'Save a calculated value into a field',
694 'link' => array(
695 'content' => 'calculations',
696 'param' => 'field-calculations-wordpress-form',
697 ),
698 'lite' => false,
699 ),
700 array(
701 'label' => 'Allow multiple file uploads',
702 'link' => array(
703 'content' => 'file-uploads',
704 'param' => 'wordpress-multi-file-upload-fields',
705 ),
706 'lite' => false,
707 ),
708 array(
709 'label' => 'Repeat sections of fields',
710 'link' => array(
711 'content' => 'repeaters',
712 'param' => 'repeatable-sections-forms',
713 ),
714 'lite' => false,
715 ),
716 array(
717 'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
718 'link' => array(
719 'content' => 'conditional-logic',
720 'param' => 'conditional-logic-wordpress-forms',
721 ),
722 'lite' => false,
723 ),
724 array(
725 'label' => 'Confirmation fields',
726 'link' => array(
727 'content' => 'confirmation-fields',
728 'param' => 'confirmation-fields-wordpress-forms',
729 ),
730 'lite' => false,
731 ),
732 array(
733 'label' => 'Multi-paged forms',
734 'link' => array(
735 'content' => 'page-breaks',
736 'param' => 'wordpress-multi-page-forms',
737 ),
738 'lite' => false,
739 ),
740 array(
741 '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.',
742 'lite' => false,
743 ),
744 array(
745 'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
746 'lite' => true,
747 ),
748 array(
749 'label' => 'Drag & Drop Form building',
750 'link' => array(
751 'content' => 'drag-drop',
752 'param' => 'drag-drop-forms',
753 ),
754 'lite' => true,
755 ),
756 array(
757 'label' => 'Create forms from Templates',
758 'link' => array(
759 'content' => 'form-templates',
760 'param' => 'wordpress-form-templates',
761 ),
762 'lite' => true,
763 ),
764 array(
765 'label' => 'Import and export forms with XML',
766 'link' => array(
767 'content' => 'import',
768 'param' => 'importing-exporting-wordpress-forms',
769 ),
770 'lite' => true,
771 ),
772 array(
773 'label' => 'Use input placeholder text in your fields that clear when typing starts.',
774 'lite' => true,
775 ),
776 ),
777 'Form Actions' => array(
778 array(
779 'label' => 'Conditionally send your email notifications based on values in your form',
780 'link' => array(
781 'content' => 'conditional-emails',
782 ),
783 'lite' => false,
784 ),
785 array(
786 'label' => 'Create and edit WordPress posts or custom posts from the front-end',
787 'link' => array(
788 'content' => 'create-posts',
789 'param' => 'create-posts-pages-wordpress-forms',
790 ),
791 'lite' => false,
792 ),
793 array(
794 'label' => 'Send multiple emails and autoresponders',
795 'link' => array(
796 'content' => 'multiple-emails',
797 'param' => 'virtually-unlimited-emails',
798 ),
799 'lite' => true,
800 ),
801 ),
802 'Form Appearance' => array(
803 array(
804 'label' => 'Create Multiple styles for different forms',
805 'link' => array(
806 'content' => 'multiple-styles',
807 'param' => 'wordpress-visual-form-styler',
808 ),
809 'lite' => false,
810 ),
811 array(
812 'label' => 'Customizable layout with CSS classes',
813 'link' => array(
814 'content' => 'form-layout',
815 'param' => 'wordpress-mobile-friendly-forms',
816 ),
817 'lite' => true,
818 ),
819 array(
820 'label' => 'Customize the HTML for your forms',
821 'link' => array(
822 'content' => 'custom-html',
823 'param' => 'customizable-html-wordpress-form',
824 ),
825 'lite' => true,
826 ),
827 array(
828 'label' => 'Style your form with the Visual Form Styler',
829 'lite' => true,
830 ),
831 ),
832 );
833
834 include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
835 }
836
837 /**
838 * Install Pro after connection with Formidable.
839 *
840 * @since 4.02.05
841 */
842 public static function connect_pro() {
843 FrmAppHelper::permission_check( 'install_plugins' );
844 check_ajax_referer( 'frm_ajax', 'nonce' );
845
846 $url = FrmAppHelper::get_post_param( 'plugin', '', 'sanitize_text_field' );
847 if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
848 wp_die();
849 }
850
851 $response = array();
852
853 // It's already installed and active.
854 $active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
855 if ( is_wp_error( $active ) ) {
856 // The plugin was installed, but not active. Download it now.
857 self::ajax_install_addon();
858 } else {
859 $response['active'] = true;
860 $response['success'] = true;
861 }
862
863 echo json_encode( $response );
864 wp_die();
865 }
866
867 /**
868 * @since 4.08
869 */
870 protected static function download_and_activate() {
871 // Set the current screen to avoid undefined notices.
872 if ( is_admin() ) {
873 global $hook_suffix;
874 set_current_screen();
875 }
876
877 self::maybe_show_cred_form();
878
879 $installed = self::install_addon();
880 if ( is_array( $installed ) && isset( $installed['message'] ) ) {
881 return $installed;
882 }
883 self::maybe_activate_addon( $installed );
884 }
885
886 /**
887 * @since 3.04.02
888 */
889 protected static function maybe_show_cred_form() {
890 if ( ! function_exists( 'request_filesystem_credentials' ) ) {
891 include_once( ABSPATH . 'wp-admin/includes/file.php' );
892 }
893
894 // Start output bufferring to catch the filesystem form if credentials are needed.
895 ob_start();
896
897 $show_form = false;
898 $method = '';
899 $url = add_query_arg( array( 'page' => 'formidable-settings' ), admin_url( 'admin.php' ) );
900 $url = esc_url_raw( $url );
901 $creds = request_filesystem_credentials( $url, $method, false, false, null );
902
903 if ( false === $creds ) {
904 $show_form = true;
905 } elseif ( ! WP_Filesystem( $creds ) ) {
906 request_filesystem_credentials( $url, $method, true, false, null );
907 $show_form = true;
908 }
909
910 if ( $show_form ) {
911 $form = ob_get_clean();
912 $message = __( 'Sorry, your site requires FTP authentication. Please download plugins from FormidableForms.com and install them manually.', 'formidable' );
913 $data = $form;
914 $response = array(
915 'success' => false,
916 'message' => $message,
917 'form' => $form,
918 );
919 wp_send_json( $response );
920 }
921
922 ob_end_clean();
923 }
924
925 /**
926 * We do not need any extra credentials if we have gotten this far,
927 * so let's install the plugin.
928 *
929 * @since 3.04.02
930 */
931 protected static function install_addon() {
932 require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
933
934 $download_url = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
935
936 // Create the plugin upgrader with our custom skin.
937 $installer = new Plugin_Upgrader( new FrmInstallerSkin() );
938 $installer->install( $download_url );
939
940 // Flush the cache and return the newly installed plugin basename.
941 wp_cache_flush();
942
943 $plugin = $installer->plugin_info();
944 if ( empty( $plugin ) ) {
945 return array(
946 'message' => 'Plugin was not installed. ' . $installer->result,
947 'success' => false,
948 );
949 }
950 return $plugin;
951 }
952
953 /**
954 * @since 3.06.03
955 */
956 public static function ajax_activate_addon() {
957
958 self::install_addon_permissions();
959
960 // Set the current screen to avoid undefined notices.
961 global $hook_suffix;
962 set_current_screen();
963
964 $plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
965 self::maybe_activate_addon( $plugin );
966
967 // Send back a response.
968 echo json_encode( __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' ) );
969 wp_die();
970 }
971
972 /**
973 * @since 3.04.02
974 * @param string $installed The plugin folder name with file name
975 */
976 protected static function maybe_activate_addon( $installed ) {
977 if ( ! $installed ) {
978 return;
979 }
980
981 $activate = activate_plugin( $installed );
982 if ( is_wp_error( $activate ) ) {
983 // Ignore the invalid header message that shows with nested plugins.
984 if ( $activate->get_error_code() !== 'no_plugin_header' ) {
985 if ( wp_doing_ajax() ) {
986 echo json_encode( array( 'error' => $activate->get_error_message() ) );
987 wp_die();
988 }
989 return array(
990 'message' => $activate->get_error_message(),
991 'success' => false,
992 );
993 }
994 }
995 }
996
997 /**
998 * Run security checks before installing
999 *
1000 * @since 3.04.02
1001 */
1002 protected static function install_addon_permissions() {
1003 check_ajax_referer( 'frm_ajax', 'nonce' );
1004
1005 if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) ) {
1006 echo json_encode( true );
1007 wp_die();
1008 }
1009 }
1010
1011 /**
1012 * @since 4.08
1013 */
1014 public static function connect_link() {
1015 $auth = get_option( 'frm_connect_token' );
1016 if ( empty( $auth ) ) {
1017 $auth = hash( 'sha512', wp_rand() );
1018 update_option( 'frm_connect_token', $auth );
1019 }
1020 $link = FrmAppHelper::admin_upgrade_link( 'connect', 'api-connect' );
1021 $args = array(
1022 'v' => 2,
1023 'siteurl' => FrmAppHelper::site_url(),
1024 'url' => get_rest_url(),
1025 'token' => $auth,
1026 'l' => self::get_pro_license(),
1027 );
1028
1029 return add_query_arg( $args, $link );
1030 }
1031
1032 /**
1033 * Check the auth value for install permission.
1034 *
1035 * @since 4.08
1036 *
1037 * @return bool
1038 */
1039 public static function can_install_addon_api() {
1040 // Verify params present (auth & download link).
1041 $post_auth = FrmAppHelper::get_param( 'token', '', 'request', 'sanitize_text_field' );
1042 $post_url = FrmAppHelper::get_param( 'file_url', '', 'request', 'sanitize_text_field' );
1043
1044 if ( empty( $post_auth ) || empty( $post_url ) ) {
1045 return false;
1046 }
1047
1048 // Verify auth.
1049 $auth = get_option( 'frm_connect_token' );
1050 if ( empty( $auth ) || ! hash_equals( $auth, $post_auth ) ) {
1051 return false;
1052 }
1053
1054 return true;
1055 }
1056
1057 /**
1058 * Install and/or activate the add-on file.
1059 *
1060 * @since 4.08
1061 */
1062 public static function install_addon_api() {
1063 // Sanitize when it's used to prevent double sanitizing.
1064 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
1065 $_POST['plugin'] = isset( $_REQUEST['file_url'] ) ? $_REQUEST['file_url'] : ''; // Set for later use
1066
1067 $error = esc_html__( 'Could not install an upgrade. Please download from formidableforms.com and install manually.', 'formidable' );
1068
1069 // Delete so cannot replay.
1070 delete_option( 'frm_connect_token' );
1071
1072 // It's already installed and active.
1073 $active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1074 if ( is_wp_error( $active ) ) {
1075 // Download plugin now.
1076 $response = self::download_and_activate();
1077 if ( is_array( $response ) && isset( $response['success'] ) ) {
1078 return $response;
1079 }
1080 }
1081
1082 // If empty license, save it now.
1083 if ( empty( self::get_pro_license() ) && function_exists( 'load_formidable_pro' ) ) {
1084 load_formidable_pro();
1085 $license = stripslashes( FrmAppHelper::get_param( 'key', '', 'request', 'sanitize_text_field' ) );
1086 if ( empty( $license ) ) {
1087 return array(
1088 'success' => false,
1089 'error' => 'That site does not have a valid license key.',
1090 );
1091 }
1092
1093 $response = FrmAddon::activate_license_for_plugin( $license, 'formidable_pro' );
1094 if ( ! $response['success'] ) {
1095 // Could not activate license.
1096 return $response;
1097 }
1098 }
1099
1100 return array(
1101 'success' => true,
1102 );
1103 }
1104
1105 /**
1106 * Render a conditional action button for a specified plugin
1107 *
1108 * @param string $plugin
1109 * @param array|string $upgrade_link_args
1110 * @since 4.09
1111 */
1112 public static function conditional_action_button( $plugin, $upgrade_link_args ) {
1113 if ( is_callable( 'FrmProAddonsController::conditional_action_button' ) ) {
1114 return FrmProAddonsController::conditional_action_button( $plugin, $upgrade_link_args );
1115 }
1116
1117 $addon = self::get_addon( $plugin );
1118 $upgrade_link = FrmAppHelper::admin_upgrade_link( $upgrade_link_args );
1119 self::addon_upgrade_link( $addon, $upgrade_link );
1120 }
1121
1122 /**
1123 * Render a conditional action button for an add on
1124 *
1125 * @since 4.09.01
1126 * @param array $addon
1127 * @param string|false $license_type
1128 * @param string $plan_required
1129 * @param string $upgrade_link
1130 */
1131 public static function show_conditional_action_button( $atts ) {
1132 if ( is_callable( 'FrmProAddonsController::show_conditional_action_button' ) ) {
1133 return FrmProAddonsController::show_conditional_action_button( $atts );
1134 }
1135
1136 self::addon_upgrade_link( $atts['addon'], $atts['upgrade_link'] );
1137 }
1138
1139 /**
1140 * @since 4.09.01
1141 */
1142 protected static function addon_upgrade_link( $addon, $upgrade_link ) {
1143 if ( $addon ) {
1144 $upgrade_link .= '&utm_content=' . $addon['slug'];
1145 }
1146
1147 if ( $addon && isset( $addon['categories'] ) && in_array( 'Solution', $addon['categories'], true ) ) {
1148 // Solutions will go to a separate page.
1149 $upgrade_link = FrmAppHelper::admin_upgrade_link( 'addons', $addon['link'] );
1150 }
1151 ?>
1152 <a class="install-now button button-secondary frm-button-secondary" href="<?php echo esc_url( $upgrade_link ); ?>" target="_blank" rel="noopener" aria-label="<?php esc_attr_e( 'Upgrade Now', 'formidable' ); ?>">
1153 <?php esc_html_e( 'Upgrade Now', 'formidable' ); ?>
1154 </a>
1155 <?php
1156 }
1157
1158 /**
1159 * @since 3.04.02
1160 */
1161 public static function ajax_install_addon() {
1162 self::install_addon_permissions();
1163
1164 self::download_and_activate();
1165
1166 // Send back a response.
1167 echo json_encode( __( 'Your plugin has been installed. Please reload the page to see more options.', 'formidable' ) );
1168 wp_die();
1169 }
1170
1171 /**
1172 * @since 4.06.02
1173 * @deprecated 4.09.01
1174 */
1175 public static function ajax_multiple_addons() {
1176 FrmDeprecated::ajax_multiple_addons();
1177 }
1178
1179 /**
1180 * @since 3.04.03
1181 * @deprecated 3.06
1182 * @codeCoverageIgnore
1183 * @return array
1184 */
1185 public static function error_for_license( $license ) {
1186 return FrmDeprecated::error_for_license( $license );
1187 }
1188
1189 /**
1190 * @since 3.04.03
1191 * @deprecated 3.06
1192 * @codeCoverageIgnore
1193 */
1194 public static function get_pro_updater() {
1195 return FrmDeprecated::get_pro_updater();
1196 }
1197
1198 /**
1199 * @since 3.04.03
1200 * @deprecated 3.06
1201 * @codeCoverageIgnore
1202 *
1203 * @return array
1204 */
1205 public static function get_addon_info( $license = '' ) {
1206 return FrmDeprecated::get_addon_info( $license );
1207 }
1208
1209 /**
1210 * @since 3.04.03
1211 * @deprecated 3.06
1212 * @codeCoverageIgnore
1213 *
1214 * @return string
1215 */
1216 public static function get_cache_key( $license ) {
1217 return FrmDeprecated::get_cache_key( $license );
1218 }
1219
1220 /**
1221 * @since 3.04.03
1222 * @deprecated 3.06
1223 * @codeCoverageIgnore
1224 */
1225 public static function reset_cached_addons( $license = '' ) {
1226 FrmDeprecated::reset_cached_addons( $license );
1227 }
1228
1229 /**
1230 * @since 2.03.08
1231 * @deprecated 3.04.03
1232 * @codeCoverageIgnore
1233 *
1234 * @param boolean $return
1235 * @param string $package
1236 *
1237 * @return boolean
1238 */
1239 public static function add_shorten_edd_filename_filter( $return, $package ) {
1240 return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
1241 }
1242
1243 /**
1244 * @since 2.03.08
1245 * @deprecated 3.04.03
1246 * @codeCoverageIgnore
1247 *
1248 * @param string $filename
1249 * @param string $ext
1250 *
1251 * @return string
1252 */
1253 public static function shorten_edd_filename( $filename, $ext ) {
1254 return FrmDeprecated::shorten_edd_filename( $filename, $ext );
1255 }
1256
1257 /**
1258 * @deprecated 3.04.03
1259 * @codeCoverageIgnore
1260 */
1261 public static function get_licenses() {
1262 FrmDeprecated::get_licenses();
1263 }
1264 }
1265