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

1,165 lines 31.4 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 ) ) {
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 $settings[] = '<a href="' . esc_url( FrmAppHelper::admin_upgrade_link( 'plugin-row' ) ) . '" target="_blank" rel="noopener"><b style="color:#1da867;font-weight:700;">' . esc_html__( 'Upgrade to Pro', 'formidable' ) . '</b></a>';
297 }
298
299 $settings[] = '<a href="' . esc_url( admin_url( 'admin.php?page=formidable' ) ) . '">' . __( 'Build a Form', 'formidable' ) . '</a>';
300
301 return array_merge( $settings, $links );
302 }
303
304 /**
305 * @return void
306 */
307 public static function pro_get_started_headline() {
308 self::review_request();
309 FrmAppHelper::min_pro_version_notice( '4.0' );
310 }
311
312 /**
313 * Add admin notices as needed for reviews
314 *
315 * @since 3.04.03
316 *
317 * @return void
318 */
319 private static function review_request() {
320 $reviews = new FrmReviews();
321 $reviews->review_request();
322 }
323
324 /**
325 * Save the request to hide the review
326 *
327 * @since 3.04.03
328 *
329 * @return void
330 */
331 public static function dismiss_review() {
332 FrmAppHelper::permission_check( 'frm_change_settings' );
333 check_ajax_referer( 'frm_ajax', 'nonce' );
334
335 $reviews = new FrmReviews();
336 $reviews->dismiss_review();
337 }
338
339 /**
340 * @since 3.04.02
341 *
342 * @return void
343 */
344 public static function include_upgrade_overlay() {
345 self::enqueue_dialog_assets();
346 add_action( 'admin_footer', 'FrmAppController::upgrade_overlay_html' );
347 }
348
349 /**
350 * Enqueue scripts and styles required for modals.
351 *
352 * @since 5.3
353 *
354 * @return void
355 */
356 public static function enqueue_dialog_assets() {
357 wp_enqueue_script( 'jquery-ui-dialog' );
358 wp_enqueue_style( 'jquery-ui-dialog' );
359 }
360
361 /**
362 * @since 3.06.03
363 *
364 * @return void
365 */
366 public static function upgrade_overlay_html() {
367 $is_pro = FrmAppHelper::pro_is_installed();
368 $upgrade_link = array(
369 'medium' => 'builder',
370 'content' => 'upgrade',
371 );
372 $default_link = FrmAppHelper::admin_upgrade_link( $upgrade_link );
373 $plugin_path = FrmAppHelper::plugin_path();
374 $shared_path = $plugin_path . '/classes/views/shared/';
375
376 include $shared_path . 'upgrade_overlay.php';
377 include $shared_path . 'confirm-overlay.php';
378
379 if ( FrmAppHelper::is_admin_page( 'formidable-welcome' ) || FrmAppHelper::on_form_listing_page() ) {
380 self::new_form_overlay_html();
381 }
382 }
383
384 /**
385 * @return void
386 */
387 private static function new_form_overlay_html() {
388 FrmFormsController::before_list_templates();
389
390 $plugin_path = FrmAppHelper::plugin_path();
391 $path = $plugin_path . '/classes/views/frm-forms/';
392 $expired = FrmFormsController::expired();
393 $expiring = FrmAddonsController::is_license_expiring();
394 $user = wp_get_current_user(); // $user used in leave-email.php to determine a default value for field
395 $view_path = $path . 'new-form-overlay/';
396 $modal_class = '';
397 $upgrade_link = FrmAppHelper::admin_upgrade_link(
398 array(
399 'medium' => 'new-template',
400 'content' => 'upgrade',
401 )
402 );
403 $renew_link = FrmAppHelper::admin_upgrade_link(
404 array(
405 'medium' => 'new-template',
406 'content' => 'renew',
407 )
408 );
409 $blocks_to_render = array();
410
411 if ( ! FrmAppHelper::pro_is_installed() ) {
412 // avoid rendering the email and code blocks for users who have upgraded or have a free license already
413 $api = new FrmFormTemplateApi();
414 if ( ! $api->has_free_access() ) {
415 array_push( $blocks_to_render, 'email', 'code' );
416 }
417 }
418
419 // avoid rendering the upgrade block for users with elite
420 if ( 'elite' !== FrmAddonsController::license_type() ) {
421 $blocks_to_render[] = 'upgrade';
422 }
423
424 // avoid rendering the renew block for users who are not currently expired
425 if ( $expired ) {
426 $blocks_to_render[] = 'renew';
427 $modal_class = 'frm-expired';
428 } elseif ( $expiring ) {
429 $modal_class = 'frm-expiring';
430 }
431
432 include $path . 'new-form-overlay.php';
433 }
434
435 /**
436 * @return void
437 */
438 public static function include_info_overlay() {
439 self::enqueue_dialog_assets();
440 add_action( 'admin_footer', 'FrmAppController::info_overlay_html' );
441 }
442
443 /**
444 * @return void
445 */
446 public static function info_overlay_html() {
447 include FrmAppHelper::plugin_path() . '/classes/views/shared/info-overlay.php';
448 }
449
450 /**
451 * @since 3.04.02
452 *
453 * @return void
454 */
455 public static function remove_upsells() {
456 remove_action( 'frm_before_settings', 'FrmSettingsController::license_box' );
457 remove_action( 'frm_after_settings', 'FrmSettingsController::settings_cta' );
458 remove_action( 'frm_add_form_style_tab_options', 'FrmFormsController::add_form_style_tab_options' );
459 remove_action( 'frm_after_field_options', 'FrmFormsController::logic_tip' );
460 }
461
462 /**
463 * If there are CURL problems on this server, wp_remote_post won't work for installing
464 * Use a javascript fallback instead.
465 *
466 * @since 2.0.3
467 *
468 * @return void
469 */
470 public static function install_js_fallback() {
471 FrmAppHelper::load_admin_wide_js();
472 ?>
473 <div id="frm_install_message"></div>
474 <script>jQuery(document).ready( frm_install_now );</script>
475 <?php
476 }
477
478 /**
479 * Check if the database is outdated
480 *
481 * @since 2.0.1
482 * @return boolean
483 */
484 public static function needs_update() {
485 $needs_upgrade = self::compare_for_update(
486 array(
487 'option' => 'frm_db_version',
488 'new_db_version' => FrmAppHelper::$db_version,
489 'new_plugin_version' => FrmAppHelper::plugin_version(),
490 )
491 );
492
493 if ( ! $needs_upgrade ) {
494 $needs_upgrade = apply_filters( 'frm_db_needs_upgrade', $needs_upgrade );
495 }
496
497 return $needs_upgrade;
498 }
499
500 /**
501 * Check both version number and DB number for changes
502 *
503 * @since 3.0.04
504 *
505 * @param array $atts
506 * @return bool
507 */
508 public static function compare_for_update( $atts ) {
509 $db_version = get_option( $atts['option'] );
510
511 if ( strpos( $db_version, '-' ) === false ) {
512 $needs_upgrade = true;
513 } else {
514 $last_upgrade = explode( '-', $db_version );
515 $needs_db_upgrade = (int) $last_upgrade[1] < (int) $atts['new_db_version'];
516 $new_version = version_compare( $last_upgrade[0], $atts['new_plugin_version'], '<' );
517 $needs_upgrade = $needs_db_upgrade || $new_version;
518 }
519
520 return $needs_upgrade;
521 }
522
523 /**
524 * Check for database update and trigger js loading
525 *
526 * @since 2.0.1
527 *
528 * @return void
529 */
530 public static function admin_init() {
531 if ( FrmAppHelper::is_admin_page( 'formidable' ) && 'duplicate' === FrmAppHelper::get_param( 'frm_action' ) ) {
532 FrmFormsController::duplicate();
533 }
534
535 if ( FrmAppHelper::is_style_editor_page() && 'save' === FrmAppHelper::get_param( 'frm_action' ) ) {
536 // Hook in earlier than FrmStylesController::route so we can redirect before the headers have been sent.
537 FrmStylesController::save_style();
538 }
539
540 new FrmPersonalData(); // register personal data hooks
541
542 if ( ! FrmAppHelper::doing_ajax() && self::needs_update() ) {
543 self::network_upgrade_site();
544 }
545
546 if ( ! FrmAppHelper::doing_ajax() ) {
547 // don't continue during ajax calls
548 self::admin_js();
549 }
550
551 if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
552 $action = FrmAppHelper::get_param( 'frm_action' );
553
554 if ( in_array( $action, array( 'add_new', 'list_templates' ), true ) ) {
555 wp_safe_redirect( admin_url( 'admin.php?page=formidable&triggerNewFormModal=1' ) );
556 exit;
557 }
558
559 FrmInbox::maybe_disable_screen_options();
560 }
561
562 self::maybe_add_ip_warning();
563 }
564
565 /**
566 * Show a warning for the IP address setting if it hasn't been set.
567 *
568 * @since 6.1
569 *
570 * @return void
571 */
572 private static function maybe_add_ip_warning() {
573 $settings = FrmAppHelper::get_settings();
574 if ( false !== $settings->custom_header_ip ) {
575 // The setting has been changed from the false default (to either 1 or 0), so stop showing the message.
576 return;
577 }
578
579 if ( ! self::is_behind_proxy() ) {
580 // This message is only applicable when using a reverse proxy.
581 return;
582 }
583
584 if ( FrmAppHelper::get_post_param( 'frm_action', '', 'sanitize_text_field' ) ) {
585 // Avoid the message on a POST action. We don't want to show the message if we're saving global settings.
586 return;
587 }
588
589 $global_settings_link = admin_url( 'admin.php?page=formidable-settings' ) . '#frm_custom_header_ip';
590 $message = sprintf(
591 // Translators: 1: Global Settings Link
592 __( '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' ),
593 '<a href="' . esc_url( $global_settings_link ) . '">Global Settings</a>'
594 );
595 $option_name = 'frm_dismiss_ip_address_notice';
596 FrmAppHelper::add_dismissable_warning_message( $message, $option_name );
597 }
598
599 /**
600 * Check if any reverse proxy headers are set.
601 *
602 * @since 6.1
603 *
604 * @return bool
605 */
606 private static function is_behind_proxy() {
607 $custom_headers = FrmAppHelper::get_custom_header_keys_for_ip();
608 foreach ( $custom_headers as $header ) {
609 if ( 'REMOTE_ADDR' === $header ) {
610 // We want to check every key but REMOTE_ADDR. REMOTE_ATTR is not unique to reverse proxy servers.
611 continue;
612 }
613
614 $ip = trim( FrmAppHelper::get_server_value( $header ) );
615 // Return true for anything that isn't empty but ignoring values like ::1.
616 if ( $ip && 0 !== strpos( $ip, '::' ) ) {
617 return true;
618 }
619 }
620
621 return false;
622 }
623
624 /**
625 * @return void
626 */
627 public static function admin_js() {
628 $plugin_url = FrmAppHelper::plugin_url();
629 $version = FrmAppHelper::plugin_version();
630
631 FrmAppHelper::load_admin_wide_js();
632
633 wp_register_style( 'formidable_admin_global', $plugin_url . '/css/admin/frm_admin_global.css', array(), $version );
634 wp_enqueue_style( 'formidable_admin_global' );
635
636 wp_register_style( 'formidable-admin', $plugin_url . '/css/frm_admin.css', array(), $version );
637 wp_register_style( 'formidable-grids', $plugin_url . '/css/frm_grids.css', array(), $version );
638
639 wp_register_script( 'formidable_dom', $plugin_url . '/js/admin/dom.js', array( 'jquery', 'jquery-ui-dialog', 'wp-i18n' ), $version, true );
640 wp_register_script( 'formidable_embed', $plugin_url . '/js/admin/embed.js', array( 'formidable_dom', 'jquery-ui-autocomplete' ), $version, true );
641 self::register_popper1();
642 wp_register_script( 'bootstrap_tooltip', $plugin_url . '/js/bootstrap.min.js', array( 'jquery', 'popper' ), '4.6.1', true );
643 wp_register_script( 'formidable_settings', $plugin_url . '/js/admin/settings.js', array(), $version, true );
644
645 $page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
646
647 // Enqueue Floating Links.
648 $is_valid_page =
649 FrmAppHelper::is_formidable_admin() &&
650 ! FrmAppHelper::is_style_editor_page() &&
651 ! FrmAppHelper::is_admin_page( 'formidable-views-editor' ) &&
652 ! FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
653 if ( $is_valid_page && FrmAppHelper::is_formidable_branding() ) {
654 self::enqueue_floating_links( $plugin_url, $version );
655 }
656 unset( $is_valid_page );
657
658 if ( 'formidable-applications' === $page ) {
659 FrmApplicationsController::load_assets();
660 return;
661 }
662
663 $dependencies = array(
664 'formidable_admin_global',
665 'jquery',
666 'jquery-ui-core',
667 'jquery-ui-draggable',
668 'jquery-ui-sortable',
669 'bootstrap_tooltip',
670 'bootstrap-multiselect',
671 'wp-i18n',
672 'wp-hooks', // Required in WP versions older than 5.7
673 'formidable_dom',
674 'formidable_embed',
675 );
676
677 if ( FrmAppHelper::is_style_editor_page( 'edit' ) ) {
678 // We only need to load the color picker when editing styles.
679 $dependencies[] = 'wp-color-picker';
680 }
681
682 wp_register_script( 'formidable_admin', $plugin_url . '/js/formidable_admin.js', $dependencies, $version, true );
683
684 if ( FrmAppHelper::on_form_listing_page() ) {
685 // For the existing page dropdown in the Form embed modal.
686 wp_enqueue_script( 'jquery-ui-autocomplete' );
687 }
688
689 wp_register_script( 'bootstrap-multiselect', $plugin_url . '/js/bootstrap-multiselect.js', array( 'jquery', 'bootstrap_tooltip', 'popper' ), '1.1.1', true );
690
691 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title' );
692
693 global $pagenow;
694 if ( strpos( $page, 'formidable' ) === 0 || ( $pagenow === 'edit.php' && $post_type === 'frm_display' ) ) {
695
696 wp_enqueue_script( 'admin-widgets' );
697 wp_enqueue_style( 'widgets' );
698 self::maybe_deregister_popper2();
699 wp_enqueue_script( 'formidable_admin' );
700 wp_enqueue_script( 'formidable_embed' );
701 FrmAppHelper::localize_script( 'admin' );
702
703 wp_enqueue_style( 'formidable-admin' );
704 if ( 'formidable-styles' !== $page && 'formidable-styles2' !== $page ) {
705 wp_enqueue_style( 'formidable-grids' );
706 wp_enqueue_style( 'formidable-dropzone' );
707 } else {
708 wp_enqueue_style( 'formidable-grids' );
709 }
710
711 if ( 'formidable-entries' === $page ) {
712 // Load front end js for entries.
713 wp_enqueue_script( 'formidable' );
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 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title' );
1079
1080 // Check admin privileges, screen mode, and branding
1081 $is_not_admin = ! FrmAppHelper::is_formidable_admin() && $post_type !== 'frm_logs';
1082 $is_full_screen = FrmAppHelper::is_full_screen();
1083 $is_not_formidable_branding = ! FrmAppHelper::is_formidable_branding();
1084
1085 // Exit if any of the above conditions are met
1086 if ( $is_not_admin || $is_full_screen || $is_not_formidable_branding ) {
1087 return;
1088 }
1089
1090 include FrmAppHelper::plugin_path() . '/classes/views/shared/admin-footer-links.php';
1091 }
1092
1093 /**
1094 * @deprecated 3.0.04
1095 *
1096 * @codeCoverageIgnore
1097 *
1098 * @return void
1099 */
1100 public static function activation_install() {
1101 FrmDeprecated::activation_install();
1102 }
1103
1104 /**
1105 * @deprecated 3.0
1106 * @codeCoverageIgnore
1107 */
1108 public static function page_route( $content ) {
1109 return FrmDeprecated::page_route( $content );
1110 }
1111
1112 /**
1113 * Include icons on page for Embed Form modal.
1114 *
1115 * @since 5.2
1116 *
1117 * @return void
1118 */
1119 public static function include_embed_form_icons() {
1120 _deprecated_function( __METHOD__, '5.3' );
1121 }
1122
1123 /**
1124 * @deprecated 1.07.05 This is still referenced in the API add on as of v1.13.
1125 * @codeCoverageIgnore
1126 *
1127 * @param array $atts
1128 * @return string
1129 */
1130 public static function get_form_shortcode( $atts ) {
1131 _deprecated_function( __FUNCTION__, '1.07.05', 'FrmFormsController::get_form_shortcode' );
1132 return FrmFormsController::get_form_shortcode( $atts );
1133 }
1134
1135 /**
1136 * Handles Floating Links' scripts and styles enqueueing.
1137 *
1138 * @since 6.4
1139 *
1140 * @param string $plugin_url URL of the plugin.
1141 * @param string $version Current version of the plugin.
1142 * @return void
1143 */
1144 private static function enqueue_floating_links( $plugin_url, $version ) {
1145 if ( ! $plugin_url || ! $version ) {
1146 // If any required parameters are missing, exit early.
1147 return;
1148 }
1149
1150 // Enqueue the Floating Links styles.
1151 wp_enqueue_style( 's11-floating-links', $plugin_url . '/css/packages/s11-floating-links.css', array(), $version );
1152
1153 // Enqueue the Floating Links script.
1154 wp_enqueue_script( 's11-floating-links', $plugin_url . '/js/packages/floating-links/s11-floating-links.js', array(), $version, true );
1155
1156 // Enqueue the config script.
1157 wp_enqueue_script( 's11-floating-links-config', $plugin_url . '/js/packages/floating-links/config.js', array( 'wp-i18n' ), $version, true );
1158 wp_set_script_translations( 's11-floating-links-config', 's11-' );
1159 $floating_links_data = array(
1160 'proIsInstalled' => FrmAppHelper::pro_is_installed(),
1161 );
1162 wp_localize_script( 's11-floating-links-config', 's11FloatingLinksData', $floating_links_data );
1163 }
1164 }
1165