: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$_modules = $parent_modules;
$_modules = $child_modules;
$_modules = array_merge( $parent_modules, $child_modules );
$module_fields = array();
$custom_css_unwanted_types = array( 'custom_css', 'column_settings_css', 'column_settings_css_fields', 'column_settings_custom_css' );
foreach( $_modules as $_module_slug => $_module ) {
// filter modules by slug if needed
if ( 'all' !== $module_type && $module_type !== $_module_slug ) {
$module_fields[ $_module_slug ] = $_module->custom_css_fields;
foreach ( $module_fields[ $_module_slug ] as &$item ) {
$item['hover'] = self::$_->array_get( $item, 'hover', 'tabs' );
$item['mobile_options'] = self::$_->array_get( $item, 'mobile_options', true );
// Automatically added module ID and module class fields to setting modal's CSS tab
if ( ! empty( $_module->fields_unprocessed ) ) {
foreach ( $_module->fields_unprocessed as $field_unprocessed_key => $field_unprocessed ) {
$has_tab_slug = isset( $field_unprocessed['tab_slug'] );
$is_css_field = $has_tab_slug && 'custom_css' === $field_unprocessed['tab_slug'];
$has_type = isset( $field_unprocessed['type'] );
$is_unwanted_css_field = $has_type && in_array( $field_unprocessed['type'], $custom_css_unwanted_types );
$is_template_inside_css_tab = is_string( $field_unprocessed ) && self::$option_template->is_template_inside_tab( 'custom_css', $field_unprocessed );
// Option template's template that might be rendered in custom_css tab
if ( ( $is_css_field && ! $is_unwanted_css_field ) || $is_template_inside_css_tab ) {
$module_fields[ $_module_slug ][ $field_unprocessed_key ] = $field_unprocessed;
// Some module types must be separated for the Global Presets.
// For example we keep all section types as `et_pb_section` however they need different Global Presets.
$additional_slugs = self::$global_presets_manager->get_module_additional_slugs( $_module_slug );
foreach ( $additional_slugs as $alias ) {
$module_fields[ $alias ] = $module_fields[ $_module_slug ];
if ( 'all' !== $module_type ) {
return $module_fields[ $module_type ];
static function get_modules_i10n( $post_type = '', $mode = 'all', $module_type = 'all' ) {
$parent_modules = self::get_parent_modules( $post_type );
$child_modules = self::get_child_modules( $post_type );
$_modules = $parent_modules;
$_modules = $child_modules;
$_modules = array_merge( $parent_modules, $child_modules );
foreach( $_modules as $_module_slug => $_module ) {
// filter modules by slug if needed
if ( 'all' !== $module_type && $module_type !== $_module_slug ) {
$fields[$_module_slug] = array(
'addNew' => $_module->add_new_child_text()
if ( 'all' !== $module_type ) {
return $fields[ $module_type ];
public static function get_modules_transitions( $post_type = '', $mode = 'all', $module_type = 'all' ) {
* @var ET_Builder_Element[] $_modules
$parent_modules = self::get_parent_modules( $post_type );
$child_modules = self::get_child_modules( $post_type );
$_modules = $parent_modules;
$_modules = $child_modules;
$_modules = array_merge( $parent_modules, $child_modules );
foreach ( $_modules as $_module_slug => $_module ) {
// filter modules by slug if needed
if ( 'all' !== $module_type && $module_type !== $_module_slug ) {
$fields[ $_module_slug ] = $_module->get_transition_fields_css_props();
public static function get_module_items_configs( $post_type ) {
$modules = self::get_parent_and_child_modules( $post_type );
foreach ( $modules as $slug => $module ) {
if ( isset( $module->module_items_config ) ) {
$configs[ $slug ] = $module->module_items_config;
static function get_module_fields( $post_type, $module ) {
$_modules = self::get_parent_and_child_modules( $post_type );
if ( ! empty( $_modules[ $module ] ) ) {
return $_modules[ $module ]->fields_unprocessed;
static function get_parent_module_fields( $post_type, $module ) {
if ( ! empty( self::$parent_modules[ $post_type ][ $module ] ) ) {
return self::$parent_modules[ $post_type ][ $module ]->get_complete_fields();
static function get_child_module_fields( $post_type, $module ) {
if ( ! empty( self::$child_modules[ $post_type ][ $module ] ) ) {
return self::$child_modules[ $post_type ][ $module ]->get_complete_fields();
static function get_parent_module_field( $post_type, $module, $field ) {
$fields = self::get_parent_module_fields( $post_type, $module );
if ( ! empty( $fields[ $field ] ) ) {
return $fields[ $field ];
static function get_font_icon_fields( $post_type = '' ) {
$_modules = self::get_parent_and_child_modules( $post_type );
$module_fields = array();
foreach ( $_modules as $module_name => $module ) {
foreach ($module->fields_unprocessed as $module_field_name => $module_field) {
if ( isset( $module_field['type'] ) && 'select_icon' === $module_field['type'] ) {
$module_fields[ $module_name ][ $module_field_name ] = true;
* Retrieves credits of custom modules for VB
* @return array of credits info by module slug
public static function get_custom_modules_credits( $post_type = '' ) {
$modules = self::get_parent_and_child_modules( $post_type );
* @var $module_slug string
* @var $module ET_Builder_Module
foreach ( $modules as $module_slug => $module ) {
// Include custom module credits for displaying them within VB
if ( $module->_is_official_module ) {
if ( isset( $module->module_credits ) && is_array( $module->module_credits ) ) {
$result[ $module_slug ] = $module->module_credits;
static function get_media_quries( $for_js=false ) {
'min_width_1405' => '@media only screen and ( min-width: 1405px )',
'1100_1405' => '@media only screen and ( min-width: 1100px ) and ( max-width: 1405px)',
'981_1405' => '@media only screen and ( min-width: 981px ) and ( max-width: 1405px)',
'981_1100' => '@media only screen and ( min-width: 981px ) and ( max-width: 1100px )',
'min_width_981' => '@media only screen and ( min-width: 981px )',
'max_width_980' => '@media only screen and ( max-width: 980px )',
'768_980' => '@media only screen and ( min-width: 768px ) and ( max-width: 980px )',
'min_width_768' => '@media only screen and ( min-width: 768px )',
'max_width_767' => '@media only screen and ( max-width: 767px )',
'max_width_479' => '@media only screen and ( max-width: 479px )',
$media_queries['mobile'] = $media_queries['max_width_767'];
$media_queries = apply_filters( 'et_builder_media_queries', $media_queries );
if ( 'for_js' === $for_js ) {
$processed_queries = array();
foreach ( $media_queries as $key => $value ) {
$processed_queries[] = array( $key, $value );
$processed_queries = $media_queries;
return $processed_queries;
static function set_media_queries() {
self::$media_queries = self::get_media_quries();
static function get_media_query( $name ) {
if ( ! isset( self::$media_queries[ $name ] ) ) {
return self::$media_queries[ $name ];
static function get_style_key() {
if ( self::is_theme_builder_layout() ) {
return self::get_layout_id();
// Use a generic key in all other cases.
// For example, injector plugins that repeat a layout in a loop
// need to group that CSS under the same key.
static function get_style_array( $internal = false, $key = 0 ) {
$styles = $internal ? self::$internal_modules_styles : self::$styles;
$key = self::get_style_key();
return isset( $styles[ $key ] ) ? $styles[ $key ] : array();
* Intended to be used for unit testing
static function reset_styles() {
self::$internal_modules_styles = array();
self::$media_queries = array();
static function get_style( $internal = false, $key = 0 ) {
// use appropriate array depending on which styles we need
$styles_array = self::get_style_array( $internal, $key );
if ( empty( $styles_array ) ) {
global $et_user_fonts_queue;
if ( ! empty( $et_user_fonts_queue ) ) {
$output .= et_builder_enqueue_user_fonts( $et_user_fonts_queue );
$styles_by_media_queries = $styles_array;
$styles_count = (int) count( $styles_by_media_queries );
$media_queries_order = array_merge( array( 'general' ), array_values( self::$media_queries ) );
// make sure styles in the array ordered by media query correctly from bigger to smaller screensize
$styles_by_media_queries_sorted = array_merge( array_flip( $media_queries_order ), $styles_by_media_queries );
foreach ( $styles_by_media_queries_sorted as $media_query => $styles ) {
// skip wrong values which were added during the array sorting
if ( ! is_array( $styles ) ) {
$media_query_output = '';
$wrap_into_media_query = 'general' !== $media_query;
// sort styles by priority
et_()->uasort( $styles, array( 'ET_Builder_Element', 'compare_by_priority' ) );
// get each rule in a media query
foreach ( $styles as $selector => $settings ) {
$media_query_output .= sprintf(
$settings['declaration'],
( $wrap_into_media_query ? "\t" : '' )
// All css rules that don't use media queries are assigned to the "general" key.
// Wrap all non-general settings into media query.
if ( $wrap_into_media_query ) {
$media_query_output = sprintf(
'%3$s%3$s%1$s {%2$s%3$s}',
$output .= $media_query_output;
static function get_column_video_background( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$formatted_args = array();
foreach ( $args as $key => $value) {
$key_length = strlen( $key );
$formatted_args[ substr( $key, 0, ( $key_length - 2 ) ) ] = $value;
return self::get_video_background( $formatted_args, $conditional_tags, $current_page );
* Generate video background markup.
* @since 3.23 Add support for responsive settings.
* @param array $args Background values.
* @param array $conditional_tags Conditional tags.
* @param array $current_page Current page info.
* @return mixed Mixed background content generated as video markup.
static function get_video_background( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$base_name = isset( $args['computed_variables'] ) && isset( $args['computed_variables']['base_name'] ) ? $args['computed_variables']['base_name'] : 'background';
$device = isset( $args['computed_variables'] ) && isset( $args['computed_variables']['device'] ) ? $args['computed_variables']['device'] : 'desktop';
$suffix = ! empty( $device ) && 'desktop' !== $device ? "_{$device}" : '';
"{$base_name}_video_mp4{$suffix}" => '',
"{$base_name}_video_webm{$suffix}" => '',
"{$base_name}_video_width{$suffix}" => '',
"{$base_name}_video_height{$suffix}" => '',
$args = wp_parse_args( $args, $defaults );
if ( '' === $args["{$base_name}_video_mp4{$suffix}"] && '' === $args["{$base_name}_video_webm{$suffix}"] ) {
return do_shortcode( sprintf( '
<video loop="loop" autoplay playsinline muted %3$s%4$s>
( '' !== $args["{$base_name}_video_mp4{$suffix}"] ? sprintf( '<source type="video/mp4" src="%s" />', esc_url( $args["{$base_name}_video_mp4{$suffix}"] ) ) : '' ),
( '' !== $args["{$base_name}_video_webm{$suffix}"] ? sprintf( '<source type="video/webm" src="%s" />', esc_url( $args["{$base_name}_video_webm{$suffix}"] ) ) : '' ),
( '' !== $args["{$base_name}_video_width{$suffix}"] ? sprintf( ' width="%s"', esc_attr( intval( $args["{$base_name}_video_width{$suffix}"] ) ) ) : '' ),
( '' !== $args["{$base_name}_video_height{$suffix}"] ? sprintf( ' height="%s"', esc_attr( intval( $args["{$base_name}_video_height{$suffix}"] ) ) ) : '' )
static function clean_internal_modules_styles( $need_internal_styles = true ) {
// clean the styles array
self::$internal_modules_styles[ self::get_style_key() ] = array();
// set the flag to make sure new styles will be saved to the correct place
self::$prepare_internal_styles = $need_internal_styles;
// generate unique number to make sure module classes will be unique if shortcode is generated via ajax
self::$internal_modules_counter = rand( 10000, 99999 );
* Set the field dependencies based on the `show_if` or `show_if_not` key from the
* @param string $slug The module's slug. ie `et_pb_section`
* @param string $field_id The field id. id `background_color`
* @param array $field_info Associative array of the field's data.
protected static function set_field_dependencies( $slug, $field_id, $field_info ) {
// bail if the field_info is not an array.
if ( ! is_array( $field_info ) || ! self::$_->array_get( $field_info, 'bb_support', true ) ) {
// otherwise we keep going.
foreach ( array( 'show_if', 'show_if_not' ) as $dependency_type ) {
if ( ! isset( $field_info[ $dependency_type ] ) ) {
if ( ! self::$data_utils->is_assoc_array( $field_info[ $dependency_type ] ) ) {
foreach ( $field_info[ $dependency_type ] as $dependency => $value ) {
// dependency -> dependent (eg. et_pb_signup.provider.affects.first_name_field.show_if: mailchimp)
$address = self::$_->esc_array( array( $slug, $dependency, 'affects', $field_id, $dependency_type ), 'esc_attr' );
self::$data_utils->array_set( self::$field_dependencies, $address, self::$_->esc_array( $value, 'esc_attr' ) );
// dependent -> dependency (eg. et_pb_signup.first_name_field.show_if.provider: mailchimp)
$address = self::$_->esc_array( array( $slug, $field_id, $dependency_type, $dependency ), 'esc_attr' );
self::$data_utils->array_set( self::$field_dependencies, $address, self::$_->esc_array( $value, 'esc_attr' ) );
public static function get_field_dependencies( $post_type ) {
if ( self::$field_dependencies ) {
return self::$field_dependencies;
$all_modules = self::get_parent_and_child_modules( $post_type );
foreach ( $all_modules as $module_slug => $module ) {
$all_fields = $module->sort_fields( $module->_get_fields() );
foreach ( $all_fields as $field_id => $field_info ) {
if ( isset( $field_info['type'] ) && 'composite' === $field_info['type'] ) {
foreach ( $field_info['composite_structure'] as $field ) {
foreach ( $field['controls'] as $control => $data ) {
self::set_field_dependencies( $module_slug, $control, $data );
self::set_field_dependencies( $module_slug, $field_id, $field_info );
return self::$field_dependencies;
static function set_style( $function_name, $style ) {
$selectors = is_array( $style['selector'] ) ? $style['selector'] : array( $style['selector'] );
foreach ( $selectors as $item ) {
foreach ( self::$_->sanitize_css_placeholders( $item ) as $selector ) {
$selector = apply_filters( "{$function_name}_css_selector", $selector );
self::_set_style( $function_name, array_merge( $style, array( 'selector' => $selector ) ) );
* Applies the responsive and hover style for a specified option