: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if (!isset($col['styling'][$prop])) {
$col['styling'][$prop] = '';
if (strpos($col['styling'][$prop], ',') === false && is_numeric($v)) {
//the first value is old value of v5(if user will try to downgrade FW),the second after converting
$col['styling'][$prop] .= ',' . $v;
if (!isset($col['styling']['breakpoint_' . $bp])) {
$col['styling']['breakpoint_' . $bp] = array();
if ($v === '%') {//unit proop
$col['styling']['breakpoint_' . $bp][$prop] = $v;
if (!isset($col['styling']['breakpoint_' . $bp][$prop])) {
$col['styling']['breakpoint_' . $bp][$prop] = '';
if (strpos($col['styling']['breakpoint_' . $bp][$prop], ',') === false && is_numeric($v)) {
$col['styling']['breakpoint_' . $bp][$prop] .= ',' . $v;
$update = $hasChange = true;
if ($hasChange === true) {
for ($i = 0; $i < $bpLength - 1; ++$i) {
if (!empty($col['styling']['breakpoint_' . $bp])) {
$st = $col['styling']['breakpoint_' . $bp];
foreach ($allowed as $p) {
for ($j = $i + 1; $j < $bpLength; ++$j) {
$parentBp = $breakpints[$j];
$parentSt = $parentBp === 'desktop' ? $col['styling'] : (isset($col['styling']['breakpoint_' . $parentBp]) ? $col['styling']['breakpoint_' . $parentBp] : null);
if (isset($parentSt[$p])) {
if (isset($parentSt) && ($parentSt[$p] == $st[$p] || strpos($parentSt[$p], $st[$p]) !== false)) {
unset($col['styling']['breakpoint_' . $bp][$p]);
if (empty($col['styling']['breakpoint_' . $bp])) {
unset($col['styling']['breakpoint_' . $bp]);
if (!empty($col['modules'])) {
foreach ($col['modules'] as &$mod) {
if (!empty($mod['cols'])) {
foreach ($mod['cols'] as &$sub_col) {
if (isset($convert[$sub_col['element_id']])) {
foreach ($convert[$sub_col['element_id']] as $bp => $props) {
if (in_array($bp, $breakpints, true)) {
foreach ($props as $prop => $v) {
if (in_array($prop, $allowed, true)) {
if ($v === '%') {//unit proop
$sub_col['styling'][$prop] = $v;
if (!isset($sub_col['styling'][$prop])) {
$sub_col['styling'][$prop] = '';
if (strpos($sub_col['styling'][$prop], ',') === false && is_numeric($v)) {
$sub_col['styling'][$prop] .= ',' . $v;
if (!isset($sub_col['styling']['breakpoint_' . $bp])) {
$sub_col['styling']['breakpoint_' . $bp] = array();
if ($v === '%') {//unit proop
$sub_col['styling']['breakpoint_' . $bp][$prop] = $v;
if (!isset($sub_col['styling']['breakpoint_' . $bp][$prop])) {
$sub_col['styling']['breakpoint_' . $bp][$prop] = '';
if (strpos($sub_col['styling']['breakpoint_' . $bp][$prop], ',') === false && is_numeric($v)) {
$sub_col['styling']['breakpoint_' . $bp][$prop] .= ',' . $v;
$update = $hasChange = true;
if ($hasChange === true) {
for ($i = 0; $i < $bpLength - 1; ++$i) {
if (!empty($sub_col['styling']['breakpoint_' . $bp])) {
$st = $sub_col['styling']['breakpoint_' . $bp];
foreach ($allowed as $p) {
for ($j = $i + 1; $j < $bpLength; ++$j) {
$parentBp = $breakpints[$j];
$parentSt = $parentBp === 'desktop' ? $sub_col['styling'] : (isset($sub_col['styling']['breakpoint_' . $parentBp]) ? $sub_col['styling']['breakpoint_' . $parentBp] : null);
if (isset($parentSt[$p])) {
if (isset($parentSt) && ($parentSt[$p] == $st[$p] || strpos($parentSt[$p], $st[$p]) !== false)) {
unset($sub_col['styling']['breakpoint_' . $bp][$p]);
if (empty($sub_col['styling']['breakpoint_' . $bp])) {
unset($sub_col['styling']['breakpoint_' . $bp]);
unset($convert, $allowed, $breakpints);
self::$builder_is_saving = true;
ThemifyBuilder_Data_Manager::update_builder_meta($id, $builder_data, false);
* Remove Builder static content, leaving an empty shell to inject Builder output in later.
public static function clear_static_content(?string $content):?string {
global $wp_current_filter;
if (!in_array('get_the_excerpt', $wp_current_filter, true) && !Themify_Builder_Model::is_builder_disabled_for_post_type(get_post_type()) && ThemifyBuilder_Data_Manager::has_static_content($content)) {
$empty_placeholder = ThemifyBuilder_Data_Manager::add_static_content_wrapper('');
$content = ThemifyBuilder_Data_Manager::update_static_content_string($empty_placeholder, $content);
* Hook to content filter to show builder output
public static function builder_show_on_front(?string $content=''):?string {
$is_gs_admin_page = isset($_GET['page']) && 'themify-global-styles' === $_GET['page'] && is_admin();
// Exclude builder output in admin post list mode excerpt, Don`t show builder on product single description
($is_gs_admin_page === false && (!is_object($post) || ( is_admin() && !themify_is_ajax() ) || (!Themify_Builder_Model::is_front_builder_activate() && false === apply_filters('themify_builder_display', true, $post_id) ) || post_password_required()
)) || (themify_is_woocommerce_active() && (themify_is_shop() || is_singular('product')))/* disable Builder display on WC pages. Those are handled in Themify_Builder_Plugin_Compat */
global $wp_current_filter;
if (in_array('get_the_excerpt', $wp_current_filter, true)) {
return $content ? $content : self::get_first_text($post_id);
if (strpos($post->post_content, '<!--more-->') !== false && !is_single($post->ID) && !is_page($post->ID)) {
return self::render($post_id, $content);
* Renders Builder data for a given $post_id
* If $content is sent, the function will attempt to find the proper place
* where Builder content should be injected to. Otherwise, raw output is returned.
public static function render(?int $post_id,?string $content = ''):?string {
if (!Themify_Builder_Model::is_builder_disabled_for_post_type(get_post_type($post_id))) {
/* in the frontend editor, render only a container and set the frontend_builder_ids[] property */
if ($post_id == self::$builder_active_id && Themify_Builder_Model::is_front_builder_activate()) {
Themify_Builder_Stylesheet::enqueue_stylesheet(false, $post_id);
$builder_output = sprintf('<div id="themify_builder_content-%1$d" data-postid="%1$d" class="tf_clear themify_builder_content themify_builder_content-%1$d themify_builder"></div>', $post_id);
Themify_Builder::get_builder_stylesheet('');
/* Infinite-loop prevention */
if (in_array($post_id, self::$post_ids, true)) {
/* we have already rendered this, go back. */
$builder_data = ThemifyBuilder_Data_Manager::get_data($post_id);
if(empty($builder_data) && !Themify_Builder_Model::is_frontend_editor_page()){
self::$post_ids[] = $post_id;
$template_args = array();
// Check For page break module
$page_breaks = self::count_page_break_modules($post_id);
$pb_result = self::load_current_inner_page_content($builder_data, $page_breaks);
$builder_data = $pb_result['builder_data'];
$template_args['pb_pagination'] = $pb_result['pagination'];
$template_args['builder_output'] = $builder_data;
$template_args['builder_id'] = $post_id;
$isLoop=self::$is_loop===true || $ThemifyBuilder->in_the_loop === true;
$template = $isLoop ? 'builder-layout-part-output.php' : 'builder-output.php';
self::$is_rendering = true;
$builder_output = Themify_Builder_Component_Module::retrieve_template($template, $template_args, THEMIFY_BUILDER_TEMPLATES_DIR, '', false);
self::$is_rendering = false;
if (strpos($builder_output, 'module_row') !== false) {
do_action('themify_builder_before_template_content_render');
Themify_Builder_Stylesheet::enqueue_stylesheet(false, $post_id);
Themify_Builder::get_builder_stylesheet($builder_output);
/* render finished, make the Builder content of this particular post available to be rendered again */
array_pop(self::$post_ids);
/* if $content parameter is empty, simply return the builder output, no need to replace anything */
/* find where Builder output should be injected to inside $content */
// Start builder block replacement
if (Themify_Builder_Model::is_gutenberg_active() && Themify_Builder_Gutenberg::has_builder_block($content)) {
$content = ThemifyBuilder_Data_Manager::update_static_content_string('', $content); // remove static content tag
$content = Themify_Builder_Gutenberg::replace_builder_block_tag($builder_output, $content);
elseif (ThemifyBuilder_Data_Manager::has_static_content($content)) {
$content = ThemifyBuilder_Data_Manager::update_static_content_string($builder_output, $content);
$display_position = apply_filters('themify_builder_display_position', 'below', $post_id);
if ('above' === $display_position) {
$content = $builder_output . $content;
$content .= $builder_output;
* Load stylesheet for Builder if necessary.
public static function get_builder_stylesheet(string $builder_output,bool $force = false) {
/* in RSS feeds and REST API endpoints, do not output the scripts */
if (self::$frontedit_active === true || is_feed() || themify_is_rest() || (isset($_GET['tf-scroll']) && $_GET['tf-scroll'] === 'yes' && themify_is_ajax())) {
if ($is === null && ($force === true || Themify_Builder_Model::is_front_builder_activate() || strpos($builder_output, 'module_row') !== false )) { // check if builder has any content
Themify_Enqueue_Assets::addPreLoadJs(THEMIFY_BUILDER_URI . '/js/themify-builder-script.js', THEMIFY_VERSION);
if (!themify_is_themify_theme() || !Themify_Enqueue_Assets::addCssToFile('builder-styles-css', THEMIFY_BUILDER_URI . '/css/themify-builder-style.css', THEMIFY_VERSION, 'themify_common')) {
themify_enque_style('builder-styles-css', THEMIFY_BUILDER_URI . '/css/themify-builder-style.css', null, THEMIFY_VERSION);
if (is_rtl() && !Themify_Enqueue_Assets::addCssToFile('builder-styles-rtl', THEMIFY_BUILDER_URI . '/css/themify-builder-style-rtl.css', THEMIFY_VERSION, 'builder-styles-css')) {
themify_enque_style('builder-styles-rtl', THEMIFY_BUILDER_URI . '/css/themify-builder-style-rtl.css', null, THEMIFY_VERSION);
Themify_Enqueue_Assets::addLocalization('done', 'tb_style', true);
* Check Builder can edit current post or not
public static function builder_is_available():?int {
$post_id = themify_shop_pageId();
} elseif (!is_archive() && !is_home() && !is_search() && !is_404()) {
$p = get_queried_object(); //get_the_ID can back wrong post id
$post_id = isset($p->ID) ? $p->ID : null;
$is = Themify_Builder_Model::is_frontend_editor_page($post_id);
$is = !Themify_Builder_Model::is_builder_disabled_for_post_type(get_post_type($post_id));
$is = apply_filters('themify_builder_admin_bar_is_available', $is);
return $is === true ? $post_id : null;
public static function body_class(array $classes):array {
if (Themify_Builder_Model::is_frontend_editor_page()) {
if (Themify_Builder_Model::is_front_builder_activate()) {
$classes[] = 'themify_builder_active builder-breakpoint-desktop';
if (Themify_Global_Styles::$isGlobalEditPage === true) {
if (Themify_Builder_Model::is_animation_active()) {
$classes[] = 'tb_animation_on';
return apply_filters('themify_builder_body_class', $classes);
public static function inline_css():void {
$is_animation = Themify_Builder_Model::is_animation_active();
$is_parallax = Themify_Builder_Model::is_parallax_active();
$is_lax = Themify_Builder_Model::is_scroll_effect_active();
$is_sticky = Themify_Builder_Model::is_sticky_scroll_active();
$is_builder_active = Themify_Builder_Model::is_front_builder_activate();
$bp = themify_get_breakpoints();
$tablet = $bp['tablet'][1];
if ($is_animation !== false) {
$st = '.tb_animation_on{overflow-x:hidden}.themify_builder .wow{visibility:hidden;animation-fill-mode:both}[data-tf-animation]{will-change:transform,opacity,visibility}';
if ($is_animation === 'm') {
$st = '@media(min-width:' . $tablet . 'px){' . $st . '}';
if ($is_builder_active === true) {
$st .= '.hover-wow.tb_hover_animate{animation-delay:initial!important}';
$noscript = '.themify_builder .wow,.wow .tf_lazy{visibility:visible!important}';
if ($is_parallax !== true) {
$p = '.themify_builder .builder-parallax-scrolling{background-position-y:0!important}';
if ($is_parallax === 'm') {
$p = '@media(max-width:' . $tablet . 'px){' . $p . '}';
$p = '.themify_builder .tf_lax_done{transition-duration:.8s;transition-timing-function:cubic-bezier(.165,.84,.44,1)}';
$p = '@media(min-width:' . $tablet . 'px){' . $p . '}';
$p .= '@media(max-width:' . ($tablet + 2) . 'px){.themify_builder .tf_lax_done{opacity:unset!important;transform:unset!important;filter:unset!important}}';
if ($is_sticky !== false) {
$p = '[data-sticky-active].tb_sticky_scroll_active{z-index:1}[data-sticky-active].tb_sticky_scroll_active .hide-on-stick{display:none}';
if ($is_sticky === 'm') {
$p = '@media(min-width:' . $tablet . 'px){' . $p . '}';
$bp = array('desktop' => ($bp['tablet_landscape'][1] + 1)) + $bp;
$p = $is_builder_active === true ? 'display:none!important' : 'width:0!important;height:0!important;padding:0!important;visibility:hidden!important;margin:0!important;display:table-column!important;background:0!important;content-visibility:hidden;overflow:hidden!important';
foreach ($bp as $k => $v) {
$visiblity_st .= '@media(';
$visiblity_st .= 'min-width:' . $v[0] . 'px) and (max-width:' . $v[1] . 'px)';
$visiblity_st .= $k === 'desktop' ? 'min' : 'max';
$visiblity_st .= '-width:' . $v . 'px)';
$visiblity_st .= '{.hide-' . $k . '{' . $p . '}}';
$gutters = Themify_Builder_Model::get_gutters(false);
foreach ($gutters as $k => $v) {
$gutter_st .= '--' . $k . ':' . $v . '%;';
$st .= 'div.row_inner,div.module_subrow{' . $gutter_st . '}';
$st .= '@media(max-width:' . $tablet . 'px){div.module-gallery-grid{--galn:var(--galt)}}';
$st .= '@media(max-width:' . $mobile . 'px){
.themify_map.tf_map_loaded{width:100%!important}
.ui.builder_button,.ui.nav li a{padding:.525em 1.15em}
.fullheight>.row_inner:not(.tb_col_count_1){min-height:0}
div.module-gallery-grid{--galn:var(--galm);gap:8px}
echo '<style id="tb_inline_styles" data-no-optimize="1">', $st, '</style>';
echo '<noscript><style>', $noscript, '</style></noscript>';
public static function reset_builder_query(string $action = 'reset'):void {
if ('reset' === $action) {
remove_filter('the_content', array(__CLASS__, 'builder_show_on_front'), 11);
} elseif ('restore' === $action) {
add_filter('the_content', array(__CLASS__, 'builder_show_on_front'), 11);
* Load content of only current inner page
* @param $page_breaks count of page break modules
public static function load_current_inner_page_content(array $builder_data,int $page_breaks):array {
$p = !empty($_GET['tb-page']) ? (int) $_GET['tb-page'] : 1;
foreach ($builder_data as $row) {
if (isset($row['styling']['custom_css_row']) && strpos($row['styling']['custom_css_row'], 'tb-page-break') !== false) {
$temp_data[$page_num][] = $row;
$p = ($p > $page_breaks || $p < 1) ? 1 : $p;
'pagination' => Themify_Builder_Component_Module::get_pagination('', '', 'tb-page', 0, $page_breaks, $p),
'builder_data' => isset($temp_data[$p]) ? $temp_data[$p] : $builder_data
* Check builder content for page break module
private static function count_page_break_modules(int $post_id):int {
$data = ThemifyBuilder_Data_Manager::get_data($post_id, true);
return preg_match_all('/"mod_name":"page-break"/', $data, $modules);
* Actions to perform when login via Login module fails
public static function wp_login_failed($username) {
if (isset($_SERVER['HTTP_REFERER'])) {
$referrer = $_SERVER['HTTP_REFERER']; // where did the post submission come from?
// if there's a valid referrer, and it's not the default log-in screen
if (isset($_POST['tb_login'], $_POST['tb_redirect_fail']) && (int) $_POST['tb_login'] === 1 && !empty($referrer) && !strstr($referrer, 'wp-login') && !strstr($referrer, 'wp-admin')) {
wp_safe_redirect($_POST['tb_redirect_fail']);
private static function plugins_compatibility() {
'autooptimize' => 'autoptimize/autoptimize.php',
'bwpminify' => 'bwp-minify/bwp-minify.php',
'cachepress' => 'sg-cachepress/sg-cachepress.php',
'dokan' => 'dokan-pro/dokan-pro.php',
'duplicateposts' => 'duplicate-post/duplicate-post.php',