Upgarded to 4.17.4

This commit is contained in:
2022-06-23 13:17:18 +01:00
parent 80f1e87db9
commit a04fb0c7af
404 changed files with 54683 additions and 4417 deletions

View File

@ -0,0 +1,388 @@
<?php
/**
* Block Templates Compatibility.
*
* @package Builder
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Block Templates Compatibility Class.
*
* @since 4.9.8
*/
class ET_Builder_Block_Templates {
/**
* Instance of `ET_Builder_Block_Templates`.
*
* @var ET_Builder_Block_Templates
*/
private static $_instance;
/**
* ET_Builder_Block_Templates constructor.
*/
public function __construct() {
$this->init_hooks();
}
/**
* Get the class instance.
*
* @since 4.9.8
*
* @return ET_Builder_Block_Templates
*/
public static function instance() {
if ( ! self::$_instance ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Initialize some hooks to support compatibility with block templates.
*
* @since 4.14.7
*/
public function init_hooks() {
// Bail early if block templates compatibility is not needed.
if ( ! self::is_block_templates_compat_needed() ) {
return;
}
// Filters block template loeaders.
add_action( 'wp_loaded', array( 'ET_Builder_Block_Templates', 'filter_template_loaders' ) );
// WooCommerce compatibility for themes that support FSE.
add_action( 'template_redirect', array( 'ET_Builder_Block_Templates', 'remove_unsupported_theme_filter' ), 12 );
}
/**
* Filter specific template loaders to use theme template files if any instead of
* 'wp_template' posts.
*
* @since ??
*/
public static function filter_template_loaders() {
$template_slugs = self::get_supported_template_slugs();
foreach ( $template_slugs as $template_slug ) {
$template_name = str_replace( '-', '', $template_slug );
$template_filter = $template_name . '_template';
add_filter( $template_filter, array( 'ET_Builder_Block_Templates', 'override_block_template' ), 30, 3 );
}
}
/**
* Maybe override block templates.
*
* This action should be executed only when:
* - TB Template is active on current page
* - Current template is block template canvas
*
* @since 4.14.7
*
* @param string $template Current template path.
*/
public static function override_block_template( $template = '', $type = '', $templates = array() ) {
// Bail early if there is no TB templates for current page request.
if ( empty( et_theme_builder_get_template_layouts() ) ) {
return $template;
}
$override_header = et_theme_builder_overrides_layout( ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE );
$override_body = et_theme_builder_overrides_layout( ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE );
$override_footer = et_theme_builder_overrides_layout( ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE );
// Bail early if TB doesn't override any layouts.
if ( ! $override_header && ! $override_body && ! $override_footer ) {
return $template;
}
// Bail early if current template is not `template-canvas.php`.
if ( 'template-canvas.php' !== basename( $template ) ) {
return $template;
}
// 1. Override the template canvas with PHP template.
// Use `locate_template` to get the PHP template. If the template doesn't exist, use
// default builder block template canvas as replacement.
$canvas_template = ET_BUILDER_DIR . 'templates/block-template-canvas.php';
$old_template = $template;
$new_template = locate_template( $templates );
$template = file_exists( $new_template ) ? $new_template : $canvas_template;
// 2. Add needed actions and remove default template canvas actions.
// Remove viewport meta tag.
if ( function_exists( '_block_template_viewport_meta_tag' ) ) {
remove_action( 'wp_head', '_block_template_viewport_meta_tag', 0 );
}
// Render conditional title tag for `title-tag` support.
add_action( 'wp_head', '_wp_render_title_tag', 1 );
// Remove unconditional title tag.
if ( function_exists( '_block_template_render_title_tag' ) ) {
remove_action( 'wp_head', '_block_template_render_title_tag', 1 );
}
// 3. Enqueue block templates compatibility fixes.
// Those fixes are related to missing header and footer PHP templates.
if ( $canvas_template === $template ) {
// Add opening and closing wrappers for builder block template canvas because
// there is no specific wrappers found when a page use block template canvas.
add_action( 'et_theme_builder_template_after_header', array( 'ET_Builder_Block_Templates', 'main_content_opening_wrapper' ) );
add_action( 'et_theme_builder_template_before_footer', array( 'ET_Builder_Block_Templates', 'main_content_closing_wrapper' ) );
// Add styles to fix the body layout on additional wrappers added above.
add_action( 'wp_enqueue_scripts', array( 'ET_Builder_Block_Templates', 'block_template_styles' ) );
// Disable deperecated warnings on missing files.
add_action( 'deprecated_file_included', array( 'ET_Builder_Block_Templates', 'disable_deprecated_file_warnings' ) );
}
/**
* Fires additional actions after builder override block template.
*
* @since 4.14.7
*
* @param string $template New processed block template.
* @param string $old_template Original block template.
*/
do_action( 'et_after_override_block_template', $template, $old_template );
return $template;
}
/**
* Set main content opening wrapper.
*
* Provide the opening wrapper tags only to ensure TB layout works smoothly. The same
* wrapper is being used on Divi theme.
*
* @since 4.14.7
*/
public static function main_content_opening_wrapper() {
// Bail early if DBP is inactive because the issue doesn't happen on Divi/Extra.
if ( ! et_is_builder_plugin_active() ) {
return;
}
// By default, content class is `builder-content`. This class has no style at all
// because it's controlled by the builder itself. This class can be useful as an
// indicator and selector for the content built with builder.
$content_class = 'builder-content';
// When current page is singular page, check builder and divi/layout block usage.
if ( is_singular() ) {
$post_id = get_the_ID();
$is_page_builder_used = et_pb_is_pagebuilder_used( $post_id );
// The `block-content wp-site-blocks` classes will added on current page when:
// - Builder is not used.
// - Builder is used but it's coming from Divi Layout block.
// The `block-content` class has style to reset content width. The `wp-site-blocks`
// class is needed to mimic default block content styles.
if ( ! $is_page_builder_used || ( $is_page_builder_used && has_block( 'divi/layout', $post_id ) ) ) {
$content_class = 'block-content wp-site-blocks';
}
}
?>
<div id="et-main-area">
<div id="main-content" class="<?php echo esc_attr( $content_class ); ?>">
<?php
}
/**
* Set main content closing wrapper.
*
* Provide the closing wrapper tag only to ensure TB layout works smoothly. The same
* wrapper is being used on Divi theme.
*
* @since 4.14.7
*/
public static function main_content_closing_wrapper() {
// Bail early if DBP is inactive because the issue doesn't happen on Divi/Extra.
if ( ! et_is_builder_plugin_active() ) {
return;
}
?>
</div><!-- #main-content -->
</div><!-- #et-main-area -->
<?php
}
/**
* Enqueue block templates compatibility styles.
*
* @since 4.14.7
*/
public static function block_template_styles() {
// Bail early if DBP is inactive because the issue doesn't happen on Divi/Extra.
if ( ! et_is_builder_plugin_active() ) {
return;
}
wp_enqueue_style( 'et-block-templates-styles', ET_BUILDER_URI . '/styles/block_templates.css', array(), ET_BUILDER_PRODUCT_VERSION );
}
/**
* Disable deprecated files warnings.
*
* Since themes that support block template may don't have some files, the template
* may fall into backward compatibility for those files and trigger warnings. Hence,
* we need to disable them temporarily. The list of files:
* - header
* - footer
* - comments
*
* @since 4.14.7
*
* @param string $file File info.
*/
public static function disable_deprecated_file_warnings( $file ) {
// Bail early if DBP is inactive because the issue doesn't happen on Divi/Extra.
if ( ! et_is_builder_plugin_active() ) {
return;
}
if ( strpos( $file, 'header.php' ) || strpos( $file, 'footer.php' ) || strpos( $file, 'comments.php' ) ) {
add_filter( 'deprecated_file_trigger_error', '__return_false' );
} else {
add_filter( 'deprecated_file_trigger_error', '__return_true' );
}
}
/**
* Remove unsupported theme filters for WooCommerce.
*
* When current theme supports FSE, WooCommerce will mark it as unsupported theme and
* overrides some filters and few of them are related to builder. Hence, we need to
* remove those filters to ensure Divi Builder works normally.
*
* @since 4.14.7
*/
public static function remove_unsupported_theme_filter() {
// Bail early if WooCommerce is not active or current theme is not block theme.
if ( ! et_is_woocommerce_plugin_active() || ! et_builder_is_block_theme() ) {
return;
}
// Single Product.
if ( is_product() ) {
global $post;
$post_id = $post ? $post->ID : 0;
// Only remove those filters when current product uses builder.
if ( et_pb_is_pagebuilder_used( $post_id ) ) {
remove_filter( 'the_content', array( 'WC_Template_Loader', 'unsupported_theme_product_content_filter' ), 10 );
remove_filter( 'woocommerce_product_tabs', array( 'WC_Template_Loader', 'unsupported_theme_remove_review_tab' ), 10 );
}
}
}
/**
* Determine whether block templates compatibility support is needed or not.
*
* Support block templates compatibility only if:
* - Current WordPress or Gutenberg supports block templates
* - Current theme supports block templates
*
* @since ??
*
* @return boolean Compatibility status.
*/
public static function is_block_templates_compat_needed() {
// Bail early if `locate_block_template` function doesn't exists (WP 5.8 above).
if ( ! function_exists( 'locate_block_template' ) ) {
return false;
}
// Whether current theme supports block templates or block theme.
$is_theme_supports_block_templates = current_theme_supports( 'block-templates' );
$is_block_theme = et_builder_is_block_theme();
$is_block_templates_compat_needed = $is_theme_supports_block_templates || $is_block_theme;
/**
* Filters the result of the block templates compatibility check.
*
* @since ??
*
* @param boolean $is_block_templates_compat_needed Compatibility status.
*/
return (bool) apply_filters( 'et_builder_is_block_templates_compat_needed', $is_block_templates_compat_needed );
}
/**
* Get supported template slugs.
*
* Those template slugs are available on TB.
*
* @since ??
*
* @return string[] List of supported template slugs.
*/
public static function get_supported_template_slugs() {
/**
* List of possible hook names:
* - `404_template`
* - `archive_template`
* - `author_template`
* - `category_template`
* - `date_template`
* - `frontpage_template`
* - `home_template`
* - `index_template`
* - `page_template`
* - `privacypolicy_template`
* - `search_template`
* - `single_template`
* - `singular_template`
* - `tag_template`
* - `taxonomy_template`
*
* Don't include `attachment`, `embed`, `paged` because they aren't modified on TB.
*/
$default_template_slugs = array(
'index',
'home',
'front-page',
'singular',
'single',
'page',
'archive',
'author',
'category',
'taxonomy',
'date',
'tag',
'search',
'privacy-policy',
'404',
);
$template_slugs = $default_template_slugs;
// Use `get_default_block_template_types` result if it exists.
if ( function_exists( 'get_default_block_template_types' ) ) {
$template_types = (array) get_default_block_template_types();
if ( isset( $template_types['attachment'] ) ) {
unset( $template_types['attachment'] );
}
$template_slugs = ! empty( $template_types ) ? array_keys( $template_types ) : $default_template_types;
}
return $template_slugs;
}
}
ET_Builder_Block_Templates::instance();

View File

@ -202,33 +202,10 @@ class ET_GB_Editor_Typography {
);
}
$body_font_color = esc_html( et_get_option( 'font_color' ) );
if ( ! empty( $body_font_color ) ) {
$body_styles .= et_builder_generate_css_style(
array(
'style' => 'color',
'value' => $body_font_color,
)
);
}
if ( ! empty( $body_styles ) ) {
$body_styles = sprintf( 'body { %1$s }', $body_styles );
}
$link_color = esc_html( et_get_option( 'link_color' ) );
if ( ! empty( $link_color ) ) {
$body_styles .= et_builder_generate_css(
array(
'style' => 'color',
'value' => $link_color,
'selector' => 'a',
)
);
}
return $body_styles;
}
@ -270,17 +247,6 @@ class ET_GB_Editor_Typography {
);
}
$header_color = esc_html( et_get_option( 'header_color' ) );
if ( ! empty( $header_color ) ) {
$title_styles .= et_builder_generate_css_style(
array(
'style' => 'color',
'value' => $header_color,
)
);
}
$body_header_height = esc_html( et_get_option( 'body_header_height' ) );
if ( ! empty( $body_header_height ) && '1' !== $body_header_height ) {
@ -353,11 +319,13 @@ class ET_GB_Editor_Typography {
// Get style generated by modules.
$tb_style = ET_Builder_Element::get_style();
$have_post_content_style = preg_match( '/\.et_pb_post_content_0 { (.*) }/', $tb_style, $matches );
// Remove `color` property from theme builder style.
$tb_style = preg_replace( '/(?<=[{;\s])color:.*?;/s', '', $tb_style );
$have_post_content_style = preg_match( '/\.et_pb_post_content_0\s*{\s*(.*?)\s*}/s', $tb_style, $matches );
if ( $have_post_content_style && isset( $matches[1] ) ) {
$et_pb_post_content_styles = explode( ';', $matches[1] );
$typography_properties = array(
'color',
'font-family',
'font-size',
'font-weight',
@ -375,9 +343,9 @@ class ET_GB_Editor_Typography {
foreach ( $et_pb_post_content_styles as $et_pb_post_content_style ) {
$style = explode( ':', $et_pb_post_content_style ); // explode CSS property and value.
$css_property = trim( et_()->array_get( $style, '0' ) );
$css_property = trim( $style[0] );
if ( in_array( $css_property, $typography_properties, true ) ) {
$post_content_style .= $css_property . ':' . et_()->array_get( $style, '1' ) . ';';
$post_content_style .= $css_property . ':' . $style[1] . ';';
}
}

View File

@ -77,7 +77,6 @@ class ET_GB_Block_Layout {
// Block rendering on frontend
add_filter( 'render_block', array( $this, 'render_block' ), 100, 2 );
add_filter( 'get_the_excerpt', array( $this, 'get_the_post_excerpt' ) );
}
/**
@ -164,137 +163,104 @@ class ET_GB_Block_Layout {
}
/**
* Filter rendered blocks on FE.
* Filter rendered Divi - Layout block on FE.
*
* @since 4.1.0
* @since 4.10.0 Filter core/post-excerpt rendered output.
* @since 4.14.5 Move other blocks. {@see feature/gutenberg/blocks}.
* @since 4.14.8 Add support for WP Editor.
*
* @param string $block_content Saved & serialized block data.
* @param array $block Block info.
*/
public function render_block( $block_content, $block ) {
// Core - Post Excerpt block.
if ( 'core/post-excerpt' === $block['blockName'] ) {
return $this->get_rendered_post_excerpt( $block_content, true );
}
// Divi - Layout block.
if ( 'divi/layout' === $block['blockName'] ) {
global $et_is_layout_block;
// Set flag.
$et_is_layout_block = true;
// Render block content's shortcode. Block content actually can be rendered without this
// method and only depending to WordPress' `do_shortcode` hooked into `the_content`. However
// layout block need to set global for detecting that shortcode is rendered inside layout
// block hence the early shortcode rendering between global variables.
$block_content = do_shortcode( $block_content );
// Reset flag.
$et_is_layout_block = false;
if ( 'divi/layout' !== $block['blockName'] ) {
return $block_content;
}
return $block_content;
}
global $et_is_layout_block, $et_layout_block_info;
/**
* Filter post excerpt of REST API request.
*
* @since 4.9.10
* @since 4.10.0 Only filter post excerpt rendered from REST API request. This API request
* is being used by Block Editor.
*
* @param string $post_excerpt Current post excerpt rendered.
*
* @return string Modified post excerpt.
*/
public function get_the_post_excerpt( $post_excerpt ) {
// Bail early if current request is not REST API request.
if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) {
return $post_excerpt;
// Get WP Editor template data to determine whether current Divi Layout block is
// rendered inside WP Editor template or not.
$template = $this->get_wp_editor_template_on_render();
$template_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0;
$block_to_render = class_exists( 'WP_Block_Supports' ) && ! empty( WP_Block_Supports::$block_to_render ) ? WP_Block_Supports::$block_to_render : array();
// Set flag.
$et_is_layout_block = true;
$et_layout_block_info = array(
'block' => $block,
'block_to_render' => $block_to_render,
'template' => $template,
);
// Start - Divi Layout block inside WP Editor Template or Template Part.
if ( ! empty( $template ) && $template_id > 0 ) {
ET_Builder_Element::begin_wp_editor_template( $template_id );
}
return $this->get_rendered_post_excerpt( $post_excerpt );
}
// Render - Divi Layout block inside Post Content/Template/Template Part.
// Render block content's shortcode. Block content actually can be rendered without this
// method and only depending to WordPress' `do_shortcode` hooked into `the_content`. However
// layout block need to set global for detecting that shortcode is rendered inside layout
// block hence the early shortcode rendering between global variables.
$block_content = do_shortcode( $block_content );
/**
* Get rendered post excerpt built with builder. Always return rendered $post_excerpt
* because it's already wrapped with Post Excerpt block wrapper.
*
* @since 4.10.0
*
* @param string $post_excerpt Current rendered post excerpt.
* @param boolean $is_wrapped Whether the post excerpt is wrapped or not.
*
* @return string Old or new rendered post excerpt.
*/
public function get_rendered_post_excerpt( $post_excerpt, $is_wrapped = false ) {
// Bail early if no global post. Need to get the post here due to some issues with
// 3rd party plugins regarding missing 2nd arg on the `get_the_excerpt` filter.
$post = get_post();
if ( empty( $post ) ) {
return $post_excerpt;
}
// End - Divi Layout block inside WP Editor Template or Template Part.
if ( ! empty( $template ) && $template_id > 0 ) {
// 1. Append builder layout and content wrappers.
$block_content = et_builder_get_layout_opening_wrapper() . $block_content . et_builder_get_layout_closing_wrapper();
if ( ! empty( $post->post_excerpt ) ) {
return $post_excerpt;
}
/** This filter is documented in core.php */
$wrap = apply_filters( 'et_builder_add_outer_content_wrap', true );
// Bail early if Builder framework is not loaded. There are some cases where 3rd
// party plugins run scan without visiting theme functions file.
if ( ! function_exists( 'et_builder_load_framework' ) ) {
return $post_excerpt;
}
if ( ! et_pb_is_pagebuilder_used( $post->ID ) ) {
return $post_excerpt;
}
static $et_rendered_post_excerpt = array();
// Bail early if current post is already processed.
if ( isset( $et_rendered_post_excerpt[ $post->ID ] ) ) {
return $et_rendered_post_excerpt[ $post->ID ];
}
// 1. Ensure all the ET shortcode are registered.
if ( ! did_action( 'et_builder_ready' ) ) {
// When the `get_the_excerpt` filter is called by Query Loop block on the FE,
// the `ET_Builder_Element` class is loaded properly but no ET shortcode is
// registered yet. In this case, we can call `et_builder_init_global_settings`
// & `et_builder_add_main_elements` methods directly. However, this class is not
// loaded on the Block Editor, so we have to load all related files manually
// before we can call those methods to register the shortcode.
if ( ! class_exists( 'ET_Builder_Element' ) ) {
require_once ET_BUILDER_DIR . 'class-et-builder-value.php';
require_once ET_BUILDER_DIR . 'class-et-builder-element.php';
require_once ET_BUILDER_DIR . 'ab-testing.php';
if ( $wrap ) {
$block_content = et_builder_get_builder_content_opening_wrapper() . $block_content . et_builder_get_builder_content_closing_wrapper();
}
et_builder_init_global_settings();
et_builder_add_main_elements();
et_builder_settings_init();
// 2. Pass styles to page resource which will handle their output.
$post_id = is_singular() ? ET_Post_Stack::get_main_post_id() : $template_id;
$result = ET_Builder_Element::setup_advanced_styles_manager( $post_id );
$advanced_styles_manager = $result['manager'];
if ( isset( $result['deferred'] ) ) {
$deferred_styles_manager = $result['deferred'];
}
if ( ET_Builder_Element::$forced_inline_styles || ! $advanced_styles_manager->has_file() || $advanced_styles_manager->forced_inline ) {
/** This filter is documented in frontend-builder/theme-builder/frontend.php */
$is_critical_enabled = apply_filters( 'et_builder_critical_css_enabled', false );
$critical = $is_critical_enabled ? ET_Builder_Element::get_style( false, $template_id, true ) . ET_Builder_Element::get_style( true, $template_id, true ) : array();
$styles = ET_Builder_Element::get_style( false, $template_id ) . ET_Builder_Element::get_style( true, $template_id );
if ( empty( $critical ) ) {
// No critical styles defined, just enqueue everything as usual.
if ( ! empty( $styles ) ) {
if ( isset( $deferred_styles_manager ) ) {
$deferred_styles_manager->set_data( $styles, 40 );
} else {
$advanced_styles_manager->set_data( $styles, 40 );
}
}
} else {
$advanced_styles_manager->set_data( $critical, 40 );
if ( ! empty( $styles ) ) {
// Defer everything else.
$deferred_styles_manager->set_data( $styles, 40 );
}
}
}
ET_Builder_Element::end_wp_editor_template();
}
// 2. Generate Builder post excerpt.
// WordPress post excerpt length comes from `excerpt_length` filter. And, it's
// words based length, not characters based length.
$excerpt_length = apply_filters( 'excerpt_length', 55 );
$new_post_excerpt = et_core_intentionally_unescaped( wpautop( et_delete_post_first_video( truncate_post( $excerpt_length, false, $post, true, true ) ) ), 'html' );
// Reset flag.
$et_is_layout_block = false;
$et_layout_block_info = false;
// 3. Ensure to return the block wrapper if the $post_excerpt is already wrapped.
if ( $is_wrapped ) {
$wrapper = '/(<p class="wp-block-post-excerpt__excerpt">)(.*?)(<a|<\/p>)/';
$new_post_excerpt = wp_strip_all_tags( $new_post_excerpt );
$new_post_excerpt = preg_replace( $wrapper, "$1{$new_post_excerpt}$3", $post_excerpt );
}
$et_rendered_post_excerpt[ $post->ID ] = $new_post_excerpt;
return $new_post_excerpt;
return $block_content;
}
/**
@ -664,6 +630,105 @@ class ET_GB_Block_Layout {
[/et_pb_row]
[/et_pb_section]';
}
/**
* Get current active WP Editor template on block render.
*
* @since 4.14.8
*
* @return WP_Block_Template|null Template. Return null if it doesn't exist.
*/
public function get_wp_editor_template_on_render() {
global $post;
static $templates_result = null;
// Bail early if `get_block_template` function doesn't exist because we need it to
// get template data. This function is introduced on WP 5.8 along with Template and
// Template Parts editors.
if ( ! function_exists( 'get_block_template' ) ) {
return null;
}
// Bail early if current post is not singular.
if ( ! is_singular() ) {
return null;
}
// Bail early if TB override current layouts.
if ( ! empty( et_theme_builder_get_template_layouts() ) ) {
$override_header = et_theme_builder_overrides_layout( ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE );
$override_body = et_theme_builder_overrides_layout( ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE );
$override_footer = et_theme_builder_overrides_layout( ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE );
if ( $override_header || $override_body || $override_footer ) {
return null;
}
}
// Get WP Editor template data to determine whether current Divi Layout block is
// rendered inside WP Editor template or not.
$block_to_render = class_exists( 'WP_Block_Supports' ) && ! empty( WP_Block_Supports::$block_to_render ) ? WP_Block_Supports::$block_to_render : array();
$block_to_render_name = et_()->array_get( $block_to_render, 'blockName', '' );
// Bail early if block to render name is post content. Divi Layout block inside post
// content will be rendered normally.
if ( 'core/post-content' === $block_to_render_name ) {
return null;
}
// 1. Generate template type and slug.
$template_type = '';
$template_slug = '';
if ( 'core/template-part' === $block_to_render_name ) {
$template_type = ET_WP_EDITOR_TEMPLATE_PART_POST_TYPE;
$template_slug = et_()->array_get( $block_to_render, array( 'attrs', 'slug' ), '' );
} else {
$template_type = ET_WP_EDITOR_TEMPLATE_POST_TYPE;
$template_slug = ! empty( $post->page_template ) ? $post->page_template : $this->get_default_template_slug();
}
$template_type_slug = "{$template_type}-{$template_slug}";
// Bail early if current template type + slug is already processed.
if ( ! empty( $templates_result[ $template_type_slug ] ) ) {
return $templates_result[ $template_type_slug ];
}
// 2. Get block template data based on post slug and post type.
$template = ! empty( $template_type ) && ! empty( $template_slug ) ? get_block_template( get_stylesheet() . '//' . $template_slug, $template_type ) : null;
// 3. Save the result to be used later.
$templates_result[ $template_type_slug ] = $template;
return $template;
}
/**
* Get default template slug.
*
* @since 4.14.8
*
* @return string Template type.
*/
public function get_default_template_slug() {
// Bail early if current page isn't singular. At this moment, Divi Layout block only
// support singular page. Once we solved Divi Layout block issue on Site Editor, the
// template type check below will be updated.
if ( ! is_singular() ) {
return '';
}
// At this moment, only single.html and page.html are editable.
if ( is_page() ) {
return 'page';
} elseif ( is_single() ) {
return 'single';
}
return '';
}
}
// Initialize ET_GB_Block_Layout

View File

@ -0,0 +1,201 @@
<?php
/**
* ET_GB_Block_Post_Excerpt class file.
*
* @class ET_GB_Block_Post_Excerpt
* @package Builder
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class to handle Core - Post Excerpt block integration.
*/
class ET_GB_Block_Post_Excerpt {
/**
* Class instance.
*
* @var ET_GB_Block_Post_Excerpt
*/
private static $_instance;
/**
* Class constructor.
*/
public function __construct() {
if ( ! et_core_is_gutenberg_active() ) {
return;
}
$this->register_hooks();
}
/**
* Get class instance.
*
* @since 4.14.5
*
* @return ET_GB_Block_Post_Excerpt Class instance.
*/
public static function instance() {
if ( null === self::$_instance ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Register hooks
*
* @since 4.14.5
*/
public function register_hooks() {
add_filter( 'render_block_core/post-excerpt', array( $this, 'render_block' ), 10, 2 );
add_filter( 'get_the_excerpt', array( $this, 'get_the_post_excerpt' ) );
}
/**
* Filter rendered Core - Post Excerpt block on FE.
*
* @since 4.14.5
*
* @param string $block_content Saved & serialized block data.
* @param array $parsed_block Block info.
*
* @return string Modified block post excerpt.
*/
public function render_block( $block_content, $parsed_block ) {
$attributes = ! empty( $parsed_block['attrs'] ) ? $parsed_block['attrs'] : array();
return $this->get_rendered_post_excerpt( $block_content, true, $attributes );
}
/**
* Filter post excerpt of REST API request.
*
* Only filter post excerpt rendered from REST API request. This API request is being
* used by Block Editor.
*
* @since 4.14.5
*
* @param string $post_excerpt Current post excerpt rendered.
*
* @return string Modified post excerpt.
*/
public function get_the_post_excerpt( $post_excerpt ) {
// Bail early if current request is not REST API request.
if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) {
return $post_excerpt;
}
return $this->get_rendered_post_excerpt( $post_excerpt );
}
/**
* Get rendered post excerpt built with builder. Always return rendered $block_excerpt
* because it's already wrapped with Post Excerpt block wrapper.
*
* @since 4.14.5
*
* @param string $block_excerpt Current rendered post excerpt.
* @param boolean $is_wrapped Whether the post excerpt is wrapped or not.
* @param array $attributes Block attributes values.
*
* @return string Old or new rendered post excerpt.
*/
public function get_rendered_post_excerpt( $block_excerpt, $is_wrapped = false, $attributes = array() ) {
// Bail early if no global post. Need to get the post here due to some issues with
// 3rd party plugins regarding missing 2nd arg on the `get_the_excerpt` filter.
$post_id = ! empty( $attributes['postId'] ) ? (int) $attributes['postId'] : 0;
$post = $post_id ? get_post( $post_id ) : get_post();
if ( empty( $post ) ) {
return $block_excerpt;
}
if ( ! empty( $post->post_excerpt ) ) {
return $block_excerpt;
}
// Bail early if Builder framework is not loaded. There are some cases where 3rd
// party plugins run scan without visiting theme functions file.
if ( ! function_exists( 'et_builder_load_framework' ) ) {
return $block_excerpt;
}
if ( ! et_pb_is_pagebuilder_used( $post->ID ) ) {
return $block_excerpt;
}
static $et_rendered_post_excerpt = array();
// Bail early if current post is already processed.
if ( isset( $et_rendered_post_excerpt[ $post->ID ] ) ) {
return $et_rendered_post_excerpt[ $post->ID ];
}
// 1. Ensure all the ET shortcode are registered.
if ( ! did_action( 'et_builder_ready' ) ) {
// When the `get_the_excerpt` filter is called by Query Loop block on the FE,
// the `ET_Builder_Element` class is loaded properly but no ET shortcode is
// registered yet. In this case, we can call `et_builder_init_global_settings`
// & `et_builder_add_main_elements` methods directly. However, this class is not
// loaded on the Block Editor, so we have to load all related files manually
// before we can call those methods to register the shortcode.
if ( ! class_exists( 'ET_Builder_Element' ) ) {
require_once ET_BUILDER_DIR . 'class-et-builder-value.php';
require_once ET_BUILDER_DIR . 'class-et-builder-element.php';
require_once ET_BUILDER_DIR . 'ab-testing.php';
}
et_builder_init_global_settings();
et_builder_add_main_elements();
et_builder_settings_init();
}
// 2. Generate Builder post excerpt.
// WordPress post excerpt length comes from `excerpt_length` filter. And, it's
// words based length, not characters based length.
$excerpt_length = apply_filters( 'excerpt_length', 55 );
$new_post_excerpt = et_core_intentionally_unescaped( wpautop( et_delete_post_first_video( truncate_post( $excerpt_length, false, $post, true, true ) ) ), 'html' );
// 3. Ensure to return the block wrapper if the $block_excerpt is already wrapped.
if ( $is_wrapped && ! empty( $new_post_excerpt ) ) {
$new_post_excerpt = wp_strip_all_tags( $new_post_excerpt );
// If generated block excerpt is not empty, we just need to replace the excerpt
// text with the new one. Otherwise, we have to rebuilt the block excerpt.
if ( ! empty( $block_excerpt ) ) {
$wrapper = '/(<p class="wp-block-post-excerpt__excerpt">)(.*?)(<a|<\/p>)/';
$new_post_excerpt = preg_replace( $wrapper, "$1{$new_post_excerpt}$3", $block_excerpt );
} else {
// 3.a. More Text.
$more_text = ! empty( $attributes['moreText'] ) ? '<a class="wp-block-post-excerpt__more-link" href="' . esc_url( get_the_permalink( $post->ID ) ) . '">' . esc_html( $attributes['moreText'] ) . '</a>' : '';
// 3.b. Text Align Class.
$classes = ! empty( $attributes['textAlign'] ) ? 'has-text-align-' . esc_attr( $attributes['textAlign'] ) : '';
$wrapper_attrs = get_block_wrapper_attributes( array( 'class' => $classes ) );
// 3.c. Post Excerpt Content.
$content = '<p class="wp-block-post-excerpt__excerpt">' . $new_post_excerpt;
$show_more_on_new_line = et_()->array_get( $attributes, 'showMoreOnNewLine', true );
if ( $show_more_on_new_line && ! empty( $more_text ) ) {
$content .= '</p><p class="wp-block-post-excerpt__more-text">' . $more_text . '</p>';
} else {
$content .= $more_text . '</p>';
}
$new_post_excerpt = sprintf( '<div %1$s>%2$s</div>', $wrapper_attrs, $content );
}
}
$et_rendered_post_excerpt[ $post->ID ] = $new_post_excerpt;
return $new_post_excerpt;
}
}
// Initialize ET_GB_Block_Post_Excerpt.
ET_GB_Block_Post_Excerpt::instance();

View File

@ -0,0 +1,198 @@
<?php
/**
* Helpers needed for the WP Editor compatibility.
*
* @package Divi
* @subpackage Builder
* @since 4.14.8
*/
if ( ! defined( 'ET_WP_EDITOR_TEMPLATE_POST_TYPE' ) ) {
define( 'ET_WP_EDITOR_TEMPLATE_POST_TYPE', 'wp_template' );
}
if ( ! defined( 'ET_WP_EDITOR_TEMPLATE_PART_POST_TYPE' ) ) {
define( 'ET_WP_EDITOR_TEMPLATE_PART_POST_TYPE', 'wp_template_part' );
}
if ( ! function_exists( 'et_builder_get_wp_editor_template_post_types' ) ) {
/**
* Get supported WP Editor template post types.
*
* At this moment, the list is:
* - wp_template
* - wp_template_part
*
* @since 4.14.8
*
* @return array List of supported WP Editor template post types.
*/
function et_builder_get_wp_editor_template_post_types() {
// Supported WP Editor template post types.
$post_types = array(
ET_WP_EDITOR_TEMPLATE_POST_TYPE,
ET_WP_EDITOR_TEMPLATE_PART_POST_TYPE,
);
return $post_types;
}
}
if ( ! function_exists( 'et_builder_is_wp_editor_template_post_type' ) ) {
/**
* Whether current post type is supported WP Editor template post type or not.
*
* @since 4.14.8
*
* @param string $type Template post type.
*
* @return boolean Post type check status.
*/
function et_builder_is_wp_editor_template_post_type( $type ) {
return in_array( $type, et_builder_get_wp_editor_template_post_types(), true );
}
}
if ( ! function_exists( 'et_builder_wp_editor_decorate_page_resource_slug' ) ) {
/**
* Decorate a page resource slug based on the current request and WP Editor.
*
* @since 4.14.8
*
* @param integer|string $post_id Post ID.
* @param string $resource_slug Resource slug.
*
* @return string
*/
function et_builder_wp_editor_decorate_page_resource_slug( $post_id, $resource_slug ) {
// Bail early if current page is not singular.
if ( ! is_numeric( $post_id ) || ! is_singular() ) {
return $resource_slug;
}
$templates = et_builder_get_wp_editor_templates();
// Bail early if current page doesn't have templates.
if ( empty( $templates ) ) {
return $resource_slug;
}
foreach ( $templates as $template ) {
// The `wpe` is stand for WP Editor.
$template_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0;
$resource_slug .= $template_id ? '-wpe-' . $template_id : '';
}
return $resource_slug;
}
}
if ( ! function_exists( 'et_builder_get_wp_editor_templates' ) ) {
/**
* Get WP Editor templates on current post.
*
* @since 4.14.8
*
* @return array List of templates and template parts.
*/
function et_builder_get_wp_editor_templates() {
static $templates = null;
// Bail early if the list is already processed.
if ( null !== $templates ) {
return $templates;
}
$templates = array();
// Bail early if `get_block_template` function doesn't exist because we need it to
// get template data. This function is introduced on WP 5.8 along with Template and
// Template Parts editors.
if ( ! function_exists( 'get_block_template' ) ) {
return $templates;
}
// Bail early if current page is not singular.
if ( ! is_singular() ) {
return $templates;
}
global $post;
// Bail early if current post doesn't have page template.
if ( empty( $post->page_template ) ) {
return $templates;
}
// A. Template.
// Get block template data based on post slug and post type.
$template = get_block_template( get_stylesheet() . '//' . $post->page_template, ET_WP_EDITOR_TEMPLATE_POST_TYPE );
// Bail early if the template is empty.
if ( empty( $template ) ) {
return $templates;
}
$template_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0;
$templates[ $template_id ] = $template;
// Parse and fetch blocks list in the template to find the template parts.
$blocks = parse_blocks( $template->content );
// Bail early if the blocks is empty.
if ( empty( $blocks ) ) {
return $templates;
}
foreach ( $blocks as $block ) {
$name = et_()->array_get( $block, 'blockName' );
$slug = et_()->array_get( $block, array( 'attrs', 'slug' ) );
// Skip if current block is not template part.
if ( 'core/template-part' !== $name || empty( $slug ) ) {
continue;
}
// B. Template Parts.
// Get block template part data based on post slug and post type.
$template_part = get_block_template( get_stylesheet() . '//' . $slug, ET_WP_EDITOR_TEMPLATE_PART_POST_TYPE );
// Skip if the template part is empty.
if ( empty( $template_part ) ) {
continue;
}
$template_part_id = isset( $template_part->wp_id ) ? (int) $template_part->wp_id : 0;
$templates[ $template_part_id ] = $template_part;
}
return $templates;
}
}
if ( ! function_exists( 'et_builder_is_block_theme' ) ) {
/**
* Whether current theme is block theme or not.
*
* @since ??
*
* @return boolean Block theme status.
*/
function et_builder_is_block_theme() {
// Use `wp_is_block_theme` on WP 5.9.
if ( function_exists( 'wp_is_block_theme' ) ) {
return (bool) wp_is_block_theme();
}
// Use `gutenberg_is_fse_theme` on GB plugin.
if ( function_exists( 'gutenberg_is_fse_theme' ) ) {
return (bool) gutenberg_is_fse_theme();
}
// Use manual check on WP 5.8 below.
$block_templates_index_html_file = get_stylesheet_directory() . '/block-templates/index.html';
$templates_index_html_file = get_stylesheet_directory() . '/templates/index.html';
return is_readable( $block_templates_index_html_file ) || is_readable( $templates_index_html_file );
}
}