: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
foreach ( $values as $mode => $value ) {
if ( $selected_mode && ! in_array( $mode, $selected_mode, true ) ) {
$has_value = self::compare_value( $value, $value_compare );
if ( ! $has_value && 'desktop' !== $mode && $inherit ) {
$has_value = self::compare_value( $this->get_inherit_value( $name, $mode ), $value_compare );
* Get props inherit value
* @param string $name Field key.
* @param string $selected_mode Selected view mode.
public function get_inherit_value( $name, $selected_mode ) {
$values = $this->get_values( $name, false );
if ( isset( $values[ $selected_mode ] ) ) {
return $values[ $selected_mode ];
* Get module props conditional value.
* @param string $name Props name.
* @param string $mode Select only specified modes: desktop, tablet, phone, hover.
* @param mixed $conditionals Extra data to compare.
* @return mixed Calculated conditional value. Will return null if not match any comparison.
public function get_conditional_value( $name, $mode = 'desktop', $conditionals = array() ) {
if ( ! $this->conditional_values ) {
foreach ( $this->conditional_values as $compare ) {
if ( ! isset( $compare['name'] ) || $compare['name'] !== $name ) {
if ( isset( $compare['conditionals'] ) && $compare['conditionals'] ) {
$is_conditionals_match = true;
foreach ( $compare['conditionals'] as $conditional_key => $conditional_value ) {
if ( ! isset( $conditionals[ $conditional_key ] ) || $conditionals[ $conditional_key ] !== $conditional_value ) {
$is_conditionals_match = false;
if ( ! $is_conditionals_match ) {
if ( isset( $compare['props'] ) && $compare['props'] ) {
foreach ( $compare['props'] as $prop_key => $prop_value ) {
if ( ! $prop_key && ! is_numeric( $prop_key ) ) {
if ( 'hover' === $mode && ! $this->hover_is_enabled( $prop_key ) ) {
if ( in_array( $mode, array( 'tablet', 'phone' ), true ) && ! $this->responsive_is_enabled( $prop_key ) ) {
if ( ! $this->has_value( $prop_key, $prop_value, $mode ) ) {
if ( ! $is_props_match ) {
$value = $compare['value'];
if ( preg_match_all( $this->pattern, $value, $matches, PREG_SET_ORDER, 0 ) ) {
foreach ( $matches as $match ) {
if ( ! isset( $match[1] ) ) {
$value = str_replace( $match[0], $this->get_value( $match[1], $mode ), $value );
* @param ET_Builder_Element $module Module object.
public function set_module( $module ) {
if ( ! $module instanceof ET_Builder_Element ) {
return et_debug( __( 'Invalid module instance passed to ET_Builder_Module_Helper_MultiViewOptions::set_module', 'et_builder' ) );
if ( property_exists( $module, 'slug' ) ) {
$this->slug = $module->slug;
if ( property_exists( $module, 'props' ) && $module->props && is_array( $module->props ) ) {
if ( empty( $props['content'] ) && property_exists( $module, 'content' ) ) {
$props['content'] = $module->content;
if ( in_array( $module->slug, array( 'et_pb_code', 'et_pb_fullwidth_code' ), true ) ) {
if ( isset( $props['content'] ) ) {
$props['raw_content'] = $props['content'];
if ( isset( $props[ 'content' . self::$hover_enabled_suffix ] ) ) {
$props[ 'raw_content' . self::$hover_enabled_suffix ] = $props[ 'content' . self::$hover_enabled_suffix ];
if ( isset( $props[ 'content' . self::$responsive_enabled_suffix ] ) ) {
$props[ 'raw_content' . self::$responsive_enabled_suffix ] = $props[ 'content' . self::$responsive_enabled_suffix ];
foreach ( $props as $key => $value ) {
$this->set_props( $key, $value );
$this->set_inherited_props();
* @param string $name Props key.
* @param array $value Props value.
public function set_props( $name, $value ) {
// Always clear cached values to keep the data up to date
// in case the props defined in looping
$this->clear_cached_values( $name );
$this->props[ $name ] = $value;
* @param string $name Props key.
public function clear_cached_values( $name ) {
if ( isset( $this->cached_values[ $name ] ) ) {
unset( $this->cached_values[ $name ] );
* Set list props that inherited.
public function set_inherited_props() {
if ( ! property_exists( $this->module, 'mv_inherited_props' ) || ! is_array( $this->module->mv_inherited_props ) ) {
$this->inherited_props = $this->module->mv_inherited_props;
* Check if props value suppose to be inherited
* @param string $name_by_mode Full name of the props.
* @param string $value Props value.
public function is_props_inherited( $name_by_mode, $value ) {
return isset( $this->inherited_props[ $name_by_mode ] ) && '' === $value;
* Set option default value.
* @param string $name Data key.
* @param array $default_value Default value.
public function set_default_value( $name, $default_value ) {
$this->default_values[ $name ] = $this->normalize_values( $default_value );
* Set options default values.
* @param array $default_values Default values.
public function set_default_values( $default_values ) {
if ( $default_values && is_array( $default_values ) ) {
foreach ( $default_values as $name => $value ) {
$this->set_default_value( $name, $value );
* Set option conditional value.
* @param string $name Prop key.
* @param string $value Custom conditional value.
* @param array $props Key value pair of props list to compare.
* @param array $conditionals Conditionals parameter go compare to calculate the value.
public function set_conditional_value( $name, $value, $props, $conditionals = array() ) {
if ( ! $props || ! is_array( $props ) ) {
if ( ! is_array( $conditionals ) ) {
// Order index is used to preserve original order when sorting "equal" items
// as the order of "equal" items in PHP is "undefined" after sorting.
'order' => count( $this->conditional_values ),
'conditionals' => $conditionals,
$this->conditional_values[] = $conditional;
// Sort by count of props and count of conditionals.
usort( $this->conditional_values, array( $this, 'sort_conditional_values' ) );
* Set option conditional values.
* @param array $conditional_values Default values.
public function set_conditional_values( $conditional_values ) {
if ( ! $conditional_values || ! is_array( $conditional_values ) ) {
foreach ( $conditional_values as $conditional_key => $param ) {
if ( ! isset( $param['value'] ) ) {
if ( ! isset( $param['props'] ) ) {
$conditionals = isset( $param['conditionals'] ) ? $param['conditionals'] : array();
$this->set_conditional_value( $conditional_key, $param['value'], $param['props'], $conditionals );
* Set custom variable data.
* @param string $name Data key.
* @param array $values The values to inject.
public function set_custom_prop( $name, $values ) {
// Always clear cached values to keep the data up to date
// in case the props defined in looping
$this->clear_cached_values( $name );
// Set the custom props data.
$this->custom_props[ $name ] = $this->normalize_values( $values );
* Set custom variables data.
* @param array $custom_props Defined custom props data.
public function set_custom_props( $custom_props ) {
if ( $custom_props && is_array( $custom_props ) ) {
foreach ( $custom_props as $name => $values ) {
$this->set_custom_prop( $name, $values );
* Render the multi view HTML element
* $multi_view->render_element( array(
* 'content' => 'Hello {{name}}', // Assume name props value is John
* - Will generate output:
* $multi_view->render_element( array(
* 'content' => 'get_the_title', // Assume current page title is Hello World
* - Will generate output:
* $multi_view->render_element( array(
* 'content' => get_the_title(), // Assume current page title is Hello World
* - Will generate output:
* $multi_view->render_element( array(
* 'src' => '{{image_url}}, // Assume image_url props value is test.jpg
* 'width' => '{{image_width}}px', // Assume image_width props value is 50
* 'height' => '{{image_height}}px', // Assume image_height props value is 100
* - Will generate output:
* <img src="test.jpg" width="50px" height="100px" />
* $multi_view->render_element( array(
* 'content' => 'Lorem Ipsum',
* 'background-image' => 'url({{image_url}})', // Assume image_url props value is test.jpg
* 'font-size' => '{{title_font_size}}px', // Assume title_font_size props value is 20
* - Will generate output:
* <div style="background-image: url(test.jpg); font-size: 20px;">Lorem Ipsum</div>
* $multi_view->render_element( array(
* 'content' => 'Lorem Ipsum',
* 'et_pb_slider_no_arrows' => array
* 'show_arrows' => 'off', // Assume show_arrows props value is off
* 'et_pb_slider_carousel' => array
* 'show_thumbnails' => 'on', // Assume show_thumbnails props value is on
* - Will generate output:
* <div class=et_pb_slider_no_arrows et_pb_slider_carousel">Lorem Ipsum</div>
* $multi_view->render_element( array(
* 'content' => 'Lorem Ipsum',
* 'show_thumbnails' => 'off',
* - Will generate output that will visible when show_arrows is on and show_thumbnails is off:
* @param array $contexts {
* @type string $tag HTML element tag name. Example: div, img, p. Default is span.
* @type string $content Param that will be used to populate the content data.
* Use props name wrapped with 2 curly brackets within the value for find & replace wildcard: {{props_name}}
* @type array $attrs Param that will be used to populate the attributes data.
* Associative array key used as attribute name and the value will be used as attribute value.
* Special case for 'class' and 'style' attribute name will only generating output for desktop mode.
* Use 'styles' or 'classes' context for multi modes usage.
* Use props name wrapped with 2 curly brackets within the value for find & replace wildcard: {{props_name}}
* @type array $styles Param that will be used to populate the inline style attributes data.
* Associative array key used as style property name and the value will be used as inline style property value.
* Use props name wrapped with 2 curly brackets within the value for find & replace wildcard: {{props_name}}
* @type array $classes Param that will be used to populate the class data.
* Associative array key used as class name and the value is associative array as the conditional check compared with prop value.
* The conditional check array key used as the prop name and the value used as the conditional check compared with prop value.
* The class will be added if all conditional check is true and will be removed if any of conditional check is false.
* @type array $visibility Param that will be used to populate the visibility data.
* Associative array key used as the prop name and the value used as the conditional check compared with prop value.
* The element will visible if all conditional check is true and will be hidden if any of conditional check is false.
* @type string $target HTML element selector target which the element will be modified. Default is empty string.
* Dynamic module order class wildcard string is accepted: %%order_class%%
* @type string $hover_selector HTML element selector which trigger the hover event. Default is empty string.
* Dynamic module order class wildcard string is accepted: %%order_class%%
* @type string $render_slug Render slug that will be used to calculate the module order class. Default is current module slug.
* @type array $custom_props Defined custom props data.
* @type array $conditional_values Defined data sources for data toggle.
* @type array $required List of required props key to render the element.
* Will render the element if all of the props required keys is fulfilled.
* Default is empty array it will try to gather any props name set in the 'content' context.
* Set to false to disable conditional check.
* @type array $required_some List of props key need to be fulfilled to render the element.
* Will render the element if any one of the required props keys is fulfilled.
* When defined, $required_some parameter will be prioritized over $required parameter.
* @param boolean $echo Whether to print the output instead returning it.
public function render_element( $contexts = array(), $echo = false ) {
// Define the array of defaults.
'custom_props' => array(),