: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$processed_attr_value = str_replace( array( '%22', '%92', '%91', '%93', '%5c' ), array( '"', '\\', '[', ']', '\\' ),$processed_attr_value );
// Restore string for font icon attribute from "##xx##" to "%%xx%%".
$processed_attr_value = preg_replace( '/##([0-9]+)##/', '%%$1%%', $processed_attr_value );
$shortcode_attributes[ $attribute_key ] = $processed_attr_value;
$this->props = $shortcode_attributes;
* Provide a way for sub-class to access $this->_render_count without a chance to alter its value
protected function render_count() {
return $this->_render_count;
* Bumps the render count for this module instance and the module instance whose slug is
* set as {@see self::$_bumps_render_count} (if any).
protected function _bump_render_count() {
if ( $this->_bumps_render_count ) {
$module = self::get_module( $this->_bumps_render_count, $this->get_post_type() );
$module->_render_count++;
* check whether ab testing enabled for current module and calculate whether it should be displayed currently or not
private function _is_display_module( $shortcode_atts ) {
$ab_subject_id = isset( $shortcode_atts['ab_subject_id'] ) && '' !== $shortcode_atts['ab_subject_id'] ? $shortcode_atts['ab_subject_id'] : false;
// return true if testing is disabled or current module has no subject id.
if ( ! $ab_subject_id ) {
return $this->_check_ab_test_subject( $ab_subject_id );
* check whether the current module should be displayed or not
private function _check_ab_test_subject( $ab_subject_id = false ) {
global $et_pb_ab_subject;
if ( ! $ab_subject_id ) {
return $ab_subject_id === et_()->array_get( $et_pb_ab_subject, self::get_layout_id(), '' );
protected static function _get_index( $key ) {
$theme_builder_group = self::get_theme_builder_layout_type();
$key = array_merge( array( $theme_builder_group ), (array) $key );
return et_()->array_get( self::$_indices, $key, -1 );
protected static function _set_index( $key, $index ) {
$theme_builder_group = self::get_theme_builder_layout_type();
$key = array_merge( array( $theme_builder_group ), (array) $key );
et_()->array_set( self::$_indices, $key, $index );
* Resets indexes used when generating element addresses.
public static function reset_element_indexes( $content = '', $force = false ) {
if ( ! $force && ( ! self::$can_reset_element_indexes || ! is_main_query() ) ) {
$slugs = self::get_parent_slugs_regex();
if ( $content && ! preg_match( "/{$slugs}/", $content ) ) {
// At least one builder element should be present.
global $wp_current_filter;
if ( in_array( 'the_content', $wp_current_filter ) ) {
$call_counts = array_count_values( $wp_current_filter );
if ( $call_counts['the_content'] > 1 ) {
// This is a nested call. We only want to reset indexes after the top-most call.
self::_set_index( self::INDEX_SECTION, -1 );
self::_set_index( self::INDEX_ROW, -1 );
self::_set_index( self::INDEX_ROW_INNER, -1 );
self::_set_index( self::INDEX_COLUMN, -1 );
self::_set_index( self::INDEX_COLUMN_INNER, -1 );
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
// Reset module order classes
self::_set_index( self::INDEX_MODULE_ORDER, array() );
self::_set_index( self::INDEX_INNER_MODULE_ORDER, array() );
* Generates the element's address. Every builder element on the page is assigned an address
* based on it's index and those of it's parents using the following format:
* `$section.$row.$column.$module[.$module_item]`
* For example, if a module is the forth module in the first column in the third row in the
* second section on the page, it's address would be: `1.2.0.3` (indexes are zero-based).
* @since 3.1 Renamed from `_get_current_shortcode_address()` to `generate_element_address()`
* @param string render slug
public function generate_element_address( $render_slug = '' ) {
// Flag child module. $this->type isn't accurate in this context since some modules reuse other
// modules' render() method for rendering their output (ie. accordion item).
// Even though Column and Column Inner are child elements of Row they shouldn't be processed as child items
$is_child_module = in_array( $render_slug, self::get_child_slugs( $this->get_post_type() ) ) && false === strpos( $render_slug, '_column_inner' ) && false === strpos( $render_slug, '_column' );
if ( false !== strpos( $render_slug, '_section' ) ) {
self::_set_index( self::INDEX_SECTION, self::_get_index( self::INDEX_SECTION ) + 1 );
// Reset every module index inside section
self::_set_index( self::INDEX_ROW, -1 );
self::_set_index( self::INDEX_ROW_INNER, -1 );
self::_set_index( self::INDEX_COLUMN, -1 );
self::_set_index( self::INDEX_COLUMN_INNER, -1 );
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
} else if ( false !== strpos( $render_slug, '_row_inner' ) ) {
self::_set_index( self::INDEX_ROW_INNER, self::_get_index( self::INDEX_ROW_INNER ) + 1 );
// Reset every module index inside row inner
self::_set_index( self::INDEX_COLUMN_INNER, -1 );
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
} else if ( false !== strpos( $render_slug, '_row' ) ) {
self::_set_index( self::INDEX_ROW, self::_get_index( self::INDEX_ROW ) + 1 );
// Reset every module index inside row
self::_set_index( self::INDEX_COLUMN, -1 );
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
} else if ( false !== strpos( $render_slug, '_column_inner' ) ) {
self::_set_index( self::INDEX_COLUMN_INNER, self::_get_index( self::INDEX_COLUMN_INNER ) + 1 );
// Reset every module index inside column inner
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
} else if ( false !== strpos( $render_slug, '_column' ) && -1 === self::_get_index( self::INDEX_ROW ) ) {
self::_set_index( self::INDEX_COLUMN, self::_get_index( self::INDEX_COLUMN ) + 1 );
// Reset every module index inside column of specialty section
self::_set_index( self::INDEX_ROW_INNER, -1 );
self::_set_index( self::INDEX_COLUMN_INNER, -1 );
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
} else if ( false !== strpos( $render_slug, '_column' ) ) {
self::_set_index( self::INDEX_COLUMN, self::_get_index( self::INDEX_COLUMN ) + 1 );
// Reset every module index inside column of regular section
self::_set_index( self::INDEX_MODULE, -1 );
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
} else if ( $is_child_module ) {
self::_set_index( self::INDEX_MODULE_ITEM, self::_get_index( self::INDEX_MODULE_ITEM ) + 1 );
self::_set_index( self::INDEX_MODULE, self::_get_index( self::INDEX_MODULE ) + 1 );
// Reset module item index inside module
self::_set_index( self::INDEX_MODULE_ITEM, -1 );
$address = self::_get_index( self::INDEX_SECTION );
if ( -1 === self::_get_index( self::INDEX_ROW ) && -1 === self::_get_index( self::INDEX_ROW_INNER ) ) {
// Fullwidth & Specialty (without column inner) Section's module
$parts = array( self::_get_index( self::INDEX_COLUMN ), self::_get_index( self::INDEX_MODULE ) );
} else if ( 0 <= self::_get_index( self::INDEX_ROW_INNER ) ) {
// Specialty (inside column inner) Section's module
$parts = array( self::_get_index( self::INDEX_COLUMN ), self::_get_index( self::INDEX_ROW_INNER ), self::_get_index( self::INDEX_COLUMN_INNER ), self::_get_index( self::INDEX_MODULE ) );
// Regular section's module
$parts = array( self::_get_index( self::INDEX_ROW ), self::_get_index( self::INDEX_COLUMN ), self::_get_index( self::INDEX_MODULE ) );
foreach ( $parts as $part ) {
if ( $is_child_module ) {
$address .= '.' . self::_get_index( self::INDEX_MODULE_ITEM );
* Resolves conditional defaults
* @param array $values Fields.
* @param string $render_slug
function resolve_conditional_defaults( $values, $render_slug = '' ) {
// Resolve conditional defaults for the FE
$resolved = $this->get_default_props();
if ( $render_slug && $render_slug !== $this->slug ) {
if ( $module = self::get_module( $render_slug, $this->get_post_type() ) ) {
$resolved = array_merge( $resolved, $module->get_default_props() );
foreach ( $resolved as $field_name => $field_default ) {
if ( is_array( $field_default ) && 2 === count( $field_default ) && ! empty( $field_default[0] ) ) {
if ( is_array( $field_default[1] ) ) {
// Looks like we have a conditional default
// Get $depend_field value or use the first default if undefined.
list ( $depend_field, $conditional_defaults ) = $field_default;
reset( $conditional_defaults );
$default_key = isset( $values[ $depend_field ] ) ? $values[ $depend_field ] : key( $conditional_defaults );
// Set the resolved default
$resolved[ $field_name ] = isset( $conditional_defaults[ $default_key ] ) ? $conditional_defaults[ $default_key ] : null;
} else if ( 'filter' === $field_default[0] ) {
$resolved[ $field_name ] = apply_filters( $field_default[1], $field_name );
if ( ! is_array( $values ) ) {
foreach ( $values as $attr => $value ) {
if ( ! preg_match( ET_Builder_Module_Helper_MultiViewOptions::get_regex_suffix(), $attr ) ) {
$resolved[ $attr ] = $value;
$skip_base_names = array(
foreach ( array_keys( $values ) as $attr ) {
$base_name = 0 === strpos( $attr, 'content' ) ? 'content' : ET_Builder_Module_Helper_MultiViewOptions::get_name_base( $attr );
if ( in_array( $base_name, $skip_base_names, true ) ) {
$base_names[ $base_name ] = $base_name;
// Set the props list that the value need to be inherited.
// to get the responsive content able to display content for tablet/phone/hover only mode
foreach ( $base_names as $base_name ) {
foreach ( array( 'hover', 'tablet', 'phone' ) as $mode ) {
$name_by_mode = ET_Builder_Module_Helper_MultiViewOptions::get_name_by_mode( $base_name, $mode );
if ( ! isset( $values[ $name_by_mode ] ) && ! isset( $resolved[ $name_by_mode ] ) ) {
// Set value inheritance flag for hover mode.
$this->mv_inherited_props[ $name_by_mode ] = $name_by_mode;
} else if( ! isset( $values[ $name_by_mode ] ) && isset( $resolved[ $name_by_mode ] ) && '' === $resolved[ $name_by_mode ] ) {
// Set value inheritance flag for tablet & phone mode.
$this->mv_inherited_props[ $name_by_mode ] = $name_by_mode;
* Get wrapper settings. Combining module-defined wrapper settings with default wrapper settings
* @param string $render_slug module slug
protected function get_wrapper_settings( $render_slug = '' ) {
global $et_fb_processing_shortcode_object;
// The following defaults are used on both frontend & builder
'parallax_background' => '',
'video_background' => '',
'class' => 'et_pb_module_inner',
// The following defaults are only used on frontend. VB handles these on ETBuilderInjectedComponent based on live props
// Note: get_parallax_image_background() and video_background() have to be called before module_classname()
if ( ! $et_fb_processing_shortcode_object ) {
$use_background_image = self::$_->array_get( $this->advanced_fields, 'background.use_background_image', false );
$use_background_video = self::$_->array_get( $this->advanced_fields, 'background.use_background_video', false );
$use_module_id = self::$_->array_get( $this->props, 'module_id', '' );
// Module might disable image background
if ( $use_background_image ) {
$defaults['parallax_background'] = $this->get_parallax_image_background();
// Module might disable video background
if ( $use_background_video ) {
$defaults['video_background'] = $this->video_background();
// Module might intentionally has custom id fields (ie. Module items)
$defaults['attrs']['id'] = $this->module_id( false );
$defaults['attrs']['class'] = $this->module_classname( $render_slug );
if ( ! $defaults['attrs'] ) {
// Make sure we get an empty object when this is output as JSON later.
$defaults['attrs'] = new stdClass;
// Fill empty argument attributes by default values
return wp_parse_args( $this->wrapper_settings, $defaults );
* Wrap module's rendered output with proper module wrapper. Ensuring module has consistent
* wrapper output which compatible with module attribute and background insertion.
* @param string $output Module's rendered output
* @param string $render_slug Slug of module that is used for rendering output
protected function _render_module_wrapper( $output = '', $render_slug = '' ) {
$wrapper_settings = $this->get_wrapper_settings( $render_slug );
$outer_wrapper_attrs = $wrapper_settings['attrs'];
$inner_wrapper_attrs = $wrapper_settings['inner_attrs'];
* Filters the HTML attributes for the module's outer wrapper. The dynamic portion of the
* filter name, '$slug', corresponds to the module's slug.
* @since 3.23 Add support for responsive video background.
* @param string[] $outer_wrapper_attrs
* @param ET_Builder_Element $module_instance
$outer_wrapper_attrs = apply_filters( "et_builder_module_{$slug}_outer_wrapper_attrs", $outer_wrapper_attrs, $this );
* Filters the HTML attributes for the module's inner wrapper. The dynamic portion of the
* filter name, '$slug', corresponds to the module's slug.
* @param string[] $inner_wrapper_attrs
* @param ET_Builder_Element $module_instance
$inner_wrapper_attrs = apply_filters( "et_builder_module_{$slug}_inner_wrapper_attrs", $inner_wrapper_attrs, $this );
et_html_attrs( $outer_wrapper_attrs ),
$wrapper_settings['parallax_background'],
$wrapper_settings['video_background'],
et_html_attrs( $inner_wrapper_attrs ),
et_()->array_get( $wrapper_settings, 'video_background_tablet', '' ),
et_()->array_get( $wrapper_settings, 'video_background_phone', '' )
* Resolves the values for dynamic attributes.
* @param array $original_attrs List of attributes
* @return array Processed attributes with resolved dynamic values.
function process_dynamic_attrs( $original_attrs ) {
global $et_fb_processing_shortcode_object;
$attrs = $original_attrs;
$enabled_dynamic_attributes = $this->_get_enabled_dynamic_attributes( $attrs );
if ( is_array( $attrs ) ) {
foreach ( $attrs as $key => $value ) {
$attrs[ $key ] = $this->_resolve_value(
$enabled_dynamic_attributes,
$et_fb_processing_shortcode_object
* Prepares for and then calls the module's {@see self::render()} method.
* @since 3.23 Add support for generating responsive animation.
* @since 3.1 Renamed from `_shortcode_callback()` to `_render()`.
* @param array $attrs List of attributes
* @param string $content Content being processed
* @param string $render_slug Slug of module that is used for rendering output