: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
public function get_composite_property_values( $attrs, $composite_name, $name, $default_value = '', $force_return = false ) {
$default_value = esc_attr( $default_value );
'desktop' => $default_value,
'tablet' => $default_value,
'phone' => $default_value,
// Ensure attrs, composite name (parent property name), name (property name) are not empty.
if ( empty( $attrs ) || '' === $composite_name || '' === $name ) {
$is_responsive = $this->is_responsive_enabled( $attrs, $composite_name );
// Get values for each devices.
$values['desktop'] = esc_attr( $this->get_any_value( $attrs, $name, $default_value, $force_return ) );
$values['tablet'] = esc_attr( $this->get_any_value( $attrs, "{$name}_tablet", $default_value, $force_return ) );
$values['phone'] = esc_attr( $this->get_any_value( $attrs, "{$name}_phone", $default_value, $force_return ) );
* Get multiple attributes value from current active device.
* Basically, this function is combination of:
* - Get any value of attribute
* - Check attribute responsive status for tablet/phone
* - Only send non empty attributes, except you force to return any given value
* - Doing all of the process above for more than one fields
* @param array $attrs All module attributes.
* @param string $list List of options name. Name should be field base name.
* @param bool $force_return Force to return any value.
* @param string $device Current device name.
* @return array All option values.
public function get_any_responsive_values( $attrs, $list, $force_return = false, $device = 'desktop' ) {
// Ensure list is not empty and valid array.
if ( empty( $list ) || ! is_array( $list ) ) {
// Ensure device is not empty.
$device = '' === $device ? 'desktop' : $device;
// Fetch each attribute and store it in $values.
foreach ( $list as $field_key => $field_value ) {
// Check responsive status if current device is tablet or phone.
if ( 'desktop' !== $device && ! $this->is_responsive_enabled( $attrs, $field_key ) ) {
$value = $this->get_any_value( $attrs, $field_key, $field_value, $force_return, $device );
// No need to save the value if it's empty and we don't force to return any value.
if ( ! $force_return && empty( $value ) ) {
$values[ $field_key ] = $value;
* Get default value of active device. Mechanism:
* - Desktop => Return default value.
* - Tablet => Return desktop value or default value.
* - Phone => Return tablet value or desktop value or default value.
* @param array $attrs All module attributes.
* @param string $name Option name.
* @param array $default_value All module advanced defaults.
* @return mixed Previous option value based on active device.
public function get_default_value( $attrs, $name = '', $default_value = '' ) {
$base_name = $this->get_field_base_name( $name );
$device = $this->get_device_name( $name );
// Get default value and return it for Desktop.
if ( 'desktop' === $device ) {
// Get tablet value and return it for Tablet.
$desktop_value = $this->get( $attrs, "{$base_name}", $default_value, true );
if ( 'tablet' === $device ) {
// Get phone value and return it for Phone.
$tablet_value = $this->get( $attrs, "{$base_name}_tablet", $desktop_value, true );
if ( 'phone' === $device ) {
* Returns responsive modes list from largest to narrow
public function get_modes() {
return array( self::DESKTOP, self::TABLET, self::PHONE );
* Returns next wider mode then provided
public function get_wider_mode( $mode ) {
$modes = $this->get_modes();
$key = array_search( $this->validate_mode( $mode ), $modes );
return false != $key ? et_()->array_get( $modes, '[' . ( -- $key ) . ']', null ) : null;
* Returns next narrower mode then provided
public function get_narrower_mode( $mode ) {
$modes = $this->get_modes();
$key = array_search( $this->validate_mode( $mode ), $modes );
return false !== $key && isset( $modes[ $key + 1 ] ) ? $modes[ $key + 1 ] : null;
* Return default responsive mode
public function get_default_mode() {
* Returns setting field name by responsive mode
public function get_field( $setting, $mode ) {
return $setting . $this->mode_field( (string) $this->validate_mode( $mode ) );
* Returns setting field name of the last edited mode
public function get_last_edited_field( $setting ) {
return "{$setting}_last_edited";
* Checks if setting responsive mode is enabled
public function is_enabled( $setting, $props ) {
$value = et_builder_module_prop( $this->get_last_edited_field( $this->get_field_base_name( $setting ) ), $props, '' );
return et_pb_get_responsive_status( $value );
* Returns the props value by mode
* If no mode provided, the default mode is used
public function get_value( $setting, $props, $mode = null, $default = '' ) {
$mode = $this->get_mode_or_default( $mode );
if ( $this->get_default_mode() != $mode && ! $this->is_enabled( $setting, $props ) ) {
return et_builder_module_prop( $this->get_field( $setting, $mode ), $props, $default );
* Is the implementation of get_value specifically for desktop mode
* Note: since the desktop mode is the default mode,
* this method would similar to get_value without providing mode,
* but can be used for a more explicit representation
public function get_desktop_value( $setting, $props, $default = null ) {
return $this->get_value( $setting, $props, self::DESKTOP, $default );
* Is the implementation of get_value specifically for tablet mode
public function get_tablet_value( $setting, $props, $default = null ) {
return $this->get_value( $setting, $props, self::TABLET, $default );
* Is the implementation of get_value specifically for phone mode
public function get_phone_value( $setting, $props, $default = null ) {
return $this->get_value( $setting, $props, self::PHONE, $default );
* Returns the last edited responsive mode of the provided setting
* If not valid value is provided, default mode is returned
public function get_last_edited( $setting, $props ) {
$value = et_builder_module_prop( $this->get_last_edited_field( $setting ), $props, '' );
$mode = et_()->array_get( explode( '|', $value ), '[1]' );
return $this->validate_mode( $mode ) ? $mode : $this->get_default_mode();
* Get breakpoint minimum widths
public function get_breakpoint_min_widths() {
* Get breakpoint based on device name.
public function get_breakpoint_by_device( $device = 'desktop' ) {
case 'desktop_tablet_only' :
protected function validate_mode( $mode ) {
return in_array( strtolower( $mode ), $this->get_modes() ) ? strtolower( $mode ) : false;
protected function get_mode_or_default( $mode ) {
return $this->validate_mode( $mode ) ? strtolower( $mode ) : $this->get_default_mode();
* The default mode suffix is empty
protected function mode_field( $mode ) {
case $this->get_default_mode() :
* Generates the css code for responsive options.
* Uses array of values for each device as input parameter and css_selector with property to
* Copy of et_pb_generate_responsive_css() with some modifications to improve.
* @param array $values_array All device values.
* @param mixed $css_selector CSS selector.
* @param string $css_property CSS property.
* @param string $function_name Module slug.
* @param string $additional_css Additional CSS.
* @param string $type Value type to determine need filter or not. Previously, it only
* accept value from range control and run a function to process
* @param string $priority CSS style declaration priority.
public function generate_responsive_css( $values_array, $css_selector, $css_property, $function_name, $additional_css = '', $type = 'range', $priority = '' ) {
if ( empty( $values_array ) ) {
foreach( $values_array as $device => $current_value ) {
if ( empty( $current_value ) ) {
// There are some cases where selector is an object contains specific selector for
$selector = $css_selector;
if ( is_array( $css_selector ) ) {
$selector = ! empty( $css_selector[ $device ] ) ? $css_selector[ $device ] : '';
if ( empty( $selector ) ) {
// There are some cases before we can declare the CSS style:
// 1. The value is an array contains pair of properties and values.
// 2. The value is single string but we have multiple properties exist.
// 3. The value is single string with only one property.
// Value can be provided as a string or array in following format:
// 'property_1' => 'value_1', 'property_2' => 'value_2', ... ,
// 'property_n' => 'value_n'
if ( is_array( $current_value ) ) {
foreach( $current_value as $this_property => $this_value ) {
if ( empty( $this_property ) || '' === $this_value ) {
// Get valid value. Previously, it only works for range control value and run
// et_builder_process_range_value function directly. Keep it as it is now for
// backward compatibility.
$valid_value = $this_value;
if ( 'range' === $type ) {
$valid_value = et_builder_process_range_value( $this_value );
esc_html( $valid_value ),
'' !== $additional_css ? $additional_css : ';'
} else if ( is_array( $css_property ) ) {
// Get valid value. Previously, it only works for range control value and run
// et_builder_process_range_value function directly.
$valid_value = $current_value;
if ( 'range' === $type ) {
$valid_value = et_builder_process_range_value( $current_value );
foreach( $css_property as $this_property ) {
if ( empty( $this_property ) ) {
esc_html( $valid_value ),
'' !== $additional_css ? $additional_css : ';'
} else if ( ! empty( $css_property ) ) {
// Get valid value. Previously, it only works for range control value and run
// et_builder_process_range_value function directly.
$valid_value = $current_value;
if ( 'range' === $type ) {
$valid_value = et_builder_process_range_value( $current_value );
esc_html( $valid_value ),
'' !== $additional_css ? $additional_css : ';'
if ( '' === $declaration ) {
'declaration' => $declaration,
if ( 'desktop_only' === $device ) {
$style['media_query'] = ET_Builder_Element::get_media_query( 'min_width_981' );
} elseif ( 'desktop' !== $device ) {
$current_media_query = 'tablet' === $device ? 'max_width_980' : 'max_width_767';
$style['media_query'] = ET_Builder_Element::get_media_query( $current_media_query );
if ( '' !== $priority ) {
$style['priority'] = $priority;
ET_Builder_Element::set_style( $function_name, $style );
* Generates the CSS code for responsive options based on existing declaration.
* Similar with generate_responsive_css(), but it's only used to declare the CSS and selector
* without set styles on ET_Builder_Element.
* @param array $values_array All device values.
* @param mixed $css_selector CSS selector.
* @param string $function_name Module slug.
* @param string $priority CSS style declaration priority.
public function declare_responsive_css( $values_array, $css_selector, $function_name, $priority = '' ) {
if ( empty( $values_array ) ) {