: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$button_text_size_hover = $this->get_hover_value( "{$option_name}_text_size" );
$button_text_size_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_text_size" );
$button_text_size = isset( $button_text_size_values['desktop'] ) ? $button_text_size_values['desktop'] : '';
$button_text_size_tablet = isset( $button_text_size_values['tablet'] ) ? $button_text_size_values['tablet'] : '';
$button_text_size_phone = isset( $button_text_size_values['phone'] ) ? $button_text_size_values['phone'] : '';
$button_text_color_hover = $this->get_hover_value( "{$option_name}_text_color" );
$button_text_color_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_text_color" );
$button_text_color = isset( $button_text_color_values['desktop'] ) ? $button_text_color_values['desktop'] : '';
$button_text_color_tablet = isset( $button_text_color_values['tablet'] ) ? $button_text_color_values['tablet'] : '';
$button_text_color_phone = isset( $button_text_color_values['phone'] ) ? $button_text_color_values['phone'] : '';
$button_border_width_hover = $this->get_hover_value( "{$option_name}_border_width" );
$button_border_width_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_border_width" );
$button_border_width = isset( $button_border_width_values['desktop'] ) ? $button_border_width_values['desktop'] : '';
$button_border_width_tablet = isset( $button_border_width_values['tablet'] ) ? $button_border_width_values['tablet'] : '';
$button_border_width_phone = isset( $button_border_width_values['phone'] ) ? $button_border_width_values['phone'] : '';
$button_border_color_hover = $this->get_hover_value( "{$option_name}_border_color" );
$button_border_color_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_border_color" );
$button_border_color = isset( $button_border_color_values['desktop'] ) ? $button_border_color_values['desktop'] : '';
$button_border_color_tablet = isset( $button_border_color_values['tablet'] ) ? $button_border_color_values['tablet'] : '';
$button_border_color_phone = isset( $button_border_color_values['phone'] ) ? $button_border_color_values['phone'] : '';
$button_border_radius_hover = $this->get_hover_value( "{$option_name}_border_radius" );
$button_border_radius_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_border_radius" );
$button_border_radius = isset( $button_border_radius_values['desktop'] ) ? $button_border_radius_values['desktop'] : '';
$button_border_radius_tablet = isset( $button_border_radius_values['tablet'] ) ? $button_border_radius_values['tablet'] : '';
$button_border_radius_phone = isset( $button_border_radius_values['phone'] ) ? $button_border_radius_values['phone'] : '';
$button_font_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_font" );
$button_font = isset( $button_font_values['desktop'] ) ? $button_font_values['desktop'] : '';
$button_font_tablet = isset( $button_font_values['tablet'] ) ? $button_font_values['tablet'] : '';
$button_font_phone = isset( $button_font_values['phone'] ) ? $button_font_values['phone'] : '';
// Button Letter Spacing.
$button_letter_spacing_hover = $this->get_hover_value( "{$option_name}_letter_spacing" );
$button_letter_spacing_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_letter_spacing" );
$button_letter_spacing = isset( $button_letter_spacing_values['desktop'] ) ? $button_letter_spacing_values['desktop'] : '';
$button_letter_spacing_tablet = isset( $button_letter_spacing_values['tablet'] ) ? $button_letter_spacing_values['tablet'] : '';
$button_letter_spacing_phone = isset( $button_letter_spacing_values['phone'] ) ? $button_letter_spacing_values['phone'] : '';
$button_icon_color_hover = et_pb_hover_options()->get_value( "{$option_name}_icon_color", $this->props );
$button_icon_color_values = et_pb_responsive_options()->get_property_values( $this->props, "{$option_name}_icon_color" );
$button_icon_color = isset( $button_icon_color_values['desktop'] ) ? $button_icon_color_values['desktop'] : '';
$button_icon_color_tablet = isset( $button_icon_color_values['tablet'] ) ? $button_icon_color_values['tablet'] : '';
$button_icon_color_phone = isset( $button_icon_color_values['phone'] ) ? $button_icon_color_values['phone'] : '';
$button_icon_pseudo_selector = $button_icon_placement === 'left' ? ':before' : ':after';
$hide_icon_setting = isset( $option_settings['hide_icon'] ) ? $option_settings['hide_icon'] : false;
$hide_custom_padding_setting = isset( $option_settings['hide_custom_padding'] ) ? $option_settings['hide_custom_padding'] : false;
// If module hides the button icon settings, no need to render button icon. So, we need
// to the button_use_icon value as 'off'.
if ( $hide_icon_setting ) {
$button_use_icon = 'off';
// Specific selector needs to be explicitly defined to make button alignment works
if ( isset( $option_settings['use_alignment'] ) && $option_settings['use_alignment'] && isset( $option_settings['css'] ) && isset( $option_settings['css']['alignment'] ) ) {
$button_alignment_selector = $option_settings['css']['alignment'];
if ( '' !== $button_alignment_selector ) {
// Get button alignment responsive status.
$button_alignment_responsive_active = isset( $this->props["{$option_name}_alignment_last_edited"] ) ? et_pb_get_responsive_status( $this->props["{$option_name}_alignment_last_edited"] ) : false;
// Print styles for each devices.
foreach ( array( 'desktop', 'tablet', 'phone' ) as $device ) {
$is_desktop = 'desktop' === $device;
$button_key = ! $is_desktop ? "{$option_name}_alignment_{$device}" : "{$option_name}_alignment";
$button_alignment = $this->props["{$button_key}"];
// Ensure button alignment value is not empty.
if ( empty( $button_alignment ) ) {
$button_alignment_data = array(
'selector' => $button_alignment_selector,
'declaration' => esc_html( "text-align: {$button_alignment};" ),
// Skip tablet/phone if responsive setting is disabled.
if ( ! $button_alignment_responsive_active ) {
// Set media query for tablet/phone.
$current_media_query = 'tablet' === $device ? 'max_width_980' : 'max_width_767';
$button_alignment_data['media_query'] = ET_Builder_Element::get_media_query( $current_media_query );
self::set_style( $function_name, $button_alignment_data );
if ( 'on' === $button_custom ) {
$is_default_button_text_size = $this->_is_field_default( 'button_text_size', $button_text_size );
$is_default_button_icon_placement = $this->_is_field_default( 'button_icon_placement', $button_icon_placement );
$is_default_button_on_hover = $this->_is_field_default( 'button_on_hover', $button_on_hover );
$is_default_button_icon = $this->_is_field_default( 'button_icon', $button_icon );
$is_default_hover_placement = $is_default_button_on_hover && $is_default_button_icon_placement;
$button_text_size_processed = $is_default_button_text_size ? '20px' : et_builder_process_range_value( $button_text_size );
$button_text_size_hover_processed = strlen( $button_text_size_hover ) && $button_text_size !== $button_text_size_hover ? et_builder_process_range_value( $button_text_size_hover ) : '';
$button_border_radius_processed = '' !== $button_border_radius && 'px' !== $button_border_radius ? et_builder_process_range_value( $button_border_radius ) : '';
$button_border_radius_hover_processed = null !== $button_border_radius_hover && 'px' !== $button_border_radius_hover && $button_border_radius_hover !== $button_border_radius ? et_builder_process_range_value( $button_border_radius_hover ) : '';
$button_use_icon = '' === $button_use_icon ? 'on' : $button_use_icon;
$css_element = ! empty( $option_settings['css']['main'] ) ? $option_settings['css']['main'] : $this->main_css_element . ' .et_pb_button';
$css_element_processed = $css_element;
$is_dbp = et_builder_has_limitation( 'use_limited_main' );
if ( $is_dbp && ! empty( $option_settings['css']['limited_main'] ) ) {
$css_element_processed = $option_settings['css']['limited_main'];
} else if ( ! $is_dbp ) {
// Explicitly add '.et_pb_section' to the selector so selector splitting during prefixing
// does not incorrectly add third party classes before #et-boc.
$css_element_processed = "body #page-container .et_pb_section {$css_element}";
if ( et_builder_has_limitation('force_use_global_important') ) {
$button_border_radius_processed .= '' !== $button_border_radius_processed ? ' !important' : '';
$button_border_radius_hover_processed .= '' !== $button_border_radius_hover_processed ? ' !important' : '';
$global_use_icon_value = et_builder_option( 'all_buttons_icon' );
$main_element_styles_padding_important = 'no' === $global_use_icon_value && 'off' !== $button_use_icon;
// Check existing button custom padding on desktop before generating padding.
// If current button has custom padding, we should not set default padding,
$button_padding_name = 'et_pb_button' !== $function_name ? "{$option_name}_custom_padding" : 'custom_padding';
$button_padding_value = et_pb_responsive_options()->get_any_value( $this->props, $button_padding_name );
$button_padding_value = ! empty( $button_padding_value ) ? explode( '|', $button_padding_value ) : array();
$button_padding_right = self::$_->array_get( $button_padding_value, 1, '' );
$button_padding_left = self::$_->array_get( $button_padding_value, 3, '' );
$main_element_styles = sprintf(
'' !== $button_text_color ? sprintf( 'color:%1$s !important;', $button_text_color ) : '',
'' !== $button_border_width && 'px' !== $button_border_width ? sprintf( 'border-width:%1$s !important;', et_builder_process_range_value( $button_border_width ) ) : '',
'' !== $button_border_color ? sprintf( 'border-color:%1$s;', $button_border_color ) : '',
'' !== $button_border_radius_processed ? sprintf( 'border-radius:%1$s;', $button_border_radius_processed ) : '',
'' !== $button_letter_spacing && 'px' !== $button_letter_spacing ? sprintf( 'letter-spacing:%1$s;', et_builder_process_range_value( $button_letter_spacing ) ) : '', // #5
! $is_default_button_text_size ? sprintf( 'font-size:%1$s;', $button_text_size_processed ) : '',
'' !== $button_font ? et_builder_set_element_font( $button_font, true ) : '',
'off' === $button_on_hover && empty( $button_padding_right ) ?
sprintf( 'padding-right: %1$s%2$s;',
'left' === $button_icon_placement ? '0.7em' : '2em',
$main_element_styles_padding_important ? ' !important' : ''
'off' === $button_on_hover && empty( $button_padding_left ) ?
sprintf( 'padding-left:%1$s%2$s;',
'left' === $button_icon_placement ? '2em' : '0.7em',
$main_element_styles_padding_important ? ' !important' : ''
self::set_style( $function_name, array(
'selector' => $css_element_processed,
'declaration' => rtrim( $main_element_styles ),
// Check existing button custom padding on hover before generating padding on
// hover. If current button has custom padding on hover, we should not set
// default padding on hover, just leave it empty.
$button_padding_hover_value = et_pb_hover_options()->get_value( $button_padding_name, $this->props, '' );
$button_padding_hover_value = ! empty( $button_padding_hover_value ) ? explode( '|', $button_padding_hover_value ) : array();
$button_padding_hover_right = self::$_->array_get( $button_padding_hover_value, 1, '' );
$button_padding_hover_left = self::$_->array_get( $button_padding_hover_value, 3, '' );
$on_hover_padding_right = ! empty( $button_padding_hover_right ) ? '' : sprintf( 'padding-right: %1$s%2$s;',
'left' === $button_icon_placement ? '0.7em' : '2em',
$main_element_styles_padding_important ? ' !important' : ''
$on_hover_padding_left = ! empty( $button_padding_hover_left ) ? '' : sprintf( 'padding-left: %1$s%2$s;',
'left' === $button_icon_placement ? '2em' : '0.7em',
$main_element_styles_padding_important ? ' !important' : ''
// if button has default icon position or disabled globally and not enabled in module then no padding css should be generated.
$on_hover_padding = $is_default_button_icon_placement || ('default' === $button_use_icon && 'no' === $global_use_icon_value)
// Avoid adding useless style when value equals its default
$button_letter_spacing_hover = $this->_is_field_default( $hover->get_hover_field( 'button_letter_spacing' ), $button_letter_spacing_hover) ? '' : $button_letter_spacing_hover;
$main_element_styles_hover = sprintf(
! empty( $button_text_color_hover ) ? sprintf( 'color:%1$s !important;', $button_text_color_hover ) : '',
! empty( $button_border_color_hover ) ? sprintf( 'border-color:%1$s !important;', $button_border_color_hover ) : '',
'' !== $button_border_radius_hover_processed ? sprintf( 'border-radius:%1$s;', $button_border_radius_hover_processed ) : '',
! empty( $button_letter_spacing_hover ) && 'px' !== $button_letter_spacing_hover && $button_letter_spacing_hover !== $button_letter_spacing ? sprintf( 'letter-spacing:%1$s;', et_builder_process_range_value( $button_letter_spacing_hover ) ) : '',
'off' === $button_on_hover || $hide_custom_padding_setting ? '' : $on_hover_padding,
'' !== $button_text_size_hover_processed ? sprintf( 'font-size:%1$s !important;', $button_text_size_hover_processed ) : '',
! empty( $button_border_width_hover ) ? sprintf( 'border-width:%1$s !important;', $button_border_width_hover ) : ''
$main_element_styles_hover_declaration = rtrim( $main_element_styles_hover );
if ( $main_element_styles_hover_declaration ) {
self::set_style( $function_name, array(
'selector' => $css_element_processed . ':hover',
'declaration' => $main_element_styles_hover_declaration,
$main_element_styles_after_hover = '';
if ( 'off' === $button_use_icon ) {
$main_element_styles_after = 'display:none !important;';
$selector = sprintf( '%1$s:before, %1$s:after', $css_element_processed );
// Check button custom padding. Prepend option name to get the correct padding.
$custom_padding = self::$_->array_get( $this->props, 'custom_padding', '' );
if ( 'et_pb_button' !== $function_name ) {
$custom_padding = self::$_->array_get( $this->props, "{$option_name}_custom_padding", '' );
if ( empty( $custom_padding ) ) {
$no_icon_styles .= 'padding: 0.3em 1em !important;';
$padding_array = explode( '|', $custom_padding );
if ( empty( $padding_array[1] ) ) {
$no_icon_styles .= 'padding-right: 1em !important;';
if ( empty( $padding_array[3] ) ) {
$no_icon_styles .= 'padding-left: 1em !important;';
// No need to print custom padding if custom padding setting is disabled.
if ( ! empty( $no_icon_styles ) && ! $hide_custom_padding_setting ) {
self::set_style( $function_name, array(
'selector' => $css_element_processed . ',' . $css_element_processed . ':hover',
'declaration' => rtrim( $no_icon_styles ),
$button_icon_code = '' !== $button_icon ? str_replace( ';', '', str_replace( '&#x', '', html_entity_decode( et_pb_process_font_icon( $button_icon ) ) ) ) : '';
$main_element_styles_after = sprintf(
'' !== $button_icon_color ? sprintf( 'color:%1$s;', $button_icon_color ) : '',
'' !== $button_icon_code ? 'line-height: inherit;' : '',
'' !== $button_icon_code ? 'font-size: inherit !important;' : '',
$is_default_hover_placement ? '' : sprintf( 'opacity:%1$s;', 'off' !== $button_on_hover ? '0' : '1' ),
'off' !== $button_on_hover && '' !== $button_icon_code ?
sprintf( 'margin-left: %1$s; %2$s: auto;',
'left' === $button_icon_placement ? '-1.3em' : '-1em',
'left' === $button_icon_placement ? 'right' : 'left'
'off' === $button_on_hover ?
sprintf( 'margin-left: %1$s; %2$s:auto;',
'left' === $button_icon_placement ? '-1.3em' : '.3em',
'left' === $button_icon_placement ? 'right' : 'left'
( ! $is_default_button_icon_placement && in_array( $button_use_icon , array( 'default', 'on' ) ) ? 'display: inline-block;' : '' )
if ( ! empty( $button_icon_color_hover ) && $button_icon_color_hover !== $button_icon_color ) {
$main_element_styles_after_hover = sprintf( 'color: %1$s', $button_icon_color_hover );
if ( 'left' === $button_icon_placement ) {
$button_icon_left_content = '' !== $button_icon_code ? 'content: attr(data-icon);' : '';
self::set_style( $function_name, array(
'selector' => $css_element_processed . ':after',
'declaration' => 'display: none;',
if ( et_builder_has_limitation('use_additional_limiting_styles') ) {
self::set_style( $function_name, array(
'selector' => '.et_pb_row ' . $css_element_processed . ':hover',
'declaration' => 'padding-right: 1em; padding-left: 2em;',
self::set_style( $function_name, array(
'selector' => $css_element_processed . ':before',
'declaration' => $button_icon_left_content . ' ; font-family: "ETmodules" !important;',
// if button has default icon/hover/placement and disabled globally or not enabled in module then no :after:hover css should be generated.
if ( ! ( $is_default_button_icon && $is_default_hover_placement ) &&
( 'default' !== $button_use_icon || 'no' !== $global_use_icon_value ) ) {
$hover_after_styles = sprintf(
'' !== $button_icon_code ?
sprintf( 'margin-left:%1$s;', '35' !== $button_icon_code ? '.3em' : '0' )
'' !== $button_icon_code ?
sprintf( '%1$s: auto; margin-left: %2$s;',
'left' === $button_icon_placement ? 'right' : 'left',
'left' === $button_icon_placement ? '-1.3em' : '.3em'
'off' !== $button_on_hover ? 'opacity: 1;' : ''
self::set_style( $function_name, array(
'selector' => $css_element_processed . ':hover' . $button_icon_pseudo_selector,
'declaration' => rtrim( $hover_after_styles ),
if ( '' === $button_icon && ! $is_default_button_text_size ) {
$default_icons_size = '1.6em';
$custom_icon_size = $button_text_size_processed;
self::set_style( $function_name, array(
'selector' => $css_element_processed . $button_icon_pseudo_selector,
'declaration' => sprintf( 'font-size:%1$s;', $default_icons_size ),
self::set_style( $function_name, array(
'selector' => 'body.et_button_custom_icon #page-container ' . $css_element . $button_icon_pseudo_selector,
'declaration' => sprintf( 'font-size:%1$s;', $custom_icon_size ),
if ( '' === $button_icon && '' !== $button_text_size_hover_processed ) {
$default_icons_size = '1.6em';
$custom_icon_size = $button_text_size_hover_processed;
self::set_style( $function_name, array(
'selector' => $css_element_processed . ':hover' . $button_icon_pseudo_selector,
'declaration' => sprintf( 'font-size:%1$s;', $default_icons_size ),
self::set_style( $function_name, array(
'selector' => 'body.et_button_custom_icon #page-container ' . $css_element . ':hover' . $button_icon_pseudo_selector,
'declaration' => sprintf( 'font-size:%1$s;', $custom_icon_size ),
$selector = $css_element_processed . $button_icon_pseudo_selector;
self::set_style( $function_name, array(
'declaration' => rtrim( $main_element_styles_after ),
self::set_style( $function_name, array(
'selector' => et_pb_hover_options()->add_hover_to_selectors( $selector ),
'declaration' => rtrim( $main_element_styles_after_hover ),
// Responsive Button Styles.
$prev_icon = $button_icon;
foreach( array( 'tablet', 'phone' ) as $device ) {
$current_media_query = 'tablet' === $device ? 'max_width_980' : 'max_width_767';
$current_text_size = 'tablet' === $device ? $button_text_size_tablet : $button_text_size_phone;
$current_text_size = '' !== $current_text_size ? et_builder_process_range_value( $current_text_size ) : '';
$current_text_color = 'tablet' === $device ? $button_text_color_tablet : $button_text_color_phone;
$current_border_width = 'tablet' === $device ? $button_border_width_tablet : $button_border_width_phone;
$current_border_width = '' !== $current_border_width ? et_builder_process_range_value( $current_border_width ) : '';
$current_border_color = 'tablet' === $device ? $button_border_color_tablet : $button_border_color_phone;
$current_border_radius = 'tablet' === $device ? $button_border_radius_tablet : $button_border_radius_phone;
$current_border_radius = '' !== $current_border_radius ? et_builder_process_range_value( $current_border_radius ) : '';
$current_letter_spacing = 'tablet' === $device ? $button_letter_spacing_tablet : $button_letter_spacing_phone;
$current_letter_spacing = '' !== $current_letter_spacing ? et_builder_process_range_value( $current_letter_spacing ) : '';
$current_font = 'tablet' === $device ? $button_font_tablet : $button_font_phone;
$current_icon_color = 'tablet' === $device ? $button_icon_color_tablet : $button_icon_color_phone;
// The attributes below should inherit larger device.
$current_icon = et_pb_responsive_options()->get_property_value( $this->props, "{$option_name}_icon", $button_icon, $device, true );
$current_icon_placement = et_pb_responsive_options()->get_property_value( $this->props, "{$option_name}_icon_placement", $button_icon_placement, $device, true );
$current_on_hover = et_pb_responsive_options()->get_property_value( $this->props, "{$option_name}_on_hover", $button_on_hover, $device, true );
$is_default_hover_placement = '' === $current_on_hover && '' === $current_icon_placement;
$button_icon_pseudo_selector = 'left' === $current_icon_placement ? ':before' : ':after';
// Force to have important tag.
if ( et_builder_has_limitation('force_use_global_important') ) {
$current_border_radius .= '' !== $current_border_radius ? ' !important' : '';
// Get right and left custom padding value. The reset padding should not
// be applied if current button has custom padding defined.
$current_padding_name = et_pb_responsive_options()->get_field_name( $button_padding_name, $device );
$current_padding_value = et_pb_responsive_options()->get_any_value( $this->props, $current_padding_name, '', true );
$current_padding_value = ! empty( $current_padding_value ) ? explode( '|', $current_padding_value ) : array();
$current_padding_default = et_pb_responsive_options()->get_default_value( $this->props, $current_padding_name );
$current_padding_default = ! empty( $current_padding_default ) ? explode( '|', $current_padding_default ) : array();
$current_padding_right = self::$_->array_get( $current_padding_value, 1, '' );
$current_padding_left = self::$_->array_get( $current_padding_value, 3, '' );
$current_padding_default_right = self::$_->array_get( $current_padding_default, 1, '' );
$current_padding_default_left = self::$_->array_get( $current_padding_default, 3, '' );
// Reset responsive padding right. Only reset padding if current device
// doesn't have value and the previous device has value to be reset.
$responsive_padding_right = '';
$responsive_hover_padding_right = '';
if ( empty( $current_padding_right ) && ! empty( $current_padding_default_right ) ) {
// Default padding for normal and hover.
$responsive_padding_right = '1em';
// If padding hover right deosn't exist, add default padding for hover.
if ( empty( $button_padding_hover_right ) ) {
$responsive_hover_padding_right = 'left' === $current_icon_placement ? '2em' : '0.7em';
// If icon on hover is disabled, set padding value like hover state
// and remove padding for hover because it's same.
if ( 'off' === $current_on_hover ) {
$responsive_padding_right = 'left' === $current_icon_placement ? '2em' : '0.7em';
$responsive_hover_padding_right = '';
// Reset responsive padding left. Only reset padding if current device
// doesn't have value and the previous device has value to be reset.
$responsive_padding_left = '';
$responsive_hover_padding_left = '';
if ( empty( $current_padding_left ) && ! empty( $current_padding_default_left ) ) {
// Default padding for normal and hover.
$responsive_padding_left = '1em';
// If padding hover left deosn't exist, add default padding for hover.
if ( empty( $button_padding_hover_left ) ) {
$responsive_hover_padding_left = 'left' === $current_icon_placement ? '2em' : '0.7em';
// If icon on hover is disabled, set padding value like hover state
// and remove padding for hover because it's same.
if ( 'off' === $current_on_hover ) {
$responsive_padding_left = 'left' === $current_icon_placement ? '0.7em' : '2em';
$responsive_hover_padding_left = '';
// Remove responsive on hover padding left & right.
if ( '' === $current_icon_placement || ( 'default' === $button_use_icon && 'no' === $global_use_icon_value ) || $hide_custom_padding_setting ) {
$responsive_hover_padding_left = '';
$responsive_hover_padding_right = '';
// Responsive button declaration.
$responsive_button_declaration = trim( sprintf(