: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if ( $is_background_image_active ) {
// Flag to inform BG Color if current module has Image.
$has_background_image = true;
// Check previous BG image status. Needed to get the correct value.
$is_prev_background_image_active = true;
$is_prev_background_image_active = 'tablet' === $device ? $background_image_status['desktop'] : $background_image_status['tablet'];
$background_size_default = self::$_->array_get( $this->fields_unprocessed, 'background_size.default', '' );
$background_size = et_pb_responsive_options()->get_any_value( $this->props, "background_size{$suffix}", $background_size_default, ! $is_prev_background_image_active );
if ( '' !== $background_size ) {
'background-size: %1$s; ',
esc_html( $background_size )
$background_position_default = self::$_->array_get( $this->fields_unprocessed, 'background_position.default', '' );
$background_position = et_pb_responsive_options()->get_any_value( $this->props, "background_position{$suffix}", $background_position_default, ! $is_prev_background_image_active );
if ( '' !== $background_position ) {
'background-position: %1$s; ',
esc_html( str_replace( '_', ' ', $background_position ) )
$background_repeat_default = self::$_->array_get( $this->fields_unprocessed, 'background_repeat.default', '' );
$background_repeat = et_pb_responsive_options()->get_any_value( $this->props, "background_repeat{$suffix}", $background_repeat_default, ! $is_prev_background_image_active );
if ( '' !== $background_repeat ) {
'background-repeat: %1$s; ',
esc_html( $background_repeat )
$background_blend_default = self::$_->array_get( $this->fields_unprocessed, 'background_blend.default', '' );
$background_blend = et_pb_responsive_options()->get_any_value( $this->props, "background_blend{$suffix}", $background_blend_default, ! $is_prev_background_image_active );
$background_blend_inherit = et_pb_responsive_options()->get_any_value( $this->props, "background_blend{$suffix}", '', true );
if ( '' !== $background_blend_inherit ) {
// Don't print the same image blend style.
if ( '' !== $background_blend ) {
'background-blend-mode: %1$s; ',
esc_html( $background_blend )
// Reset - If background has image and gradient, force background-color: initial.
if ( $has_background_color_gradient && $has_background_image && $use_background_color_reset_options !== 'fields_only' && $background_blend_inherit !== $background_blend_default ) {
$has_background_gradient_and_image = true;
$background_color_style = 'initial';
$style .= sprintf( 'background-color: initial%1$s; ', esc_html( $important ) );
$processed_background_blend = $background_blend;
// Only append background image when the image is exist.
$background_images[] = sprintf( 'url(%1$s)', esc_html( $background_image ) );
} else if ( '' === $background_image ) {
// Reset - If background image is disabled, ensure we reset prev background blend mode.
if ( '' !== $processed_background_blend ) {
$style .= 'background-blend-mode: normal; ';
$processed_background_blend = '';
$is_background_image_disabled = true;
if ( ! empty( $background_images ) ) {
// The browsers stack the images in the opposite order to what you'd expect.
if ( 'on' !== $background_color_gradient_overlays_image ) {
$background_images = array_reverse( $background_images );
// Save gradient setting into property for later usage
if ( $this->save_processed_background ) {
et_()->array_set( $this->processed_background, "{$device}.gradient_overlays_image", true );
// Set background image styles only it's different compared to the larger device.
$background_image_style = join( ', ', $background_images );
if ( $processed_background_image !== $background_image_style ) {
'background-image: %1$s%2$s;',
esc_html( $background_image_style ),
} else if ( ! $is_desktop && $is_background_color_gradient_disabled && $is_background_image_disabled ) {
// Reset - If background image and gradient are disabled, reset current background image.
$background_image_style = 'initial';
'background-image: %1$s%2$s;',
esc_html( $background_image_style ),
// Save processed background images.
$processed_background_image = $background_image_style;
if ( $use_background_color_options && 'fields_only' !== $use_background_color_options ) {
$use_background_color_value = et_pb_responsive_options()->get_any_value( $this->props, "use_background_color{$suffix}", 'on', true );
if ( ! $has_background_gradient_and_image && 'off' !== $use_background_color_value ) {
$background_color = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'background_color', $device, 'background', $this->fields_unprocessed );
$background_color = ! $is_desktop && '' === $background_color ? 'initial' : $background_color;
$background_color_style = $background_color;
if ( '' !== $background_color && $processed_background_color !== $background_color ) {
'background-color: %1$s%2$s; ',
esc_html( $background_color ),
// If text module has background color set position to relative, as opposed to set text module as relative by default.
// Changing background selector to point to et_pb_text_inner will not render background correctly
// If position options are set they will override this value.
if ( 'et_pb_text' === $function_name ) {
$style .= 'position: relative; ';
} else if ( $has_background_color_toggle_options && 'off' === $use_background_color_value && ! $is_desktop ) {
// Reset - If current module has background color toggle, it's off, and current mode
// it's not desktop, we should reset the background color.
'background-color: initial %1$s; ',
// Save processed background color.
$processed_background_color = $background_color_style;
// Render background styles.
// Add media query parameter.
$background_args = array();
$current_media_query = 'tablet' === $device ? 'max_width_980' : 'max_width_767';
$background_args['media_query'] = ET_Builder_Element::get_media_query( $current_media_query );
$css_element = ! empty( $settings['css']['main'] ) ? $settings['css']['main'] : $this->main_css_element;
self::set_style( $function_name, wp_parse_args( $background_args, array(
'selector' => $css_element,
'declaration' => rtrim( $style ),
'priority' => $this->_style_priority,
if ( et_builder_is_hover_enabled( 'background', $this->props ) ) {
$background_images_hover = array();
$has_background_color_gradient_hover = false;
$has_background_image_hover = false;
$has_background_gradient_and_image_hover = false;
$is_background_color_gradient_hover_disabled = false;
$is_background_image_hover_disabled = false;
$background_color_gradient_overlays_image_hover = 'off';
// Background Gradient Hover.
// This part is little bit different compared to other hover implementation. In this case,
// hover is enabled on the background field, not on the each of those fields. So, built
// in function get_value() doesn't work in this case. Temporarily, we need to fetch the
// the value from get_raw_value().
if ( $use_background_color_gradient_options && 'fields_only' !== $use_background_color_gradient_options ) {
$use_background_color_gradient_hover = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'use_background_color_gradient', 'hover', 'background', $this->fields_unprocessed );
// 1. Ensure gradient color is active and values are not null.
if ( 'on' === $use_background_color_gradient_hover ) {
// Desktop value as default.
$background_color_gradient_type_desktop = self::$_->array_get( $gradient_properties_desktop, 'type', '' );
$background_color_gradient_direction_desktop = self::$_->array_get( $gradient_properties_desktop, 'direction', '' );
$background_color_gradient_radial_direction_desktop = self::$_->array_get( $gradient_properties_desktop, 'radial_direction', '' );
$background_color_gradient_color_start_desktop = self::$_->array_get( $gradient_properties_desktop, 'color_start', '' );
$background_color_gradient_color_end_desktop = self::$_->array_get( $gradient_properties_desktop, 'color_end', '' );
$background_color_gradient_start_position_desktop = self::$_->array_get( $gradient_properties_desktop, 'start_position', '' );
$background_color_gradient_end_position_desktop = self::$_->array_get( $gradient_properties_desktop, 'end_position', '' );
$background_color_gradient_type_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_type', $this->props, $background_color_gradient_type_desktop );
$background_color_gradient_direction_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_direction', $this->props, $background_color_gradient_direction_desktop );
$background_color_gradient_direction_radial_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_direction_radial', $this->props, $background_color_gradient_radial_direction_desktop );
$background_color_gradient_start_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_start', $this->props, $background_color_gradient_color_start_desktop );
$background_color_gradient_end_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_end', $this->props, $background_color_gradient_color_end_desktop );
$background_color_gradient_start_position_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_start_position', $this->props, $background_color_gradient_start_position_desktop );
$background_color_gradient_end_position_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_end_position', $this->props, $background_color_gradient_end_position_desktop );
$background_color_gradient_overlays_image_hover = et_pb_hover_options()->get_raw_value( 'background_color_gradient_overlays_image', $this->props, $background_color_gradient_overlays_image_desktop );
// Flag to inform BG Color if current module has Gradient.
$has_background_color_gradient_hover = true;
$gradient_values_hover = array(
'type' => '' !== $background_color_gradient_type_hover ? $background_color_gradient_type_hover : $background_color_gradient_type_desktop,
'direction' => '' !== $background_color_gradient_direction_hover ? $background_color_gradient_direction_hover : $background_color_gradient_direction_desktop,
'radial_direction' => '' !== $background_color_gradient_direction_radial_hover ? $background_color_gradient_direction_radial_hover : $background_color_gradient_radial_direction_desktop,
'color_start' => '' !== $background_color_gradient_start_hover ? $background_color_gradient_start_hover : $background_color_gradient_color_start_desktop,
'color_end' => '' !== $background_color_gradient_end_hover ? $background_color_gradient_end_hover : $background_color_gradient_color_end_desktop,
'start_position' => '' !== $background_color_gradient_start_position_hover ? $background_color_gradient_start_position_hover : $background_color_gradient_start_position_desktop,
'end_position' => '' !== $background_color_gradient_end_position_hover ? $background_color_gradient_end_position_hover : $background_color_gradient_end_position_desktop,
$background_gradient_hover = $this->get_gradient( $gradient_values_hover );
$background_images_hover[] = $background_gradient_hover;
// Save resulted gradient into property for later usage
if ( $this->save_processed_background ) {
et_()->array_set( $this->processed_background, "hover.gradient", $background_gradient_hover );
} else if ( 'off' === $use_background_color_gradient_hover ) {
$is_background_color_gradient_hover_disabled = true;
// Background Image Hover.
// This part is little bit different compared to other hover implementation. In this case,
// hover is enabled on the background field, not on the each of those fields. So, built
// in function get_value() doesn't work in this case. Temporarily, we need to fetch the
// the value from get_raw_value().
if ( $use_background_image_options && 'fields_only' !== $use_background_image_options ) {
$background_image_hover = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'background_image', 'hover', 'background', $this->fields_unprocessed );
$parallax_hover = et_pb_hover_options()->get_raw_value( 'parallax', $this->props );
// Featured image as background is in higher priority.
if ( $this->featured_image_background ) {
$featured_image = self::$_->array_get( $this->props, 'featured_image', '' );
$featured_placement = self::$_->array_get( $this->props, 'featured_placement', '' );
$featured_image_src_obj = wp_get_attachment_image_src( get_post_thumbnail_id( self::_get_main_post_id() ), 'full' );
$featured_image_src = isset( $featured_image_src_obj[0] ) ? $featured_image_src_obj[0] : '';
if ( 'on' === $featured_image && 'background' === $featured_placement && '' !== $featured_image_src ) {
$background_image = $featured_image_src;
if ( '' !== $background_image_hover && null !== $background_image_hover && 'on' !== $parallax_hover ) {
// Flag to inform BG Color if current module has Image.
$has_background_image_hover = true;
$background_size_hover = et_pb_hover_options()->get_raw_value( 'background_size', $this->props );
$background_size_desktop = self::$_->array_get( $this->props, 'background_size', '' );
$is_same_background_size = $background_size_hover === $background_size_desktop;
if ( empty( $background_size_hover ) && ! empty( $background_size_desktop ) ) {
$background_size_hover = $background_size_desktop;
if ( ! empty( $background_size_hover ) && ! $is_same_background_size ) {
'background-size: %1$s; ',
esc_html( $background_size_hover )
$background_position_hover = et_pb_hover_options()->get_raw_value( 'background_position', $this->props );
$background_position_desktop = self::$_->array_get( $this->props, 'background_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-position: %1$s; ',
esc_html( str_replace( '_', ' ', $background_position_hover ) )
$background_repeat_hover = et_pb_hover_options()->get_raw_value( 'background_repeat', $this->props );
$background_repeat_desktop = self::$_->array_get( $this->props, 'background_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-repeat: %1$s; ',
esc_html( $background_repeat_hover )
$background_blend_hover = et_pb_hover_options()->get_raw_value( 'background_blend', $this->props );
$background_blend_default = self::$_->array_get( $this->fields_unprocessed, 'background_blend.default', '' );
$background_blend_desktop = self::$_->array_get( $this->props, 'background_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 ) ) {
// Don't print the same background blend.
if ( ! $is_same_background_blend ) {
'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;
$style_hover .= sprintf( 'background-color: initial%1$s; ', esc_html( $important ) );
// Only append background image when the image is exist.
$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 );
// Save gradient setting into property for later usage
if ( $this->save_processed_background ) {
et_()->array_set( $this->processed_background, "hover.gradient_overlays_image", true );
'background-image: %1$s%2$s;',
esc_html( join( ', ', $background_images_hover ) ),
} else if ( $is_background_color_gradient_hover_disabled && $is_background_image_hover_disabled ) {
'background-image: initial %1$s;',
// Background Color Hover.
if ( $use_background_color_options && 'fields_only' !== $use_background_color_options ) {
$use_background_color_hover_value = self::$_->array_get( $this->props, 'use_background_color__hover', '' );
$use_background_color_hover_value = ! empty( $use_background_color_hover_value ) ? $use_background_color_hover_value : self::$_->array_get( $this->props, 'use_background_color', 'on' );
if ( ! $has_background_gradient_and_image_hover && 'off' !== $use_background_color_hover_value ) {
$background_color_hover = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'background_color', 'hover', 'background', $this->fields_unprocessed );
$background_color_hover = '' !== $background_color_hover ? $background_color_hover : 'transparent';
if ( '' !== $background_color_hover ) {
'background-color: %1$s%2$s; ',
esc_html( $background_color_hover ),
} else if ( $has_background_color_toggle_options && 'off' === $use_background_color_hover_value ) {
// Reset - If current module has background color toggle, it's off, and current mode
// it's not desktop, we should reset the background color.
'background-color: initial %1$s; ',
// Render background hover styles.
if ( '' !== $style_hover ) {
$css_element_main = self::$_->array_get( $settings, 'css.main', $this->main_css_element );
$css_element_hover = self::$_->array_get( $settings, 'css.hover', et_pb_hover_options()->add_hover_to_order_class( $css_element_main ) );
self::set_style( $function_name, array(
'selector' => $css_element_hover,
'declaration' => rtrim( $style_hover ),
'priority' => $this->_style_priority,
* Process advanced text options.
* @since 3.23 Add support to generate responsive styles of text orientation.
* @param string $function_name Module slug.
function process_advanced_text_options( $function_name ) {
// Disable if module doesn't set advanced_fields property and has no VB support
if ( ! $this->has_vb_support() && ! $this->has_advanced_fields ) {
if ( ! self::$_->array_get( $this->advanced_fields, 'text', false ) ) {
$text_options = $this->advanced_fields['text'];
if ( isset( $text_options['css'] ) && is_array( $text_options['css'] ) ) {
$text_css = $text_options['css'];
$text_orientation_default = isset( $this->fields_unprocessed['text_orientation']['default'] ) ? $this->fields_unprocessed['text_orientation']['default'] : '';
$text_orientation = $this->get_text_orientation() !== $text_orientation_default ? $this->get_text_orientation() : '';
$text_orientation_tablet = $this->get_text_orientation( 'tablet', $text_orientation_default );
$text_orientation_phone = $this->get_text_orientation( 'phone', $text_orientation_default );
// Normally, text orientation attr adds et_pb_text_align_* class name to its module wrapper
// In some cases, it needs to target particular children inside the module. Thus, only prints
// styling if selector is given
if ( isset( $text_css['text_orientation'] ) ) {
$text_orientation_values = array(
'desktop' => esc_attr( $text_orientation ),
'tablet' => esc_attr( $text_orientation_tablet ),
'phone' => esc_attr( $text_orientation_phone ),
et_pb_responsive_options()->generate_responsive_css( $text_orientation_values, $text_css['text_orientation'], 'text-align', $function_name, '', 'alignment', $this->_style_priority );
* Output border and border radius styling
* @since 3.23 Add support to generate responsive styles of border styles and radii.]
function process_advanced_borders_options( $function_name ) {
// Disable if module doesn't set advanced_fields property and has no VB support
if ( ! $this->has_vb_support() && ! $this->has_advanced_fields ) {
global $et_fb_processing_shortcode_object;
$borders = self::$_->array_get( $this->advanced_fields, 'borders', array( 'default' => array() ) );
$border_field = ET_Builder_Module_Fields_Factory::get( 'Border' );
if ( is_array( $borders ) && ! empty( $borders ) ) {
foreach ( $borders as $border_name => $border ) {
// Enable module to disable border options
if ( false === $border ) {
// Blurb image specific adjustment
if ( 'image' === $border_name && 'et_pb_blurb' === $this->slug && 'on' === self::$_->array_get( $this->props, 'use_icon' ) ) {
// Blog specific adjustment
if ( 'fullwidth' === $border_name && 'et_pb_blog' === $this->slug && 'on' !== self::$_->array_get( $this->props, 'fullwidth' ) ) {
// Login & signup specific adjustment
if ( 'fields_focus' === $border_name && in_array( $this->slug, array( 'et_pb_login', 'et_pb_signup' ) ) && 'on' !== self::$_->array_get( $this->props, 'use_focus_border_color' ) ) {
// Check field visibility against its dependency
if ( ! $this->_is_field_applicable( $border ) ) {
$is_border_default = 'default' === $border_name;
$suffix = $is_border_default ? '' : "_{$border_name}";
if ( $is_border_default && $this->slug !== $function_name ) {
// This module's shortcode callback is being used to render another module (like accordion item
// uses toggle ) so we need to make sure border option overrides are taken from the other module
$fields = self::get_advanced_fields( $this->get_post_type(), 'all', $function_name );
$border = self::$_->array_get( $fields, 'advanced_common.border', array() );
// Backward compatibility. For 3rd party modules which define `_add_additional_border_fields` and do not have `process_advanced_border_options`