version 4.13.0

This commit is contained in:
2021-12-07 11:08:05 +00:00
commit cb26d2c0c4
1285 changed files with 254735 additions and 0 deletions

View File

@ -0,0 +1,10 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Load the same plugin compat class.
*/
require_once 'advanced-custom-fields.php';

View File

@ -0,0 +1,364 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the Advanced Custom Fields plugin.
*
* @since 3.17.2
*
* @link https://www.advancedcustomfields.com/
*/
class ET_Builder_Plugin_Compat_Advanced_Custom_Fields extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 3.17.2
*/
public function __construct() {
$this->plugin_id = $this->_get_plugin_id();
$this->init_hooks();
}
/**
* Get the currently activated ACF plugin id as the FREE and PRO versions are separate plugins.
*
* @since 3.18
*
* @return string
*/
protected function _get_plugin_id() {
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$pro = 'advanced-custom-fields-pro/acf.php';
$free = 'advanced-custom-fields/acf.php';
return is_plugin_active( $pro ) ? $pro : $free;
}
/**
* Hook methods to WordPress.
*
* @since 3.17.2
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_dynamic_content_meta_value', array( $this, 'maybe_filter_dynamic_content_meta_value' ), 10, 3 );
add_filter( 'et_builder_custom_dynamic_content_fields', array( $this, 'maybe_filter_dynamic_content_fields' ), 10, 3 );
}
/**
* Format ACF meta values accordingly.
*
* @since 3.17.2
*
* @param string $meta_value
* @param string $meta_key
* @param integer $post_id
*
* @return string
*/
public function maybe_filter_dynamic_content_meta_value( $meta_value, $meta_key, $post_id ) {
global $wp_query;
$post_type = get_post_type( $post_id );
$identifier = $post_id;
if ( et_theme_builder_is_layout_post_type( $post_type ) ) {
return $this->format_placeholder_value( $meta_key, $post_id );
}
$is_blog_query = isset( $wp_query->et_pb_blog_query ) && $wp_query->et_pb_blog_query;
if ( ! $is_blog_query && ( is_category() || is_tag() || is_tax() ) ) {
$term = get_queried_object();
$identifier = "{$term->taxonomy}_{$term->term_id}";
} elseif ( is_author() ) {
$user = get_queried_object();
$identifier = "user_{$user->ID}";
}
$acf_value = get_field( $meta_key, $identifier );
if ( false === $acf_value ) {
return $meta_value;
}
$acf_field = get_field_object( $meta_key, $post_id, array( 'load_value' => false ) );
$acf_value = $this->format_field_value( $acf_value, $acf_field );
if ( is_array( $acf_value ) || is_object( $acf_value ) ) {
// Avoid exposing unformatted values.
$acf_value = '';
}
return (string) $acf_value;
}
/**
* Format ACF dynamic content field.
*
* @since 3.17.2
*
* @param array[] $custom_fields
* @param int $post_id
* @param mixed[] $raw_custom_fields
*
* @return array[] modified $custom_fields
*/
public function maybe_filter_dynamic_content_fields( $custom_fields, $post_id, $raw_custom_fields ) {
if ( ! $post_id || et_theme_builder_is_layout_post_type( get_post_type( $post_id ) ) ) {
$post_id = 0;
}
return $this->maybe_filter_dynamic_content_fields_from_groups( $custom_fields, $post_id, $raw_custom_fields );
}
/**
* Format ACF dynamic content fields for TB layouts.
*
* @since 4.0.9
*
* @param array[] $custom_fields
* @param int $post_id
* @param mixed[] $raw_custom_fields
*
* @return array[] modified $custom_fields
*/
public function maybe_filter_dynamic_content_fields_from_groups( $custom_fields, $post_id, $raw_custom_fields ) {
$groups = 0 !== $post_id ? acf_get_field_groups( array( 'post_id' => $post_id ) ) : acf_get_field_groups();
foreach ( $groups as $group ) {
$fields = $this->expand_fields( acf_get_fields( $group['ID'] ) );
foreach ( $fields as $field ) {
if ( 'group' === $field['type'] ) {
// Remove all group fields as ACF stores empty values for them.
unset( $custom_fields[ "custom_meta_{$field['name']}" ] );
continue;
}
$settings = array(
'label' => esc_html( $field['label'] ),
'type' => 'any',
'fields' => array(
'before' => array(
'label' => et_builder_i18n( 'Before' ),
'type' => 'text',
'default' => '',
'show_on' => 'text',
),
'after' => array(
'label' => et_builder_i18n( 'After' ),
'type' => 'text',
'default' => '',
'show_on' => 'text',
),
),
'meta_key' => $field['name'],
'custom' => true,
'group' => "ACF: {$group['title']}",
);
if ( current_user_can( 'unfiltered_html' ) ) {
$settings['fields']['enable_html'] = array(
'label' => esc_html__( 'Enable raw HTML', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
// Set enable_html default to `on` for taxonomy fields so builder
// automatically renders taxonomy list properly as unescaped HTML.
'default' => 'taxonomy' === $field['type'] ? 'on' : 'off',
'show_on' => 'text',
);
}
$custom_fields[ "custom_meta_{$field['name']}" ] = $settings;
}
}
return $custom_fields;
}
/**
* Expand ACF fields into their subfields in the order they are specified, if any.
*
* @since 4.0.9
*
* @param array[] $fields
* @param string $name_prefix
* @param string $label_prefix
*
* @return array[]
*/
public function expand_fields( $fields, $name_prefix = '', $label_prefix = '' ) {
$expanded = array();
foreach ( $fields as $field ) {
$expanded[] = array(
array_merge(
$field,
array(
'name' => $name_prefix . $field['name'],
'label' => $label_prefix . $field['label'],
)
),
);
if ( 'group' === $field['type'] ) {
$expanded[] = $this->expand_fields(
$field['sub_fields'],
$name_prefix . $field['name'] . '_',
$label_prefix . $field['label'] . ': '
);
}
}
if ( empty( $expanded ) ) {
return array();
}
// @phpcs:ignore Generic.PHP.ForbiddenFunctions.Found
return call_user_func_array( 'array_merge', $expanded );
}
/**
* Format a field value based on the field type.
*
* @param mixed $value
* @param array $field
*
* @return mixed
*/
protected function format_field_value( $value, $field ) {
if ( ! is_array( $field ) || empty( $field['type'] ) ) {
return $value;
}
switch ( $field['type'] ) {
case 'image':
$format = isset( $field['return_format'] ) ? $field['return_format'] : 'url';
switch ( $format ) {
case 'array':
$value = esc_url( wp_get_attachment_url( intval( $value['id'] ) ) );
break;
case 'id':
$value = esc_url( wp_get_attachment_url( intval( $value ) ) );
break;
}
break;
case 'select':
case 'checkbox':
$value = is_array( $value ) ? $value : array( $value );
$value_labels = array();
foreach ( $value as $value_key ) {
$choice_label = isset( $field['choices'][ $value_key ] ) ? $field['choices'][ $value_key ] : '';
if ( ! empty( $choice_label ) ) {
$value_labels[] = $choice_label;
}
}
$value = implode( ', ', $value_labels );
break;
case 'true_false':
$value = et_builder_i18n( $value ? 'Yes' : 'No' );
break;
case 'taxonomy':
// If taxonomy configuration exist, get HTML output of given value (ids).
if ( isset( $field['taxonomy'] ) ) {
$terms = get_terms(
array(
'taxonomy' => $field['taxonomy'],
'include' => $value,
)
);
$link = 'on';
$separator = ', ';
if ( is_array( $terms ) ) {
$value = et_builder_list_terms( $terms, $link, $separator );
}
}
break;
default:
// Handle multiple values for which a more appropriate formatting method is not available.
if ( isset( $field['multiple'] ) && $field['multiple'] ) {
$value = implode( ', ', $value );
}
break;
}
// Value escaping left to the user to decide since some fields hold rich content.
$value = et_core_esc_previously( $value );
return $value;
}
/**
* Format a placeholder value based on the field type.
*
* @param string $meta_key
* @param integer $post_id
*
* @return mixed
*/
protected function format_placeholder_value( $meta_key, $post_id ) {
if ( function_exists( 'acf_get_field' ) ) {
$field = acf_get_field( $meta_key );
} else {
$field = get_field_object( $meta_key, false, array( 'load_value' => false ) );
}
if ( ! is_array( $field ) || empty( $field['type'] ) ) {
return esc_html__( 'Your ACF Field Value Will Display Here', 'et_builder' );
}
$value = esc_html(
sprintf(
// Translators: %1$s: ACF Field name
__( 'Your "%1$s" ACF Field Value Will Display Here', 'et_builder' ),
$field['label']
)
);
switch ( $field['type'] ) {
case 'image':
$value = ET_BUILDER_PLACEHOLDER_LANDSCAPE_IMAGE_DATA;
break;
case 'taxonomy':
$value = esc_html(
implode(
', ',
array(
__( 'Category 1', 'et_builder' ),
__( 'Category 2', 'et_builder' ),
__( 'Category 3', 'et_builder' ),
)
)
);
break;
}
return $value;
}
}
new ET_Builder_Plugin_Compat_Advanced_Custom_Fields();

View File

@ -0,0 +1,51 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Amazon S3 Offload
*
* @since 3.0.49
*
* @link https://wordpress.org/plugins/amazon-s3-and-cloudfront/
*/
class ET_Builder_Plugin_Compat_WP_Offload_S3_Pro extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'amazon-s3-and-cloudfront-pro/amazon-s3-and-cloudfront-pro.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1.1.6
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest theme version
add_action( 'et_fb_ajax_save_verification_result', array( $this, 'override_fb_ajax_save_verification' ) );
}
/**
* @param bool $verification
*
* @return bool
*/
function override_fb_ajax_save_verification( $verification ) {
return true;
}
}
new ET_Builder_Plugin_Compat_WP_Offload_S3_Pro();

View File

@ -0,0 +1,101 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Amazon S3 Offload
*
* @since 3.0.49
*
* @link https://wordpress.org/plugins/amazon-s3-and-cloudfront/
*/
class ET_Builder_Plugin_Compat_WP_Offload_S3 extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'amazon-s3-and-cloudfront/wordpress-s3.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1.1.6
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest theme version
add_action( 'et_fb_ajax_save_verification_result', array( $this, 'override_fb_ajax_save_verification' ) );
// Filter attachment IDs for images with an external/CDN URL.
add_filter( 'et_get_attachment_id_by_url_pre', array( $this, 'et_get_attachment_id_by_url_pre' ), 10, 2 );
// Filter image urls in the raw post content.
add_filter( 'et_fb_load_raw_post_content', array( $this, 'filter_urls_on_raw_post_content' ), 10, 2 );
}
/**
* @param bool $verification
*
* @return bool
*/
function override_fb_ajax_save_verification( $verification ) {
return true;
}
/**
* Filter attachment ID in case it has an external/CDN URL.
*
* @since 4.2.1
*
* @param bool|int $attachment_id_pre Default value. Default is false.
* @param string $url URL of the image need to query.
*
* @return bool|int
*/
public function et_get_attachment_id_by_url_pre( $attachment_id_pre, $url ) {
global $as3cf;
$as3cf_s3_to_local = new AS3CF_S3_To_Local( $as3cf );
$attachment_id = $as3cf_s3_to_local->get_attachment_id_from_url( $url );
if ( $attachment_id ) {
return $attachment_id;
}
return $attachment_id_pre;
}
/**
* Filter the raw post content to be used to generate the builder data.
* The `et_fb_get_builder_shortcode_object()` directly access the raw post_content, so the image URL not properly transformed
*
* @since 4.7.0
*
* @param string $post_content The post content.
* @param string $post_id The post ID.
* @return string
*/
public function filter_urls_on_raw_post_content( $post_content, $post_id ) {
global $as3cf;
if ( property_exists( $as3cf, 'filter_local' ) && method_exists( $as3cf->filter_local, 'filter_post' ) ) {
$post_content = $as3cf->filter_local->filter_post( $post_content );
}
return $post_content;
}
}
new ET_Builder_Plugin_Compat_WP_Offload_S3();

View File

@ -0,0 +1,49 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Autoptimize
*
* @since 3.17.1
*
* @link https://wordpress.org/plugins/autoptimize/
*/
class ET_Builder_Plugin_Compat_Autoptimize extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'autoptimize/autoptimize.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
if ( $enabled['vb'] || $enabled['bfb'] ) {
// JS optimization breaks the builder so we need to disable it
add_filter( 'autoptimize_filter_js_noptimize', '__return_true' );
add_filter( 'autoptimize_filter_css_noptimize', '__return_true' );
}
}
}
new ET_Builder_Plugin_Compat_Autoptimize();

View File

@ -0,0 +1,55 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Caldera Forms
*
* @since 3.17.3
*
* @link https://wordpress.org/plugins/caldera-forms/
*/
class ET_Builder_Plugin_Compat_Caldera_Forms extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'caldera-forms/caldera-core.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1.7.6
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
if ( ! class_exists( 'Caldera_Forms_Admin' ) ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
if ( $enabled['vb'] && ! $enabled['bfb'] ) {
// Caldera Form custom tinyMCE's button doesn't work in VB, let's remove it.
$instance = Caldera_Forms_Admin::get_instance();
remove_action( 'media_buttons', array( $instance, 'shortcode_insert_button' ), 11 );
}
}
}
new ET_Builder_Plugin_Compat_Caldera_Forms();

View File

@ -0,0 +1,81 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the Cartflows plugin.
*
* @since 4.0.7
*
* @link https://wordpress.org/plugins/cartflows/
*/
class ET_Builder_Plugin_Compat_Cartflows extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.0.7
*/
public function __construct() {
$this->plugin_id = 'cartflows/cartflows.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.0.7
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'wp', array( $this, 'maybe_disable_theme_builder' ), 9 );
}
/**
* Disable theme builder for specific Cartflow templates that don't use
* the normal WordPress partials (get_header(), get_footer()).
*
* @since 4.0.7
*/
public function maybe_disable_theme_builder() {
$step_post_type = defined( 'CARTFLOWS_STEP_POST_TYPE' ) ? CARTFLOWS_STEP_POST_TYPE : 'cartflows_step';
if ( is_singular( $step_post_type ) ) {
/**
* Filters page templates that should have the Theme Builder disabled.
*
* @since 4.0.7
*
* @param string[] $templates
*/
$disable_for = apply_filters( 'et_builder_compatibility_cartflows_templates_without_theme_builder', array( 'cartflows-default', 'cartflows-canvas' ) );
$template = get_post_meta( get_the_ID(), '_wp_page_template', true );
if ( in_array( $template, $disable_for, true ) ) {
add_filter( 'et_theme_builder_template_layouts', array( $this, 'disable_theme_builder' ) );
}
}
}
/**
* Disable theme builder for the current request by returning no layouts for it.
*
* @since 4.0.7
*
* @param array $layouts
*
* @return array
*/
public function disable_theme_builder( $layouts ) {
return array();
}
}
new ET_Builder_Plugin_Compat_Cartflows();

View File

@ -0,0 +1,69 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for CDN Enabler
*
* @since 3.19.10
*
* @link https://wordpress.org/plugins/cdn-enabler/
*/
class ET_Builder_Plugin_Compat_CDN_Enabler extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'cdn-enabler/cdn-enabler.php';
$this->init_hooks();
}
/**
* Replace CDN Enabler option with custom values.
*
* @param string $value Option value.
*
* @access public.
* @return void
*/
public function option_cdn_enabler( $value ) {
$fix = ',(,]';
$excludes = et_()->array_get( $value, 'excludes', '' );
// If the fix isn't included
if ( substr( $excludes, -strlen( $fix ) ) !== $fix ) {
$value['excludes'] = "$excludes$fix";
}
return $value;
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1.0.8
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
if ( $enabled['vb'] || $enabled['bfb'] ) {
add_action( 'option_cdn_enabler', array( $this, 'option_cdn_enabler' ) );
}
}
}
new ET_Builder_Plugin_Compat_CDN_Enabler();

View File

@ -0,0 +1,51 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for CoursePress Pro
*
* @since 3.21.3
*/
class ET_Builder_Plugin_Compat_CoursePress extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'coursepress/coursepress.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
if ( ! method_exists( 'CoursePress_Admin_Edit', 'enable_tinymce' ) ) {
return;
}
// Remove the filter so it doesn't execute too early....
remove_filter( 'user_can_richedit', array( 'CoursePress_Admin_Edit', 'enable_tinymce' ) );
// ... and add it again later, when it won't cause errors.
add_action( 'current_screen', array( $this, 'current_screen' ) );
}
/**
* Add the filter again.
*
* @access public.
* @return void
*/
public function current_screen() {
add_filter( 'user_can_richedit', array( 'CoursePress_Admin_Edit', 'enable_tinymce' ) );
}
}
new ET_Builder_Plugin_Compat_CoursePress();

View File

@ -0,0 +1,51 @@
<?php
/**
* Plugin Compatibility for Divi Filterable Blog Module plugin.
*
* @package Divi
* @subpackage Builder
* @since 4.11.4
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Plugin Compatibility for Divi Filterable Blog Module.
*
* @since 4.11.4
*/
class ET_Builder_Plugin_Compat_Divi_Filterable_Blog_Module extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.11.4
*/
public function __construct() {
$this->init_hooks();
}
/**
* Initialize hooks.
*
* @since 4.11.4
*
* @return void
*/
public function init_hooks() {
if ( ! is_plugin_active( 'divi-filterable-blog-module/divi-filterable-blog-module.php' ) ) {
return;
}
$dfbm_controller = new dfbmControllerInitialize();
$dfbm_module = new dfbmControllerModules();
// Add new hooks.
add_action( 'et_builder_ready', array( $dfbm_controller, 'setFrontend' ) );
add_action( 'et_builder_ready', array( $dfbm_module, 'modules' ) );
}
}
new ET_Builder_Plugin_Compat_Divi_Filterable_Blog_Module();

View File

@ -0,0 +1,71 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Divi Code Snippet Module
*
* @since 3.17.3
*/
class ET_Builder_Plugin_Compat_Divi_Code_Snippet_Module extends ET_Builder_Plugin_Compat_Base {
protected $posts = '';
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'divi-module-code-snippet/divi-module-code-snippet.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
if ( function_exists( 'load_DMB_Module_Code_Snippet' ) && function_exists( 'load_db_cs_ET_Builder_Module' ) ) {
remove_action( 'wp_loaded', 'load_db_cs_ET_Builder_Module' );
remove_action( 'wp_loaded', 'load_DMB_Module_Code_Snippet' );
add_action( 'et_builder_ready', array( $this, 'et_builder_ready' ) );
add_filter( 'the_posts', array( $this, 'the_posts' ) );
}
}
/**
* Saves filter value for later use.
*
* @return array
*/
public function the_posts( $posts ) {
$this->posts = $posts;
return $posts;
}
/**
* Runs when the builder is ready.
*
* @return void
*/
public function et_builder_ready() {
load_db_cs_ET_Builder_Module();
load_DMB_Module_Code_Snippet();
$instance = et_()->array_get( ET_Builder_Module::get_modules(), 'et_pb_dmb_code_snippet', false );
if ( $instance ) {
$instance->module_used_in_post( $this->posts );
}
}
}
new ET_Builder_Plugin_Compat_Divi_Code_Snippet_Module();

View File

@ -0,0 +1,65 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Divi Testimonial Slider.
*
* @since 4.0.10
*/
class ET_Builder_Plugin_Compat_DiviTestimonialSlider extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.0.10
*/
public function __construct() {
$this->plugin_id = 'divi-testimonial-slider/divi-testimonial-slider.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.0.10
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
$hook = array( $this, 'remove_random_default' );
$slugs = array(
'et_pb_b3_testimonial_archive',
'et_pb_b3_testimonial_grid_slider',
'et_pb_testimonial_slider',
);
foreach ( $slugs as $slug ) {
add_filter( "et_pb_all_fields_unprocessed_{$slug}", $hook );
}
}
/**
* Replace the random default with a fixed value.
*
* @since 4.0.10
*
* @param array $advanced_fields
*
* @return array
*/
public function remove_random_default( $fields_unprocessed ) {
et_()->array_set( $fields_unprocessed, 'hidden_field.default', 50 );
return $fields_unprocessed;
}
}
new ET_Builder_Plugin_Compat_DiviTestimonialSlider();

View File

@ -0,0 +1,106 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Divi Layout Injector
*
* @since 3.0.62
*
* @link https://elegantmarketplace.com/downloads/divi-layout-injector
*/
class ET_Builder_Plugin_Compat_Divi_Layout_Injector extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'divi_layout_injector/divi_layout_injector.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'wp', array( $this, 'maybe_disable_in_tb' ) );
add_action( 'wp', array( $this, 'maybe_filter_builder_used' ), 9 );
add_action( 'updated_option', array( $this, 'updated_option_cb' ), 10, 3 );
add_action( 'updated_post_meta', array( $this, 'updated_post_meta_cb' ), 10, 4 );
}
/**
* Disable layout injection when editing TB layouts.
*
* @since 4.0
*/
function maybe_disable_in_tb() {
if ( et_builder_tb_enabled() ) {
remove_action( 'get_header', 'sb_divi_fe_record_start', 1 );
remove_filter( 'the_content', 'sb_divi_fe_content' );
remove_action( 'wp_footer', 'sb_divi_fe_footer_end' );
}
}
function maybe_filter_builder_used() {
$types = array( 'layout', 'page' );
$will_inject = is_404() && in_array( get_option( 'sb_divi_fe_404_type', 'layout' ), $types );
if ( is_404() ) {
$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 );
// Remove 404 page redirect if 404 page built in Theme Builder.
if ( $override_header || $override_body || $override_footer ) {
remove_action( 'template_redirect', 'sb_divi_fe_404' );
remove_action( 'get_header', 'sb_divi_fe_record_start', 1 );
remove_filter( 'the_content', 'sb_divi_fe_content' );
remove_action( 'wp_footer', 'sb_divi_fe_footer_end' );
}
}
if ( ! $will_inject ) {
$will_inject = $this->will_inject_layout();
}
if ( $will_inject ) {
add_filter( 'et_core_is_builder_used_on_current_request', '__return_true', 10, 0 );
}
}
function updated_option_cb( $option, $old_value, $value ) {
if ( 0 === strpos( $option, 'sb_divi_fe' ) ) {
ET_Core_PageResource::remove_static_resources( 'all', 'all' );
}
}
function updated_post_meta_cb( $meta_id, $object_id, $meta_key, $_meta_value ) {
if ( 'sb_divi_fe_layout_overrides' === $meta_key ) {
ET_Core_PageResource::remove_static_resources( $object_id, 'all' );
}
}
function will_inject_layout() {
$locations = array( 'pre-header', 'post-menu', 'pre-content', 'post-content', 'pre-footer' );
foreach ( $locations as $location ) {
if ( sb_divi_fe_get_layout( $location ) ) {
return true;
}
}
return false;
}
}
new ET_Builder_Plugin_Compat_Divi_Layout_Injector();

View File

@ -0,0 +1,60 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Divi Woo Layout Injector.
*
* @since 4.0.5
*
* @link https://elegantmarketplace.com/downloads/woo-layout-injector-subscription/
*/
class ET_Builder_Plugin_Compat_Divi_Woo_Layout_Injector extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*/
function __construct() {
$this->plugin_id = 'divi_woo_layout_injector/divi_woo_layout_injector.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'the_content', array( $this, 'maybe_disable_in_the_content' ), 998 );
}
/**
* Disable layout injection when editing TB layouts.
*
* @since 4.0.5
*
* @param string $content
*
* @return string
*/
function maybe_disable_in_the_content( $content ) {
$is_tb = et_theme_builder_is_layout_post_type( get_post_type( get_the_ID() ) );
if ( $is_tb ) {
remove_filter( 'the_content', 'sb_et_woo_li_content_filter', 999 );
} elseif ( did_action( 'plugins_loaded' ) && ! has_action( 'the_content', 'sb_et_woo_li_content_filter' ) ) {
add_filter( 'the_content', 'sb_et_woo_li_content_filter', 999 );
}
return $content;
}
}
new ET_Builder_Plugin_Compat_Divi_Woo_Layout_Injector();

View File

@ -0,0 +1,77 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for dk-pdf
*
* @since 3.0.96
* @link https://wordpress.org/plugins/dk-pdf/
*/
class ET_Builder_Plugin_Compat_DK_Pdf extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'dk-pdf/dk-pdf.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Note: once this issue is fixed in future version, run version_compare() to limit the scope
* of the hooked fix
* Latest plugin version: 1.9.3
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest theme version
// If current page has pdf query string, it means that DK PDF re-route the request to
// display the pdf version of the page
if ( isset( $_GET['pdf'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
add_filter(
'et_pb_load_main_elements_priority',
array( $this, 'fix_load_main_elements_priority' )
);
}
// Add styling to fix DK PDF button when page builder is used
add_action( 'wp_enqueue_scripts', array( $this, 'fix_dkpdf_button_styling' ), 20 );
}
/**
* Modify priority of et_builder_add_main_elements() hook so it'll be triggered before dk-pdf
*
* @return int
*/
function fix_load_main_elements_priority( $priority ) {
return 7;
}
/**
* Modify DK PDF button if the page uses builder
*
* @return void
*/
function fix_dkpdf_button_styling() {
global $post;
if ( isset( $post->ID ) && et_pb_is_pagebuilder_used( $post->ID ) ) {
$content_width = et_get_option( 'content_width', 1080 );
wp_add_inline_style(
'dkpdf-frontend',
'.dkpdf-button-container { float: none; width: 80%; max-width: ' . $content_width . 'px; margin: 0 auto; }'
);
}
}
}
new ET_Builder_Plugin_Compat_DK_Pdf();

View File

@ -0,0 +1,57 @@
<?php
/**
* Plugin compat divi space.
*
* @package Divi
* @subpackage Builder
* @since 4.10.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Plugin compatibility for CoursePress Pro
*
* @since 3.21.3
*/
class ET_Builder_Plugin_Compat_DiviRocket extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'ds-divi-rocket/ds-divi-rocket.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @return void
*/
public function init_hooks() {
if ( ! class_exists( 'DiviRocket' ) ) {
return;
}
add_action( 'wp_loaded', array( $this, 'remove_shortcode_manager' ) );
}
/**
* Remove the extra shortcode manager.
*
* @since 4.10.0
* @return void
*/
public function remove_shortcode_manager() {
// Set empty array to short-circuit the plugin's shortcode manager.
DiviRocket::$shortcodeFiles = []; //phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- third party.
}
}
new ET_Builder_Plugin_Compat_DiviRocket();

View File

@ -0,0 +1,170 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for easy-digital-downloads
*
* @since 0.7 (builder version)
* @link https://easydigitaldownloads.com
*/
class ET_Builder_Plugin_Compat_Easy_Digital_Downloads extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'easy-digital-downloads/easy-digital-downloads.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Note: once this issue is fixed in future version, run version_compare() to limit the scope of the hooked fix
* Latest plugin version: 2.6.17
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest theme version
if ( ! is_admin() ) {
add_filter( 'edd_purchase_link_defaults', array( $this, 'purchase_link_defaults' ) );
add_filter( 'shortcode_atts_purchase_link', array( $this, 'purchase_link_defaults' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'add_compatibility_scripts' ), 15 );
} else {
add_filter( 'edd_checkout_button_purchase', array( $this, 'modify_edd_checkout_button_purchase' ) );
}
}
/**
* Appended et_pb_button for various EDD button so it matches Divi styled button
*
* @param array initial link configuration
* @return array moodified link configuration
*/
function purchase_link_defaults( $args ) {
if ( isset( $args['class'] ) ) {
$args['class'] = $args['class'] . ' et_pb_button';
}
return $args;
}
/**
* Addded et_pb_button class for checkout button which has no attribute filter
*
* @param string of HTML of the button
* @return string of modified HTML of the button
*/
function modify_edd_checkout_button_purchase( $button ) {
$button = str_replace( 'edd-submit', 'edd-submit et_pb_button', $button );
return $button;
}
/**
* Added additional styling & scripts for EDD on Divi
*
* @return void
*/
function add_compatibility_scripts() {
// Normalize UI for Divi Builder
if ( et_is_builder_plugin_active() ) {
wp_add_inline_style(
'et-builder-modules-style',
'
' . ET_BUILDER_CSS_PREFIX . ' .edd_download_inner {
padding: 0 8px 8px;
margin: 0 0 10px;
}
' . ET_BUILDER_CSS_PREFIX . ' .edd_download_excerpt p {
margin-bottom: 25px;
}
' . ET_BUILDER_CSS_PREFIX . ' .edd_purchase_submit_wrapper {
margin-top: 15px;
margin-bottom: 35px;
}
' . ET_BUILDER_CSS_PREFIX . ' ul.edd-cart {
border: 1px solid #eee;
margin-top: 0.8em;
}
' . ET_BUILDER_CSS_PREFIX . ' ul.edd-cart li {
padding: 0.8em 1.387em;
border-bottom: 1px solid #eee;
}
' . ET_BUILDER_CSS_PREFIX . ' ul.edd-cart li:last-child {
border-bottom: none;
}
' . ET_BUILDER_CSS_PREFIX . ' ul.edd-cart .edd-cart-item span {
padding: 0 3px;
}
' . ET_BUILDER_CSS_PREFIX . ' ul.edd-cart .edd-cart-item a {
text-decoration: underline !important;
}
' . ET_BUILDER_CSS_PREFIX . ' .edd_cart_item_image {
margin-right: 10px;
display: inline-block;
vertical-align: middle;
}
' . ET_BUILDER_CSS_PREFIX . ' .edd-cart-meta.edd_subtotal,
' . ET_BUILDER_CSS_PREFIX . ' .edd-cart-meta.edd_total {
background: #f9f9f9;
}
' . ET_BUILDER_CSS_PREFIX . ' .cart_item.edd_checkout {
padding: 1.387em;
}
' . ET_BUILDER_CSS_PREFIX . ' .et_pb_module a.edd_cart_remove_item_btn {
text-decoration: underline !important;
}
' . ET_BUILDER_CSS_PREFIX . ' #edd_profile_editor_form .edd-select,
' . ET_BUILDER_CSS_PREFIX . ' #edd_profile_editor_form .edd-input {
margin-bottom: 5px;
}
' . ET_BUILDER_CSS_PREFIX . ' #edd_final_total_wrap {
margin-bottom: 20px;
}
' . ET_BUILDER_CSS_PREFIX . ' .et_pb_module .et_pb_button {
border-bottom-style: solid;
border-bottom-width: 2px;
}
' . ET_BUILDER_CSS_PREFIX . ' .et_pb_module input.et_pb_button:hover {
padding-right: 1em;
}
'
);
}
// Re-styled button with Divi's button UI using javascript due to lack of filter
wp_add_inline_script(
et_get_combined_script_handle(),
"
(function($){
$(function(){
$('.cart_item.edd_checkout a, input[name=\"edd_register_submit\"], .edd_submit').addClass( 'et_pb_button' ).attr('style', 'padding-right: 1em;');
});
})(jQuery)
"
);
}
}
new ET_Builder_Plugin_Compat_Easy_Digital_Downloads();

View File

@ -0,0 +1,139 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the EventOn plugin.
*
* @since 3.10
*
* @link http://www.myeventon.com/
*/
class ET_Builder_Plugin_Compat_Eventon extends ET_Builder_Plugin_Compat_Base {
/**
* Event post type.
*
* @var string
*/
protected $event_post_type = 'ajde_events';
/**
* Constructor.
*
* @since 3.10
*/
public function __construct() {
$this->plugin_id = 'eventon/eventon.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 3.10
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_post_type_blocklist', array( $this, 'maybe_filter_post_type_blocklist' ) );
add_filter( 'et_builder_third_party_post_types', array( $this, 'maybe_filter_third_party_post_types' ) );
add_filter( 'et_builder_post_types', array( $this, 'maybe_filter_builder_post_types' ) );
add_filter( 'et_fb_post_types', array( $this, 'maybe_filter_builder_post_types' ) );
add_filter( 'et_builder_fb_enabled_for_post', array( $this, 'maybe_filter_fb_enabled_for_post' ), 10, 2 );
}
/**
* Get whether the EventOn content filter is set to WordPress' default one.
*
* @since 3.10
*
* @return boolean
*/
public function uses_default_filter() {
$options = get_option( 'evcal_options_evcal_1' );
return ! empty( $options['evo_content_filter'] ) && $options['evo_content_filter'] === 'def';
}
/**
* Maybe filter the post type blocklist if the post type is not supported.
*
* @since 3.10
*
* @param string[] $post_types
*
* @return string[]
*/
public function maybe_filter_post_type_blocklist( $post_types ) {
if ( ! $this->uses_default_filter() ) {
$post_types[] = $this->event_post_type;
}
return $post_types;
}
/**
* Maybe filter the supported post type allowlist if the post type is supported.
*
* @since 3.10
*
* @param string[] $post_types
*
* @return string[]
*/
public function maybe_filter_third_party_post_types( $post_types ) {
if ( $this->uses_default_filter() ) {
$post_types[] = $this->event_post_type;
}
return $post_types;
}
/**
* Maybe filter the enabled post type list if the post type has been enabled but the content
* filter has been changed back to the unsupported one.
*
* @since 3.10
*
* @param string[] $post_types
*
* @return string[]
*/
public function maybe_filter_builder_post_types( $post_types ) {
if ( ! $this->uses_default_filter() ) {
$index = array_search( $this->event_post_type, $post_types );
array_splice( $post_types, $index, 1 );
}
return $post_types;
}
/**
* Maybe disable the FB for a given post if the builder was enabled but the
* content filter was switched after that.
*
* @since 3.10
*
* @param boolean $enabled
* @param integer $post_id
*
* @return boolean
*/
public function maybe_filter_fb_enabled_for_post( $enabled, $post_id ) {
$post_type = get_post_type( $post_id );
if ( $post_type === $this->event_post_type && ! $this->uses_default_filter() ) {
$enabled = false;
}
return $enabled;
}
}
new ET_Builder_Plugin_Compat_Eventon();

View File

@ -0,0 +1,71 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for Events Manager plugin.
*
* @since 3.10
*
* @link https://wordpress.org/plugins/events-manager/
*/
class ET_Builder_Plugin_Compat_Events_Manager extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 3.10
*/
public function __construct() {
$this->plugin_id = 'events-manager/events-manager.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 3.10
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'em_event_output_placeholder', array( $this, 'maybe_filter_content' ), 10, 4 );
add_filter( 'em_location_output_placeholder', array( $this, 'maybe_filter_content' ), 10, 4 );
}
/**
* Pass the single event content through et_fb_app_boot() since Events Manager skips usual
* `the_content` filters.
*
* @since 3.10
*
* @param string $replace
* @param mixed $event
* @param string $full_result
* @param mixed $target
*
* @return string
*/
public function maybe_filter_content( $replace, $event, $full_result, $target ) {
$content_placeholders = array(
'#_NOTES',
'#_EVENTNOTES',
'#_DESCRIPTION',
'#_LOCATIONNOTES',
);
if ( ! function_exists( 'et_fb_app_boot' ) || ! in_array( $full_result, $content_placeholders ) ) {
return $replace;
}
return et_fb_app_boot( $replace );
}
}
new ET_Builder_Plugin_Compat_Events_Manager();

View File

@ -0,0 +1,65 @@
<?php
/**
* Compatibility for Image Photo Gallery Final Tiles Grid.
*
* @package Divi
* @subpackage Builder
* @since 4.10.6
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for Image Photo Gallery Final Tiles Grid.
*
* @since 4.10.6
*
* @link https://wordpress.org/plugins/final-tiles-grid-gallery-lite/
*/
class ET_Builder_Plugin_Compat_Image_Photo_Gallery_Final_Tiles_Grid extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.6
*/
public function __construct() {
$this->plugin_id = 'final-tiles-grid-gallery-lite/FinalTilesGalleryLite.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.6
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_enable_jquery_body', array( $this, 'maybe_disable_jquery_body' ), 10, 2 );
}
/**
* Maybe Disable JQuery Body feature.
*
* @since 4.10.6
*
* @param bool $enabled Whether the feature should be enabled or not.
* @param string $content TB/Post content.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled, $content ) {
// Disable when showing plugin's shortcode.
return false !== strpos( $content, '[FinalTilesGallery' ) ? false : $enabled;
}
}
new ET_Builder_Plugin_Compat_Image_Photo_Gallery_Final_Tiles_Grid();

View File

@ -0,0 +1,38 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Gravityforms
*
* @since 3.19
*
* @link https://www.gravityforms.com/
*/
class ET_Builder_Plugin_Compat_Gravityforms extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'gravityforms/gravityforms.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
$is_bfb = et_()->array_get( $_GET, 'et_bfb' );
// Load Gravity Form button in BFB
if ( $is_bfb ) {
add_filter( 'gform_display_add_form_button', '__return_true' );
}
}
}
new ET_Builder_Plugin_Compat_Gravityforms();

View File

@ -0,0 +1,68 @@
<?php
/**
* Compatibility Gravity Forms Signature Add-On.
*
* @package Divi
* @subpackage Builder
* @since 4.10.6
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility Gravity Forms Signature Add-On.
*
* @since 4.10.6
*
* @link https://gravityforms.com
*/
class ET_Builder_Plugin_Compat_GravityForms_Signature_AddOn extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.6
*/
public function __construct() {
$this->plugin_id = 'gravityformssignature/signature.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.6
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_enable_jquery_body', array( $this, 'maybe_disable_jquery_body' ), 10, 2 );
}
/**
* Maybe Disable JQuery Body feature.
*
* @since 4.10.6
*
* @param bool $enabled Whether the feature should be enabled or not.
* @param string $content TB/Post content.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled, $content ) {
// Disable when plugin scripts are enqueued or `gravityform` shortcode is used.
// Ideally we'd want to do the latter only when the form actually includes a signature field
// but that would require extracting and parsing the shortcode manually in order to get the form ID
// and we already have enough opened can of worms to deal with.
return wp_script_is( 'super_signature_script' ) || false !== strpos( $content, '[gravityform' ) ? false : $enabled;
}
}
new ET_Builder_Plugin_Compat_GravityForms_Signature_AddOn();

View File

@ -0,0 +1,62 @@
<?php // phpcs:disable Squiz.Commenting.FileComment.Missing -- Not used in other compat classes.
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the Heroic Knowledge Base plugin.
*
* @link https://herothemes.com/plugins/heroic-wordpress-knowledge-base/
*/
class ET_Builder_Plugin_Compat_HT_Knowledge_Base extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*/
public function __construct() {
$this->plugin_id = 'ht-knowledge-base/ht-knowledge-base.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'template_include', array( $this, 'tb_category_page_compatibility' ) );
}
/**
* Compatibility with Heroic Knowledge Base :: Theme Builder doesn't work on category pages
* https://github.com/elegantthemes/Divi/issues/22184
*
* @param string $template The template file.
*
* @return string $template The filtered template file.
*/
public function tb_category_page_compatibility( $template ) {
global $wp_query, $ht_knowledge_base_init;
// Dummy post default.
$dummy_post_default = array();
$queried_object = isset( $wp_query->queried_object ) ? $wp_query->queried_object : null;
if ( ! empty( $queried_object->taxonomy ) && 'ht_kb_category' === $queried_object->taxonomy ) {
$dummy_post_default['is_tax'] = true;
// Reset post.
$ht_knowledge_base_init->ht_kb_theme_compat_reset_post( $dummy_post_default );
}
return $template;
}
}
new ET_Builder_Plugin_Compat_HT_Knowledge_Base();

View File

@ -0,0 +1,128 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the Imagify plugin.
*
* @since 4.4.6
*
* @link https://wordpress.org/plugins/imagify/
*/
class ET_Builder_Plugin_Compat_Imagify extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.4.6
*/
public function __construct() {
$this->plugin_id = 'imagify/imagify.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.4.6
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'wp_enqueue_scripts', array( $this, 'overrides_main_style' ) );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'overrides_customizer_styles' ) );
}
/**
* Overrides main style if needed. Please modify it accordingly in the future.
*
* @since 4.4.6
*/
public function overrides_main_style() {
if ( ! function_exists( 'get_imagify_option' ) ) {
return;
}
$style = '';
// Logo - Custom style should be applied only when WebP + picture tag is enabled.
$is_webp = get_imagify_option( 'display_webp' );
$is_webp_picture = 'picture' === get_imagify_option( 'display_webp_method' );
if ( $is_webp && $is_webp_picture ) {
$logo_height = esc_attr( et_get_option( 'logo_height', '54' ) );
$style .= "
picture#logo {
display: inherit;
}
picture#logo source, picture#logo img {
width: auto;
max-height: {$logo_height}%;
vertical-align: middle;
}
@media (min-width: 981px) {
.et_vertical_nav #main-header picture#logo source,
.et_vertical_nav #main-header picture#logo img {
margin-bottom: 28px;
}
}
";
}
if ( ! empty( $style ) ) {
wp_add_inline_style( 'divi-style', $style );
}
}
/**
* Overrides customizer style if needed. Please modify it accordingly in the future.
*
* @since 4.4.6
*/
function overrides_customizer_styles() {
if ( ! function_exists( 'get_imagify_option' ) ) {
return;
}
$scripts = '';
// Logo - Custom style should be applied only when WebP + picture tag is enabled.
$is_webp = get_imagify_option( 'display_webp' );
$is_webp_picture = 'picture' === get_imagify_option( 'display_webp_method' );
if ( $is_webp && $is_webp_picture ) {
$scripts .= "
(function($, api){
var logo_image = '';
function fix_webp_logo_height() {
if ('' === logo_image) {
var context = frames['customize-' + api.previewer.channel()].document;
logo_image = $('picture#logo img, picture#logo source', context);
}
var logo_height = api.value('et_divi[logo_height]')();
logo_height = 'undefined' === typeof logo_height ? 54 : parseInt(logo_height);
logo_image.css('max-height', logo_height + '%');
}
api('et_divi[logo_height]', function(value) {
value.bind(function(to) {
fix_webp_logo_height();
});
});
})(jQuery, wp.customize);
";
}
if ( ! empty( $scripts ) ) {
wp_add_inline_script( 'divi-customizer-controls-js', $scripts );
}
}
}
new ET_Builder_Plugin_Compat_Imagify();

View File

@ -0,0 +1,55 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for insert-pages
*
* @since 0.7 (builder version)
* @link https://wordpress.org/plugins/insert-pages/
*/
class ET_Builder_Plugin_Compat_Insert_Pages extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'insert-pages/insert-pages.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Note: once this issue is fixed in future version, run version_compare() to limit the scope of the hooked fix
* Latest plugin version: 2.7.2
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest theme version
add_action( 'admin_init', array( $this, 'disable_mce_buttons_on_builder' ), 1 );
}
/**
* insert-pages' tinyMCE button causes sub-module's tinyMCE editor to be empty when being opened.
* This might damage user's content. Since there's no hook to filter or modify insert-pages' js events,
* it'd be safer to deregister insert-pages' tinyMCE button
*
* @return void
*/
function disable_mce_buttons_on_builder() {
global $insertPages_plugin;
if ( is_null( $insertPages_plugin ) ) {
return;
}
remove_action( 'admin_head', array( $insertPages_plugin, 'insertPages_admin_init' ), 1 );
}
}
new ET_Builder_Plugin_Compat_Insert_Pages();

View File

@ -0,0 +1,60 @@
<?php
/**
* Plugin compatibility for Jucra ACF Maps.
*
* @package Divi
* @subpackage Builder
* @since 4.10.5
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Plugin compatibility for Jucra ACF Maps.
*
* @since 4.10.5
*
* @link https://www.jucra.com/display-acf-maps-in-a-divi-theme-builder-page/
*/
class ET_Builder_Plugin_Compat_Jucra_ACF_Maps extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'jucra-acf-google-maps-for-divi/index.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
add_filter( 'et_builder_enable_jquery_body', [ $this, 'maybe_disable_jquery_body' ], 10, 2 );
}
/**
* Disable JQuery Body feature when showing a map
*
* @since 4.10.5
*
* @param bool $enabled Whether the feature should be enabled or not.
* @param string $content TB/Post Content.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled, $content = '' ) {
if ( empty( $content ) ) {
return $enabled;
}
// disable when the shortcode is found.
return false === strpos( $content, 'jucra_acf_map' ) ? $enabled : false;
}
}
new ET_Builder_Plugin_Compat_Jucra_ACF_Maps();

View File

@ -0,0 +1,51 @@
<?php
/**
* Compatibility for kvCORE.
*
* @package Divi
* @subpackage Builder
* @since 4.10.8
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for kvCORE.
*
* @since 4.10.8
*
* @link https://wordpress.org/plugins/kvcore-idx/
*/
class ET_Builder_Plugin_Compat_KvCORE extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.8
*/
public function __construct() {
$this->plugin_id = 'kvcore-idx/kvcore-idx.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.8
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
// Plugin is just incompatible with JQuery Body feature.
add_filter( 'et_builder_enable_jquery_body', '__return_false', 10, 2 );
}
}
new ET_Builder_Plugin_Compat_KvCORE();

View File

@ -0,0 +1,40 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WordPress Landing Pages
*/
class ET_Builder_Plugin_Compat_Landing_Pages extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'landing-pages/landing-pages.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
add_action( 'et_fb_framework_loaded', array( $this, 'fix_the_content_hooks' ) );
}
function fix_the_content_hooks() {
$post_id = et_core_page_resource_get_the_ID();
$post_type = get_post_type( $post_id );
if ( 'landing-page' === $post_type ) {
// Landing Page plugin adds `the_content` filter with 20 priority, so we have to fire our actions after that.
add_filter( 'the_content', 'et_fb_app_boot', 30 );
add_filter( 'the_content', 'et_builder_add_builder_content_wrapper', 31 );
}
}
}
new ET_Builder_Plugin_Compat_Landing_Pages();

View File

@ -0,0 +1,65 @@
<?php
/**
* Compatibility for M Chart
*
* @package Divi
* @subpackage Builder
* @since 4.10.6
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for M Chart.
*
* @since 4.10.6
*
* @link http://github.com/methnen/m-chart
*/
class ET_Builder_Plugin_Compat_M_Chart extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.6
*/
public function __construct() {
$this->plugin_id = 'm-chart/m-chart.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.6
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_enable_jquery_body', array( $this, 'maybe_disable_jquery_body' ), 10, 2 );
}
/**
* Maybe Disable JQuery Body feature.
*
* @since 4.10.6
*
* @param bool $enabled Whether the feature should be enabled or not.
* @param string $content TB/Post content.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled, $content ) {
// Disable when showing plugin's post type / shortcode.
return is_singular( 'm-chart' ) || false !== strpos( $content, '[chart' ) ? false : $enabled;
}
}
new ET_Builder_Plugin_Compat_M_Chart();

View File

@ -0,0 +1,59 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for "MapPress Easy Google Maps"
*
* @since 3.0.98
* @link https://wordpress.org/plugins/insert-pages/
*/
class ET_Builder_Plugin_Compat_Mappress extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'mappress-google-maps-for-wordpress/mappress.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Once this issue is fixed in future version, do version_compare() to limit the scope of the fix
* Latest plugin version: 2.47.5
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest plugin version
add_action( 'wp_footer', array( $this, 'dequeue_scripts' ) );
}
/**
* Mappress loads the exact same Google Maps library Divi is using which causes an issue
*
* @return void
*/
function dequeue_scripts() {
// Check if current page is builder page and enqueueing Google Maps script
if ( is_singular() && et_pb_is_pagebuilder_used( get_the_ID() ) && et_pb_enqueue_google_maps_script() ) {
// Deregister MapPress' Google Maps
wp_dequeue_script( 'mappress-gmaps' );
// There's no cleaner way to add dependency to registered script, thus direct access to
// $wp_scripts. Append Divi's google maps handle to make MapPress' script depends on it
global $wp_scripts;
if ( isset( $wp_scripts->registered['mappress'] ) && ! in_array( 'google-maps-api', $wp_scripts->registered['mappress']->deps ) ) {
$wp_scripts->registered['mappress']->deps[] = 'google-maps-api';
}
}
}
}
new ET_Builder_Plugin_Compat_Mappress();

View File

@ -0,0 +1,65 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Max Mega Menu
*
* @since 4.4.5
*
* @link https://wordpress.org/plugins/megamenu/
*/
class ET_Builder_Plugin_Compat_Megamenu extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'megamenu/megamenu.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_get_widget_areas_list', array( $this, 'remove_sidebar' ) );
}
/**
* Remove Mega Menu sidebar from Builders widget areas list.
*
* @since 4.4.5
*
* @return void
*/
public function remove_sidebar( $list ) {
// This plugin creates a custom sidebar for convenience: widgets added
// to menus are also listed in Widgets WP Admin page and can be edited
// there.
// Such area can't be used by the Sidebar Module because only added
// when `is_admin() === true`, hence it would always show as empty when
// rendered by the FE.
// Additionally, it causes Builder to reload when cache is deleted
// ( eg due to enabling/disabling a plugin ).
// This is due to widget areas being included in static helpers and the
// list being different when generated inline (when the page is
// loading) or via the AJAX call: `is_admin` would be `false` in the
// first case and `true` in the latter.
unset( $list['mega-menu'] );
return $list;
}
}
new ET_Builder_Plugin_Compat_Megamenu();

View File

@ -0,0 +1,54 @@
<?php
/**
* Compatibility for Modern Events Calendar Lite.
*
* @package Divi
* @subpackage Builder
* @since 4.10.6
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for Modern Events Calendar Lite.
*
* @since 4.10.6
*
* @link https://wordpress.org/plugins/modern-events-calendar-lite/
*/
class ET_Builder_Plugin_Compat_Modern_Events_Calendar_Lite extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.6
*/
public function __construct() {
$this->plugin_id = 'modern-events-calendar-lite/modern-events-calendar-lite.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.6
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
// Modern Events Calendar Lite JS code is:
// 1. Added everywhere.
// 2. Not compatible with JQuery Body feature.
// Only way to solve is to always disable the latter when the plugin is active.
add_filter( 'et_builder_enable_jquery_body', '__return_false' );
}
}
new ET_Builder_Plugin_Compat_Modern_Events_Calendar_Lite();

View File

@ -0,0 +1,65 @@
<?php
/**
* Compatibility for NEX-Forms.
*
* @package Divi
* @subpackage Builder
* @since 4.10.8
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for NEX-Forms.
*
* @since 4.10.8
*
* @link https://wordpress.org/plugins/nex-forms-express-wp-form-builder/
*/
class ET_Builder_Plugin_Compat_NEX_Forms extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.8
*/
public function __construct() {
$this->plugin_id = 'nex-forms-express-wp-form-builder/main.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.8
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_enable_jquery_body', array( $this, 'maybe_disable_jquery_body' ), 10, 2 );
}
/**
* Maybe Disable JQuery Body feature.
*
* @since 4.10.8
*
* @param bool $enabled Whether the feature should be enabled or not.
* @param string $content TB/Post content.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled, $content ) {
// Disable when enqueued or `NEXForms` shortcode is used.
return false !== strpos( $content, '[NEXForms' ) ? false : $enabled;
}
}
new ET_Builder_Plugin_Compat_NEX_Forms();

View File

@ -0,0 +1,64 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Paid Membership Pro
*
* @since 3.20.2
*
* @link https://wordpress.org/plugins/paid-memberships-pro/
*/
class ET_Builder_Plugin_Compat_PaidMembershipProp extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'paid-memberships-pro/paid-memberships-pro.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
if ( ! function_exists( 'pmpro_wp' ) ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
if ( $enabled['vb'] || $enabled['bfb'] ) {
// Override plugin's redirection code.
remove_action( 'wp', 'pmpro_wp', 1 );
add_action( 'wp', array( $this, 'wp' ), 1 );
}
}
/**
* Disable plugin redirections when VB/BFB page and current user can edit.
*
* @return void
*/
public function wp() {
global $post;
if ( ! ( $post && current_user_can( 'edit_post', $post->ID ) ) ) {
// Perform redirections anyway when current user cannot edit the page.
pmpro_wp();
}
}
}
new ET_Builder_Plugin_Compat_PaidMembershipProp();

View File

@ -0,0 +1,59 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Photo Gallery
*
* @since 3.21.3
*/
class ET_Builder_Plugin_Compat_PhotoGallery extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'photo-gallery/photo-gallery.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
if ( ! method_exists( 'BWG', 'instance' ) ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
// I know what you're thinking .... can't check for 'edit_post' because too early
// and don't have a post ID yet but will do inside the filter.
if ( $enabled['vb'] && ! $enabled['bfb'] && current_user_can( 'edit_posts' ) ) {
add_action( 'wp', array( $this, 'wp' ) );
}
}
/**
* Disable plugin's TinyMCE custom button because it doesn't work in VB
*
* @access public.
* @return void
*/
public function wp() {
global $post;
if ( $post && current_user_can( 'edit_post', $post->ID ) ) {
remove_filter( 'media_buttons_context', array( BWG::instance(), 'media_button' ) );
}
}
}
new ET_Builder_Plugin_Compat_PhotoGallery();

View File

@ -0,0 +1,65 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for PilotPress Views
*
* @since 3.21.1
*
* @link https://wordpress.org/plugins/pilotpress/
*/
class ET_Builder_Plugin_Compat_PilotPress extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'pilotpress/pilotpress.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
// I know what you're thinking .... can't check for 'edit_post' because too early
// and don't have a post ID yet but will do inside the filter.
if ( ( $enabled['vb'] || $enabled['bfb'] ) && current_user_can( 'edit_posts' ) ) {
// Plugin's content filter breaks VB / BFB, disable it
add_action( 'pilotpress_content_hiding', array( $this, 'pilotpress_content_hiding' ) );
}
}
/**
* Remove plugin's custom content filter.
*
* @return void
*/
public function pilotpress_content_hiding() {
global $pilotpress, $post;
if ( $pilotpress && $post && current_user_can( 'edit_post', $post->ID ) ) {
remove_filter( 'the_content', array( $pilotpress, 'content_process' ) );
}
}
}
new ET_Builder_Plugin_Compat_PilotPress();

View File

@ -0,0 +1,149 @@
<?php
/**
* ET_Builder_Plugin_Compat_Popup_Maker class file.
*
* @class ET_Builder_Plugin_Compat_Popup_Maker
* @package Builder
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for Popup Maker plugin.
*
* @since ??
*
* @link https://wordpress.org/plugins/popup-maker/
*/
class ET_Builder_Plugin_Compat_Popup_Maker extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since ??
*/
public function __construct() {
$this->plugin_id = 'popup-maker/popup-maker.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since ??
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'all_module_css_selector', array( $this, 'et_builder_maybe_update_module_styles_selector' ), 10, 4 );
add_filter( 'et_pb_set_style_selector', array( $this, 'et_builder_maybe_update_selector' ), 10, 4 );
add_filter( 'et_core_enqueued_style_handle', array( $this, 'et_builder_maybe_update_style_handle' ), 10, 4 );
// Disable Feature: Dynamic Assets.
add_filter( 'et_use_dynamic_css', array( $this, 'et_builder_disable_dynamic_features' ), 10, 4 );
add_filter( 'et_should_generate_dynamic_assets', array( $this, 'et_builder_disable_dynamic_features' ), 10, 4 );
// Disable Cache in Feature Manager.
add_filter( 'et_builder_post_feature_cache_enabled', array( $this, 'et_builder_disable_dynamic_features' ), 10, 4 );
}
/**
* Return false if Popup Maker is active to disable dynamic assets feature.
*
* @since ??
*
* @param bool $current_state Current state of the feature.
*
* @return string
*/
public function et_builder_disable_dynamic_features( $current_state ) {
// Should only be modified for Popup Maker plugin.
if ( ! class_exists( 'PUM_Shortcode_Popup' ) ) {
return $current_state;
}
return false;
}
/**
* Update Divi Builder selector for Popup Maker plugin.
* The purpose of this update is to make sure custom module styles applied to the content inside Popup Maker which placed outside the main page content and `#page-container` container
*
* @since ??
*
* @param string $selector Selector to modify.
*
* @return string
*/
public function et_builder_maybe_update_module_styles_selector( $selector ) {
// Selector should only be modified for Popup Maker plugin.
if ( ! class_exists( 'PUM_Shortcode_Popup' ) ) {
return $selector;
}
// Add 'body .pum-container' into selector along with existing 'body #page-container' to target the content inside Popup Maker.
if ( false !== strpos( $selector, 'body #page-container' ) ) {
// add the prefix for all the selectors in a string.
$pum_prefixed_selector = str_replace( 'body #page-container', 'body .pum-container', $selector );
$selector .= ', ' . $pum_prefixed_selector;
}
return $selector;
}
/**
* Update Divi Builder selector for Popup Maker plugin.
* The purpose of this update is to make sure custom module styles applied to the content inside Popup Maker which placed outside the main page content and `#et-boc` container
*
* @since ??
*
* @param string $selector Selector to modify.
*
* @return string
*/
public function et_builder_maybe_update_selector( $selector ) {
// Selector should only be modified for Popup Maker plugin.
if ( ! class_exists( 'PUM_Shortcode_Popup' ) ) {
return $selector;
}
// Add '.et-db .pum' into selector along with existing '.et-db #et-boc' to target the content inside Popup Maker.
if ( false !== strpos( $selector, '.et-db #et-boc' ) ) {
// add the prefix for all the selectors in a string.
$non_prefixed_selector = str_replace( '.et-db #et-boc', '.et-db .pum', $selector );
$selector .= ', ' . $non_prefixed_selector;
}
return $selector;
}
/**
* Update divi-style handle when replacing divi main style with the CPT style for Popup Maker plugin.
* The purpose of this update is to make sure Divi main style is loaded along with the CPT style
* Otherwise Content inside Popup Maker plugin loses styles because it's placed outside the main page content and `#et-boc` container
*
* @since ??
*
* @param string $handle Handle to modify.
*
* @return string
*/
public function et_builder_maybe_update_style_handle( $handle ) {
// Handle should only be modified for Popup Maker plugin and when it's `divi-style`.
if ( ! class_exists( 'PUM_Shortcode_Popup' ) || 'divi-style' !== $handle ) {
return $handle;
}
// Add suffix to make sure not prefixed divi-style won't be dequeued.
return $handle . '-pum';
}
}
new ET_Builder_Plugin_Compat_Popup_Maker();

View File

@ -0,0 +1,10 @@
<?php // phpcs:disable Squiz.Commenting.FileComment.Missing -- Not used in other compat classes.
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Load the same plugin compat class.
*/
require_once 'relevanssi.php';

View File

@ -0,0 +1,85 @@
<?php // phpcs:ignore WordPress.Files.FileName -- We don't follow WP filename format.
/**
* ET_Builder_Plugin_Compat_Relevanssi class file.
*
* @class ET_Builder_Plugin_Compat_Relevanssi
* @package Builder
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the Relevanssi plugin.
*
* @since 4.7.0
*
* @link https://wordpress.org/plugins/relevanssi/
*/
class ET_Builder_Plugin_Compat_Relevanssi extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.7.0
*/
public function __construct() {
$this->plugin_id = $this->_get_plugin_id();
$this->init_hooks();
}
/**
* Get the currently activated plugin id as the FREE and PRO versions are separate plugins.
*
* @since 4.9.4
*
* @return string
*/
protected function _get_plugin_id() {
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$pro = 'relevanssi-premium/relevanssi.php';
$free = 'relevanssi/relevanssi.php';
return is_plugin_active( $pro ) ? $pro : $free;
}
/**
* Hook methods to WordPress.
*
* @since 4.7.0
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_blog_query', array( $this, 'maybe_modify_blog_query' ) );
}
/**
* Maybe modify blog query to intercept the posts result.
*
* @since 4.7.0
*
* @param WP_Query $query Main blog query.
*
* @return WP_Query Modified blog query.
*/
public function maybe_modify_blog_query( $query ) {
// Modify blog query when the current page is search result page.
if ( is_search() && function_exists( 'relevanssi_do_query' ) && $query->query_vars['s'] ) {
relevanssi_do_query( $query );
}
return $query;
}
}
new ET_Builder_Plugin_Compat_Relevanssi();

View File

@ -0,0 +1,5 @@
jQuery( function ( $ ) {
$( '.learndash-wrapper .ld-focus header.et-l.et-l--header, .learndash-wrapper .ld-focus footer.et-l.et-l--footer' ).css( {
'display': 'none',
} );
} );

View File

@ -0,0 +1,58 @@
(function($) {
$(() => {
$('body').on('click', '.js-wpml-translate-link', function() {
const $this = $(this);
const url = $this.attr('href');
if (! url) {
return;
}
// Bail early if current layout has translation.
if (! url.startsWith('post-new')) {
return;
}
// Find translation language ID and trid.
const langIds = url.match(/lang\=(\w+)&/);
const langId = langIds && 'undefined' !== typeof langIds[1] ? langIds[1] : '';
const trids = url.match(/trid\=(\w+)&/);
const trid = trids && 'undefined' !== typeof trids[1] ? trids[1] : '';
if (! langId || ! trid) {
return false;
}
const thisElement = $this.html();
$this.html('<span class="spinner et-builder-wpml-compat-spinner" style="visibility: visible; margin: 0;"></span>');
$.ajax({
type: 'POST',
url: et_builder_wpml_compat_options.ajaxurl,
dataType: 'json',
data: {
action: 'et_builder_wpml_translate_layout',
nonce: et_builder_wpml_compat_options.nonces.et_builder_wpml_translate_layout,
translation_trid: trid,
translation_lang_id: langId,
},
})
.done(result => {
if ('undefined' !== typeof result) {
if (result.success && 'undefined' !== typeof result.data) {
window.location.href = _.unescape(result.data.edit_layout_link);
}
}
$this.html(thisElement);
})
.fail(data => {
console.log(data.responseText);
$this.html(thisElement);
});
return false;
});
});
})(jQuery);

View File

@ -0,0 +1,218 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the Rank Math SEO plugin.
*
* @since 4.4.2
*
* @link https://wordpress.org/plugins/seo-by-rank-math/
*/
class ET_Builder_Plugin_Compat_Rank_Math_SEO extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.4.2
*/
public function __construct() {
$this->plugin_id = 'seo-by-rank-math/rank-math.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.4.2
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'rank_math/sitemap/urlimages', array( $this, 'get_module_images' ), 10, 2 );
}
/**
* Add Divi builder module's images to Rank Math sitemap.
*
* @since 4.4.2
*
* @param array $images Existing images.
* @param int $post_id
* @return array
*/
public function get_module_images( $images, $post_id ) {
$post = get_post( absint( $post_id ) );
if ( ! $post ) {
return $images;
}
// All Divi modules with image. And the image is generated into img tag, not
// as background or overlay. Mostly, those modules have alt field setting.
$modules_with_image = array(
'et_pb_image' => true,
'et_pb_fullwidth_image' => true,
'et_pb_blurb' => array(
'src' => 'image',
),
'et_pb_team_member' => array(
'src' => 'image_url',
),
'et_pb_menu' => array(
'src' => 'logo',
),
'et_pb_fullwidth_menu' => array(
'src' => 'logo',
),
'et_pb_slide' => array(
'src' => 'image',
),
'et_pb_fullwidth_header' => array(
'logo' => array(
'src' => 'logo_image_url',
'title' => 'logo_title',
'alt' => 'logo_alt_text',
),
'header' => array(
'src' => 'header_image_url',
'title' => 'image_title',
'alt' => 'image_alt_text',
),
),
);
foreach ( $modules_with_image as $module_name => $module_attrs ) {
// Find all modules shortcodes with image from the content.
$modules = $this->_get_module_shortcode( $post->post_content, $module_name );
if ( empty( $modules ) ) {
continue;
}
foreach ( $modules as $module ) {
// Don't add if the image and its attributes empty.
$new_images = $this->_get_image_attrs( $module, $module_attrs );
if ( ! empty( $new_images ) ) {
$images = array_merge( $images, $new_images );
}
}
}
// Gallery modules is different with the other modules with image because
// the images are saved as ID. So, we need to fetch the IDs first then loop
// through the IDs to get source, title text, and alt text.
$galleries = $this->_get_module_shortcode( $post->post_content, 'et_pb_gallery' );
if ( ! empty( $galleries ) ) {
foreach ( $galleries as $gallery ) {
// Find gallery ids, if it doesn't exist, skip the process.
$gallery_ids = $this->_get_image_attr( $gallery, 'gallery_ids' );
$gallery_ids = explode( ',', $gallery_ids );
if ( empty( $gallery_ids ) ) {
continue;
}
foreach ( $gallery_ids as $gallery_id ) {
$image_attrs = array();
// Find image source, if it doesn't exist, skip the process.
$src_values = wp_get_attachment_image_src( $gallery_id, 'full' );
$src_value = et_()->array_get( $src_values, '0' );
if ( empty( $src_value ) ) {
continue;
}
$image_attrs['src'] = esc_url( $src_value );
// Find image title text. In our Gallery module, alt text uses the
// same title text from the attachment. Keep it here for consistency.
$title_value = get_the_title( $gallery_id );
if ( ! empty( $title_value ) ) {
$image_attrs['title'] = esc_attr( $title_value );
$image_attrs['alt'] = esc_attr( $title_value );
}
$images[] = $image_attrs;
}
}
}
return $images;
}
/**
* Get module shortcode from post content.
*
* @since 4.4.2
*
* @param string $content
* @param string $module
* @return string
*/
private function _get_module_shortcode( $content, $module ) {
preg_match_all( '/\[' . $module . '[^]]*]/', $content, $module_values );
return et_()->array_get( $module_values, '0' );
}
/**
* Get image attributes value and collect them as an array. Attributes list:
* source URL, title text, and alternative text.
*
* @since 4.4.2
*
* @param string $module
* @param array $module_attrs
* @return array
*/
private function _get_image_attrs( $module, $module_attrs ) {
$images = array();
$types = true !== $module_attrs && ! isset( $module_attrs['src'] ) ? $module_attrs : array( $module_attrs );
foreach ( $types as $type_attrs ) {
$image_attrs = array();
// Find image source, if it doesn't exist, skip the process.
$src_attr = et_()->array_get( $type_attrs, 'src', 'src' );
$src_value = $this->_get_image_attr( $module, $src_attr );
if ( empty( $src_value ) ) {
continue;
}
$image_attrs['src'] = esc_url( $src_value );
$title_attr = et_()->array_get( $type_attrs, 'title', 'title_text' );
$title_value = $this->_get_image_attr( $module, $title_attr );
if ( ! empty( $title_value ) ) {
$image_attrs['title'] = esc_attr( $title_value );
}
$alt_attr = et_()->array_get( $type_attrs, 'alt', 'alt' );
$alt_value = $this->_get_image_attr( $module, $alt_attr );
if ( ! empty( $alt_value ) ) {
$image_attrs['alt'] = esc_attr( $alt_value );
}
$images[] = $image_attrs;
}
return $images;
}
/**
* Get image attribute value from the module shortcode.
*
* @since 4.4.2
*
* @param string $content
* @param string $attr
* @return string
*/
private function _get_image_attr( $content, $attr ) {
preg_match( '/' . $attr . '="([^"]*)"/', $content, $attr_values );
return et_()->array_get( $attr_values, '1' );
}
}
new ET_Builder_Plugin_Compat_Rank_Math_SEO();

View File

@ -0,0 +1,164 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for the LearnDash plugin.
*
* @since 4.3.4
*
* @link https://www.learndash.com/
*/
class ET_Builder_Plugin_Compat_LearnDash extends ET_Builder_Plugin_Compat_Base {
/**
* Original `in_the_loop` property value for the layouts.
*
* @var array
*/
protected $_in_the_loop = array();
/**
* Constructor.
*
* @since 4.3.4
*/
public function __construct() {
$this->plugin_id = 'sfwd-lms/sfwd_lms.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.3.4
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'learndash-focus-header-before', array( $this, 'fire_learndash_compatibility_action' ) );
add_action( 'learndash-focus-template-start', array( $this, 'maybe_inject_theme_builder_header' ) );
add_action( 'learndash-focus-template-end', array( $this, 'maybe_inject_theme_builder_footer' ) );
add_action( 'et_theme_builder_template_before_body', array( $this, 'maybe_override_query_before_body' ), 10, 3 );
add_action( 'et_theme_builder_template_after_body', array( $this, 'maybe_override_query_after_body' ), 10, 3 );
add_action( 'wp_enqueue_scripts', array( $this, 'focus_mode_compatibility_script' ), 99 );
}
/**
* Maybe override `$wp_query` temporarily before TB layout body template.
*
* @since 4.7.4
*
* @param integer $layout_id TB layout post ID (header, body, footer).
* @param boolean $layout_enabled Current layout status whether is enabled or not.
* @param integer $template_id TB template post ID (parent of TB layout).
*/
public function maybe_override_query_before_body( $layout_id, $layout_enabled, $template_id ) {
if ( ! $layout_enabled || ! function_exists( 'learndash_get_post_types' ) ) {
return;
}
if ( ! in_array( get_post_type(), learndash_get_post_types(), true ) ) {
return;
}
global $wp_query;
// Save current value as reference for later usage.
$this->_in_the_loop[ $layout_id ] = $wp_query->in_the_loop;
// Force the query to be treated as a loop (fake loop).
$wp_query->in_the_loop = true;
}
/**
* Maybe restore `$wp_query` after TB layout body template rendered.
*
* @since 4.7.4
*
* @param integer $layout_id TB layout post ID (header, body, footer).
* @param boolean $layout_enabled Current layout status whether is enabled or not.
* @param integer $template_id TB template post ID (parent of TB layout).
*/
public function maybe_override_query_after_body( $layout_id, $layout_enabled, $template_id ) {
if ( ! $layout_enabled || ! function_exists( 'learndash_get_post_types' ) ) {
return;
}
if ( ! in_array( get_post_type(), learndash_get_post_types(), true ) ) {
return;
}
global $wp_query;
// Restore `in_the_loop` property to original state.
$wp_query->in_the_loop = et_()->array_get( $this->_in_the_loop, $layout_id, false );
}
/**
* Disable TB hooks for Divi and Extra.
*
* @since 4.3.4
*/
public function fire_learndash_compatibility_action() {
/**
* Fires when LearnDash Focus mode is enabled for the current request.
*
* @since 4.3.4
*/
do_action( 'et_theme_builder_compatibility_learndash_focus_mode' );
}
/**
* Maybe inject the TB header back in.
*
* @since 4.3.4
*/
public function maybe_inject_theme_builder_header() {
$layouts = et_theme_builder_get_template_layouts();
if ( empty( $layouts ) ) {
return;
}
et_theme_builder_frontend_render_header(
$layouts[ ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE ]['id'],
$layouts[ ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE ]['enabled'],
$layouts[ ET_THEME_BUILDER_TEMPLATE_POST_TYPE ]
);
}
/**
* Maybe inject the TB footer back in.
*
* @since 4.3.4
*/
public function maybe_inject_theme_builder_footer() {
$layouts = et_theme_builder_get_template_layouts();
if ( empty( $layouts ) ) {
return;
}
et_theme_builder_frontend_render_footer(
$layouts[ ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE ]['id'],
$layouts[ ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE ]['enabled'],
$layouts[ ET_THEME_BUILDER_TEMPLATE_POST_TYPE ]
);
}
/**
* Focus Mode compatibility for global header and footer.
*/
public function focus_mode_compatibility_script() {
wp_enqueue_script( 'et-builder-sfwd-lms-compat-scripts', ET_BUILDER_URI . '/plugin-compat/scripts/sfwd-lms.js', array( 'jquery' ), ET_BUILDER_VERSION, true );
}
}
new ET_Builder_Plugin_Compat_LearnDash();

View File

@ -0,0 +1,85 @@
<?php
/**
* Plugin compatibility for Siteground Optimizer.
*
* @package Divi
* @subpackage Builder
* @since 4.11.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Plugin compatibility for SiteGround Optimizer
*
* @since 4.11.0
*
* @link https://wordpress.org/plugins/sg-cachepress/
*/
class ET_Builder_Plugin_Compat_SiteGround_Optimizer extends ET_Builder_Plugin_Compat_Base {
/**
* Stylesheet handle.
*
* @var null
*/
private $_stylesheet_handle = null;
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'sg-cachepress/sg-cachepress.php';
$this->_stylesheet_handle = ET_Dynamic_Assets::init()->get_style_css_handle();
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @return void
*/
public function init_hooks() {
if ( ! is_plugin_active( $this->plugin_id ) ) {
return;
}
add_filter( 'sgo_css_combine_exclude', array( $this, 'exclude_inline_styles_from_siteground_cache' ) );
}
/**
* Exclude styles from being combined in SiteGround cache.
*
* @param array $excluded_stylesheets Excluded styles from being combined.
*/
public function exclude_inline_styles_from_siteground_cache( $excluded_stylesheets ) {
global $shortname;
$is_critical_enabled = apply_filters( 'et_builder_critical_css_enabled', false );
// If Critical CSS is enabled, we don't need to process further.
if ( $is_critical_enabled ) {
return $excluded_stylesheets;
}
$style_prefix = 'divi-builder';
if ( 'divi' === $shortname ) {
$style_prefix = 'divi';
} elseif ( 'extra' === $shortname ) {
$style_prefix = 'extra';
}
$style_prefix = $style_prefix . '-dynamic';
return array_merge(
$excluded_stylesheets,
array( $this->_stylesheet_handle, $style_prefix )
);
}
}
new ET_Builder_Plugin_Compat_SiteGround_Optimizer();

View File

@ -0,0 +1,56 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for siteorigin-panels
*
* @since 0.7 (builder version)
* @link https://wordpress.org/plugins/siteorigin-panels/
*/
class ET_Builder_Plugin_Compat_Siteorigin_Panels extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'siteorigin-panels/siteorigin-panels.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Note: once this issue is fixed in future version, run version_compare() to limit the scope of the hooked fix
* Latest plugin version: 2.4.21
*
* @return void
*/
private function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Up to: latest theme version
add_action( 'siteorigin_panels_filter_content_enabled', array( $this, 'disable_siteorigin_builder_content' ) );
}
/**
* If Divi Builder is used, disable siteorigin builder content alteration
*
* @return bool
*/
function disable_siteorigin_builder_content( $status ) {
global $post;
if ( isset( $post->ID ) && et_pb_is_pagebuilder_used( $post->ID ) ) {
$status = false;
// Remove Site Origin Builder's Live Editor Admin Menu if builder active on current page
remove_action( 'admin_bar_menu', 'siteorigin_panels_live_edit_link', 100 );
}
return $status;
}
}
new ET_Builder_Plugin_Compat_Siteorigin_Panels();

View File

@ -0,0 +1,351 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WPML Multilingual CMS
*
* @since 3.0.64
*
* @link https://wpml.org
*/
class ET_Builder_Plugin_Compat_WPML_Multilingual_CMS extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'sitepress-multilingual-cms/sitepress.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 3.7.1
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_admin_scripts' ) );
// Override the configuration
add_action( 'wpml_config_array', array( $this, 'override_wpml_configuration' ) );
add_filter(
'et_pb_module_shortcode_attributes',
array( $this, '_filter_traslate_shop_module_categories_ids' ),
10,
5
);
// Override the language code used in the AJAX request that checks if
// cached definitions/helpers needs to be updated.
add_filter( 'et_fb_current_page_params', array( $this, 'override_current_page_params' ) );
// Override suppress_filters argument when accessing library layouts,
add_filter( 'et_pb_show_all_layouts_suppress_filters', '__return_true' );
// Handle Divi Library Layout translation process.
add_action( 'wp_ajax_et_builder_wpml_translate_layout', array( $this, 'translate_layout' ) );
add_filter( 'wp_insert_post_empty_content', array( $this, 'maybe_allow_save_empty_content' ), 10, 2 );
}
/**
* @param array $config
*
* @return array
*/
function override_wpml_configuration( $config ) {
if ( ! empty( $config['wpml-config']['custom-fields']['custom-field'] ) ) {
$missing_fields = array(
array(
'value' => '_et_pb_built_for_post_type',
'attr' => array(
'action' => 'copy',
),
),
);
$seen = array();
$fields = $config['wpml-config']['custom-fields']['custom-field'];
foreach ( $fields as $field ) {
$seen[ $field['value'] ] = true;
}
foreach ( $missing_fields as $field ) {
if ( empty( $seen[ $field['value'] ] ) ) {
// The missing field is really missing, let's add it
$fields[] = $field;
}
}
$config['wpml-config']['custom-fields']['custom-field'] = $fields;
}
if ( ! empty( $config['wpml-config']['taxonomies']['taxonomy'] ) ) {
$taxonomy_replacements = array(
'scope' => array(
'translate' => 0,
),
'layout_type' => array(
'translate' => 0,
),
'module_width' => array(
'translate' => 0,
),
'layout_category' => array(
'translate' => 1,
),
);
$fixed_taxonomies = array();
$taxonomies = $config['wpml-config']['taxonomies']['taxonomy'];
foreach ( $taxonomies as $taxonomy ) {
if ( ! empty( $taxonomy_replacements[ $taxonomy['value'] ] ) ) {
// Replace attributes
$taxonomy['attr'] = $taxonomy_replacements[ $taxonomy['value'] ];
}
$fixed_taxonomies[] = $taxonomy;
}
$config['wpml-config']['taxonomies']['taxonomy'] = $fixed_taxonomies;
}
return $config;
}
/**
* Convert selected categories ids to translated ones.
*
* @internal
*
* @param array $shortcode_atts
* @param array $atts
* @param string $slug
* @param string $address
*
* @return array
**/
public function _filter_traslate_shop_module_categories_ids( $shortcode_atts, $atts, $slug, $address ) {
if (
! is_admin() && $slug === 'et_pb_shop'
&&
! empty( $shortcode_atts['type'] )
&&
$shortcode_atts['type'] === 'product_category'
&&
! empty( $shortcode_atts['include_categories'] )
) {
$cats_array = explode( ',', $shortcode_atts['include_categories'] );
$new_ids = array();
foreach ( $cats_array as $cat_id ) {
$translated_cat_id = apply_filters( 'wpml_object_id', $cat_id, 'product_cat' );
$new_ids[] = ! empty( $translated_cat_id ) ? $translated_cat_id : $cat_id;
}
$shortcode_atts['include_categories'] = implode( ',', $new_ids );
}
return $shortcode_atts;
}
/**
* Override the language code used in the AJAX request that checks if
* cached definitions/helpers needs to be updated.
*
* @param array $params
*
* @return array
*/
public function override_current_page_params( $params ) {
$langCode = apply_filters( 'wpml_current_language', false );
if ( $langCode ) {
$params['langCode'] = $langCode;
}
return $params;
}
/**
* Enqueues admin related scripts and styles for WPML compatiblity.
*
* @since 4.5.7
*/
public function maybe_enqueue_admin_scripts() {
global $typenow;
if ( 'et_pb_layout' === $typenow ) {
wp_enqueue_script( 'et-builder-wpml-compat-scripts', ET_BUILDER_URI . '/plugin-compat/scripts/sitepress-multilingual-cms.js', array( 'jquery', 'lodash' ), ET_BUILDER_VERSION, true );
wp_localize_script(
'et-builder-wpml-compat-scripts',
'et_builder_wpml_compat_options',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonces' => array(
'et_builder_wpml_translate_layout' => wp_create_nonce( 'et_builder_wpml_translate_layout' ),
),
)
);
}
}
/**
* Translate library layout on the background.
*
* @since 4.5.7
*/
public function translate_layout() {
et_builder_security_check( 'divi_library', 'edit_posts', 'et_builder_wpml_translate_layout', 'nonce' );
// phpcs:disable WordPress.Security.NonceVerification -- Already verified by et_builder_security_check
$translation_trid = (int) sanitize_text_field( et_()->array_get( $_POST, 'translation_trid' ) );
$translation_lang_id = sanitize_text_field( et_()->array_get( $_POST, 'translation_lang_id' ) );
// phpcs:enable
if ( empty( $translation_trid ) || empty( $translation_lang_id ) ) {
wp_send_json_error(
array(
'message' => 'Incorrect translation group or language ID.',
)
);
}
$element_type = apply_filters( 'wpml_element_type', ET_BUILDER_LAYOUT_POST_TYPE );
$translation_details = apply_filters( 'wpml_get_element_translations', null, $translation_trid, $element_type );
$original_layout_id = '';
// Find original layout ID.
if ( ! empty( $translation_details ) ) {
foreach ( $translation_details as $translation_detail ) {
$translation_original = isset( $translation_detail->original ) ? $translation_detail->original : '';
$translation_element_id = isset( $translation_detail->element_id ) ? $translation_detail->element_id : '';
if ( '1' === $translation_original ) {
$original_layout_id = $translation_element_id;
break;
}
}
}
if ( empty( $original_layout_id ) ) {
wp_send_json_error(
array(
'message' => 'No translation found.',
)
);
}
// Meta.
$meta_values = array();
$meta_keys = array(
'_et_pb_row_layout',
'_et_pb_module_type',
'_et_pb_excluded_global_options',
'_et_pb_built_for_post_type',
);
foreach ( $meta_keys as $meta_key ) {
$meta_value = get_post_meta( $original_layout_id, $meta_key, true );
if ( ! empty( $meta_value ) ) {
$meta_values[ $meta_key ] = $meta_value;
}
}
// Taxonomy.
$tax_values = array();
$tax_args = array( 'fields' => 'names' );
$tax_keys = array(
'scope',
'layout_type',
'module_width',
);
foreach ( $tax_keys as $tax_key ) {
$terms = get_the_terms( $original_layout_id, $tax_key );
if ( is_wp_error( $terms ) ) {
continue;
}
// Only expect the last term to be saved here.
foreach ( $terms as $term ) {
$tax_values[ $tax_key ] = $term->slug;
}
}
// 1. Create new layout based on meta and taxonomy of original layout.
$translation_layout_id = et_pb_create_layout( '', '', $meta_values, $tax_values );
if ( is_wp_error( $translation_layout_id ) ) {
wp_send_json_error(
array(
'message' => 'Failed to create translation layout.',
)
);
}
// Translation Details.
$original_language_args = array(
'element_id' => $original_layout_id,
'element_type' => ET_BUILDER_LAYOUT_POST_TYPE,
);
$original_language_info = apply_filters( 'wpml_element_language_details', null, $original_language_args );
$translation_language_args = array(
'element_id' => $translation_layout_id,
'element_type' => $element_type,
'trid' => $original_language_info->trid,
'language_code' => $translation_lang_id,
'source_language_code' => $original_language_info->language_code,
);
// 2. Set the new layout as translation of the original layout.
do_action( 'wpml_set_element_language_details', $translation_language_args );
wp_send_json_success(
array(
'original_layout_id' => $original_layout_id,
'translation_layout_id' => $translation_layout_id,
'edit_layout_link' => esc_url_raw( get_edit_post_link( $translation_layout_id ) ),
)
);
}
/**
* Allow library layout with empty title and content to be inserted as new post for
* translation purpose.
*
* @since 4.5.7
*
* @param bool $maybe_empty Original status.
* @param array $postarr Array of post data.
*/
public function maybe_allow_save_empty_content( $maybe_empty, $postarr ) {
$post_status = et_()->array_get( $postarr, 'post_status' );
$post_type = et_()->array_get( $postarr, 'post_type' );
if ( $maybe_empty && ET_BUILDER_LAYOUT_POST_TYPE === $post_type && 'publish' === $post_status ) {
return false;
}
return $maybe_empty;
}
}
new ET_Builder_Plugin_Compat_WPML_Multilingual_CMS();

View File

@ -0,0 +1,51 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Table Of Contents Plus
*
* @since 3.0.89
*
* @link https://wordpress.org/plugins/table-of-contents-plus/
*/
class ET_Builder_Plugin_Compat_Table_Of_Contents_Plus extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'table-of-contents-plus/toc.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1601
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Do not render plugin shortcodes in admin
add_filter( 'et_pb_admin_excluded_shortcodes', array( $this, 'et_pb_admin_excluded_shortcodes' ) );
}
/**
* @param array $config
*
* @return array
*/
function et_pb_admin_excluded_shortcodes( $shortcodes ) {
$shortcodes[] = 'toc';
return $shortcodes;
}
}
new ET_Builder_Plugin_Compat_Table_Of_Contents_Plus();

View File

@ -0,0 +1,65 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for The Events Calendar Community Events plugin.
*
* @since 4.4.9
*
* @link https://theeventscalendar.com/
*/
class ET_Builder_Plugin_Compat_The_Events_Calendar_Community_Events extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.4.9
*/
public function __construct() {
$this->plugin_id = 'the-events-calendar-community-events/tribe-community-events.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.4.9
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'the_post', array( $this, 'maybe_restore_layout_content' ), 11, 2 );
}
/**
* Maybe restore TB layout content.
*
* Restore global $pages content on TB layouts when they override the template.
*
* @param WP_Post $post
*
* @return void
*/
function maybe_restore_layout_content( $post ) {
if ( ! et_theme_builder_is_layout_post_type( $post->post_type ) ) {
return;
}
if ( ! et_theme_builder_overrides_layout( $post->post_type ) ) {
return;
}
global $pages;
$pages = array( $post->post_content );
}
}
new ET_Builder_Plugin_Compat_The_Events_Calendar_Community_Events();

View File

@ -0,0 +1,171 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for The Events Calendar plugin.
*
* @since 3.10
*
* @link https://wordpress.org/plugins/the-events-calendar/
*/
class ET_Builder_Plugin_Compat_The_Events_Calendar extends ET_Builder_Plugin_Compat_Base {
public $actual_post_query;
public $spoofed_post_query;
/**
* Constructor.
*
* @since 3.10
*/
public function __construct() {
$this->plugin_id = 'the-events-calendar/the-events-calendar.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
* Latest plugin version: 4.6.19
*
* @todo once this issue is fixed in future version, run version_compare() to limit the scope of the hooked fix
*
* @since 3.10
* @since 4.4.6 Bump loop_start hook priority to cover post hijacking issue.
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_action( 'wp', array( $this, 'register_spoofed_post_fix' ) );
add_action( 'loop_start', array( $this, 'maybe_disable_post_spoofing' ), 1001 );
add_filter( 'wp_insert_post_empty_content', array( $this, 'maybe_allow_save_empty_content' ), 10, 2 );
add_filter( 'et_builder_enable_jquery_body', array( $this, 'maybe_disable_jquery_body' ) );
}
/**
* Disable JQuery Body feature when showing calendar.
*
* @since 4.10.5
*
* @param bool $enabled Whether the feature should be enabled or not.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled ) {
return is_post_type_archive( 'tribe_events' ) ? false : $enabled;
}
/**
* The Events Calendar register Tribe__Events__Templates::maybeSpoofQuery() on wp_head (100) hook
* which modifies global $posts. This modified post object breaks anything that came after wp_head
* until the spoofed post is fixed. Anything that relies on $post global value on body_class is affected
* (ie Divi's hide nav until scroll because it adds classname to <body> to work)
*
* @since 3.10
*
* @return void
*/
function register_spoofed_post_fix() {
// Bail if global $post doesn't exist for some reason. Just to be safe.
if ( ! isset( $GLOBALS['post'] ) ) {
return;
}
// Only apply spoofed post fix if builder is used in custom post type page
if ( ! et_builder_post_is_of_custom_post_type( get_the_ID() ) || ! et_pb_is_pagebuilder_used( get_the_ID() ) ) {
return;
}
// Get actual $post query before Tribe__Events__Templates::maybeSpoofQuery() modifies it
$this->actual_post_query = $GLOBALS['post'];
// Return spoofed $post into its actual post then re-return it into spoofed post object
add_action( 'et_layout_body_class_before', array( $this, 'fix_post_query' ) );
add_action( 'et_layout_body_class_after', array( $this, 'respoofed_post_query' ) );
}
/**
* Return spoofed $post into its actual post so anything that relies to $post object works as expected
*
* @since 3.10
*
* @return void
*/
function fix_post_query() {
// Bail if global $post doesn't exist for some reason. Just to be safe.
if ( ! isset( $GLOBALS['post'] ) ) {
return;
}
$this->spoofed_post_query = $GLOBALS['post'];
$GLOBALS['post'] = $this->actual_post_query; // phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited
}
/**
* Re-return actual $post object into spoofed post so The Event Calendar works as expected
*
* @since 3.10
*
* @return void
*/
function respoofed_post_query() {
$GLOBALS['post'] = $this->spoofed_post_query; // phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited
}
/**
* Maybe disable post spoofing when a TB body layout is used.
*
* @since 4.2.2
* @since 4.4.6 Maybe disable post hijacking on Page Template v2.
*/
function maybe_disable_post_spoofing() {
if ( et_theme_builder_overrides_layout( ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE ) ) {
remove_action( 'the_post', array( 'Tribe__Events__Templates', 'spoof_the_post' ) );
// Ensure to check the class and tribe() method exists. Method tribe() is used
// to return an instance of the class and resolve the object.
if ( class_exists( '\Tribe\Events\Views\V2\Template\Page' ) && function_exists( 'tribe' ) ) {
$page = tribe( \Tribe\Events\Views\V2\Template\Page::class );
remove_action( 'the_post', array( $page, 'hijack_the_post' ), 25 );
}
}
}
/**
* Allow event with empty title to update post and trigger save_post action when
* activating BFB for the first time. So, event post meta can be saved as well.
*
* @since 4.4.4
*
* @param bool $maybe_empty Original status.
* @param array $postarr Array of post data.
*/
public function maybe_allow_save_empty_content( $maybe_empty, $postarr ) {
$post_action = et_()->array_get( $postarr, 'action' );
$post_id = et_()->array_get( $postarr, 'post_ID', 0 );
$post_status = et_()->array_get( $postarr, 'post_status' );
$post_origin_status = et_()->array_get( $postarr, 'original_post_status' );
$post_type = et_()->array_get( $postarr, 'post_type' );
// Ensure to override the status only on very first BFB activation and
// limited for tribe_events post type only.
$is_edit_action = 'editpost' === $post_action;
$is_builder_used = et_pb_is_pagebuilder_used( $post_id );
$is_post_draft = 'draft' === $post_status && 'auto-draft' === $post_origin_status;
$is_post_event = 'tribe_events' === $post_type;
if ( $is_edit_action && $is_builder_used && $is_post_draft && $is_post_event ) {
return false;
}
return $maybe_empty;
}
}
new ET_Builder_Plugin_Compat_The_Events_Calendar();

View File

@ -0,0 +1,47 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WordPress Toolbar Publish Button
*/
class ET_Builder_Plugin_Compat_Toolber_Publish_Button extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'toolbar-publish-button/toolbar-publish-button.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_fb_ignore_adminbar_click_ids', array( $this, 'et_fb_ignore_adminbar_click_ids' ) );
}
/**
* Add this plugin `publish` button to ignored Admin Bar click ids.
*
* @param array $ids Ignored Admin Bar click ids.
*
* @access public.
* @return array
*/
public function et_fb_ignore_adminbar_click_ids( $ids ) {
$ids[] = 'top-toolbar-submit';
return $ids;
}
}
new ET_Builder_Plugin_Compat_Toolber_Publish_Button();

View File

@ -0,0 +1,65 @@
<?php
/**
* Compatibility for PayPal Plus for WooCommerce.
*
* @package Divi
* @subpackage Builder
* @since 4.10.8
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for PayPal Plus for WooCommerce.
*
* @since 4.10.8
*
* @link https://wordpress.org/plugins/woo-paypalplus/
*/
class ET_Builder_Plugin_Compat_Woo_PayPal_Plus extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.8
*/
public function __construct() {
$this->plugin_id = 'woo-paypalplus/paypalplus-woocommerce.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.8
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found.
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_enable_jquery_body', array( $this, 'maybe_disable_jquery_body' ), 10, 2 );
}
/**
* Maybe Disable JQuery Body feature.
*
* @since 4.10.8
*
* @param bool $enabled Whether the feature should be enabled or not.
* @param string $content TB/Post content.
*
* @return bool
*/
public function maybe_disable_jquery_body( $enabled, $content ) {
// Disable when plugin scripts are enqueued.
return wp_script_is( 'ppplus' ) ? false : $enabled;
}
}
new ET_Builder_Plugin_Compat_Woo_PayPal_Plus();

View File

@ -0,0 +1,359 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WooCommerce
*
* @since 3.0.65 (builder version)
* @link https://wordpress.org/plugins/woocommerce/
*/
class ET_Builder_Plugin_Compat_WooCommerce extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'woocommerce/woocommerce.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Latest plugin version: 3.1.1
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found or needed functions do not exist
if (
! $this->get_plugin_version() ||
! function_exists( 'is_cart' ) ||
! function_exists( 'is_account_page' )
) {
return;
}
// Up to: latest theme version
add_filter( 'et_grab_image_setting', array( $this, 'disable_et_grab_image_setting' ), 1 );
// Hook before calling comments_template function in module.
add_action( 'et_fb_before_comments_template', array( $this, 'remove_filter_comments_number_by_woo' ) );
add_action( 'et_builder_before_comments_number', array( $this, 'remove_filter_comments_number_by_woo' ) );
// Hook afer calling comments_template function in module.
add_action( 'et_fb_after_comments_template', array( $this, 'restore_filter_comments_number_by_woo' ) );
add_action( 'et_builder_after_comments_number', array( $this, 'restore_filter_comments_number_by_woo' ) );
// Prevent malformed html in demo store notice from breaking the VB.
add_filter( 'woocommerce_demo_store', 'et_core_fix_unclosed_html_tags' );
// Dynamic Content
add_filter( 'et_builder_dynamic_content_display_hidden_meta_keys', array( $this, 'filter_dynamic_content_display_hidden_meta_keys' ), 10, 2 );
add_filter( 'et_builder_dynamic_content_custom_field_label', array( $this, 'filter_dynamic_content_custom_field_label' ), 10, 2 );
add_filter( 'et_builder_dynamic_content_meta_value', array( $this, 'maybe_filter_dynamic_content_meta_value' ), 10, 3 );
if ( is_object( WC() ) && is_object( WC()->structured_data ) ) {
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
if ( ( $enabled['vb'] || $enabled['bfb'] ) ) {
// Hook generates JSON-LD which is used by some search engines but it's not needed in VB/BFB
// and it also breaks inline generation of static definitions.
remove_action( 'woocommerce_single_product_summary', array( WC()->structured_data, 'generate_product_data' ), 60 );
}
}
// Theme Builder.
add_filter( 'et_theme_builder_template_settings_options', array( $this, 'maybe_filter_theme_builder_template_settings_options' ) );
add_action( 'et_theme_builder_after_layout_opening_wrappers', array( $this, 'maybe_trigger_woo_hooks_in_theme_builder_body' ) );
}
/**
* When an order is cancelled, WooCommerce cart shortcode changes the order status to prevent
* the 'Your order was cancelled.' notice from being shown multiple times.
* Since grab_image renders shortcodes twice, it must be disabled in the cart page or else the notice
* will not be shown at all.
* My Account Page and Checkout Page is also affected by the same issue.
*
* @return bool
*/
function disable_et_grab_image_setting( $settings ) {
return ( is_cart() || is_checkout() || is_account_page() ) ? false : $settings;
}
/**
* Remove comments_number filter added by Woo that caused missing comment
* count in Comment module
*
* @return void
*/
public function remove_filter_comments_number_by_woo() {
if ( ! current_theme_supports( 'woocommerce' ) || ( function_exists( 'wc_get_page_id' ) && wc_get_page_id( 'shop' ) < 0 ) ) {
remove_filter( 'comments_number', '__return_empty_string' );
}
}
/**
* Restore comments_number that removed by remove_filter_comments_number_by_woo
*
* @return void
*/
public function restore_filter_comments_number_by_woo() {
if ( ! current_theme_supports( 'woocommerce' ) || ( function_exists( 'wc_get_page_id' ) && wc_get_page_id( 'shop' ) < 0 ) ) {
add_filter( 'comments_number', '__return_empty_string' );
}
}
/**
* Allowlist hidden WooCommerce meta keys for dynamic content.
*
* @since 3.17.2
*
* @param string[] $meta_keys
* @param integer $post_id
*
* @return string[]
*/
public function filter_dynamic_content_display_hidden_meta_keys( $meta_keys, $post_id ) {
return array_merge(
$meta_keys,
array(
'_stock_status',
'_regular_price',
'_sale_price',
)
);
}
/**
* Rename label of known displayed hidden post meta fields in dynamic content.
*
* @since 3.17.2
*
* @param string $label
* @param string $key
*
* @return string
*/
public function filter_dynamic_content_custom_field_label( $label, $key ) {
$custom_labels = array(
'total_sales' => esc_html__( 'Product Total Sales', 'et_builder' ),
'_stock_status' => esc_html__( 'Product Stock Status', 'et_builder' ),
'_regular_price' => esc_html__( 'Product Regular Price', 'et_builder' ),
'_sale_price' => esc_html__( 'Product Sale Price', 'et_builder' ),
);
if ( isset( $custom_labels[ $key ] ) ) {
return $custom_labels[ $key ];
}
return $label;
}
/**
* Format WooCommerce meta values accordingly.
*
* @since 3.17.2
*
* @param string $meta_value
* @param string $meta_key
* @param integer $post_id
*
* @return string
*/
public function maybe_filter_dynamic_content_meta_value( $meta_value, $meta_key, $post_id ) {
switch ( $meta_key ) {
case '_stock_status':
// Check for function existance just in case
if ( function_exists( 'wc_get_product_stock_status_options' ) ) {
$stock_statuses = wc_get_product_stock_status_options();
// Format meta value into human readable format
if ( ! empty( $stock_statuses[ $meta_value ] ) ) {
$meta_value = esc_html( $stock_statuses[ $meta_value ] );
}
}
break;
}
return $meta_value;
}
/**
* Add Theme Builder template settings options.
*
* @since 4.0
*
* @param array $options
*
* @return array
*/
public function maybe_filter_theme_builder_template_settings_options( $options ) {
$woocommerce_options = array(
'woocommerce' => array(
'label' => esc_html__( 'WooCommerce Pages', 'et_builder' ),
'settings' => array(
array(
'id' => 'woocommerce:shop',
'label' => esc_html__( 'Shop', 'et_builder' ),
'title' => trim( str_replace( home_url(), '', get_post_type_archive_link( 'product' ) ), '/' ),
'priority' => 120,
'validate' => array( $this, 'theme_builder_validate_woocommerce_shop' ),
),
array(
'id' => 'woocommerce:cart',
'label' => esc_html__( 'Cart', 'et_builder' ),
'title' => get_post_field( 'post_name', wc_get_page_id( 'cart' ) ),
'priority' => 120,
'validate' => array( $this, 'theme_builder_validate_woocommerce_cart' ),
),
array(
'id' => 'woocommerce:checkout',
'label' => esc_html__( 'Checkout', 'et_builder' ),
'title' => get_post_field( 'post_name', wc_get_page_id( 'checkout' ) ),
'priority' => 120,
'validate' => array( $this, 'theme_builder_validate_woocommerce_checkout' ),
),
array(
'id' => 'woocommerce:my_account',
'label' => esc_html__( 'My Account', 'et_builder' ),
'title' => get_post_field( 'post_name', wc_get_page_id( 'myaccount' ) ),
'priority' => 130,
'validate' => array( $this, 'theme_builder_validate_woocommerce_my_account' ),
),
),
),
);
$archive_index = array_search( 'archive', array_keys( $options ) );
if ( false === $archive_index ) {
return array_merge(
$options,
$woocommerce_options
);
}
return array_merge(
array_slice( $options, 0, $archive_index + 1, true ),
$woocommerce_options,
array_slice( $options, $archive_index + 1, null, true )
);
}
/**
* Theme Builder: Validate woocommerce:shop.
*
* @since 4.0
*
* @param string $type
* @param string $subtype
* @param integer $id
* @param string[] $setting
*
* @return bool
*/
public function theme_builder_validate_woocommerce_shop( $type, $subtype, $id, $setting ) {
return (
( ET_Theme_Builder_Request::TYPE_POST_TYPE_ARCHIVE === $type && $subtype === 'product' )
||
( ET_Theme_Builder_Request::TYPE_SINGULAR === $type && $id === wc_get_page_id( 'shop' ) )
);
}
/**
* Theme Builder: Validate woocommerce:cart.
*
* @since 4.0
*
* @param string $type
* @param string $subtype
* @param integer $id
* @param string[] $setting
*
* @return bool
*/
public function theme_builder_validate_woocommerce_cart( $type, $subtype, $id, $setting ) {
return ET_Theme_Builder_Request::TYPE_SINGULAR === $type && $id === wc_get_page_id( 'cart' );
}
/**
* Theme Builder: Validate woocommerce:checkout.
*
* @since 4.0
*
* @param string $type
* @param string $subtype
* @param integer $id
* @param string[] $setting
*
* @return bool
*/
public function theme_builder_validate_woocommerce_checkout( $type, $subtype, $id, $setting ) {
return ET_Theme_Builder_Request::TYPE_SINGULAR === $type && $id === wc_get_page_id( 'checkout' );
}
/**
* Theme Builder: Validate woocommerce:my_account.
*
* @since 4.0
*
* @param string $type
* @param string $subtype
* @param integer $id
* @param string[] $setting
*
* @return bool
*/
public function theme_builder_validate_woocommerce_my_account( $type, $subtype, $id, $setting ) {
return ET_Theme_Builder_Request::TYPE_SINGULAR === $type && $id === wc_get_page_id( 'myaccount' );
}
/**
* Trigger Woo hooks before a Theme Builder body layout is rendered
* so stuff like structured data is output.
*
* @since 4.0.10
*
* @param string $layout_type
*/
public function maybe_trigger_woo_hooks_in_theme_builder_body( $layout_type ) {
global $product;
if ( ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE !== $layout_type || ! is_singular( 'product' ) ) {
return;
}
if ( $product && ! is_a( $product, 'WC_Product' ) ) {
// Required for Woo to setup its $product global.
the_post();
}
// Make sure builder and non-builder products do not render
// anything as this will be taken care of by the
// Post Content module in TB, if used.
et_builder_wc_disable_default_layout();
remove_action(
'woocommerce_after_single_product_summary',
'et_builder_wc_product_render_layout',
5
);
// Trigger the usual Woo hooks so functionality like structured data works.
do_action( 'woocommerce_before_single_product' );
if ( ! post_password_required() ) {
do_action( 'woocommerce_before_single_product_summary' );
do_action( 'woocommerce_single_product_summary' );
do_action( 'woocommerce_after_single_product_summary' );
do_action( 'woocommerce_after_single_product' );
}
}
}
new ET_Builder_Plugin_Compat_WooCommerce();

View File

@ -0,0 +1,60 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WordPress MU Domain Mapping
*/
class ET_Builder_Plugin_Compat_Mu_Domain_Mapping extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'wordpress-mu-domain-mapping/domain_mapping.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* @return void
*/
function init_hooks() {
if ( ! function_exists( 'redirect_to_mapped_domain' ) ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
// I know what you're thinking .... can't check for 'edit_post' because too early
// and don't have a post ID yet but will do inside the filter.
if ( ( $enabled['vb'] || $enabled['bfb'] ) && current_user_can( 'edit_posts' ) ) {
// Override plugin's redirection code.
remove_action( 'template_redirect', 'redirect_to_mapped_domain' );
add_action( 'template_redirect', array( $this, 'redirect' ) );
}
}
/**
* Disable plugin redirections when VB/BFB page and current user can edit.
*
* @return void
*/
public function redirect() {
global $post;
if ( ! ( $post && current_user_can( 'edit_post', $post->ID ) ) ) {
// Perform redirections anyway when current user cannot edit the page.
redirect_to_mapped_domain();
}
}
}
new ET_Builder_Plugin_Compat_Mu_Domain_Mapping();

View File

@ -0,0 +1,96 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Yoast SEO
*
* @since 3.0.76 (builder version)
* @link https://wordpress.org/plugins/wordpress-seo/
*/
class ET_Builder_Plugin_Compat_WordPress_SEO extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'wordpress-seo/wp-seo.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
* Latest plugin version: 3.1.1
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
// Enable Sitemap Cache
add_filter( 'wpseo_enable_xml_sitemap_transient_caching', '__return_true' );
add_filter( 'pre_get_posts', array( $this, 'maybe_load_builder_modules_early' ), 0 );
add_filter( 'wpseo_indexable_excluded_post_types', array( $this, 'exclude_tb_post_types' ), 0 );
}
/**
* Checks to see if the current request is for a sitemap and if so, loads the builder's
* modules so that they are loaded before Yoast generates the sitemap.
* {@see 'pre_get_posts' (0) Must run before Yoast's callback which has priority of 1.}
*
* @param WP_Query $query
*/
public function maybe_load_builder_modules_early( $query ) {
if ( ! $query->is_main_query() ) {
return;
}
if ( ! get_query_var( 'xsl' ) && ! get_query_var( 'sitemap' ) ) {
return;
}
remove_action( 'wp', 'et_builder_init_global_settings', 9 );
remove_action( 'wp', 'et_builder_add_main_elements' );
add_filter( 'wpseo_sitemap_content_before_parse_html_images', array( $this, 'do_shortcode' ) );
}
/**
* Exclude TB post types from indexable posts.
*
* @param array $post_types Post Types.
*
* @return array;
*/
public function exclude_tb_post_types( $post_types ) {
$tb_post_types = array(
ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE,
ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE,
ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE,
);
return array_merge( $post_types, $tb_post_types );
}
public function do_shortcode( $content ) {
// Check if content includes ET shortcode.
if ( false === strpos( $content, '[et_pb_section' ) ) {
// None found, bye.
return $content;
}
// Load modules (only once).
if ( ! did_action( 'et_builder_ready' ) ) {
et_builder_init_global_settings();
et_builder_add_main_elements();
}
// Render the shortcode.
return apply_filters( 'the_content', $content );
}
}
new ET_Builder_Plugin_Compat_WordPress_SEO();

View File

@ -0,0 +1,92 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WP Job Manager.
*
* @since 4.0.10
*
* @link https://wordpress.org/plugins/wp-job-manager/
*/
class ET_Builder_Plugin_Compat_WPJobManager extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.0.10
*/
public function __construct() {
$this->plugin_id = 'wp-job-manager/wp-job-manager.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress.
* Latest plugin version: 1.33.3
*
* @since 4.0.10
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'option_job_manager_hide_expired_content', array( $this, 'never_hide_content_in_builder' ) );
add_filter( 'wpjm_the_job_description', array( $this, 'maybe_call_the_content' ) );
}
/**
* Always show the content even for expired jobs when editing in the builder.
*
* @since 4.0.10
*
* @param mixed $hide
*
* @return boolean
*/
public function never_hide_content_in_builder( $hide ) {
if ( et_core_is_fb_enabled() ) {
return false;
}
return $hide;
}
/**
* Maybe trigger the_content() instead of returning the description as the plugin
* does not call the_content().
* Do this only if the builder is used for the current post.
*
* @since 4.0.10
*
* @param string $content
*
* @return string
*/
public function maybe_call_the_content( $content ) {
static $output = false;
if ( ! $output && et_core_is_builder_used_on_current_request() ) {
if ( doing_action( 'wp_footer' ) ) {
// Do not use the full content when outputting structured data.
return truncate_post( apply_filters( 'excerpt_length', 55 ), false );
}
$output = true;
the_content();
return '';
}
return $content;
}
}
new ET_Builder_Plugin_Compat_WPJobManager();

View File

@ -0,0 +1,53 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WP Responsive Table.
*
* @since 4.4.0
*
* @link https://wordpress.org/plugins/wp-responsive-table/
*/
class ET_Builder_Plugin_Compat_WPResponsiveTable extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'wp-responsive-table/wp-responsive-table.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1.2.4
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_render_layout', array( $this, 'add_content_wrapper' ) );
}
/**
* Equivalent of ResponsiveTable\Frontend\Frontend::addContentWrapper().
* We have no sensible way to get the instance reference and run its method
* so we just add the container it would've added manually.
*
* @since 4.4.0
*
* @param string $content
*
* @return string
*/
public function add_content_wrapper( $content ) {
return '<div class="wprt-container">' . $content . '</div>';
}
}
new ET_Builder_Plugin_Compat_WPResponsiveTable();

View File

@ -0,0 +1,10 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Load the same plugin compat class.
*/
require_once 'wp-smushit.php';

View File

@ -0,0 +1,195 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Smush
*
* @since 3.17.1
*
* @link https://wordpress.org/plugins/wp-smushit/
*/
class ET_Builder_Plugin_Compat_Smush extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = $this->_get_plugin_id();
$this->init_hooks();
}
/**
* Get the currently activated plugin id as the FREE and PRO versions are separate plugins.
*
* @since 4.0.5
*
* @return string
*/
protected function _get_plugin_id() {
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$pro = 'wp-smush-pro/wp-smush.php';
$free = 'wp-smushit/wp-smush.php';
return is_plugin_active( $pro ) ? $pro : $free;
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1601
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
'tb' => et_()->array_get( $_GET, 'et_tb' ),
// phpcs:enable
);
add_filter( 'wp_smush_should_skip_parse', array( $this, 'maybe_skip_parse' ), 11 );
if ( $enabled['vb'] || $enabled['bfb'] || $enabled['tb'] ) {
// Plugin's `enqueue` function will cause a PHP notice unless
// early exit is forced using the following custom filter
add_filter( 'wp_smush_enqueue', '__return_false' );
$class = $this->get_smush_class();
if ( ! empty( $class ) ) {
// @phpcs:ignore Generic.PHP.ForbiddenFunctions.Found
$mod = call_user_func( array( $class, 'get_instance' ) )->core()->mod;
$props = get_object_vars( $mod );
if ( isset( $props['lazy'] ) ) {
// In Smush 3.3+, lazy loading enqueues and inlines several
// scripts but the instance is public so we can get a
// reference and remove the enqueuing action.
remove_action( 'wp_enqueue_scripts', array( $props['lazy'], 'enqueue_assets' ) );
} else {
// The lazy loading instance is private in Smush 3.2.* so
// we dequeue the script it enqueues as those versions
// only load a single script.
add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_lazy_load' ) );
}
}
}
add_filter( 'et_core_page_resource_get_data', array( $this, 'maybe_get_background_images_cdn' ), 10, 3 );
}
/**
* Disable Smush page parsing in VB.
*
* @param boolean $skip
*
* @return boolean
*/
public function maybe_skip_parse( $skip ) {
if ( et_core_is_fb_enabled() ) {
return true;
}
return $skip;
}
/**
* Get the base Smush class name.
*
* @since 4.0.3
*
* @return string
*/
public function get_smush_class() {
$classes = array(
'WP_Smush',
// @since 3.3.0
'Smush\\WP_Smush',
);
foreach ( $classes as $test ) {
if ( class_exists( $test ) ) {
return $test;
}
}
return '';
}
/**
* Dequeue Smush lazy load in builder.
*
* @since 4.0.10
*/
public function dequeue_lazy_load() {
if ( wp_script_is( 'smush-lazy-load', 'enqueued' ) ) {
wp_dequeue_script( 'smush-lazy-load' );
}
}
/**
* Maybe convert background images local URL inside the styles into CDN before it's
* saved as static resource.
*
* @since 4.4.9
*
* @param array $data_resource
* @param string $context
* @param ET_Core_PageResource $page_resource
*
* @return string
*/
public function maybe_get_background_images_cdn( $data_resource, $context, $page_resource ) {
// Bail early if the context is not 'file' or the data resource is empty or resource
// is not unified (single post & builder is being used).
if ( 'file' !== $context || empty( $data_resource ) || ! strpos( $page_resource->slug, 'unified' ) ) {
return $data_resource;
}
if ( ! class_exists( '\Smush\Core\Settings' ) || ! class_exists( '\Smush\Core\Modules\Helpers\Parser' ) ) {
return $data_resource;
}
$smush_settings = Smush\Core\Settings::get_instance();
$cdn = $smush_settings->get( 'cdn' );
$background_images = $smush_settings->get( 'background_images' );
// Both of CDN and Background Images modules should be activated.
if ( ! $cdn || ! $background_images ) {
return $data_resource;
}
$new_data_resource = $data_resource;
$smush_parser = new Smush\Core\Modules\Helpers\Parser();
$smush_parser->enable( 'cdn' );
$smush_parser->enable( 'background_images' );
// Converting background images local URL into CDN.
foreach ( $data_resource as $priority => $data_part ) {
$new_data_part = array();
foreach ( $data_part as $data ) {
$new_data_part[] = $smush_parser->parse_page( $data );
}
$new_data_resource[ $priority ] = $new_data_part;
}
return $new_data_resource;
}
}
new ET_Builder_Plugin_Compat_Smush();

View File

@ -0,0 +1,120 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for Toolset Views
*
* @since 3.20
*
* @link https://toolset.com
*/
class ET_Builder_Plugin_Compat_ToolsetViews extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
public function __construct() {
$this->plugin_id = 'wp-views/wp-views.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 2.7.1
*
* @return void
*/
public function init_hooks() {
// Bail if there's no version found
if ( ! $this->get_plugin_version() ) {
return;
}
add_filter( 'et_builder_post_types', array( $this, 'add_post_type' ) );
add_filter( 'et_builder_third_party_post_types', array( $this, 'add_post_type' ) );
add_filter( 'et_builder_third_party_unqueriable_post_types', array( $this, 'add_post_type' ) );
$enabled = array(
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
'vb' => et_()->array_get( $_GET, 'et_fb' ),
'bfb' => et_()->array_get( $_GET, 'et_bfb' ),
// phpcs:enable
);
if ( $enabled['vb'] && ! $enabled['bfb'] ) {
// Fields and Views custom TinyMCE button doesn't work in VB and also generate an error.
add_action( 'toolset_editor_add_form_buttons', '__return_false' );
}
// I know what you're thinking .... can't check for 'edit_post' because too early
// and don't have a post ID yet but will do inside the filter.
if ( $enabled['vb'] && $enabled['bfb'] && current_user_can( 'edit_posts' ) ) {
// Content templates not using Divi break the BFB, disable them.
add_filter( 'get_post_metadata', array( $this, 'disable_views' ), 10, 4 );
}
add_filter( 'et_builder_render_layout', array( $this, 'transform_shortcodes' ), 4 );
}
/**
* Add `view-template` post type.
*
* @param array $types
* @return array
*/
public function add_post_type( $types ) {
return array_merge( $types, array( 'view-template' ) );
}
/**
* Disable Views for a post.
*
* @param null|array|string $value The value get_metadata() should return - a single metadata value,
* or an array of values.
* @param int $object_id Object ID.
* @param string $meta_key Meta key.
* @param bool $single Whether to return only the first value of the specified $meta_key.
*
* @access public.
* @return void
*/
public function disable_views( $value, $object_id, $meta_key, $single ) {
if ( '_views_template' === $meta_key && current_user_can( 'edit_post', $object_id ) ) {
return false;
}
return $value;
}
/**
* Transform {!{ ... }!} shortcodes to [] ones.
*
* @since 4.0.10
*
* @param string $content
*
* @return string
*/
public function transform_shortcodes( $content ) {
/**
* @see WPV_Frontend_Render_Filters::pre_process_shortcodes()
*
* @param string $content
*/
$content = apply_filters( 'wpv-pre-process-shortcodes', $content );
/**
* @see Toolset_Shortcode_Transformer::replace_shortcode_placeholders_with_brackets()
*
* @param string $content
*/
$content = apply_filters( 'toolset_transform_shortcode_format', $content );
return $content;
}
}
new ET_Builder_Plugin_Compat_ToolsetViews();

View File

@ -0,0 +1,49 @@
<?php
/**
* Compatibility for WP3D Models.
*
* @package Divi
* @subpackage Builder
* @since 4.10.8
*/
if ( ! defined( 'ABSPATH' ) ) {
// Exit if accessed directly.
exit;
}
/**
* Compatibility for WP3D Models.
*
* @since 4.10.8
*
* @link https://wp3dmodels.com/
*/
class ET_Builder_Plugin_Compat_WP3D_Models extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor.
*
* @since 4.10.8
*/
public function __construct() {
$this->init_hooks();
}
/**
* Hook methods to WordPress.
*
* @since 4.10.8
*
* @return void
*/
public function init_hooks() {
// No version check here is intentional: the plugin is very niche, commercial only,
// expensive and they ignored my request to provide a copy so that I could fix the issue.
// Due the above, we don't know the complete slug.
// However, by checking customer's site, we know for sure that folder is name `wp3d-models`
// and that's enough to detect the plugin and disable JQuery Body.
add_filter( 'et_builder_enable_jquery_body', '__return_false', 10, 2 );
}
}
new ET_Builder_Plugin_Compat_WP3D_Models();

View File

@ -0,0 +1,61 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Plugin compatibility for WPML Sticky Links. This plugin needs WPML Multilingual
* CMS plugin to work.
*
* @since 4.4.5
*
* @link https://wpml.org
*/
class ET_Builder_Plugin_Compat_WPML_Sticky_Links extends ET_Builder_Plugin_Compat_Base {
/**
* Constructor
*/
function __construct() {
$this->plugin_id = 'wpml-sticky-links/plugin.php';
$this->init_hooks();
}
/**
* Hook methods to WordPress
*
* Latest plugin version: 1.5.1
*
* @return void
*/
function init_hooks() {
// Bail if there's no version found or no WPML Multilingual CMS plugin active.
if ( ! $this->get_plugin_version() || ! defined( 'ICL_PLUGIN_PATH' ) ) {
return;
}
add_filter( 'et_pb_module_content', array( $this, 'maybe_show_permalinks' ), 10, 3 );
}
/**
* Convert sticky links into permalinks on Global items.
*
* @since 4.4.5
*
* @param string $content
* @param array $props
* @param array $attrs
* @return string
*/
public function maybe_show_permalinks( $content, $props, $attrs ) {
$global_module_id = et_()->array_get( $attrs, 'global_module' );
if ( empty( $global_module_id ) || ! class_exists( 'WPML_Sticky_Links' ) ) {
return $content;
}
$sticky_links = new WPML_Sticky_Links();
return $sticky_links->show_permalinks( $content );
}
}
new ET_Builder_Plugin_Compat_WPML_Sticky_Links();