PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.7
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.7
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 / FrmAppController.php

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

1,217 lines 33.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 FrmAppController {
7
8 /**
9 * @return void
10 */
11 public static function menu() {
12 FrmAppHelper::maybe_add_permissions();
13 if ( ! current_user_can( 'frm_view_forms' ) ) {
14 return;
15 }
16
17 $menu_name = FrmAppHelper::get_menu_name();
18 add_menu_page( 'Formidable', $menu_name, 'frm_view_forms', 'formidable', 'FrmFormsController::route', self::menu_icon(), self::get_menu_position() );
19 }
20
21 /**
22 * @return int
23 */
24 private static function get_menu_position() {
25 return (int) apply_filters( 'frm_menu_position', 29 );
26 }
27
28 /**
29 * @since 3.05
30 */
31 private static function menu_icon() {
32 $icon = FrmAppHelper::svg_logo(
33 array(
34 'fill' => '#a0a5aa',
35 'orange' => '#a0a5aa',
36 )
37 );
38 $icon = 'data:image/svg+xml;base64,' . base64_encode( $icon );
39
40 return apply_filters( 'frm_icon', $icon );
41 }
42
43 /**
44 * @since 3.0
45 */
46 public static function add_admin_class( $classes ) {
47 if ( self::is_white_page() ) {
48 $classes .= ' frm-white-body ';
49 $classes .= self::get_os();
50
51 $page = str_replace( 'formidable-', '', FrmAppHelper::simple_get( 'page', 'sanitize_title' ) );
52 if ( empty( $page ) || $page === 'formidable' ) {
53 $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
54 if ( in_array( $action, array( 'settings', 'edit', 'list' ) ) ) {
55 $page .= $action;
56 } else {
57 $page = $action;
58 }
59 }
60 if ( ! empty( $page ) ) {
61 $classes .= ' frm-admin-page-' . $page;
62 }
63 }
64
65 if ( FrmAppHelper::is_full_screen() ) {
66 $full_screen_on = self::get_full_screen_setting();
67 $add_class = '';
68 if ( $full_screen_on ) {
69 $add_class = ' frm-full-screen is-fullscreen-mode';
70 wp_enqueue_style( 'wp-edit-post' ); // Load the CSS for .is-fullscreen-mode.
71 }
72 $classes .= apply_filters( 'frm_admin_full_screen_class', $add_class );
73 }
74
75 if ( ! FrmAppHelper::pro_is_installed() ) {
76 $classes .= ' frm-lite ';
77 }
78
79 if ( get_user_setting( 'unfold' ) && 'f' !== get_user_setting( 'mfold' ) ) {
80 $classes .= ' frm-unfold ';
81 }
82
83 return $classes;
84 }
85
86 /**
87 * Get the full screen mode setting from the block editor.
88 *
89 * @since 6.1
90 *
91 * @return bool
92 */
93 private static function get_full_screen_setting() {
94 global $wpdb;
95 $meta_key = $wpdb->get_blog_prefix() . 'persisted_preferences';
96
97 $prefs = get_user_meta( get_current_user_id(), $meta_key, true );
98 if ( $prefs && isset( $prefs['core/edit-post']['fullscreenMode'] ) ) {
99 return $prefs['core/edit-post']['fullscreenMode'];
100 }
101
102 return true;
103 }
104
105 /**
106 * @since 4.0
107 *
108 * @return string
109 */
110 private static function get_os() {
111 $agent = strtolower( FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ) );
112 $os = '';
113 if ( strpos( $agent, 'mac' ) !== false ) {
114 $os = ' osx';
115 } elseif ( strpos( $agent, 'linux' ) !== false ) {
116 $os = ' linux';
117 } elseif ( strpos( $agent, 'windows' ) !== false ) {
118 $os = ' windows';
119 }
120 return $os;
121 }
122
123 /**
124 * @since 3.0
125 */
126 private static function is_white_page() {
127 $white_pages = array(
128 'formidable',
129 'formidable-entries',
130 'formidable-views',
131 'formidable-views-editor',
132 'formidable-pro-upgrade',
133 'formidable-addons',
134 'formidable-import',
135 'formidable-settings',
136 'formidable-styles',
137 'formidable-styles2',
138 'formidable-inbox',
139 'formidable-welcome',
140 'formidable-applications',
141 FrmFormTemplatesController::PAGE_SLUG,
142 );
143
144 if ( ! class_exists( 'FrmTransHooksController', false ) && ! FrmTransLiteAppHelper::should_fallback_to_paypal() ) {
145 // Only consider the payments page as a "white page" when the Payments submodule is off.
146 // Otherwise this causes a lot of styling issues when the Stripe add-on (or Authorize.Net) is active.
147
148 // Add an extra check to avoid white page styling on the PayPal "edit" action.
149 // We fallback to the PayPal add on for the "edit" action since Stripe Lite does not have an edit view.
150 if ( ! in_array( FrmAppHelper::simple_get( 'action' ), array( 'edit', 'new' ), true ) || ! is_callable( 'FrmPaymentsController::route' ) ) {
151 $white_pages[] = 'formidable-payments';
152 }
153 }
154
155 $get_page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
156 $is_white_page = in_array( $get_page, $white_pages, true );
157
158 if ( ! $is_white_page ) {
159 $screen = get_current_screen();
160 $is_white_page = ( $screen && strpos( $screen->id, 'frm_display' ) !== false );
161 }
162
163 /**
164 * Allow another add on to style a page as a Formidable "white page", which adds a white background color.
165 *
166 * @since 5.3
167 *
168 * @param bool $is_white_page
169 */
170 $is_white_page = apply_filters( 'frm_is_white_page', $is_white_page );
171
172 return $is_white_page;
173 }
174
175 /**
176 * @return void
177 */
178 public static function load_wp_admin_style() {
179 FrmAppHelper::load_font_style();
180 }
181
182 /**
183 * @param bool $show_nav
184 * @param string $title
185 *
186 * @psalm-param 'hide'|'show' $title
187 *
188 * @return void
189 */
190 public static function get_form_nav( $form, $show_nav = false, $title = 'show' ) {
191 $show_nav = FrmAppHelper::get_param( 'show_nav', $show_nav, 'get', 'absint' );
192 if ( empty( $show_nav ) || ! $form ) {
193 return;
194 }
195
196 FrmForm::maybe_get_form( $form );
197 if ( ! is_object( $form ) ) {
198 return;
199 }
200
201 $id = $form->id;
202 $current_page = self::get_current_page();
203 $nav_items = self::get_form_nav_items( $form );
204
205 include( FrmAppHelper::plugin_path() . '/classes/views/shared/form-nav.php' );
206 }
207
208 /**
209 * @return string
210 */
211 private static function get_current_page() {
212 $page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
213 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title', 'None' );
214 $current_page = isset( $_GET['page'] ) ? $page : $post_type;
215
216 if ( FrmAppHelper::is_view_builder_page() ) {
217 $current_page = 'frm_display';
218 }
219
220 return $current_page;
221 }
222
223 /**
224 * @param object $form
225 * @return array
226 */
227 private static function get_form_nav_items( $form ) {
228 $id = $form->parent_form_id ? $form->parent_form_id : $form->id;
229
230 $nav_items = array(
231 array(
232 'link' => FrmForm::get_edit_link( $id ),
233 'label' => __( 'Build', 'formidable' ),
234 'current' => array( 'edit', 'new', 'duplicate' ),
235 'page' => 'formidable',
236 'permission' => 'frm_edit_forms',
237 ),
238 array(
239 'link' => FrmStylesHelper::get_list_url( $id ),
240 'label' => __( 'Style', 'formidable' ),
241 'current' => array(),
242 'page' => 'formidable-styles',
243 'permission' => 'frm_edit_forms',
244 ),
245 array(
246 'link' => admin_url( 'admin.php?page=formidable&frm_action=settings&id=' . absint( $id ) ),
247 'label' => __( 'Settings', 'formidable' ),
248 'current' => array( 'settings' ),
249 'page' => 'formidable',
250 'permission' => 'frm_edit_forms',
251 ),
252 array(
253 'link' => admin_url( 'admin.php?page=formidable-entries&frm_action=list&form=' . absint( $id ) ),
254 'label' => __( 'Entries', 'formidable' ),
255 'current' => array(),
256 'page' => 'formidable-entries',
257 'permission' => 'frm_view_entries',
258 ),
259 );
260
261 $views_installed = is_callable( 'FrmProAppHelper::views_is_installed' ) ? FrmProAppHelper::views_is_installed() : FrmAppHelper::pro_is_installed();
262
263 if ( ! $views_installed ) {
264 $nav_items[] = array(
265 'link' => admin_url( 'admin.php?page=formidable-views&form=' . absint( $id ) ),
266 'label' => __( 'Views', 'formidable' ),
267 'current' => array(),
268 'page' => 'formidable-views',
269 'permission' => 'frm_view_entries',
270 'atts' => array(
271 'class' => 'frm_noallow',
272 ),
273 );
274 }
275
276 // Let people know reports and views exist.
277 if ( ! FrmAppHelper::pro_is_installed() ) {
278 $nav_items[] = array(
279 'link' => admin_url( 'admin.php?page=formidable&frm_action=lite-reports&form=' . absint( $id ) ),
280 'label' => __( 'Reports', 'formidable' ),
281 'current' => array( 'reports' ),
282 'page' => 'formidable',
283 'permission' => 'frm_view_entries',
284 'atts' => array(
285 'class' => 'frm_noallow',
286 ),
287 );
288 }
289
290 $nav_args = array(
291 'form_id' => $id,
292 'form' => $form,
293 );
294
295 return (array) apply_filters( 'frm_form_nav_list', $nav_items, $nav_args );
296 }
297
298 // Adds a settings link to the plugins page
299 /**
300 * @return array
301 */
302 public static function settings_link( $links ) {
303 $settings = array();
304
305 if ( ! FrmAppHelper::pro_is_installed() ) {
306 $label = FrmAddonsController::is_license_expired() ? __( 'Renew', 'formidable' ) : __( 'Upgrade to Pro', 'formidable' );
307 $settings[] = '<a href="' . esc_url( FrmAppHelper::admin_upgrade_link( 'plugin-row' ) ) . '" target="_blank" rel="noopener"><b style="color:#1da867;font-weight:700;">' . esc_html( $label ) . '</b></a>';
308 }
309
310 $settings[] = '<a href="' . esc_url( admin_url( 'admin.php?page=formidable' ) ) . '">' . __( 'Build a Form', 'formidable' ) . '</a>';
311
312 return array_merge( $settings, $links );
313 }
314
315 /**
316 * @return void
317 */
318 public static function pro_get_started_headline() {
319 self::review_request();
320 FrmAppHelper::min_pro_version_notice( '4.0' );
321 }
322
323 /**
324 * Add admin notices as needed for reviews
325 *
326 * @since 3.04.03
327 *
328 * @return void
329 */
330 private static function review_request() {
331 $reviews = new FrmReviews();
332 $reviews->review_request();
333 }
334
335 /**
336 * Save the request to hide the review
337 *
338 * @since 3.04.03
339 *
340 * @return void
341 */
342 public static function dismiss_review() {
343 FrmAppHelper::permission_check( 'frm_change_settings' );
344 check_ajax_referer( 'frm_ajax', 'nonce' );
345
346 $reviews = new FrmReviews();
347 $reviews->dismiss_review();
348 }
349
350 /**
351 * @since 3.04.02
352 *
353 * @return void
354 */
355 public static function include_upgrade_overlay() {
356 self::enqueue_dialog_assets();
357 add_action( 'admin_footer', 'FrmAppController::upgrade_overlay_html' );
358 }
359
360 /**
361 * Enqueue scripts and styles required for modals.
362 *
363 * @since 5.3
364 *
365 * @return void
366 */
367 public static function enqueue_dialog_assets() {
368 wp_enqueue_script( 'jquery-ui-dialog' );
369 wp_enqueue_style( 'jquery-ui-dialog' );
370 }
371
372 /**
373 * @since 3.06.03
374 *
375 * @return void
376 */
377 public static function upgrade_overlay_html() {
378 $is_pro = FrmAppHelper::pro_is_installed();
379 $upgrade_link = array(
380 'medium' => 'builder',
381 'content' => 'upgrade',
382 );
383 $default_link = FrmAppHelper::admin_upgrade_link( $upgrade_link );
384 $plugin_path = FrmAppHelper::plugin_path();
385 $shared_path = $plugin_path . '/classes/views/shared/';
386
387 include $shared_path . 'upgrade_overlay.php';
388 include $shared_path . 'confirm-overlay.php';
389 }
390
391 /**
392 * Create a basic form with an email field.
393 *
394 * @param string $form_key
395 * @param string $title
396 * @param string $description
397 * @return void
398 */
399 public static function api_email_form( $form_key, $title, $description ) {
400 $user = wp_get_current_user();
401 $args = array(
402 'api_url' => 'https://sandbox.formidableforms.com/api/wp-json/frm/v2/forms/' . $form_key . '?return=html&exclude_script=jquery&exclude_style=formidable-css',
403 'title' => $title,
404 'description' => $description,
405 );
406 require FrmAppHelper::plugin_path() . '/classes/views/form-templates/modals/leave-email-modal.php';
407 }
408
409 /**
410 * @return void
411 */
412 public static function include_info_overlay() {
413 self::enqueue_dialog_assets();
414 add_action( 'admin_footer', 'FrmAppController::info_overlay_html' );
415 }
416
417 /**
418 * @return void
419 */
420 public static function info_overlay_html() {
421 include FrmAppHelper::plugin_path() . '/classes/views/shared/info-overlay.php';
422 }
423
424 /**
425 * @since 3.04.02
426 *
427 * @return void
428 */
429 public static function remove_upsells() {
430 remove_action( 'frm_before_settings', 'FrmSettingsController::license_box' );
431 remove_action( 'frm_after_settings', 'FrmSettingsController::settings_cta' );
432 remove_action( 'frm_add_form_style_tab_options', 'FrmFormsController::add_form_style_tab_options' );
433 remove_action( 'frm_after_field_options', 'FrmFormsController::logic_tip' );
434 }
435
436 /**
437 * If there are CURL problems on this server, wp_remote_post won't work for installing
438 * Use a javascript fallback instead.
439 *
440 * @since 2.0.3
441 *
442 * @return void
443 */
444 public static function install_js_fallback() {
445 FrmAppHelper::load_admin_wide_js();
446 ?>
447 <div id="frm_install_message"></div>
448 <script>jQuery(document).ready( frm_install_now );</script>
449 <?php
450 }
451
452 /**
453 * Check if the database is outdated
454 *
455 * @since 2.0.1
456 * @return boolean
457 */
458 public static function needs_update() {
459 $needs_upgrade = self::compare_for_update(
460 array(
461 'option' => 'frm_db_version',
462 'new_db_version' => FrmAppHelper::$db_version,
463 'new_plugin_version' => FrmAppHelper::plugin_version(),
464 )
465 );
466
467 if ( ! $needs_upgrade ) {
468 $needs_upgrade = apply_filters( 'frm_db_needs_upgrade', $needs_upgrade );
469 }
470
471 return $needs_upgrade;
472 }
473
474 /**
475 * Check both version number and DB number for changes
476 *
477 * @since 3.0.04
478 *
479 * @param array $atts
480 * @return bool
481 */
482 public static function compare_for_update( $atts ) {
483 $db_version = get_option( $atts['option'] );
484
485 if ( strpos( $db_version, '-' ) === false ) {
486 $needs_upgrade = true;
487 } else {
488 $last_upgrade = explode( '-', $db_version );
489 $needs_db_upgrade = (int) $last_upgrade[1] < (int) $atts['new_db_version'];
490 $new_version = version_compare( $last_upgrade[0], $atts['new_plugin_version'], '<' );
491 $needs_upgrade = $needs_db_upgrade || $new_version;
492 }
493
494 return $needs_upgrade;
495 }
496
497 /**
498 * Check for database update and trigger js loading
499 *
500 * @since 2.0.1
501 *
502 * @return void
503 */
504 public static function admin_init() {
505 if ( FrmAppHelper::is_admin_page( 'formidable' ) && 'duplicate' === FrmAppHelper::get_param( 'frm_action' ) ) {
506 FrmFormsController::duplicate();
507 }
508
509 if ( FrmAppHelper::is_style_editor_page() && 'save' === FrmAppHelper::get_param( 'frm_action' ) ) {
510 // Hook in earlier than FrmStylesController::route so we can redirect before the headers have been sent.
511 FrmStylesController::save_style();
512 }
513
514 new FrmPersonalData(); // register personal data hooks
515
516 if ( ! FrmAppHelper::doing_ajax() && self::needs_update() ) {
517 self::network_upgrade_site();
518 }
519
520 if ( ! FrmAppHelper::doing_ajax() ) {
521 // don't continue during ajax calls
522 self::admin_js();
523 }
524
525 if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
526 // Redirect to the "Form Templates" page if the 'frm_action' parameter matches specific actions.
527 // This provides backward compatibility for old addons that use legacy modal templates.
528 $action = FrmAppHelper::get_param( 'frm_action' );
529 $trigger_name_modal = FrmAppHelper::get_param( 'triggerNewFormModal' );
530 if ( $trigger_name_modal || in_array( $action, array( 'add_new', 'list_templates' ), true ) ) {
531 $application_id = FrmAppHelper::simple_get( 'applicationId', 'absint' );
532 $url_param = $application_id ? '&applicationId=' . $application_id : '';
533
534 wp_safe_redirect( admin_url( 'admin.php?page=' . FrmFormTemplatesController::PAGE_SLUG . $url_param ) );
535 exit;
536 }
537
538 FrmInbox::maybe_disable_screen_options();
539 }
540
541 self::maybe_add_ip_warning();
542 }
543
544 /**
545 * Show a warning for the IP address setting if it hasn't been set.
546 *
547 * @since 6.1
548 *
549 * @return void
550 */
551 private static function maybe_add_ip_warning() {
552 $settings = FrmAppHelper::get_settings();
553 if ( false !== $settings->custom_header_ip ) {
554 // The setting has been changed from the false default (to either 1 or 0), so stop showing the message.
555 return;
556 }
557
558 if ( ! self::is_behind_proxy() ) {
559 // This message is only applicable when using a reverse proxy.
560 return;
561 }
562
563 if ( FrmAppHelper::get_post_param( 'frm_action', '', 'sanitize_text_field' ) ) {
564 // Avoid the message on a POST action. We don't want to show the message if we're saving global settings.
565 return;
566 }
567
568 $global_settings_link = admin_url( 'admin.php?page=formidable-settings' ) . '#frm_custom_header_ip';
569 $message = sprintf(
570 // Translators: 1: Global Settings Link
571 __( 'IP addresses in form submissions may no longer be accurate! If you are experiencing issues, we recommend going to %1$s and enabling the "Use custom headers when retrieving IPs with form submissions." setting.', 'formidable' ),
572 '<a href="' . esc_url( $global_settings_link ) . '">Global Settings</a>'
573 );
574 $option_name = 'frm_dismiss_ip_address_notice';
575 FrmAppHelper::add_dismissable_warning_message( $message, $option_name );
576 }
577
578 /**
579 * Check if any reverse proxy headers are set.
580 *
581 * @since 6.1
582 *
583 * @return bool
584 */
585 private static function is_behind_proxy() {
586 $custom_headers = FrmAppHelper::get_custom_header_keys_for_ip();
587 foreach ( $custom_headers as $header ) {
588 if ( 'REMOTE_ADDR' === $header ) {
589 // We want to check every key but REMOTE_ADDR. REMOTE_ATTR is not unique to reverse proxy servers.
590 continue;
591 }
592
593 $ip = trim( FrmAppHelper::get_server_value( $header ) );
594 // Return true for anything that isn't empty but ignoring values like ::1.
595 if ( $ip && 0 !== strpos( $ip, '::' ) ) {
596 return true;
597 }
598 }
599
600 return false;
601 }
602
603 /**
604 * @return void
605 */
606 public static function admin_js() {
607 $plugin_url = FrmAppHelper::plugin_url();
608 $version = FrmAppHelper::plugin_version();
609
610 FrmAppHelper::load_admin_wide_js();
611
612 if ( class_exists( 'FrmOverlayController' ) ) {
613 // This should always exist.
614 // But it may not have loaded properly when updating the plugin.
615 FrmOverlayController::register_assets();
616 }
617
618 wp_register_style( 'formidable_admin_global', $plugin_url . '/css/admin/frm_admin_global.css', array(), $version );
619 wp_enqueue_style( 'formidable_admin_global' );
620
621 wp_register_style( 'formidable-admin', $plugin_url . '/css/frm_admin.css', array(), $version );
622 wp_register_style( 'formidable-grids', $plugin_url . '/css/frm_grids.css', array(), $version );
623
624 wp_register_script( 'formidable_dom', $plugin_url . '/js/admin/dom.js', array( 'jquery', 'jquery-ui-dialog', 'wp-i18n' ), $version, true );
625 wp_register_script( 'formidable_embed', $plugin_url . '/js/admin/embed.js', array( 'formidable_dom', 'jquery-ui-autocomplete' ), $version, true );
626 self::register_popper1();
627 wp_register_script( 'bootstrap_tooltip', $plugin_url . '/js/bootstrap.min.js', array( 'jquery', 'popper' ), '4.6.1', true );
628 wp_register_script( 'formidable_settings', $plugin_url . '/js/admin/settings.js', array(), $version, true );
629
630 $page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
631
632 // Enqueue Floating Links.
633 $is_valid_page =
634 FrmAppHelper::is_formidable_admin() &&
635 ! FrmAppHelper::is_style_editor_page() &&
636 ! FrmAppHelper::is_admin_page( 'formidable-views-editor' ) &&
637 ! FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
638 if ( $is_valid_page && FrmAppHelper::is_formidable_branding() ) {
639 self::enqueue_floating_links( $plugin_url, $version );
640 }
641 unset( $is_valid_page );
642
643 if ( 'formidable-applications' === $page ) {
644 FrmApplicationsController::load_assets();
645 return;
646 }
647
648 $dependencies = array(
649 'formidable_admin_global',
650 'jquery',
651 'jquery-ui-core',
652 'jquery-ui-draggable',
653 'jquery-ui-sortable',
654 'bootstrap_tooltip',
655 'bootstrap-multiselect',
656 'wp-i18n',
657 'wp-hooks', // Required in WP versions older than 5.7
658 'formidable_dom',
659 'formidable_embed',
660 );
661
662 if ( FrmAppHelper::is_style_editor_page( 'edit' ) ) {
663 // We only need to load the color picker when editing styles.
664 $dependencies[] = 'wp-color-picker';
665 }
666
667 wp_register_script( 'formidable_admin', $plugin_url . '/js/formidable_admin.js', $dependencies, $version, true );
668
669 if ( FrmAppHelper::on_form_listing_page() ) {
670 // For the existing page dropdown in the Form embed modal.
671 wp_enqueue_script( 'jquery-ui-autocomplete' );
672 }
673
674 wp_register_script( 'bootstrap-multiselect', $plugin_url . '/js/bootstrap-multiselect.js', array( 'jquery', 'bootstrap_tooltip', 'popper' ), '1.1.1', true );
675
676 if ( ! class_exists( 'FrmTransHooksController', false ) ) {
677 /**
678 * Gateway fields are included for add-on compatibility but we do not want it to be visible.
679 * They do however need to be visible when the payments submodule is active.
680 */
681 wp_add_inline_style(
682 'formidable-admin',
683 '#frm_builder_page li[data-ftype="gateway"] { display: none; }'
684 );
685 }
686
687 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title' );
688
689 global $pagenow;
690 if ( strpos( $page, 'formidable' ) === 0 || ( $pagenow === 'edit.php' && $post_type === 'frm_display' ) ) {
691
692 wp_enqueue_script( 'admin-widgets' );
693 wp_enqueue_style( 'widgets' );
694 self::maybe_deregister_popper2();
695 wp_enqueue_script( 'formidable_admin' );
696 wp_enqueue_script( 'formidable_embed' );
697 FrmAppHelper::localize_script( 'admin' );
698
699 wp_enqueue_style( 'formidable-admin' );
700 if ( 'formidable-styles' !== $page && 'formidable-styles2' !== $page ) {
701 wp_enqueue_style( 'formidable-grids' );
702 wp_enqueue_style( 'formidable-dropzone' );
703 } else {
704 wp_enqueue_style( 'formidable-grids' );
705 }
706
707 if ( 'formidable-entries' === $page ) {
708 // Load front end js for entries.
709 wp_enqueue_script( 'formidable' );
710
711 // Registers and enqueues the entries page scripts.
712 wp_register_script( 'formidable_entries', $plugin_url . '/js/admin/entries.js', array( 'formidable_admin', 'wp-dom-ready' ), $version, true );
713 wp_enqueue_script( 'formidable_entries' );
714 }
715
716 do_action( 'frm_enqueue_builder_scripts' );
717 self::include_upgrade_overlay();
718 self::include_info_overlay();
719 } elseif ( FrmAppHelper::is_view_builder_page() ) {
720 if ( isset( $_REQUEST['post_type'] ) ) {
721 $post_type = sanitize_title( wp_unslash( $_REQUEST['post_type'] ) );
722 } elseif ( isset( $_REQUEST['post'] ) && absint( $_REQUEST['post'] ) ) {
723 $post = get_post( absint( wp_unslash( $_REQUEST['post'] ) ) );
724 if ( ! $post ) {
725 return;
726 }
727 $post_type = $post->post_type;
728 } else {
729 return;
730 }
731
732 if ( $post_type === 'frm_display' ) {
733 self::enqueue_legacy_views_assets();
734 }
735 }
736
737 }
738
739 /**
740 * @since 6.3.2
741 *
742 * @return void
743 */
744 public static function admin_enqueue_scripts() {
745 self::load_wp_admin_style();
746 self::maybe_force_formidable_block_on_gutenberg_page();
747 }
748
749 /**
750 * Enqueue required assets for the Legacy Views editor (Views v4.x).
751 *
752 * @since 6.1.2
753 *
754 * @return void
755 */
756 private static function enqueue_legacy_views_assets() {
757 wp_enqueue_style( 'formidable-grids' );
758 wp_enqueue_script( 'jquery-ui-draggable' );
759 self::maybe_deregister_popper2();
760 wp_enqueue_script( 'formidable_admin' );
761 wp_add_inline_style(
762 'formidable-admin',
763 '
764 .frm-white-body.post-type-frm_display .columns-2 {
765 display: block;
766 overflow: visible;
767 }
768
769 .frm-white-body.post-type-frm_display .columns-2 > div {
770 overflow-y: hidden;
771 }
772
773 .frm-white-body.post-type-frm_display #titlediv #title-prompt-text {
774 padding: 3px 0 0 10px;
775 }
776
777 .post-type-frm_display #field-search-input,
778 .post-type-frm_display #advanced-search-input {
779 flex: 1;
780 }
781 '
782 );
783 wp_enqueue_style( 'formidable-admin' );
784 FrmAppHelper::localize_script( 'admin' );
785 self::include_info_overlay();
786 }
787
788 /**
789 * Fix a Duplicator Pro conflict because it uses Popper 2. See issue #3459.
790 *
791 * @since 5.2.02.01
792 *
793 * @return void
794 */
795 private static function maybe_deregister_popper2() {
796 global $wp_scripts;
797
798 if ( ! array_key_exists( 'popper', $wp_scripts->registered ) ) {
799 return;
800 }
801
802 $popper = $wp_scripts->registered['popper'];
803 if ( version_compare( $popper->ver, '2.0', '>=' ) ) {
804 wp_deregister_script( 'popper' );
805 self::register_popper1();
806 }
807 }
808
809 /**
810 * Register Popper required for Bootstrap 4.
811 *
812 * @since 5.2.02.01
813 *
814 * @return void
815 */
816 private static function register_popper1() {
817 wp_register_script( 'popper', FrmAppHelper::plugin_url() . '/js/popper.min.js', array( 'jquery' ), '1.16.0', true );
818 }
819
820 /**
821 * Automatically insert a Formidable block when loading Gutenberg when $_GET['frmForm' is set.
822 *
823 * @since 5.2
824 *
825 * @return void
826 */
827 private static function maybe_force_formidable_block_on_gutenberg_page() {
828 global $pagenow;
829 if ( 'post.php' !== $pagenow ) {
830 return;
831 }
832
833 $form_id = FrmAppHelper::simple_get( 'frmForm', 'absint' );
834 if ( ! $form_id ) {
835 return;
836 }
837
838 self::add_js_to_inject_gutenberg_block( 'formidable/simple-form', 'formId', $form_id );
839 }
840
841 /**
842 * @since 5.3
843 *
844 * @param string $block_name
845 * @param string $object_key
846 * @param array|string $object_id
847 *
848 * @return void
849 */
850 public static function add_js_to_inject_gutenberg_block( $block_name, $object_key, $object_id ) {
851 require FrmAppHelper::plugin_path() . '/classes/views/shared/edit-page-js.php';
852 }
853
854 /**
855 * @return void
856 */
857 public static function load_lang() {
858 load_plugin_textdomain( 'formidable', false, FrmAppHelper::plugin_folder() . '/languages/' );
859 }
860
861 /**
862 * Check if the styles are updated when a form is loaded on the front-end
863 *
864 * @since 3.0.1
865 *
866 * @return void
867 */
868 public static function maybe_update_styles() {
869 if ( self::needs_update() ) {
870 self::network_upgrade_site();
871 }
872 }
873
874 /**
875 * @since 3.0
876 *
877 * @return void
878 */
879 public static function create_rest_routes() {
880 $args = array(
881 'methods' => 'GET',
882 'callback' => 'FrmAppController::api_install',
883 'permission_callback' => __CLASS__ . '::can_update_db',
884 );
885
886 register_rest_route( 'frm-admin/v1', '/install', $args );
887
888 $args = array(
889 'methods' => 'GET',
890 'callback' => 'FrmAddonsController::install_addon_api',
891 'permission_callback' => 'FrmAddonsController::can_install_addon_api',
892 );
893
894 register_rest_route( 'frm-admin/v1', '/install-addon', $args );
895 }
896
897 /**
898 * Make sure the install is only being run when we tell it to.
899 * We don't want to run manually by people calling the API.
900 *
901 * @since 4.06.02
902 */
903 public static function can_update_db() {
904 return get_transient( 'frm_updating_api' );
905 }
906
907 /**
908 * Run silent upgrade on each site in the network during a network upgrade.
909 * Update database settings for all sites in a network during network upgrade process.
910 *
911 * @since 2.0.1
912 *
913 * @param int $blog_id Blog ID.
914 *
915 * @return void
916 */
917 public static function network_upgrade_site( $blog_id = 0 ) {
918 // Flag to check if install is happening as intended.
919 set_transient( 'frm_updating_api', true, MINUTE_IN_SECONDS );
920 $request = new WP_REST_Request( 'GET', '/frm-admin/v1/install' );
921
922 self::maybe_add_wp_site_health();
923
924 if ( $blog_id ) {
925 switch_to_blog( $blog_id );
926 $response = rest_do_request( $request );
927 restore_current_blog();
928 } else {
929 $response = rest_do_request( $request );
930 }
931
932 if ( $response->is_error() ) {
933 // if the remove post fails, use javascript instead
934 add_action( 'admin_notices', 'FrmAppController::install_js_fallback' );
935 }
936 }
937
938 /**
939 * Make sure WP_Site_Health has been included because it is required when calling rest_do_request.
940 * Check first that the file exists because WP_Site_Health was only introduced in WordPress 5.2.
941 *
942 * @return void
943 */
944 private static function maybe_add_wp_site_health() {
945 if ( ! class_exists( 'WP_Site_Health' ) ) {
946 $wp_site_health_path = ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
947 if ( file_exists( $wp_site_health_path ) ) {
948 require_once $wp_site_health_path;
949 }
950 }
951 }
952
953 /**
954 * @since 3.0
955 *
956 * @return true
957 */
958 public static function api_install() {
959 delete_transient( 'frm_updating_api' );
960 if ( self::needs_update() ) {
961 $running = get_option( 'frm_install_running' );
962 if ( false === $running || $running < strtotime( '-5 minutes' ) ) {
963 update_option( 'frm_install_running', time(), 'no' );
964 self::install();
965 delete_option( 'frm_install_running' );
966 }
967 }
968
969 return true;
970 }
971
972 /**
973 * Silent database upgrade (no redirect).
974 * Called via ajax request during network upgrade process.
975 *
976 * @since 2.0.1
977 *
978 * @return void
979 */
980 public static function ajax_install() {
981 FrmAppHelper::permission_check( 'frm_change_settings' );
982 check_ajax_referer( 'frm_ajax', 'nonce' );
983 self::api_install();
984 wp_die();
985 }
986
987 /**
988 * @return void
989 */
990 public static function install() {
991 $frmdb = new FrmMigrate();
992 $frmdb->upgrade();
993 }
994
995 /**
996 * @return void
997 */
998 public static function uninstall() {
999 FrmAppHelper::permission_check( 'administrator' );
1000 check_ajax_referer( 'frm_ajax', 'nonce' );
1001
1002 $frmdb = new FrmMigrate();
1003 $frmdb->uninstall();
1004
1005 //disable the plugin and redirect after uninstall so the tables don't get added right back
1006 $plugins = array( FrmAppHelper::plugin_folder() . '/formidable.php', 'formidable-pro/formidable-pro.php' );
1007 deactivate_plugins( $plugins, false, false );
1008 echo esc_url_raw( admin_url( 'plugins.php?deactivate=true' ) );
1009
1010 wp_die();
1011 }
1012
1013 public static function drop_tables( $tables ) {
1014 global $wpdb;
1015 $tables[] = $wpdb->prefix . 'frm_fields';
1016 $tables[] = $wpdb->prefix . 'frm_forms';
1017 $tables[] = $wpdb->prefix . 'frm_items';
1018 $tables[] = $wpdb->prefix . 'frm_item_metas';
1019
1020 return $tables;
1021 }
1022
1023 /**
1024 * @return void
1025 */
1026 public static function deauthorize() {
1027 FrmAppHelper::permission_check( 'frm_change_settings' );
1028 check_ajax_referer( 'frm_ajax', 'nonce' );
1029
1030 delete_option( 'frmpro-credentials' );
1031 delete_option( 'frmpro-authorized' );
1032 delete_site_option( 'frmpro-credentials' );
1033 delete_site_option( 'frmpro-authorized' );
1034 wp_die();
1035 }
1036
1037 /**
1038 * This is triggered when Formidable is activated.
1039 *
1040 * @return void
1041 */
1042 public static function handle_activation() {
1043 self::maybe_activate_payment_cron();
1044 }
1045
1046 /**
1047 * The payment cron is unscheduled when Formidable is deactivated.
1048 * We need to add it back again on activation if Stripe is configured.
1049 *
1050 * @since 6.5
1051 *
1052 * @return void
1053 */
1054 private static function maybe_activate_payment_cron() {
1055 if ( ! FrmStrpLiteConnectHelper::stripe_connect_is_setup() ) {
1056 return;
1057 }
1058
1059 FrmTransLiteAppController::maybe_schedule_cron();
1060 }
1061
1062 public static function set_footer_text( $text ) {
1063 if ( FrmAppHelper::is_formidable_admin() ) {
1064 $text = '';
1065 }
1066
1067 return $text;
1068 }
1069
1070 /**
1071 * Add admin footer links.
1072 *
1073 * @since 6.4.1
1074 *
1075 * @return void
1076 */
1077 public static function add_admin_footer_links() {
1078 if ( self::should_show_footer_links() ) {
1079 include FrmAppHelper::plugin_path() . '/classes/views/shared/admin-footer-links.php';
1080 }
1081 }
1082
1083 /**
1084 * Check if the footer links should be shown.
1085 *
1086 * @since 6.7
1087 *
1088 * @return bool
1089 */
1090 private static function should_show_footer_links() {
1091 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title' );
1092 $is_formidable_page = FrmAppHelper::is_formidable_admin() || 'frm_logs' === $post_type;
1093 $show_footer_links = $is_formidable_page;
1094 if ( FrmAppHelper::is_full_screen() || ! FrmAppHelper::is_formidable_branding() ) {
1095 $show_footer_links = false;
1096 }
1097
1098 /**
1099 * Filter whether to show the Formidable footer links.
1100 *
1101 * @since 6.7
1102 *
1103 * @param bool $show_footer_links
1104 * @return bool
1105 */
1106 return apply_filters( 'frm_show_footer_links', $show_footer_links );
1107 }
1108
1109 /**
1110 * Show an error modal and terminate the script execution.
1111 *
1112 * @since 6.7
1113 *
1114 * @param array $error_args Arguments that control the behavior of the error modal.
1115 *
1116 * @return void
1117 */
1118 public static function show_error_modal( $error_args ) {
1119 $defaults = array(
1120 'title' => '',
1121 'body' => '',
1122 'cancel_url' => '',
1123 'cancel_classes' => '',
1124 'continue_url' => '',
1125 'continue_classes' => '',
1126 'icon' => 'frm_lock_simple',
1127 );
1128
1129 $error_args = wp_parse_args( $error_args, $defaults );
1130 if ( ! isset( $error_args['cancel_text'] ) && ! empty( $error_args['cancel_url'] ) ) {
1131 $error_args['cancel_text'] = __( 'Cancel', 'formidable' );
1132 }
1133
1134 if ( ! isset( $error_args['continue_text'] ) && ! empty( $error_args['continue_url'] ) ) {
1135 $error_args['continue_text'] = __( 'Continue', 'formidable' );
1136 }
1137
1138 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/error-modal.php';
1139 }
1140
1141 /**
1142 * @deprecated 3.0.04
1143 *
1144 * @codeCoverageIgnore
1145 *
1146 * @return void
1147 */
1148 public static function activation_install() {
1149 FrmDeprecated::activation_install();
1150 }
1151
1152 /**
1153 * @deprecated 3.0
1154 * @codeCoverageIgnore
1155 */
1156 public static function page_route( $content ) {
1157 return FrmDeprecated::page_route( $content );
1158 }
1159
1160 /**
1161 * Include icons on page for Embed Form modal.
1162 *
1163 * @since 5.2
1164 *
1165 * @return void
1166 */
1167 public static function include_embed_form_icons() {
1168 _deprecated_function( __METHOD__, '5.3' );
1169 }
1170
1171 /**
1172 * @deprecated 1.07.05 This is still referenced in the API add on as of v1.13.
1173 * @codeCoverageIgnore
1174 *
1175 * @param array $atts
1176 * @return string
1177 */
1178 public static function get_form_shortcode( $atts ) {
1179 _deprecated_function( __FUNCTION__, '1.07.05', 'FrmFormsController::get_form_shortcode' );
1180 return FrmFormsController::get_form_shortcode( $atts );
1181 }
1182
1183 /**
1184 * Handles Floating Links' scripts and styles enqueueing.
1185 *
1186 * @since 6.4
1187 *
1188 * @param string $plugin_url URL of the plugin.
1189 * @param string $version Current version of the plugin.
1190 * @return void
1191 */
1192 private static function enqueue_floating_links( $plugin_url, $version ) {
1193 if ( ! $plugin_url || ! $version ) {
1194 // If any required parameters are missing, exit early.
1195 return;
1196 }
1197
1198 // Enqueue the Floating Links styles.
1199 wp_enqueue_style( 's11-floating-links', $plugin_url . '/css/packages/s11-floating-links.css', array(), $version );
1200
1201 // Enqueue the Floating Links script.
1202 wp_enqueue_script( 's11-floating-links', $plugin_url . '/js/packages/floating-links/s11-floating-links.js', array(), $version, true );
1203
1204 // Enqueue the config script.
1205 wp_enqueue_script( 's11-floating-links-config', $plugin_url . '/js/packages/floating-links/config.js', array( 'wp-i18n' ), $version, true );
1206
1207 if ( function_exists( 'wp_set_script_translations' ) ) {
1208 wp_set_script_translations( 's11-floating-links-config', 's11-' );
1209 }
1210
1211 $floating_links_data = array(
1212 'proIsInstalled' => FrmAppHelper::pro_is_installed(),
1213 );
1214 wp_localize_script( 's11-floating-links-config', 's11FloatingLinksData', $floating_links_data );
1215 }
1216 }
1217