: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
defined('ABSPATH') || exit;
if (!class_exists('Themify_Builder',false)) :
* Main Themify Builder class
public static $registered_post_types = array('post', 'page');
* Define builder grid active or not
public static $frontedit_active = false;
* Define builder grid active id
public static $builder_active_id = null;
* Get status of builder content whether inside builder content or not
public static $is_loop = false;
* A list of posts which have been rendered by Builder
private static $post_ids = array();
public static $builder_is_saving = false;
private static $tooltips = [];
/* flag to indicate when Builder is rendering the output */
private static $is_rendering = false;
public $in_the_loop = false;//deprecated use $is_loop
* Themify Builder Constructor
public function __construct() {
public static function init():void {
add_action('init', array(__CLASS__, 'register_deprecated_cpt'));
// Include required files
Themify_Builder_Layouts::init();
Themify_Global_Styles::init();
self::plugins_compatibility();
if (is_admin() || themify_is_rest()) {
add_action('wp_loaded', array(__CLASS__, 'wp_loaded'));
add_action('wp', array(__CLASS__, 'wp_loaded'), 100);
// Login module action for failed login
add_action('wp_login_failed', array(__CLASS__, 'wp_login_failed'));
public static function register_deprecated_cpt():void {
Themify_Builder_Model::builder_cpt_check();
'plural' => __('Portfolios', 'themify'),
'singular' => __('Portfolio', 'themify'),
'rewrite' => apply_filters('themify_portfolio_rewrite', 'project'),
'menu_icon' => 'dashicons-portfolio'
'plural' => __('Highlights', 'themify'),
'singular' => __('Highlight', 'themify'),
'menu_icon' => 'dashicons-welcome-write-blog'
'plural' => __('Slides', 'themify'),
'singular' => __('Slide', 'themify'),
'supports' => array('title', 'editor', 'author', 'thumbnail', 'custom-fields'),
'menu_icon' => 'dashicons-slides'
'plural' => __('Testimonials', 'themify'),
'singular' => __('Testimonial', 'themify'),
'menu_icon' => 'dashicons-testimonial'
foreach ($post_types as $key => $args) {
if (Themify_Builder_Model::is_cpt_active($key) && Themify_Builder_Model::is_module_active($key)) {
if (!post_type_exists($key)) {
'name' => $args['plural'],
'singular_name' => $args['singular'],
'add_new' => __('Add New', 'themify'),
'add_new_item' => sprintf(__('Add New %s', 'themify'), $args['singular']),
'edit_item' => sprintf(__('Edit %s', 'themify'), $args['singular']),
'new_item' => sprintf(__('New %s', 'themify'), $args['singular']),
'view_item' => sprintf(__('View %s', 'themify'), $args['singular']),
'search_items' => sprintf(__('Search %s', 'themify'), $args['plural']),
'not_found' => sprintf(__('No %s found', 'themify'), $args['plural']),
'not_found_in_trash' => sprintf(__('No %s found in Trash', 'themify'), $args['plural']),
'menu_name' => $args['plural']
'supports' => isset($args['supports']) ? $args['supports'] : array('title', 'editor', 'thumbnail', 'custom-fields', 'excerpt'),
'show_in_nav_menus' => false,
'publicly_queryable' => true,
'rewrite' => array('slug' => isset($args['rewrite']) ? $args['rewrite'] : strtolower($args['singular'])),
'capability_type' => 'post',
'menu_icon' => isset($args['menu_icon']) ? $args['menu_icon'] : ''
register_post_type($key, $options);
self::$registered_post_types[]=$key;
if (!taxonomy_exists($key . '-category')) {
'name' => sprintf(__('%s Categories', 'themify'), $args['singular']),
'singular_name' => sprintf(__('%s Category', 'themify'), $args['singular']),
'search_items' => sprintf(__('Search %s Categories', 'themify'), $args['singular']),
'popular_items' => sprintf(__('Popular %s Categories', 'themify'), $args['singular']),
'all_items' => sprintf(__('All Categories', 'themify'), $args['singular']),
'parent_item' => sprintf(__('Parent %s Category', 'themify'), $args['singular']),
'parent_item_colon' => sprintf(__('Parent %s Category:', 'themify'), $args['singular']),
'edit_item' => sprintf(__('Edit %s Category', 'themify'), $args['singular']),
'update_item' => sprintf(__('Update %s Category', 'themify'), $args['singular']),
'add_new_item' => sprintf(__('Add New %s Category', 'themify'), $args['singular']),
'new_item_name' => sprintf(__('New %s Category', 'themify'), $args['singular']),
'separate_items_with_commas' => sprintf(__('Separate %s Category with commas', 'themify'), $args['singular']),
'add_or_remove_items' => sprintf(__('Add or remove %s Category', 'themify'), $args['singular']),
'choose_from_most_used' => sprintf(__('Choose from the most used %s Category', 'themify'), $args['singular']),
'menu_name' => sprintf(__('%s Category', 'themify'), $args['singular']),
'show_in_nav_menus' => false,
'show_admin_column' => true,
register_taxonomy($key . '-category', $key, $options);
public static function wp_loaded() {
add_filter('themify_builder_module_content', array('Themify_Builder_Model', 'format_text'));
if (Themify_Builder_Model::is_front_builder_activate() === false) {
$func = function_exists('wp_filter_content_tags') ? 'wp_filter_content_tags' : 'wp_make_content_images_responsive';
add_filter('themify_builder_module_content', $func);
add_filter('themify_image_make_responsive_image', $func);
add_action('themify_builder_background_styling', array(__CLASS__, 'display_tooltip'), 10, 3);
add_action( 'template_include', [ __CLASS__, 'template_include' ], 1000 );
elseif (isset($_GET['tb-id']) || isset($_COOKIE['tb_active'])) {
self::$builder_active_id = isset($_GET['tb-id']) ? (int) $_GET['tb-id'] : (int) $_COOKIE['tb_active'];
themify_disable_other_lazy();
if (did_action('wp') > 0) {
add_action('wp', array(__CLASS__, 'wp_hook'));
$is_ajax=themify_is_ajax();
$has_access=($is_admin===true && $is_ajax===false) || ($is_ajax===true && isset($_POST['admin']))?Themify_Access_Role::check_access_backend():Themify_Builder_Model::is_frontend_editor_page();
if ($has_access===true) {
add_action('wp_enqueue_scripts', array(__CLASS__, 'register_js_css'), 9);
add_action('wp_head', array(__CLASS__, 'inline_css'), -1001);
add_filter('the_content', array(__CLASS__, 'clear_static_content'), 1);
add_filter('the_content', array(__CLASS__, 'builder_show_on_front'), 11);
add_filter('body_class', array(__CLASS__, 'body_class'), 10);
// Add extra protocols like skype: to WordPress allowed protocols.
if (!has_filter('kses_allowed_protocols', 'themify_allow_extra_protocols') && function_exists('themify_allow_extra_protocols')) {
add_filter('kses_allowed_protocols', 'themify_allow_extra_protocols');
Themify_Builder_Stylesheet::init();
Themify_Builder_Visibility_Controls::init();
//convert old data to new grid data,can be removed after updates
add_action('wp_ajax_nopriv_tb_update_old_data', array(__CLASS__, 'convert_data'), 10);
add_action('wp_ajax_tb_update_old_data', array(__CLASS__, 'convert_data'), 10);
public static function template_include( $template ) {
if ( is_singular() && isset( $_GET['post_in_lightbox'] ) ) {
wp_enqueue_style( 'tb_post_lightbox', THEMIFY_BUILDER_CSS_MODULES . 'post-lightbox.css', null, THEMIFY_VERSION);
add_filter( 'body_class', [ __CLASS__, 'post_in_lightbox_body_class' ] );
if ( current_theme_supports( 'themify-builder-lightbox-template' ) ) {
$themify->header_enabled = false;
$themify->footer_enabled = false;
$themify->layout = 'sidebar-none';
$template = Themify_Builder_Component_Module::locate_template( 'post_in_lightbox.php' );
public static function post_in_lightbox_body_class( $classes ) {
$classes[] = 'tb_post_lightbox';
* Return all modules for a post as a two-dimensional array
public static function get_builder_modules_list(?int $post_id = null,?array $builder_data = null,bool $only_check = false) {
if ($builder_data === null) {
$builder_data = ThemifyBuilder_Data_Manager::get_data($post_id);
if ($only_check !== false) {
return strpos(json_encode($builder_data), 'mod_settings') !== false;
// loop through modules in Builder
if (is_array($builder_data)) {
foreach ($builder_data as $row) {
$_modules = array_merge( $_modules, self::_get_modules_recursive( $row ) );
* Find modules within the $row, recursively search for submodules
private static function _get_modules_recursive( $row ) : array {
if ( ! empty( $row['cols'] ) ) {
foreach ( $row['cols'] as $col ) {
if ( ! empty( $col['modules'] ) ) {
foreach ( $col['modules'] as $module ) {
if ( isset( $module['mod_name'] ) ) {
$modules = array_merge( $modules, self::_get_modules_recursive( $module ) );
* Return first not empty text module
public static function get_first_text(?int $post_id = null,?array $builder_data = null):string {
if ($builder_data === null) {
$builder_data = ThemifyBuilder_Data_Manager::get_data($post_id);
// loop through modules in Builder
if (is_array($builder_data)) {
foreach ($builder_data as $row) {
if (!empty($row['cols'])) {
foreach ($row['cols'] as $col) {
if (!empty($col['modules'])) {
foreach ($col['modules'] as $mod) {
if (isset($mod['mod_name']) && $mod['mod_name'] === 'text' && !empty($mod['mod_settings']['content_text'])) {
return $mod['mod_settings']['content_text'];
if (!empty($mod['cols'])) {
foreach ($mod['cols'] as $sub_col) {
if (!empty($sub_col['modules'])) {
foreach ($sub_col['modules'] as $sub_module) {
if (isset($sub_module['mod_name']) && $sub_module['mod_name'] === 'text' && !empty($sub_module['mod_settings']['content_text'])) {
return $sub_module['mod_settings']['content_text'];
private static function setup():void {
do_action('themify_builder_setup_modules');
if ((!empty($_REQUEST['action']) && !in_array($_REQUEST['action'], array('tb_update_tick', 'tb_load_module_partial', 'tb_render_element', 'tb_module_favorite', 'themify_regenerate_css_files_ajax', 'render_element_shortcode_ajaxify', 'get_ajax_post_types', 'tb_help'), true) && themify_is_ajax()) || Themify_Builder_Model::is_front_builder_activate()) {
Themify_Builder_Component_Module::load_modules();
public static function wp_hook():void {
do_action('themify_builder_run');
private static function includes_always():void {
if (Themify_Builder_Model::is_gutenberg_active()) {
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-gutenberg.php';
include THEMIFY_BUILDER_CLASSES_DIR . '/class-builder-data-manager.php';
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-stylesheet.php';
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-widgets.php';
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-visibility-controls.php';
if (current_user_can('publish_pages')) {
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-page.php';
include THEMIFY_BUILDER_INCLUDES_DIR . '/components/base.php';
include THEMIFY_BUILDER_INCLUDES_DIR . '/components/row.php';
include THEMIFY_BUILDER_INCLUDES_DIR . '/components/subrow.php';
include THEMIFY_BUILDER_INCLUDES_DIR . '/components/column.php';
include THEMIFY_BUILDER_INCLUDES_DIR . '/components/module.php';
private static function includes_active():void {
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-active.php';
private static function includes_admin():void {
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-admin.php';
* List of post types that support the editor
public static function builder_post_types_support():array {
$public_post_types = get_post_types(array(
$post_types = array_merge($public_post_types, array('post', 'page'));
foreach ($post_types as $key => $type) {
if (!post_type_supports($type, 'editor')) {
unset($post_types[$key]);
return apply_filters('themify_builder_post_types_support', $post_types);
* Register styles and scripts necessary for Builder template output.
* These are enqueued when a user initializes Builder or from a template output.
* Registered style handlers:
* Registered script handlers:
* themify-builder-module-plugins-js
* themify-builder-script-js
public static function register_js_css():void {
add_action('wp_footer', array(__CLASS__, 'footer_js'));
public static function footer_js():void {
'fullwidth_support' => Themify_Builder_Model::is_fullwidth_layout_supported(),
'is_sticky' => Themify_Builder_Model::is_sticky_scroll_active(),
'is_animation' => Themify_Builder_Model::is_animation_active(),
'is_parallax' => Themify_Builder_Model::is_parallax_active(),
'scrollHighlight' => apply_filters('themify_builder_scroll_highlight_vars', array()) //Inject variable values in Scroll-Highlight script
if (Themify_Builder_Model::is_front_builder_activate()) {
$modules=Themify_Builder_Component_Module::load_modules();
foreach ($modules as $id=>$m) {
$assets = $m::get_js_css();
Themify_Builder_Component_Module::add_modules_assets($id, $assets);
elseif (!empty(self::$tooltips)) {
Themify_Enqueue_Assets::addLocalization('builder_tooltips', self::$tooltips);
$offset = themify_builder_get('setting-scrollto_offset', 'builder_scrollTo');
$args['scrollHighlight']['offset'] = (int) $offset;
$speed = themify_builder_get('scrollto_speed', 'builder_scrollTo_speed');
$args['scrollHighlight']['speed'] = ( (float) $speed * 1000 ) + .01; /* .01 second is added in case user enters 0 to disable the animation */
$args['addons'] = Themify_Builder_Component_Module::get_modules_assets();
$args = apply_filters('themify_builder_script_vars', $args);
if (true === $args['is_animation']) {
unset($args['is_animation']);
if (true === $args['is_parallax']) {
unset($args['is_parallax']);
if (true === $args['is_sticky']) {
unset($args['is_sticky']);
if ($args['fullwidth_support'] === true) {
unset($args['fullwidth_support']);
$args['fullwidth_support'] = 1;
Themify_Enqueue_Assets::localize_script('themify-main-script', 'tbLocalScript', $args);
* Only need to save converted old css col padding to new grid css padding
public static function convert_data() {
check_ajax_referer('tf_nonce', 'nonce');
if (!empty($_POST['data']) && !empty($_POST['bid'])) {
$id = (int) $_POST['bid'];
$builder_data = ThemifyBuilder_Data_Manager::get_data($id);
if (is_array($builder_data)) {
$convert = json_decode(stripslashes_deep($_POST['data']), true);
$breakpints = array_reverse(array_keys(themify_get_breakpoints()));
$breakpints[] = 'desktop';
$bpLength = count($breakpints);
$allowed = array('padding', 'padding_top', 'padding_bottom', 'padding_left', 'padding_right', 'padding_left_unit', 'padding_right_unit', 'padding_top_unit', 'padding_bottom_unit', 'margin-bottom', 'margin-top', 'margin-bottom_unit', 'margin-top_unit');
foreach ($builder_data as &$row) {
if (!empty($row['cols'])) {
foreach ($row['cols'] as &$col) {
if (isset($convert[$col['element_id']])) {
foreach ($convert[$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
$col['styling'][$prop] = $v;