false,
] );
/**
* File upload shortcodes - stored as custom post types
*/
register_post_type( FileUploadConfig::POST_TYPE, [
'public' => false,
] );
}
/**
* Returns the url for closing the TCB editing screen.
*
* If no post id is set then will use native WP functions to get the editing URL for the piece of content that's currently being edited
*
* @param bool $post_id
*
* @return string
*/
function tcb_get_editor_close_url( $post_id = false ) {
/**
* we need to make sure that if the admin is https, then the editor link is also https, otherwise any ajax requests through wp ajax api will not work
*/
$admin_ssl = strpos( admin_url(), 'https' ) === 0;
if ( empty( $post_id ) ) {
$post_id = get_the_ID();
}
$editor_link = set_url_scheme( get_permalink( $post_id ) );
$close_url = apply_filters( 'tcb_close_url', $admin_ssl ? str_replace( 'http://', 'https://', $editor_link ) : $editor_link );
return $close_url;
}
/**
* Returns the url for the TCB editing screen.
*
* If no post id is set then will use native WP functions to get the editing URL for the piece of content that's currently being edited
*
* @param int $post_id
* @param bool $main_frame whether or not to get the main frame Editor URL or the child frame one
*
* @return string
*/
function tcb_get_editor_url( $post_id = 0, $main_frame = true ) {
/**
* we need to make sure that if the admin is https, then the editor link is also https, otherwise any ajax requests through wp ajax api will not work
*/
$admin_ssl = strpos( admin_url(), 'https' ) === 0;
if ( empty( $post_id ) ) {
$post_id = get_the_ID();
}
/*
* We need the post to complete the full arguments for the preview_post_link filter
*/
$params = [
TVE_EDITOR_FLAG => 'true',
];
if ( $main_frame ) {
$editor_link = get_edit_post_link( $post_id, '' );
$params['action'] = 'architect';
} else {
$params[ TVE_FRAME_FLAG ] = wp_create_nonce( TVE_FRAME_FLAG );
$editor_link = set_url_scheme( get_permalink( $post_id ) );
$editor_link = apply_filters( 'tcb_frame_request_uri', $editor_link, $post_id );
}
$editor_link = add_query_arg( apply_filters( 'tcb_editor_edit_link_query_args', $params, $post_id ), $editor_link ?: '' );
/**
* Fix issue with course overview not saving with the correct post ID.
**/
if ( 'tva_course_overview' === get_post_type( $post_id ) ) {
$editor_link = add_query_arg( 'editor_id', $post_id, $editor_link );
}
return $admin_ssl ? str_replace( 'http://', 'https://', $editor_link ) : $editor_link;
}
/**
* Returns the preview URL for any given post/page
*
* If no post id is set then will use native WP functions to get the editing URL for the piece of content that's currently being edited
*
* @param bool $post_id
* @param bool $preview
*
* @return string
*/
function tcb_get_preview_url( $post_id = false, $preview = true ) {
global $tve_post;
if ( empty( $post_id ) && ! empty( $tve_post ) ) {
$post_id = $tve_post->ID;
}
$post_id = ( $post_id ) ? $post_id : get_the_ID();
/*
* We need the post to complete the full arguments for the preview_post_link filter
*/
$post = get_post( $post_id );
$preview_link = set_url_scheme( get_permalink( $post_id ) );
$query_args = [];
if ( $preview ) {
$query_args['preview'] = 'true';
}
$preview_link = esc_url( apply_filters( 'preview_post_link', add_query_arg( apply_filters( 'tcb_editor_preview_link_query_args', $query_args, $post_id ), $preview_link ), $post ) );
return $preview_link;
}
/**
* Get default edit link for a post (WP edit / a custom dashboard)
*
* @param int $post_id
*
* @return string
*/
function tcb_get_default_edit_url( $post_id = 0 ) {
if ( empty( $post_id ) ) {
$post_id = get_the_ID();
}
$post = get_post( $post_id );
$edit_link = set_url_scheme( get_edit_post_link( $post_id ) );
/**
* Allows changing the default wp post's edit link
* Used for save & return to edit dashboard
*
* @param string $edit_link - default wp edit link
* @param stdClass $post - current post
*/
$edit_link = esc_url( apply_filters( 'tcb_edit_post_default_url', $edit_link, $post ) );
return $edit_link;
}
/**
*
* checks whether the $post_type is editable using the TCB
*
* @param string $post_type
* @param int $post_id
*
* @return bool true if the post type is editable
*/
function tve_is_post_type_editable( $post_type, $post_id = null ) {
/* post types that are not editable using the content builder - handled as a blacklist */
$blacklist_post_types = [
'acf-field-group',
'focus_area',
'thrive_optin',
'tvo_shortcode',
/**
* On Cartflows's 'cartflows_flow' posts can't be edited with TAR
*/
'cartflows_flow',
];
$blacklist_post_types = apply_filters( 'tcb_post_types', $blacklist_post_types );
if ( isset( $blacklist_post_types['force_whitelist'] ) && is_array( $blacklist_post_types['force_whitelist'] ) ) {
return in_array( $post_type, $blacklist_post_types['force_whitelist'] ) || 'tva_course_overview' === $post_type;
}
if ( in_array( $post_type, $blacklist_post_types ) ) {
return false;
}
if ( $post_id === null ) {
$post_id = get_the_ID();
}
return apply_filters( 'tcb_post_editable', true, $post_type, $post_id );
}
/**
* Sometimes the only way to make the plugin work with other scripts is by deregistering them on the editor page
*/
function tve_remove_conflicting_scripts() {
if ( is_editor_page() ) {
/** Genesis framework - Media Child theme contains a script that prevents users from being able to close the media library */
wp_dequeue_script( 'yt-embed' );
wp_deregister_script( 'yt-embed' );
/** Member player loads jquery tools which conflicts with jQuery UI */
wp_dequeue_script( 'mpjquerytools' );
wp_deregister_script( 'mpjquerytools' );
/** Solved Conflict with WooCommerce Geolocation setting with cache */
/** When Geolocation with page cache is enabled scripts are duplicated in the iFrame */
wp_deregister_script( 'wc-geolocation' );
wp_dequeue_script( 'wc-geolocation' );
/* wp 2019 theme expecting to have a .site-branding div in the page */
wp_deregister_script( 'twentynineteen-touch-navigation' );
wp_dequeue_script( 'twentynineteen-touch-navigation' );
/* Payment Forms for Paystack is retarded, forcing own version of jquery which is as old as time */
wp_deregister_script( 'blockUI' );
wp_dequeue_script( 'blockUI' );
wp_deregister_script( 'jQuery_UI' );
wp_dequeue_script( 'jQuery_UI' );
/* TAR-5246 - floating preview in editor is not working because of the mm scripts */
wp_dequeue_script( 'mm-common-core.js' );
wp_deregister_script( 'mm-common-core.js' );
wp_dequeue_script( 'mm-preview.js' );
wp_deregister_script( 'mm-preview.js' );
wp_dequeue_script( 'membermouse-socialLogin' );
wp_deregister_script( 'membermouse-socialLogin' );
wp_dequeue_script( 'inbound-analytics' );
wp_deregister_script( 'inbound-analytics' );
}
}
/**
* Adds TCB editing URL to underneath the post title in the WordPress post listings view
*
* @param $actions
* @param $page_object
*
* @return mixed
*/
function thrive_page_row_buttons( $actions, $page_object ) {
if (
! tve_is_post_type_editable( $page_object->post_type ) || // don't add url to blacklisted content types
! TCB_Product::has_post_access( $page_object->ID ) ||
$page_object->post_status === 'trash'
) {
return $actions;
}
$page_for_posts = get_option( 'page_for_posts' );
if ( $page_for_posts && $page_object->ID == $page_for_posts ) {
return $actions;
}
?>
is_in_grace_period( 'tcb' ) ) {
$license_expired_class = 'thrive-license-warning';
} elseif ( ! TD_TTW_User_Licenses::get_instance()->has_active_license( 'tcb' ) ) {
$license_expired_class = 'thrive-license-warning-red';
}
}
$url = tcb_get_editor_url( $page_object->ID );
$actions['tcb'] = '' . __( 'Edit with Thrive Architect', 'thrive-cb' ) . '';
return $actions;
}
/**
* Load meta tags for social media and others
*
* @param int $post_id
*/
function tve_load_meta_tags( $post_id = 0 ) {
if ( empty( $post_id ) ) {
$post_id = get_the_ID();
}
$globals = tve_get_post_meta( $post_id, 'tve_globals' );
if ( ! empty( $globals['fb_comment_admins'] ) ) {
$fb_admins = json_decode( $globals['fb_comment_admins'] );
if ( ! empty( $fb_admins ) && is_array( $fb_admins ) ) {
foreach ( $fb_admins as $admin ) {
echo '';
}
}
}
}
/**
* Returns global style for an element given as a parameter
*
* @param string $for_element
* @param string $option_name
* @param int $for_post
*
* @return array
*/
function tve_get_global_styles( $for_element = '', $option_name = '', $for_post = 0 ) {
if ( empty( $option_name ) ) {
$global_style_options = tve_get_global_styles_option_names();
$option_name = $global_style_options[ $for_element ];
}
if ( ! empty( $for_post ) ) {
$global_styles = get_post_meta( $for_post, $option_name, true );
} else {
$global_styles = get_option( $option_name, [] );
}
$global_styles = apply_filters( 'tcb_global_styles', $global_styles );
$element_global_styles = [];
if ( ! is_array( $global_styles ) ) {
/**
* Avoid cases where the user is modifying the DB
*/
$global_styles = [];
}
foreach ( $global_styles as $identifier => $styles ) {
$element_global_styles[] = array(
'id' => $identifier,
'name' => stripslashes( $styles['name'] ),
'cls' => constant( 'TVE_GLOBAL_STYLE_' . strtoupper( $for_element ) . '_CLS_PREFIX' ) . $identifier,
'attr' => empty( $styles['dom']['attr'] ) ? [] : $styles['dom']['attr'],
'default_css' => empty( $styles['default_css'] ) ? [] : $styles['default_css'],
'default_html' => empty( $styles['default_html'] ) ? [] : $styles['default_html'],
'smart_config' => empty( $styles['smart_config'] ) ? [] : $styles['smart_config'],
);
}
return $element_global_styles;
}
/**
* Hook on wp_head WP Action
*
* Outputs Thrive Global Variables
*/
function tve_load_global_variables() {
$global_colors = tcb_color_manager()->get_list();
$global_gradients = get_option( apply_filters( 'tcb_global_gradients_option_name', 'thrv_global_gradients' ), [] );
echo '';
}
/**
* Outputs the global styles inside the main frame
*/
function tve_load_global_styles() {
echo tve_get_shared_styles( '', '300' ); //phpcs:ignore
}
/**
* Prepares the outputted CSS string by replacing the CSS Variables with their values
*
* @param string $css_string
* @param bool $bypass_editor_check
* @param bool $allow_lp_vars
*
* @return mixed|string
*/
function tve_prepare_global_variables_for_front( $css_string = '', $bypass_editor_check = false, $allow_lp_vars = true ) {
if ( false === $bypass_editor_check && is_editor_page_raw() ) {
return tcb_custom_css( $css_string );
}
$global_colors = tcb_color_manager()->get_list();
/**
* TODO: implement also a tcb_gradient_manager that handles the gradient logic
*/
$global_gradients = get_option( apply_filters( 'tcb_global_gradients_option_name', 'thrv_global_gradients' ), [] );
$search = [];
$replace = [];
foreach ( $global_colors as $color ) {
$search[] = 'var(' . TVE_GLOBAL_COLOR_VAR_CSS_PREFIX . $color['id'] . ')';
$replace[] = $color['color'];
}
foreach ( $global_gradients as $gradient ) {
$search[] = 'var(' . TVE_GLOBAL_GRADIENT_VAR_CSS_PREFIX . $gradient['id'] . ')';
$replace[] = $gradient['gradient'];
}
if ( $allow_lp_vars && wp_doing_ajax() && ! empty( $_REQUEST['post_id'] ) && is_numeric( $_REQUEST['post_id'] ) ) {
/**
* For AJAX Requests we need also that filter to be called
*
* Therefore we instantiate a landing page object if the provided post is a landing page
*/
$post = tcb_post( absint( $_REQUEST['post_id'] ) );
if ( $post->is_landing_page() ) {
tcb_landing_page( absint( $_REQUEST['post_id'] ) );
}
}
$front_variables = apply_filters( 'tcb_prepare_global_variables_for_front', $search, $replace );
if ( ! empty( $front_variables['search'] ) && ! empty( $front_variables['replace'] ) ) {
$search = array_merge( $search, $front_variables['search'] );
$replace = array_merge( $replace, $front_variables['replace'] );
}
$css_string = str_replace( $search, $replace, $css_string );
return tcb_custom_css( $css_string );
}
/**
* Prepares the master variables for output
*
* Used in the ThriveTheme and in TAR
*
* @param array $master_variable
*
* @return string
*/
function tve_prepare_master_variable( $master_variable = [] ) {
if ( empty( $master_variable['hsl'] ) || ! is_array( $master_variable['hsl'] ) ) {
return '';
}
$master_config = array(
TVE_MAIN_COLOR_H . ':' . $master_variable['hsl']['h'],
TVE_MAIN_COLOR_S . ':' . ( strpos( $master_variable['hsl']['s'], 'var(' ) === false ? ( (float) $master_variable['hsl']['s'] * 100 ) . '%' : $master_variable['hsl']['s'] ),
TVE_MAIN_COLOR_L . ':' . ( strpos( $master_variable['hsl']['l'], 'var(' ) === false ? ( (float) $master_variable['hsl']['l'] * 100 ) . '%' : $master_variable['hsl']['l'] ),
TVE_MAIN_COLOR_A . ':' . ( isset( $master_variable['hsl']['a'] ) ? $master_variable['hsl']['a'] : '1' ),
);
return implode( ';', $master_config ) . ';';
}
/**
* Print hsl parts of a color
*
* @param $color_name
* @param $hsl_data
*
* @return string
*/
function tve_print_color_hsl( $color_name, $hsl_data ) {
$hsl_vars = array(
$color_name . '-h:' . $hsl_data['h'],
$color_name . '-s:' . ( (float) $hsl_data['s'] * 100 ) . '%',
$color_name . '-l:' . ( (float) $hsl_data['l'] * 100 ) . '%',
$color_name . '-a:' . $hsl_data['a'],
);
return implode( ';', $hsl_vars ) . ';';
}
/**
* Convert a rgb color to its hsl data
*
* @param string $rgbString
* @param string $return_type
*
* @return array|string
*/
function tve_rgb2hsl( $rgbString = '', $return_type = 'code' ) {
if ( strpos( $rgbString, '#' ) !== false ) {
$rgb_array = tve_hex2rgb( $rgbString );
} else {
preg_match( '#\((.*?)\)#', $rgbString, $match );
$rgb_array = explode( ',', $match[1] );
}
$r = trim( $rgb_array[0] );
$g = trim( $rgb_array[1] );
$b = trim( $rgb_array[2] );
$a = empty( $rgb_array[3] ) ? 1 : trim( $rgb_array[3] );
if ( $r === '' || $g === '' || $b === '' || count( $rgb_array ) > 4 ) {
return [ 0, 0, 0, 0 ];
}
$r /= 255;
$g /= 255;
$b /= 255;
$max = max( $r, $g, $b );
$min = min( $r, $g, $b );
$l = ( $max + $min ) / 2;
if ( $max == $min ) {
$h = $s = 0;
} else {
$d = $max - $min;
$s = $l > 0.5 ? $d / ( 2 - $max - $min ) : $d / ( $max + $min );
switch ( $max ) {
case $r:
$h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 );
break;
case $g:
$h = ( $b - $r ) / $d + 2;
break;
case $b:
$h = ( $r - $g ) / $d + 4;
break;
}
$h /= 6;
}
$h = floor( $h * 360 );
$s = floor( $s * 100 );
$l = floor( $l * 100 );
$code = array(
'h' => $h,
's' => round( $s / 100, 2 ),
'l' => round( $l / 100, 2 ),
'a' => (float) $a,
);
if ( $return_type === 'code' ) {
return $code;
}
return tve_prepare_hsla_code( $code );
}
/**
* Used inside TAR and Theme Builder
* Returns the HSLA color string made from HSLA code
*
* @param array $code
*
* @return string
*/
function tve_prepare_hsla_code( $code = [] ) {
$hue = $code['h'];
$saturation = $code['s'];
$lightness = $code['l'];
$alpha = isset( $code['a'] ) ? $code['a'] : 1;
return "hsla($hue, $saturation, $lightness, $alpha)";
}
/**
* @param numeric $h
* @param numeric $s
* @param numeric $l
* @param numeric $a
* @param string $return_type
*
* @return array|string
*/
function tve_hsl2rgb( $h, $s, $l, $a = 1, $return_type = 'code' ) {
if ( ( is_numeric( $h ) && $h >= 0 && $h <= 360 ) &&
( is_numeric( $s ) && $s >= 0 && $s <= 1 ) &&
( is_numeric( $l ) && $l >= 0 && $l <= 1 ) &&
( is_numeric( $a ) && $a >= 0 && $a <= 1 ) ) {
$c = ( 1 - abs( 2 * $l - 1 ) ) * $s;
$x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) );
$m = $l - ( $c / 2 );
if ( $h < 60 ) {
$r = $c;
$g = $x;
$b = 0;
} elseif ( $h < 120 ) {
$r = $x;
$g = $c;
$b = 0;
} elseif ( $h < 180 ) {
$r = 0;
$g = $c;
$b = $x;
} elseif ( $h < 240 ) {
$r = 0;
$g = $x;
$b = $c;
} elseif ( $h < 300 ) {
$r = $x;
$g = 0;
$b = $c;
} else {
$r = $c;
$g = 0;
$b = $x;
}
$r = ( $r + $m ) * 255;
$g = ( $g + $m ) * 255;
$b = ( $b + $m ) * 255;
$code = array(
'r' => floor( $r ),
'g' => floor( $g ),
'b' => floor( $b ),
'a' => $a,
);
if ( $return_type === 'code' ) {
return $code;
}
return 'rgba(' . $code['r'] . ',' . $code['g'] . ',' . $code['b'] . ',' . $code['a'] . ')';
}
if ( $return_type === 'code' ) {
return [ 'r' => 0, 'g' => 0, 'b' => 0, 'a' => 0 ];
}
return 'rgba(0,0,0,0)';
}
/**
* @param $hex
*
* @return array
*/
function tve_hex2rgb( $hex ) {
$hex = str_replace( '#', '', $hex );
$length = strlen( $hex );
return array(
hexdec( $length === 6 ? substr( $hex, 0, 2 ) : ( $length === 3 ? str_repeat( substr( $hex, 0, 1 ), 2 ) : 0 ) ),
hexdec( $length === 6 ? substr( $hex, 2, 2 ) : ( $length === 3 ? str_repeat( substr( $hex, 1, 1 ), 2 ) : 0 ) ),
hexdec( $length === 6 ? substr( $hex, 4, 2 ) : ( $length === 3 ? str_repeat( substr( $hex, 2, 1 ), 2 ) : 0 ) ),
);
}
/**
* it's a hook on the wp_head WP action
*
* outputs the CSS needed for the custom fonts
*/
function tve_load_font_css() {
do_action( 'tcb_extra_fonts_css' );
$all_fonts = tve_get_all_custom_fonts();
if ( empty( $all_fonts ) ) {
return;
}
echo '';
}
/**
* output the css for the $fonts array
*
* @param array $fonts
*/
function tve_output_custom_font_css( $fonts ) {
echo '';
}
/**
* Prepare font family name to be added to css rule
*
* @param $font_family
*/
function tve_prepare_font_family( $font_family ) {
$chunks = explode( ',', $font_family );
$length = count( $chunks );
$font = '';
foreach ( $chunks as $key => $value ) {
$font .= "'" . trim( $value ) . "'";
$font .= ( $key + 1 ) < $length ? ', ' : '';
}
return $font;
}
/**
* Adds an icon and link to the admin bar for quick access to the editor. Only shows when not already in Thrive Architect
*
* @param array $nodes
* @param string $thrive_node_id
*
* @return array|void
*/
function thrive_editor_admin_bar( $nodes ) {
$theme = wp_get_theme();
// SUPP-1408 Hive theme leaves the query object in an unknown state
if ( 'Hive' === $theme->name || 'Hive' === $theme->parent_theme ) {
wp_reset_query();
}
$post_id = get_the_ID();
/**
* Beside other restrictions the edit button in admin bar should be displayed
* not only on single posts or pages
*/
$should_display = apply_filters( 'tcb_display_button_in_admin_bar', is_single() || is_page() );
if ( $should_display && is_admin_bar_showing() && tve_is_post_type_editable( get_post_type() ) && TCB_Product::has_external_access( $post_id ) ) {
$license_expired_class = '';
if ( ! apply_filters( 'tcb_skip_license_check', false ) ) {
if ( TD_TTW_User_Licenses::get_instance()->is_in_grace_period( 'tcb' ) ) {
$license_expired_class = 'thrive-license-warning';
} elseif ( ! TD_TTW_User_Licenses::get_instance()->has_active_license( 'tcb' ) ) {
$license_expired_class = 'thrive-license-warning-red';
}
}
if ( ! isset( $_GET[ TVE_EDITOR_FLAG ] ) ) {
$editor_link = tcb_get_editor_url( $post_id );
$args = array(
'id' => 'tve_button',
'title' => '' . __( 'Edit with Thrive Architect', 'thrive-cb' ),
'href' => $editor_link,
'meta' => [
'class' => 'thrive-admin-tar',
],
);
} elseif ( get_post_type() === 'post' || get_post_type() === 'page' ) {
$close_editor_link = tcb_get_editor_close_url( $post_id );
$args = array(
'id' => 'tve_button',
'title' => '' . __( 'Close Thrive Architect', 'thrive-cb' ),
'href' => $close_editor_link,
'meta' => [
'class' => 'thrive-admin-bar',
],
);
} else {
return;
}
$args['order'] = 0;
$nodes[] = $args;
}
return $nodes;
}
/**
* Checks for [embed] shortcodes inside the content and uses the run_shortcode() function from class-wp-embed.php to render them instead of using do_shortcode() .
*
* @param $content
*
* @return mixed
*/
function tve_handle_embed_shortcode( $content ) {
/* if we find an [embed] tag, give the content to the run_shortcode() function from class-wp-embed */
if ( strpos( $content, '[embed' ) !== false ) {
global $wp_embed;
$content = $wp_embed->run_shortcode( $content );
}
return $content;
}
/**
* add the editor content to $content, but at priority 101 so not affected by custom theme shortcode functions that are common with some theme developers
*
* @param string $content the post content
* @param null|string $use_case used to control the output, e.g. it can be used to return just TCB content, not full content
*
* @return string
*/
function tve_editor_content( $content, $use_case = null ) {
global $post;
$tcb_post = tcb_post( $post );
$is_editor_page = is_editor_page();
$post_id = get_the_ID();
if ( isset( $GLOBALS['TVE_CONTENT_SKIP_ONCE'] ) ) {
unset( $GLOBALS['TVE_CONTENT_SKIP_ONCE'] );
return $content;
}
/**
* SUPP-12988 on event pages the content was duplicated (this function is somehow called twice)
* We want to skip the second execution of this function to avoid duplicating content.
*/
global $EM_Event;
if ( ! empty( $EM_Event ) && get_post_type() === 'event' && is_singular() ) {
$GLOBALS['TVE_CONTENT_SKIP_ONCE'] = true;
}
/**
* check if current post is protected by a membership plugin
*/
if ( ! tve_membership_plugin_can_display_content() ) {
return $content;
}
if ( ! tve_is_post_type_editable( get_post_type( $post_id ) ) ) {
return $content;
}
$is_landing_page = tve_post_is_landing_page( $post_id );
$tcb_force_excerpt = false;
if ( $use_case !== 'tcb_content' && post_password_required( $post ) ) {
return $is_landing_page ? '
' . get_the_password_form( $post ) . '
' : $content;
}
if ( $is_editor_page ) {
// this is an editor page
$tve_saved_content = tve_get_post_meta( $post_id, 'tve_updated_post', true );
/**
* SUPP-4806 Conflict (max call stack exceeded most likely) with Yoast SEO Address / Map Widgets
*/
if ( doing_filter( 'get_the_excerpt' ) || doing_filter( 'the_excerpt' ) ) {
return $tve_saved_content . $content;
}
/**
* If there is no TCB-saved content, but the post / page contains WP content, create a WP-Content element in TCB containing everything from WP
*/
if ( empty( $tve_saved_content ) ) {
$tve_saved_content = $tcb_post->get_wp_element();
$tcb_post->meta( 'tcb2_ready', 1 );
}
} else {
/* SUPP-2680 - removed the custom css display from here - it's loaded from the wp_enqueue_scripts hook */
if ( $use_case !== 'tcb_content' ) { // do not trucate the contents if we require it all
/* if the editor was specifically disabled for this post, just return the content */
if ( $tcb_post->editor_disabled() ) {
return $content;
}
/**
* do not truncate the post content if the current page is a feed and the option for the feed display is "Full text"
*/
$rss_use_excerpt = false;
if ( is_feed() ) {
$rss_use_excerpt = (bool) get_option( 'rss_use_excerpt' );
}
$tcb_force_excerpt = apply_filters( 'tcb_force_excerpt', false );
if ( $rss_use_excerpt || ! is_singular() || $tcb_force_excerpt ) {
$more_found = tve_get_post_meta( get_the_ID(), 'tve_content_more_found', true );
$content_before_more = tve_get_post_meta( get_the_ID(), 'tve_content_before_more', true );
if ( $more_found ) {
if ( is_feed() ) {
$more_link = ' […]';
} else {
$more_link = ' ' . __( 'Continue Reading', 'thrive-cb' ) . '';
$more_link = apply_filters( 'the_content_more_link', $more_link, __( 'Continue Reading', 'thrive-cb' ) );
}
$tve_saved_content = $content_before_more . $more_link;
$tve_saved_content = force_balance_tags( $tve_saved_content );
$content = ''; /* clear out anything else after this point */
$content_trimmed = true;
} elseif ( is_feed() && $rss_use_excerpt ) {
$rss_content = tve_get_post_meta( $post_id, 'tve_updated_post', true ) . $content;
if ( $rss_content ) {
$tve_saved_content = wp_trim_excerpt( $rss_content );
}
$content_trimmed = true;
}
}
}
if ( ! isset( $tve_saved_content ) ) {
$tve_saved_content = tve_get_post_meta( $post_id, 'tve_updated_post', true );
$tve_saved_content = tve_restore_script_tags( $tve_saved_content );
}
if ( empty( $tve_saved_content ) ) {
// return empty content if nothing is inserted in the editor - this is to make sure that first page section on the page will actually be displayed ok
return $use_case === 'tcb_content' ? '' : $content;
}
$tve_saved_content = tve_compat_content_filters_before_shortcode( $tve_saved_content );
/**
* Prepare Events configuration
* We only skip feeds page here. The content can be placed anywhere on the page
* We have to cover the case when the page is not a landing page and the content is outside the loop
*/
if ( ! is_feed() ) {
// append lightbox HTML to the end of the body
tve_parse_events( $tve_saved_content );
}
/* make images responsive */
if ( function_exists( 'wp_filter_content_tags' ) ) {
try {
$tve_saved_content = wp_filter_content_tags( $tve_saved_content );
} catch ( Error $e ) {
/* just so it won't break the page */
}
} elseif ( function_exists( 'wp_make_content_images_responsive' ) ) {
$tve_saved_content = wp_make_content_images_responsive( $tve_saved_content );
}
}
$tve_saved_content = tve_thrive_shortcodes( $tve_saved_content, $is_editor_page );
/* render the content added through WP Editor (element: "WordPress Content") */
$tve_saved_content = tve_do_wp_shortcodes( $tve_saved_content, $is_editor_page );
if ( ! $is_editor_page ) {
//for the case when user put a shortcode inside a "p" element
$tve_saved_content = shortcode_unautop( $tve_saved_content );
/* search for WP's tag and split the content based on that */
if ( $use_case !== 'tcb_content' && ( ! is_singular() || $tcb_force_excerpt ) && ! isset( $content_trimmed ) ) {
if ( preg_match( '##', $tve_saved_content, $m ) ) {
list( $tve_saved_content ) = explode( $m[0], $tve_saved_content, 2 );
$tve_saved_content = preg_replace( '#
$#s', '', $tve_saved_content );
$more_link = ' ' . __( 'Continue Reading', 'thrive-cb' ) . '';
$more_link = apply_filters( 'the_content_more_link', $more_link, __( 'Continue Reading', 'thrive-cb' ) );
$tve_saved_content = force_balance_tags( $tve_saved_content . $more_link );
}
}
/* fix for SUPP-5168, treat [embed] shortcodes separately by delegating the shortcode function to class-wp-embed.php */
$tve_saved_content = tve_handle_embed_shortcode( $tve_saved_content );
if ( $is_landing_page ) {
$tve_saved_content = do_shortcode( $tve_saved_content );
$tve_saved_content = tve_compat_content_filters_after_shortcode( $tve_saved_content );
} else {
$theme = wp_get_theme();
/**
* Stendhal theme removes the default WP do_shortcode on the_content filter and adds their own. not sure why
*/
if ( $theme->name === 'Stendhal' || $theme->parent_theme === 'Stendhal' ) {
$tve_saved_content = do_shortcode( $tve_saved_content );
}
}
/**
* Replace again {tcb_} shortcodes in case they are used in shortcodes
*/
$tve_saved_content = tve_do_custom_content_shortcodes( $tve_saved_content );
}
$style_family_id = is_singular() ? ' id="tve_flt" ' : ' ';
$wrap = [
'start' => '
',
'end' => '
',
];
/* don't wrap when page is feed OR when we're rendering a post list inside the editor
* use case that breaks - add post list in top section with full content => when editing the post, tve_editor will be the one from the post list, not the one from the current post
*/
if ( is_feed() || ( ! TCB_Post_List::is_outside_post_list_render() && is_editor_page_raw( true ) ) ) {
$wrap['start'] = $wrap['end'] = '';
} elseif ( $is_editor_page && get_post_type( $post_id ) === 'tcb_lightbox' ) {
$wrap['start'] .= '
';
$wrap['end'] .= '
';
}
if ( tve_get_post_meta( $post_id, 'thrive_icon_pack' ) ) {
TCB_Icon_Manager::enqueue_icon_pack();
}
tve_enqueue_extra_resources( $post_id );
/**
* fix for LG errors being included in the page
*/
$tve_saved_content = preg_replace_callback( '/__CONFIG_lead_generation__(.+?)__CONFIG_lead_generation__/s', 'tcb_lg_err_inputs', $tve_saved_content );
$tve_saved_content = apply_filters( $is_editor_page ? 'tcb_alter_editor_content' : 'tcb_clean_frontend_content', $tve_saved_content );
$tve_saved_content = tcb_remove_deprecated_strings( $tve_saved_content );
if ( doing_filter( 'get_the_excerpt' ) ) {
/* add some space for when the content is stripped for the excerpt */
$tve_saved_content = str_replace( '
', '
', $tve_saved_content );
}
/**
* Change post / page content
*
* @param string $tve_saved_content
* @param bool $is_landing_page
*/
$tve_saved_content = apply_filters( 'tcb.landing_page_content', $tve_saved_content, $is_landing_page );
if ( $is_landing_page ) {
$header = TCB_Symbol_Template::symbol_render_shortcode( array(
'id' => get_post_meta( $post_id, '_tve_header', true ),
'tve_shortcode_config' => $is_editor_page,
), true );
$footer = TCB_Symbol_Template::symbol_render_shortcode( array(
'id' => get_post_meta( $post_id, '_tve_footer', true ),
'tve_shortcode_config' => $is_editor_page,
), true );
if ( ! $is_editor_page ) {
$header = tcb_clean_frontend_content( $header );
$footer = tcb_clean_frontend_content( $footer );
}
$tve_saved_content = $header . $tve_saved_content . $footer;
}
return $wrap['start'] . $tve_saved_content . $wrap['end'] . $content;
}
/**
* Pre-process of content before serving it - remove some of the problem strings reported by customers
* Ensure backward-compatibility with fixed issues - e.g. remove "noopener" and "noreferrer" attributes
*
* @param string $content
*
* @return string
*/
function tcb_remove_deprecated_strings( $content ) {
$content = str_replace( [
' data-default="Your Heading Here"',
' data-default="Enter your text here..."',
], [ '', '' ], $content );
$content = str_replace( [ ' rel="noopener noreferrer"', ' rel="noreferrer noopener"' ], '', $content );
$content = str_replace( [
' rel="nofollow noopener noreferrer"',
' rel="noreferrer noopener nofollow"',
], ' rel="nofollow"', $content );
$content = str_replace( [
' rel="noopener nofollow noreferrer"',
' rel="noreferrer nofollow noopener"',
], ' rel="nofollow"', $content );
$content = str_replace(
'spotlightr.com/publish/',
'spotlightr.com/watch/',
$content );
/**
* Action filter - remove deprecated texts
*/
return apply_filters( 'tcb_remove_deprecated_strings', $content );
}
/**
* Updating the Theme first and then trying to activate TAr results in a fatal error
*/
if ( ! function_exists( 'tve_save_post_callback' ) ) {
/**
* When a page is edited from admin -> we need to use the same title for the associated lightbox, if the page in question is a landing page
* Copy post tve meta to revision meta
*
* This method is also called when a revision of a post is added
*
* @param $post_id
*
* @see defaults-filters.php for add_action("post_updated")
*
* @see wp_insert_post which is doing: "post_updated", "save_post"
*/
function tve_save_post_callback( $post_id ) {
/**
* If $post_id is an ID of a revision POST
*/
if ( $parent_id = wp_is_post_revision( $post_id ) ) {
$meta_keys = tve_get_used_meta_keys();
/**
* copy post metas to its revision
*/
foreach ( $meta_keys as $meta_key ) {
if ( $meta_key === 'tve_landing_page' ) {
$meta_value = get_post_meta( $parent_id, $meta_key, true );
} else {
$meta_value = tve_get_post_meta( $parent_id, $meta_key );
}
add_metadata( 'post', $post_id, 'tve_revision_' . $meta_key, $meta_value );
}
}
$post_type = get_post_type( $post_id );
if ( $post_type !== 'page' ) {
return;
}
$is_landing_page = tve_post_is_landing_page( $post_id );
$tve_globals = tve_get_post_meta( $post_id, 'tve_globals' );
if ( ! $is_landing_page || empty( $tve_globals['lightbox_id'] ) ) {
return;
}
$lightbox = get_post( $tve_globals['lightbox_id'] );
if ( ! $lightbox || ! ( $lightbox instanceof WP_Post ) || $lightbox->post_type !== 'tcb_lightbox' ) {
return;
}
wp_update_post( array(
'ID' => $tve_globals['lightbox_id'],
'post_title' => 'Lightbox - ' . get_the_title( $post_id ),
) );
}
}
/**
* Filter the wp content out of the post for posts that only use TCB content
*
* @param string $content
*
* @return string
*/
function tve_clean_wp_editor_content( $content ) {
if ( post_password_required() || ! tve_is_post_type_editable( get_post_type() ) ) {
return $content;
}
if ( ! tve_membership_plugin_can_display_content() ) {
return $content;
}
$tcb_post = tcb_post();
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
/**
* Optimize Press Conflict With TAR
* If the page is an optimize press page, we return the page
*/
$is_optimize_press_page = get_post_meta( $tcb_post->ID, '_optimizepress_pagebuilder', true );
if ( ! empty( $is_optimize_press_page ) && is_plugin_active( 'optimizePressPlugin/optimizepress.php' ) ) {
return $content;
}
/**
* WPBakery Visual Composer Conflict with TAR
* https://wpbakery.com/
* If the page is an WPBakery Visual Composer page, we return the page
*/
$is_visual_composer = get_post_meta( $tcb_post->ID, '_wpb_vc_js_status', true );
if ( ! empty( $is_visual_composer ) && is_plugin_active( 'js_composer/js_composer.php' ) && ! $tcb_post->meta( 'tcb_editor_enabled' ) ) {
return $content;
}
if ( $tcb_post->meta( 'tcb_editor_enabled' ) ) {
$content = TVE_FLAG_HTML_ELEMENT;
} elseif ( is_editor_page() ) {
/**
* Introduced content checks to avoid saving this meta key for posts not being edited with TAr
*/
$has_tcb_content = $tcb_post->meta( 'tve_globals', null, true );
if ( $tcb_post->meta( 'tcb2_ready' ) || empty( $tcb_post->post_content ) || ! $has_tcb_content ) {
$content = TVE_FLAG_HTML_ELEMENT;
}
}
return $content;
}
/**
* check if there are any extra icon packs needed on the current page / post
*
* @param $post_id
*/
function tve_enqueue_extra_resources( $post_id ) {
$globals = tve_get_post_meta( $post_id, 'tve_globals' );
if ( ! empty( $globals['used_icon_packs'] ) && ! empty( $globals['extra_icons'] ) ) {
$used_icons_font_family = $globals['used_icon_packs'];
foreach ( $globals['extra_icons'] as $icon_pack ) {
if ( ! in_array( $icon_pack['font-family'], $used_icons_font_family ) ) {
continue;
}
wp_enqueue_style( md5( $icon_pack['css'] ), tve_url_no_protocol( $icon_pack['css'] ) );
}
}
/* any of the extra imported fonts - only in case of imported landing pages */
if ( ! empty( $globals['extra_fonts'] ) ) {
foreach ( $globals['extra_fonts'] as $font ) {
if ( empty( $font['ignore'] ) ) {
wp_enqueue_style( md5( $font['font_url'] ), tve_url_no_protocol( $font['font_url'] ) );
}
}
}
}
/**
* wrapper over the wp enqueue_style function
* it will append the TVE_VERSION as a query string parameter to the $src if $ver is left empty
*
* @param $handle
* @param $src
* @param array $deps
* @param bool $ver
* @param $media
*/
function tve_enqueue_style( $handle, $src, $deps = [], $ver = false, $media = 'all' ) {
if ( $ver === false ) {
$ver = TVE_VERSION;
}
wp_enqueue_style( $handle, $src, $deps, $ver, $media );
}
/**
* wrapper over the wp_enqueue_script functions
* it will add the plugin version to the script source if no version is specified
*
* @param $handle
* @param string $src
* @param array $deps
* @param bool $ver
* @param bool $in_footer
*/
function tve_enqueue_script( $handle, $src = '', $deps = [], $ver = false, $in_footer = false ) {
if ( $ver === false ) {
$ver = TVE_VERSION;
}
wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
}
/**
* some features in the editor can only be displayed if we have knowledge about the theme and thus should only display on a thrive theme (borderless content for instance)
* this function checks the global variable that's set in all thrive themes to check if the user is using a thrive theme or not
**/
function tve_check_if_thrive_theme() {
global $is_thrive_theme;
return ! empty( $is_thrive_theme );
}
/**
* Whitelist filter for custom fields that are considered protected by other plugins but want to be displayed
*
* @param $meta_key
*
* @return bool
*/
function tve_whitelist_custom_fields( $meta_key ) {
return in_array( $meta_key, TCB_Custom_Fields_Shortcode::$whitelisted_fields );
}
/**
* Hides thrive editor custom fields from being modified in the standard WP post / page edit screen
*
* @param $protected
* @param $meta_key
*
* @return bool
*/
function tve_hide_custom_fields( $protected, $meta_key ) {
if ( tve_whitelist_custom_fields( $meta_key ) ) {
return false;
}
foreach ( TCB_Custom_Fields_Shortcode::$protected_fields as $key ) {
if ( $key == $meta_key || strpos( $meta_key, $key ) === 0 || ! ! get_post_meta( get_the_ID(), '_' . $meta_key, true ) ) {
return true;
}
}
return $protected;
}
/**
* This is a replica of the WP function get_extended
* The returned array has 'main', 'extended', and 'more_text' keys. Main has the text before
* the . The 'extended' key has the content after the
* comment. The 'more_text' key has the custom "Read More" text.
*
* @param string $post Post content.
*
* @return array Post before ('main'), after ('extended'), and custom readmore ('more_text').
*/
function tve_get_extended( $post ) {
//Match the "More..." nodes
$more_tag = '#(.+?)#s';
if ( preg_match( $more_tag, $post, $matches ) ) {
list( $main, $extended ) = explode( $matches[0], $post, 2 );
$more_text = $matches[1];
$more_found = true;
} else {
$main = $post;
$extended = '';
$more_text = '';
$more_found = false;
}
// ` leading and trailing whitespace
$main = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $main );
$extended = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $extended );
$more_text = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $more_text );
return [
'main' => $main,
'extended' => $extended,
'more_text' => $more_text,
'more_found' => $more_found,
];
}
/**
* Adds inline script to hide more tag from the front end display
*
* @depricated
*/
function tve_hide_more_tag() {
_doing_it_wrong(
__FUNCTION__,
'This is deprecated since TAr version 2.4.5',
'2.4.5'
);
}
/**
* if the current post is a landing page created with TCB, forward the control over to the landing page layout.php file
*
* if the current post is a Thrive CB Lightbox, display it on a page that will mimic it's behaviour (semi-transparent background, close button etc)
*
* if there is a hook registered for displaying content, call that hook
*
* @return bool
*/
function tcb_custom_editable_content() {
// don't apply template redirects unless single post / page is being displayed.
if ( ! apply_filters( 'tcb_is_editor_page', is_singular() ) || is_feed() || is_comment_feed() ) {
return false;
}
$allow_landing_page_edit = apply_filters( 'tcb_allow_landing_page_edit', tve_in_architect() );
$post_id = get_the_ID();
$post_type = get_post_type( $post_id );
/**
* the filter should append its own custom templates based on the post ID / type
* if this array is not empty, it will use the first found file from this array as the post content template
*/
$custom_post_layouts = apply_filters( 'tcb_custom_post_layouts', [], $post_id, $post_type );
/* For TCB, we only have tcb_lightbox and landing pages editable with a separate layout */
if ( $post_type !== 'tcb_lightbox' && ! ( $lp_template = tve_post_is_landing_page( $post_id ) ) && empty( $custom_post_layouts ) ) {
return false;
}
$landing_page_dir = plugin_dir_path( __DIR__ ) . 'landing-page';
if ( $allow_landing_page_edit && $post_type === 'tcb_lightbox' ) {
tcb_lightbox( $post_id )->output_layout();
exit();
}
if ( $allow_landing_page_edit && ! empty( $lp_template ) ) {
/**
* first, check if a membership plugin is protecting this page and, if the user does not have access, just proceed with the regular page content
*/
if ( ! tve_membership_plugin_can_display_content() ) {
return false;
}
/* instantiate the $tcb_landing_page object - this is used throughout the layout.php for the landing page */
$tcb_landing_page = tcb_landing_page( $post_id, $lp_template );
$GLOBALS['tcb_lp_template'] = $lp_template;
$GLOBALS['tcb_landing_page'] = $tcb_landing_page;
/* base CSS file for all Page Templates */
if ( ! tve_check_if_thrive_theme() && ! \TCB\Lightspeed\Main::has_optimized_assets( $post_id ) && tve_in_architect() ) {
tve_enqueue_style( 'tve_landing_page_base_css', tve_editor_url( 'landing-page/templates/css/base.css' ), 99 );
}
$tcb_landing_page->enqueue_css();
$tcb_landing_page->ensure_external_assets();
include_once ABSPATH . '/wp-admin/includes/plugin.php';
if ( is_editor_page() || ! tve_hooked_in_template_redirect() ) {
/**
* added this here, because setting up a Landing Page as the homepage of your site would cause WP to not redirect properly non-www homepage to www homepage
*/
redirect_canonical();
/**
* Allow hooking before any output is generated for a landing page
*
* @param string $template_path full path to the template file being rendered
* @param TCB_Landing_Page $tcb_landing_page landing page instance
*/
do_action( 'tcb_landing_page_template_redirect', $landing_page_dir . '/layout.php', $tcb_landing_page );
/* give the control over to the landing page template */
include $landing_page_dir . '/layout.php';
exit();
}
/**
* Mark the fact that we removed the 'the_content' filter so we can add it back ( in landing-page/layout.php ).
*/
$GLOBALS['tcb_landing_page_needs_filter'] = true;
/**
* temporarily remove the_content filter for landing pages (just to not output anything in the head) - it caused issues on some shortcodes.
* this is re-added from the landing page layout.php file
*/
remove_filter( 'the_content', 'tve_editor_content' );
/**
* remove thrive_template_redirect filter from the themes
*/
remove_filter( 'template_redirect', 'thrive_template_redirect' );
/**
* this is a fix for conflicts appearing with various membership / coming soon plugins that use the template_redirect hook
*/
remove_all_filters( 'template_include' );
add_filter( 'template_include', 'tcb_get_landing_page_template_layout' );
/**
* Add template_include Filter After they were removed
*/
tve_compat_re_add_template_include_filters();
/**
* make sure we'll have at least one of these fired
*/
add_filter( 'page_template', 'tcb_get_landing_page_template_layout' );
} elseif ( $post_type !== 'post' && $post_type !== 'page' && ! empty( $custom_post_layouts ) && is_array( $custom_post_layouts ) ) {
/**
* loop through each of the post_custom_layouts files array to find the first valid one
*/
foreach ( $custom_post_layouts as $file ) {
$file = @realpath( $file );
if ( ! is_file( $file ) ) {
continue;
}
include $file;
exit();
}
}
}
/**
* @param string $template
*
* @return string the full path to the landing page layout template
*/
function tcb_get_landing_page_template_layout( $template ) {
return plugin_dir_path( dirname( __FILE__ ) ) . 'landing-page/layout.php';
}
/**
* parse and prepare all the required configuration for the different events
*
* @param string $content TCB - meta post content
*/
function tve_parse_events( &$content ) {
list( $start, $end ) = [
'__TCB_EVENT_',
'_TNEVE_BCT__',
];
if ( strpos( $content, $start ) === false ) {
return;
}
$triggers = tve_get_event_triggers();
$actions = tve_get_event_actions();
$event_pattern = "#data-tcb-events=('|\"){$start}(.+?){$end}('|\")#";
/* hold all the javascript callbacks required for the identified actions */
$javascript_callbacks = isset( $GLOBALS['tve_event_manager_callbacks'] ) ? $GLOBALS['tve_event_manager_callbacks'] : [];
/* holds all the Global JS required by different actions and event triggers on page load */
$registered_javascript_globals = isset( $GLOBALS['tve_event_manager_global_js'] ) ? $GLOBALS['tve_event_manager_global_js'] : [];
/* hold all instances of the Action classes in order to output stuff in the footer, we need to get out of the_content filter */
$registered_actions = isset( $GLOBALS['tve_event_manager_actions'] ) ? $GLOBALS['tve_event_manager_actions'] : [];
/*
* match all instances for Event Configurations
*/
if ( preg_match_all( $event_pattern, $content, $matches, PREG_OFFSET_CAPTURE ) !== false ) {
foreach ( $matches[2] as $i => $data ) {
$m = htmlspecialchars_decode( $data[0] ); // the actual matched regexp group
if ( ! ( $_params = json_decode( $m, true ) ) ) {
$_params = [];
}
if ( empty( $_params ) ) {
continue;
}
foreach ( $_params as $index => $event_config ) {
if ( empty( $event_config['t'] ) || empty( $event_config['a'] ) || ! isset( $triggers[ $event_config['t'] ] ) || ! isset( $actions[ $event_config['a'] ] ) ) {
continue;
}
/** @var TCB_Event_Action_Abstract $action */
$action = clone $actions[ $event_config['a'] ];
$registered_actions [] = [
'class' => $action,
'event_config' => $event_config,
];
if ( ! isset( $javascript_callbacks[ $event_config['a'] ] ) ) {
$javascript_callbacks[ $event_config['a'] ] = $action->getJsActionCallback();
}
if ( ! isset( $registered_javascript_globals[ 'action_' . $event_config['a'] ] ) ) {
$registered_javascript_globals[ 'action_' . $event_config['a'] ] = $action;
}
if ( ! isset( $registered_javascript_globals[ 'trigger_' . $event_config['t'] ] ) ) {
$registered_javascript_globals[ 'trigger_' . $event_config['t'] ] = $triggers[ $event_config['t'] ];
}
}
}
}
if ( empty( $javascript_callbacks ) ) {
return;
}
/* we need to add all the javascript callbacks into the page */
/* this cannot be done using wp_localize_script WP function, as each if the callback will actually be JS code */
///euuuughhh
$GLOBALS['tve_event_manager_callbacks'] = $javascript_callbacks;
$GLOBALS['tve_event_manager_global_js'] = $registered_javascript_globals;
$GLOBALS['tve_event_manager_actions'] = $registered_actions;
/* execute the mainPostCallback on all of the related actions, some of them might need to register stuff (e.g. lightboxes) */
foreach ( $GLOBALS['tve_event_manager_actions'] as $key => $item ) {
if ( empty( $item['main_post_callback_'] ) ) {
$GLOBALS['tve_event_manager_actions'][ $key ]['main_post_callback_'] = true;
$result = $item['class']->mainPostCallback( $item['event_config'] );
if ( is_string( $result ) ) {
$content .= $result;
}
}
}
/* remove previously assigned callback, if any - in case of list pages */
remove_action( 'wp_print_footer_scripts', 'tve_print_footer_events', - 50 );
add_action( 'wp_print_footer_scripts', 'tve_print_footer_events', - 50 );
}
/**
* We only leave this style family
*
* @return array
*/
function tve_get_style_families() {
return [ 'Flat' => tve_editor_css( 'thrive_flat.css' ) . '?ver=' . TVE_VERSION ];
}
/**
* load up all event manager callbacks into the page
*/
function tve_print_footer_events() {
if ( ! empty( $GLOBALS['tve_event_manager_callbacks'] ) ) {
echo '';
}
if ( ! empty( $GLOBALS['tve_event_manager_triggers'] ) ) {
echo '';
}
if ( ! empty( $GLOBALS['tve_event_manager_global_js'] ) ) {
foreach ( $GLOBALS['tve_event_manager_global_js'] as $object ) {
$object->outputGlobalJavascript();
}
}
if ( ! empty( $GLOBALS['tve_event_manager_actions'] ) ) {
foreach ( $GLOBALS['tve_event_manager_actions'] as $data ) {
if ( ! empty( $data['class'] ) && $data['class'] instanceof TCB_Event_Action_Abstract ) {
echo $data['class']->applyContentFilter( $data['event_config'] ); // phpcs:ignore
}
}
}
}
/**
* fills in some default font data and adds the custom font to the custom fonts list
*
* @return array the full array for the added font
*/
function tve_add_custom_font( $font_data ) {
$custom_fonts = tve_get_all_custom_fonts();
if ( ! isset( $font_data['font_id'] ) ) {
$font_data['font_id'] = count( $custom_fonts ) + 1;
}
if ( ! isset( $font_data['font_class'] ) ) {
$font_data['font_class'] = 'ttfm' . $font_data['font_id'];
}
if ( ! isset( $font_data['custom_css'] ) ) {
$font_data['custom_css'] = '';
}
if ( ! isset( $font_data['font_color'] ) ) {
$font_data['font_color'] = '';
}
if ( ! isset( $font_data['font_height'] ) ) {
$font_data['font_height'] = '1.6em';
}
if ( ! isset( $font_data['font_size'] ) ) {
$font_data['font_size'] = '1.6em';
}
if ( ! isset( $font_data['font_character_set'] ) ) {
$font_data['font_character_set'] = 'latin';
}
$custom_fonts [] = $font_data;
update_option( 'thrive_font_manager_options', json_encode( $custom_fonts ) );
return $font_data;
}
/**
* Update the image size with, url, width and height
*
* @param string $image_path
* @param array $template
* @param string $image_source
*
* @return array
*/
function tve_update_image_size( $image_path, $template, $image_source ) {
if ( is_file( $image_path ) && ini_get( 'allow_url_fopen' ) ) {
list( $width, $height ) = getimagesize( $image_path );
} else {
$width = 0;
$height = 0;
}
return array_merge( $template,
[
'thumb' => [
'url' => $image_source,
'w' => $width,
'h' => $height,
],
] );
}
/**
* run any necessary code that would be required during an upgrade
*
* @param $old_version
* @param $new_version
*/
function tve_run_plugin_upgrade( $old_version, $new_version ) {
if ( version_compare( $old_version, '1.74', '<' ) ) {
/**
* refactoring of user templates
*/
$user_templates = TCB\UserTemplates\Template::get_old_templates();
$css = get_option( 'tve_user_templates_styles' );
$new_templates = [];
if ( ! empty( $user_templates ) ) {
foreach ( $user_templates as $name => $content ) {
if ( is_array( $content ) ) {
continue;
}
$found = true;
$new_templates [] = array(
'name' => urldecode( stripslashes( $name ) ),
'content' => stripslashes( $content ),
'css' => isset( $css[ $name ] ) ? trim( stripslashes( $css[ $name ] ) ) : '',
);
}
}
if ( isset( $found ) ) {
usort( $new_templates, 'tve_tpl_sort' );
TCB\UserTemplates\Template::save_old_templates( $new_templates );
delete_option( 'tve_user_templates_styles' );
}
}
if ( version_compare( $old_version, '2.4.8', '<' ) ) {
$user_templates = TCB\UserTemplates\Template::get_old_templates();
$upload_dir = wp_get_upload_dir();
if ( ! empty( $upload_dir['basedir'] ) ) {
foreach ( $user_templates as & $template ) {
if ( ! isset( $template['thumb'] ) && isset( $template['image_url'] ) ) {
$image_path = trailingslashit( $upload_dir['basedir'] ) . 'thrive-visual-editor/user_templates/' . basename( $template['image_url'] );
$template = tve_update_image_size( $image_path, $template, $template['image_url'] );
$do_update = true;
unset( $template['image_url'] );
}
}
unset( $template );
}
if ( isset( $do_update ) ) {
TCB\UserTemplates\Template::save_old_templates( $user_templates );
}
}
}
/**
* determine whether the user is on the editor page or not (also takes into account edit capabilities)
*
* @return bool
*/
function is_editor_page() {
/**
* during AJAX calls, we need to apply a filter to get this value, we cannot rely on the traditional detection
*/
if ( wp_doing_ajax() ) {
$is_editor_page = apply_filters( 'tcb_is_editor_page_ajax', false );
if ( $is_editor_page ) {
return true;
}
}
if ( apply_filters( 'tcb_is_inner_frame_override', false ) ) {
return true;
}
if ( is_admin() ) {
return false;
}
if ( ! apply_filters( 'tcb_is_editor_page', (bool) get_the_ID() ) ) {
return false;
}
return isset( $_GET[ TVE_EDITOR_FLAG ] ) && TCB_Product::has_external_access( get_the_ID() ) && tve_membership_plugin_can_display_content();
}
/**
* check if there is a valid activated license for the TCB plugin
*
* @return bool
*/
function tve_tcb__license_activated() {
return TVE_Dash_Product_LicenseManager::getInstance()->itemActivated( TVE_Dash_Product_LicenseManager::TCB_TAG );
}
/**
* determine whether the user is on the editor page or not based just on a $_GET parameter
* modification: WP 4 removed the "preview" parameter
*
* @param bool $check_ajax_request whether or not to also return true for ajax requests made from the editor page
*
* @return bool
*/
function is_editor_page_raw( $check_ajax_request = false ) {
/**
* during AJAX calls, we need to apply a filter to get this value, we cannot rely on the traditional detection
*/
$is_rest_ajax = ! empty( $_REQUEST['tar_editor_page'] ) && defined( 'REST_REQUEST' ) && REST_REQUEST;
if ( $is_rest_ajax || wp_doing_ajax() ) {
$is_editor_ajax = $check_ajax_request && ! empty( $_REQUEST['tar_editor_page'] );
if ( apply_filters( 'tcb_is_editor_page_raw_ajax', $is_editor_ajax ) ) {
return true;
}
}
return isset( $_GET[ TVE_EDITOR_FLAG ] );
}
/**
* Removes the theme CSS from the architect page
*/
function tve_remove_theme_css() {
global $wp_styles;
$theme = get_template();
$stylesheet_dir = basename( get_stylesheet_directory() );
foreach ( $wp_styles->queue as $handle ) {
$src = $wp_styles->registered[ $handle ]->src;
if ( apply_filters( 'tcb_remove_theme_css', strpos( $src, $theme ) !== false || strpos( $src, $stylesheet_dir ) !== false, $src ) ) {
wp_deregister_style( $handle );
}
}
}
/**
* only enqueue scripts on our own editor pages
*/
function tve_enqueue_editor_scripts() {
$post_id = get_the_ID();
/**
* Fix issue with course overview not saving with the correct post ID.
**/
if ( $editor_id = filter_input( INPUT_GET, 'editor_id', FILTER_VALIDATE_INT ) ) {
$post_id = $editor_id;
}
$post_type = get_post_type( $post_id );
if ( is_editor_page() && tve_is_post_type_editable( $post_type ) ) {
$js_suffix = TCB_Utils::get_js_suffix();
/**
* this is to handle the following case: an user who has the TL plugin (or others) installed, TCB installed and enabled, but TCB license is expired
* in this case, users should still be able to edit stuff from outside the TCB plugin, such as forms
*/
if ( tve_tcb__license_activated() || apply_filters( 'tcb_skip_license_check', false ) ) {
/**
* apply extra filters that should check if the user can actually use the editor to edit this particular piece of content
*/
if ( apply_filters( 'tcb_user_can_edit', true, $post_id ) ) {
\TCB\Lightspeed\JS::get_instance( $post_id )->enqueue_scripts();
/**
* enqueue resizable for older WP versions
*/
wp_enqueue_script( 'jquery-ui-resizable' );
tve_enqueue_script( 'tcb-froala', tve_editor_js( '/froala' . $js_suffix ), [ 'tve_editor', 'backbone' ] );
/** control panel scripts and dependencies */
tve_enqueue_script( 'tve_editor', tve_editor_js( '/editor' . $js_suffix ), [
'jquery',
'jquery-ui-autocomplete',
'jquery-ui-slider',
'jquery-ui-resizable',
'underscore',
], false, true );
// Enqueue dom-to-image script. Used for generation of the images
wp_enqueue_script( 'tcb-dom-to-image', tve_editor_url() . '/editor/js/libs/dom-to-image' . $js_suffix, [ 'tve_editor' ] );
// Enqueue lazyload script. Used for lazyloading images
wp_enqueue_script( 'tcb-lazyload', tve_editor_url() . '/editor/js/libs/lazyload.min.js', [ 'tve_editor' ] );
// jQuery UI stuff
// no need to append TVE_VERSION for these scripts
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'jquery-serialize-object' );
wp_enqueue_script( 'jquery-ui-core', [ 'jquery' ] );
wp_enqueue_script( 'jquery-ui-autocomplete' );
wp_enqueue_script( 'jquery-ui-sortable' );
wp_enqueue_script( 'jquery-ui-slider', [ 'jquery', 'jquery-ui-core' ] );
wp_enqueue_script( 'jquery-masonry', [ 'jquery' ] );
/*script needed to load the VooPlayer videos*/
wp_enqueue_script( 'vooplayer_script', 'https://s3.spotlightr.com/assets/vooplayer.js', [], '', false );
// now enqueue the styles
tve_enqueue_style( 'tve_editor_style', tve_editor_css( 'editor.css' ) );
tve_enqueue_style( 'tve_inner_style', tve_editor_css( 'editor/style.css' ) );
// custom fonts from Font Manager
$all_fonts = tve_get_all_custom_fonts();
$all_fonts_enqueue = apply_filters( 'tve_filter_custom_fonts_for_enqueue_in_editor', $all_fonts );
tve_enqueue_fonts( $all_fonts_enqueue );
/**
* we need to enforce this check here, so that we don't make http requests from https pages
*/
$admin_base_url = admin_url( '/', is_ssl() ? 'https' : 'admin' );
// for some reason, the above line does not work in some instances
if ( is_ssl() ) {
$admin_base_url = str_replace( 'http://', 'https://', $admin_base_url );
}
/**
* Get all dynamic links available
*/
$dynamic_links = apply_filters( 'tcb_dynamiclink_data', [] );
/* add the 'Content' and 'Custom Fields' keys at the end of the array */
$dynamic_links = array_merge( $dynamic_links, [
'Content' => [],
'Custom Fields' => [],
'Shortcode' => [],
] );
$hidden_dynamic_links_options = [ 'Custom Fields Global' ]; //Hide options but keep their data
$author_social_url = tve_author_social_url();
// pass variables needed to client side
$tve_path_params = array(
'admin_url' => $admin_base_url,
'site_url' => site_url(),
'cpanel_dir' => tve_editor_url() . '/editor',
'shortcodes_dir' => tve_editor_url() . '/shortcodes/templates/',
'editor_dir' => tve_editor_css(),
'post_id' => $post_id,
'post_url' => get_permalink( $post_id ),
'tve_version' => TVE_VERSION,
'ajax_url' => $admin_base_url . 'admin-ajax.php',
'is_rtl' => (int) is_rtl(),
'woocommerce' => \TCB\Integrations\WooCommerce\Main::get_localized_data(),
'conditional_display' => \TCB\ConditionalDisplay\Main::get_localized_data(),
'custom_fonts' => $all_fonts,
'post_type' => $post_type,
'taxonomies' => get_object_taxonomies( 'post', 'object' ),
'post_types' => tve_get_regular_post_types(),
'date_format' => get_option( 'date_format' ),
'time_format' => get_option( 'time_format' ),
'routes' => array(
'base' => get_rest_url( get_current_blog_id(), 'tcb/v1' ),
'posts' => get_rest_url( get_current_blog_id(), 'tcb/v1' . '/posts' ),
),
'dynamic_image_placeholders' => array(
'featured' => TCB_Post_List_Featured_Image::get_default_url(),
'author' => TCB_Post_List_Author_Image::get_default_url(),
'user' => tcb_dynamic_user_image_instance( get_current_user_id() )->get_placeholder_url(),
//a fully transparent 840 x 840px png
'transparent_bkg' => tve_editor_url( 'editor/css/images/hidden_placeholder.png' ),
),
'post_list_pagination' => TCB_Utils::get_pagination_localized_data(),
'post_image' => array(
'featured' => TCB_Post_List_Featured_Image::get_default_url( $post_id ),
'author' => TCB_Post_List_Author_Image::get_default_url( $post_id ),
'user' => tcb_dynamic_user_image_instance( get_current_user_id() )->get_default_url(),
),
'user_image' => array(
'name' => tcb_dynamic_user_image_instance( get_current_user_id() )->get_user_name(),
),
'featured_image' => array(
'default_sizes' => array_keys( TCB_Post_List_Featured_Image::filter_available_sizes() ),
'image_subsizes' => TCB_Post_List_Featured_Image::get_registered_image_subsizes(),
),
'dynamic_links' => $dynamic_links,
'dynamic_links_categories' => array_values( array_diff( array_keys( $dynamic_links ), $hidden_dynamic_links_options ) ),
/**
* Each element in the array should be a group ( group name = key, array of values ) :
* 'Group Name' => [
* [
* 'name' => 'VisibleName', // ?? visible name in editing mode
* 'value' => 'shortcode_tag', // shortcode tag that's rendered in the page
* 'option' => 'Shortcode Title', // shortcode title - title displayed in the menu
* ],
* ],
*
* !Important note: When adding new groups on this filter, also add them in SHORTCODE_GROUP_ORDER_MAP in JS in order to specify where it should show up
*/
'inline_shortcodes' => apply_filters( 'tcb_inline_shortcodes', [] ),
'external_custom_fields' => tcb_custom_fields_api()->get_all_external_fields(),
'tve_fa_kit' => get_option( 'tve_fa_kit', '' ),
'tve_icon_api' => TVE_ICON_API,
'author_social_links' => $author_social_url,
'site_locale' => tve_get_locale(),
);
$tve_path_params = apply_filters( 'tcb_editor_javascript_params', $tve_path_params, $post_id, $post_type );
wp_localize_script( 'tve_editor', 'tve_path_params', $tve_path_params );
/* some params will be needed also for the frontend script */
$frontend_options = array(
'is_editor_page' => true,
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'social_fb_app_id' => tve_get_social_fb_app_id(),
'is_single' => (string) ( (int) is_singular() ),
'nonce' => TCB_Utils::create_nonce(),
);
/**
* Allows adding frontend options from different plugins
*
* @param $frontend_options
*/
$frontend_options = apply_filters( 'tve_frontend_options_data', $frontend_options );
wp_localize_script( 'tve_frontend', 'tve_frontend_options', $frontend_options );
do_action( 'tcb_editor_enqueue_scripts' );
}
} else {
add_action( 'wp_print_footer_scripts', 'tve_license_notice' );
}
}
}
/**
* Return the regular post types without the blacklisted ones.
*
* @return array
*/
function tve_get_regular_post_types() {
$ignored_types = apply_filters( 'thrive_ignored_post_types', array(
'attachment',
'tcb_lightbox',
'tcb_symbol',
'mailpoet_page',
TCB\UserTemplates\Template::get_post_type_name(),
TCB\SavedLandingPages\Saved_Lp::get_post_type_name(),
TCB\Notifications\Post_Type::NAME,
TCB\ConditionalDisplay\PostTypes\Global_Conditional_Set::NAME,
TCB\ConditionalDisplay\PostTypes\Conditional_Display_Group::NAME,
) );
$all = get_post_types( [ 'public' => true ] );
$post_types = [];
foreach ( $all as $key => $post_type ) {
if ( in_array( $key, $ignored_types, true ) ) {
continue;
}
$post_types[ $key ] = array(
'label' => tvd_get_post_type_label( $key ),
'plural_label' => get_post_type_object( $key )->labels->name,
);
}
return $post_types;
}
/**
* enqueue the associated style family for a post / page
*
* this also gets called in archive (list) pages, there we need to load style families for each post from the list
*
* @param null $post_id optional this will only come filled in when calling it from a lightbox
*/
function tve_enqueue_style_family( $post_id = null ) {
global $wp_query;
if ( null === $post_id ) {
$posts_to_load = $wp_query->posts;
if ( empty( $posts_to_load ) || ! is_array( $posts_to_load ) ) {
return;
}
$posts = [];
foreach ( $posts_to_load as $post ) {
$posts [] = $post->ID;
}
} else {
$posts = [ $post_id ];
}
foreach ( $posts as $p_id ) {
\TCB\Lightspeed\Css::get_instance( $p_id )->load_optimized_style( 'base' );
}
}
/**
* get the css class for a style family
*
* @param int $post_id
*
* @return string
*/
function tve_get_style_family_class( $post_id ) {
return 'tve_flt';
}
function tve_get_style_enqueue_id() {
return 'tve_style_family_tve_flt';
}
/**
* Returns all global style option names depending on the element type
*
* @return array
*/
function tve_get_global_styles_option_names() {
return apply_filters( 'tcb_global_styles_option_name', [
'button' => 'tve_global_button_styles',
'section' => 'tve_global_section_styles',
'contentbox' => 'tve_global_contentbox_styles',
'link' => 'tve_global_link_styles',
'text' => 'tve_global_text_styles',
] );
}
/**
* Constructs the shared styles css
*
* @param string $post_content
* @param string $for_media
* @param boolean $editor_ajax_check optional. Controls whether or not to output global styles in ajax requests in the editor page.
* @param boolean $store_globals Whether to store the parsed styles in the global cache
*
* @return string
*/
function tve_get_shared_styles( $post_content = '', $for_media = '', $editor_ajax_check = true, $store_globals = true ) {
$for_media = (string) $for_media;
/**
* Makes sure global styles are not loaded into editor page via ajax
*/
if ( $editor_ajax_check && wp_doing_ajax() && is_editor_page_raw( true ) ) {
return '';
}
/**
* Makes sure global styles are only loaded once in the editor page
*/
if ( ! wp_doing_ajax() && tcb_editor()->is_inner_frame() && ! doing_action( 'wp_head' ) ) {
return '';
}
$output = '';
$shared_styles = [];
$global_style_options = tve_get_global_styles_option_names();
$button_styles = get_option( $global_style_options['button'], [] );
$section_styles = get_option( $global_style_options['section'], [] );
$cb_styles = get_option( $global_style_options['contentbox'], [] );
$link_styles = get_option( $global_style_options['link'], [] );
$text_styles = get_option( $global_style_options['text'], [] );
$styles_types = apply_filters( 'tcb_get_extra_global_styles', [ $button_styles, $section_styles, $cb_styles, $link_styles, $text_styles ] );
$is_editor_page = is_editor_page_raw( true );
if ( $is_editor_page ) {
$post_content = '';
}
if ( empty( $GLOBALS['tve_parsed_shared_styles'] ) ) {
/* so we won't render the same shared style multiple times */
$GLOBALS['tve_parsed_shared_styles'] = [];
}
foreach ( $styles_types as $style_type ) {
if ( ! is_array( $style_type ) ) {
$style_type = [];
}
foreach ( $style_type as $identifier => $styles ) {
if ( empty( $styles['css'] ) ) {
/**
* Security check
*/
continue;
}
if ( in_array( $identifier, $GLOBALS['tve_parsed_shared_styles'] ) || (
! empty( $post_content ) &&
( strpos( $post_content, TVE_GLOBAL_STYLE_CLS_PREFIX ) === false || strpos( $post_content, $identifier ) === false ) )
) {
continue;
}
if ( $store_globals ) {
$GLOBALS['tve_parsed_shared_styles'][] = $identifier;
}
foreach ( $styles['css'] as $media => $css ) {
if ( empty( $shared_styles[ $media ] ) ) {
$shared_styles[ $media ] = [];
}
$shared_styles[ $media ] = array_merge( $shared_styles[ $media ], $css );
}
if ( empty( $styles['fonts'] ) ) {
/**
* Security check
*/
continue;
}
foreach ( $styles['fonts'] as $i => $import_rule ) {
$output .= $import_rule;
}
}
}
/**
* Default styles should only be printed in this node in the editor page, and only if a landing page allows it (if editing a landing page)
*/
$output_default_styles = $is_editor_page;
if ( $output_default_styles && tcb_post()->is_landing_page() && tcb_landing_page( get_the_ID() )->should_strip_head_css() ) {
$output_default_styles = false;
}
/**
* The filter allows including / excluding shared styles from the current piece of content
*
* @param bool $output_default_styles
*/
$output_default_styles = apply_filters( 'tcb_output_default_styles', $output_default_styles );
if ( $output_default_styles ) {
/* Make sure default styles are inserted before the global styles */
$default_styles = tve_prepare_default_styles();
$output .= implode( "", $default_styles['@imports'] );
foreach ( $default_styles['media'] as $media_key => $css_str ) {
if ( ! isset( $shared_styles[ $media_key ] ) ) {
$shared_styles[ $media_key ] = [ $css_str ];
} else {
array_unshift( $shared_styles[ $media_key ], $css_str );
}
}
}
foreach ( $shared_styles as $media => $css_array ) {
if ( ! empty( $for_media ) && strpos( $media, $for_media ) === false ) {
/**
* If for media parameter is defined it will output only the css for that particular media
*/
continue;
}
$output .= '@media' . $media . '{';
foreach ( $css_array as $css_item ) {
$output .= $css_item;
}
$output .= '}';
}
$global_selector = tcb_selection_root();
$selector = apply_filters( 'tcb_global_styles_selector', $global_selector );
$output = str_replace( $global_selector, $selector, $output );
if ( ! empty( $output ) || $is_editor_page ) {
$output = TCB\Lightspeed\Fonts::parse_google_fonts( stripslashes( $output ) );
$output = sprintf( '', tve_prepare_global_variables_for_front( $output ) );
}
return $output;
}
/**
* Loads user defined custom css in the header to override style family css
* If called with $post_id != null, it will load the custom css and user custom css from inside the loop (in case of homepage consisting of other pages, for example)
*/
function tve_load_custom_css( $post_id = null ) {
if ( is_feed() ) {
return;
}
if ( ! is_null( $post_id ) ) {
/**
* Outputs the shared styles css
*/
echo tve_get_shared_styles( tve_get_post_meta( $post_id, 'tve_updated_post' ) );
$custom_css = trim( tve_get_post_meta( $post_id, 'tve_custom_css', true ) . tve_get_post_meta( $post_id, 'tve_user_custom_css', true ) );
if ( $custom_css ) {
$custom_css = do_shortcode( tve_prepare_global_variables_for_front( $custom_css ) );
echo sprintf(
'',
tcb_custom_css( $custom_css )
);
}
/**
* Used for printing extra css on the page, called from LP class
*/
do_action( 'tcb_print_custom_style', $post_id );
return;
}
TCB_Utils::before_custom_css_processing();
global $wp_query;
$posts_to_load = $wp_query->posts;
global $css_loaded_post_id;
$css_loaded_post_id = [];
/* user-defined css from the Custom CSS content element */
$user_custom_css = '';
if ( $posts_to_load ) {
$inline_styles = '';
$post_content = '';
foreach ( $posts_to_load as $post ) {
$inline_styles .= tve_get_post_meta( $post->ID, 'tve_custom_css', true );
$user_custom_css .= tve_get_post_meta( $post->ID, 'tve_user_custom_css', true );
array_push( $css_loaded_post_id, $post->ID );
$post_content .= tve_get_post_meta( $post->ID, 'tve_updated_post' );
/**
* Used for printing extra css on the page, called from LP class
*/
do_action( 'tcb_print_custom_style', $post->ID );
}
$is_editor_page = is_editor_page();
if ( ! empty( $post_content ) || $is_editor_page ) {
/**
* Outputs the shared styles css
*/
echo tve_get_shared_styles( $post_content );
}
if ( ! empty( $inline_styles ) ) {
$inline_styles = do_shortcode( tve_prepare_global_variables_for_front( $inline_styles ) );
$inline_styles = tcb_custom_css( $inline_styles );
$inline_styles = TCB\Lightspeed\Fonts::parse_google_fonts( $inline_styles );
?>
%s', $user_custom_css ) : '';
}
/**
* Action triggered to load more css or force css that wasnt loaded by TAR
* e.g 404 templates
*/
do_action( 'tve_after_load_custom_css' );
TCB_Utils::after_custom_css_processing();
}
/**
* checks to see if content being loaded is actually being loaded from within the loop (correctly) or being pulled
* incorrectly to make up another page (for instance, a homepage that pulls different sections from pieces of content)
*/
function tve_check_in_loop( $post_id ) {
global $css_loaded_post_id;
if ( ! empty( $css_loaded_post_id ) && in_array( $post_id, $css_loaded_post_id ) ) {
return true;
}
return false;
}
/**
* replace [tcb-script] with script tags
*
* @param array $matches
*
* @return string
*/
function tve_restore_script_tags_replace( $matches ) {
$matches[2] = str_replace( '<\\/script', '<\\\\/script', $matches[2] );
$content = '';
if ( ! is_editor_page_raw() && strpos( $matches[1], 'tickettailor.com' ) !== false ) {
/*
* tickettailor.com js widget has a particularity: they require the parent node of the script to have the className attribute equal to "tt-widget"
* Because the script is wrapped in a element, we cannot dynamically change that class to `tt-widget`
*
* Solution is to close the `` tag, output the script, then reopen an empty tag
* This only needs to be done on frontend, not on the editor page
*/
$content = '' . $content . '';
}
return $content;
}
/**
* replace [tcb-noscript] with