: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
'et_pb_static_css_file' => self::_get_static_css_generation_field( 'page' ),
* Get page setting fields' meta_key map. Most page settings' field meta key is identical to
* its field['id'] but some fields use different meta_key. Map might need in some situations
* @param bool $meta_key_to_id reverse mapping if set to false
public static function get_page_setting_meta_key_map( $meta_key_to_id = true ) {
// Less likely to change, populate it once will be sufficient
foreach ( self::_get_page_settings_fields() as $field_id => $field ) {
if ( isset( $field['meta_key'] ) ) {
// The map can be reversed if needed
$map[ $field['meta_key'] ] = $field_id;
$map[ $field_id ] = $field['meta_key'];
protected static function _get_page_settings_values( $post_id ) {
$post_id = $post_id ? $post_id : get_the_ID();
if ( ! empty( self::$_PAGE_SETTINGS_VALUES[ $post_id ] ) ) {
return self::$_PAGE_SETTINGS_VALUES[ $post_id ];
$overflow = et_pb_overflow();
$OVERFLOW_DEFAULT = ET_Builder_Module_Helper_Overflow::OVERFLOW_DEFAULT;
$fields = self::$_PAGE_SETTINGS_FIELDS;
$default_bounce_rate_limit = 5;
$ab_bounce_rate_limit = get_post_meta( $post_id, '_et_pb_ab_bounce_rate_limit', true );
$et_pb_ab_bounce_rate_limit = '' !== $ab_bounce_rate_limit ? $ab_bounce_rate_limit : $default_bounce_rate_limit;
$is_default[] = $et_pb_ab_bounce_rate_limit === $default_bounce_rate_limit ? 'et_pb_ab_bounce_rate_limit' : '';
$color_palette = get_post_meta( $post_id, '_et_pb_color_palette', true );
$default = $fields['et_pb_color_palette']['default'];
$et_pb_color_palette = '' !== $color_palette ? $color_palette : $default;
$is_default[] = $et_pb_color_palette === $default ? 'et_pb_color_palette' : '';
$gutter_width = get_post_meta( $post_id, '_et_pb_gutter_width', true );
$default = $fields['et_pb_page_gutter_width']['default'];
$et_pb_page_gutter_width = '' !== $gutter_width ? $gutter_width : $default;
$is_default[] = $et_pb_page_gutter_width === $default ? 'et_pb_page_gutter_width' : '';
$light_text_color = get_post_meta( $post_id, '_et_pb_light_text_color', true );
$default = $fields['et_pb_light_text_color']['default'];
$et_pb_light_text_color = '' !== $light_text_color ? $light_text_color : $default;
$is_default[] = strtolower( $et_pb_light_text_color ) === $default ? 'et_pb_light_text_color' : '';
$dark_text_color = get_post_meta( $post_id, '_et_pb_dark_text_color', true );
$default = $fields['et_pb_dark_text_color']['default'];
$et_pb_dark_text_color = '' !== $dark_text_color ? $dark_text_color : $default;
$is_default[] = strtolower( $et_pb_dark_text_color ) === $default ? 'et_pb_dark_text_color' : '';
$content_area_background_color = get_post_meta( $post_id, '_et_pb_content_area_background_color', true );
$default = $fields['et_pb_content_area_background_color']['default'];
$et_pb_content_area_background_color = '' !== $content_area_background_color ? $content_area_background_color : $default;
$is_default[] = strtolower( $et_pb_content_area_background_color ) === $default ? 'et_pb_content_area_background_color' : '';
$section_background_color = get_post_meta( $post_id, '_et_pb_section_background_color', true );
$default = $fields['et_pb_section_background_color']['default'];
$et_pb_section_background_color = '' !== $section_background_color ? $section_background_color : $default;
$is_default[] = strtolower( $et_pb_section_background_color ) === $default ? 'et_pb_section_background_color' : '';
$overflow_x = (string) get_post_meta( $post_id, $overflow->get_field_x( '_et_pb_' ), true );
$is_default[] = empty( $overflow_x ) || $overflow_x == $OVERFLOW_DEFAULT ? $overflow->get_field_x( 'et_pb_' ) : '';
$overflow_y = (string) get_post_meta( $post_id, $overflow->get_field_y( '_et_pb_' ), true );
$is_default[] = empty( $overflow_y ) || $overflow_y == $OVERFLOW_DEFAULT ? $overflow->get_field_y( 'et_pb_' ) : '';
$static_css_file = get_post_meta( $post_id, '_et_pb_static_css_file', true );
$default = $fields['et_pb_static_css_file']['default'];
$et_pb_static_css_file = '' !== $static_css_file ? $static_css_file : $default;
$is_default[] = $et_pb_static_css_file === $default ? 'et_pb_static_css_file' : '';
self::$_PAGE_SETTINGS_IS_DEFAULT[ $post_id ] = $is_default;
$post = get_post( $post_id );
'et_pb_enable_ab_testing' => et_is_ab_testing_active() ? 'on' : 'off',
'et_pb_ab_bounce_rate_limit' => $et_pb_ab_bounce_rate_limit,
'et_pb_ab_stats_refresh_interval' => et_pb_ab_get_refresh_interval( $post_id ),
'et_pb_ab_subjects' => et_pb_ab_get_subjects( $post_id ),
'et_pb_enable_shortcode_tracking' => get_post_meta( $post_id, '_et_pb_enable_shortcode_tracking', true ),
'et_pb_ab_current_shortcode' => '[et_pb_split_track id="' . $post_id . '" /]',
'et_pb_custom_css' => get_post_meta( $post_id, '_et_pb_custom_css', true ),
'et_pb_color_palette' => $et_pb_color_palette,
'et_pb_page_gutter_width' => $et_pb_page_gutter_width,
'et_pb_light_text_color' => strtolower( $et_pb_light_text_color ),
'et_pb_dark_text_color' => strtolower( $et_pb_dark_text_color ),
'et_pb_content_area_background_color' => strtolower( $et_pb_content_area_background_color ),
'et_pb_section_background_color' => strtolower( $et_pb_section_background_color ),
'et_pb_static_css_file' => $et_pb_static_css_file,
'et_pb_post_settings_title' => $post ? $post->post_title : '',
'et_pb_post_settings_excerpt' => $post ? $post->post_excerpt : '',
'et_pb_post_settings_image' => get_post_thumbnail_id( $post_id ),
'et_pb_post_settings_categories' => self::_get_object_terms( $post_id, 'category' ),
'et_pb_post_settings_tags' => self::_get_object_terms( $post_id, 'post_tag' ),
'et_pb_post_settings_project_categories' => self::_get_object_terms( $post_id, 'project_category' ),
'et_pb_post_settings_project_tags' => self::_get_object_terms( $post_id, 'project_tag' ),
et_pb_overflow()->get_field_x( 'et_pb_' ) => $overflow_x,
et_pb_overflow()->get_field_y( 'et_pb_' ) => $overflow_y,
'et_pb_page_z_index' => get_post_meta( $post_id, '_et_pb_page_z_index', true )
* Filters Divi Builder page settings values.
* @param mixed[] $builder_settings {
* Builder Settings Values
* @type string $setting_name Setting value.
* @param string|int $post_id
$values = self::$_PAGE_SETTINGS_VALUES[ $post_id ] = apply_filters( 'et_builder_page_settings_values', $values, $post_id );
* Filters the Divi Builder's page settings values.
* @deprecated {@see 'et_builder_page_settings_values'}
* @since 3.0.45 Deprecation.
return apply_filters( 'et_pb_get_builder_settings_values', $values, $post_id );
protected static function _get_static_css_generation_field( $scope ) {
'page' => esc_html__( "When this option is enabled, the builder's inline CSS styles for this page will be cached and served as a static file. Enabling this option can help improve performance.", 'et_builder' ),
'builder' => esc_html__( "When this option is enabled, the builder's inline CSS styles for all pages will be cached and served as static files. Enabling this option can help improve performance.", 'et_builder' ),
'type' => 'yes_no_button',
'id' => 'et_pb_static_css_file',
'label' => esc_html__( 'Static CSS File Generation', 'et_builder' ),
'description' => $description[ $scope ],
'on' => __( 'On', 'et_builder' ),
'off' => __( 'Off', 'et_builder' ),
'validation_type' => 'simple_text',
'class' => 'et_builder_clear_static_css',
'title' => esc_html_x( 'Clear', 'clear static css files', 'et_builder' ),
'is_after_element' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'performance',
protected static function _get_post_type_options_defaults() {
$post_types = et_builder_get_enabled_builder_post_types();
$post_type_options = array();
foreach ( $post_types as $post_type ) {
$post_type_options[ $post_type ] = 'on';
return $post_type_options;
* Returns all taxonomy terms for a given post.
* @param int $post_id Post ID.
* @param string $taxonomy Taxonomy name.
protected static function _get_object_terms( $post_id, $taxonomy ) {
$terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'ids' ) );
return is_array( $terms ) ? implode( ',', $terms ) : '';
public static function get_registered_post_type_options() {
return et_get_registered_post_type_options( 'ET_Builder_Settings::sort_post_types' );
public static function sort_post_types( $a, $b ) {
// ASCII has a total of 127 characters, so 500 as the interval
// should be a sufficiently high number.
$rank_priority = array( 'page' => 1500, 'post' => 1000, 'project' => 500 );
$a_rank = isset( $rank_priority[ $a->name ] ) ? $rank_priority[ $a->name ] : 0;
$b_rank = isset( $rank_priority[ $b->name ] ) ? $rank_priority[ $b->name ] : 0;
return strcasecmp( $a->label, $b->label ) - $a_rank + $b_rank;
protected function _initialize() {
* Filters Divi Builder settings field definitions.
self::$_BUILDER_SETTINGS_FIELDS = apply_filters( 'et_builder_settings_definitions', self::_get_builder_settings_fields() );
* Filters Divi Builder settings values.
* @param mixed[] $builder_settings {
* Builder Settings Values
* @type string $setting_name Setting value.
self::$_BUILDER_SETTINGS_VALUES = apply_filters( 'et_builder_settings_values', self::_get_builder_settings_values() );
if ( function_exists( 'is_product' ) && is_product() ) {
self::$_PAGE_SETTINGS_FIELDS = self::_get_page_settings_fields( 'product' );
self::$_PAGE_SETTINGS_FIELDS = self::_get_page_settings_fields();
* Filters Divi Builder page settings field definitions.
* @since 3.29 Customize Page Settings Fields for Product CPT.
self::$_PAGE_SETTINGS_FIELDS = apply_filters( 'et_builder_page_settings_definitions',
self::$_PAGE_SETTINGS_FIELDS );
* Filters Divi Builder page settings field definitions.
* @deprecated {@see 'et_builder_page_settings_definitions'}
* @since 3.0.45 Deprecation.
self::$_PAGE_SETTINGS_FIELDS = apply_filters( 'et_pb_get_builder_settings_configurations', self::$_PAGE_SETTINGS_FIELDS );
self::$_PAGE_SETTINGS_VALUES = array();
protected static function _maybe_clear_cached_static_css_files( $setting, $setting_value ) {
if ( in_array( $setting, array( 'et_pb_css_in_footer', 'et_pb_static_css_file' ) ) ) {
ET_Core_PageResource::remove_static_resources( 'all', 'all' );
protected function _register_callbacks() {
$class = get_class( $this );
// Setup post meta callback registration on preview page. Priority has to be less than 10
// so get_post_meta used on self::_get_page_settings_values() are affected
add_action( 'wp', array( $this, '_register_preview_post_metadata' ), 5 );
add_action( 'et_builder_settings_update_option', array( $class, 'update_option_cb'), 10, 3 );
// setup plugin style options, rather than epanel
if ( et_is_builder_plugin_active() ) {
add_filter( 'et_builder_plugin_dashboard_sections', array( $class, 'add_plugin_dashboard_sections' ) );
add_filter( 'et_builder_plugin_dashboard_fields_data', array( $class, 'add_plugin_dashboard_fields_data' ) );
add_action( 'et_pb_builder_after_save_options', array( $class, 'plugin_dashboard_option_saved_cb' ), 10, 4 );
add_action( 'et_pb_builder_option_value', array( $class, 'plugin_dashboard_option_value_cb' ), 10, 2 );
add_filter( 'et_epanel_tab_names', array( $class, 'add_epanel_tab' ) );
add_filter( 'et_epanel_layout_data', array( $class, 'add_epanel_tab_content' ) );
add_action( 'et_epanel_update_option', array( $class, 'update_option_cb' ), 10, 3 );
* Adds a tab for the builder to ePanel's tabs array.
* {@see 'et_epanel_tab_names'}
public static function add_epanel_tab( $tabs ) {
$builder_tab = esc_html_x( 'Builder', 'Divi Builder', 'et_builder' );
$keys = array_keys( $tabs );
$values = array_values( $tabs );
array_splice( $keys, 2, 0, 'builder' );
array_splice( $values, 2, 0, $builder_tab );
return array_combine( $keys, $values );
* Adds builder settings fields data to the builder plugin's options dashboard.
* {@see 'et_builder_plugin_dashboard_fields_data'}
* @param array[] $dashboard_data
* @return array[] $dashboard_data
public static function add_plugin_dashboard_fields_data( $dashboard_data ) {
$tabs = self::get_tabs( 'builder' );
$fields = self::get_fields( 'builder' );
$toggles = self::get_toggles();
foreach ( $tabs as $tab_slug => $tab_name ) {
$section = $tab_slug . '_main_options';
if ( ! isset( $dashboard_data[ $section ] ) ) {
$dashboard_data[ $section ] = array();
$dashboard_data[ $section ][] = array( 'type' => 'main_title', 'title' => '' );
foreach ( $toggles as $toggle_slug => $toggle ) {
$section_started = false;
foreach ( $fields as $field_slug => $field_info ) {
if ( $tab_slug !== $field_info['tab_slug'] || $toggle_slug !== $field_info['toggle_slug'] ) {
if ( 'et_pb_css_in_footer' === $field_info['id'] ) {
if ( ! $section_started ) {
$dashboard_data[ $section ][] = array( 'type' => 'section_start', 'title' => $toggles[ $toggle_slug ] );
$field_info['hint_text'] = $field_info['description'];
$field_info['name'] = $field_info['id'];
$field_info['title'] = $field_info['label'];
$dashboard_data[ $section ][] = $field_info;
if ( isset( $field_info['after'] ) ) {
$dashboard_data[ $section ][] = $field_info['after'];
if ( $section_started ) {
$dashboard_data[ $section ][] = array( 'type' => 'section_end' );
* Adds tabs for builder settings to the builder plugin's options dashboard.
* {@see 'et_builder_plugin_dashboard_sections'}
* @param array[] $sections
* @return array[] $sections
public static function add_plugin_dashboard_sections( $sections ) {
$tabs = self::get_tabs( 'builder' );
foreach ( $tabs as $tab_slug => $tab_name ) {
$sections[ $tab_slug ] = array(
'title' => et_core_esc_previously( $tab_name ),
'main' => esc_html__( 'Main', 'et_builder' ),
* Adds builder settings to ePanel. {@see 'et_epanel_layout_data'}
* @param array $layout_data
public static function add_epanel_tab_content( $layout_data ) {
foreach ( $layout_data as $data ) {
if ( $done || ! isset( $data['name'], $data['type'] ) ) {
if ( 'wrap-navigation' === $data['name'] && 'contenttab-wrapend' === $data['type'] ) {
$builder_options = self::_get_builder_settings_in_epanel_format();
$result = array_merge( $result, $builder_options );
public static function update_option_cb( $setting, $setting_value, $post_id = 'global' ) {
if ( did_action( 'wp_ajax_et_fb_ajax_save' ) ) {
self::_maybe_clear_cached_static_css_files( $setting, $setting_value );
* Returns builder settings fields data for the provided settings scope.
* @param string $scope Get settings fields for scope (page|builder|all). Default 'page'.
* @return array[] See {@link ET_Builder_Element::get_fields()} for structure.
public static function get_fields( $scope = 'page' ) {
if ( 'builder' === $scope ) {
$fields = self::$_BUILDER_SETTINGS_FIELDS;
} else if ( 'page' === $scope ) {
$fields = self::$_PAGE_SETTINGS_FIELDS;
* @return ET_Builder_Settings
public static function get_instance() {
if ( null === self::$_instance ) {
self::$_instance = new ET_Builder_Settings();
* Returns the localized tab names for the builder settings.
* @type string $tab_slug Tab name
public static function get_tabs( $scope = 'page' ) {
$advanced = esc_html_x( 'Advanced', 'Design Settings', 'et_builder' );
$post_type_integration = esc_html_x( 'Post Type Integration', 'Builder Settings', 'et_builder' );
if ( 'page' === $scope ) {
'content' => esc_html_x( 'Content', 'Content Settings', 'et_builder' ),
'design' => esc_html_x( 'Design', 'Design Settings', 'et_builder' ),
} else if ( 'builder' === $scope ) {
'post_type_integration' => $post_type_integration,