* @copyright 2007-2022 Leotheme * @license http://leotheme.com - prestashop template provider */ namespace LeoElements; use LeoElements\Core\Base\App; use LeoElements\Core\Base\Document; use LeoElements\Core\Responsive\Files\Frontend as FrontendFile; use LeoElements\Core\Files\CSS\Global_CSS; use LeoElements\Core\Files\CSS\Post as Post_CSS; use LeoElements\Core\Files\CSS\Post_Preview; use LeoElements\Core\Responsive\Responsive; use LeoElements\Core\Settings\Manager as SettingsManager; use LeoElements\Leo_Helper; if ( ! defined( '_PS_VERSION_' ) ) { exit; // Exit if accessed directly. } /** * Elementor frontend. * * Elementor frontend handler class is responsible for initializing Elementor in * the frontend. * * @since 1.0.0 */ class Frontend extends App { /** * The priority of the content filter. */ const THE_CONTENT_FILTER_PRIORITY = 9; /** * Post ID. * * Holds the ID of the current post. * * @access private * * @var int Post ID. */ private $post_id; /** * Fonts to enqueue * * Holds the list of fonts that are being used in the current page. * * @since 1.9.4 * @access public * * @var array Used fonts. Default is an empty array. */ public $fonts_to_enqueue = []; /** * Registered fonts. * * Holds the list of enqueued fonts in the current page. * * @since 1.0.0 * @access private * * @var array Registered fonts. Default is an empty array. */ private $registered_fonts = []; /** * Icon Fonts to enqueue * * Holds the list of Icon fonts that are being used in the current page. * * @since 1.0.0 * @access private * * @var array Used icon fonts. Default is an empty array. */ private $icon_fonts_to_enqueue = []; /** * Enqueue Icon Fonts * * Holds the list of Icon fonts already enqueued in the current page. * * @since 1.0.0 * @access private * * @var array enqueued icon fonts. Default is an empty array. */ private $enqueued_icon_fonts = []; /** * Whether the page is using Elementor. * * Used to determine whether the current page is using Elementor. * * @since 1.0.0 * @access private * * @var bool Whether Elementor is being used. Default is false. */ private $_has_elementor_in_page = false; /** * Whether the excerpt is being called. * * Used to determine whether the call to `the_content()` came from `get_the_excerpt()`. * * @since 1.0.0 * @access private * * @var bool Whether the excerpt is being used. Default is false. */ private $_is_excerpt = false; /** * Filters removed from the content. * * Hold the list of filters removed from `the_content()`. Used to hold the filters that * conflicted with Elementor while Elementor process the content. * * @since 1.0.0 * @access private * * @var array Filters removed from the content. Default is an empty array. */ private $content_removed_filters = []; /** * @var Document[] */ private $admin_bar_edit_documents = []; /** * @var string[] */ private $body_classes = [ 'elementor-default', ]; /** * Front End constructor. * * Initializing Elementor front end. Make sure we are not in admin, not and * redirect from old URL structure of Elementor editor. * * @since 1.0.0 * @access public */ public function __construct() { // We don't need this class in admin side, but in AJAX requests. if ( Leo_Helper::is_admin() && ! Leo_Helper::wp_doing_ajax() ) { return; } Leo_Helper::add_action( 'template_redirect', [ $this, 'init' ] ); Leo_Helper::add_action( 'wp_enqueue_scripts', [ $this, 'register_scripts' ], 5 ); Leo_Helper::add_action( 'wp_enqueue_scripts', [ $this, 'register_styles' ], 5 ); $this->add_content_filter(); // Hack to avoid enqueue post CSS while it's a `the_excerpt` call. Leo_Helper::add_filter( 'get_the_excerpt', [ $this, 'start_excerpt_flag' ], 1 ); Leo_Helper::add_filter( 'get_the_excerpt', [ $this, 'end_excerpt_flag' ], 20 ); } /** * Get module name. * * Retrieve the module name. * * @since 1.0.0 * @access public * * @return string Module name. */ public function get_name() { return 'frontend'; } /** * Init. * * Initialize Elementor front end. Hooks the needed actions to run Elementor * in the front end, including script and style registration. * * Fired by `template_redirect` action. * * @since 1.0.0 * @access public */ public function init() { if ( Plugin::$instance->editor->is_edit_mode() ) { return; } Leo_Helper::add_filter( 'body_class', [ $this, 'body_class' ] ); if ( Plugin::$instance->preview->is_preview_mode() ) { return; } if ( current_user_can( 'manage_options' ) ) { Plugin::$instance->init_common(); } $this->post_id = Leo_Helper::get_the_ID(); if ( Leo_Helper::is_singular() && Plugin::$instance->db->is_built_with_elementor( $this->post_id ) ) { Leo_Helper::add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_styles' ] ); } // Priority 7 to allow google fonts in header template to load in
tag Leo_Helper::add_action( 'wp_head', [ $this, 'print_fonts_links' ], 7 ); Leo_Helper::add_action( 'wp_footer', [ $this, 'wp_footer' ] ); } /** * @since 2.0.12 * @access public * @param string|array $class */ public function add_body_class( $class ) { if ( is_array( $class ) ) { $this->body_classes = array_merge( $this->body_classes, $class ); } else { $this->body_classes[] = $class; } } /** * Body tag classes. * * Add new elementor classes to the body tag. * * Fired by `body_class` filter. * * @since 1.0.0 * @access public * * @param array $classes Optional. One or more classes to add to the body tag class list. * Default is an empty array. * * @return array Body tag classes. */ public function body_class( $classes = [] ) { $classes = array_merge( $classes, $this->body_classes ); $id = Leo_Helper::get_the_ID(); if ( Leo_Helper::is_singular() && Plugin::$instance->db->is_built_with_elementor( $id ) ) { $classes[] = 'elementor-page elementor-page-' . $id; } return $classes; } /** * Add content filter. * * Remove plain content and render the content generated by Elementor. * * @since 1.8.0 * @access public */ public function add_content_filter() { Leo_Helper::add_filter( 'the_content', [ $this, 'apply_builder_in_content' ], self::THE_CONTENT_FILTER_PRIORITY ); } /** * Remove content filter. * * When the Elementor generated content rendered, we remove the filter to prevent multiple * accuracies. This way we make sure Elementor renders the content only once. * * @since 1.8.0 * @access public */ public function remove_content_filter() { remove_filter( 'the_content', [ $this, 'apply_builder_in_content' ], self::THE_CONTENT_FILTER_PRIORITY ); } /** * Registers scripts. * * Registers all the frontend scripts. * * Fired by `wp_enqueue_scripts` action. * * @since 1.2.1 * @access public */ public function register_scripts() { /** * Before frontend register scripts. * * Fires before Elementor frontend scripts are registered. * * @since 1.2.1 */ Leo_Helper::do_action( 'elementor/frontend/before_register_scripts' ); Leo_Helper::wp_register_script( 'elementor-frontend-modules', $this->get_js_assets_url( 'frontend-modules' ), [ 'jquery', ], LEOELEMENTS_VERSION, true ); Leo_Helper::wp_register_script( 'elementor-waypoints', $this->get_js_assets_url( 'waypoints', 'assets/lib/waypoints/' ), [ 'jquery', ], '4.0.2', true ); Leo_Helper::wp_register_script( 'flatpickr', $this->get_js_assets_url( 'flatpickr', 'assets/lib/flatpickr/' ), [ 'jquery', ], '4.1.4', true ); Leo_Helper::wp_register_script( 'imagesloaded', $this->get_js_assets_url( 'imagesloaded', 'assets/lib/imagesloaded/' ), [ 'jquery', ], '4.1.0', true ); Leo_Helper::wp_register_script( 'jquery-numerator', $this->get_js_assets_url( 'jquery-numerator', 'assets/lib/jquery-numerator/' ), [ 'jquery', ], '0.2.1', true ); Leo_Helper::wp_register_script( 'swiper', $this->get_js_assets_url( 'swiper', 'assets/lib/swiper/' ), [], '4.4.6', true ); Leo_Helper::wp_register_script( 'jquery-slick', $this->get_js_assets_url( 'slick', 'assets/lib/slick/' ), [ 'jquery', ], '1.8.1', true ); Leo_Helper::wp_register_script( 'elementor-dialog', $this->get_js_assets_url( 'dialog', 'assets/lib/dialog/' ), [ 'jquery-ui-position', ], '4.7.1', true ); Leo_Helper::wp_register_script( 'elementor-frontend', $this->get_js_assets_url( 'frontend' ), [ 'elementor-frontend-modules', 'elementor-dialog', 'elementor-waypoints', 'swiper', ], LEOELEMENTS_VERSION, true ); /** * After frontend register scripts. * * Fires after Elementor frontend scripts are registered. * * @since 1.2.1 */ Leo_Helper::do_action( 'elementor/frontend/after_register_scripts' ); } /** * Registers styles. * * Registers all the frontend styles. * * Fired by `wp_enqueue_scripts` action. * * @since 1.2.0 * @access public */ public function register_styles() { /** * Before frontend register styles. * * Fires before Elementor frontend styles are registered. * * @since 1.2.0 */ Leo_Helper::do_action( 'elementor/frontend/before_register_styles' ); Leo_Helper::wp_register_style( 'font-awesome', $this->get_css_assets_url( 'font-awesome', 'assets/lib/font-awesome/css/' ), [], '4.7.0' ); Leo_Helper::wp_register_style( 'ce-icons', $this->get_css_assets_url( 'ce-icons', 'assets/lib/eicons/css/' ), [], '5.11.0' ); Leo_Helper::wp_register_style( 'elementor-animations', $this->get_css_assets_url( 'animations', 'assets/lib/animations/', true ), [], LEOELEMENTS_VERSION ); Leo_Helper::wp_register_style( 'flatpickr', $this->get_css_assets_url( 'flatpickr', 'assets/lib/flatpickr/' ), [], '4.1.4' ); $min_suffix = Utils::is_script_debug() ? '' : '.min'; $direction_suffix = Leo_Helper::is_rtl() ? '-rtl' : ''; $frontend_file_name = 'frontend' . $direction_suffix . $min_suffix . '.css'; $has_custom_file = Responsive::has_custom_breakpoints(); if ( $has_custom_file ) { $frontend_file = new FrontendFile( 'custom-' . $frontend_file_name, Responsive::get_stylesheet_templates_path() . $frontend_file_name ); $time = $frontend_file->get_meta( 'time' ); if ( ! $time ) { $frontend_file->update(); } $frontend_file_url = $frontend_file->get_url(); } else { $frontend_file_url = LEOELEMENTS_ASSETS_URL . 'css/' . $frontend_file_name; } Leo_Helper::wp_register_style( 'elementor-frontend', $frontend_file_url, [], $has_custom_file ? null : LEOELEMENTS_VERSION ); /** * After frontend register styles. * * Fires after Elementor frontend styles are registered. * * @since 1.2.0 */ Leo_Helper::do_action( 'elementor/frontend/after_register_styles' ); } /** * Enqueue scripts. * * Enqueue all the frontend scripts. * * @since 1.0.0 * @access public */ public function enqueue_scripts() { /** * Before frontend enqueue scripts. * * Fires before Elementor frontend scripts are enqueued. * * @since 1.0.0 */ Leo_Helper::do_action( 'elementor/frontend/before_enqueue_scripts' ); Leo_Helper::wp_enqueue_script( 'elementor-frontend' ); $this->print_config(); /** * After frontend enqueue scripts. * * Fires after Elementor frontend scripts are enqueued. * * @since 1.0.0 */ Leo_Helper::do_action( 'elementor/frontend/after_enqueue_scripts' ); } /** * Enqueue styles. * * Enqueue all the frontend styles. * * Fired by `wp_enqueue_scripts` action. * * @since 1.0.0 * @access public */ public function enqueue_styles() { /** * Before frontend styles enqueued. * * Fires before Elementor frontend styles are enqueued. * * @since 1.0.0 */ Leo_Helper::do_action( 'elementor/frontend/before_enqueue_styles' ); Leo_Helper::wp_enqueue_style( 'elementor-icons' ); Leo_Helper::wp_enqueue_style( 'elementor-animations' ); Leo_Helper::wp_enqueue_style( 'elementor-frontend' ); /** * After frontend styles enqueued. * * Fires after Elementor frontend styles are enqueued. * * @since 1.0.0 */ Leo_Helper::do_action( 'elementor/frontend/after_enqueue_styles' ); if ( ! Plugin::$instance->preview->is_preview_mode() ) { $this->parse_global_css_code(); $post_id = Leo_Helper::get_the_ID(); // Check $post_id for virtual pages. check is singular because the $post_id is set to the first post on archive pages. if ( $post_id && Leo_Helper::is_singular() ) { $css_file = Post_CSS::create( Leo_Helper::get_the_ID() ); $css_file->enqueue(); } } } /** * Elementor footer scripts and styles. * * Handle styles and scripts that are not printed in the header. * * Fired by `wp_footer` action. * * @since 1.0.11 * @access public */ public function wp_footer() { if ( ! $this->_has_elementor_in_page ) { return; } $this->enqueue_styles(); $this->enqueue_scripts(); $this->print_fonts_links(); } /** * Print fonts links. * * Enqueue all the frontend fonts by url. * * Fired by `wp_head` action. * * @since 1.9.4 * @access public */ public function print_fonts_links() { $google_fonts = [ 'upload' => [], 'google' => [], 'early' => [], ]; foreach ( $this->fonts_to_enqueue as $key => $font ) { $font_type = Fonts::get_font_type( $font ); switch ( $font_type ) { case Fonts::TUANVU_UPLOAD: $google_fonts['upload'][] = $font; break; case Fonts::GOOGLE: $google_fonts['google'][] = $font; break; case Fonts::EARLYACCESS: $google_fonts['early'][] = $font; break; case false: $this->maybe_enqueue_icon_font( $font ); break; default: /** * Print font links. * * Fires when Elementor frontend fonts are printed on the HEAD tag. * * The dynamic portion of the hook name, `$font_type`, refers to the font type. * * @since 2.0.0 * * @param string $font Font name. */ Leo_Helper::do_action( "elementor/fonts/print_font_links/{$font_type}", $font ); } } $this->fonts_to_enqueue = []; $this->enqueue_google_fonts( $google_fonts ); // $this->enqueue_upload_fonts( $google_fonts ); $this->enqueue_icon_fonts(); } private function maybe_enqueue_icon_font( $icon_font_type ) { if ( ! Icons_Manager::is_migration_allowed() ) { return; } $icons_types = Icons_Manager::get_icon_manager_tabs(); if ( ! isset( $icons_types[ $icon_font_type ] ) ) { return; } $icon_type = $icons_types[ $icon_font_type ]; if ( isset( $icon_type['url'] ) ) { $this->icon_fonts_to_enqueue[ $icon_font_type ] = [ $icon_type['url'] ]; } } private function enqueue_icon_fonts() { if ( empty( $this->icon_fonts_to_enqueue ) || ! Icons_Manager::is_migration_allowed() ) { return; } foreach ( $this->icon_fonts_to_enqueue as $icon_type => $css_url ) { Leo_Helper::wp_enqueue_style( 'elementor-icons-' . $icon_type ); $this->enqueued_icon_fonts[] = $css_url; } //clear enqueued icons $this->icon_fonts_to_enqueue = []; } /** * Print Google fonts. * * Enqueue all the frontend Google fonts. * * Fired by `wp_head` action. * * @since 1.0.0 * @access private * * @param array $google_fonts Optional. Google fonts to print in the frontend. * Default is an empty array. */ private function enqueue_google_fonts( $google_fonts = [] ) { static $google_fonts_index = 0; $print_google_fonts = true; /** * Print frontend google fonts. * * Filters whether to enqueue Google fonts in the frontend. * * @since 1.0.0 * * @param bool $print_google_fonts Whether to enqueue Google fonts. Default is true. */ $print_google_fonts = Leo_Helper::apply_filters( 'elementor/frontend/print_google_fonts', $print_google_fonts ); if ( ! $print_google_fonts ) { return; } // Print used fonts if ( ! empty( $google_fonts['google'] ) ) { $google_fonts_index++; foreach ( $google_fonts['google'] as &$font ) { $font = str_replace( ' ', '+', $font ) . ':100,100italic,200,200italic,300,300italic,400,400italic,500,500italic,600,600italic,700,700italic,800,800italic,900,900italic'; } $fonts_url = sprintf( 'https://fonts.googleapis.com/css?family=%s', implode( rawurlencode( '|' ), $google_fonts['google'] ) ); $subsets = [ 'ru_RU' => 'cyrillic', 'bg_BG' => 'cyrillic', 'he_IL' => 'hebrew', 'el' => 'greek', 'vi' => 'vietnamese', 'uk' => 'cyrillic', 'cs_CZ' => 'latin-ext', 'ro_RO' => 'latin-ext', 'pl_PL' => 'latin-ext', ]; $locale= \Context::getContext()->language->iso_code; if ( isset( $subsets[ $locale ] ) ) { $fonts_url .= '&subset=' . $subsets[ $locale ]; } echo ''; // phpcs:ignore } if ( ! empty( $google_fonts['upload'] ) ) { $google_fonts_index++; foreach ( $google_fonts['upload'] as &$font ) { $mldfont = \LeoElementsFont::getAllFontsByFamily($font); if($mldfont) { // __PS_BASE_URI__ . 'themes/' . apPageHelper::getThemeName() . '/assets/img/patterns/' // _PS_BASE_URL_.__PS_BASE_URI__.'themes/'._THEME_NAME_.'/assets/fonts/' // $fonts_url = sprintf( 'http://leo_tuanvu/Framework-N/MixFashion/themes/leo_mixfashion/assets/fonts/'. $mldfont['file']); $fonts_url = sprintf( _PS_BASE_URL_SSL_.__PS_BASE_URI__.'themes/'._THEME_NAME_.'/assets/fonts/' . $mldfont['file']); $files = explode(',', $mldfont['file']); $content = ''; $content .= "@font-face {\n"; $content .= "font-family:'".$mldfont['font_family']."';\n"; $content .= "font-style:'".$mldfont['font_style']."';\n"; $content .= "font-weight:'".$mldfont['font_weight']."';\n"; $content .= "src:local('".$mldfont['font_family']."'),"; foreach ($files as $file_k => $file) { $content .= "\n" . "url(" . _PS_BASE_URL_SSL_.__PS_BASE_URI__.'themes/'._THEME_NAME_.'/assets/fonts/' .$file.") format('".explode('.', $file)[count(explode('.', $file)) - 1]."')"; $content .= ($file_k == count($files) - 1) ? ';' : ','; } $content .= "}\n"; // echo ''; // phpcs:ignore // $mldfont $this->theme_dir = \leoECHelper::getConfigDir('_PS_THEME_DIR_'); $this->theme_dir = _PS_THEME_DIR_; $this->module_name = 'leoelements'; $this->profile_css_folder = $this->theme_dir.'modules/leoelements/views/css/'; \LeoECSetting::writeFile($this->profile_css_folder, $GLOBALS['leoelements']['parse_post_css_code'].'.css', $content); // echo ''; // $uri = \leoECHelper::getCssDir().'profiles/'.$GLOBALS['leoelements']['parse_post_css_code'].'.css'; // echo '' . "\n"; // var_dump($uri); // echo '' . "\n"; // die(); // if ((file_exists(_PS_THEME_DIR_.$uri) && filesize(_PS_THEME_DIR_.$uri)) || (file_exists(_PS_THEME_DIR_.'assets/css/'.$uri) && filesize(_PS_THEME_DIR_.'assets/css/'.$uri))) { // echo ''; // } $uri = 'modules/leoelements/views/css/'.$GLOBALS['leoelements']['parse_post_css_code'].'.css'; if (file_exists(_PS_THEME_DIR_.$uri)) { $fonts_url = sprintf( _PS_BASE_URL_SSL_.__PS_BASE_URI__.'themes/'._THEME_NAME_.'/' . $uri); echo ''; } // echo ''; // echo " //"; } } } if ( ! empty( $google_fonts['early'] ) ) { foreach ( $google_fonts['early'] as $current_font ) { $google_fonts_index++; //printf( '', strtolower( str_replace( ' ', '', $current_font ) ) ); $font_url = sprintf( 'https://fonts.googleapis.com/earlyaccess/%s.css', strtolower( str_replace( ' ', '', $current_font ) ) ); Leo_Helper::wp_enqueue_style( 'google-earlyaccess-' . $google_fonts_index, $font_url ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion } } } // private function enqueue_upload_fonts( $google_fonts = [] ) { // static $google_fonts_index = 0; // // $print_google_fonts = true; // // /** // * Print frontend google fonts. // * // * Filters whether to enqueue Google fonts in the frontend. // * // * @since 1.0.0 // * // * @param bool $print_google_fonts Whether to enqueue Google fonts. Default is true. // */ // $print_google_fonts = Leo_Helper::apply_filters( 'elementor/frontend/print_google_fonts', $print_google_fonts ); // // if ( ! $print_google_fonts ) { // return; // } // // // Print used fonts // if ( ! empty( $google_fonts['google'] ) ) { // $google_fonts_index++; // // foreach ( $google_fonts['google'] as &$font ) { // $font = str_replace( ' ', '+', $font ) . ':100,100italic,200,200italic,300,300italic,400,400italic,500,500italic,600,600italic,700,700italic,800,800italic,900,900italic'; // } // // $fonts_url = sprintf( 'https://fonts.googleapis.com/css?family=%s', implode( rawurlencode( '|' ), $google_fonts['google'] ) ); // // $subsets = [ // 'ru_RU' => 'cyrillic', // 'bg_BG' => 'cyrillic', // 'he_IL' => 'hebrew', // 'el' => 'greek', // 'vi' => 'vietnamese', // 'uk' => 'cyrillic', // 'cs_CZ' => 'latin-ext', // 'ro_RO' => 'latin-ext', // 'pl_PL' => 'latin-ext', // ]; // // $locale= \Context::getContext()->language->iso_code; // // if ( isset( $subsets[ $locale ] ) ) { // $fonts_url .= '&subset=' . $subsets[ $locale ]; // } // // echo ''; // phpcs:ignore // } // // if ( ! empty( $google_fonts['early'] ) ) { // foreach ( $google_fonts['early'] as $current_font ) { // $google_fonts_index++; // // //printf( '', strtolower( str_replace( ' ', '', $current_font ) ) ); // // $font_url = sprintf( 'https://fonts.googleapis.com/earlyaccess/%s.css', strtolower( str_replace( ' ', '', $current_font ) ) ); // // Leo_Helper::wp_enqueue_style( 'google-earlyaccess-' . $google_fonts_index, $font_url ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion // } // } // // } /** * Enqueue fonts. * * Enqueue all the frontend fonts. * * @since 1.2.0 * @access public * * @param array $font Fonts to enqueue in the frontend. */ public function enqueue_font( $font ) { if ( in_array( $font, $this->registered_fonts ) ) { return; } $this->fonts_to_enqueue[] = $font; $this->registered_fonts[] = $font; $this->print_fonts_links(); } /** * Parse global CSS. * * Enqueue the global CSS file. * * @since 1.2.0 * @access protected */ public function parse_global_css_code() { $scheme_css_file = Global_CSS::create( 'global.css' ); ob_start(); $scheme_css_file->enqueue(); return ob_get_clean(); } /** * Parse global CSS. * * Enqueue the global CSS file. * * @since 1.2.0 * @access protected */ public function parse_post_css_code( $id_post ) { $GLOBALS['leoelements']['parse_post_css_code'] = $id_post; $css_file = Post_CSS::create( $id_post ); ob_start(); if( \Tools::getValue( 'wp_preview' ) == Leo_Helper::$id_post ){ $css_file->print_css(); }else{ $css_file->enqueue(); } return ob_get_clean(); } /** * Apply builder in content. * * Used to apply the Elementor page editor on the post content. * * @since 1.0.0 * @access public * * @param string $content The post content. * * @return string The post content. */ public function apply_builder_in_content( $content ) { $this->restore_content_filters(); if ( Plugin::$instance->preview->is_preview_mode() || $this->_is_excerpt ) { return $content; } // Remove the filter itself in order to allow other `the_content` in the elements $this->remove_content_filter(); $post_id = Leo_Helper::get_the_ID(); $builder_content = $this->get_builder_content( $post_id ); if ( ! empty( $builder_content ) ) { $content = $builder_content; $this->remove_content_filters(); } // Add the filter again for other `the_content` calls $this->add_content_filter(); return $content; } /** * Retrieve builder content. * * Used to render and return the post content with all the Elementor elements. * * Note that this method is an internal method, please use `get_builder_content_for_display()`. * * @since 1.0.0 * @access public * * @param int $post_id The post ID. * @param bool $with_css Optional. Whether to retrieve the content with CSS * or not. Default is false. * * @return string The post content. */ public function get_builder_content( $post_id, $with_css = false ) { $document = Plugin::$instance->documents->get_doc_for_frontend( $post_id ); $data = $document->get_elements_data(); /** * Frontend builder content data. * * Filters the builder content in the frontend. * * @since 1.0.0 * * @param array $data The builder content. * @param int $post_id The post ID. */ $data = Leo_Helper::apply_filters( 'elementor/frontend/builder_content_data', $data, $post_id ); ob_start(); if ( $with_css ) { $css_file = Post_CSS::create( $post_id ); $css_file->print_css(); } $document->print_elements_with_wrapper( $data ); $content = ob_get_clean(); /** * Frontend content. * * Filters the content in the frontend. * * @since 1.0.0 * * @param string $content The content. */ $content = Leo_Helper::apply_filters( 'elementor/frontend/the_content', $content ); return $content; } /** * Add Elementor menu to admin bar. * * Add new admin bar item only on singular pages, to display a link that * allows the user to edit with Elementor. * * Fired by `admin_bar_menu` action. * * @since 1.3.4 * @access public * * @param \WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference. */ public function add_menu_in_admin_bar( \WP_Admin_Bar $wp_admin_bar ) { if ( empty( $this->admin_bar_edit_documents ) ) { return; } $queried_object_id = get_queried_object_id(); $menu_args = [ 'id' => 'elementor_edit_page', 'title' => Leo_Helper::__( 'Edit with Elementor', 'elementor' ), ]; if ( Leo_Helper::is_singular() && isset( $this->admin_bar_edit_documents[ $queried_object_id ] ) ) { $menu_args['href'] = $this->admin_bar_edit_documents[ $queried_object_id ]->get_edit_url(); unset( $this->admin_bar_edit_documents[ $queried_object_id ] ); } $wp_admin_bar->add_node( $menu_args ); foreach ( $this->admin_bar_edit_documents as $document ) { $wp_admin_bar->add_menu( [ 'id' => 'elementor_edit_doc_' . $document->get_main_id(), 'parent' => 'elementor_edit_page', 'title' => sprintf( '%s%s', $document->get_post()->post_title, $document::get_title() ), 'href' => $document->get_edit_url(), ] ); } } /** * Retrieve builder content for display. * * Used to render and return the post content with all the Elementor elements. * * @since 1.0.0 * @access public * * @param int $post_id The post ID. * * @param bool $with_css Optional. Whether to retrieve the content with CSS * or not. Default is false. * * @return string The post content. */ public function get_builder_content_for_display( $post_id, $with_css = false ) { if ( ! get_post( $post_id ) ) { return ''; } $editor = Plugin::$instance->editor; // Avoid recursion if ( Leo_Helper::get_the_ID() === (int) $post_id ) { $content = ''; if ( $editor->is_edit_mode() ) { $content = '