: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
// Ensure toggles is exist.
if ( ! isset( $this->settings_modal_toggles[ $tab_slug ]['toggles'] ) ) {
$this->settings_modal_toggles[ $tab_slug ]['toggles'] = array();
// Stop the process here if the toggle slug doesn't exist. It should exist before we add
if ( ! isset( $this->settings_modal_toggles[ $tab_slug ]['toggles'][ $toggle_slug ] ) ) {
// Don't replace existing sub toggles.
$toggle = $this->settings_modal_toggles[ $tab_slug ]['toggles'][ $toggle_slug ];
$sub_toggles = isset( $toggle['sub_toggles'] ) ? $toggle['sub_toggles'] : array();
if ( ! empty( $sub_toggles ) ) {
$this->settings_modal_toggles[ $tab_slug ]['toggles'][ $toggle_slug ]['sub_toggles'] = $sub_toggle_items;
// Set tabbed sub toggles status.
if ( $tabbed_subtoggles ) {
$this->settings_modal_toggles[ $tab_slug ]['toggles'][ $toggle_slug ]['tabbed_subtoggles'] = $tabbed_subtoggles;
// Set BB icons support status.
if ( $bb_icons_support ) {
$this->settings_modal_toggles[ $tab_slug ]['toggles'][ $toggle_slug ]['bb_icons_support'] = $bb_icons_support;
private function _get_fields() {
$this->fields = $this->fields_unprocessed;
$this->fields = $this->process_fields( $this->fields );
$this->fields = apply_filters( 'et_builder_module_fields_' . $this->slug, $this->fields );
foreach ( $this->fields as $field_name => $field ) {
$this->fields[ $field_name ] = apply_filters('et_builder_module_fields_' . $this->slug . '_field_' . $field_name, $field );
// Option template replaces field's array configuration into string which refers to
// saved template data & template id
if ( is_array( $this->fields[ $field_name ] ) ) {
$this->fields[ $field_name ]['name'] = $field_name;
* Checks if the field value equals its default value
* @param string $name Field name.
* @param mixed $value Field value.
protected function _is_field_default( $name, $value ) {
if ( ! isset( $this->fields_unprocessed[ $name ] ) ) {
$field = $this->fields_unprocessed[ $name ];
$default = self::$_->array_get( $field, 'default', '' );
$default_on_front = self::$_->array_get( $field, 'default_on_front', 'not_found' );
if ( 'not_found' !== $default_on_front ) {
return $default_on_front === $value;
if ( is_array( $default ) && ! empty( $default[0] ) && is_array( $default[1] ) ) {
// This is a conditional default. Let's try to resolve it.
list ( $depend_field, $conditional_defaults ) = $default;
$default_key = self::$_->array_get( $this->props, $depend_field, key( $conditional_defaults ) );
$default = self::$_->array_get( $conditional_defaults, $default_key, null );
return $default === $value;
// intended to be overridden as needed
function process_fields( $fields ) {
return apply_filters( 'et_pb_module_processed_fields', $fields, $this->slug );
* Get the settings fields data for this element.
* @todo Finish documenting return value's structure.
* @type mixed[] $setting_field_key {
* @type string $type Setting field type.
* @type string $id CSS id for the setting.
* @type string $label Text label for the setting. Translatable.
* @type string $description Description for the settings. Translatable.
* @type string $class Optional. Css class for the settings.
* @type string[] $affects Optional. The keys of all settings that depend on this setting.
* @type string[] $depends_on Optional. The keys of all settings that this setting depends on.
* @type string $depends_show_if Optional. Only show this setting when the settings
* on which it depends has a value equal to this.
* @type string $depends_show_if_not Optional. Only show this setting when the settings
* on which it depends has a value that is not equal to this.
function get_fields() { return array(); }
* Returns props value by provided key, if the value is empty, returns the default value
public function prop( $prop, $default = null ) {
return et_builder_module_prop( $prop, $this->props, $default );
* Get module defined fields + automatically generated fields
* @since 3.23 Add auto generate responsive settings suffix based on mobile_options parameter.
* @internal Added to make get_fields() lighter. Initially added during BFB's 3rd party support
function get_complete_fields() {
$fields = $this->get_fields();
$responsive_suffixes = array( 'tablet', 'phone', 'last_edited' );
// Loop fields and modify it if needed
foreach ( $fields as $field_name => $field ) {
// Automatically generate responsive fields
$supports_responsive = ( isset( $field['responsive'] ) && $field['responsive'] ) || ( isset( $field['mobile_options'] ) && $field['mobile_options'] );
if ( $supports_responsive ) {
// Get tab and toggle slugs value
$tab_slug = isset( $field['tab_slug'] ) ? $field['tab_slug'] : '';
$toggle_slug = isset( $field['toggle_slug'] ) ? $field['toggle_slug'] : '';
foreach ( $responsive_suffixes as $responsive_suffix ) {
$responsive_field_name = "{$field_name}_{$responsive_suffix}";
$fields[ $responsive_field_name ] = array(
'toggle_slug' => $toggle_slug,
// Add general fields for modules including Columns.
if ( ( ! isset( $this->type ) || 'child' !== $this->type ) || in_array( $this->slug, array( 'et_pb_column', 'et_pb_column_inner' ) ) ) {
if ( ! isset( $i18n['complete'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['complete'] = array(
'section' => esc_html__( 'section', 'et_builder' ),
'row' => esc_html__( 'row', 'et_builder' ),
'module' => esc_html__( 'module', 'et_builder' ),
'label' => esc_html__( 'Disable on', 'et_builder' ),
'description' => esc_html__( 'This will disable the %1$s on selected devices', 'et_builder' ),
'description' => esc_html__( 'This will change the label of the module in the builder for easy identification.', 'et_builder' ),
'label' => esc_html__( 'CSS ID', 'et_builder' ),
'description' => esc_html__( "Assign a unique CSS ID to the element which can be used to assign custom CSS styles from within your child theme or from within Divi's custom CSS inputs.", 'et_builder' ),
'label' => esc_html__( 'CSS Class', 'et_builder' ),
'description' => esc_html__( "Assign any number of CSS Classes to the element, separated by spaces, which can be used to assign custom CSS styles from within your child theme or from within Divi's custom CSS inputs.", 'et_builder' ),
$disabled_on_fields = array();
'et_pb_section' => $i18n['complete']['section'],
'et_pb_row' => $i18n['complete']['row'],
$disable_label = isset( $slug_labels[ $this->slug ] ) ? $slug_labels[ $this->slug ] : $i18n['complete']['module'];
$disabled_on_fields = array(
'label' => $i18n['complete']['disabled']['label'],
'description' => sprintf( $i18n['complete']['disabled']['description'], $disable_label ),
'type' => 'multiple_checkboxes',
'phone' => et_builder_i18n( 'Phone' ),
'tablet' => et_builder_i18n( 'Tablet' ),
'desktop' => et_builder_i18n( 'Desktop' ),
'additional_att' => 'disable_on',
'option_category' => 'configuration',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
$common_general_fields = array(
'label' => et_builder_i18n( 'Admin Label' ),
'description' => $i18n['complete']['admin']['description'],
'option_category' => 'configuration',
'toggle_slug' => 'admin_label',
'label' => $i18n['complete']['id']['label'],
'description' => $i18n['complete']['id']['description'],
'option_category' => 'configuration',
'tab_slug' => 'custom_css',
'toggle_slug' => 'classes',
'option_class' => 'et_pb_custom_css_regular',
'label' => $i18n['complete']['class']['label'],
'description' => $i18n['complete']['class']['description'],
'option_category' => 'configuration',
'tab_slug' => 'custom_css',
'toggle_slug' => 'classes',
'option_class' => 'et_pb_custom_css_regular',
$general_fields = array_merge( $disabled_on_fields, $common_general_fields );
$fields = array_merge( $fields, apply_filters( 'et_builder_module_general_fields', $general_fields ) );
* Get configuration for module's advanced fields. This method is meant to be overridden in module classes.
* @return array[] {@see self::$advanced_fields}
public function get_advanced_fields_config() {
return $this->advanced_fields;
* Get configuration for module's custom css fields. This method is meant to be overridden in module classes.
* @return array[] {@see self::$custom_css_fields}
public function get_custom_css_fields_config() {
return $this->custom_css_fields;
* Returns Global Presets settings
public static function get_global_presets() {
return self::$global_presets_manager->get_global_presets();
* Get custom tabs for the module's settings modal. This method is meant to be overridden in module classes.
* @return array[] {@see self::$settings_modal_tabs}
public function get_settings_modal_tabs() {
return $this->settings_modal_tabs;
* Get toggles for the module's settings modal. This method is meant to be overridden in module classes.
* @return array[] {@see self::$settings_modal_toggles}
public function get_settings_modal_toggles() {
return $this->settings_modal_toggles;
* Generate column fields.
* @param number $column_number number of column
* @param array $base_fields base fields for column
* @return array column fields
function get_column_fields( $column_number = 1, $base_fields = array() ) {
// Loop column's base fields
foreach ( $base_fields as $field_name => $field ) {
// Loop (number of column) times
for ( $index = 1; $index <= $column_number; $index++ ) {
// Some attribute's id is not located at the bottom of the attribute name
if ( isset( $field['has_custom_index_location'] ) && $field['has_custom_index_location'] ) {
$column_name = str_replace( '%column_index%', $index, $field_name );
$column_name = "{$field_name}_{$index}";
$fields[ $column_name ] = array(
// Most column field is an empty-type attribute. Non-empty attribute are likely
// attribute for computed field which needs to have suffix ID
if ( ! empty( $field ) ) {
// Append suffix to the module variable
foreach ( $field as $attr_name => $attr_value ) {
if ( 'has_custom_index_location' === $attr_name ) {
if ( is_array( $attr_value ) && 'computed_callback' !== $attr_name ) {
$attr_value = $this->_append_suffix( $attr_value, $index );
$fields[ $column_name ][ $attr_name ] = $attr_value;
* Append suffix to simple array value
* @param array $values array value
* @param string $suffix intended suffix for output's array
* @return array suffixed value
function _append_suffix( $values, $suffix ) {
foreach ( $values as $value ) {
$output[] = "{$value}_{$suffix}";
* Returns module style priority.
function get_style_priority() {
return $this->_style_priority;
function get_post_type() {
global $post, $et_builder_post_type;
if ( isset( $_POST['et_post_type'] ) && ! $et_builder_post_type ) { // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
$et_builder_post_type = sanitize_text_field( $_POST['et_post_type'] );
if ( is_a( $post, 'WP_POST' ) && ( is_admin() || ! isset( $et_builder_post_type ) ) ) {
$layout_type = self::get_theme_builder_layout_type();
return isset( $et_builder_post_type ) ? $et_builder_post_type : 'post';
static function optimize_bb_chunk( $content ) {
if ( ! ET_BUILDER_OPTIMIZE_TEMPLATES ) {
return str_replace( self::$_unique_bb_strip, '', $content );
static function get_unique_bb_key( $content ) {
if ( ! ET_BUILDER_OPTIMIZE_TEMPLATES ) {
$content = self::optimize_bb_chunk( $content );
if ( isset( self::$_unique_bb_keys_map[ $content ] ) ) {
$key = self::$_unique_bb_keys_map[ $content ];
self::$_unique_bb_keys_values[] = $content;
$key = count( self::$_unique_bb_keys_values ) - 1;
self::$_unique_bb_keys_map[ $content ] = $key;
$content = "<!-- $key -->";
function wrap_settings_option( $option_output, $field, $name = '' ) {
// Option template convert array field into string id; return early to prevent error
if ( is_string( $field ) ) {
return self::get_unique_bb_key( $option_output );
$new_depends = isset( $field['show_if'] ) || isset( $field['show_if_not'] );
if ( ! $new_depends && ( isset( $field['depends_show_if'] ) || isset( $field['depends_show_if_not'] ) ) ) {
if ( isset( $field['depends_show_if_not'] ) ) {
$depends_show_if_not = is_array( $field['depends_show_if_not'] ) ? implode( ',', $field['depends_show_if_not'] ) : $field['depends_show_if_not'];
$depends_attr = sprintf( ' data-depends_show_if_not="%s"', esc_attr( $depends_show_if_not ) );
$depends_attr = sprintf( ' data-depends_show_if="%s"', esc_attr( $field['depends_show_if'] ) );
if ( isset( $field['depends_on_responsive'] ) ) {
$depends_attr .= sprintf( ' data-depends_on_responsive="%s"', esc_attr( implode( ',', $field['depends_on_responsive'] ) ) );
// Overriding background color's attribute, turning it into appropriate background attributes
if ( isset( $field['type'] ) && isset( $field['name' ] ) && 'background_color' === $field['name'] && ! self::$_->array_get( $field, 'skip_background_ui' ) ) {
$field['type'] = 'background';
// Removing depends default variable which hides background color for unified background field UI
if ( isset( $field['depends_show_if'] ) ) {
unset( $field['depends_show_if'] );
'%6$s<div class="et-pb-option et-pb-option--%10$s%1$s%2$s%3$s%8$s%9$s%12$s%13$s"%4$s tabindex="-1" data-option_name="%11$s">%5$s</div>%7$s',
( ! empty( $field['type'] ) && 'tiny_mce' === $field['type'] ? ' et-pb-option-main-content' : '' ),
$depends || $new_depends ? ' et-pb-depends' : '',
( ! empty( $field['type'] ) && 'hidden' === $field['type'] ? ' et_pb_hidden' : '' ),
( $depends ? $depends_attr : '' ),
"\n\t\t\t\t" . $option_output . "\n\t\t\t",
( ! empty( $field['type'] ) && 'hidden' === $field['type'] ? esc_attr( sprintf( ' et-pb-option-%1$s', $field['name'] ) ) : '' ),
( ! empty( $field['option_class'] ) ? ' ' . $field['option_class'] : '' ),
isset( $field['type'] ) ? esc_attr( $field['type'] ) : '',
esc_attr( $field['name'] ),
isset( $field['specialty_only'] ) && 'yes' === $field['specialty_only'] ? ' et-pb-specialty-only-option' : '',
$new_depends ? ' et-pb-new-depends' : ''
if ( ! empty( $field['hover'] ) ) {
if ( 'tabs' === $field['hover'] ) {
$this->last_hover_tab_field = $name;
$hover = $this->last_hover_tab_field;
$begin = '<div class="et-pb-option ';
$pos = strpos( $output, $begin );
$output = substr_replace(
"<div data-depends_hover=\"$hover\" class=\"et-pb-option-standard et-pb-option ",