* Global admin related items and functionality.
if ( ! defined( 'ABSPATH' ) ) {
use WPForms\Admin\Blocks\Links;
use WPForms\Admin\Notice;
* Load styles for all WPForms-related admin screens.
function wpforms_admin_styles() {
if ( ! wpforms_is_admin_page() ) {
$min = wpforms_get_min_suffix();
// jQuery.Confirm Reloaded.
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.confirm/jquery-confirm.min.css',
// Minicolors (color picker).
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.minicolors/jquery.minicolors.min.css',
WPFORMS_PLUGIN_URL . 'assets/lib/font-awesome/font-awesome.min.css',
WPFORMS_PLUGIN_URL . "assets/css/admin{$min}.css",
'wpforms-multiselect-checkboxes',
WPFORMS_PLUGIN_URL . 'assets/lib/wpforms-multiselect/wpforms-multiselect-checkboxes.min.css',
// Remove TinyMCE editor styles from third-party themes and plugins.
// WordPress 5.7 color set.
if ( version_compare( get_bloginfo( 'version' ), '5.7', '>=' ) ) {
'wpforms-admin-wp5.7-color',
WPFORMS_PLUGIN_URL . "assets/css/admin-wp5.7-colors{$min}.css",
add_action( 'admin_enqueue_scripts', 'wpforms_admin_styles', 5 );
* Load scripts for all WPForms-related admin screens.
* @noinspection HtmlUnknownTarget
function wpforms_admin_scripts() {
if ( ! wpforms_is_admin_page() ) {
$min = wpforms_get_min_suffix();
if ( wpforms_is_admin_page( 'settings', 'email' ) ) {
// jQuery.Confirm Reloaded.
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.confirm/jquery-confirm.min.js',
// Minicolors (color picker).
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.minicolors/jquery.minicolors.min.js',
WPFORMS_PLUGIN_URL . 'assets/lib/choices.min.js',
WPFORMS_PLUGIN_URL . 'assets/lib/conditions.min.js',
WPFORMS_PLUGIN_URL . "assets/js/share/utils{$min}.js",
WPFORMS_PLUGIN_URL . "assets/js/admin/share/admin-utils{$min}.js",
WPFORMS_PLUGIN_URL . "assets/js/admin/admin{$min}.js",
[ 'jquery', 'underscore', 'wp-util' ],
'wpforms-multiselect-checkboxes',
WPFORMS_PLUGIN_URL . 'assets/lib/wpforms-multiselect/wpforms-multiselect-checkboxes.min.js',
$default_choicesjs_loading_text = esc_html__( 'Loading...', 'wpforms-lite' );
$default_choicesjs_no_results_text = esc_html__( 'No results found', 'wpforms-lite' );
$default_choicesjs_no_choices_text = esc_html__( 'No choices to choose from', 'wpforms-lite' );
$image_extensions = wpforms_chain( get_allowed_mime_types() )
static function ( $mime ) {
return strpos( $mime, 'image/' ) === 0 ? $mime : '';
'addon_activate' => esc_html__( 'Activate', 'wpforms-lite' ),
'addon_activated' => esc_html__( 'Activated', 'wpforms-lite' ),
'addon_active' => esc_html__( 'Active', 'wpforms-lite' ),
'addon_deactivate' => esc_html__( 'Deactivate', 'wpforms-lite' ),
'addon_inactive' => esc_html__( 'Inactive', 'wpforms-lite' ),
'addon_install' => esc_html__( 'Install Addon', 'wpforms-lite' ),
'addon_error' => sprintf(
wp_kses( /* translators: %1$s - addon download URL, %2$s - link to manual installation guide, %3$s - link to contact support. */
__( 'Could not install the addon. Please <a href="%1$s" target="_blank" rel="noopener noreferrer">download it from wpforms.com</a> and <a href="%2$s" target="_blank" rel="noopener noreferrer">install it manually</a>, or <a href="%3$s" target="_blank" rel="noopener noreferrer">contact support</a> for assistance.', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/account/licenses/', 'Licenses', 'Addons Error' ) ),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-manually-install-addons-in-wpforms/', 'Addons Doc', 'Addons Error' ) ),
esc_url( wpforms_utm_link( 'https://wpforms.com/contact/', 'Contact', 'Addons Error' ) )
'plugin_error' => esc_html__( 'Could not install the plugin automatically. Please download and install it manually.', 'wpforms-lite' ),
'addon_search' => esc_html__( 'Searching Addons', 'wpforms-lite' ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'cancel' => esc_html__( 'Cancel', 'wpforms-lite' ),
'continue' => esc_html__( 'Continue', 'wpforms-lite' ),
'close' => esc_html__( 'Close', 'wpforms-lite' ),
'close_refresh' => esc_html__( 'Close and Refresh', 'wpforms-lite' ),
'column_selector_title' => esc_html__( 'Change columns to display', 'wpforms-lite' ),
'column_selector_no_fields' => esc_html__( 'Sorry, there are no form fields that match your criteria.', 'wpforms-lite' ),
'column_selector_no_meta' => esc_html__( 'Sorry, there is no entry meta that match your criteria.', 'wpforms-lite' ),
'entry_delete_confirm' => esc_html__( 'Are you sure you want to delete this entry? This will also remove all associated files, notes, and logs.', 'wpforms-lite' ),
'entry_delete_all_confirm' => esc_html__( 'Are you sure you want to delete ALL entries? This will also remove all associated files, notes, and logs.', 'wpforms-lite' ),
'entry_delete_n_confirm' => sprintf( /* translators: %s - entry count. */
esc_html__( 'Are you sure you want to delete %s entries? This will also remove all associated files, notes, and logs.', 'wpforms-lite' ),
'entry_trash_confirm' => esc_html__( 'Are you sure you want to trash this entry? This will also remove all associated files, notes, and logs.', 'wpforms-lite' ),
'entry_trash_all_confirm' => esc_html__( 'Are you sure you want to trash ALL entries? This will also remove all associated files, notes, and logs.', 'wpforms-lite' ),
'entry_trash_n_confirm' => sprintf( /* translators: %s - entry count. */
esc_html__( 'Are you sure you want to trash %s entries? This will also remove all associated files, notes, and logs.', 'wpforms-lite' ),
'entry_empty_fields_hide' => esc_html__( 'Hide Empty Fields', 'wpforms-lite' ),
'entry_empty_fields_show' => esc_html__( 'Show Empty Fields', 'wpforms-lite' ),
'entry_note_delete_confirm' => esc_html__( 'Are you sure you want to delete this note?', 'wpforms-lite' ),
'entry_unstar' => esc_html__( 'Unstar entry', 'wpforms-lite' ),
'entry_star' => esc_html__( 'Star entry', 'wpforms-lite' ),
'entry_read' => esc_html__( 'Mark entry read', 'wpforms-lite' ),
'entry_unread' => esc_html__( 'Mark entry unread', 'wpforms-lite' ),
'form_delete_confirm' => esc_html__( 'Are you sure you want to delete this form and all its entries?', 'wpforms-lite' ),
'template_delete_confirm' => esc_html__( 'Are you sure you want to delete this template and all its entries?', 'wpforms-lite' ),
'form_delete_n_confirm' => esc_html__( 'Are you sure you want to delete the selected forms and all their entries?', 'wpforms-lite' ),
'form_delete_all_confirm' => esc_html__( 'Are you sure you want to delete ALL the forms in the trash and all their entries?', 'wpforms-lite' ),
'form_duplicate_confirm' => esc_html__( 'Are you sure you want to duplicate this form?', 'wpforms-lite' ),
'template_duplicate_confirm' => esc_html__( 'Are you sure you want to duplicate this template?', 'wpforms-lite' ),
'heads_up' => esc_html__( 'Heads up!', 'wpforms-lite' ),
'importer_forms_required' => esc_html__( 'Please select at least one form to import.', 'wpforms-lite' ),
'isPro' => wpforms()->is_pro(),
'nonce' => wp_create_nonce( 'wpforms-admin' ),
'almost_done' => esc_html__( 'Almost Done', 'wpforms-lite' ),
'thanks_for_interest' => esc_html__( 'Thanks for your interest in WPForms Pro!', 'wpforms-lite' ),
'oops' => esc_html__( 'Oops!', 'wpforms-lite' ),
'uh_oh' => esc_html__( 'Uh oh!', 'wpforms-lite' ),
'ok' => esc_html__( 'OK', 'wpforms-lite' ),
'plugin_install_activate_btn' => esc_html__( 'Install and Activate', 'wpforms-lite' ),
'plugin_install_activate_confirm' => esc_html__( 'needs to be installed and activated to import its forms. Would you like us to install and activate it for you?', 'wpforms-lite' ),
'plugin_activate_btn' => esc_html__( 'Activate', 'wpforms-lite' ),
'plugin_activate_confirm' => esc_html__( 'needs to be activated to import its forms. Would you like us to activate it for you?', 'wpforms-lite' ),
'provider_delete_confirm' => esc_html__( 'Are you sure you want to disconnect this account? Any form connections you have set up will be lost.', 'wpforms-lite' ),
'provider_delete_error' => esc_html__( 'Could not disconnect this account.', 'wpforms-lite' ),
'provider_auth_error' => esc_html__( 'Could not authenticate with the provider.', 'wpforms-lite' ),
'connecting' => esc_html__( 'Connecting...', 'wpforms-lite' ),
'save_refresh' => esc_html__( 'Save and Refresh', 'wpforms-lite' ),
'save_changes' => esc_html__( 'Save Changes', 'wpforms-lite' ),
'server_error' => esc_html__( 'Unfortunately there was a server connection error.', 'wpforms-lite' ),
'unknown_error' => esc_html__( 'Unknown error.', 'wpforms-lite' ),
'settings_form_style_base' => sprintf(
wp_kses( /* translators: %s - WPForms.com docs page URL. */
__( 'You\'ve selected <strong>Base Styling Only</strong>, which may result in styling issues. <a href="%s" target="_blank" rel="noopener noreferrer">Please check out our tutorial</a> for common issues and recommendations.', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/', 'settings-license-modal', 'Base Styling Only' ) )
'settings_form_style_none' => sprintf(
wp_kses( /* translators: %s - WPForms.com docs page URL. */
__( 'You\'ve selected <strong>No Styling</strong>, which will likely result in significant styling issues and is recommended only for developers. <a href="%s" target="_blank" rel="noopener noreferrer">Please check out our tutorial</a> for more details and recommendations.', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/', 'settings-license-modal', 'No Styling' ) )
'testing' => esc_html__( 'Testing', 'wpforms-lite' ),
'recreating' => esc_html__( 'Recreating', 'wpforms-lite' ),
'upgrade_completed' => esc_html__( 'Upgrade was successfully completed!', 'wpforms-lite' ),
'upload_image_title' => esc_html__( 'Upload or Choose Your Image', 'wpforms-lite' ),
'upload_image_button' => esc_html__( 'Use Image', 'wpforms-lite' ),
'upload_image_extensions' => $image_extensions,
'upload_image_extensions_error' => esc_html__( 'You tried uploading a file type that is not allowed. Please try again.', 'wpforms-lite' ),
'upgrade_modal' => wpforms_get_upgrade_modal_text(),
'choicesjs_loading' => $default_choicesjs_loading_text,
'choicesjs_no_results' => $default_choicesjs_no_results_text,
'choicesjs_no_choices' => $default_choicesjs_no_choices_text,
'debug' => wpforms_debug(),
'edit_license' => esc_html__( 'To edit the License Key, please first click the Remove Key button. Please note that removing this key will remove access to updates, addons, and support.', 'wpforms-lite' ),
'something_went_wrong' => esc_html__( 'Something went wrong', 'wpforms-lite' ),
'success' => esc_html__( 'Success', 'wpforms-lite' ),
'loading' => esc_html__( 'Loading...', 'wpforms-lite' ),
'use_default_template' => esc_html__( 'Use Default Template', 'wpforms-lite' ),
'error_select_template' => esc_html__( 'Something went wrong while applying the form template. Please try again. If the error persists, contact our support team.', 'wpforms-lite' ),
wp_kses( /* translators: %s - link to WPForms.com docs page. */
__( 'Something went wrong. Please try again, and if the problem persists, <a href="%1$s" target="_blank" rel="noopener noreferrer">contact our support team</a>.', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/contact/', 'error-modal', 'contact our support team' ) )
* Allow theme/plugin developers to adjust main strings on backend/admin part.
* @param array $strings Main admin localized strings.
$strings = (array) apply_filters( 'wpforms_admin_strings', $strings );
* Allow theme/plugin developers to adjust Choices.js settings on backend/admin part.
* @see https://github.com/Choices-js/Choices#setup For configuration options.
* @param array $choicesjs_config Choicesjs configuration.
$choicesjs_config = (array) apply_filters(
'wpforms_admin_scripts_choicesjs_config',
'searchEnabled' => false,
// Forces the search to look for exact matches anywhere in the string.
'loadingText' => ! empty( $strings['choicesjs_loading'] ) ? $strings['choicesjs_loading'] : $default_choicesjs_loading_text,
'noResultsText' => ! empty( $strings['choicesjs_no_results'] ) ? $strings['choicesjs_no_results'] : $default_choicesjs_no_results_text,
'noChoicesText' => ! empty( $strings['choicesjs_no_choices'] ) ? $strings['choicesjs_no_choices'] : $default_choicesjs_no_choices_text,
'wpforms_admin_choicesjs_config',
add_action( 'admin_enqueue_scripts', 'wpforms_admin_scripts' );
* Add body class to WPForms admin pages for easy reference.
* @param string $classes CSS classes, space separated.
function wpforms_admin_body_class( $classes ) {
if ( ! wpforms_is_admin_page() ) {
return "$classes wpforms-admin-page";
add_filter( 'admin_body_class', 'wpforms_admin_body_class' );
* Output the WPForms admin header.
function wpforms_admin_header() {
// Bail if we're not on a WPForms screen or page (also exclude form builder).
if ( ! wpforms_is_admin_page() ) {
* Prevent admin header outputting if needed.
* @param bool $is_admin_header_visible True if admin page header should be outputted.
if ( ! apply_filters( 'wpforms_admin_header', true ) ) {
// Omit header from the Welcome activation screen.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
if ( sanitize_key( $_REQUEST['page'] ) === 'wpforms-getting-started' ) {
$current_screen = get_current_screen();
$show_screen_options = $current_screen && $current_screen->show_screen_options();
* Fire before the admin header is outputted.
do_action( 'wpforms_admin_header_before' );
<div id="wpforms-header-temp"></div>
<div id="wpforms-header" class="wpforms-header <?php echo esc_attr( $show_screen_options ? 'wpforms-header-show-screen-options' : '' ); ?>">
<img class="wpforms-header-logo" src="<?php echo esc_url( WPFORMS_PLUGIN_URL . 'assets/images/logo.png' ); ?>" alt="WPForms Logo">
$current_page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$current_page = str_replace( 'wpforms-', '', $current_page );
'medium' => 'header_links',
'content' => $current_page . '_docs',
'medium' => 'header_links',
'content' => $current_page . '_support',
* Fire after the admin header is outputted.
do_action( 'wpforms_admin_header_after' );
add_action( 'in_admin_header', 'wpforms_admin_header', 100 );
* Remove non-WPForms notices from WPForms pages.
* @since 1.6.9 Added callback for removing on `admin_footer` hook.
function wpforms_admin_hide_unrelated_notices() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Generic.Metrics.NestingLevel.MaxExceeded
if ( ! wpforms_is_admin_page() ) {
// Define rules to remove callbacks.
'user_admin_notices' => [], // remove all callbacks.
'all_admin_notices' => [],
'render_delayed_admin_notices', // remove this particular callback.
// Extra deny callbacks (will be removed for each hook tag defined in $rules).
$common_deny_callbacks = [
'wpformsdb_admin_notice', // 'Database for WPForms' plugin.
$notice_types = array_keys( $rules );
foreach ( $notice_types as $notice_type ) {
if ( empty( $wp_filter[ $notice_type ]->callbacks ) || ! is_array( $wp_filter[ $notice_type ]->callbacks ) ) {
$remove_all_filters = empty( $rules[ $notice_type ] );
foreach ( $wp_filter[ $notice_type ]->callbacks as $priority => $hooks ) {
foreach ( $hooks as $name => $arr ) {