: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* The public-facing functionality of the plugin.
* @link https://themify.me/
* The public-facing functionality of the plugin.
* Defines the plugin name, version, and two examples hooks for how to
* enqueue the public-facing stylesheet and JavaScript.
* @author Themify <themify@themify.me>
private static $_locations = array();
private static $taxonomies = array();
public static $is_page = false;
public static $is_archive = false;
public static $is_single = false;
public static $is_singular = false;
public static $is_404 = false;
public static $is_front_page = false;
public static $is_home = false;
public static $is_attachemnt = false;
public static $is_search = false;
public static $is_category = false;
public static $is_tag = false;
public static $is_author = false;
public static $is_date = false;
public static $is_tax = false;
public static $is_post_type_archive = false;
private static $currentQuery = null;
private static $originalFile = null;
public static $isTemplatePage = false;
public static $hasShopTemplate = false;
* Initialize the class and set its properties.
* @param string $plugin_name The name of the plugin.
* @param string $version The version of this plugin.
public static function run() {
add_action('themify_builder_setup_modules',array(__CLASS__,'init'));
add_action('pre_get_posts', array(__CLASS__, 'set_archive_per_page'));
public static function init(){
add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_scripts'),9);
add_action('template_include', array(__CLASS__, 'template_include'), 15);
add_action('tbp_render_the_content', array(__CLASS__, 'render_content_page'));
add_action('template_redirect', array(__CLASS__, 'set_rules'));
if (themify_is_woocommerce_active()) {
// Adding cart icon and shopdock markup to the woocommerce fragments
add_filter('woocommerce_add_to_cart_fragments', array(__CLASS__, 'tbp_add_to_cart_fragments'));
if(Themify_Builder_Model::is_frontend_editor_page()){
add_filter('themify_module_categories', array('Tbp_Utils', 'module_categories'));
add_filter('themify_builder_ajax_front_vars', array('Tbp_Utils', 'localize_predesigned_templates'));
add_filter('themify_load_predesigned_templates', array('Tbp_Utils', 'load_predesigned_templates'), 10);
add_filter('themify_builder_admin_bar_is_available', array(__CLASS__, 'is_available'));
add_action( 'themify_builder_frontend_enqueue', array( 'Tbp_Utils', 'load_tbp_active' ) );
* Register the JavaScript for the public-facing side of the site.
public static function enqueue_scripts() {
$plugin_name = Tbp::get_plugin_name();
wp_register_script( $plugin_name, themify_enque(TBP_URL . 'public/js/tbp-script.js'), array('themify-main-script'), $v, true );
$isActive=Themify_Builder_Model::is_front_builder_activate();
if($isActive===false && empty(self::$_locations)){
* This function is provided for demonstration purposes only.
* An instance of this class should be passed to the run() function
* defined in Tbp_Loader as all of the hooks are defined
* in that particular class.
* The Tbp_Loader will then create the relationship
* between the defined hooks and the functions defined in this
Tbp_Utils::loadCssModules($plugin_name, TBP_URL . 'public/css/tbp-style.css', $v);
if (themify_is_woocommerce_active()) {
Tbp_Utils::loadCssModules($plugin_name . '-woo', TBP_URL . 'public/css/wc/tbp-woocommerce.css', $v);
foreach(self::$_locations as $loc){
Themify_Builder_Stylesheet::enqueue_stylesheet(false,$loc);
public static function get_header($name) {
remove_action('get_header', array(__CLASS__, 'get_header'),1,1);
<html <?php language_attributes(); ?>>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<?php if (!current_theme_supports('title-tag')) : ?>
<?php echo wp_get_document_title(); ?>
<body <?php body_class(); ?>>
if ( function_exists( 'wp_body_open' ) ) {
self::render_location('header');
remove_all_actions('wp_head');
$templates[] = "header-{$name}.php";
$templates[] = 'header.php';
locate_template($templates, true);
public static function get_footer($name) {
remove_action('get_footer', array(__CLASS__, 'get_footer'),1,1);
self::render_location('footer');
remove_all_actions('wp_footer');
$templates[] = "footer-{$name}.php";
$templates[] = 'footer.php';
locate_template($templates, true);
private static function render_template($post_id, $location) {
if ( $template = get_post( $post_id ) ) {
$tag = $location === 'header' || $location === 'footer' ? $location : 'main';
$id = $tag === 'main' ? 'content' : $location;
$classes = array( 'tbp_template' );
$single_product_hook=false;
if ( $location === 'product_single' ) {
$the_query = Tbp_Utils::get_wc_actual_query();
if ($the_query !== null && $the_query->have_posts() && is_object($product)) {
remove_action( 'woocommerce_before_single_product', 'woocommerce_output_all_notices', 10 );
do_action( 'woocommerce_before_single_product' );
$single_product_hook=true;
$isLoop = $ThemifyBuilder->in_the_loop === true;
$ThemifyBuilder->in_the_loop = true;
do_action('tbp_before_render_builder', $post_id, $location);
$title = $template->post_title;
if($location==='archive' || $location==='product_archive'){
Tbp_Utils::disable_ptb_loop();
echo sprintf('<!-- Builder Pro Template Start: %s -->', $title), '<' . $tag . ' id="tbp_' . $id . '" class="' . join( ' ', $classes ) . '">',
$ThemifyBuilder->get_builder_output( $post_id ),
sprintf('<!-- Builder Pro Template End: %s -->', $title), '</' . $tag . '>';
do_action('tbp_after_render_builder', $post_id, $location);
$ThemifyBuilder->in_the_loop = $isLoop;
if ($single_product_hook === true) {
do_action( 'woocommerce_after_single_product' );
public static function render_location($location) {
if (isset(self::$_locations[$location])) {
self::render_template(self::$_locations[$location], $location);
private static function collect_display_conditions() {
$activeTheme=Tbp::get_active_theme();
if (!empty($activeTheme)) {
'post_type' => Tbp_Templates::$post_type,
'ignore_sticky_posts'=>true,
'key' => 'tbp_associated_theme',
'value' => $activeTheme->post_name,
$templates = get_posts($args);
foreach ($templates as $template) {
$condition = Tbp_Utils::get_template_conditions($template->ID);
$list_conditions = array();
foreach ($condition as $c) {
$list_conditions[$c['type']][] = $c;
$conditions[$template->ID] = $list_conditions;
private static function set_condition_tags() {
self::$is_404 = is_404();
if (self::$is_404 === false) {
self::$is_page = is_page();
self::$is_attachemnt = self::$is_page === false && is_attachment();
self::$is_single = self::$is_page === false && self::$is_attachemnt === false && is_single();
self::$is_singular = self::$is_page === true || self::$is_attachemnt === true || self::$is_single === true;
if (self::$is_singular === false) {
self::$is_home = is_home();
if (self::$is_home === false) {
self::$is_category = is_category();
if (self::$is_category === false) {
self::$is_tag = is_tag();
if (self::$is_tag === false) {
self::$is_tax = is_tax();
if (self::$is_tax === false) {
self::$is_search = is_search();
if (self::$is_search === false) {
self::$is_author = is_author();
if (self::$is_author === false) {
self::$is_post_type_archive = is_post_type_archive();
if (self::$is_post_type_archive === false) {
self::$is_date = is_date();
self::$is_archive = self::$is_category === true || self::$is_tag === true || self::$is_tax === true || self::$is_home === true || self::$is_author === true || self::$is_date === true || self::$is_search === true || self::$is_post_type_archive === true || is_archive();
self::$isTemplatePage = is_singular(Tbp_Templates::$post_type);
self::$is_front_page = self::$is_page === true && is_front_page();
if ( self::$is_author ) {
// on author archives, the query object returns empty until template_redirect
add_action( 'template_redirect', array( __CLASS__, 'cache_query_object' ), 1 );
self::cache_query_object();
* Cache the global query object
* Hooked to "template_redirect"
public static function cache_query_object() {
self::$currentQuery = get_queried_object();
public static function get_current_query() {
return self::$currentQuery;
private static function checking_display_rules() {
if (!empty(self::$_locations) || (self::$is_archive===false && self::$is_page===false && is_singular('tglobal_style'))) {
self::set_condition_tags();
if (self::$isTemplatePage === true) {
$template_type = get_post_meta($id, 'tbp_template_type', true);
self::$_locations[$template_type] = $id;
if(($template_type==='product_single' || $template_type==='product_archive') && themify_is_woocommerce_active()){
add_filter('themify_builder_body_class', array(__CLASS__,'add_wc_to_body'));
$is_multilingual = Tbp_Utils::is_multilingual();
$conditions = self::collect_display_conditions();
// Cached the taxonomy lists
$tax = Tbp_Utils::get_taxonomies();
foreach ($tax as $slug => $v) {
self::$taxonomies[$slug] = true;
$currentPostType = ! empty( self::$currentQuery->post_type ) ? self::$currentQuery->post_type : null;
if ( self::$is_404 === true || self::$is_page === true ) {
$currentPostType = 'page';
elseif(self::$is_archive===true && empty($currentPostType)){
if(self::$is_category === true || self::$is_tag === true || self::$is_tax === true){
$tax = self::$currentQuery===null?false:get_taxonomy(self::$currentQuery->taxonomy);
if($tax===false){// WP doesn't recognized 404 page when taxonomy/term doesn't exist
self::$is_archive=self::$is_category=self::$is_tag=self::$is_tax=false;
$currentPostType=$tax->object_type;
elseif(self::$is_post_type_archive===true){
$currentPostType = self::$currentQuery->name;
$currentPostType = 'post';
} else if ( self::$is_home === true && ! self::$is_front_page ) { // Posts Page
$currentPostType = 'post';
$isArray = is_array($currentPostType);
foreach ($conditions as $id => $condition_type) {
$translated_template = false;
if ( $is_multilingual ) {
$translated_template = Tbp_Utils::get_translated_object_id( $id, 'tbp_template' );
if (isset($condition_type['exclude']) || isset($condition_type['include'])) {
$location = get_post_meta($id, 'tbp_template_type', true);
if((self::$is_archive===false && ($location==='archive' || $location==='product_archive')) || (self::$is_singular===false && ($location==='single' || $location==='product_single')) || ($location==='page' && self::$is_page===false && self::$is_404===false)){
if (isset($condition_type['include'])) {
foreach ($condition_type['include'] as $condition) {
$post_type = Tbp_Utils::get_post_type( $location, $condition );
if ( $post_type === 'any' || ( ( $isArray === true && self::check_intersect( $currentPostType, $post_type ) === true ) || ( $isArray === false && in_array( $currentPostType, $post_type, true ) ) ) ) {
$view = self::get_condition_settings($id, $location, $condition);
if ( $is_multilingual ) {
if ( ! empty( $translated_template ) && 'publish' === get_post_status( $translated_template ) ) {
$id = $translated_template;
/* always translate the template assignments; without translation,
* the original template is applied and used on all languages.
$view = self::translate_view( $view );
// check if template is assigned to the current context, returns the priority of the template
$priority = self::is_current_view( $view );
self::$_locations[ $location ][ $priority ][ $id ] = $id;
unset($condition_type['include']);
if (isset($condition_type['exclude'])) {
foreach ($condition_type['exclude'] as $condition) {
$post_type = Tbp_Utils::get_post_type($location, $condition);
if($post_type==='any' || (($isArray===true && self::check_intersect($currentPostType,$post_type)===true)|| ($isArray===false && in_array($currentPostType,$post_type,true)))){
$view = self::get_condition_settings($id, $location, $condition);
if ( $is_multilingual ) {
if ( ! empty( $translated_template ) && 'publish' === get_post_status( $translated_template ) ) {
$id = $translated_template;
$view = self::translate_view( $view );
if ( self::is_current_view( $view ) ) {
// Exclude condition applies. Disable the template.
if ( ! empty( self::$_locations[ $location ] ) && is_array( self::$_locations[ $location ] ) ) {
foreach ( self::$_locations[ $location ] as $priority => $templates ) {
unset( self::$_locations[ $location ][ $priority ][ $id ] );
unset( $condition_type['exclude'] );
// clean up empty elements
self::$_locations = Tbp_Utils::array_filter_recursive( self::$_locations );
// for each location, set the template with the highest priority as active
if ( ! empty( self::$_locations ) ) {
foreach (self::$_locations as $location => $templates ) {
$highest_priority = max( array_keys( $templates ) );
self::$_locations[ $location ] = reset( $templates[ $highest_priority ] );
if(isset(self::$_locations['product_archive'])){
unset(self::$_locations['archive']);
if(isset(self::$_locations['product_single']) || isset(self::$_locations['page'])){
unset(self::$_locations['single']);
private static function get_condition_settings($id, $location, $condition) {
$query = isset($condition['query']) ? $condition['query'] : '';
$detail = $condition['detail'];
$general = $condition['general'];
if ($location === 'header' || $location === 'footer') {