: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$background_hover_style .= sprintf(
'background-size: %1$s; ',
esc_html( $background_size_hover )
$background_position_hover = et_pb_hover_options()->get_raw_value( "{$background_prefix}position", $this->props );
$background_position_desktop = self::$_->array_get( $this->props, "{$background_prefix}position", '' );
$is_same_background_position = $background_position_hover === $background_position_desktop;
if ( empty( $background_position_hover ) && ! empty( $background_position_desktop ) ) {
$background_position_hover = $background_position_desktop;
if ( ! empty( $background_position_hover ) && ! $is_same_background_position ) {
$background_hover_style .= sprintf(
'background-position: %1$s; ',
esc_html( str_replace( '_', ' ', $background_position_hover ) )
$background_repeat_hover = et_pb_hover_options()->get_raw_value( "{$background_prefix}repeat", $this->props );
$background_repeat_desktop = self::$_->array_get( $this->props, "{$background_prefix}repeat", '' );
$is_same_background_repeat = $background_repeat_hover === $background_repeat_desktop;
if ( empty( $background_repeat_hover ) && ! empty( $background_repeat_desktop ) ) {
$background_repeat_hover = $background_repeat_desktop;
if ( ! empty( $background_repeat_hover ) && ! $is_same_background_repeat ) {
$background_hover_style .= sprintf(
'background-repeat: %1$s; ',
esc_html( $background_repeat_hover )
$background_blend_hover = et_pb_hover_options()->get_raw_value( "{$background_prefix}blend", $this->props );
$background_blend_default = self::$_->array_get( $this->fields_unprocessed, "{$background_prefix}blend.default", '' );
$background_blend_desktop = self::$_->array_get( $this->props, "{$background_prefix}blend", '' );
$is_same_background_blend = $background_blend_hover === $background_blend_desktop;
if ( empty( $background_blend_hover ) && ! empty( $background_blend_desktop ) ) {
$background_blend_hover = $background_blend_desktop;
if ( ! empty( $background_blend_hover ) ) {
if ( ! $is_same_background_blend ) {
$background_hover_style .= sprintf(
'background-blend-mode: %1$s; ',
esc_html( $background_blend_hover )
// Force background-color: initial;
if ( $has_background_color_gradient_hover && $has_background_image_hover && $background_blend_hover !== $background_blend_default ) {
$has_background_gradient_and_image_hover = true;
$background_hover_style .= 'background-color: initial !important;';
// Only append background image when the image exists.
$background_images_hover[] = sprintf( 'url(%1$s)', esc_html( $background_image_hover ) );
} else if ( '' === $background_image_hover ) {
$is_background_image_hover_disabled = true;
if ( ! empty( $background_images_hover ) ) {
// The browsers stack the images in the opposite order to what you'd expect.
if ( 'on' !== $background_color_gradient_overlays_image_hover ) {
$background_images_hover = array_reverse( $background_images_hover );
$background_hover_style .= sprintf(
'background-image: %1$s !important;',
esc_html( join( ', ', $background_images_hover ) )
} else if ( $is_background_color_gradient_hover_disabled && $is_background_image_hover_disabled ) {
$background_hover_style .= 'background-image: initial !important;';
// Background Color Hover.
if ( ! $has_background_gradient_and_image_hover ) {
$background_color_hover = et_pb_responsive_options()->get_inheritance_background_value( $this->props, "{$background_prefix}color", 'hover', $background_base_name, $this->fields_unprocessed );
$background_color_hover = '' !== $background_color_hover ? $background_color_hover : 'transparent';
if ( '' !== $background_color_hover ) {
$background_hover_style .= sprintf(
'background-color: %1$s !important; ',
esc_html( $background_color_hover )
// Print background hover gradient and image styles.
if ( '' !== $background_hover_style ) {
$background_hover_style_attrs = array(
'selector' => $css_element_processed . ':hover',
'declaration' => rtrim( $background_hover_style ),
'priority' => $this->_style_priority,
self::set_style( $function_name, $background_hover_style_attrs );
* Process form field options into correct CSS styles.
* Fields will be processed here (name, mode, custom selector):
* - Background Color -> Hover -> Form field selector
* - Background Focus Color -> Hover -> Form field focus selector
* - Text Color -> Hover -> Form field & placeholder selector
* - Text Focus Color -> Hover -> Form field & placeholder focus selector
* @param string $function_name Module slug.
function process_advanced_form_field_options( $function_name ) {
// Disable if module doesn't set advanced_fields property and has no VB support.
if ( ! $this->has_advanced_fields ) {
// Ensure form field exist on advanced fields.
if ( ! self::$_->array_get( $this->advanced_fields, 'form_field', false ) ) {
// Fetch every single form field instances.
foreach ( $this->advanced_fields['form_field'] as $option_name => $option_settings ) {
// 1.a. Build main element selector.
$element_selector = ! empty( $option_settings['css']['main'] ) ? $option_settings['css']['main'] : "{$this->main_css_element} .input";
if ( et_builder_has_limitation( 'use_limited_main' ) && ! empty( $option_settings['css']['limited_main'] ) ) {
$element_selector = $option_settings['css']['limited_main'];
// 1.b. Build pseudo element selector.
$element_hover_selector = ! empty( $option_settings['css']['hover'] ) ? $option_settings['css']['hover'] : "{$element_selector}:hover";
$element_focus_selector = ! empty( $option_settings['css']['focus'] ) ? $option_settings['css']['focus'] : "{$element_selector}:focus";
$element_focus_hover_selector = ! empty( $option_settings['css']['focus_hover'] ) ? $option_settings['css']['focus_hover'] : "{$element_selector}:focus:hover";
// 1.c. Build custom form field selector.
$bg_color_selector = ! empty( $option_settings['css']['background_color'] ) ? $option_settings['css']['background_color'] : $element_selector;
$bg_color_hover_selector = ! empty( $option_settings['css']['background_color_hover'] ) ? $option_settings['css']['background_color_hover'] : $element_hover_selector;
$bg_color_focus_selector = ! empty( $option_settings['css']['focus_background_color'] ) ? $option_settings['css']['focus_background_color'] : $element_focus_selector;
$bg_color_focus_hover_selector = ! empty( $option_settings['css']['focus_background_color_hover'] ) ? $option_settings['css']['focus_background_color_hover'] : $element_focus_hover_selector;
$text_color_selector = ! empty( $option_settings['css']['form_text_color'] ) ? $option_settings['css']['form_text_color'] : $element_selector;
$text_color_hover_selector = ! empty( $option_settings['css']['form_text_color_hover'] ) ? $option_settings['css']['form_text_color_hover'] : $element_hover_selector;
$text_color_focus_selector = ! empty( $option_settings['css']['focus_text_color'] ) ? $option_settings['css']['focus_text_color'] : $element_focus_selector;
$text_color_focus_hover_selector = ! empty( $option_settings['css']['focus_text_color_hover'] ) ? $option_settings['css']['focus_text_color_hover'] : $element_focus_hover_selector;
$placeholder_option = self::$_->array_get( $option_settings, 'placeholder', true );
$base_selector = false !== strpos( $element_selector, ',' ) ? "{$this->main_css_element} .input" : $element_selector;
$placeholder_selector = ! empty( $option_settings['css']['placeholder'] ) ? $option_settings['css']['placeholder'] : "{$base_selector}::placeholder, {$base_selector}::-webkit-input-placeholder, {$base_selector}::-moz-placeholder, {$base_selector}::-ms-input-placeholder";
$placeholder_hover_selector = ! empty( $option_settings['css']['placeholder_hover'] ) ? $option_settings['css']['placeholder_hover'] : "{$base_selector}:hover::placeholder, {$base_selector}:hover::-webkit-input-placeholder, {$base_selector}:hover::-moz-placeholder, {$base_selector}:hover::-ms-input-placeholder";
$placeholder_focus_selector = ! empty( $option_settings['css']['placeholder_focus'] ) ? $option_settings['css']['placeholder_focus'] : "{$base_selector}:focus::placeholder, {$base_selector}:focus::-webkit-input-placeholder, {$base_selector}:focus::-moz-placeholder, {$base_selector}:focus::-ms-input-placeholder";
$placeholder_focus_hover_selector = ! empty( $option_settings['css']['placeholder_focus_hover'] ) ? $option_settings['css']['placeholder_focus_hover'] : "{$base_selector}:focus:hover::placeholder, {$base_selector}:focus:hover::-webkit-input-placeholder, {$base_selector}:focus:hover::-moz-placeholder, {$base_selector}:focus:hover::-ms-input-placeholder";
// 2. Default important status.
$force_global_important = et_builder_has_limitation( 'force_use_global_important' );
$important_list = isset( $option_settings['css']['important'] ) ? $option_settings['css']['important'] : array();
// 3.a.1. Field Background Color.
$is_field_bg_color_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, "{$option_name}_background_color" );
$field_bg_color_values = array(
'desktop' => esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_background_color" ) ),
'tablet' => $is_field_bg_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_background_color_tablet" ) ) : '',
'phone' => $is_field_bg_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_background_color_phone" ) ) : '',
$field_bg_color_important = $force_global_important || in_array( 'background_color', $important_list, true ) ? ' !important;' : '';
et_pb_responsive_options()->generate_responsive_css( $field_bg_color_values, $bg_color_selector, 'background-color', $function_name, $field_bg_color_important, 'color' );
// 3.a.2. Field Background Hover Color.
$field_bg_color_hover = $this->get_hover_value("{$option_name}_background_color" );
if ( ! empty( $field_bg_color_hover ) ) {
self::set_style( $function_name, array(
'selector' => $bg_color_hover_selector,
'declaration' => sprintf( 'background-color:%1$s%2$s;', $field_bg_color_hover, $field_bg_color_important ),
// 3.b.1. Field Focus Background Color.
$is_field_focus_bg_color_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, "{$option_name}_focus_background_color" );
$field_focus_bg_color_values = array(
'desktop' => esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_focus_background_color" ) ),
'tablet' => $is_field_focus_bg_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_focus_background_color_tablet" ) ) : '',
'phone' => $is_field_focus_bg_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_focus_background_color_phone" ) ) : '',
$field_focus_bg_color_important = $force_global_important || in_array( 'focus_background_color', $important_list, true ) ? ' !important' : '';
et_pb_responsive_options()->generate_responsive_css( $field_focus_bg_color_values, $bg_color_focus_selector, 'background-color', $function_name, $field_focus_bg_color_important, 'color' );
// 3.b.2. Field Focus Background Hover Color.
$field_focus_bg_color_hover = $this->get_hover_value("{$option_name}_focus_background_color" );
if ( ! empty( $field_focus_bg_color_hover ) ) {
self::set_style( $function_name, array(
'selector' => $bg_color_focus_hover_selector,
'declaration' => sprintf( 'background-color:%1$s%2$s;', $field_focus_bg_color_hover, $field_focus_bg_color_important ),
// 3.c.1. Field Text Color.
$is_field_text_color_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, "{$option_name}_text_color" );
$field_text_color_values = array(
'desktop' => esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_text_color" ) ),
'tablet' => $is_field_text_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_text_color_tablet" ) ) : '',
'phone' => $is_field_text_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_text_color_phone" ) ) : '',
$field_text_color_important = in_array( 'form_text_color', $important_list ) ? ' !important' : '';
$text_color_selector = $placeholder_option ? "{$text_color_selector}, {$placeholder_selector}" : $text_color_selector;
et_pb_responsive_options()->generate_responsive_css( $field_text_color_values, $text_color_selector, 'color', $function_name, $field_text_color_important, 'color' );
// 3.c.2. Field Text Color.
$field_text_color_hover = $this->get_hover_value("{$option_name}_text_color" );
if ( ! empty( $field_text_color_hover ) ) {
$text_color_hover_selector = $placeholder_option ? "{$text_color_hover_selector}, {$placeholder_hover_selector}" : $text_color_hover_selector;
self::set_style( $function_name, array(
'selector' => $text_color_hover_selector,
'declaration' => sprintf( 'color:%1$s%2$s;', $field_text_color_hover, $field_text_color_important ),
// 3.d.1. Field Focus Text Color.
$is_field_focus_text_color_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, "{$option_name}_focus_text_color" );
$field_focus_text_color_values = array(
'desktop' => esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_focus_text_color" ) ),
'tablet' => $is_field_focus_text_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_focus_text_color_tablet" ) ) : '',
'phone' => $is_field_focus_text_color_responsive ? esc_attr( et_pb_responsive_options()->get_any_value( $this->props, "{$option_name}_focus_text_color_phone" ) ) : '',
$text_color_focus_selector = $placeholder_option ? "{$text_color_focus_selector}, {$placeholder_focus_selector}" : $text_color_focus_selector;
$field_focus_text_color_important = in_array( 'form_text_color', $important_list ) ? ' !important' : '';
et_pb_responsive_options()->generate_responsive_css( $field_focus_text_color_values, $text_color_focus_selector, 'color', $function_name, $field_focus_text_color_important, 'color' );
// 3.d.2. Field Focus Text Hover Color.
$field_focus_text_color_hover = $this->get_hover_value("{$option_name}_focus_text_color" );
if ( ! empty( $field_focus_text_color_hover ) ) {
$text_color_focus_hover_selector = $placeholder_option ? "{$text_color_focus_hover_selector}, {$placeholder_focus_hover_selector}" : $text_color_focus_hover_selector;
self::set_style( $function_name, array(
'selector' => $text_color_focus_hover_selector,
'declaration' => sprintf( 'color:%1$s%2$s;', $field_focus_text_color_hover, $field_focus_text_color_important ),
function process_custom_css_fields( $function_name ) {
if ( empty( $this->custom_css_fields ) ) {
foreach ( $this->custom_css_fields as $slug => $option ) {
$css = $this->props["custom_css_{$slug}"];
$order_class = isset( $this->main_css_element ) && count( explode( ' ', $this->main_css_element ) ) === 1 ? $selector = $this->main_css_element : '%%order_class%%';
$selector = ! empty( $option['selector'] ) ? $option['selector'] : '';
if ( false === strpos( $selector, '%%order_class%%' ) ) {
if ( ! ( isset( $option['no_space_before_selector'] ) && $option['no_space_before_selector'] ) && '' !== $selector ) {
$selector = " {$selector}";
$selector = "{$order_class}{$selector}";
if ( et_pb_responsive_options()->is_responsive_enabled( $this->props, "custom_css_{$slug}" ) ) {
$responsive_values = et_pb_responsive_options()->get_property_values( $this->props, "custom_css_{$slug}" );
// Desktop mode custom CSS.
self::set_style( $function_name, array(
'declaration' => trim( $css ),
'media_query' => empty( $responsive_values['tablet'] ) ? null : ET_Builder_Element::get_media_query( 'min_width_981' ),
// Tablet mode custom CSS.
$tablet_css = et_pb_responsive_options()->get_tablet_value( "custom_css_{$slug}", $this->props );
if ( ! empty( $tablet_css ) ) {
self::set_style( $function_name, array(
'declaration' => trim( $tablet_css ),
'media_query' => empty( $responsive_values['phone'] ) ? ET_Builder_Element::get_media_query( 'max_width_980' ) : ET_Builder_Element::get_media_query( '768_980' ),
// Phone mode custom CSS.
$phone_css = et_pb_responsive_options()->get_phone_value( "custom_css_{$slug}", $this->props );
if ( ! empty( $phone_css ) ) {
self::set_style( $function_name, array(
'declaration' => trim( $phone_css ),
'media_query' => ET_Builder_Element::get_media_query( 'max_width_767' ),
// Non responsive mode custom CSS.
self::set_style( $function_name, array(
'declaration' => trim( $css ),
// Hover mode custom CSS.
if ( et_pb_hover_options()->is_enabled( "custom_css_{$slug}", $this->props ) ) {
$hover_css = et_pb_hover_options()->get_value( "custom_css_{$slug}", $this->props );
if ( ! empty( $hover_css ) ) {
self::set_style( $function_name, array(
'selector' => $this->add_hover_to_selectors( $selector ),
'declaration' => trim( $hover_css ),
* Process box shadow CSS styles.
* @since 3.23 Add responsive support. Pass device attributes and make sure no duplicate styles
* @param string $function_name Module slug.
function process_box_shadow( $function_name ) {
* @var ET_Builder_Module_Field_BoxShadow $box_shadow
$box_shadow = ET_Builder_Module_Fields_Factory::get( 'BoxShadow' );
$advanced_fields = self::$_->array_get( $this->advanced_fields, 'box_shadow', array( 'default' => array() ) );
if ( ! $advanced_fields ) {
// A module can have multiple advanced box shadow fields (i.e. default + button's box shadow) which are
// generated by advanced button fields
foreach ( $advanced_fields as $option_name => $option_settings ) {
// Enable module to explicitly disable box shadow fields (box shadow is automatically)
// added to all module by default
if ( false === $option_settings ) {
// Prepare attribute for getting box shadow's css declaration
$declaration_args = array(
'suffix' => $option_name === 'default' ? '' : "_{$option_name}",
'important' => self::$_->array_get( $option_settings, 'css.important', false ),
// Enable module to conditionally print box shadow styling if particular attribute(s) have specific value.
// This works in 'OR' logic. Once an attribute doesn't match the value, this box shadow styling is skipped
$show_if = self::$_->array_get( $option_settings, 'css.show_if', array() );
if ( ! empty( $show_if ) ) {
foreach ( $show_if as $show_if_attr_name => $show_if_attr_value ) {
$attr_value = self::$_->array_get( $this->props, $show_if_attr_name, '' );
// Skip printing this box shadow value once one of the attribute value doesn't
// match with given value
if ( $attr_value !== $show_if_attr_value ) {
// Enable module to conditionally print box shadow styling if particular attribute(s) doesn't have
// specific value. This works on 'OR' logic. Once an attribute matches the supplied value, this
// box shadow styling is skipped
$show_if_not = self::$_->array_get( $option_settings, 'css.show_if_not', array() );
if ( ! empty( $show_if_not ) ) {
$show_if_not_skip = false;
foreach ( $show_if_not as $show_if_not_attr_name => $show_if_not_attr_value ) {
$attr_value = self::$_->array_get( $this->props, $show_if_not_attr_name, '' );
// Skip printing this box value once this attribute value matches the given value
if ( $attr_value === $show_if_not_attr_value ) {
$show_if_not_skip = true;
if ( $show_if_not_skip ) {
$overlay = self::$_->array_get( $option_settings, 'css.overlay', false );
$has_video_bg = ! empty( $atts['background_video_mp4'] ) || ! empty( $atts['background_video_webm'] );
$inset = $box_shadow->is_inset( $box_shadow->get_value( $this->props, $declaration_args ) );
$inset_hover = $box_shadow->is_inset( $box_shadow->get_value(
array_merge( $declaration_args, array( 'hover' => true ) )
$selector = self::$_->array_get( $option_settings, 'css.main', '%%order_class%%' );
// Default box shadow affects module while other affects group element it belongs to (ie image, button, etc)
$hover_selector = 'default' === $option_name ? $this->add_hover_to_order_class( $selector ) : $this->add_hover_to_selectors( $selector );
// Custom box shadow hover selector.
$custom_hover = self::$_->array_get( $option_settings, 'css.hover', '' );
if ( '' !== $custom_hover ) {
$hover_selector = $custom_hover;
// Render box shadow styles for esponsive settings.
foreach( et_pb_responsive_options()->get_modes() as $device ) {
$device_declaration_args = array_merge( $declaration_args, array( 'device' => $device ) );
// Get box-shadow styles.
if ( ( $inset && 'inset' === $overlay ) || 'always' === $overlay || $has_video_bg ) {
$box_shadow_style = $box_shadow->get_overlay_style(
$box_shadow_style = $box_shadow->get_style(
// Compare current device declaration and previous declaration to avoid
// duplicate rendered styles. Or don't render if current declaration is
$declaration = isset( $box_shadow_style['declaration'] ) ? $box_shadow_style['declaration'] : '';
if ( $prev_declaration === $declaration || empty( $declaration ) ) {
$prev_declaration = $declaration;
// Set media query for tablet and phone.
if ( 'desktop' !== $device ) {
$breakpoint = 'tablet' === $device ? 'max_width_980' : 'max_width_767';
$media_query = ET_Builder_Element::get_media_query( $breakpoint );
$box_shadow_style['media_query'] = $media_query;
if ( ( $inset_hover && 'inset' == $overlay ) || 'always' == $overlay || $has_video_bg ) {
$box_shadow->get_overlay_style(
array_merge( $declaration_args, array( 'hover' => true ) )
array_merge( $declaration_args, array( 'hover' => true ) )
function make_options_filterable() {