: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
function et_fb_shortcode_tags() {
$shortcode_tag_names = array();
foreach ( $shortcode_tags as $shortcode_tag_name => $shortcode_tag_cb ) {
$shortcode_tag_names[] = $shortcode_tag_name;
return implode( '|', $shortcode_tag_names );
function et_fb_prepare_library_cats() {
$raw_categories_array = apply_filters( 'et_pb_new_layout_cats_array', get_terms( 'layout_category', array( 'hide_empty' => false ) ) );
$clean_categories_array = array();
if ( is_array( $raw_categories_array ) && ! empty( $raw_categories_array ) ) {
foreach( $raw_categories_array as $category ) {
$clean_categories_array[] = array(
'name' => html_entity_decode( $category->name ),
'id' => $category->term_id,
'slug' => $category->slug,
return $clean_categories_array;
function et_fb_get_layout_type( $post_id ) {
return et_fb_get_layout_term_slug( $post_id, 'layout_type' );
function et_fb_get_layout_term_slug( $post_id, $term_name ) {
$post_terms = wp_get_post_terms( $post_id, $term_name );
$slug = $post_terms[0]->slug;
function et_fb_comments_template() {
return ET_BUILDER_DIR . 'comments_template.php';
function et_fb_modify_comments_request( $params ) {
// modify the request parameters the way it doesn't change the result just to make request with unique parameters
$params->query_vars['type__not_in'] = 'et_pb_comments_random_type_9999';
function et_fb_comments_submit_button( $submit_button ) {
'<button name="%1$s" type="submit" id="%2$s" class="%3$s">%4$s</button>',
esc_attr( 'et_pb_submit' ),
esc_attr( 'submit et_pb_button' ),
esc_html_x( 'Submit Comment', 'et_builder' )
* Generate custom comments number for Comments Module preview in Theme Builder.
function et_builder_set_comments_number() {
* Generate Dummy comment for Comments Module preview in Theme Builder.
function et_builder_add_fake_comments() {
return array( new WP_Comment( (object) array(
'comment_author' => 'Jane Doe',
'comment_date' => '2019-01-01 12:00:00',
'comment_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar nulla eu purus pharetra mollis. Nullam fringilla, ligula sit amet placerat rhoncus, arcu dui hendrerit ligula, ac rutrum mi neque quis orci. Morbi at tortor non eros feugiat commodo.',
'comment_approved' => '1',
* Append all default comment fields such as Author, Email, Website to Comment field for Comments Module preview in Theme Builder.
* @see comment_form() in /wp-includes/comment-template.php
function et_builder_set_comment_fields( $field ) {
$req = get_option( 'require_name_email' );
$commenter = wp_get_current_commenter();
$html_req = $req ? " required='required'" : '';
'<p class="comment-form-author"><label for="author">%1$s%2$s</label><input id="author" name="author" type="text" value="%3$s" size="30" maxlength="245"%4$s /></p>',
esc_html__( 'Name', 'et_builder' ),
$req ? ' <span class="required">*</span>' : '',
esc_attr( $commenter['comment_author'] ),
et_core_intentionally_unescaped( $html_req, 'fixed_string' )
'<p class="comment-form-email"><label for="email">%1$s%2$s</label><input id="email" name="email" type="email" value="%3$s" size="30" maxlength="100" aria-describedby="email-notes"%4$s /></p>',
esc_html__( 'Email', 'et_builder' ),
$req ? ' <span class="required">*</span>' : '',
esc_attr( $commenter['comment_author_email'] ),
et_core_intentionally_unescaped( $html_req, 'fixed_string' )
'<p class="comment-form-url"><label for="url">%1$s</label><input id="url" name="url" type="url" value="%2$s" size="30" maxlength="200" /></p>',
esc_html__( 'Website', 'et_builder' ),
esc_attr( $commenter['comment_author_url'] )
return $field . $author . $email . $url;
// comments template cannot be generated via AJAX so prepare it beforehand
function et_fb_get_comments_markup() {
$post_type = isset( $post->post_type ) ? $post->post_type : false;
// Modify the Comments content for the Comment Module preview in TB.
if ( et_theme_builder_is_layout_post_type( $post_type ) ) {
add_filter( 'comments_open', '__return_true' );
add_filter( 'comment_form_field_comment', 'et_builder_set_comment_fields' );
add_filter( 'get_comments_number', 'et_builder_set_comments_number' );
add_filter( 'comments_array', 'et_builder_add_fake_comments' );
// Modify the comments request to make sure it's unique.
// Otherwise WP generates SQL error and doesn't allow multiple comments sections on single page
add_action( 'pre_get_comments', 'et_fb_modify_comments_request', 1 );
// include custom comments_template to display the comment section with Divi style
add_filter( 'comments_template', 'et_fb_comments_template' );
// Modify submit button to be advanced button style ready
add_filter( 'comment_form_submit_button', 'et_fb_comments_submit_button' );
// Custom action before calling comments_template.
do_action( 'et_fb_before_comments_template' );
comments_template( '', true );
$comments_content = ob_get_contents();
// Custom action after calling comments_template.
do_action( 'et_fb_after_comments_template' );
// remove all the actions and filters to not break the default comments section from theme
remove_filter( 'comments_template', 'et_fb_comments_template' );
remove_action( 'pre_get_comments', 'et_fb_modify_comments_request', 1 );
return $comments_content;
// List of shortcode wrappers that requires adjustment in VB. Plugins which uses fullscreen dimension
// tend to apply negative positioning which looks inappropriate on VB's shortcode mechanism
function et_fb_known_shortcode_wrappers() {
return apply_filters( 'et_fb_known_shortcode_wrappers', array(
'.fullscreen-container', // revolution slider,
'.esg-container-fullscreen-forcer', // essential grid
'.ls-wp-fullwidth-helper', // layer slider
function et_builder_autosave_interval() {
return apply_filters( 'et_builder_autosave_interval', et_builder_heartbeat_interval() / 2 );
function et_fb_heartbeat_settings($settings) {
$settings['suspension'] = 'disable';
$settings['interval'] = et_builder_heartbeat_interval();
add_filter( 'heartbeat_settings', 'et_fb_heartbeat_settings', 11 );
// This function is used to add dynamic helpers whose content changes frequently
// because depending on the current post or options that can be edited by the user.
function et_fb_get_dynamic_backend_helpers() {
// Override $post data if current visual builder is rendering layout block; This is needed
// because block editor might be used in CPT that has no frontend such as reusable block's
// `wp_block` CPT so layout block preview needs to be rendered using latest / other post
// frontend. To correctly render and update the layout, adjust post ID and other data accordingly
$is_layout_block_preview = ET_GB_Block_Layout::is_layout_block_preview();
if ( $is_layout_block_preview && isset( $_GET['et_post_id' ] ) ) {
$et_post_id = (int) $_GET['et_post_id'];
$post = get_post( $et_post_id );
$post_type = isset( $post->post_type ) ? $post->post_type : false;
$post_id = isset( $post->ID ) ? $post->ID : false;
$post_status = isset( $post->post_status ) ? $post->post_status : false;
$post_title = isset( $post->post_title ) ? esc_attr( $post->post_title ) : false;
$post_thumbnail_alt = has_post_thumbnail() ? get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) : false;
$post_thumbnail_title = has_post_thumbnail() ? get_post( get_post_thumbnail_id() )->post_title : false;
$current_user = wp_get_current_user();
if ( 'et_pb_layout' === $post_type ) {
$layout_type = et_fb_get_layout_type( $post_id );
$layout_scope = et_fb_get_layout_term_slug( $post_id, 'scope' );
$layout_built_for = get_post_meta( $post_id, '_et_pb_built_for_post_type', 'page' );
$current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
// disable product tour on the app launch, so it won't be started next time.
if ( et_builder_is_product_tour_enabled() ) {
et_fb_disable_product_tour();
$theme_builder_layouts = et_theme_builder_get_template_layouts();
// In some cases when page created using Polylang
// it may have predefined content, so inital content is not empty.
$has_predefined_content = isset( $_GET['from_post'] ) && 'empty' !== $_GET['from_post'] ? 'yes' : 'no';
// Validate the Theme Builder body layout and its post content module, if any.
$has_tb_layouts = ! empty( $theme_builder_layouts );
$is_tb_layout = et_theme_builder_is_layout_post_type( $post_type );
$tb_body_layout = et_()->array_get( $theme_builder_layouts, ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE, array() );
$tb_body_has_post_content = $tb_body_layout && et_theme_builder_layout_has_post_content( $tb_body_layout );
$has_valid_body_layout = ! $has_tb_layouts || $is_tb_layout || $tb_body_has_post_content;
// Prepare a Post Content module failure notification if there are any
// Theme Builder layouts active for the current request.
$post_content_failure_notification = '';
if ( ! empty( $theme_builder_layouts ) ) {
$post_content_failure_notification = et_theme_builder_get_failure_notification_modal(
get_the_title( $theme_builder_layouts[ ET_THEME_BUILDER_TEMPLATE_POST_TYPE ] ),
$theme_builder_layouts[ ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE ]['enabled']
'site_url' => get_site_url(),
'locale' => get_user_locale(),
'debug' => defined( 'ET_DEBUG' ) && ET_DEBUG,
'postTitle' => $post_title,
'postStatus' => $post_status,
'postType' => $post_type,
'postThumbnailAlt' => $post_thumbnail_alt,
'postThumbnailTitle' => $post_thumbnail_title,
'isCustomPostType' => et_builder_is_post_type_custom( $post_type ) ? 'yes' : 'no',
'layoutType' => $layout_type,
'layoutScope' => $layout_scope,
'layoutBuiltFor' => $layout_built_for,
'hasPredefinedContent' => $has_predefined_content,
'publishCapability' => ( is_page() && ! current_user_can( 'publish_pages' ) ) || ( ! is_page() && ! current_user_can( 'publish_posts' ) ) ? 'no_publish' : 'publish',
'ajaxUrl' => is_ssl() ? admin_url( 'admin-ajax.php' ) : admin_url( 'admin-ajax.php', 'http' ),
'et_account' => et_core_get_et_account(),
'productTourStatus' => et_builder_is_product_tour_enabled() ? 'on' : 'off',
'gutterWidth' => (string) et_get_option( 'gutter_width', '3' ),
'sectionPadding' => et_get_option( 'section_padding', 4 ),
'cookie_path' => SITECOOKIEPATH,
'etBuilderAccentColor' => et_builder_accent_color(),
'gmt_offset_string' => et_pb_get_gmt_offset_string(),
'currentUserDisplayName' => $current_user->display_name,
'currentRole' => et_pb_get_current_user_role(),
'currentUserCapabilities' => array(
'manageOptions' => current_user_can( 'manage_options' ),
'exportUrl' => et_fb_get_portability_export_url(),
'nonces' => et_fb_get_nonces(),
'currentPage' => et_fb_current_page_params(),
'appPreferences' => et_fb_app_preferences(),
'pageSettingsFields' => ET_Builder_Settings::get_fields(),
'pageSettingsValues' => ET_Builder_Settings::get_values(),
'abTestingSubjects' => false !== ( $all_subjects_raw = get_post_meta( $post_id, '_et_pb_ab_subjects', true ) ) ? explode( ',', $all_subjects_raw ) : array(),
'productTourText' => et_fb_get_product_tour_text( $post_id ),
'show_page_creation' => $is_layout_block_preview ? '' : get_post_meta( $post_id, '_et_pb_show_page_creation', true ),
'mediaButtons' => et_builder_get_media_buttons(),
'shortcode_tags' => et_fb_shortcode_tags(),
'sectionHeight' => et_get_option( 'tablet_section_height' ),
'sectionHeight' => et_get_option( 'phone_section_height' ),
'abTesting' => et_builder_ab_options( $post->ID ),
'conditionalTags' => et_fb_conditional_tag_params(),
'commentsModuleMarkup' => et_fb_get_comments_markup(),
'failureNotification' => et_builder_get_failure_notification_modal(),
'noBrowserSupportNotification' => et_builder_get_no_browser_notification_modal(),
* Filters taxonomies array.
* @param array Array of all registered taxonomies.
'getTaxonomies' => apply_filters( 'et_fb_taxonomies', et_fb_get_taxonomy_terms() ),
* Filters taxonomy labels.
* @param array Array of labels for all registered taxonomies.
'getTaxonomyLabels' => apply_filters( 'et_fb_taxonomy_labels', et_fb_get_taxonomy_labels() ),
'loginFormUrl' => esc_url( site_url( 'wp-login.php', 'login_post' ) ),
'forgotPasswordUrl' => esc_url( wp_lostpassword_url() ),
'logoutUrl' => esc_url( wp_logout_url() ),
'logoutUrlRedirect' => esc_url( wp_logout_url( $current_url ) ),
'themeOptionsUrl' => esc_url( et_pb_get_options_page_link() ),
'builderPreviewStyle' => ET_BUILDER_URI . '/styles/preview.css',
'themeCustomizerUrl' => et_pb_is_allowed( 'theme_customizer' ) ? add_query_arg( array(
'et_customizer_option_set' => 'theme',
'url' => urlencode( $current_url )
), admin_url( 'customize.php' ) ) : false,
'roleEditorUrl' => current_user_can( 'manage_options' ) ? add_query_arg( array( 'page' => 'et_divi_role_editor' ), admin_url( 'admin.php' ) ) : false,
'manageLibraryUrl' => current_user_can( 'manage_options' ) ? add_query_arg( array( 'post_type' => 'et_pb_layout' ), admin_url( 'edit.php' ) ) : false,
'ajaxUrl' => is_ssl() ? admin_url( 'admin-ajax.php' ) : admin_url( 'admin-ajax.php', 'http' ),
'et_pb_countdown_timer' => array(
'date_time' => gmdate( 'Y-m-d H:i', current_time( 'timestamp' ) + ( 30 * 86400 ) ), // next 30 days from current day
'isLayout' => et_theme_builder_is_layout_post_type( $post_type ),
'layoutPostTypes' => et_theme_builder_get_layout_post_types(),
'bodyLayoutPostType' => ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE,
'postContentModules' => et_theme_builder_get_post_content_modules(),
'hasValidBodyLayout' => $has_valid_body_layout,
'noPostContentFailureNotification' => $post_content_failure_notification,
'loginAs' => sprintf( esc_html__( 'Login as %s', 'et_builder' ), $current_user->display_name ),
'<div class="et_pb_section"><div class="et_pb_row"><div class="et_pb_column et_pb_column_4_4">
<h1>Post Content Heading 1</h1>
<p>Post Content Paragraph Text. Lorem ipsum dolor sit amet, <a href="#">consectetur adipiscing elit</a>. Ut vitae congue libero, nec finibus purus. Vestibulum egestas orci vel ornare venenatis. Sed et ultricies turpis. Donec sit amet rhoncus erat. Phasellus volutpat vitae mi eu aliquam.</p>
<h2>Post Content Heading 2</h2>
<p>Curabitur a commodo sapien, at pellentesque velit. Vestibulum ornare vulputate. Mauris tempus massa orci, vitae lacinia tortor maximus sit amet. In hac habitasse platea dictumst. Praesent id tincidunt dolor. Morbi gravida sapien convallis sapien tempus consequat. </p>
<h3>Post Content Heading 3</h3>
<p>Post Content Block Quote. Vehicula velit ut felis semper, non convallis dolor fermentum. Sed sapien nisl, tempus ut semper sed, congue quis leo. Integer nec suscipit lacus. Duis luctus eros dui, nec finibus lectus tempor nec. Pellentesque at tincidunt turpis.</p>
<img src="' . ET_BUILDER_PLACEHOLDER_LANDSCAPE_IMAGE_DATA . '" alt="" />
<h4>Post Content Heading 4</h4>
<li>Vestibulum posuere</li>
<li>Mi interdum nunc dignissim auctor</li>
<li>Cras non dignissim quam, at volutpat massa</li>
<h5>Post Content Heading 5</h5>
<li>Ut mattis orci in scelerisque tempus</li>
<li>Velit urna sagittis arcu</li>
<li>Mon ultrices risus lectus non nisl</li>
<h6>Post Content Heading 6</h6>
<p>posuere nec lectus sit amet, pulvinar dapibus sapien. Donec placerat erat ac fermentum accumsan. Nunc in scelerisque dui. Etiam vitae purus velit. Proin dictum auctor mi, eu congue odio tempus et. Curabitur ac semper ligula. Praesent purus ligula, ultricies vel porta ac, elementum et lacus. Nullam vitae augue aliquet, condimentum est ut, vehicula sapien. Donec euismod, sem et elementum finibus, lacus mauris pulvinar enim, nec faucibus sapien neque quis sem. Vivamus suscipit tortor eget felis porttitor volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p>
'title' => ET_Builder_Settings::get_title(),
'toggles' => ET_Builder_Settings::get_toggles(),
'globalPresets' => ET_Builder_Element::get_global_presets(),
'module_cache_filename_id' => ET_Builder_Element::get_cache_filename_id( $post_type ),
'registeredPostTypeOptions' => et_get_registered_post_type_options(),
'wrapperPrefix' => ET_BUILDER_CSS_WRAPPER_PREFIX,
'containerPrefix' => ET_BUILDER_CSS_CONTAINER_PREFIX,
'layoutPrefix' => ET_BUILDER_CSS_LAYOUT_PREFIX,
'prefix' => ET_BUILDER_CSS_PREFIX,
$custom_defaults_unmigrated = et_get_option( ET_Builder_Global_Presets_Settings::CUSTOM_DEFAULTS_UNMIGRATED_OPTION, false );
if ( $custom_defaults_unmigrated ) {
$helpers['customDefaultsUnmigrated'] = ET_Builder_Global_Presets_Settings::migrate_custom_defaults_to_global_presets( $custom_defaults_unmigrated );
$helpers['dynamicContentFields'] = et_builder_get_dynamic_content_fields( $post_id, 'edit' );
// This function is used to add static helpers whose content changes rarely
// eg: google fonts, module defaults and so on.
function et_fb_get_static_backend_helpers($post_type) {
$custom_user_fonts = et_builder_get_custom_fonts();
$use_google_fonts = et_core_use_google_fonts();
$websafe_fonts = et_builder_get_websafe_fonts();
$google_fonts = $websafe_fonts;
if ( $use_google_fonts ) {
$google_fonts = array_merge( $websafe_fonts, et_builder_get_google_fonts() ) ;
$google_fonts = array_merge( array( 'Default' => array() ), $google_fonts );
* @param array $modules_array.
$fb_modules_array = apply_filters( 'et_fb_modules_array', ET_Builder_Element::get_modules_array( $post_type, true ) );
* Filters modules list which affect "Add New Row" button position.
* @param array $modules_list.
$modules_row_overlapping_add_new = apply_filters( 'et_fb_modules_row_overlapping_add_new', array(
'et_pb_social_media_follow',
$modules_defaults = array(
'title' => _x( 'Your Title Goes Here', 'Modules dummy content', 'et_builder' ),
'subtitle' => _x( 'Subtitle goes Here', 'et_builder' ),
'body' => _x( '<p>Your content goes here. Edit or remove this text inline or in the module Content settings. You can also style every aspect of this content in the module Design settings and even apply custom CSS to this text in the module Advanced settings.</p>',
'button' => _x( 'Click Here', 'Modules dummy content', 'et_builder' ),
'landscape' => ET_BUILDER_PLACEHOLDER_LANDSCAPE_IMAGE_DATA,
'portrait' => ET_BUILDER_PLACEHOLDER_PORTRAIT_IMAGE_DATA,
'video' => 'https://www.youtube.com/watch?v=FkQuawiGWUw',
$woocommerce_modules_defaults = array(
$app_preferences = et_fb_app_preferences_settings();
'blog_id' => get_current_blog_id(),
'diviLibraryUrl' => ET_BUILDER_DIVI_LIBRARY_URL,
'autosaveInterval' => et_builder_autosave_interval(),
'shortcodeObject' => array(),
'autosaveShortcodeObject' => array(),
'tinymcePlugins' => apply_filters( 'et_fb_tinymce_plugins', array(
'tinymceSkinUrl' => ET_FB_ASSETS_URI . '/vendors/tinymce-skin',
'tinymceCSSFiles' => esc_url( includes_url( 'js/tinymce' ) . '/skins/wordpress/wp-content.css' ),
'images_uri' => ET_BUILDER_URI .'/images',
'optionTemplate' => array(
'fieldNamePrefix' => et_pb_option_template()->template_prefix,
'templates' => et_pb_option_template()->templates(),
'data' => et_pb_option_template()->all(),
'componentDefinitions' => array(
'generalFields' => array(),