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

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