namespace WPForms\Admin\Settings;
use WPForms\Emails\Helpers;
use WPForms\Emails\Notifications;
use WPForms\Admin\Education\Helpers as EducationHelpers;
* Settings will be accessible via “WPForms” → “Settings” → “Email”.
* Content is plain text type.
* Temporary storage for the style overrides preferences.
private $style_overrides;
* Determines if the user has the education modal.
* If true, the value will be used to add the Education modal class to the setting controls.
* This is only available in the free version.
* Determines if the user has the legacy template.
* If true, the value will be used to add the Legacy template class to the setting controls.
private $has_legacy_template;
private function hooks() {
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
add_filter( 'wpforms_update_settings', [ $this, 'maybe_update_settings' ] );
add_filter( 'wpforms_settings_tabs', [ $this, 'register_settings_tabs' ], 5 );
add_filter( 'wpforms_settings_defaults', [ $this, 'register_settings_fields' ], 5 );
* Enqueue scripts and styles.
* Static resources are enqueued only on the "Email" settings page.
public function enqueue_assets() {
// Leave if the current page is not the "Email" settings page.
if ( ! $this->is_settings_page() ) {
$min = wpforms_get_min_suffix();
'wpforms-contrast-checker',
WPFORMS_PLUGIN_URL . "assets/js/admin/share/contrast-checker{$min}.js",
WPFORMS_PLUGIN_URL . "assets/js/admin/share/xor{$min}.js",
'wpforms-admin-email-settings',
WPFORMS_PLUGIN_URL . "assets/js/admin/email/settings{$min}.js",
[ 'jquery', 'wpforms-admin', 'wp-escape-html', 'wp-url', 'choicesjs', 'wpforms-contrast-checker', 'wpforms-xor' ],
'wpforms-admin-email-settings',
'wpforms_admin_email_settings',
'contrast_fail' => esc_html__( 'This color combination may be hard to read. Try increasing the contrast between the body and text colors.', 'wpforms-lite' ),
* @param array $settings Admin area settings list.
public function maybe_update_settings( $settings ) {
// Leave if the current page is not the "Email" settings page.
if ( ! $this->is_settings_page() ) {
// Remove the appearance mode switcher from the settings array.
unset( $settings['email-appearance'] );
// Backup the Pro version background color setting to the free version.
// This is needed to keep the background color when the Pro version is deactivated.
if ( wpforms()->is_pro() && ! Helpers::is_legacy_html_template() ) {
$settings['email-background-color'] = sanitize_hex_color( $settings['email-color-scheme']['email_background_color'] );
$settings['email-background-color-dark'] = sanitize_hex_color( $settings['email-color-scheme-dark']['email_background_color_dark'] );
// Backup the free version background color setting to the Pro version.
// This is needed to keep the background color when the Pro version is activated.
$settings['email-color-scheme']['email_background_color'] = sanitize_hex_color( $settings['email-background-color'] );
$settings['email-color-scheme-dark']['email_background_color_dark'] = sanitize_hex_color( $settings['email-background-color-dark'] );
* Register "Email" settings tab.
* @param array $tabs Admin area tabs list.
public function register_settings_tabs( $tabs ) {
'name' => esc_html__( 'Email', 'wpforms-lite' ),
'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
return wpforms_array_insert( $tabs, $payments, 'general' );
* Register "Email" settings fields.
* @param array $settings Admin area settings list.
public function register_settings_fields( $settings ) {
$this->plain_text = Helpers::is_plain_text_template();
$this->has_education = ! wpforms()->is_pro() ? 'education-modal' : '';
$this->style_overrides = Helpers::get_current_template_style_overrides();
$this->has_legacy_template = Helpers::is_legacy_html_template() ? 'legacy-template' : '';
$preview_link = $this->get_current_template_preview_link();
'content' => $this->get_heading_content(),
'class' => [ 'section-heading', 'no-desc' ],
'id' => 'email-template',
'name' => esc_html__( 'Template', 'wpforms-lite' ),
'class' => [ 'wpforms-email-template', 'wpforms-card-image-group' ],
'type' => 'email_template',
'default' => Notifications::DEFAULT_TEMPLATE,
'options' => Helpers::get_email_template_choices(),
'value' => Helpers::get_current_template_name(),
// The reason that we're using the 'content' type is to avoid saving the value in the option storage.
// The value is used only for the appearance mode switcher, and merely acts as a switch between dark and light mode controls.
'id' => 'email-appearance',
'name' => esc_html__( 'Appearance', 'wpforms-lite' ),
'desc' => esc_html__( 'Modern email clients support viewing emails in light and dark modes. You can upload a header image and customize the style for each appearance mode independently to ensure an optimal reading experience.', 'wpforms-lite' ),
'class' => [ 'wpforms-setting-row-radio', 'hide-for-template-none', 'email-appearance-mode-toggle', $this->has_legacy_template ],
'is_hidden' => $this->plain_text,
'light' => esc_html__( 'Light', 'wpforms-lite' ),
'dark' => esc_html__( 'Dark', 'wpforms-lite' ),
'is_hidden' => empty( $preview_link ),
'content' => $preview_link,
'id' => 'sending-heading',
'content' => '<h4>' . esc_html__( 'Sending', 'wpforms-lite' ) . '</h4>',
'class' => [ 'section-heading', 'no-desc' ],
'name' => esc_html__( 'Optimize Email Sending', 'wpforms-lite' ),
wp_kses( /* translators: %1$s - WPForms.com Email settings documentation URL. */
__( 'Send emails asynchronously, which can make processing faster but may delay email delivery by a minute or two. <a href="%1$s" target="_blank" rel="noopener noreferrer" class="wpforms-learn-more">Learn More</a>', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/a-complete-guide-to-wpforms-settings/#email', 'Settings - Email', 'Optimize Email Sending Documentation' ) )
'id' => 'email-carbon-copy',
'name' => esc_html__( 'Carbon Copy', 'wpforms-lite' ),
'desc' => esc_html__( 'Enable the ability to CC: email addresses in the form notification settings.', 'wpforms-lite' ),
// Add the style controls.
$settings['email'] = $this->add_appearance_controls( $settings['email'] );
// Maybe add the Legacy template notice.
$settings['email'] = $this->maybe_add_legacy_notice( $settings['email'] );
* Maybe add the legacy template notice.
* @param array $settings Email settings.
private function maybe_add_legacy_notice( $settings ) {
if ( ! $this->is_settings_page() || ! Helpers::is_legacy_html_template() ) {
$content = '<div class="notice-info"><p>';
wp_kses( /* translators: %1$s - WPForms.com Email settings legacy template documentation URL. */
__( 'Some style settings are not available when using the Legacy template. <a href="%1$s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/customizing-form-notification-emails/#legacy-template', 'Settings - Email', 'Legacy Template' ) )
$content .= '</p></div>';
// Add the background color control after the header image.
return wpforms_array_insert(
'email-legacy-notice' => [
'id' => 'email-legacy-notice',
'class' => 'wpforms-email-legacy-notice',
* Add appearance controls.
* This will include controls for both Light and Dark modes.
* @param array $settings Email settings.
private function add_appearance_controls( $settings ) {
// Education modal arguments.
$education_args = [ 'action' => 'upgrade' ];
// New settings for the Light mode.
'email-header-image' => [
'id' => 'email-header-image',
'name' => esc_html__( 'Header Image', 'wpforms-lite' ),
'desc' => esc_html__( 'Upload or choose a logo to be displayed at the top of email notifications.', 'wpforms-lite' ),
'class' => [ 'wpforms-email-header-image', 'hide-for-template-none', 'has-preview-changes', 'email-light-mode', $this->get_external_header_image_class() ],
'is_hidden' => $this->plain_text,
'email-header-image-size' => [
'id' => 'email-header-image-size',
'class' => [ 'wpforms-email-header-image-size', 'has-preview-changes', 'email-light-mode' ],
'small' => esc_html__( 'Small', 'wpforms-lite' ),
'medium' => esc_html__( 'Medium', 'wpforms-lite' ),
'large' => esc_html__( 'Large', 'wpforms-lite' ),
'email-color-scheme' => [
'id' => 'email-color-scheme',
'name' => esc_html__( 'Color Scheme', 'wpforms-lite' ),
'class' => [ 'email-color-scheme', 'hide-for-template-none', 'has-preview-changes', 'email-light-mode', $this->has_education, $this->has_legacy_template ],
'type' => 'color_scheme',
'is_hidden' => $this->plain_text,
'education_badge' => $this->get_pro_education_badge(),
'data_attributes' => $this->has_education ? array_merge( [ 'name' => esc_html__( 'Color Scheme', 'wpforms-lite' ) ], $education_args ) : [],
'colors' => $this->get_color_scheme_controls(),
'id' => 'email-typography',
'name' => esc_html__( 'Typography', 'wpforms-lite' ),
'desc' => esc_html__( 'Choose the style that’s applied to all text in email notifications.', 'wpforms-lite' ),
'class' => [ 'hide-for-template-none', 'has-preview-changes', 'email-typography', 'email-light-mode', $this->has_education, $this->has_legacy_template ],
'education_badge' => $this->get_pro_education_badge(),
'data_attributes' => $this->has_education ? array_merge( [ 'name' => esc_html__( 'Typography', 'wpforms-lite' ) ], $education_args ) : [],
'is_hidden' => $this->plain_text,
'default' => 'sans-serif',
'sans-serif' => esc_html__( 'Sans Serif', 'wpforms-lite' ),
'serif' => esc_html__( 'Serif', 'wpforms-lite' ),
// Add background color control if the Pro version is not active or Legacy template is selected.
$new_setting = $this->maybe_add_background_color_control( $new_setting );
return wpforms_array_insert(
$this->add_appearance_dark_mode_controls( $new_setting ),
* Add appearance dark mode controls.
* This function will duplicate the default "Light" color
* controls to create corresponding controls for dark mode.
* @param array $settings Email settings.
private function add_appearance_dark_mode_controls( $settings ) {
// Duplicate and modify each item for dark mode.
foreach ( $settings as $key => $item ) {
// Duplicate the item with '-dark' added to the key.
$dark_key = "{$key}-dark";
$settings[ $dark_key ] = $item;
// Modify the 'name' within the duplicated item.
if ( isset( $settings[ $dark_key ]['id'] ) ) {
$settings[ $dark_key ]['id'] .= '-dark';
$classes = &$settings[ $dark_key ]['class'];
$classes[] = 'email-dark-mode';
$classes[] = 'wpforms-hide';
// Remove classes related to light mode.
static function ( $class_name ) {
return $class_name !== 'email-light-mode' && $class_name !== 'has-external-image-url';
// Override the description for the header image control.
if ( $key === 'email-header-image' ) {
$settings[ $dark_key ]['desc'] = esc_html__( 'Upload or choose a logo to be displayed at the top of email notifications. Light mode image will be used if not set.', 'wpforms-lite' );
// Override the background color control attributes.
if ( $key === 'email-background-color' ) {
$settings[ $dark_key ]['default'] = sanitize_hex_color( $this->style_overrides['email_background_color_dark'] );
$settings[ $dark_key ]['data']['fallback-color'] = sanitize_hex_color( $this->style_overrides['email_background_color_dark'] );
// Override the color scheme control attributes.
if ( $key === 'email-color-scheme' ) {
$settings[ $dark_key ]['colors'] = $this->get_color_scheme_controls( true );
* Get Email settings heading content.
private function get_heading_content() {
return wpforms_render( 'admin/settings/email-heading' );
* Get Email settings education badge.
* This is only available in the free version.
private function get_pro_education_badge() {
// Leave early if the user has the Lite version.
if ( empty( $this->has_education ) ) {
// Output the education badge.
return EducationHelpers::get_badge( 'Pro' );
* Generate color scheme controls for the color picker.