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

1,197 lines 32.6 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 $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 FrmOverlayController::register_assets();
649
650 wp_register_style( 'formidable_admin_global', $plugin_url . '/css/admin/frm_admin_global.css', array(), $version );
651 wp_enqueue_style( 'formidable_admin_global' );
652
653 wp_register_style( 'formidable-admin', $plugin_url . '/css/frm_admin.css', array(), $version );
654 wp_register_style( 'formidable-grids', $plugin_url . '/css/frm_grids.css', array(), $version );
655
656 wp_register_script( 'formidable_dom', $plugin_url . '/js/admin/dom.js', array( 'jquery', 'jquery-ui-dialog', 'wp-i18n' ), $version, true );
657 wp_register_script( 'formidable_embed', $plugin_url . '/js/admin/embed.js', array( 'formidable_dom', 'jquery-ui-autocomplete' ), $version, true );
658 self::register_popper1();
659 wp_register_script( 'bootstrap_tooltip', $plugin_url . '/js/bootstrap.min.js', array( 'jquery', 'popper' ), '4.6.1', true );
660 wp_register_script( 'formidable_settings', $plugin_url . '/js/admin/settings.js', array(), $version, true );
661
662 $page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
663
664 // Enqueue Floating Links.
665 $is_valid_page =
666 FrmAppHelper::is_formidable_admin() &&
667 ! FrmAppHelper::is_style_editor_page() &&
668 ! FrmAppHelper::is_admin_page( 'formidable-views-editor' ) &&
669 ! FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
670 if ( $is_valid_page && FrmAppHelper::is_formidable_branding() ) {
671 self::enqueue_floating_links( $plugin_url, $version );
672 }
673 unset( $is_valid_page );
674
675 if ( 'formidable-applications' === $page ) {
676 FrmApplicationsController::load_assets();
677 return;
678 }
679
680 $dependencies = array(
681 'formidable_admin_global',
682 'jquery',
683 'jquery-ui-core',
684 'jquery-ui-draggable',
685 'jquery-ui-sortable',
686 'bootstrap_tooltip',
687 'bootstrap-multiselect',
688 'wp-i18n',
689 'wp-hooks', // Required in WP versions older than 5.7
690 'formidable_dom',
691 'formidable_embed',
692 );
693
694 if ( FrmAppHelper::is_style_editor_page( 'edit' ) ) {
695 // We only need to load the color picker when editing styles.
696 $dependencies[] = 'wp-color-picker';
697 }
698
699 wp_register_script( 'formidable_admin', $plugin_url . '/js/formidable_admin.js', $dependencies, $version, true );
700
701 if ( FrmAppHelper::on_form_listing_page() ) {
702 // For the existing page dropdown in the Form embed modal.
703 wp_enqueue_script( 'jquery-ui-autocomplete' );
704 }
705
706 wp_register_script( 'bootstrap-multiselect', $plugin_url . '/js/bootstrap-multiselect.js', array( 'jquery', 'bootstrap_tooltip', 'popper' ), '1.1.1', true );
707
708 if ( ! class_exists( 'FrmTransHooksController', false ) ) {
709 /**
710 * Gateway fields are included for add-on compatibility but we do not want it to be visible.
711 * They do however need to be visible when the payments submodule is active.
712 */
713 wp_add_inline_style(
714 'formidable-admin',
715 '#frm_builder_page li[data-ftype="gateway"] { display: none; }'
716 );
717 }
718
719 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title' );
720
721 global $pagenow;
722 if ( strpos( $page, 'formidable' ) === 0 || ( $pagenow === 'edit.php' && $post_type === 'frm_display' ) ) {
723
724 wp_enqueue_script( 'admin-widgets' );
725 wp_enqueue_style( 'widgets' );
726 self::maybe_deregister_popper2();
727 wp_enqueue_script( 'formidable_admin' );
728 wp_enqueue_script( 'formidable_embed' );
729 FrmAppHelper::localize_script( 'admin' );
730
731 wp_enqueue_style( 'formidable-admin' );
732 if ( 'formidable-styles' !== $page && 'formidable-styles2' !== $page ) {
733 wp_enqueue_style( 'formidable-grids' );
734 wp_enqueue_style( 'formidable-dropzone' );
735 } else {
736 wp_enqueue_style( 'formidable-grids' );
737 }
738
739 if ( 'formidable-entries' === $page ) {
740 // Load front end js for entries.
741 wp_enqueue_script( 'formidable' );
742 }
743
744 do_action( 'frm_enqueue_builder_scripts' );
745 self::include_upgrade_overlay();
746 self::include_info_overlay();
747 } elseif ( FrmAppHelper::is_view_builder_page() ) {
748 if ( isset( $_REQUEST['post_type'] ) ) {
749 $post_type = sanitize_title( wp_unslash( $_REQUEST['post_type'] ) );
750 } elseif ( isset( $_REQUEST['post'] ) && absint( $_REQUEST['post'] ) ) {
751 $post = get_post( absint( wp_unslash( $_REQUEST['post'] ) ) );
752 if ( ! $post ) {
753 return;
754 }
755 $post_type = $post->post_type;
756 } else {
757 return;
758 }
759
760 if ( $post_type === 'frm_display' ) {
761 self::enqueue_legacy_views_assets();
762 }
763 }
764
765 }
766
767 /**
768 * @since 6.3.2
769 *
770 * @return void
771 */
772 public static function admin_enqueue_scripts() {
773 self::load_wp_admin_style();
774 self::maybe_force_formidable_block_on_gutenberg_page();
775 }
776
777 /**
778 * Enqueue required assets for the Legacy Views editor (Views v4.x).
779 *
780 * @since 6.1.2
781 *
782 * @return void
783 */
784 private static function enqueue_legacy_views_assets() {
785 wp_enqueue_style( 'formidable-grids' );
786 wp_enqueue_script( 'jquery-ui-draggable' );
787 self::maybe_deregister_popper2();
788 wp_enqueue_script( 'formidable_admin' );
789 wp_add_inline_style(
790 'formidable-admin',
791 '
792 .frm-white-body.post-type-frm_display .columns-2 {
793 display: block;
794 overflow: visible;
795 }
796
797 .frm-white-body.post-type-frm_display .columns-2 > div {
798 overflow-y: hidden;
799 }
800
801 .frm-white-body.post-type-frm_display #titlediv #title-prompt-text {
802 padding: 3px 0 0 10px;
803 }
804
805 .post-type-frm_display #field-search-input,
806 .post-type-frm_display #advanced-search-input {
807 flex: 1;
808 }
809 '
810 );
811 wp_enqueue_style( 'formidable-admin' );
812 FrmAppHelper::localize_script( 'admin' );
813 self::include_info_overlay();
814 }
815
816 /**
817 * Fix a Duplicator Pro conflict because it uses Popper 2. See issue #3459.
818 *
819 * @since 5.2.02.01
820 *
821 * @return void
822 */
823 private static function maybe_deregister_popper2() {
824 global $wp_scripts;
825
826 if ( ! array_key_exists( 'popper', $wp_scripts->registered ) ) {
827 return;
828 }
829
830 $popper = $wp_scripts->registered['popper'];
831 if ( version_compare( $popper->ver, '2.0', '>=' ) ) {
832 wp_deregister_script( 'popper' );
833 self::register_popper1();
834 }
835 }
836
837 /**
838 * Register Popper required for Bootstrap 4.
839 *
840 * @since 5.2.02.01
841 *
842 * @return void
843 */
844 private static function register_popper1() {
845 wp_register_script( 'popper', FrmAppHelper::plugin_url() . '/js/popper.min.js', array( 'jquery' ), '1.16.0', true );
846 }
847
848 /**
849 * Automatically insert a Formidable block when loading Gutenberg when $_GET['frmForm' is set.
850 *
851 * @since 5.2
852 *
853 * @return void
854 */
855 private static function maybe_force_formidable_block_on_gutenberg_page() {
856 global $pagenow;
857 if ( 'post.php' !== $pagenow ) {
858 return;
859 }
860
861 $form_id = FrmAppHelper::simple_get( 'frmForm', 'absint' );
862 if ( ! $form_id ) {
863 return;
864 }
865
866 self::add_js_to_inject_gutenberg_block( 'formidable/simple-form', 'formId', $form_id );
867 }
868
869 /**
870 * @since 5.3
871 *
872 * @param string $block_name
873 * @param string $object_key
874 * @param array|string $object_id
875 *
876 * @return void
877 */
878 public static function add_js_to_inject_gutenberg_block( $block_name, $object_key, $object_id ) {
879 require FrmAppHelper::plugin_path() . '/classes/views/shared/edit-page-js.php';
880 }
881
882 /**
883 * @return void
884 */
885 public static function load_lang() {
886 load_plugin_textdomain( 'formidable', false, FrmAppHelper::plugin_folder() . '/languages/' );
887 }
888
889 /**
890 * Check if the styles are updated when a form is loaded on the front-end
891 *
892 * @since 3.0.1
893 *
894 * @return void
895 */
896 public static function maybe_update_styles() {
897 if ( self::needs_update() ) {
898 self::network_upgrade_site();
899 }
900 }
901
902 /**
903 * @since 3.0
904 *
905 * @return void
906 */
907 public static function create_rest_routes() {
908 $args = array(
909 'methods' => 'GET',
910 'callback' => 'FrmAppController::api_install',
911 'permission_callback' => __CLASS__ . '::can_update_db',
912 );
913
914 register_rest_route( 'frm-admin/v1', '/install', $args );
915
916 $args = array(
917 'methods' => 'GET',
918 'callback' => 'FrmAddonsController::install_addon_api',
919 'permission_callback' => 'FrmAddonsController::can_install_addon_api',
920 );
921
922 register_rest_route( 'frm-admin/v1', '/install-addon', $args );
923 }
924
925 /**
926 * Make sure the install is only being run when we tell it to.
927 * We don't want to run manually by people calling the API.
928 *
929 * @since 4.06.02
930 */
931 public static function can_update_db() {
932 return get_transient( 'frm_updating_api' );
933 }
934
935 /**
936 * Run silent upgrade on each site in the network during a network upgrade.
937 * Update database settings for all sites in a network during network upgrade process.
938 *
939 * @since 2.0.1
940 *
941 * @param int $blog_id Blog ID.
942 *
943 * @return void
944 */
945 public static function network_upgrade_site( $blog_id = 0 ) {
946 // Flag to check if install is happening as intended.
947 set_transient( 'frm_updating_api', true, MINUTE_IN_SECONDS );
948 $request = new WP_REST_Request( 'GET', '/frm-admin/v1/install' );
949
950 self::maybe_add_wp_site_health();
951
952 if ( $blog_id ) {
953 switch_to_blog( $blog_id );
954 $response = rest_do_request( $request );
955 restore_current_blog();
956 } else {
957 $response = rest_do_request( $request );
958 }
959
960 if ( $response->is_error() ) {
961 // if the remove post fails, use javascript instead
962 add_action( 'admin_notices', 'FrmAppController::install_js_fallback' );
963 }
964 }
965
966 /**
967 * Make sure WP_Site_Health has been included because it is required when calling rest_do_request.
968 * Check first that the file exists because WP_Site_Health was only introduced in WordPress 5.2.
969 *
970 * @return void
971 */
972 private static function maybe_add_wp_site_health() {
973 if ( ! class_exists( 'WP_Site_Health' ) ) {
974 $wp_site_health_path = ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
975 if ( file_exists( $wp_site_health_path ) ) {
976 require_once $wp_site_health_path;
977 }
978 }
979 }
980
981 /**
982 * @since 3.0
983 *
984 * @return true
985 */
986 public static function api_install() {
987 delete_transient( 'frm_updating_api' );
988 if ( self::needs_update() ) {
989 $running = get_option( 'frm_install_running' );
990 if ( false === $running || $running < strtotime( '-5 minutes' ) ) {
991 update_option( 'frm_install_running', time(), 'no' );
992 self::install();
993 delete_option( 'frm_install_running' );
994 }
995 }
996
997 return true;
998 }
999
1000 /**
1001 * Silent database upgrade (no redirect).
1002 * Called via ajax request during network upgrade process.
1003 *
1004 * @since 2.0.1
1005 *
1006 * @return void
1007 */
1008 public static function ajax_install() {
1009 FrmAppHelper::permission_check( 'frm_change_settings' );
1010 check_ajax_referer( 'frm_ajax', 'nonce' );
1011 self::api_install();
1012 wp_die();
1013 }
1014
1015 /**
1016 * @return void
1017 */
1018 public static function install() {
1019 $frmdb = new FrmMigrate();
1020 $frmdb->upgrade();
1021 }
1022
1023 /**
1024 * @return void
1025 */
1026 public static function uninstall() {
1027 FrmAppHelper::permission_check( 'administrator' );
1028 check_ajax_referer( 'frm_ajax', 'nonce' );
1029
1030 $frmdb = new FrmMigrate();
1031 $frmdb->uninstall();
1032
1033 //disable the plugin and redirect after uninstall so the tables don't get added right back
1034 $plugins = array( FrmAppHelper::plugin_folder() . '/formidable.php', 'formidable-pro/formidable-pro.php' );
1035 deactivate_plugins( $plugins, false, false );
1036 echo esc_url_raw( admin_url( 'plugins.php?deactivate=true' ) );
1037
1038 wp_die();
1039 }
1040
1041 public static function drop_tables( $tables ) {
1042 global $wpdb;
1043 $tables[] = $wpdb->prefix . 'frm_fields';
1044 $tables[] = $wpdb->prefix . 'frm_forms';
1045 $tables[] = $wpdb->prefix . 'frm_items';
1046 $tables[] = $wpdb->prefix . 'frm_item_metas';
1047
1048 return $tables;
1049 }
1050
1051 /**
1052 * @return void
1053 */
1054 public static function deauthorize() {
1055 FrmAppHelper::permission_check( 'frm_change_settings' );
1056 check_ajax_referer( 'frm_ajax', 'nonce' );
1057
1058 delete_option( 'frmpro-credentials' );
1059 delete_option( 'frmpro-authorized' );
1060 delete_site_option( 'frmpro-credentials' );
1061 delete_site_option( 'frmpro-authorized' );
1062 wp_die();
1063 }
1064
1065 /**
1066 * This is triggered when Formidable is activated.
1067 *
1068 * @return void
1069 */
1070 public static function handle_activation() {
1071 self::maybe_activate_payment_cron();
1072 }
1073
1074 /**
1075 * The payment cron is unscheduled when Formidable is deactivated.
1076 * We need to add it back again on activation if Stripe is configured.
1077 *
1078 * @since 6.5
1079 *
1080 * @return void
1081 */
1082 private static function maybe_activate_payment_cron() {
1083 if ( ! FrmStrpLiteConnectHelper::stripe_connect_is_setup() ) {
1084 return;
1085 }
1086
1087 FrmTransLiteAppController::maybe_schedule_cron();
1088 }
1089
1090 public static function set_footer_text( $text ) {
1091 if ( FrmAppHelper::is_formidable_admin() ) {
1092 $text = '';
1093 }
1094
1095 return $text;
1096 }
1097
1098 /**
1099 * Add admin footer links.
1100 *
1101 * @since 6.4.1
1102 *
1103 * @return void
1104 */
1105 public static function add_admin_footer_links() {
1106 $post_type = FrmAppHelper::simple_get( 'post_type', 'sanitize_title' );
1107
1108 // Check admin privileges, screen mode, and branding
1109 $is_not_admin = ! FrmAppHelper::is_formidable_admin() && $post_type !== 'frm_logs';
1110 $is_full_screen = FrmAppHelper::is_full_screen();
1111 $is_not_formidable_branding = ! FrmAppHelper::is_formidable_branding();
1112
1113 // Exit if any of the above conditions are met
1114 if ( $is_not_admin || $is_full_screen || $is_not_formidable_branding ) {
1115 return;
1116 }
1117
1118 include FrmAppHelper::plugin_path() . '/classes/views/shared/admin-footer-links.php';
1119 }
1120
1121 /**
1122 * @deprecated 3.0.04
1123 *
1124 * @codeCoverageIgnore
1125 *
1126 * @return void
1127 */
1128 public static function activation_install() {
1129 FrmDeprecated::activation_install();
1130 }
1131
1132 /**
1133 * @deprecated 3.0
1134 * @codeCoverageIgnore
1135 */
1136 public static function page_route( $content ) {
1137 return FrmDeprecated::page_route( $content );
1138 }
1139
1140 /**
1141 * Include icons on page for Embed Form modal.
1142 *
1143 * @since 5.2
1144 *
1145 * @return void
1146 */
1147 public static function include_embed_form_icons() {
1148 _deprecated_function( __METHOD__, '5.3' );
1149 }
1150
1151 /**
1152 * @deprecated 1.07.05 This is still referenced in the API add on as of v1.13.
1153 * @codeCoverageIgnore
1154 *
1155 * @param array $atts
1156 * @return string
1157 */
1158 public static function get_form_shortcode( $atts ) {
1159 _deprecated_function( __FUNCTION__, '1.07.05', 'FrmFormsController::get_form_shortcode' );
1160 return FrmFormsController::get_form_shortcode( $atts );
1161 }
1162
1163 /**
1164 * Handles Floating Links' scripts and styles enqueueing.
1165 *
1166 * @since 6.4
1167 *
1168 * @param string $plugin_url URL of the plugin.
1169 * @param string $version Current version of the plugin.
1170 * @return void
1171 */
1172 private static function enqueue_floating_links( $plugin_url, $version ) {
1173 if ( ! $plugin_url || ! $version ) {
1174 // If any required parameters are missing, exit early.
1175 return;
1176 }
1177
1178 // Enqueue the Floating Links styles.
1179 wp_enqueue_style( 's11-floating-links', $plugin_url . '/css/packages/s11-floating-links.css', array(), $version );
1180
1181 // Enqueue the Floating Links script.
1182 wp_enqueue_script( 's11-floating-links', $plugin_url . '/js/packages/floating-links/s11-floating-links.js', array(), $version, true );
1183
1184 // Enqueue the config script.
1185 wp_enqueue_script( 's11-floating-links-config', $plugin_url . '/js/packages/floating-links/config.js', array( 'wp-i18n' ), $version, true );
1186
1187 if ( function_exists( 'wp_set_script_translations' ) ) {
1188 wp_set_script_translations( 's11-floating-links-config', 's11-' );
1189 }
1190
1191 $floating_links_data = array(
1192 'proIsInstalled' => FrmAppHelper::pro_is_installed(),
1193 );
1194 wp_localize_script( 's11-floating-links-config', 's11FloatingLinksData', $floating_links_data );
1195 }
1196 }
1197