version 4.13.0
This commit is contained in:
4
includes/builder/_et_builder_version.php
Normal file
4
includes/builder/_et_builder_version.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
// Note, this will be updated automatically during grunt release task
|
||||
$ET_BUILDER_VERSION = '3.17.3';
|
1525
includes/builder/ab-testing.php
Normal file
1525
includes/builder/ab-testing.php
Normal file
File diff suppressed because it is too large
Load Diff
347
includes/builder/api/DiviExtension.php
Normal file
347
includes/builder/api/DiviExtension.php
Normal file
@ -0,0 +1,347 @@
|
||||
<?php
|
||||
/**
|
||||
* Divi extension base class.
|
||||
*
|
||||
* @package Builder
|
||||
* @subpackage API
|
||||
* @since 4.6.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement the Divi Extension.
|
||||
*/
|
||||
class DiviExtension {
|
||||
|
||||
/**
|
||||
* Utility class instance.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var ET_Core_Data_Utils
|
||||
*/
|
||||
protected static $_;
|
||||
|
||||
/**
|
||||
* Dependencies for the extension's JavaScript bundles.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var array {
|
||||
* JavaScript Bundle Dependencies
|
||||
*
|
||||
* @type string[] $builder Dependencies for the builder bundle
|
||||
* @type string[] $frontend Dependencies for the frontend bundle
|
||||
* }
|
||||
*/
|
||||
protected $_bundle_dependencies = array();
|
||||
|
||||
/**
|
||||
* Builder bundle data
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_builder_js_data = array();
|
||||
|
||||
/**
|
||||
* Frontend bundle data
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_frontend_js_data = array();
|
||||
|
||||
/**
|
||||
* Whether or not the extension's debug mode is enabled. This should always be enabled
|
||||
* during development and never be enabled in production.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_debug;
|
||||
|
||||
/**
|
||||
* The gettext domain for the extension's translations.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $gettext_domain;
|
||||
|
||||
/**
|
||||
* The extension's WP Plugin name.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Absolute path to the extension's directory.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plugin_dir;
|
||||
|
||||
/**
|
||||
* The extension's directory URL.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plugin_dir_url;
|
||||
|
||||
/**
|
||||
* The extension's version.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* DiviExtension constructor.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param string $name This Divi Extension's WP Plugin name/slug.
|
||||
* @param array $args Argument flexibility for child classes.
|
||||
*/
|
||||
public function __construct( $name = '', $args = array() ) {
|
||||
if ( ! self::$_ ) {
|
||||
self::$_ = ET_Core_Data_Utils::instance();
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
if ( $this->name ) {
|
||||
$this->_initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues minified, production javascript bundles.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
protected function _enqueue_bundles() {
|
||||
// Frontend Bundle.
|
||||
$bundle_url = "{$this->plugin_dir_url}scripts/frontend-bundle.min.js";
|
||||
|
||||
wp_enqueue_script( "{$this->name}-frontend-bundle", $bundle_url, $this->_bundle_dependencies['frontend'], $this->version, true );
|
||||
|
||||
if ( et_core_is_fb_enabled() ) {
|
||||
// Builder Bundle.
|
||||
$bundle_url = "{$this->plugin_dir_url}scripts/builder-bundle.min.js";
|
||||
|
||||
wp_enqueue_script( "{$this->name}-builder-bundle", $bundle_url, $this->_bundle_dependencies['builder'], $this->version, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues non-minified, hot reloaded javascript bundles.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
protected function _enqueue_debug_bundles() {
|
||||
// Frontend Bundle.
|
||||
$site_url = wp_parse_url( get_site_url() );
|
||||
$hot_bundle_url = "{$site_url['scheme']}://{$site_url['host']}:3000/static/js/frontend-bundle.js";
|
||||
|
||||
wp_enqueue_script( "{$this->name}-frontend-bundle", $hot_bundle_url, $this->_bundle_dependencies['frontend'], $this->version, true );
|
||||
|
||||
if ( et_core_is_fb_enabled() ) {
|
||||
// Builder Bundle.
|
||||
$hot_bundle_url = "{$site_url['scheme']}://{$site_url['host']}:3000/static/js/builder-bundle.js";
|
||||
|
||||
wp_enqueue_script( "{$this->name}-builder-bundle", $hot_bundle_url, $this->_bundle_dependencies['builder'], $this->version, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues minified (production) or non-minified (hot reloaded) backend styles.
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
protected function _enqueue_backend_styles() {
|
||||
if ( $this->_debug ) {
|
||||
$site_url = wp_parse_url( get_site_url() );
|
||||
$backend_styles_url = "{$site_url['scheme']}://{$site_url['host']}:3000/styles/backend-style.css";
|
||||
} else {
|
||||
$extension_dir_path = plugin_dir_path( $this->plugin_dir );
|
||||
$backend_styles_path = "{$extension_dir_path}styles/backend-style.min.css";
|
||||
$backend_styles_url = "{$this->plugin_dir_url}styles/backend-style.min.css";
|
||||
|
||||
// Ensure backend style CSS file exists on production.
|
||||
if ( ! file_exists( $backend_styles_path ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Backend Styles - VB.
|
||||
wp_enqueue_style( "{$this->name}-backend-styles", $backend_styles_url, array(), $this->version );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets initial value of {@see self::$_bundle_dependencies}.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
protected function _set_bundle_dependencies() {
|
||||
/**
|
||||
* Builder script handle name
|
||||
*
|
||||
* @since 3.??
|
||||
*
|
||||
* @param string
|
||||
*/
|
||||
|
||||
$this->_bundle_dependencies = array(
|
||||
'builder' => array( 'react-dom', "{$this->name}-frontend-bundle" ),
|
||||
'frontend' => array( 'jquery', et_get_combined_script_handle() ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@see self::$_debug} based on the extension's global DEBUG constant.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
protected function _set_debug_mode() {
|
||||
$name_parts = explode( '_', get_class( $this ) );
|
||||
$prefix = strtoupper( $name_parts[0] );
|
||||
$debug = $prefix . '_DEBUG';
|
||||
|
||||
$this->_debug = defined( $debug ) && constant( $debug );
|
||||
|
||||
if ( $this->_debug && ! DiviExtensions::register_debug_mode( $this ) ) {
|
||||
$this->_debug = false;
|
||||
|
||||
et_error( "You're Doing It Wrong! Only one Divi Extension can be in debug mode at a time." );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads custom modules when the builder is ready.
|
||||
*
|
||||
* @since 3.1
|
||||
* @deprecated ?? - Use {@see 'hook_et_builder_ready'} instead.
|
||||
*/
|
||||
public function hook_et_builder_modules_loaded() {
|
||||
$this->hook_et_builder_ready();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads custom modules when the builder is ready.
|
||||
* {@see 'et_builder_ready'}
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function hook_et_builder_ready() {
|
||||
if ( file_exists( trailingslashit( $this->plugin_dir ) . 'loader.php' ) ) {
|
||||
require_once trailingslashit( $this->plugin_dir ) . 'loader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs initialization tasks.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
protected function _initialize() {
|
||||
DiviExtensions::add( $this );
|
||||
|
||||
$this->_set_debug_mode();
|
||||
$this->_set_bundle_dependencies();
|
||||
|
||||
// Setup translations.
|
||||
load_plugin_textdomain( $this->gettext_domain, false, basename( $this->plugin_dir ) . '/languages' );
|
||||
|
||||
// Register callbacks.
|
||||
register_activation_hook( trailingslashit( $this->plugin_dir ) . $this->name . '.php', array( $this, 'wp_hook_activate' ) );
|
||||
register_deactivation_hook( trailingslashit( $this->plugin_dir ) . $this->name . '.php', array( $this, 'wp_hook_deactivate' ) );
|
||||
|
||||
add_action( 'et_builder_ready', array( $this, 'hook_et_builder_ready' ), 9 );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'wp_hook_enqueue_scripts' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_hook_enqueue_scripts' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs tasks when the plugin is activated.
|
||||
* {@see 'activate_$PLUGINNAME'}
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public function wp_hook_activate() {
|
||||
// Force the legacy backend builder to reload its template cache.
|
||||
// This ensures that custom modules are available for use right away.
|
||||
et_pb_force_regenerate_templates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs tasks when the plugin is deactivated.
|
||||
* {@see 'deactivate_$PLUGINNAME'}
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public function wp_hook_deactivate() {}
|
||||
|
||||
/**
|
||||
* Enqueues the extension's scripts and styles.
|
||||
* {@see 'wp_enqueue_scripts'}
|
||||
*
|
||||
* @since 3.1
|
||||
* @since 4.4.9 Added backend styles for handling custom builder styles.
|
||||
*/
|
||||
public function wp_hook_enqueue_scripts() {
|
||||
if ( $this->_debug ) {
|
||||
$this->_enqueue_debug_bundles();
|
||||
} else {
|
||||
$styles = et_is_builder_plugin_active() ? 'style-dbp' : 'style';
|
||||
$styles_url = "{$this->plugin_dir_url}styles/{$styles}.min.css";
|
||||
|
||||
wp_enqueue_style( "{$this->name}-styles", $styles_url, array(), $this->version );
|
||||
|
||||
$this->_enqueue_bundles();
|
||||
}
|
||||
|
||||
if ( et_core_is_fb_enabled() && ! et_builder_bfb_enabled() ) {
|
||||
$this->_enqueue_backend_styles();
|
||||
}
|
||||
|
||||
// Normalize the extension name to get actual script name. For example from 'divi-custom-modules' to `DiviCustomModules`.
|
||||
$extension_name = str_replace( ' ', '', ucwords( str_replace( '-', ' ', $this->name ) ) );
|
||||
|
||||
// Enqueue frontend bundle's data.
|
||||
if ( ! empty( $this->_frontend_js_data ) ) {
|
||||
wp_localize_script( "{$this->name}-frontend-bundle", "{$extension_name}FrontendData", $this->_frontend_js_data );
|
||||
}
|
||||
|
||||
// Enqueue builder bundle's data.
|
||||
if ( et_core_is_fb_enabled() && ! empty( $this->_builder_js_data ) ) {
|
||||
wp_localize_script( "{$this->name}-builder-bundle", "{$extension_name}BuilderData", $this->_builder_js_data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the extension's scripts and styles for admin area.
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
public function admin_hook_enqueue_scripts() {
|
||||
if ( et_builder_bfb_enabled() || et_builder_is_tb_admin_screen() ) {
|
||||
$this->_enqueue_backend_styles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
new DiviExtension();
|
123
includes/builder/api/DiviExtensions.php
Normal file
123
includes/builder/api/DiviExtensions.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* Extension API: DiviExtensions class.
|
||||
*
|
||||
* @package Builder
|
||||
* @subpackage API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Composite class to manage all Divi Extensions.
|
||||
*/
|
||||
class DiviExtensions {
|
||||
|
||||
/**
|
||||
* Utility class instance.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var ET_Core_Data_Utils
|
||||
*/
|
||||
protected static $_;
|
||||
|
||||
/**
|
||||
* The first extension to enable debug mode for itself. Only one Divi Extension can be in
|
||||
* debug mode at a time.
|
||||
*
|
||||
* @var DiviExtension
|
||||
*/
|
||||
protected static $_debugging_extension;
|
||||
|
||||
/**
|
||||
* List of all instances of the Divi Extension.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @var DiviExtension[] {
|
||||
* All current Divi Extension instances
|
||||
*
|
||||
* @type DiviExtension $name Instance
|
||||
* }
|
||||
*/
|
||||
private static $_extensions;
|
||||
|
||||
/**
|
||||
* Register a Divi Extension instance.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param DiviExtension $instance Instance.
|
||||
*/
|
||||
public static function add( $instance ) {
|
||||
if ( ! isset( self::$_extensions[ $instance->name ] ) ) {
|
||||
self::$_extensions[ $instance->name ] = $instance;
|
||||
} else {
|
||||
et_error( "A Divi Extension named {$instance->name} already exists!" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get one or all Divi Extension instances.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param string $name The extension name. Default: 'all'.
|
||||
*
|
||||
* @return DiviExtension|DiviExtension[]|null
|
||||
*/
|
||||
public static function get( $name = 'all' ) {
|
||||
if ( 'all' === $name ) {
|
||||
return self::$_extensions;
|
||||
}
|
||||
|
||||
return self::$_->array_get( self::$_extensions, $name, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the base `DiviExtension` class.
|
||||
*/
|
||||
public static function initialize() {
|
||||
self::$_ = ET_Core_Data_Utils::instance();
|
||||
|
||||
require_once ET_BUILDER_DIR . 'api/DiviExtension.php';
|
||||
|
||||
/**
|
||||
* Fires when the {@see DiviExtension} base class is available.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
do_action( 'divi_extensions_init' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not a Divi Extension is in debug mode.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_debugging_extension() {
|
||||
return ! is_null( self::$_debugging_extension );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register's an extension instance for debug mode if one hasn't already been registered.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param DiviExtension $instance Instance.
|
||||
*
|
||||
* @return bool Whether or not request was successful
|
||||
*/
|
||||
public static function register_debug_mode( $instance ) {
|
||||
if ( ! self::$_debugging_extension ) {
|
||||
self::$_debugging_extension = $instance;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DiviExtensions::initialize();
|
329
includes/builder/api/rest/BlockLayout.php
Normal file
329
includes/builder/api/rest/BlockLayout.php
Normal file
@ -0,0 +1,329 @@
|
||||
<?php
|
||||
/**
|
||||
* Rest API: Layout Block
|
||||
*
|
||||
* @package Divi
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for custom REST API endpoint for Divi Layout block.
|
||||
*/
|
||||
class ET_Api_Rest_Block_Layout {
|
||||
|
||||
/**
|
||||
* Instance of `ET_Api_Rest_Block_Layout`.
|
||||
*
|
||||
* @var ET_Api_Rest_Block_Layout
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* ET_Api_Rest_Block_Layout constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class instance
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return object class instance
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( null === self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register callback for Layout block REST API
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
public function register() {
|
||||
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register REST API routes for Layout block
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
'divi/v1',
|
||||
'get_layout_content',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array( $this, 'get_layout_content_callback' ),
|
||||
'args' => array(
|
||||
'id' => array(
|
||||
// using intval directly doesn't work, hence the custom callback.
|
||||
'sanitize_callback' => array( $this, 'sanitize_int' ),
|
||||
'validation_callback' => 'is_numeric',
|
||||
),
|
||||
'nonce' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'permission_callback' => array( $this, 'rest_api_layout_block_permission' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
'divi/v1',
|
||||
'block/layout/builder_edit_data',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array( $this, 'process_builder_edit_data' ),
|
||||
'args' => array(
|
||||
'action' => array(
|
||||
'sanitize_callback' => array( $this, 'sanitize_action' ), // update|delete|get.
|
||||
'validation_callback' => array( $this, 'validate_action' ),
|
||||
),
|
||||
'postId' => array(
|
||||
'sanitize_callback' => array( $this, 'sanitize_int' ),
|
||||
'validation_callback' => 'is_numeric',
|
||||
),
|
||||
'blockId' => array(
|
||||
'sanitize_callback' => 'sanitize_title',
|
||||
),
|
||||
'layoutContent' => array(
|
||||
'sanitize_callback' => 'wp_kses_post',
|
||||
),
|
||||
'nonce' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'permission_callback' => array( $this, 'rest_api_layout_block_permission' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get layout content based on given post ID
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return string|WP_Error
|
||||
*/
|
||||
public function get_layout_content_callback( WP_REST_Request $request ) {
|
||||
$post_id = $request->get_param( 'id' );
|
||||
$nonce = $request->get_param( 'nonce' );
|
||||
|
||||
// Action nonce check. REST API actually has checked for nonce at cookie sent on every
|
||||
// request and performed capability-based check. This check perform action-based nonce
|
||||
// check to strengthen the security
|
||||
// @see https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/.
|
||||
if ( ! wp_verify_nonce( $nonce, 'et_rest_get_layout_content' ) ) {
|
||||
return new WP_Error(
|
||||
'invalid_nonce',
|
||||
esc_html__( 'Invalid nonce', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// request has to have id param.
|
||||
if ( ! $post_id ) {
|
||||
return new WP_Error(
|
||||
'no_layout_id',
|
||||
esc_html__( 'No layout id found', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! isset( $post->post_content ) || ! $post->post_content ) {
|
||||
return new WP_Error(
|
||||
'no_layout_found',
|
||||
esc_html__( 'No valid layout content found.', 'et_builder' ),
|
||||
array(
|
||||
'status' => 404,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $post->post_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process /block/layout/builder_edit_data route request
|
||||
*
|
||||
* @param WP_Rest_Request $request Request to prepare items for.
|
||||
*
|
||||
* @return string|WP_Error
|
||||
* @since 4.1.0
|
||||
*/
|
||||
public function process_builder_edit_data( WP_Rest_Request $request ) {
|
||||
$post_id = $request->get_param( 'postId' );
|
||||
$block_id = $request->get_param( 'blockId' );
|
||||
$nonce = $request->get_param( 'nonce' );
|
||||
|
||||
// No post ID.
|
||||
if ( empty( $post_id ) ) {
|
||||
return new WP_Error(
|
||||
'no_post_id',
|
||||
esc_html__( 'No post id', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// No block ID.
|
||||
if ( empty( $block_id ) ) {
|
||||
return new WP_Error(
|
||||
'no_block_id',
|
||||
esc_html__( 'No block id', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Action nonce check. REST API actually has checked for nonce at cookie sent on every
|
||||
// request and performed capability-based check. This check perform action-based nonce
|
||||
// check to strengthen the security
|
||||
// @see https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/.
|
||||
if ( ! wp_verify_nonce( $nonce, 'et_rest_process_builder_edit_data' ) ) {
|
||||
return new WP_Error(
|
||||
'invalid_nonce',
|
||||
esc_html__( 'Invalid nonce', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$result = '';
|
||||
$post_meta_key = "_et_block_layout_preview_{$block_id}";
|
||||
|
||||
switch ( $request->get_param( 'action' ) ) {
|
||||
case 'get':
|
||||
$result = get_post_meta( $post_id, $post_meta_key, true );
|
||||
break;
|
||||
case 'update':
|
||||
$layout_content = $request->get_param( 'layoutContent' );
|
||||
|
||||
// No layout content.
|
||||
if ( empty( $layout_content ) ) {
|
||||
return new WP_Error(
|
||||
'no_layout_content',
|
||||
esc_html__( 'No layout content', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$saved_layout_content = get_post_meta( $post_id, $post_meta_key, true );
|
||||
|
||||
if ( ! empty( $saved_layout_content ) && $saved_layout_content === $layout_content ) {
|
||||
// If for some reason layout exist and identical to the one being sent, return
|
||||
// true because update_post_meta() returns false if it updates the meta key and
|
||||
// the value doesn't change.
|
||||
$result = true;
|
||||
} else {
|
||||
// Otherwise, attempt to save post meta and returns how it goes.
|
||||
$result = update_post_meta(
|
||||
$post_id,
|
||||
$post_meta_key,
|
||||
$layout_content
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'delete':
|
||||
$result = delete_post_meta( $post_id, $post_meta_key );
|
||||
break;
|
||||
default:
|
||||
return new WP_Error(
|
||||
'no_valid_action',
|
||||
esc_html__( 'No valid action found', 'et_builder' ),
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'result' => $result,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize int value
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param int|mixed $value Value.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sanitize_int( $value ) {
|
||||
return intval( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize request "action" argument
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param string $value Action value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_action( $value ) {
|
||||
return $this->validate_action( $value ) ? $value : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate request "action" argument
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param string $value Action value.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate_action( $value ) {
|
||||
$valid_builder_edit_data_actions = array(
|
||||
'get',
|
||||
'update',
|
||||
'delete',
|
||||
);
|
||||
|
||||
return in_array( $value, $valid_builder_edit_data_actions, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission callback for get layout permalink REST API endpoint
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rest_api_layout_block_permission() {
|
||||
return current_user_can( 'edit_posts' ) && et_pb_is_allowed( 'use_visual_builder' );
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize ET_Api_Rest_Block_Layout.
|
||||
ET_Api_Rest_Block_Layout::instance();
|
366
includes/builder/autoload.php
Normal file
366
includes/builder/autoload.php
Normal file
@ -0,0 +1,366 @@
|
||||
<?php
|
||||
/**
|
||||
* Register autoloader.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.6.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Autoloader for module fields.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload_fields( $class ) {
|
||||
// For multipart classnames.
|
||||
$class = str_replace( '_', '', $class );
|
||||
require_once "module/field/{$class}.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader for module helpers.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload_helpers( $class ) {
|
||||
// For multipart classnames.
|
||||
$class = str_replace( '_', '', $class );
|
||||
require_once "module/helpers/{$class}.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader for module motion helpers.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload_helpers_motion( $class ) {
|
||||
// For multipart classnames.
|
||||
$class = str_replace( '_', '', $class );
|
||||
require_once "module/helpers/motion/{$class}.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader for module types.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload_types( $class ) {
|
||||
// For multipart classnames.
|
||||
$class = str_replace( '_', '', $class );
|
||||
require_once "module/type/{$class}.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader for woo modules.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload_woo_modules( $class ) {
|
||||
// For multipart classnames.
|
||||
$class = str_replace( '_', '', $class );
|
||||
require_once "module/woocommerce/{$class}.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader for modules.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload_modules( $class ) {
|
||||
// For multipart classnames.
|
||||
$class = str_replace( '_', '', $class );
|
||||
|
||||
if ( file_exists( ET_BUILDER_DIR . "module/{$class}.php" ) ) {
|
||||
require_once "module/{$class}.php";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader for module helpers and structure elements.
|
||||
*
|
||||
* @param string $class The class name.
|
||||
*/
|
||||
function _et_pb_autoload( $class ) {
|
||||
if ( in_array( $class, [ 'ET_Builder_Section', 'ET_Builder_Row', 'ET_Builder_Row_Inner', 'ET_Builder_Column' ], true ) ) {
|
||||
require_once 'main-structure-elements.php';
|
||||
} elseif ( 'ET_Builder_I18n' === $class ) {
|
||||
require_once 'feature/I18n.php';
|
||||
} elseif ( in_array( $class, [ 'ET_Builder_Element', 'ET_Builder_Module', 'ET_Builder_Structure_Element' ], true ) ) {
|
||||
// This is needed for custom module that extends official module and gets registered in unexpected location.
|
||||
require_once ET_BUILDER_DIR . 'functions.php';
|
||||
|
||||
require_once 'class-et-builder-element.php';
|
||||
} elseif ( 'ET_Builder_Module_Shortcode_Manager' === $class ) {
|
||||
require_once 'class-et-builder-module-shortcode-manager.php';
|
||||
} elseif ( 'ET_Builder_Post_Feature_Base' === $class ) {
|
||||
require_once 'class-et-builder-post-feature-base.php';
|
||||
} elseif ( 'ET_Builder_Module_Features' === $class ) {
|
||||
require_once 'class-et-builder-module-features.php';
|
||||
} elseif ( 'ET_Builder_Module_Fields_Factory' === $class ) {
|
||||
require_once 'module/field/Factory.php';
|
||||
} elseif ( 'ET_Builder_Module_Use_Detection' === $class ) {
|
||||
require_once 'class-et-builder-module-use-detection.php';
|
||||
} elseif ( 'ET_Global_Settings' === $class ) {
|
||||
require_once 'class-et-global-settings.php';
|
||||
} elseif ( 'ET_Builder_Global_Feature_Base' === $class ) {
|
||||
require_once 'class-et-builder-global-feature-base.php';
|
||||
} elseif ( 'ET_Builder_Google_Fonts_Feature' === $class ) {
|
||||
require_once 'class-et-builder-google-fonts-feature.php';
|
||||
} elseif ( 'ET_Builder_Dynamic_Assets_Feature' === $class ) {
|
||||
require_once 'class-et-builder-dynamic-assets-feature.php';
|
||||
} elseif ( 'ET_Builder_Module_Field_DisplayConditions' === $class ) {
|
||||
require_once 'module/field/DisplayConditions.php';
|
||||
} elseif ( strpos( $class, 'ET_Builder_Module_Helper_Motion_' ) !== false ) {
|
||||
_et_pb_autoload_helpers_motion( str_replace( 'ET_Builder_Module_Helper_Motion_', '', $class ) );
|
||||
} elseif ( strpos( $class, 'ET_Builder_Module_Helper_' ) !== false ) {
|
||||
_et_pb_autoload_helpers( str_replace( 'ET_Builder_Module_Helper_', '', $class ) );
|
||||
} elseif ( strpos( $class, 'ET_Builder_Module_Field_' ) !== false ) {
|
||||
_et_pb_autoload_fields( str_replace( 'ET_Builder_Module_Field_', '', $class ) );
|
||||
} elseif ( strpos( $class, 'ET_Builder_Module_Type_' ) !== false ) {
|
||||
_et_pb_autoload_types( str_replace( 'ET_Builder_Module_Type_', '', $class ) );
|
||||
} elseif ( strpos( $class, 'ET_Builder_Module_Woocommerce_' ) !== false ) {
|
||||
_et_pb_autoload_woo_modules( str_replace( 'ET_Builder_Module_Woocommerce_', '', $class ) );
|
||||
} elseif ( strpos( $class, 'ET_Builder_Module_' ) !== false ) {
|
||||
_et_pb_autoload_modules( str_replace( 'ET_Builder_Module_', '', $class ) );
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register( '_et_pb_autoload' );
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Multi_Value`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Multi_Value
|
||||
*/
|
||||
function et_pb_multi_value() {
|
||||
return ET_Builder_Module_Helper_Multi_Value::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Overflow`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Overflow
|
||||
*/
|
||||
function et_pb_overflow() {
|
||||
return ET_Builder_Module_Helper_Overflow::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Alignment`.
|
||||
*
|
||||
* @param string $prefix The prefix string that may be added to field name.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Alignment
|
||||
*/
|
||||
function et_pb_alignment_options( $prefix = '' ) {
|
||||
return new ET_Builder_Module_Helper_Alignment( $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Height`.
|
||||
*
|
||||
* @param string $prefix The prefix string that may be added to field name.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Height
|
||||
*/
|
||||
function et_pb_height_options( $prefix = '' ) {
|
||||
return new ET_Builder_Module_Helper_Height( $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Hover_Options`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Hover_Options
|
||||
*/
|
||||
function et_pb_hover_options() {
|
||||
return ET_Builder_Module_Helper_Hover_Options::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sticky option instance.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Sticky_Options
|
||||
*/
|
||||
function et_pb_sticky_options() {
|
||||
return ET_Builder_Module_Helper_Sticky_Options::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Max_Height`.
|
||||
*
|
||||
* @param string $prefix The prefix string that may be added to field name.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Max_Height
|
||||
*/
|
||||
function et_pb_max_height_options( $prefix = '' ) {
|
||||
return new ET_Builder_Module_Helper_Max_Height( $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Max_Width`.
|
||||
*
|
||||
* @param string $prefix The prefix string that may be added to field name.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Max_Width
|
||||
*/
|
||||
function et_pb_max_width_options( $prefix = '' ) {
|
||||
return new ET_Builder_Module_Helper_Max_Width( $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Min_Height`.
|
||||
*
|
||||
* @param string $prefix The prefix string that may be added to field name.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Min_Height
|
||||
*/
|
||||
function et_pb_min_height_options( $prefix = '' ) {
|
||||
return new ET_Builder_Module_Helper_Min_Height( $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_ResponsiveOptions`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_ResponsiveOptions
|
||||
*/
|
||||
function et_pb_responsive_options() {
|
||||
return ET_Builder_Module_Helper_ResponsiveOptions::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Slider`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Slider
|
||||
*/
|
||||
function et_pb_slider_options() {
|
||||
return new ET_Builder_Module_Helper_Slider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Transition_Options`.
|
||||
*
|
||||
* @return ET_Builder_Module_Transition_Options
|
||||
*/
|
||||
function et_pb_transition_options() {
|
||||
return ET_Builder_Module_Helper_Transition_Options::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Width`.
|
||||
*
|
||||
* @param string $prefix The prefix string that may be added to field name.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Width
|
||||
*/
|
||||
function et_pb_width_options( $prefix = '' ) {
|
||||
return new ET_Builder_Module_Helper_Width( $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Font`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Font
|
||||
*/
|
||||
function et_pb_font_options() {
|
||||
return ET_Builder_Module_Helper_Font::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_BackgroundLayout`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_BackgroundLayout
|
||||
*/
|
||||
function et_pb_background_layout_options() {
|
||||
return ET_Builder_Module_Helper_BackgroundLayout::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get helper instance
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @param string $helper_name Helper name.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
function et_builder_get_helper( $helper_name ) {
|
||||
switch ( $helper_name ) {
|
||||
case 'sticky':
|
||||
$helper = et_pb_sticky_options();
|
||||
break;
|
||||
|
||||
case 'hover':
|
||||
$helper = et_pb_hover_options();
|
||||
break;
|
||||
|
||||
case 'responsive':
|
||||
$helper = et_pb_responsive_options();
|
||||
break;
|
||||
|
||||
default:
|
||||
$helper = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return $helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ET_Builder_Module_Helper_MultiViewOptions wrapper
|
||||
*
|
||||
* @since 3.27.1
|
||||
*
|
||||
* @param ET_Builder_Element|bool $module Module object.
|
||||
* @param array $custom_props Defined custom props data.
|
||||
* @param array $conditional_values Defined options conditional values.
|
||||
* @param array $default_values Defined options default values.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_MultiViewOptions
|
||||
*/
|
||||
function et_pb_multi_view_options( $module = false, $custom_props = array(), $conditional_values = array(), $default_values = array() ) {
|
||||
return new ET_Builder_Module_Helper_MultiViewOptions( $module, $custom_props, $conditional_values, $default_values );
|
||||
}
|
||||
|
||||
if ( et_is_woocommerce_plugin_active() ) {
|
||||
add_filter(
|
||||
'et_builder_get_woo_default_columns',
|
||||
array(
|
||||
'ET_Builder_Module_Helper_Woocommerce_Modules',
|
||||
'get_columns_posts_default_value',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_OptionTemplate`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_OptionTemplate
|
||||
*/
|
||||
function et_pb_option_template() {
|
||||
return ET_Builder_Module_Helper_OptionTemplate::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of `ET_Builder_Module_Helper_Background`.
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Background
|
||||
*
|
||||
* @since 4.3.3
|
||||
*/
|
||||
function et_pb_background_options() {
|
||||
return ET_Builder_Module_Helper_Background::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ET_Builder_Module_Helper_Media wrapper
|
||||
*
|
||||
* @since 4.6.4
|
||||
*
|
||||
* @return ET_Builder_Module_Helper_Media
|
||||
*/
|
||||
function et_pb_media_options() {
|
||||
return ET_Builder_Module_Helper_Media::instance();
|
||||
}
|
36
includes/builder/class-et-builder-dynamic-assets-feature.php
Normal file
36
includes/builder/class-et-builder-dynamic-assets-feature.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Dynamic_Assets feature class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles Dynamic_Assets feature.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Dynamic_Assets_Feature extends ET_Builder_Global_Feature_Base {
|
||||
|
||||
/**
|
||||
* Hold the class instance.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
const CACHE_META_KEY = '_et_builder_da_feature_cache';
|
||||
|
||||
/**
|
||||
* Initialize ET_Builder_Dynamic_Assets_Feature class.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
}
|
23768
includes/builder/class-et-builder-element.php
Normal file
23768
includes/builder/class-et-builder-element.php
Normal file
File diff suppressed because it is too large
Load Diff
216
includes/builder/class-et-builder-global-feature-base.php
Normal file
216
includes/builder/class-et-builder-global-feature-base.php
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* Feature base class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base Feature feature.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Global_Feature_Base {
|
||||
|
||||
const CACHE_META_KEY = '_et_builder_global_feature_cache';
|
||||
|
||||
/**
|
||||
* Primed status.
|
||||
*
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $_primed = false;
|
||||
|
||||
/**
|
||||
* Cache array.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_cache = [];
|
||||
|
||||
/**
|
||||
* Cache status.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_cache_dirty = false;
|
||||
|
||||
/**
|
||||
* Construct instance.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( self::enabled() ) {
|
||||
$this->cache_prime();
|
||||
|
||||
if ( ! has_action( 'shutdown', [ $this, 'cache_save' ] ) ) {
|
||||
add_action( 'shutdown', [ $this, 'cache_save' ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the features cache.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public static function purge_cache() {
|
||||
delete_option( static::CACHE_META_KEY );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the features cache.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function load_cache() {
|
||||
return get_option( static::CACHE_META_KEY );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether we should use cache or not.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function enabled() {
|
||||
/**
|
||||
* Whether Global Feature Cache should be enabled or not.
|
||||
*
|
||||
* @since ?
|
||||
*
|
||||
* @param bool $enabled.
|
||||
*/
|
||||
return apply_filters( 'et_builder_global_feature_cache_enabled', et_builder_is_frontend() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prime the cache.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function cache_prime() {
|
||||
if ( empty( $this->_primed ) ) {
|
||||
|
||||
$meta = self::load_cache();
|
||||
|
||||
if ( isset( $meta[1] ) ) {
|
||||
list( $stored_index, $cache ) = $meta;
|
||||
$current_index = (string) self::_get_cache_index();
|
||||
$this->_cache = ( $current_index === $stored_index ) ? $cache : [];
|
||||
}
|
||||
|
||||
$this->_primed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the cache.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function cache_save() {
|
||||
// Only if cache is "dirty" and builder is used.
|
||||
if ( $this->_cache_dirty ) {
|
||||
$cache = array( self::_get_cache_index(), $this->_cache );
|
||||
update_option( static::CACHE_META_KEY, $cache );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cache Version Index Items.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access protected
|
||||
* @return array Cache version items.
|
||||
*/
|
||||
protected static function _get_cache_index_items() {
|
||||
global $wp_version;
|
||||
|
||||
/**
|
||||
* Filters global feature cache index items.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param array Assoc array of cache index items.
|
||||
* @param string The cache meta key that the cache index items belong to.
|
||||
*/
|
||||
return apply_filters(
|
||||
'et_global_feature_cache_index_items',
|
||||
array(
|
||||
'gph' => ET_Builder_Global_Presets_History::instance()->get_global_history_index(),
|
||||
'divi' => et_get_theme_version(),
|
||||
'wp' => $wp_version,
|
||||
),
|
||||
static::CACHE_META_KEY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cache Version Index.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access protected
|
||||
* @return string .Cache version index.
|
||||
*/
|
||||
public static function _get_cache_index() {
|
||||
return wp_json_encode( self::_get_cache_index_items() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $key Cache key.
|
||||
* @param string $group Cache Group.
|
||||
*/
|
||||
public function cache_get( $key, $group = 'default' ) {
|
||||
$exists = isset( $this->_cache[ $group ] ) && isset( $this->_cache[ $group ][ $key ] );
|
||||
return $exists ? $this->_cache[ $group ][ $key ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $key Cache key.
|
||||
* @param mixed $value To be cached.
|
||||
* @param string $group Cache group.
|
||||
*/
|
||||
public function cache_set( $key, $value, $group = 'default' ) {
|
||||
$this->_cache[ $group ][ $key ] = $value;
|
||||
$this->_cache_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for cached value.
|
||||
*
|
||||
* First check cache if present, if not, determine
|
||||
* from calling the callback.
|
||||
*
|
||||
* @param string $key Name of item.
|
||||
* @param function $cb Callback function to perform logic.
|
||||
* @param string $group Cache group.
|
||||
*
|
||||
* @return bool/mixed Result.
|
||||
*/
|
||||
public function get( $key, $cb, $group = 'default' ) {
|
||||
// short circuit.
|
||||
$result = $this->cache_get( $key, $group );
|
||||
|
||||
if ( is_null( $result ) ) {
|
||||
// Set cache for next time.
|
||||
$result = $cb();
|
||||
$this->cache_set( $key, $result, $group );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
214
includes/builder/class-et-builder-google-fonts-feature.php
Normal file
214
includes/builder/class-et-builder-google-fonts-feature.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* Google_Fonts feature class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles Google_Fonts feature.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Google_Fonts_Feature extends ET_Builder_Global_Feature_Base {
|
||||
|
||||
/**
|
||||
* `ET_Builder_Google_Fonts_Feature` instance.
|
||||
*
|
||||
* @var ET_Builder_Google_Fonts_Feature
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
const CACHE_META_KEY = '_et_builder_gf_feature_cache';
|
||||
|
||||
/**
|
||||
* Returns instance of the class.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function __construct() {
|
||||
// need to set this filter up front, bc as soon as the parent __construct
|
||||
// is called then it will prime the cache so it needs
|
||||
// this cache index filter to be setup right away.
|
||||
add_filter( 'et_global_feature_cache_index_items', [ 'ET_Builder_Google_Fonts_Feature', 'cache_index_items' ], 10, 2 );
|
||||
|
||||
parent::__construct();
|
||||
|
||||
if ( self::enabled() ) {
|
||||
self::setup_transient();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize ET_Builder_Google_Fonts_Feature class.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup transient to purge cache once a day.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public static function setup_transient() {
|
||||
if ( ! get_transient( self::CACHE_META_KEY ) ) {
|
||||
self::purge_cache();
|
||||
|
||||
set_transient( self::CACHE_META_KEY, '1', DAY_IN_SECONDS );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to cache index items.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param array $items Assoc array of cache index items.
|
||||
* @param string $key The cache meta key that the cache index items belong to.
|
||||
*
|
||||
* @return array $items Assoc array of cache index items.
|
||||
*/
|
||||
public static function cache_index_items( $items, $key ) {
|
||||
global $shortname;
|
||||
|
||||
if ( self::CACHE_META_KEY === $key ) {
|
||||
$items['enable_all_character_sets'] = (string) et_get_option( "{$shortname}_gf_enable_all_character_sets", 'false' );
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an option is enabled.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param string $sub_option Google Fonts Sub Option.
|
||||
*
|
||||
* @return bool Whether the sub option is enabled.
|
||||
*/
|
||||
public function is_option_enabled( $sub_option = '' ) {
|
||||
global $shortname;
|
||||
|
||||
if ( ! self::enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( et_is_builder_plugin_active() ) {
|
||||
$options = get_option( 'et_pb_builder_options', array() );
|
||||
$option_state = isset( $options[ 'performance_main_' . $sub_option ] ) ? $options[ 'performance_main_' . $sub_option ] : 'on';
|
||||
} else {
|
||||
$option_state = et_get_option( $shortname . '_' . $sub_option, 'on' );
|
||||
}
|
||||
return 'on' === $option_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Agents.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return array[string] List of user agents.
|
||||
*/
|
||||
protected function _get_user_agents() {
|
||||
$limit_support = $this->is_option_enabled( 'limit_google_fonts_support_for_legacy_browsers' );
|
||||
|
||||
$uas = [];
|
||||
|
||||
if ( ! $limit_support ) {
|
||||
/**
|
||||
* IE9 Compat Modes
|
||||
*/
|
||||
$uas['eot'] = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)';
|
||||
|
||||
/**
|
||||
* Legacy iOS
|
||||
*/
|
||||
$uas['svg'] = 'Mozilla/4.0 (iPad; CPU OS 4_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/4.1 Mobile/9A405 Safari/7534.48.3';
|
||||
}
|
||||
|
||||
/**
|
||||
* Safari, Android, iOS
|
||||
*/
|
||||
$uas['ttf'] = 'Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) Safari/538.1 Daum/4.1';
|
||||
|
||||
/**
|
||||
* Modern Browsers.
|
||||
* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+
|
||||
*/
|
||||
$uas['woff'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0';
|
||||
|
||||
/**
|
||||
* Super Modern Browsers.
|
||||
* hrome 26+, Opera 23+, Firefox 39+
|
||||
*/
|
||||
$uas['woff2'] = 'Mozilla/5.0 (Windows NT 6.3; rv:39.0) Gecko/20100101 Firefox/39.0';
|
||||
|
||||
/**
|
||||
* Filters which user agents to use to get google fonts.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
return apply_filters( 'et_builder_google_fonts_user_agents', $uas );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch CSS file contents from google fonts URL.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param string $url The Google Fonts URL to fetch the contents for.
|
||||
*
|
||||
* @return string $url CSS file contents.
|
||||
*/
|
||||
public function fetch( $url ) {
|
||||
$all_contents = '/* Original: ' . esc_url( $url ) . ' */';
|
||||
|
||||
foreach ( $this->_get_user_agents() as $ua ) {
|
||||
$response = wp_remote_get(
|
||||
esc_url_raw( $url ),
|
||||
[
|
||||
'user-agent' => $ua,
|
||||
]
|
||||
);
|
||||
|
||||
// Return if there is no response or if there is an error.
|
||||
if ( ! is_array( $response ) || is_wp_error( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$contents = wp_remote_retrieve_body( $response );
|
||||
|
||||
$contents = '/* User Agent: ' . $ua . ' */' . "\n" . $contents;
|
||||
|
||||
$all_contents .= "\n\n" . $contents;
|
||||
}
|
||||
|
||||
$all_contents = self::minify( $all_contents );
|
||||
|
||||
return $all_contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify CSS string.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param string $data Multiline CSS data.
|
||||
*
|
||||
* @return string Minifed CSS data.
|
||||
*/
|
||||
public static function minify( $data ) {
|
||||
$data = preg_replace( '/\n/smi', '', $data );
|
||||
$data = preg_replace( '/\s\s/smi', '', $data );
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
97
includes/builder/class-et-builder-module-features.php
Normal file
97
includes/builder/class-et-builder-module-features.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Module Features feature class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles Builder Module Features.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Module_Features extends ET_Builder_Post_Feature_Base {
|
||||
|
||||
const CACHE_META_KEY = '_et_builder_module_features_cache';
|
||||
|
||||
/**
|
||||
* Cache group.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_cache_group = [];
|
||||
|
||||
/**
|
||||
* Construct instance.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
// Get shortcode tag / attributes.
|
||||
add_filter( 'pre_do_shortcode_tag', [ $this, 'set_cache_group' ], 99, 3 );
|
||||
add_filter( 'do_shortcode_tag', [ $this, 'restore_previous_cache_group' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a key from a shortcode tag and its attributes.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param string $tag Shortcode tag.
|
||||
* @param string $attrs Shortcode attributes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_key( $tag, $attrs ) {
|
||||
$key = $tag . '_' . md5( wp_json_encode( $attrs ) );
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache group.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param mixed $override Whether to override do_shortcode return value or not.
|
||||
* @param string $tag Shortcode tag.
|
||||
* @param string $attrs Shortcode attributes.
|
||||
* @return mixed
|
||||
*/
|
||||
public function set_cache_group( $override, $tag, $attrs ) {
|
||||
$this->_cache_group[] = self::get_key( $tag, $attrs );
|
||||
return $override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore previous cache group when current shortcode execution ends.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param mixed $output Shortcode content.
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore_previous_cache_group( $output ) {
|
||||
// Get rid of current shortcode cache group.
|
||||
array_pop( $this->_cache_group );
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for cached value.
|
||||
*
|
||||
* First check cache if present, if not, determine
|
||||
* from calling the callback.
|
||||
*
|
||||
* @param string $key Name of item.
|
||||
* @param function $cb Callback function to perform logic.
|
||||
* @param string $group Cache group.
|
||||
*
|
||||
* @return bool/mixed Result.
|
||||
*/
|
||||
public function get( $key, $cb, $group = 'default' ) {
|
||||
return parent::get( $key, $cb, end( $this->_cache_group ) );
|
||||
}
|
||||
|
||||
}
|
687
includes/builder/class-et-builder-module-shortcode-manager.php
Normal file
687
includes/builder/class-et-builder-module-shortcode-manager.php
Normal file
@ -0,0 +1,687 @@
|
||||
<?php
|
||||
/**
|
||||
* Shortcode Manager Class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles module shortcodes.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Module_Shortcode_Manager {
|
||||
|
||||
/**
|
||||
* Modules container.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_modules_map = [];
|
||||
|
||||
/**
|
||||
* WooCommerce modules container.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_woo_modules_map = [];
|
||||
|
||||
/**
|
||||
* Structural Modules container.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_structural_modules_map = [];
|
||||
|
||||
/**
|
||||
* Initialize shortcode manager class.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
$this->register_modules();
|
||||
$this->register_fullwidth_modules();
|
||||
$this->register_structural_modules();
|
||||
$this->register_woo_modules();
|
||||
$this->register_shortcode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start registering shortcodes.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_shortcode() {
|
||||
// is_saving_cache or other scenarios where we need to load everything.
|
||||
if ( et_builder_should_load_all_module_data() ) {
|
||||
$this->register_all_shortcodes();
|
||||
} else {
|
||||
$this->register_lazy_shortcodes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register normal modules.
|
||||
*
|
||||
* Modules dependent to each other will have
|
||||
* to have a dependency parameter on them.
|
||||
* Eg : et_pb_accordion_item needs et_pb_toggle so we
|
||||
* have to pass add that on the `deps` key.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_modules() {
|
||||
$modules = [
|
||||
'et_pb_accordion' => [
|
||||
'classname' => 'ET_Builder_Module_Accordion',
|
||||
],
|
||||
'et_pb_accordion_item' => [
|
||||
'classname' => 'ET_Builder_Module_Accordion_Item',
|
||||
'deps' => array( 'et_pb_toggle' ),
|
||||
],
|
||||
'et_pb_audio' => [
|
||||
'classname' => 'ET_Builder_Module_Audio',
|
||||
],
|
||||
'et_pb_counters' => [
|
||||
'classname' => 'ET_Builder_Module_Bar_Counters',
|
||||
],
|
||||
'et_pb_counter' => [
|
||||
'classname' => 'ET_Builder_Module_Bar_Counters_Item',
|
||||
],
|
||||
'et_pb_blog' => [
|
||||
'classname' => 'ET_Builder_Module_Blog',
|
||||
],
|
||||
'et_pb_blurb' => [
|
||||
'classname' => 'ET_Builder_Module_Blurb',
|
||||
],
|
||||
'et_pb_button' => [
|
||||
'classname' => 'ET_Builder_Module_Button',
|
||||
],
|
||||
'et_pb_circle_counter' => [
|
||||
'classname' => 'ET_Builder_Module_Circle_Counter',
|
||||
],
|
||||
'et_pb_code' => [
|
||||
'classname' => 'ET_Builder_Module_Code',
|
||||
],
|
||||
'et_pb_comments' => [
|
||||
'classname' => 'ET_Builder_Module_Comments',
|
||||
],
|
||||
'et_pb_contact_form' => [
|
||||
'classname' => 'ET_Builder_Module_Contact_Form',
|
||||
],
|
||||
'et_pb_contact_field' => [
|
||||
'classname' => 'ET_Builder_Module_Contact_Form_Item',
|
||||
],
|
||||
'et_pb_countdown_timer' => [
|
||||
'classname' => 'ET_Builder_Module_Countdown_Timer',
|
||||
],
|
||||
'et_pb_cta' => [
|
||||
'classname' => 'ET_Builder_Module_Cta',
|
||||
],
|
||||
'et_pb_divider' => [
|
||||
'classname' => 'ET_Builder_Module_Divider',
|
||||
],
|
||||
'et_pb_filterable_portfolio' => [
|
||||
'classname' => 'ET_Builder_Module_Filterable_Portfolio',
|
||||
],
|
||||
'et_pb_gallery' => [
|
||||
'classname' => 'ET_Builder_Module_Gallery',
|
||||
],
|
||||
'et_pb_image' => [
|
||||
'classname' => 'ET_Builder_Module_Image',
|
||||
],
|
||||
'et_pb_login' => [
|
||||
'classname' => 'ET_Builder_Module_Login',
|
||||
],
|
||||
'et_pb_map' => [
|
||||
'classname' => 'ET_Builder_Module_Map',
|
||||
],
|
||||
'et_pb_map_pin' => [
|
||||
'classname' => 'ET_Builder_Module_Map_Item',
|
||||
],
|
||||
'et_pb_menu' => [
|
||||
'classname' => 'ET_Builder_Module_Menu',
|
||||
],
|
||||
'et_pb_number_counter' => [
|
||||
'classname' => 'ET_Builder_Module_Number_Counter',
|
||||
],
|
||||
'et_pb_portfolio' => [
|
||||
'classname' => 'ET_Builder_Module_Portfolio',
|
||||
],
|
||||
'et_pb_post_content' => [
|
||||
'classname' => 'ET_Builder_Module_PostContent',
|
||||
],
|
||||
'et_pb_post_slider' => [
|
||||
'classname' => 'ET_Builder_Module_Post_Slider',
|
||||
],
|
||||
'et_pb_post_title' => [
|
||||
'classname' => 'ET_Builder_Module_Post_Title',
|
||||
],
|
||||
'et_pb_post_nav' => [
|
||||
'classname' => 'ET_Builder_Module_Posts_Navigation',
|
||||
],
|
||||
'et_pb_pricing_tables' => [
|
||||
'classname' => 'ET_Builder_Module_Pricing_Tables',
|
||||
],
|
||||
'et_pb_pricing_table' => [
|
||||
'classname' => 'ET_Builder_Module_Pricing_Tables_Item',
|
||||
],
|
||||
'et_pb_search' => [
|
||||
'classname' => 'ET_Builder_Module_Search',
|
||||
],
|
||||
'et_pb_shop' => [
|
||||
'classname' => 'ET_Builder_Module_Shop',
|
||||
],
|
||||
'et_pb_sidebar' => [
|
||||
'classname' => 'ET_Builder_Module_Sidebar',
|
||||
],
|
||||
'et_pb_signup' => [
|
||||
'classname' => 'ET_Builder_Module_Signup',
|
||||
],
|
||||
'et_pb_signup_custom_field' => [
|
||||
'classname' => 'ET_Builder_Module_Signup_Item',
|
||||
'preload_deps' => array( 'et_pb_contact_field' ),
|
||||
],
|
||||
'et_pb_slider' => [
|
||||
'classname' => 'ET_Builder_Module_Slider',
|
||||
],
|
||||
'et_pb_slide' => [
|
||||
'classname' => 'ET_Builder_Module_Slider_Item',
|
||||
],
|
||||
'et_pb_social_media_follow' => [
|
||||
'classname' => 'ET_Builder_Module_Social_Media_Follow',
|
||||
],
|
||||
'et_pb_social_media_follow_network' => [
|
||||
'classname' => 'ET_Builder_Module_Social_Media_Follow_Item',
|
||||
],
|
||||
'et_pb_tabs' => [
|
||||
'classname' => 'ET_Builder_Module_Tabs',
|
||||
],
|
||||
'et_pb_tab' => [
|
||||
'classname' => 'ET_Builder_Module_Tabs_Item',
|
||||
],
|
||||
'et_pb_team_member' => [
|
||||
'classname' => 'ET_Builder_Module_Team_Member',
|
||||
],
|
||||
'et_pb_testimonial' => [
|
||||
'classname' => 'ET_Builder_Module_Testimonial',
|
||||
],
|
||||
'et_pb_text' => [
|
||||
'classname' => 'ET_Builder_Module_Text',
|
||||
],
|
||||
'et_pb_toggle' => [
|
||||
'classname' => 'ET_Builder_Module_Toggle',
|
||||
],
|
||||
'et_pb_video' => [
|
||||
'classname' => 'ET_Builder_Module_Video',
|
||||
],
|
||||
'et_pb_video_slider' => [
|
||||
'classname' => 'ET_Builder_Module_Video_Slider',
|
||||
],
|
||||
'et_pb_video_slider_item' => [
|
||||
'classname' => 'ET_Builder_Module_Video_Slider_Item',
|
||||
],
|
||||
'et_pb_icon' => [
|
||||
'classname' => 'ET_Builder_Module_Icon',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Filters built-in Divi Builder module class names.
|
||||
*
|
||||
* 3rd-party plugins can use this filter to override Divi Builder modules.
|
||||
*
|
||||
* NOTE: Overriding built-in modules is not ideal and should only be used as a temporary solution.
|
||||
* The recommended approach for achieving this is using the official API:
|
||||
* https://www.elegantthemes.com/documentation/developers/divi-module/how-to-create-a-divi-builder-module/
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $additional_modules Additional modules.
|
||||
*/
|
||||
$additional_modules = apply_filters( 'et_module_classes', [] );
|
||||
$this->_modules_map = array_merge( $this->_modules_map, $modules, $additional_modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register fullwidth modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_fullwidth_modules() {
|
||||
$modules = [
|
||||
'et_pb_fullwidth_code' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Code',
|
||||
],
|
||||
'et_pb_fullwidth_header' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Header',
|
||||
],
|
||||
'et_pb_fullwidth_image' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Image',
|
||||
],
|
||||
'et_pb_fullwidth_map' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Map',
|
||||
],
|
||||
'et_pb_fullwidth_menu' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Menu',
|
||||
],
|
||||
'et_pb_fullwidth_portfolio' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Portfolio',
|
||||
],
|
||||
'et_pb_fullwidth_post_content' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_PostContent',
|
||||
],
|
||||
'et_pb_fullwidth_post_slider' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Post_Slider',
|
||||
],
|
||||
'et_pb_fullwidth_post_title' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Post_Title',
|
||||
],
|
||||
'et_pb_fullwidth_slider' => [
|
||||
'classname' => 'ET_Builder_Module_Fullwidth_Slider',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Filters built-in Divi Builder module class names.
|
||||
*
|
||||
* 3rd-party plugins can use this filter to override Divi Builder modules.
|
||||
*
|
||||
* NOTE: Overriding built-in modules is not ideal and should only be used as a temporary solution.
|
||||
* The recommended approach for achieving this is using the official API:
|
||||
* https://www.elegantthemes.com/documentation/developers/divi-module/how-to-create-a-divi-builder-module/
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $additional_modules Additional modules.
|
||||
*/
|
||||
$additional_modules = apply_filters( 'et_fullwidth_module_classes', [] );
|
||||
$this->_modules_map = array_merge( $this->_modules_map, $modules, $additional_modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register structural modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_structural_modules() {
|
||||
$modules = [
|
||||
'et_pb_section' => [
|
||||
'classname' => 'ET_Builder_Section',
|
||||
],
|
||||
'et_pb_row' => [
|
||||
'classname' => 'ET_Builder_Row',
|
||||
],
|
||||
'et_pb_row_inner' => [
|
||||
'classname' => 'ET_Builder_Row_Inner',
|
||||
],
|
||||
'et_pb_column' => [
|
||||
'classname' => 'ET_Builder_Column',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Filters built-in Divi Builder module class names.
|
||||
*
|
||||
* 3rd-party plugins can use this filter to override Divi Builder modules.
|
||||
*
|
||||
* NOTE: Overriding built-in modules is not ideal and should only be used as a temporary solution.
|
||||
* The recommended approach for achieving this is using the official API:
|
||||
* https://www.elegantthemes.com/documentation/developers/divi-module/how-to-create-a-divi-builder-module/
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $additional_modules Additional modules.
|
||||
*/
|
||||
$additional_modules = apply_filters( 'et_structural_module_classes', [] );
|
||||
$this->_structural_modules_map = array_merge( $modules, $additional_modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register woocommerce modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_woo_modules() {
|
||||
// Only add wooModules if woo is active.
|
||||
if ( ! et_is_woocommerce_plugin_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$woo_modules = [
|
||||
'et_pb_wc_add_to_cart' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Add_To_Cart',
|
||||
],
|
||||
'et_pb_wc_additional_info' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Additional_Info',
|
||||
],
|
||||
'et_pb_wc_breadcrumb' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Breadcrumb',
|
||||
],
|
||||
'et_pb_wc_cart_notice' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Cart_Notice',
|
||||
],
|
||||
'et_pb_wc_description' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Description',
|
||||
],
|
||||
'et_pb_wc_gallery' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Gallery',
|
||||
],
|
||||
'et_pb_wc_images' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Images',
|
||||
],
|
||||
'et_pb_wc_meta' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Meta',
|
||||
],
|
||||
'et_pb_wc_price' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Price',
|
||||
],
|
||||
'et_pb_wc_rating' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Rating',
|
||||
],
|
||||
'et_pb_wc_related_products' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Related_Products',
|
||||
],
|
||||
'et_pb_wc_reviews' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Reviews',
|
||||
],
|
||||
'et_pb_wc_stock' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Stock',
|
||||
],
|
||||
'et_pb_wc_tabs' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Tabs',
|
||||
],
|
||||
'et_pb_wc_title' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Title',
|
||||
],
|
||||
'et_pb_wc_upsells' => [
|
||||
'classname' => 'ET_Builder_Module_Woocommerce_Upsells',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Filters built-in Divi Builder module class names.
|
||||
*
|
||||
* 3rd-party plugins can use this filter to override Divi Builder modules.
|
||||
*
|
||||
* NOTE: Overriding built-in modules is not ideal and should only be used as a temporary solution.
|
||||
* The recommended approach for achieving this is using the official API:
|
||||
* https://www.elegantthemes.com/documentation/developers/divi-module/how-to-create-a-divi-builder-module/
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $additional_modules Additional modules.
|
||||
*/
|
||||
$additional_modules = apply_filters( 'et_woo_module_classes', [] );
|
||||
$this->_woo_modules_map = $woo_modules;
|
||||
$this->_modules_map = array_merge( $this->_modules_map, $woo_modules, $additional_modules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register shortcode.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_all_shortcodes() {
|
||||
$et_builder_module_files = glob( ET_BUILDER_DIR . 'module/*.php' );
|
||||
$et_builder_module_types = glob( ET_BUILDER_DIR . 'module/type/*.php' );
|
||||
|
||||
if ( ! $et_builder_module_files ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before the builder's module classes are loaded.
|
||||
*
|
||||
* @since 3.0.77
|
||||
*/
|
||||
do_action( 'et_builder_modules_load' );
|
||||
|
||||
foreach ( $et_builder_module_types as $module_type ) {
|
||||
require_once $module_type;
|
||||
}
|
||||
|
||||
foreach ( $et_builder_module_files as $module_file ) {
|
||||
// skip this all caps version, if it exists.
|
||||
// See https://github.com/elegantthemes/Divi/issues/24780.
|
||||
if ( 'CTA.php' === basename( $module_file ) ) {
|
||||
continue;
|
||||
}
|
||||
require_once $module_file;
|
||||
}
|
||||
|
||||
if ( et_is_woocommerce_plugin_active() ) {
|
||||
$et_builder_woocommerce_module_files = glob( ET_BUILDER_DIR . 'module/woocommerce/*.php' );
|
||||
foreach ( $et_builder_woocommerce_module_files as $module_type ) {
|
||||
require_once $module_type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after the builder's module classes are loaded.
|
||||
*
|
||||
* NOTE: this hook only fires on :
|
||||
* - Visual Builder pages
|
||||
* - Front end cache prime initial request
|
||||
*
|
||||
* IT DOES NOT fire on ALL front end requests
|
||||
*
|
||||
* @since 3.0.77
|
||||
* @deprecated ?? Introduced shortcode manager.
|
||||
* Use {@see et_builder_module_loading}/{@see et_builder_module_loaded}/{@see et_builder_ready} instead.
|
||||
*/
|
||||
do_action( 'et_builder_modules_loaded' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load shortcodes.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_lazy_shortcodes() {
|
||||
// A fake handler has to be registered for every shortcode, otherways
|
||||
// code will exit early and the pre_do_shortcode_tag hook won't be executed.
|
||||
foreach ( $this->_modules_map as $shortcode_slug => $module_data ) {
|
||||
add_shortcode( $shortcode_slug, '__return_empty_string' );
|
||||
}
|
||||
|
||||
// Load modules as needed.
|
||||
add_filter( 'pre_do_shortcode_tag', [ $this, 'load_modules' ], 99, 2 );
|
||||
|
||||
// Ensure all our module slugs are always considered, even when not loaded (yet).
|
||||
add_filter( 'et_builder_get_module_slugs_by_post_type', [ $this, 'add_module_slugs' ] );
|
||||
|
||||
add_filter( 'et_builder_get_woocommerce_modules', [ $this, 'add_woo_slugs' ] );
|
||||
|
||||
// Ensure all our structural module slugs are always considered, even when not loaded (yet).
|
||||
add_filter( 'et_builder_get_structural_module_slugs', [ $this, 'add_structural_module_slugs' ] );
|
||||
|
||||
/**
|
||||
* Fires after the builder's module classes are loaded.
|
||||
*
|
||||
* This hook is fired here for legacy reasons only.
|
||||
* Do not depend on this hook in the future.
|
||||
*
|
||||
* @since 3.0.77
|
||||
* @deprecated ?? Introduced shortcode manager.
|
||||
* Use {@see et_builder_module_loading}/{@see et_builder_module_loaded}/{@see et_builder_ready} instead.
|
||||
*/
|
||||
do_action( 'et_builder_modules_loaded' );
|
||||
|
||||
/**
|
||||
* Fires after the builder's module shortcodes are lazy registered.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
do_action( 'et_builder_module_lazy_shortcodes_registered' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add slugs for all our woo modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param array $loaded Loaded woo modules slugs.
|
||||
* @return array
|
||||
*/
|
||||
public function add_woo_slugs( $loaded ) {
|
||||
static $module_slugs;
|
||||
|
||||
// Only compute this once.
|
||||
if ( empty( $module_slugs ) ) {
|
||||
$module_slugs = array_keys( $this->_woo_modules_map );
|
||||
}
|
||||
|
||||
return array_unique( array_merge( $loaded, $module_slugs ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add slugs for all our modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param array $loaded Loaded modules slugs.
|
||||
* @return array
|
||||
*/
|
||||
public function add_module_slugs( $loaded ) {
|
||||
static $module_slugs;
|
||||
|
||||
// Only compute this once.
|
||||
if ( empty( $module_slugs ) ) {
|
||||
$module_slugs = array_keys( $this->_modules_map );
|
||||
}
|
||||
|
||||
return array_unique( array_merge( $loaded, $module_slugs ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add slugs for all our structural modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param array $loaded Loaded modules slugs.
|
||||
* @return array
|
||||
*/
|
||||
public function add_structural_module_slugs( $loaded ) {
|
||||
static $structural_module_slugs;
|
||||
|
||||
// Only compute this once.
|
||||
if ( empty( $structural_module_slugs ) ) {
|
||||
$structural_module_slugs = array_keys( $this->_structural_modules_map );
|
||||
}
|
||||
|
||||
return array_unique( array_merge( $loaded, $structural_module_slugs ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load modules.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param mixed $override Whether to override do_shortcode return value or not.
|
||||
* @param string $tag Shortcode tag.
|
||||
* @return mixed
|
||||
*/
|
||||
public function load_modules( $override, $tag ) {
|
||||
$this->maybe_load_module_from_slug( $tag );
|
||||
return $override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate module from a shortcode slug.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param string $tag Shortcode tag.
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_load_module_from_slug( $tag ) {
|
||||
|
||||
if ( empty( $this->_modules_map[ $tag ] ) ) {
|
||||
// None of our business.
|
||||
return;
|
||||
}
|
||||
|
||||
$module =& $this->_modules_map[ $tag ];
|
||||
|
||||
if ( empty( $module['instance'] ) ) {
|
||||
/**
|
||||
* Fires before module class is instantiated.
|
||||
*
|
||||
* @param string $tag Shortcode tag for module.
|
||||
* @param array $module Module loading configuration details.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
do_action( 'et_builder_module_loading', $tag, $module );
|
||||
|
||||
/**
|
||||
* Fires before module class is instantiated.
|
||||
*
|
||||
* The dynamic portion of the hook, `$tag`, refers to the shortcode tag.
|
||||
*
|
||||
* @param array $module Module loading configuration details.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
do_action( "et_builder_module_loading_{$tag}", $module );
|
||||
|
||||
// Load dependency before the class if needed.
|
||||
if ( ! empty( $module['preload_deps'] ) ) {
|
||||
foreach ( $module['preload_deps'] as $slug ) {
|
||||
$this->maybe_load_module_from_slug( $slug );
|
||||
}
|
||||
}
|
||||
|
||||
$module['instance'] = new $module['classname']();
|
||||
|
||||
if ( ! empty( $module['deps'] ) ) {
|
||||
foreach ( $module['deps'] as $slug ) {
|
||||
$this->maybe_load_module_from_slug( $slug );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after module class is instantiated.
|
||||
*
|
||||
* @param string $tag Shortcode tag for module.
|
||||
* @param array $module Module loading configuration details.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
do_action( 'et_builder_module_loaded', $tag, $module );
|
||||
|
||||
/**
|
||||
* Fires after module class is instantiated.
|
||||
*
|
||||
* The dynamic portion of the hook, `$tag`, refers to the shortcode tag.
|
||||
*
|
||||
* @param array $module Module loading configuration details.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
do_action( "et_builder_module_loaded_{$tag}", $module );
|
||||
}
|
||||
}
|
||||
}
|
207
includes/builder/class-et-builder-module-use-detection.php
Normal file
207
includes/builder/class-et-builder-module-use-detection.php
Normal file
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* Module Use Detection class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles Module Use Detection.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Module_Use_Detection {
|
||||
|
||||
/**
|
||||
* Module Slugs Used.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_modules_used = [];
|
||||
|
||||
/**
|
||||
* Module Attrs Used.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_module_attrs_used = [];
|
||||
|
||||
/**
|
||||
* Module Attr Values Used.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_module_attr_values_used = [];
|
||||
|
||||
/**
|
||||
* Valid Shortcode Slugs.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_valid_slugs = [];
|
||||
|
||||
/**
|
||||
* `ET_Builder_Module_Use_Detection` instance.
|
||||
*
|
||||
* @var ET_Builder_Module_Use_Detection
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* Construct instance.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_filter( 'pre_do_shortcode_tag', [ $this, 'log_slug_used' ], 99, 3 );
|
||||
add_action( 'wp_footer', [ $this, 'footer' ], 1000 );
|
||||
|
||||
add_action( 'et_builder_ready', array( $this, '_setup_valid_slugs' ), 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new static();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get valid slugs.
|
||||
*/
|
||||
public function _setup_valid_slugs() {
|
||||
$this->_valid_slugs = ET_Builder_Element::get_all_module_slugs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the Shortcode Tag/Slug.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
* @param mixed $override Whether to override do_shortcode return value or not.
|
||||
* @param string $tag Shortcode tag.
|
||||
* @param array $attrs Shortcode attrs.
|
||||
* @return mixed
|
||||
*/
|
||||
public function log_slug_used( $override, $tag, $attrs ) {
|
||||
$interested_attrs_and_values = apply_filters(
|
||||
'et_builder_module_attrs_values_used',
|
||||
[
|
||||
'gutter_width',
|
||||
'animation_style',
|
||||
'sticky_position',
|
||||
'specialty',
|
||||
'use_custom_gutter',
|
||||
'font_icon',
|
||||
'button_icon',
|
||||
'hover_icon',
|
||||
'scroll_down_icon',
|
||||
'social_network',
|
||||
'show_in_lightbox',
|
||||
'fullwidth',
|
||||
'scroll_vertical_motion_enable',
|
||||
'scroll_horizontal_motion_enable',
|
||||
'scroll_fade_enable',
|
||||
'scroll_scaling_enable',
|
||||
'scroll_rotating_enable',
|
||||
'scroll_blur_enable',
|
||||
'show_content',
|
||||
]
|
||||
);
|
||||
|
||||
/**
|
||||
* The "gallery" shortcode is not part of the Divi modules but is used for enqueuing MagnificPopup
|
||||
* when Divi Gallery is enabled under Theme Options > Enable Divi Gallery, so we need to include
|
||||
* it in late detection for edge cases such as shortcodes hardcoded into child themes.
|
||||
*/
|
||||
$additional_valid_slugs = apply_filters(
|
||||
'et_builder_valid_module_slugs',
|
||||
[
|
||||
'gallery',
|
||||
]
|
||||
);
|
||||
|
||||
$valid_slugs = array_unique( array_merge( $this->_valid_slugs, $additional_valid_slugs ) );
|
||||
|
||||
// Log the shortcode tags used.
|
||||
if ( in_array( $tag, $valid_slugs, true ) ) {
|
||||
$this->_modules_used[] = $tag;
|
||||
$this->_modules_used = array_unique( $this->_modules_used );
|
||||
|
||||
if ( ! is_null( $attrs ) && ! is_array( $attrs ) ) {
|
||||
$attrs = (array) $attrs;
|
||||
}
|
||||
|
||||
$found_interested_attr_and_values = array_intersect( array_keys( $attrs ), $interested_attrs_and_values );
|
||||
foreach ( $found_interested_attr_and_values as $key => $attr_name ) {
|
||||
if ( empty( $this->_module_attr_values_used[ $attr_name ] ) ) {
|
||||
$this->_module_attr_values_used[ $attr_name ] = [];
|
||||
}
|
||||
|
||||
$this->_module_attr_values_used[ $attr_name ][] = $attrs[ $attr_name ];
|
||||
$this->_module_attr_values_used[ $attr_name ] = array_unique( $this->_module_attr_values_used[ $attr_name ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add footer actions.
|
||||
*/
|
||||
public function footer() {
|
||||
/**
|
||||
* Fires after wp_footer hook and contains unique array of
|
||||
* slugs of the modules that were used on the page load.
|
||||
*
|
||||
* @param array $_used_modules Module slugs used on the page load.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
do_action( 'et_builder_modules_used', $this->_modules_used );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get modules used.
|
||||
*
|
||||
* @return array List of module slugs used.
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_modules_used() {
|
||||
return $this->_modules_used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module attrs used.
|
||||
*
|
||||
* @return array List of interested module attrs used.
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_module_attrs_used() {
|
||||
return $this->_module_attrs_used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module attr values used.
|
||||
*
|
||||
* @return array List of interested module attrs and values used.
|
||||
* @since 4.10.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_module_attr_values_used() {
|
||||
return $this->_module_attr_values_used;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ET_Builder_Module_Use_Detection::instance();
|
46
includes/builder/class-et-builder-plugin-compat-base.php
Normal file
46
includes/builder/class-et-builder-plugin-compat-base.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for plugin compatibility file
|
||||
*
|
||||
* @since 0.7 (builder version)
|
||||
*/
|
||||
class ET_Builder_Plugin_Compat_Base {
|
||||
public $plugin_id;
|
||||
|
||||
/**
|
||||
* Get plugin dir path based on plugin_id
|
||||
*
|
||||
* @return sting
|
||||
*/
|
||||
function get_plugin_dir_path() {
|
||||
return WP_PLUGIN_DIR . '/' . $this->plugin_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin data based on initialized plugin_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_plugin_data() {
|
||||
return get_plugin_data( $this->get_plugin_dir_path(), false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin version based on initialized plugin_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_plugin_version() {
|
||||
$plugin_data = $this->get_plugin_data();
|
||||
|
||||
if ( ! isset( $plugin_data['Version'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $plugin_data['Version'];
|
||||
}
|
||||
}
|
74
includes/builder/class-et-builder-plugin-compat-loader.php
Normal file
74
includes/builder/class-et-builder-plugin-compat-loader.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Load plugin compatibility file if supported plugins are activated.
|
||||
*
|
||||
* @since 0.7 (builder version)
|
||||
*
|
||||
* @package Divi
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ET_Builder_Plugin_Compat_Loader.
|
||||
*/
|
||||
class ET_Builder_Plugin_Compat_Loader {
|
||||
/**
|
||||
* Unique instance of class.
|
||||
*
|
||||
* @var ET_Builder_Plugin_Compat_Loader
|
||||
*/
|
||||
public static $instance;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instance of the class.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook methods to WordPress action and filter.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function init_hooks() {
|
||||
// Load plugin.php for frontend usage.
|
||||
if ( ! function_exists( 'is_plugin_active' ) || ! function_exists( 'get_plugins' ) ) {
|
||||
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
// Loop plugin list and load active plugin compatibility file.
|
||||
foreach ( array_keys( get_plugins() ) as $plugin ) {
|
||||
// Load plugin compat file if plugin is active.
|
||||
if ( is_plugin_active( $plugin ) ) {
|
||||
$plugin_compat_name = dirname( $plugin );
|
||||
$plugin_compat_url = apply_filters(
|
||||
"et_builder_plugin_compat_path_{$plugin_compat_name}",
|
||||
ET_BUILDER_DIR . "plugin-compat/{$plugin_compat_name}.php",
|
||||
$plugin_compat_name
|
||||
);
|
||||
|
||||
// Load plugin compat file (if compat file found).
|
||||
if ( file_exists( $plugin_compat_url ) ) {
|
||||
require_once $plugin_compat_url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ET_Builder_Plugin_Compat_Loader::init();
|
311
includes/builder/class-et-builder-post-feature-base.php
Normal file
311
includes/builder/class-et-builder-post-feature-base.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/**
|
||||
* Feature base class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Post Based Feature Base.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Post_Feature_Base {
|
||||
|
||||
|
||||
// Only save cache if time (milliseconds) to generate it is above this threshold.
|
||||
const CACHE_SAVE_THRESHOLD = 15;
|
||||
const CACHE_META_KEY = '_et_builder_module_feature_cache';
|
||||
|
||||
/**
|
||||
* Post ID.
|
||||
*
|
||||
* @access protected
|
||||
* @var int
|
||||
*/
|
||||
protected $_post_id = 0;
|
||||
|
||||
/**
|
||||
* Primed status.
|
||||
*
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $_primed = false;
|
||||
|
||||
/**
|
||||
* Cache array.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_cache = [];
|
||||
|
||||
/**
|
||||
* Total time needed to populate the cache.
|
||||
*
|
||||
* @access protected
|
||||
* @var float
|
||||
*/
|
||||
protected $_cache_set_time = 0;
|
||||
|
||||
/**
|
||||
* Whether the feature manager is enabled.
|
||||
*
|
||||
* @access protected
|
||||
* @var null|bool
|
||||
*/
|
||||
protected static $_enabled = null;
|
||||
|
||||
/**
|
||||
* Whether this page load is loading the cache or using existing cache.
|
||||
*
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $_cache_loading = false;
|
||||
|
||||
/**
|
||||
* `ET_Builder_Post_Feature_Base` instance.
|
||||
*
|
||||
* @var ET_Builder_Post_Feature_Base
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* Construct instance.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( self::enabled() ) {
|
||||
$this->_post_id = ET_Builder_Element::get_current_post_id();
|
||||
|
||||
$this->cache_prime();
|
||||
|
||||
if ( ! has_action( 'shutdown', [ $this, 'cache_save' ] ) ) {
|
||||
add_action( 'shutdown', [ $this, 'cache_save' ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize ET_Builder_Post_Feature_Base class.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new static();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the features cache for a given post.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param int $post_id The post ID to purge cache from.
|
||||
*/
|
||||
public static function purge_cache( $post_id = '' ) {
|
||||
if ( $post_id ) {
|
||||
delete_post_meta( $post_id, static::CACHE_META_KEY );
|
||||
} else {
|
||||
delete_post_meta_by_key( static::CACHE_META_KEY );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the features cache for a given post.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param int $post_id The post ID to get cache from.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function load_cache( $post_id ) {
|
||||
return get_post_meta( $post_id, static::CACHE_META_KEY, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether we should use cache or not.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function enabled() {
|
||||
if ( null === self::$_enabled ) {
|
||||
|
||||
$et_dynamic_module_framework = et_builder_dynamic_module_framework();
|
||||
|
||||
$enabled = et_builder_is_frontend() && 'on' === $et_dynamic_module_framework;
|
||||
|
||||
/**
|
||||
* Whether Post Feature Cache should be enabled or not.
|
||||
*
|
||||
* @since ?
|
||||
*
|
||||
* @param bool $enabled.
|
||||
*/
|
||||
self::$_enabled = apply_filters( 'et_builder_post_feature_cache_enabled', $enabled );
|
||||
}
|
||||
|
||||
return self::$_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prime the cache.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function cache_prime() {
|
||||
if ( empty( $this->_primed ) ) {
|
||||
|
||||
$meta = self::load_cache( $this->_post_id );
|
||||
$current_index = (string) self::_get_cache_index();
|
||||
$stored_index = null;
|
||||
|
||||
if ( isset( $meta[1] ) ) {
|
||||
list( $stored_index, $cache ) = $meta;
|
||||
$this->_cache = ( $current_index === $stored_index ) ? $cache : [];
|
||||
}
|
||||
|
||||
do_action( 'et_builder_post_feature_cache_primed', $this->_cache, $this->_post_id, $current_index, $stored_index );
|
||||
|
||||
// determine if were loading cache,
|
||||
// or using previous cache values.
|
||||
$this->_cache_loading = empty( $this->_cache );
|
||||
|
||||
$this->_primed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the cache.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function cache_save() {
|
||||
if ( ! self::enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_index = self::_get_cache_index();
|
||||
$is_above_threshold = $this->_cache_set_time >= self::CACHE_SAVE_THRESHOLD;
|
||||
|
||||
do_action( 'et_builder_post_feature_cache_save', $this->_cache, $this->_post_id, $this->_cache_set_time, $is_above_threshold, $cache_index );
|
||||
|
||||
// Only save cache if time to generate it is above a certain threshold.
|
||||
if ( $is_above_threshold ) {
|
||||
$cache = array( $cache_index, $this->_cache );
|
||||
update_post_meta( $this->_post_id, static::CACHE_META_KEY, $cache );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cache Version Index Items.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access protected
|
||||
* @return array Cache version items.
|
||||
*/
|
||||
protected static function _get_cache_index_items() {
|
||||
global $wp_version;
|
||||
|
||||
$dynamic_assets = ET_Dynamic_Assets::init();
|
||||
$tb_ids = $dynamic_assets->get_theme_builder_template_ids();
|
||||
|
||||
$tb_data = [];
|
||||
foreach ( $tb_ids as $tb_id ) {
|
||||
$tb_post = get_post( $tb_id );
|
||||
$tb_data[ $tb_id ] = $tb_post->post_modified_gmt;
|
||||
}
|
||||
|
||||
return array(
|
||||
'gph' => ET_Builder_Global_Presets_History::instance()->get_global_history_index(),
|
||||
'divi' => et_get_theme_version(),
|
||||
'wp' => $wp_version,
|
||||
'tb' => $tb_data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cache Version Index.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @access protected
|
||||
* @return string .Cache version index.
|
||||
*/
|
||||
protected static function _get_cache_index() {
|
||||
return wp_json_encode( self::_get_cache_index_items() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $key Cache key.
|
||||
* @param string $group Cache group.
|
||||
*/
|
||||
public function cache_get( $key, $group = 'default' ) {
|
||||
$exists = isset( $this->_cache[ $group ] ) && isset( $this->_cache[ $group ][ $key ] );
|
||||
return $exists ? $this->_cache[ $group ][ $key ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $key Cache key.
|
||||
* @param mixed $value To be cached.
|
||||
* @param string $group Cache group.
|
||||
* @param float $elapsed How much time it took to generate the value.
|
||||
*/
|
||||
public function cache_set( $key, $value, $group = 'default', $elapsed = 0 ) {
|
||||
// Only save truthy values into cache.
|
||||
if ( $value ) {
|
||||
$this->_cache[ $group ][ $key ] = $value;
|
||||
}
|
||||
$this->_cache_set_time += $elapsed * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for cached value.
|
||||
*
|
||||
* First check cache if present, if not, determine
|
||||
* from calling the callback.
|
||||
*
|
||||
* @param string $key Name of item.
|
||||
* @param function $cb Callback function to perform logic.
|
||||
* @param string $group Cache group.
|
||||
*
|
||||
* @return bool/mixed Result.
|
||||
*/
|
||||
public function get( $key, $cb, $group = 'default' ) {
|
||||
if ( ! self::enabled() ) {
|
||||
return $cb();
|
||||
}
|
||||
|
||||
$result = $this->cache_get( $key, $group );
|
||||
|
||||
if ( is_null( $result ) ) {
|
||||
if ( $this->_cache_loading ) {
|
||||
// Set cache for next time.
|
||||
$before = microtime( true );
|
||||
$result = $cb();
|
||||
$elapsed = microtime( true ) - $before;
|
||||
|
||||
$this->cache_set( $key, $result, $group, $elapsed );
|
||||
} else {
|
||||
// No entry found in a previsouly loaded cache,
|
||||
// means the answer was falsey last time $cb() was checked,
|
||||
// as falsey values arent stored in cache.
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
1605
includes/builder/class-et-builder-settings.php
Normal file
1605
includes/builder/class-et-builder-settings.php
Normal file
File diff suppressed because it is too large
Load Diff
47
includes/builder/class-et-builder-theme-compat-base.php
Normal file
47
includes/builder/class-et-builder-theme-compat-base.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Theme compat base class.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for plugin compatibility file.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*/
|
||||
class ET_Builder_Theme_Compat_Base {
|
||||
|
||||
/**
|
||||
* Theme name.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
public $theme_id;
|
||||
|
||||
/**
|
||||
* Get theme dir path based on theme_id.
|
||||
*
|
||||
* @return sting
|
||||
*/
|
||||
public function get_theme_dir_path() {
|
||||
return get_stylesheet_directory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get theme data.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function get_theme_data() {
|
||||
return wp_get_theme();
|
||||
}
|
||||
|
||||
}
|
68
includes/builder/class-et-builder-theme-compat-handler.php
Normal file
68
includes/builder/class-et-builder-theme-compat-handler.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Load theme compatibility file for current theme.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @package Divi
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ET_Builder_Plugin_Compat_Loader.
|
||||
*/
|
||||
class ET_Builder_Theme_Compat_Handler {
|
||||
/**
|
||||
* Unique instance of class.
|
||||
*
|
||||
* @var ET_Builder_Theme_Compat_Handler
|
||||
*/
|
||||
public static $instance;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->_init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instance of the class.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook methods to WordPress action and filter.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _init_hooks() {
|
||||
// Load plugin.php for frontend usage.
|
||||
if ( ! function_exists( 'wp_get_theme' ) ) {
|
||||
include_once ABSPATH . 'wp-admin/includes/theme.php';
|
||||
}
|
||||
|
||||
$current_theme = wp_get_theme();
|
||||
$current_theme_name = $current_theme->get( 'TextDomain' );
|
||||
$theme_compat_url = apply_filters(
|
||||
"et_builder_theme_compat_path_{$current_theme_name}",
|
||||
ET_BUILDER_DIR . "theme-compat/{$current_theme_name}.php",
|
||||
$current_theme_name
|
||||
);
|
||||
|
||||
if ( file_exists( $theme_compat_url ) ) {
|
||||
require_once $theme_compat_url;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ET_Builder_Theme_Compat_Handler::init();
|
110
includes/builder/class-et-builder-value.php
Normal file
110
includes/builder/class-et-builder-value.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Represent a simple value or a dynamic one.
|
||||
* Used for module attributes and content.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 3.17.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class ET_Builder_Value.
|
||||
*/
|
||||
class ET_Builder_Value {
|
||||
/**
|
||||
* Flag whether the value is static or dynamic.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $dynamic = false;
|
||||
|
||||
/**
|
||||
* Value content. Represents the dynamic content type when dynamic.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $content = '';
|
||||
|
||||
/**
|
||||
* Array of dynamic content settings.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @var mixed[]
|
||||
*/
|
||||
protected $settings = array();
|
||||
|
||||
/**
|
||||
* ET_Builder_Value constructor.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @param boolean $dynamic Whether content is dynamic.
|
||||
* @param string $content Value content.
|
||||
* @param array $settings Dynamic content settings.
|
||||
*/
|
||||
public function __construct( $dynamic, $content, $settings = array() ) {
|
||||
$this->dynamic = $dynamic;
|
||||
$this->content = $content;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value is dynamic or not.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_dynamic() {
|
||||
return $this->dynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value content.
|
||||
*
|
||||
* @since 4.4.4
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_content() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resolved content.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @param integer $post_id Post id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function resolve( $post_id ) {
|
||||
if ( ! $this->dynamic ) {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
return et_builder_resolve_dynamic_content( $this->content, $this->settings, $post_id, 'display' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the static content or a serialized representation of the dynamic one.
|
||||
*
|
||||
* @since 3.17.2
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize() {
|
||||
if ( ! $this->dynamic ) {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
return et_builder_serialize_dynamic_content( $this->dynamic, $this->content, $this->settings );
|
||||
}
|
||||
}
|
756
includes/builder/class-et-global-settings.php
Normal file
756
includes/builder/class-et-global-settings.php
Normal file
@ -0,0 +1,756 @@
|
||||
<?php
|
||||
/**
|
||||
* Global modules settings.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
*/
|
||||
|
||||
/**
|
||||
* Global settings class.
|
||||
*
|
||||
* @todo Rename this class to `ET_Builder_Module_Settings` so that its name clearly indicates its purpose.
|
||||
*/
|
||||
class ET_Global_Settings {
|
||||
/**
|
||||
* List of default settings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_settings = array();
|
||||
|
||||
/**
|
||||
* Whether reinit default setting values.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $_reinit_values = false;
|
||||
|
||||
/**
|
||||
* Initialize the global settings.
|
||||
*/
|
||||
public static function init() {
|
||||
// The class can only be initialized once.
|
||||
if ( ! empty( self::$_settings ) && ! self::$_reinit_values ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset _reinit_values property. It should only used once for every reinit() method call.
|
||||
if ( self::$_reinit_values ) {
|
||||
self::$_reinit_values = false;
|
||||
}
|
||||
|
||||
self::set_values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow global settings value to be reinitialized. Initially added a to make global
|
||||
* settings modifieable during unit/integration testing which uses PHPUnit & wp-browser
|
||||
*/
|
||||
public static function reinit() {
|
||||
self::$_reinit_values = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default global setting value
|
||||
*/
|
||||
private static function set_values() {
|
||||
$hover = et_pb_hover_options();
|
||||
|
||||
$font_defaults_h1 = array(
|
||||
'size' => '30px',
|
||||
'letter_spacing' => '0px',
|
||||
'line_height' => '1em',
|
||||
);
|
||||
|
||||
$font_defaults_h2 = array(
|
||||
'size' => '26px',
|
||||
'letter_spacing' => '0px',
|
||||
'line_height' => '1em',
|
||||
);
|
||||
|
||||
$font_defaults = array(
|
||||
'size' => '14',
|
||||
'color' => '#666666',
|
||||
'letter_spacing' => '0px',
|
||||
'line_height' => '1.7em',
|
||||
);
|
||||
|
||||
$background_gradient_defaults = array(
|
||||
'start' => '#2b87da',
|
||||
'end' => '#29c4a9',
|
||||
'type' => 'linear',
|
||||
'direction' => '180deg',
|
||||
'direction_radial' => 'center',
|
||||
'start_position' => '0%',
|
||||
'end_position' => '100%',
|
||||
'overlays_image' => 'off',
|
||||
);
|
||||
|
||||
$background_image_defaults = array(
|
||||
'size' => 'cover',
|
||||
'position' => 'center',
|
||||
'repeat' => 'no-repeat',
|
||||
'blend' => 'normal',
|
||||
);
|
||||
|
||||
$background_blend_mode_defaults = array(
|
||||
'background_blend_mode' => $background_image_defaults['blend'],
|
||||
);
|
||||
|
||||
$filter_defaults = array(
|
||||
'filter_hue_rotate' => '0deg',
|
||||
'filter_saturate' => '100%',
|
||||
'filter_brightness' => '100%',
|
||||
'filter_contrast' => '100%',
|
||||
'filter_invert' => '0%',
|
||||
'filter_sepia' => '0%',
|
||||
'filter_opacity' => '100%',
|
||||
'filter_blur' => '0px',
|
||||
);
|
||||
|
||||
$defaults = array(
|
||||
// Global: Buttons.
|
||||
'all_buttons_font_size' => '20',
|
||||
'all_buttons_border_width' => '2',
|
||||
'all_buttons_border_radius' => '3',
|
||||
'all_buttons_spacing' => '0',
|
||||
'all_buttons_font_style' => '',
|
||||
$hover->get_hover_field( 'all_buttons_border_radius' ) => '3',
|
||||
$hover->get_hover_field( 'all_buttons_spacing' ) => '0',
|
||||
// Global: Background Gradients.
|
||||
'all_background_gradient_start' => $background_gradient_defaults['start'],
|
||||
'all_background_gradient_end' => $background_gradient_defaults['end'],
|
||||
'all_background_gradient_type' => $background_gradient_defaults['type'],
|
||||
'all_background_gradient_direction' => $background_gradient_defaults['direction'],
|
||||
'all_background_gradient_direction_radial' => $background_gradient_defaults['direction_radial'],
|
||||
'all_background_gradient_start_position' => $background_gradient_defaults['start_position'],
|
||||
'all_background_gradient_end_position' => $background_gradient_defaults['end_position'],
|
||||
'all_background_gradient_overlays_image' => $background_gradient_defaults['overlays_image'],
|
||||
// Global: Filters.
|
||||
'all_filter_hue_rotate' => $filter_defaults['filter_hue_rotate'],
|
||||
'all_filter_saturate' => $filter_defaults['filter_saturate'],
|
||||
'all_filter_brightness' => $filter_defaults['filter_brightness'],
|
||||
'all_filter_contrast' => $filter_defaults['filter_contrast'],
|
||||
'all_filter_invert' => $filter_defaults['filter_invert'],
|
||||
'all_filter_sepia' => $filter_defaults['filter_sepia'],
|
||||
'all_filter_opacity' => $filter_defaults['filter_opacity'],
|
||||
'all_filter_blur' => $filter_defaults['filter_blur'],
|
||||
// Global: Mix Blend Mode.
|
||||
'all_mix_blend_mode' => 'normal',
|
||||
// Module: Accordion.
|
||||
'et_pb_accordion-toggle_font_size' => '16',
|
||||
'et_pb_accordion-toggle_font_style' => '',
|
||||
'et_pb_accordion-inactive_toggle_font_style' => '',
|
||||
'et_pb_accordion-toggle_icon_size' => '16',
|
||||
'et_pb_accordion-custom_padding' => '20',
|
||||
'et_pb_accordion-toggle_line_height' => '1em',
|
||||
'et_pb_accordion-toggle_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_accordion-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_accordion-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_accordion-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
// Module: Audio.
|
||||
'et_pb_audio-title_font_size' => '26',
|
||||
'et_pb_audio-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_audio-title_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_audio-title_font_style' => '',
|
||||
'et_pb_audio-caption_font_size' => $font_defaults['size'],
|
||||
'et_pb_audio-caption_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_audio-caption_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_audio-caption_font_style' => '',
|
||||
'et_pb_audio-title_text_color' => '#666666',
|
||||
'et_pb_audio-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_audio-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_audio-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_audio-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Blog.
|
||||
'et_pb_blog-header_font_size' => '18',
|
||||
'et_pb_blog-header_font_style' => '',
|
||||
'et_pb_blog-meta_font_size' => '14',
|
||||
'et_pb_blog-meta_font_style' => '',
|
||||
'et_pb_blog-meta_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_blog-meta_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_blog-header_color' => '#333333',
|
||||
'et_pb_blog-header_line_height' => '1em',
|
||||
'et_pb_blog-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_blog-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_blog-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_blog-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_blog-pagination_font_size' => $font_defaults['size'],
|
||||
'et_pb_blog-pagination_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_blog-pagination_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_blog_masonry-header_font_size' => '26',
|
||||
'et_pb_blog_masonry-header_font_style' => '',
|
||||
'et_pb_blog_masonry-meta_font_size' => '14',
|
||||
'et_pb_blog_masonry-meta_font_style' => '',
|
||||
'et_pb_blog-read_more_font_size' => '14px',
|
||||
'et_pb_blog-read_more_line_height' => $font_defaults['line_height'],
|
||||
// Module: Blurb.
|
||||
'et_pb_blurb-header_font_size' => '18',
|
||||
'et_pb_blurb-header_color' => '#333333',
|
||||
'et_pb_blurb-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_blurb-header_line_height' => '1em',
|
||||
'et_pb_blurb-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_blurb-body_color' => '#666666',
|
||||
'et_pb_blurb-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_blurb-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_blurb-text_orientation' => 'left',
|
||||
'et_pb_blurb-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_blurb-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_blurb-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_blurb-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Circle Counter.
|
||||
'et_pb_circle_counter-title_font_size' => '16',
|
||||
'et_pb_circle_counter-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_circle_counter-title_line_height' => '1em',
|
||||
'et_pb_circle_counter-title_font_style' => '',
|
||||
'et_pb_circle_counter-number_font_size' => '46',
|
||||
'et_pb_circle_counter-number_font_style' => '',
|
||||
'et_pb_circle_counter-title_color' => '#333333',
|
||||
'et_pb_circle_counter-number_line_height' => '225px',
|
||||
'et_pb_circle_counter-number_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_circle_counter-circle_color_alpha' => '0.1',
|
||||
// Module: Comments.
|
||||
'et_pb_comments-header_font_size' => $font_defaults_h1['size'],
|
||||
'et_pb_comments-header_line_height' => $font_defaults_h1['line_height'],
|
||||
// Module: Contact Form.
|
||||
'et_pb_contact_form-title_font_size' => '26',
|
||||
'et_pb_contact_form-title_font_style' => '',
|
||||
'et_pb_contact_form-form_field_font_size' => '14',
|
||||
'et_pb_contact_form-form_field_font_style' => '',
|
||||
'et_pb_contact_form-captcha_font_size' => '14',
|
||||
'et_pb_contact_form-captcha_font_style' => '',
|
||||
'et_pb_contact_form-padding' => '16',
|
||||
'et_pb_contact_form-title_color' => '#333333',
|
||||
'et_pb_contact_form-title_line_height' => '1em',
|
||||
'et_pb_contact_form-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_contact_form-form_field_color' => '#999999',
|
||||
'et_pb_contact_form-form_field_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_contact_form-form_field_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
// Module: Countdown Timer.
|
||||
'et_pb_countdown_timer-header_font_size' => '22',
|
||||
'et_pb_countdown_timer-header_font_style' => '',
|
||||
'et_pb_countdown_timer-header_color' => '#333333',
|
||||
'et_pb_countdown_timer-header_line_height' => '1em',
|
||||
'et_pb_countdown_timer-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_countdown_timer-numbers_font_size' => '54px',
|
||||
'et_pb_countdown_timer-numbers_line_height' => '54px',
|
||||
'et_pb_countdown_timer-numbers_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_countdown_timer-separator_font_size' => '54px',
|
||||
'et_pb_countdown_timer-separator_line_height' => '54px',
|
||||
'et_pb_countdown_timer-separator_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_countdown_timer-label_line_height' => '25px',
|
||||
'et_pb_countdown_timer-label_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_countdown_timer-label_font_size' => $font_defaults['size'],
|
||||
'et_pb_countdown_timer-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_countdown_timer-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_countdown_timer-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_countdown_timer-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Bar Counters Item.
|
||||
'et_pb_counter-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_counter-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_counter-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_counter-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Bar Counters.
|
||||
'et_pb_counters-title_font_size' => '12',
|
||||
'et_pb_counters-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_counters-title_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_counters-title_font_style' => '',
|
||||
'et_pb_counters-percent_font_size' => '12',
|
||||
'et_pb_counters-percent_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_counters-percent_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_counters-percent_font_style' => '',
|
||||
'et_pb_counters-border_radius' => '0',
|
||||
'et_pb_counters-padding' => '0',
|
||||
'et_pb_counters-title_color' => '#999999',
|
||||
'et_pb_counters-percent_color' => '#ffffff',
|
||||
'et_pb_counters-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_counters-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_counters-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_counters-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: CTA.
|
||||
'et_pb_cta-header_font_size' => '26',
|
||||
'et_pb_cta-header_font_style' => '',
|
||||
'et_pb_cta-custom_padding' => '40',
|
||||
'et_pb_cta-header_text_color' => '#333333',
|
||||
'et_pb_cta-header_line_height' => '1em',
|
||||
'et_pb_cta-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_cta-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_cta-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_cta-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_cta-text_orientation' => 'center',
|
||||
'et_pb_cta-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_cta-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_cta-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_cta-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Divider.
|
||||
'et_pb_divider-divider_style' => 'solid',
|
||||
'et_pb_divider-divider_weight' => '1',
|
||||
'et_pb_divider-height' => '1',
|
||||
'et_pb_divider-divider_position' => 'top',
|
||||
// Module: Filterable Portfolio.
|
||||
'et_pb_filterable_portfolio-hover_overlay_color' => 'rgba(255,255,255,0.9)',
|
||||
'et_pb_filterable_portfolio-title_font_size' => '18',
|
||||
'et_pb_filterable_portfolio-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_filterable_portfolio-title_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_filterable_portfolio-title_font_style' => '',
|
||||
'et_pb_filterable_portfolio-title_color' => '#333333',
|
||||
'et_pb_filterable_portfolio-caption_font_size' => '14',
|
||||
'et_pb_filterable_portfolio-caption_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_filterable_portfolio-caption_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_filterable_portfolio-caption_font_style' => '',
|
||||
'et_pb_filterable_portfolio-filter_font_size' => '14',
|
||||
'et_pb_filterable_portfolio-filter_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_filterable_portfolio-filter_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_filterable_portfolio-filter_font_style' => '',
|
||||
'et_pb_filterable_portfolio-pagination_font_size' => '14',
|
||||
'et_pb_filterable_portfolio-pagination_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_filterable_portfolio-pagination_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_filterable_portfolio-pagination_font_style' => '',
|
||||
'et_pb_filterable_portfolio-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_filterable_portfolio-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_filterable_portfolio-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_filterable_portfolio-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_filterable_portfolio-zoom_icon_color' => '',
|
||||
// Module: Fullwidth Header.
|
||||
'et_pb_fullwidth_header-scroll_down_icon_size' => '50px',
|
||||
'et_pb_fullwidth_header-subhead_font_size' => '18px',
|
||||
'et_pb_fullwidth_header-button_one_font_size' => '20px',
|
||||
'et_pb_fullwidth_header-button_one_border_radius' => '3px',
|
||||
'et_pb_fullwidth_header-button_two_font_size' => '20px',
|
||||
'et_pb_fullwidth_header-button_two_border_radius' => '3px',
|
||||
'et_pb_fullwidth_header-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_fullwidth_header-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_fullwidth_header-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_fullwidth_header-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Fullwidth Menu.
|
||||
'et_pb_fullwidth_menu-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_fullwidth_menu-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_fullwidth_menu-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_fullwidth_menu-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Fullwidth Portfolio.
|
||||
'et_pb_fullwidth_portfolio-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_fullwidth_portfolio-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_fullwidth_portfolio-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_fullwidth_portfolio-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_fullwidth_portfolio-zoom_icon_color' => '',
|
||||
// Module: Fullwidth Post Title.
|
||||
'et_pb_fullwidth_post_title-title_font_size' => '26px',
|
||||
'et_pb_fullwidth_post_title-title_line_height' => '1em',
|
||||
'et_pb_fullwidth_post_title-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_fullwidth_post_title-meta_font_size' => $font_defaults['size'],
|
||||
'et_pb_fullwidth_post_title-meta_line_height' => '1em',
|
||||
'et_pb_fullwidth_post_title-meta_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
// Module: Fullwidth Slider.
|
||||
'et_pb_fullwidth_slider-header_font_size' => '46',
|
||||
'et_pb_fullwidth_slider-header_font_style' => '',
|
||||
'et_pb_fullwidth_slider-body_font_size' => '16',
|
||||
'et_pb_fullwidth_slider-body_font_style' => '',
|
||||
'et_pb_fullwidth_slider-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_fullwidth_slider-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_fullwidth_slider-padding' => '16',
|
||||
'et_pb_fullwidth_slider-header_color' => '#ffffff',
|
||||
'et_pb_fullwidth_slider-header_line_height' => '1em',
|
||||
'et_pb_fullwidth_slider-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_fullwidth_slider-body_color' => '#ffffff',
|
||||
'et_pb_fullwidth_slider-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_fullwidth_slider-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_fullwidth_slider-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_fullwidth_slider-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Gallery.
|
||||
'et_pb_gallery-hover_overlay_color' => 'rgba(255,255,255,0.9)',
|
||||
'et_pb_gallery-title_font_size' => '16',
|
||||
'et_pb_gallery-title_color' => '#333333',
|
||||
'et_pb_gallery-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_gallery-title_line_height' => '1em',
|
||||
'et_pb_gallery-title_font_style' => '',
|
||||
'et_pb_gallery-caption_font_size' => '14',
|
||||
'et_pb_gallery-caption_font_style' => '',
|
||||
'et_pb_gallery-caption_color' => '#f3f3f3',
|
||||
'et_pb_gallery-caption_line_height' => '18px',
|
||||
'et_pb_gallery-caption_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_gallery-pagination_font_size' => '16px',
|
||||
'et_pb_gallery-pagination_line_height' => '1em',
|
||||
'et_pb_gallery-zoom_icon_color' => '',
|
||||
// Module: Image.
|
||||
'et_pb_image-animation' => 'left',
|
||||
// Module: Login.
|
||||
'et_pb_login-header_font_size' => '26',
|
||||
'et_pb_login-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_login-header_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_login-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_login-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_login-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_login-header_font_style' => '',
|
||||
'et_pb_login-custom_padding' => '40',
|
||||
'et_pb_login-focus_border_color' => '#ffffff',
|
||||
'et_pb_login-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_login-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_login-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_login-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Menu.
|
||||
'et_pb_menu-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_menu-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_menu-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_menu-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Number Counter.
|
||||
'et_pb_number_counter-title_font_size' => '16',
|
||||
'et_pb_number_counter-title_line_height' => '1em',
|
||||
'et_pb_number_counter-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_number_counter-title_font_style' => '',
|
||||
'et_pb_number_counter-number_font_size' => '72',
|
||||
'et_pb_number_counter-number_line_height' => '72px',
|
||||
'et_pb_number_counter-number_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_number_counter-number_font_style' => '',
|
||||
'et_pb_number_counter-title_color' => '#333333',
|
||||
'et_pb_number_counter-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_number_counter-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_number_counter-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_number_counter-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Portfolio.
|
||||
'et_pb_portfolio-hover_overlay_color' => 'rgba(255,255,255,0.9)',
|
||||
'et_pb_portfolio-title_font_size' => '18',
|
||||
'et_pb_portfolio-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_portfolio-title_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_portfolio-title_font_style' => '',
|
||||
'et_pb_portfolio-title_color' => '#333333',
|
||||
'et_pb_portfolio-caption_font_size' => '14',
|
||||
'et_pb_portfolio-caption_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_portfolio-caption_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_portfolio-caption_font_style' => '',
|
||||
'et_pb_portfolio-pagination_font_size' => '14',
|
||||
'et_pb_portfolio-pagination_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_portfolio-pagination_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_portfolio-pagination_font_style' => '',
|
||||
'et_pb_portfolio-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_portfolio-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_portfolio-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_portfolio-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_portfolio-zoom_icon_color' => '',
|
||||
// Module: Post Title.
|
||||
'et_pb_post_title-title_font_size' => '26px',
|
||||
'et_pb_post_title-title_line_height' => '1em',
|
||||
'et_pb_post_title-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_post_title-meta_font_size' => $font_defaults['size'],
|
||||
'et_pb_post_title-meta_line_height' => '1em',
|
||||
'et_pb_post_title-meta_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_post_title-parallax' => 'off',
|
||||
'et_pb_post_title-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_post_title-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_post_title-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_post_title-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Post Slider.
|
||||
'et_pb_post_slider-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_post_slider-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_post_slider-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_post_slider-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Pricing Tables Item (Pricing Table).
|
||||
'et_pb_pricing_table-header_font_size' => '22px',
|
||||
'et_pb_pricing_table-header_color' => '#ffffff',
|
||||
'et_pb_pricing_table-header_line_height' => '1em',
|
||||
'et_pb_pricing_table-subheader_font_size' => '16px',
|
||||
'et_pb_pricing_table-subheader_color' => '#ffffff',
|
||||
'et_pb_pricing_table-price_font_size' => '80px',
|
||||
'et_pb_pricing_table-price_color' => '#2EA3F2',
|
||||
'et_pb_pricing_table-price_line_height' => '82px',
|
||||
'et_pb_pricing_table-body_line_height' => '24px',
|
||||
'et_pb_pricing_table-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_pricing_table-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_pricing_table-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_pricing_table-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_pricing_table-excluded_letter_spacing' => '0px',
|
||||
'et_pb_pricing_table-excluded_line_height' => '1.7em',
|
||||
// Module: Pricing Tables.
|
||||
'et_pb_pricing_tables-header_font_size' => '22',
|
||||
'et_pb_pricing_tables-header_font_style' => '',
|
||||
'et_pb_pricing_tables-subheader_font_size' => '16',
|
||||
'et_pb_pricing_tables-subheader_font_style' => '',
|
||||
'et_pb_pricing_tables-price_font_size' => '80',
|
||||
'et_pb_pricing_tables-price_font_style' => '',
|
||||
'et_pb_pricing_tables-header_color' => '#ffffff',
|
||||
'et_pb_pricing_tables-header_line_height' => '1em',
|
||||
'et_pb_pricing_tables-subheader_color' => '#ffffff',
|
||||
'et_pb_pricing_tables-currency_frequency_font_size' => '16px',
|
||||
'et_pb_pricing_tables-currency_frequency_letter_spacing' => '0px',
|
||||
'et_pb_pricing_tables-currency_frequency_line_height' => '1.7em',
|
||||
'et_pb_pricing_tables-price_letter_spacing' => '0px',
|
||||
'et_pb_pricing_tables-price_color' => '#2EA3F2',
|
||||
'et_pb_pricing_tables-price_line_height' => '82px',
|
||||
'et_pb_pricing_tables-body_line_height' => '24px',
|
||||
'et_pb_pricing_tables-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_pricing_tables-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_pricing_tables-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_pricing_tables-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_pricing_tables-excluded_letter_spacing' => '0px',
|
||||
'et_pb_pricing_tables-excluded_line_height' => '1.7em',
|
||||
// Module: Shop.
|
||||
'et_pb_shop-title_font_size' => '16',
|
||||
'et_pb_shop-title_font_style' => '',
|
||||
'et_pb_shop-sale_badge_font_size' => '16',
|
||||
'et_pb_shop-sale_badge_font_style' => '',
|
||||
'et_pb_shop-price_font_size' => '14',
|
||||
'et_pb_shop-price_font_style' => '',
|
||||
'et_pb_shop-sale_price_font_size' => '14',
|
||||
'et_pb_shop-sale_price_font_style' => '',
|
||||
'et_pb_shop-title_color' => '#333333',
|
||||
'et_pb_shop-title_line_height' => '1em',
|
||||
'et_pb_shop-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_shop-price_line_height' => '26px',
|
||||
'et_pb_shop-price_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
// Module: Sidebar.
|
||||
'et_pb_sidebar-header_font_size' => '18',
|
||||
'et_pb_sidebar-header_font_style' => '',
|
||||
'et_pb_sidebar-header_color' => '#333333',
|
||||
'et_pb_sidebar-header_line_height' => '1em',
|
||||
'et_pb_sidebar-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_sidebar-remove_border' => 'off',
|
||||
'et_pb_sidebar-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_sidebar-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_sidebar-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
// Module: Signup.
|
||||
'et_pb_signup-header_font_size' => '26',
|
||||
'et_pb_signup-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_signup-header_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_signup-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_signup-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_signup-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_signup-result_message_font_size' => $font_defaults_h2['size'],
|
||||
'et_pb_signup-result_message_line_height' => $font_defaults_h2['line_height'],
|
||||
'et_pb_signup-header_font_style' => '',
|
||||
'et_pb_signup-padding' => '20',
|
||||
'et_pb_signup-focus_border_color' => '#ffffff',
|
||||
'et_pb_signup-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_signup-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_signup-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_signup-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_signup-form_field_font_size' => '14',
|
||||
'et_pb_signup-form_field_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_signup_form-form_field_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
// Module: Slider Item (Slide).
|
||||
'et_pb_slide-header_font_size' => '26px',
|
||||
'et_pb_slide-header_color' => '#ffffff',
|
||||
'et_pb_slide-header_line_height' => '1em',
|
||||
'et_pb_slide-body_font_size' => '16px',
|
||||
'et_pb_slide-body_color' => '#ffffff',
|
||||
'et_pb_slide-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_slide-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_slide-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_slide-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Slider.
|
||||
'et_pb_slider-header_font_size' => '46',
|
||||
'et_pb_slider-header_line_height' => '1em',
|
||||
'et_pb_slider-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_slider-header_font_style' => '',
|
||||
'et_pb_slider-body_font_size' => '16',
|
||||
'et_pb_slider-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_slider-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_slider-body_font_style' => '',
|
||||
'et_pb_slider-padding' => '16',
|
||||
'et_pb_slider-header_color' => '#ffffff',
|
||||
'et_pb_slider-body_color' => '#ffffff',
|
||||
'et_pb_slider-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_slider-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_slider-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_slider-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Social Media Follow.
|
||||
'et_pb_social_media_follow-icon_size' => '14',
|
||||
'et_pb_social_media_follow-button_font_style' => '',
|
||||
// Module: Tabs.
|
||||
'et_pb_tabs-tab_font_size' => $font_defaults['size'],
|
||||
'et_pb_tabs-tab_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_tabs-tab_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_tabs-title_font_size' => $font_defaults['size'],
|
||||
'et_pb_tabs-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_tabs-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_tabs-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_tabs-title_font_style' => '',
|
||||
'et_pb_tabs-padding' => '30',
|
||||
'et_pb_tabs-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_tabs-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_tabs-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_tabs-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Tabs Item (Tab).
|
||||
'et_pb_tab-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_tab-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_tab-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_tab-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Team Member (Person).
|
||||
'et_pb_team_member-header_font_size' => '18',
|
||||
'et_pb_team_member-header_font_style' => '',
|
||||
'et_pb_team_member-subheader_font_size' => '14',
|
||||
'et_pb_team_member-subheader_font_style' => '',
|
||||
'et_pb_team_member-social_network_icon_size' => '16',
|
||||
'et_pb_team_member-header_color' => '#333333',
|
||||
'et_pb_team_member-header_line_height' => '1em',
|
||||
'et_pb_team_member-header_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_team_member-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_team_member-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_team_member-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_team_member-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_team_member-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_team_member-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_team_member-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Testimonial.
|
||||
'et_pb_testimonial-portrait_border_radius' => '90',
|
||||
'et_pb_testimonial-portrait_width' => '90',
|
||||
'et_pb_testimonial-portrait_height' => '90',
|
||||
'et_pb_testimonial-author_name_font_style' => 'bold',
|
||||
'et_pb_testimonial-author_details_font_style' => 'bold',
|
||||
'et_pb_testimonial-border_color' => '#ffffff',
|
||||
'et_pb_testimonial-border_width' => '1px',
|
||||
'et_pb_testimonial-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_testimonial-body_line_height' => '1.5em',
|
||||
'et_pb_testimonial-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_testimonial-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_testimonial-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_testimonial-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_testimonial-background_blend' => $background_image_defaults['blend'],
|
||||
'et_pb_testimonial-quote_icon_background_color' => '#f5f5f5',
|
||||
// Module: Text.
|
||||
'et_pb_text-header_font_size' => $font_defaults_h1['size'],
|
||||
'et_pb_text-header_letter_spacing' => $font_defaults_h1['letter_spacing'],
|
||||
'et_pb_text-header_line_height' => $font_defaults_h1['line_height'],
|
||||
'et_pb_text-text_font_size' => $font_defaults['size'],
|
||||
'et_pb_text-text_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_text-text_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_text-border_color' => '#ffffff',
|
||||
'et_pb_text-border_width' => '1px',
|
||||
'et_pb_text-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_text-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_text-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_text-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Toggle.
|
||||
'et_pb_toggle-title_font_size' => '16',
|
||||
'et_pb_toggle-title_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_toggle-title_font_style' => '',
|
||||
'et_pb_toggle-inactive_title_font_style' => '',
|
||||
'et_pb_toggle-toggle_icon_size' => '16',
|
||||
'et_pb_toggle-title_color' => '#333333',
|
||||
'et_pb_toggle-title_line_height' => '1em',
|
||||
'et_pb_toggle-custom_padding' => '20',
|
||||
'et_pb_toggle-body_font_size' => $font_defaults['size'],
|
||||
'et_pb_toggle-body_line_height' => $font_defaults['line_height'],
|
||||
'et_pb_toggle-body_letter_spacing' => $font_defaults['letter_spacing'],
|
||||
'et_pb_toggle-background_size' => $background_image_defaults['size'],
|
||||
'et_pb_toggle-background_position' => $background_image_defaults['position'],
|
||||
'et_pb_toggle-background_repeat' => $background_image_defaults['repeat'],
|
||||
'et_pb_toggle-background_blend' => $background_image_defaults['blend'],
|
||||
// Module: Woo Title.
|
||||
'et_pb_wc_title-header_font_size' => $font_defaults_h1['size'],
|
||||
'et_pb_wc_title-header_line_height' => '1em',
|
||||
'et_pb_wc_stock-in_stock_text_color' => '#77a464',
|
||||
// Global: Field Input.
|
||||
'all_field_font_size' => '16',
|
||||
'all_field_border_width' => '0',
|
||||
'all_field_border_radius' => '3',
|
||||
'all_field_spacing' => '0',
|
||||
'all_field_font_style' => '',
|
||||
$hover->get_hover_field( 'all_field_border_radius' ) => '3',
|
||||
$hover->get_hover_field( 'all_field_spacing' ) => '0',
|
||||
);
|
||||
|
||||
if ( et_builder_has_limitation( 'forced_icon_color_default' ) ) {
|
||||
$defaults['et_pb_gallery-zoom_icon_color'] = et_get_option( 'accent_color', '#2ea3f2' );
|
||||
$defaults['et_pb_portfolio-zoom_icon_color'] = et_get_option( 'accent_color', '#2ea3f2' );
|
||||
$defaults['et_pb_fullwidth-portfolio-zoom_icon_color'] = et_get_option( 'accent_color', '#2ea3f2' );
|
||||
$defaults['et_pb_filterable_portfolio-zoom_icon_color'] = et_get_option( 'accent_color', '#2ea3f2' );
|
||||
}
|
||||
|
||||
$module_presets_manager = ET_Builder_Global_Presets_Settings::instance();
|
||||
if ( ! et_is_builder_plugin_active() && ! ET_Builder_Global_Presets_Settings::is_customizer_migrated() ) {
|
||||
$module_presets_manager->migrate_customizer_settings( $defaults );
|
||||
}
|
||||
|
||||
$custom_defaults_unmigrated = et_get_option( ET_Builder_Global_Presets_Settings::CUSTOM_DEFAULTS_UNMIGRATED_OPTION, false );
|
||||
|
||||
// reformat defaults array and add actual values to it.
|
||||
foreach ( $defaults as $setting_name => $default_value ) {
|
||||
$defaults[ $setting_name ] = array(
|
||||
'default' => $default_value,
|
||||
);
|
||||
|
||||
if ( ! et_is_builder_plugin_active() ) {
|
||||
$actual_value = (string) et_get_option( $setting_name, '', '', true );
|
||||
$add_as_actual = false;
|
||||
|
||||
// Pass Theme Customizer non module specific settings.
|
||||
$setting_array = explode( '-', $setting_name );
|
||||
$module_name = $setting_array[0];
|
||||
|
||||
if ( empty( $setting_array[1] ) || ! empty( $custom_defaults_unmigrated->$module_name ) && in_array( $setting_array[1], ET_Builder_Global_Presets_Settings::$phase_two_settings, true ) ) {
|
||||
$add_as_actual = true;
|
||||
}
|
||||
|
||||
if ( $add_as_actual && '' !== $actual_value ) {
|
||||
$defaults[ $setting_name ]['actual'] = $actual_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::$_settings = apply_filters( 'et_set_default_values', $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default global setting value
|
||||
*
|
||||
* @param string $name Setting name.
|
||||
* @param string $get_value Defines the value it should get: actual or default.
|
||||
*
|
||||
* @return mixed Global setting value or FALSE
|
||||
*/
|
||||
public static function get_value( $name, $get_value = 'actual' ) {
|
||||
$settings = self::$_settings;
|
||||
|
||||
if ( ! isset( $settings[ $name ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $settings[ $name ][ $get_value ] ) ) {
|
||||
$result = $settings[ $name ][ $get_value ];
|
||||
} elseif ( 'actual' === $get_value && isset( $settings[ $name ]['default'] ) ) {
|
||||
$result = $settings[ $name ]['default'];
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate 'on'/'off' into true/false
|
||||
* Pagebuilder use pseudo checkbox with 'on'/'off' value while customizer use true/false
|
||||
* which cause ET_Global_Settings' default value incompatibilities.
|
||||
*
|
||||
* @param string $name Setting name.
|
||||
* @param string $get_value Defines the value it should get: actual or default.
|
||||
* @param string $source pagebuilder or customizer.
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function get_checkbox_value( $name, $get_value = 'actual', $source = 'pagebuilder' ) {
|
||||
// Get value.
|
||||
$value = self::get_value( $name, $get_value );
|
||||
|
||||
// customizer to pagebuilder || pagebuilder to customizer.
|
||||
if ( 'customizer' === $source ) {
|
||||
if ( false === $value ) {
|
||||
return 'off';
|
||||
} else {
|
||||
return 'on';
|
||||
}
|
||||
} else {
|
||||
if ( 'off' === $value || false === $value ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the global settings.
|
||||
*/
|
||||
function et_builder_init_global_settings() {
|
||||
ET_Global_Settings::init();
|
||||
}
|
89
includes/builder/comments_template.php
Normal file
89
includes/builder/comments_template.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
if ( post_password_required() ) : ?>
|
||||
|
||||
<p class="nocomments container"><?php esc_html_e( 'This post is password protected. Enter the password to view comments.', 'et_builder' ); ?></p>
|
||||
<?php
|
||||
return;
|
||||
endif;
|
||||
|
||||
global $et_comments_header_level, $et_comments_form_title_level;
|
||||
|
||||
$et_comments_header_level_processed = isset( $et_comments_header_level ) && '' !== $et_comments_header_level ? et_pb_process_header_level( $et_comments_header_level, 'h1' ) : 'h1';
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ( empty( $comments_by_type ) ) {
|
||||
$comments_by_type = separate_comments( $comments );
|
||||
}
|
||||
?>
|
||||
|
||||
<section id="comment-wrap">
|
||||
<<?php echo et_core_intentionally_unescaped( $et_comments_header_level_processed, 'fixed_string' ); ?> id="comments" class="page_title"><?php comments_number( esc_html__( '0 Comments', 'et_builder' ), esc_html__( '1 Comment', 'et_builder' ), '% ' . esc_html__( 'Comments', 'et_builder' ) ); ?></<?php echo et_core_intentionally_unescaped( $et_comments_header_level_processed, 'fixed_string' ); ?>>
|
||||
<?php if ( have_comments() ) : ?>
|
||||
<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
|
||||
<div class="comment_navigation_top clearfix">
|
||||
<div class="nav-previous"><?php previous_comments_link( et_get_safe_localization( __( '<span class="meta-nav">←</span> Older Comments', 'et_builder' ) ) ); ?></div>
|
||||
<div class="nav-next"><?php next_comments_link( et_get_safe_localization( __( 'Newer Comments <span class="meta-nav">→</span>', 'et_builder' ) ) ); ?></div>
|
||||
</div>
|
||||
<?php endif; // check for comment navigation ?>
|
||||
|
||||
<?php if ( ! empty( $comments_by_type['comment'] ) ) : ?>
|
||||
<ol class="commentlist clearfix">
|
||||
<?php
|
||||
wp_list_comments(
|
||||
array(
|
||||
'type' => 'comment',
|
||||
'callback' => 'et_custom_comments_display',
|
||||
)
|
||||
);
|
||||
?>
|
||||
</ol>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
|
||||
<div class="comment_navigation_bottom clearfix">
|
||||
<div class="nav-previous"><?php previous_comments_link( et_get_safe_localization( __( '<span class="meta-nav">←</span> Older Comments', 'et_builder' ) ) ); ?></div>
|
||||
<div class="nav-next"><?php next_comments_link( et_get_safe_localization( __( 'Newer Comments <span class="meta-nav">→</span>', 'et_builder' ) ) ); ?></div>
|
||||
</div>
|
||||
<?php endif; // check for comment navigation ?>
|
||||
|
||||
<?php if ( ! empty( $comments_by_type['pings'] ) ) : ?>
|
||||
<div id="trackbacks">
|
||||
<h3 id="trackbacks-title"><?php esc_html_e( 'Trackbacks/Pingbacks', 'et_builder' ); ?></h3>
|
||||
<ol class="pinglist">
|
||||
<?php wp_list_comments( 'type=pings&callback=et_list_pings' ); ?>
|
||||
</ol>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : // this is displayed if there are no comments so far ?>
|
||||
<div id="comment-section" class="nocomments">
|
||||
<?php if ( 'open' === $post->comment_status ) : ?>
|
||||
|
||||
<?php else : // comments are closed ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( 'open' === $post->comment_status ) : ?>
|
||||
<?php
|
||||
// Comment submit content title level.
|
||||
$et_comments_form_title_level_processed = isset( $et_comments_form_title_level ) && '' !== $et_comments_form_title_level ? et_pb_process_header_level( $et_comments_form_title_level, 'h3' ) : 'h3';
|
||||
$et_comments_form_title_level_escaped = et_core_intentionally_unescaped( $et_comments_form_title_level_processed, 'fixed_string' );
|
||||
|
||||
comment_form(
|
||||
array(
|
||||
'label_submit' => esc_attr__( 'Submit Comment', 'et_builder' ),
|
||||
'title_reply' => '<span>' . esc_attr__( 'Submit a Comment', 'et_builder' ) . '</span>',
|
||||
'title_reply_to' => esc_attr__( 'Leave a Reply to %s', 'et_builder' ),
|
||||
'title_reply_before' => '<' . $et_comments_form_title_level_escaped . ' id="reply-title" class="comment-reply-title">',
|
||||
'title_reply_after' => '</' . $et_comments_form_title_level_escaped . '>',
|
||||
'class_submit' => 'submit et_pb_button',
|
||||
'comment_notes_after' => '',
|
||||
'id_submit' => 'et_pb_submit',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else : ?>
|
||||
|
||||
<?php endif; // if you delete this the sky will fall on your head ?>
|
||||
</section>
|
81
includes/builder/compat/early.php
Normal file
81
includes/builder/compat/early.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
// Compatibility code that needs to be run early and for each request.
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
if ( function_exists( 'ud_get_stateless_media' ) ) {
|
||||
// WP Stateless Plugin.
|
||||
function et_compat_stateless_skip_cache_busting( $result, $filename ) {
|
||||
return $filename;
|
||||
}
|
||||
|
||||
add_filter( 'stateless_skip_cache_busting', 'et_compat_stateless_skip_cache_busting', 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable JQuery Body Feature.
|
||||
*
|
||||
* @since 4.10.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function et_builder_disable_jquery_body() {
|
||||
add_filter( 'et_builder_enable_jquery_body', '__return_false' );
|
||||
}
|
||||
|
||||
if ( function_exists( 'sg_cachepress_purge_cache' ) ) {
|
||||
// Disable JQuery Body when SG CachePress JS Combine option is enabled
|
||||
// because the two features aren't compatible.
|
||||
if ( '1' === get_option( 'siteground_optimizer_combine_javascript' ) ) {
|
||||
et_builder_disable_jquery_body();
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined( 'WP_ROCKET_SLUG' ) ) {
|
||||
// Disable JQuery Body when WP Rocket Defer JS option is enabled
|
||||
// because the two features aren't compatible.
|
||||
if ( 1 === et_()->array_get( get_option( WP_ROCKET_SLUG ), 'defer_all_js' ) ) {
|
||||
et_builder_disable_jquery_body();
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined( 'LSCWP_V' ) ) {
|
||||
$options = [
|
||||
'litespeed.conf.optm-js_comb_ext_inl',
|
||||
'litespeed.conf.optm-js_defer',
|
||||
];
|
||||
|
||||
// Disable JQuery Body when some LiteSpeed Cache JS options are enabled
|
||||
// because the features aren't compatible.
|
||||
foreach ( $options as $option ) {
|
||||
if ( ! empty( get_option( $option ) ) ) {
|
||||
et_builder_disable_jquery_body();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined( 'AUTOPTIMIZE_PLUGIN_VERSION' ) ) {
|
||||
$options = [
|
||||
'autoptimize_js_include_inline',
|
||||
'autoptimize_js_defer_inline',
|
||||
'autoptimize_js_forcehead',
|
||||
];
|
||||
|
||||
// Disable JQuery Body when some Autoptimize JS options are enabled
|
||||
// because the features aren't compatible.
|
||||
foreach ( $options as $option ) {
|
||||
if ( ! empty( get_option( $option ) ) ) {
|
||||
et_builder_disable_jquery_body();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined( 'OP3_VERSION' ) ) {
|
||||
// Disable JQuery Body when some OptimizePress is active
|
||||
// because the two aren't compatible.
|
||||
et_builder_disable_jquery_body();
|
||||
}
|
41
includes/builder/compat/scripts.php
Normal file
41
includes/builder/compat/scripts.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility code that deals with 3P Services which are not integrated via
|
||||
* WP Plugins (eg. code added via integration / Code Module) because not hosted locally.
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.10.5
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
// Disable JQuery Body feature when certain 3P form services are used.
|
||||
// phpcs:disable PEAR.Functions.FunctionCallSignature.MultipleArguments -- Anonymous functions.
|
||||
// phpcs:disable PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket -- Anonymous functions.
|
||||
// phpcs:disable PEAR.Functions.FunctionCallSignature.CloseBracketLine -- Anonymous functions.
|
||||
add_filter( 'et_builder_enable_jquery_body', function( $enabled, $content = '' ) {
|
||||
if ( empty( $content ) ) {
|
||||
return $enabled;
|
||||
}
|
||||
|
||||
$services = [
|
||||
'et_builder_disable_jquery_body',
|
||||
'slick.js',
|
||||
'webforms/bbox-min.js',
|
||||
'www.cognitoforms.com',
|
||||
'mailchimp.com',
|
||||
'mindbodyonline.com/javascripts',
|
||||
'static.smartrecruiters.com/job-widget/',
|
||||
'default.salsalabs.org/api/widget/',
|
||||
];
|
||||
|
||||
$services = array_filter( $services, 'preg_quote' );
|
||||
$pattern = '#(' . implode( '|', $services ) . ')#';
|
||||
|
||||
// Disable when the service is found.
|
||||
return 1 === preg_match( $pattern, $content ) ? false : $enabled;
|
||||
}, 10, 2);
|
||||
// phpcs:enable
|
128
includes/builder/compat/woocommerce.php
Normal file
128
includes/builder/compat/woocommerce.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
$GLOBALS['et_builder_used_in_wc_shop'] = false;
|
||||
|
||||
/**
|
||||
* Determines if current page is WooCommerce's shop page + uses builder.
|
||||
* NOTE: This has to be used after pre_get_post (et_builder_wc_pre_get_posts).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_used_in_wc_shop() {
|
||||
global $et_builder_used_in_wc_shop;
|
||||
|
||||
return apply_filters(
|
||||
'et_builder_used_in_wc_shop',
|
||||
$et_builder_used_in_wc_shop
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use page.php as template for a page which uses builder & being set as shop page
|
||||
*
|
||||
* @param string path to template
|
||||
* @return string modified path to template
|
||||
*/
|
||||
function et_builder_wc_template_include( $template ) {
|
||||
// Detemine whether current page uses builder and set as
|
||||
if ( et_builder_used_in_wc_shop() && '' !== locate_template( 'page.php' ) ) {
|
||||
$template = locate_template( 'page.php' );
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
add_filter( 'template_include', 'et_builder_wc_template_include', 20 );
|
||||
|
||||
/**
|
||||
* Overwrite WooCommerce's custom query in shop page if the page uses builder.
|
||||
* After proper shop page setup (page selection + permalink flushed), the original
|
||||
* page permalink will be recognized as is_post_type_archive by WordPress' rewrite
|
||||
* URL when it is being parsed. This causes is_page() detection fails and no way
|
||||
* to get actual page ID on pre_get_posts hook, unless by doing reverse detection:
|
||||
*
|
||||
* 1. Check if current page is product archive page. Most page will fail on this.
|
||||
* 2. Afterward, if wc_get_page_id( 'shop' ) returns a page ID, it means that
|
||||
* current page is shop page (product post type archive) which is configured
|
||||
* in custom page. Next, check whether Divi Builder is used on this page or not.
|
||||
*
|
||||
* @param object query object
|
||||
* @param void
|
||||
*/
|
||||
function et_builder_wc_pre_get_posts( $query ) {
|
||||
global $et_builder_used_in_wc_shop;
|
||||
|
||||
if ( is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $query->is_main_query() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $query->is_search() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WooCommerce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'wc_get_page_id' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if current page is product archive page. Most page will fail on this.
|
||||
// initially used is_shop(), but is_shop()'s is_page() check throws error at
|
||||
// this early hook on homepage if shop page !== page_on_front
|
||||
if ( ! is_post_type_archive( 'product' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that the following check is only performed on product archive page.
|
||||
$shop_page_id = wc_get_page_id( 'shop' );
|
||||
$shop_page_object = get_post( $shop_page_id );
|
||||
$is_shop_page_exist = isset( $shop_page_object->post_type ) && 'page' === $shop_page_object->post_type;
|
||||
|
||||
if ( ! $is_shop_page_exist ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! et_pb_is_pagebuilder_used( $shop_page_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set et_builder_used_in_wc_shop() global to true
|
||||
$et_builder_used_in_wc_shop = true;
|
||||
|
||||
// Overwrite page query. This overwrite enables is_page() and other standard
|
||||
// page-related function to work normally after pre_get_posts hook
|
||||
$query->set( 'page_id', $shop_page_id );
|
||||
$query->set( 'post_type', 'page' );
|
||||
$query->set( 'posts_per_page', 1 );
|
||||
$query->set( 'wc_query', null );
|
||||
$query->set( 'meta_query', array() );
|
||||
|
||||
$query->is_singular = true;
|
||||
$query->is_page = true;
|
||||
$query->is_post_type_archive = false;
|
||||
$query->is_archive = false;
|
||||
|
||||
// Avoid unwanted <p> at the beginning of the rendered builder
|
||||
remove_filter( 'the_content', 'wpautop' );
|
||||
}
|
||||
add_action( 'pre_get_posts', 'et_builder_wc_pre_get_posts' );
|
||||
|
||||
/**
|
||||
* Remove woocommerce body classes if current shop page uses builder.
|
||||
* woocommerce-page body class causes builder's shop column styling to be irrelevant.
|
||||
*
|
||||
* @param array body classes
|
||||
* @return array modified body classes
|
||||
*/
|
||||
function et_builder_wc_body_class( $classes ) {
|
||||
if ( et_builder_used_in_wc_shop() ) {
|
||||
$classes = array_diff( $classes, array( 'woocommerce', 'woocommerce-page' ) );
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
add_filter( 'body_class', 'et_builder_wc_body_class' );
|
214
includes/builder/conditions.php
Normal file
214
includes/builder/conditions.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* Utility functions for checking conditions.
|
||||
*
|
||||
* To be included in this file a function must:
|
||||
*
|
||||
* * Return a bool value
|
||||
* * Have a name that asks a yes or no question (where the first word after
|
||||
* the et_ prefix is a word like: is, can, has, should, was, had, must, or will)
|
||||
*
|
||||
* @package Divi
|
||||
* @subpackage Builder
|
||||
* @since 4.0.7
|
||||
*/
|
||||
|
||||
// phpcs:disable Squiz.PHP.CommentedOutCode -- We may add `et_builder_()` in future.
|
||||
|
||||
/*
|
||||
Function Template
|
||||
|
||||
if ( ! function_exists( '' ) ):
|
||||
function et_builder_() {
|
||||
|
||||
}
|
||||
endif;
|
||||
|
||||
*/
|
||||
// phpcs:enable
|
||||
|
||||
// Note: Functions in this file are sorted alphabetically.
|
||||
|
||||
if ( ! function_exists( 'et_builder_is_frontend' ) ) :
|
||||
/**
|
||||
* Determine whether current request is frontend.
|
||||
* This excludes the visual builder.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_is_frontend() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Only used to disable some FE optmizations.
|
||||
$is_builder = isset( $_GET['et_fb'] ) || isset( $_GET['et_bfb'] );
|
||||
// phpcs:enable
|
||||
|
||||
return $is_builder || is_admin() || wp_doing_ajax() || wp_doing_cron() ? false : true;
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( ! function_exists( 'et_builder_is_frontend_or_builder' ) ) :
|
||||
/**
|
||||
* Determine whether current request is frontend.
|
||||
* This includes the visual builder.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_is_frontend_or_builder() {
|
||||
static $et_builder_is_frontend_or_builder = null;
|
||||
|
||||
if ( null === $et_builder_is_frontend_or_builder ) {
|
||||
if (
|
||||
! is_admin()
|
||||
&& ! wp_doing_ajax()
|
||||
&& ! wp_doing_cron()
|
||||
) {
|
||||
$et_builder_is_frontend_or_builder = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $et_builder_is_frontend_or_builder;
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( ! function_exists( 'et_builder_is_loading_data' ) ) :
|
||||
/**
|
||||
* Determine whether builder is loading full data or not.
|
||||
*
|
||||
* @param string $type Is it a bb or vb.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_is_loading_data( $type = 'vb' ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification -- This function does not change any stats, hence CSRF ok.
|
||||
if ( 'bb' === $type ) {
|
||||
return 'et_pb_get_backbone_templates' === et_()->array_get( $_POST, 'action' );
|
||||
}
|
||||
|
||||
$data_actions = array(
|
||||
'et_fb_retrieve_builder_data',
|
||||
'et_fb_update_builder_assets',
|
||||
'et_pb_process_computed_property',
|
||||
);
|
||||
|
||||
return isset( $_POST['action'] ) && in_array( $_POST['action'], $data_actions, true );
|
||||
// phpcs:enable
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( ! function_exists( 'et_builder_should_load_all_data' ) ) :
|
||||
/**
|
||||
* Determine whether to load full builder data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_should_load_all_data() {
|
||||
$needs_cached_definitions = et_core_is_fb_enabled() && ! et_fb_dynamic_asset_exists( 'definitions' );
|
||||
|
||||
return $needs_cached_definitions || ( ET_Builder_Element::is_saving_cache() || et_builder_is_loading_data() );
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( ! function_exists( 'et_builder_should_load_all_module_data' ) ) :
|
||||
/**
|
||||
* Determine whether to load all module data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_should_load_all_module_data() {
|
||||
|
||||
if ( ! et_builder_is_frontend() ) {
|
||||
// Always load everything when not a frontend request.
|
||||
return true;
|
||||
}
|
||||
|
||||
$needs_cached_definitions = et_core_is_fb_enabled();
|
||||
|
||||
$et_dynamic_module_framework = et_builder_dynamic_module_framework();
|
||||
|
||||
$result = $needs_cached_definitions || ( ET_Builder_Element::is_saving_cache() || et_builder_is_loading_data() ) || 'on' !== $et_dynamic_module_framework;
|
||||
|
||||
/**
|
||||
* Whether to load all module data,
|
||||
* including all module classes, on a given page load.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param bool $result Whether to load all module data.
|
||||
*/
|
||||
return apply_filters( 'et_builder_should_load_all_module_data', $result );
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
if ( ! function_exists( 'et_builder_dynamic_module_framework' ) ) :
|
||||
/**
|
||||
* Determine whether module framework is on.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function et_builder_dynamic_module_framework() {
|
||||
global $shortname;
|
||||
|
||||
if ( et_is_builder_plugin_active() ) {
|
||||
$options = get_option( 'et_pb_builder_options', array() );
|
||||
$et_dynamic_module_framework = isset( $options['performance_main_dynamic_module_framework'] ) ? $options['performance_main_dynamic_module_framework'] : 'on';
|
||||
} else {
|
||||
$et_dynamic_module_framework = et_get_option( $shortname . '_dynamic_module_framework', 'on' );
|
||||
}
|
||||
return $et_dynamic_module_framework;
|
||||
}
|
||||
endif;
|
||||
|
||||
if ( ! function_exists( 'et_builder_is_mod_pagespeed_enabled' ) ) :
|
||||
/**
|
||||
* Determine whether Mod PageSpeed is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function et_builder_is_mod_pagespeed_enabled() {
|
||||
static $enabled;
|
||||
|
||||
if ( isset( $enabled ) ) {
|
||||
// Use the cached value.
|
||||
return $enabled;
|
||||
}
|
||||
|
||||
$key = 'et_check_mod_pagespeed';
|
||||
$version = get_transient( $key );
|
||||
|
||||
if ( false === $version ) {
|
||||
// Mod PageSpeed is an output filter, hence it can't be detected from within the request.
|
||||
// To figure out whether it is active or not:
|
||||
// 1. Use `wp_remote_get` to make another request.
|
||||
// 2. Retrieve PageSpeed version from response headers (if set).
|
||||
// 3. Save the value in a transient for 24h.
|
||||
// The `et_check_mod_pagespeed` url parameter is also added to the request so
|
||||
// we can exit early (content is irrelevant, only headers matter).
|
||||
$args = [
|
||||
$key => 'on',
|
||||
];
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification -- Only checking arg is set.
|
||||
if ( isset( $_REQUEST['PageSpeed'] ) ) {
|
||||
// This isn't really needed but it's harmless and makes testing a lot easier.
|
||||
$args['PageSpeed'] = sanitize_text_field( $_REQUEST['PageSpeed'] );
|
||||
}
|
||||
// phpcs:enable
|
||||
|
||||
$request = wp_remote_get( add_query_arg( $args, get_home_url() ) );
|
||||
// Apache header.
|
||||
$version = wp_remote_retrieve_header( $request, 'x-mod-pagespeed' );
|
||||
if ( empty( $version ) ) {
|
||||
// Nginx header.
|
||||
$version = wp_remote_retrieve_header( $request, 'x-page-speed' );
|
||||
}
|
||||
|
||||
set_transient( $key, $version, DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
// Cache the value.
|
||||
$enabled = ! empty( $version );
|
||||
return $enabled;
|
||||
}
|
||||
endif;
|
7226
includes/builder/core.php
Normal file
7226
includes/builder/core.php
Normal file
File diff suppressed because it is too large
Load Diff
69
includes/builder/deprecations.php
Normal file
69
includes/builder/deprecations.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Deprecated symbols mapped to replacements when applicable, organized by type.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @return array[] {
|
||||
* Deprecations
|
||||
*
|
||||
* @type string[] $functions {
|
||||
* Deprecated Functions
|
||||
*
|
||||
* @type mixed $deprecated_symbol Replacement symbol or default value
|
||||
* ...
|
||||
* }
|
||||
* @type array[] $classes {
|
||||
* Deprecations By Class
|
||||
*
|
||||
* @type array[] $class_name {
|
||||
* Deprecated Symbols
|
||||
*
|
||||
* @type string[] $symbol_type {
|
||||
*
|
||||
* @type mixed $deprecated_symbol Replacement symbol or default value
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
return array(
|
||||
'functions' => array(),
|
||||
'classes' => array(
|
||||
'\ET_Builder_Module_Blurb' => array(
|
||||
'method_args' => array(
|
||||
'_add_option_toggles' => array( 'general', array() ),
|
||||
'_shortcode_callback' => array( array(), null, 'et_pb_blurb' ),
|
||||
'_shortcode_passthru_callback' => array( array(), null, 'et_pb_blurb' ),
|
||||
'additional_shortcode_callback' => array( array(), null, 'et_pb_blurb' ),
|
||||
'shortcode_callback' => array( array(), null, 'et_pb_blurb' ),
|
||||
),
|
||||
'methods' => array(
|
||||
'_add_option_toggles' => '_add_settings_modal_toggles',
|
||||
'_get_current_shortcode_address' => 'generate_element_address',
|
||||
'_shortcode_callback' => '_render',
|
||||
'_shortcode_passthru_callback' => 'render_as_builder_data',
|
||||
'additional_shortcode_callback' => 'additional_render',
|
||||
'get_shortcode_fields' => 'get_default_props',
|
||||
'pre_shortcode_content' => 'before_render',
|
||||
'shortcode_atts' => '',
|
||||
'shortcode_atts_to_data_atts' => 'props_to_html_data_attrs',
|
||||
'shortcode_callback' => 'render',
|
||||
'shortcode_output' => 'output',
|
||||
),
|
||||
'properties' => array(
|
||||
'advanced_options' => 'advanced_fields',
|
||||
'custom_css_options' => 'custom_css_fields',
|
||||
'options_toggles' => 'settings_modal_toggles',
|
||||
'shortcode_atts' => 'props',
|
||||
'shortcode_content' => 'content',
|
||||
'allowlisted_fields' => array(),
|
||||
'no_shortcode_callback' => 'no_render',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
284
includes/builder/feature/AjaxCache.php
Normal file
284
includes/builder/feature/AjaxCache.php
Normal file
@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/**
|
||||
* Ajax Cache.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to cache commonly used AJAX requests.
|
||||
*/
|
||||
class ET_Builder_Ajax_Cache {
|
||||
|
||||
/**
|
||||
* Instance of this class.
|
||||
*
|
||||
* @var ET_Builder_Ajax_Cache
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* Transient name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_transient = 'et_builder_ajax_cache';
|
||||
|
||||
/**
|
||||
* Flag to determine whether to save cache or not on `shutdown` hook.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_dirty = false;
|
||||
|
||||
/**
|
||||
* List of all ajax cache.
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
protected $_cache;
|
||||
|
||||
/**
|
||||
* ET_Builder_Ajax_Cache constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'et_builder_ajax_cache_clear', array( $this, 'clear' ), 10, 1 );
|
||||
add_action( 'shutdown', array( $this, 'save' ) );
|
||||
add_filter( 'et_builder_dynamic_asset_deps', array( $this, 'add_cache_dep' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether cache file exists or not.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function file_exists() {
|
||||
$file = $this->get_file_name();
|
||||
return $file && et_()->WPFS()->is_readable( $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether cache is empty or not.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_empty() {
|
||||
$this->load();
|
||||
return empty( $this->_cache );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue ajax cache as definitions dependency.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @param array $deps Dependencies array.
|
||||
* @param string $key Script handle.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_cache_dep( $deps, $key ) {
|
||||
// Skip all static assets but definitions.
|
||||
if ( 'et-dynamic-asset-definitions' !== $key ) {
|
||||
return $deps;
|
||||
}
|
||||
|
||||
if ( ! $this->file_exists() && ! $this->write_file() ) {
|
||||
// Bail out if cache is empty and cannot write the file.
|
||||
return $deps;
|
||||
}
|
||||
|
||||
// Enqueue ajax cache as definitions dependency.
|
||||
$handle = 'et-ajax-cache';
|
||||
$deps[] = $handle;
|
||||
wp_register_script( $handle, $this->get_url(), array(), ET_BUILDER_VERSION, false );
|
||||
|
||||
return $deps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load cache.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function load() {
|
||||
if ( is_array( $this->_cache ) ) {
|
||||
// Cache was already loaded.
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_cache = get_transient( $this->_transient );
|
||||
|
||||
if ( ! is_array( $this->_cache ) ) {
|
||||
$this->_cache = array();
|
||||
$this->delete_file();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save cache.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save() {
|
||||
// Ensure cache is loaded.
|
||||
$this->load();
|
||||
|
||||
if ( $this->_dirty ) {
|
||||
set_transient( $this->_transient, $this->_cache );
|
||||
$this->delete_file();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write cache file.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function write_file() {
|
||||
if ( $this->is_empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->get_file_name();
|
||||
$cache = '';
|
||||
foreach ( $this->_cache as $key => $value ) {
|
||||
$cache = sprintf( '"%s":%s,', $key, $value );
|
||||
}
|
||||
$cache = sprintf( '{"ajaxCache":{%s}}', rtrim( $cache, ',' ) );
|
||||
$cache = sprintf( 'window.ETBuilderBackend=jQuery.extend(true,%s,window.ETBuilderBackend)', $cache );
|
||||
|
||||
et_()->WPFS()->put_contents( $file, $cache );
|
||||
return $this->file_exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache file.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete_file() {
|
||||
if ( $this->file_exists() ) {
|
||||
et_()->WPFS()->delete( $this->get_file_name() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache key.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @param string $key Cache key.
|
||||
* @param string $content Cache value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set( $key, $content ) {
|
||||
$this->load();
|
||||
$this->_cache[ $key ] = wp_json_encode( $content );
|
||||
$this->_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset cache key.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @param string $key Cache key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unset_( $key ) {
|
||||
$this->load();
|
||||
if ( isset( $this->_cache[ $key ] ) ) {
|
||||
unset( $this->_cache[ $key ] );
|
||||
$this->_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear() {
|
||||
delete_transient( $this->_transient );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache file name.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return string.
|
||||
*/
|
||||
public function get_file_name() {
|
||||
// Per language Cache due to some data being localized.
|
||||
$lang = is_admin() || et_fb_is_enabled() ? get_user_locale() : get_locale();
|
||||
$lang = trim( sanitize_file_name( $lang ), '.' );
|
||||
$prefix = 'ajax';
|
||||
$cache = et_()->path( et_core_cache_dir()->path, $lang );
|
||||
$files = glob( "{$cache}/{$prefix}-*.js" );
|
||||
$exists = is_array( $files ) && $files;
|
||||
|
||||
if ( $exists ) {
|
||||
return $files[0];
|
||||
}
|
||||
|
||||
wp_mkdir_p( $cache );
|
||||
|
||||
// Create uniq filename.
|
||||
$uniq = str_replace( '.', '', (string) microtime( true ) );
|
||||
$file = "{$cache}/{$prefix}-{$uniq}.js";
|
||||
|
||||
return et_()->WPFS()->is_writable( dirname( $file ) ) ? $file : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache url.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_url() {
|
||||
$file = $this->get_file_name();
|
||||
$lang = basename( dirname( $file ) );
|
||||
$name = basename( $file );
|
||||
return et_()->path( et_core_cache_dir()->url, $lang, $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 4.0.10
|
||||
*
|
||||
* @return ET_Builder_Ajax_Cache
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ET_Builder_Ajax_Cache::instance();
|
757
includes/builder/feature/BlockEditorIntegration.php
Normal file
757
includes/builder/feature/BlockEditorIntegration.php
Normal file
@ -0,0 +1,757 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility for Gutenberg.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Editing GB blocks inside Divi.
|
||||
*
|
||||
* @since 3.18 Added support for WP 5.0
|
||||
* @since 3.10.2
|
||||
*/
|
||||
class ET_Builder_Block_Editor_Integration {
|
||||
|
||||
/**
|
||||
* Regex to match gallery in block editor.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_gb_gallery_regexp = '/<ul class="wp-block-gallery[^"]*?">.*?<\/ul>/mis';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* ET_Builder_Block_Editor_Integration constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the post can be edited in the block editor.
|
||||
*
|
||||
* @param mixed $post Post ID or WP_Post object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _can_edit_post( $post ) {
|
||||
if ( function_exists( 'gutenberg_can_edit_post' ) ) {
|
||||
return gutenberg_can_edit_post( $post );
|
||||
}
|
||||
|
||||
// In case WordPress is lower than version 5.0.
|
||||
if ( ! function_exists( 'use_block_editor_for_post' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return use_block_editor_for_post( $post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a post type is compatible with the block editor.
|
||||
*
|
||||
* @param string $type The post type.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _can_edit_post_type( $type ) {
|
||||
if ( function_exists( 'gutenberg_can_edit_post_type' ) ) {
|
||||
return gutenberg_can_edit_post_type( $type );
|
||||
}
|
||||
|
||||
// In case WordPress is lower than version 5.0.
|
||||
if ( ! function_exists( 'use_block_editor_for_post_type' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return use_block_editor_for_post_type( $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current editor is set to load Gutenberg.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _is_block_editor_page() {
|
||||
if ( function_exists( 'is_gutenberg_page' ) ) {
|
||||
return is_gutenberg_page();
|
||||
}
|
||||
|
||||
// In case WordPress is lower than version 5.0.
|
||||
if ( ! function_exists( 'use_block_editor_for_post' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return use_block_editor_for_post( get_the_ID() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter on map_meta_cap.
|
||||
*
|
||||
* @param array $caps Capabilities.
|
||||
* @param string $cap Capability to check.
|
||||
* @param string $user_id User ID.
|
||||
* @param array $args Additional args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function map_meta_cap( $caps, $cap, $user_id, $args ) {
|
||||
// This only needs to run once,.
|
||||
remove_filter( 'map_meta_cap', array( $this, 'map_meta_cap' ), 10 );
|
||||
if (
|
||||
// GB checks for 'edit_post' so do nothing in all other cases.
|
||||
'edit_post' !== $cap ||
|
||||
// Ignore the case where Divi wasn't used to edit the post.
|
||||
! et_pb_is_pagebuilder_used( $args[0] )
|
||||
) {
|
||||
return $caps;
|
||||
}
|
||||
// We need to add `do_not_allow` for superadmins.
|
||||
$caps = array( 'do_not_allow' );
|
||||
|
||||
return $caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user capabilities that is relevant to block editor integration
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_current_user_capabilities() {
|
||||
/**
|
||||
* Make relevant capabilities filterable should the need to check for more caps arises
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array user capabilities
|
||||
*/
|
||||
$relevant_capabilities = array(
|
||||
'divi_library',
|
||||
'use_visual_builder',
|
||||
);
|
||||
$relevant_capabilities = apply_filters( 'et_block_editor_relevant_capabilities', $relevant_capabilities );
|
||||
|
||||
$capabilities = array();
|
||||
|
||||
foreach ( $relevant_capabilities as $cap_name ) {
|
||||
$capabilities[ $cap_name ] = et_pb_is_allowed( $cap_name );
|
||||
}
|
||||
|
||||
return $capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter used to disable GB for certain post types.
|
||||
*
|
||||
* @param bool $can_edit Whether post type can be editable with gutenberg or not.
|
||||
* @param string $post_type Post type name.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function gutenberg_can_edit_post_type( $can_edit, $post_type ) {
|
||||
// The tricky part here is that GB doesn't pass the post ID to this filter but only its type
|
||||
// but we need the ID to determine whether the post has been edited with Divi.
|
||||
// Since GB uses `current_user_can( 'edit_post', $post->ID )` right after call this filter,
|
||||
// We hook into `map_meta_cap` (which gets passed the ID) and do our checks there.
|
||||
add_filter( 'map_meta_cap', array( $this, 'map_meta_cap' ), 10, 4 );
|
||||
|
||||
return $can_edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue our GB compatibility bundle.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_block_editor_assets() {
|
||||
// Load script dependencies that is used by builder on top window. These dependencies
|
||||
// happen to be the exact same scripts required by BFB top window's scripts.
|
||||
et_bfb_enqueue_scripts_dependencies();
|
||||
|
||||
// Enqueue open sans.
|
||||
et_builder_enqueue_open_sans();
|
||||
|
||||
// Enqueue integration & blocks scripts.
|
||||
$deps = array(
|
||||
'jquery',
|
||||
'et_bfb_admin_date_addon_js',
|
||||
'wp-hooks',
|
||||
);
|
||||
et_fb_enqueue_bundle( 'et-builder-gutenberg', 'gutenberg.js', $deps );
|
||||
|
||||
// Enqueue top window style.
|
||||
wp_register_style(
|
||||
'et-fb-top-window',
|
||||
ET_BUILDER_URI . '/frontend-builder/assets/css/fb-top-window.css',
|
||||
array(),
|
||||
ET_BUILDER_VERSION
|
||||
);
|
||||
|
||||
// Enqueue integration & blocks styles.
|
||||
$deps = array(
|
||||
'et-fb-top-window',
|
||||
);
|
||||
et_fb_enqueue_bundle( 'et-builder-gutenberg', 'gutenberg.css', $deps );
|
||||
|
||||
// this enqueue bundle.css.
|
||||
et_builder_enqueue_assets_main();
|
||||
|
||||
$post_id = get_the_ID();
|
||||
$post_type = get_post_type();
|
||||
$enabled_for_post_type = et_builder_enabled_for_post_type( $post_type );
|
||||
$updates_options = get_site_option( 'et_automatic_updates_options', array() );
|
||||
$et_account = array(
|
||||
'et_username' => et_()->array_get( $updates_options, 'username', '' ),
|
||||
'et_api_key' => et_()->array_get( $updates_options, 'api_key', '' ),
|
||||
'status' => get_site_option( 'et_account_status', 'not_active' ),
|
||||
);
|
||||
|
||||
// Set helpers needed by our own Gutenberg bundle.
|
||||
$gutenberg = array(
|
||||
'helpers' => array(
|
||||
'postID' => $post_id,
|
||||
'postType' => $post_type,
|
||||
'is3rdPartyPostType' => et_builder_is_post_type_custom( $post_type ) ? 'yes' : 'no',
|
||||
'vbUrl' => et_fb_get_vb_url(),
|
||||
'builderUsed' => et_pb_is_pagebuilder_used( $post_id ),
|
||||
'scriptDebug' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG,
|
||||
'canToggle' => et_pb_is_allowed( 'divi_builder_control' ) && $enabled_for_post_type,
|
||||
'isEnabled' => $enabled_for_post_type,
|
||||
'i18n' => array(
|
||||
'placeholder' => array(
|
||||
'block' => array(
|
||||
'title' => esc_html__( 'Divi Builder', 'et_builder' ),
|
||||
'description' => esc_html__( 'The Divi Builder is activated on this page. To edit your page using the builder, click the Edit With The Divi Builder button.', 'et_builder' ),
|
||||
),
|
||||
'render' => array(
|
||||
'title' => array(
|
||||
'new' => esc_html__( 'Build Your Layout Using Divi', 'et_builder' ),
|
||||
'old' => esc_html__( 'This Layout Is Built With Divi', 'et_builder' ),
|
||||
),
|
||||
'divi' => array(
|
||||
'new' => esc_html__( 'Use Divi Builder', 'et_builder' ),
|
||||
'old' => esc_html__( 'Edit With The Divi Builder', 'et_builder' ),
|
||||
),
|
||||
'default' => esc_html__( 'Use Default Editor', 'et_builder' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Loaded into ETBlockUserStore.
|
||||
'capabilities' => $this->get_current_user_capabilities(),
|
||||
|
||||
// Loaded into ETBlockLibraryStore.
|
||||
'etAccount' => $et_account,
|
||||
|
||||
// Loaded into ETBlockSettingsStore.
|
||||
'conditions' => array(
|
||||
'isRtl' => is_rtl(),
|
||||
),
|
||||
'constants' => array(
|
||||
'emptyLayout' => '[et_pb_section admin_label="section"][et_pb_row admin_label="row"][/et_pb_row][/et_pb_section]',
|
||||
),
|
||||
'nonces' => array(
|
||||
'et_builder_library_get_layouts_data' => wp_create_nonce( 'et_builder_library_get_layouts_data' ),
|
||||
'et_builder_library_update_account' => wp_create_nonce( 'et_builder_library_update_account' ),
|
||||
'et_block_layout_preview' => wp_create_nonce( 'et_block_layout_preview' ),
|
||||
'et_rest_get_layout_content' => wp_create_nonce( 'et_rest_get_layout_content' ),
|
||||
'et_rest_process_builder_edit_data' => wp_create_nonce( 'et_rest_process_builder_edit_data' ),
|
||||
),
|
||||
'urls' => array(
|
||||
'adminAjax' => admin_url( 'admin-ajax.php' ),
|
||||
'diviLibrary' => ET_BUILDER_DIVI_LIBRARY_URL,
|
||||
'home' => home_url( '/' ),
|
||||
),
|
||||
/**
|
||||
* Make DOM selectors list filterable so third party can modified it if needed
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array list of selectors
|
||||
*/
|
||||
'selectors' => apply_filters(
|
||||
'et_gb_selectors',
|
||||
array(
|
||||
'pageLayoutSelect' => '#et_pb_page_layout',
|
||||
)
|
||||
),
|
||||
/**
|
||||
* Make Content Widhts settings filterable so third party can modified it if needed
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array content width configurations
|
||||
*/
|
||||
'contentWidths' => apply_filters(
|
||||
'et_gb_content_widths',
|
||||
array(
|
||||
// Intentionally set null for default and undefined if no saved content width found
|
||||
// unless `et_gb_content_widths` is being filtered to handle Divi Builder Plugin
|
||||
// situation which might not have deifined content width.
|
||||
'default' => null,
|
||||
'current' => get_post_meta( $post_id, '_et_gb_content_width', true ),
|
||||
'min' => 320, // Min content width (small smartphone width).
|
||||
'max' => 2880, // Max content width (15" laptop * 2).
|
||||
)
|
||||
),
|
||||
);
|
||||
wp_localize_script( 'et-builder-gutenberg', 'et_builder_gutenberg', $gutenberg );
|
||||
|
||||
// Set translated strings for the scripts.
|
||||
wp_set_script_translations( 'et-builder-gutenberg', 'et_builder', ET_BUILDER_DIR . 'languages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new Divi page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_new_button() {
|
||||
global $typenow;
|
||||
if ( ! $this->_can_edit_post_type( $typenow ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$edit = 'post-new.php';
|
||||
$edit .= 'post' !== $typenow ? "?post_type=$typenow" : '';
|
||||
|
||||
// Create a nonce to auto activate VB on a new Auto Draft.
|
||||
$url = add_query_arg( 'et_fb_new_vb_nonce', wp_create_nonce( 'et_fb_new_vb_nonce' ), admin_url( $edit ) );
|
||||
$button = sprintf( '<a href="%s">%s</a>', esc_url( $url ), 'Divi' );
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var menu = document.querySelector('#split-page-title-action .dropdown');
|
||||
|
||||
if (menu) {
|
||||
menu.insertAdjacentHTML('afterbegin', '<?php echo et_core_esc_previously( $button ); ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* This filter allows VB to be directly activated for Auto Drafts.
|
||||
*
|
||||
* @param object $post Auto Draft post.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auto_draft( $post ) {
|
||||
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput -- The nonce value is used only for comparision in the `wp_verify_nonce`.
|
||||
if ( ! isset( $_GET['et_fb_new_vb_nonce'] ) || ! wp_verify_nonce( $_GET['et_fb_new_vb_nonce'], 'et_fb_new_vb_nonce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the draft.
|
||||
wp_update_post(
|
||||
array(
|
||||
'ID' => $post->ID,
|
||||
'post_status' => 'draft',
|
||||
)
|
||||
);
|
||||
|
||||
// Add VB activation nonce.
|
||||
$url = add_query_arg(
|
||||
'et_fb_activation_nonce',
|
||||
wp_create_nonce( 'et_fb_activation_nonce_' . $post->ID ),
|
||||
et_fb_prepare_ssl_link( get_permalink( $post ) )
|
||||
);
|
||||
|
||||
// Set post meta to `off` or else `et_builder_set_content_activation` won't work...
|
||||
update_post_meta( $post->ID, '_et_pb_use_builder', 'off' );
|
||||
|
||||
wp_safe_redirect( $url );
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'Edit With Divi Editor' links
|
||||
*
|
||||
* @param array $actions Currently defined actions for the row.
|
||||
* @param object $post Current post object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_edit_link( $actions, $post ) {
|
||||
// Maybe change this with et_fb_current_user_can_save or equivalent.
|
||||
|
||||
if ( ! $this->_can_edit_post( $post ) || ! et_builder_enabled_for_post_type( $post->post_type ) ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
if ( (int) get_option( 'page_for_posts' ) === $post->ID ) {
|
||||
// Post is assigned as the blog page so it does not have editable content.
|
||||
return $actions;
|
||||
}
|
||||
|
||||
$post_id = $post->ID;
|
||||
$is_divi_library = 'et_pb_layout' === get_post_type( $post_id );
|
||||
$edit_url = $is_divi_library ? get_edit_post_link( $post_id, 'raw' ) : get_permalink( $post_id );
|
||||
|
||||
if ( et_pb_is_pagebuilder_used( $post_id ) ) {
|
||||
$edit_url = et_fb_get_vb_url( $edit_url );
|
||||
} else {
|
||||
if ( ! et_pb_is_allowed( 'divi_builder_control' ) ) {
|
||||
// Do not add Divi activation link when user lacks `Toggle Divi Builder` capability.
|
||||
return $actions;
|
||||
}
|
||||
$edit_url = add_query_arg(
|
||||
array(
|
||||
'et_fb_activation_nonce' => wp_create_nonce( 'et_fb_activation_nonce_' . $post_id ),
|
||||
),
|
||||
$edit_url
|
||||
);
|
||||
}
|
||||
|
||||
$edit_action = array(
|
||||
'divi' => sprintf(
|
||||
'<a href="%s" aria-label="%s">%s</a>',
|
||||
esc_url( $edit_url ),
|
||||
esc_attr(
|
||||
sprintf(
|
||||
__( 'Edit “%s” in Divi', 'et_builder' ),
|
||||
_draft_or_post_title( $post->ID )
|
||||
)
|
||||
),
|
||||
esc_html__( 'Edit With Divi', 'et_builder' )
|
||||
),
|
||||
);
|
||||
|
||||
$actions = array_merge( $actions, $edit_action );
|
||||
|
||||
// I'm leaving this here in case we wanna change item position.
|
||||
// $edit_offset = array_search( 'edit', array_keys( $actions ), true );
|
||||
// $actions = array_merge(
|
||||
// array_slice( $actions, 0, $edit_offset + 1 ),
|
||||
// $edit_action,
|
||||
// array_slice( $actions, $edit_offset + 1 )
|
||||
// );.
|
||||
|
||||
return $actions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add filters needed to show our extra row action.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_edit_link_filters() {
|
||||
// For hierarchical post types.
|
||||
add_filter( 'page_row_actions', array( $this, 'add_edit_link' ), 10, 2 );
|
||||
// For non-hierarchical post types.
|
||||
add_filter( 'post_row_actions', array( $this, 'add_edit_link' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'Divi' to post states when builder is enabled for it.
|
||||
*
|
||||
* @param array $post_states Existing post states.
|
||||
* @param object $post Current post object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function display_post_states( $post_states, $post ) {
|
||||
// Make sure that $post_states is an array. Third party plugin might modify $post_states and makes it null
|
||||
// which create various issue (i.e. Piklist + Having a page configured as a static page).
|
||||
if ( ! is_array( $post_states ) ) {
|
||||
$post_states = array();
|
||||
}
|
||||
|
||||
if ( et_pb_is_pagebuilder_used( $post->ID ) ) {
|
||||
// Remove Gutenberg if existing.
|
||||
$key = array_search( 'Gutenberg', $post_states, true );
|
||||
if ( false !== $key ) {
|
||||
unset( $post_states[ $key ] );
|
||||
}
|
||||
// GB devs didn't allow this to be translated so why should we ?
|
||||
$post_states[] = 'Divi';
|
||||
}
|
||||
|
||||
return $post_states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that Divi enabled CPTs support 'custom-fields'.
|
||||
*
|
||||
* @since 3.19.12
|
||||
*/
|
||||
public function ensure_post_type_supports() {
|
||||
$post_types = et_builder_get_builder_post_types();
|
||||
|
||||
foreach ( $post_types as $post_type ) {
|
||||
if ( ! post_type_supports( $post_type, 'custom-fields' ) ) {
|
||||
add_post_type_support( $post_type, 'custom-fields' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter update_post_metadata return value from during a REST API update
|
||||
* when meta value isn't changed.
|
||||
*
|
||||
* @param mixed $result Previous result.
|
||||
* @param int $object_id Post ID.
|
||||
* @param string $meta_key Meta key.
|
||||
* @param mixed $meta_value Meta value.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update_post_metadata( $result, $object_id, $meta_key, $meta_value ) {
|
||||
if ( ! in_array( $meta_key, array( '_et_pb_use_builder', '_et_pb_old_content' ), true ) ) {
|
||||
// Only act if it's one of our metas.
|
||||
return $result;
|
||||
}
|
||||
if ( get_metadata( 'post', $object_id, $meta_key, true ) === $meta_value ) {
|
||||
// Return true instead of false so silly WP REST API call won't die on us....
|
||||
return true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove empty Divi GB placeholder when processing shortcode.
|
||||
*
|
||||
* @param string $post_content Raw post content (shortcode).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function et_fb_load_raw_post_content( $post_content ) {
|
||||
// Replace empty placeholder with no content so page creation will
|
||||
// still work in this case.
|
||||
return '<!-- wp:divi/placeholder /-->' === $post_content ? '' : $post_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a single GB gallery to shortcode.
|
||||
*
|
||||
* @param string $gallery Post content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gb_gallery_to_shortcode( $gallery ) {
|
||||
|
||||
$gallery = is_array( $gallery ) ? $gallery[0] : $gallery;
|
||||
$ids = preg_match_all( '/data-id="(\d+)"/i', $gallery, $matches ) ? $matches[1] : array();
|
||||
$columns = preg_match( '/<ul class="wp-block-gallery columns-(\d)[^"]*?">/i', $gallery, $matches ) ? $matches[1] : 3;
|
||||
$shortcode = sprintf(
|
||||
'[gallery columns="%s" ids="%s"]',
|
||||
intval( $columns ),
|
||||
implode( ',', array_map( 'intval', $ids ) )
|
||||
);
|
||||
|
||||
return $shortcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all GB galleries to shortcodes.
|
||||
*
|
||||
* @param string $content Post content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gb_galleries_to_shortcodes( $content ) {
|
||||
return preg_replace_callback(
|
||||
$this->_gb_gallery_regexp,
|
||||
array( $this, 'gb_gallery_to_shortcode' ),
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a specified post's content for GB gallery and, if present, return the first
|
||||
*
|
||||
* @param string $gallery Gallery data and srcs parsed from the expanded shortcode.
|
||||
* @param int|WP_Post $post Post ID or object.
|
||||
*
|
||||
* @return string|array Gallery data and srcs parsed from the expanded shortcode.
|
||||
*/
|
||||
public function get_post_gallery( $gallery, $post ) {
|
||||
if ( $gallery ) {
|
||||
return $gallery;
|
||||
}
|
||||
|
||||
$content = get_post_field( 'post_content', $post );
|
||||
if ( empty( $content ) ) {
|
||||
return $gallery;
|
||||
}
|
||||
|
||||
if ( preg_match( $this->_gb_gallery_regexp, $content, $matches ) ) {
|
||||
// Found a GB gallery.
|
||||
if ( apply_filters( 'et_gb_gallery_to_shortcode', true ) ) {
|
||||
// Return as shortcode.
|
||||
return do_shortcode( $this->gb_gallery_to_shortcode( $matches[0] ) );
|
||||
}
|
||||
// Return it as is.
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
return $gallery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete first GB gallery in content
|
||||
*
|
||||
* @param string $content Content.
|
||||
* @param bool $deleted Whether a gallery has been already deleted or not.
|
||||
* @return string
|
||||
*/
|
||||
public function et_delete_post_gallery( $content, $deleted ) {
|
||||
if ( $deleted ) {
|
||||
// If a gallery was already removed, do nothing.
|
||||
return $content;
|
||||
}
|
||||
return preg_replace( $this->_gb_gallery_regexp, '', $content, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove custom style from our metabox when GB is showing it.
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_meta_boxes( $post_type ) {
|
||||
$is_block_editor_page = $this->_is_block_editor_page();
|
||||
$is_metabox_exist = function_exists( 'et_single_settings_meta_box' );
|
||||
$is_builder_enabled = et_builder_enabled_for_post_type( $post_type );
|
||||
$is_metabox_allowed = et_pb_is_allowed( 'page_options' );
|
||||
|
||||
if ( $is_block_editor_page && $is_metabox_exist && $is_builder_enabled && $is_metabox_allowed ) {
|
||||
// Change our metabox id so that no custom style is applied.
|
||||
remove_meta_box( 'et_settings_meta_box', $post_type, 'side' );
|
||||
add_meta_box(
|
||||
'et_settings_meta_box_gutenberg',
|
||||
esc_html__( 'Divi Page Settings', 'Divi' ),
|
||||
'et_single_settings_meta_box',
|
||||
$post_type,
|
||||
'side',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into REST API page call.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rest_insert_page() {
|
||||
add_filter( 'update_post_metadata', array( $this, 'update_post_metadata' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom auth function for meta updates via REST API.
|
||||
*
|
||||
* @param boolean $allowed True if allowed to view the meta field by default, false if else.
|
||||
* @param string $meta_key The meta key.
|
||||
* @param int $id Post ID.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function meta_auth( $allowed, $meta_key, $id ) {
|
||||
return current_user_can( 'edit_post', $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook methods to WordPress
|
||||
* Latest plugin version: 1.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_hooks() {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ), 4 );
|
||||
add_action( 'admin_print_scripts-edit.php', array( $this, 'add_new_button' ), 10 );
|
||||
add_action( 'admin_init', array( $this, 'add_edit_link_filters' ) );
|
||||
|
||||
// Only need to add this filter is the nonce is present in the url request
|
||||
// nonce value will be checked in the filter itself.
|
||||
// phpcs:ignore WordPress.Security.NonceVerification -- This is just check, therefore nonce verification not required.
|
||||
if ( isset( $_GET['et_fb_new_vb_nonce'] ) ) {
|
||||
add_action( 'new_to_auto-draft', array( $this, 'auto_draft' ), 1 );
|
||||
}
|
||||
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
||||
} else {
|
||||
// If "Enable Divi Gallery" option is enabled.
|
||||
if ( apply_filters( 'et_gb_gallery_to_shortcode', false ) === true ) {
|
||||
// Converts GB galleries to shortcodes.
|
||||
add_filter( 'the_content', array( $this, 'gb_galleries_to_shortcodes' ), 1 );
|
||||
}
|
||||
if ( apply_filters( 'et_gb_gallery_include_in_get_post_gallery', false ) === true ) {
|
||||
// Makes sure `get_post_gallery` returns a GB gallery if no shortcode is found.
|
||||
add_filter( 'get_post_gallery', array( $this, 'get_post_gallery' ), 10, 2 );
|
||||
}
|
||||
// This filter gets called when Divi removes first gallery shortcode from
|
||||
// a gallery post (as in post format). We hook into that to ensure that the first GB gallery
|
||||
// is deleted if nothing else was.
|
||||
add_filter( 'et_delete_post_gallery', array( $this, 'et_delete_post_gallery' ), 10, 2 );
|
||||
// Provide other code a simple way to access the conversion function via this custom filter.
|
||||
add_filter( 'et_gb_galleries_to_shortcodes', array( $this, 'gb_galleries_to_shortcodes' ) );
|
||||
}
|
||||
|
||||
add_filter( 'et_fb_load_raw_post_content', array( $this, 'et_fb_load_raw_post_content' ) );
|
||||
add_filter( 'init', array( $this, 'ensure_post_type_supports' ), 999999 );
|
||||
|
||||
// This is one of the most idiot things I had to do ever and its due to
|
||||
// a 10 month old-yet not fixed WP bug: https://core.trac.wordpress.org/ticket/42069
|
||||
// TLDR: when updating a post with meta via WP REST API, `update_metadata` should only
|
||||
// be called for metas whose value changed.
|
||||
// However, the equality check is fooled by values including characters that are
|
||||
// slashed or converted to entities, like " or <.
|
||||
// `update_metadata` is then called and returns `false` (because value didn't change) which results
|
||||
// in REST API page update to abort with a 500 error code....
|
||||
// To fix the issue, we hook into REST API page update and force `update_metadata` to return `true`
|
||||
// when value didn't change (only applied to our own meta keys).
|
||||
add_action( 'rest_insert_page', array( $this, 'rest_insert_page' ) );
|
||||
|
||||
// Need to deal with our metabox styling when inside GB.
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 1 );
|
||||
|
||||
// To register the post metas is needed because we want to change their value within our custom GB blocks
|
||||
// Editing a post meta via REST API is allowed by default unless its key is protected (starts with `_`)
|
||||
// which is the case here so we also need to create a custom auth function.
|
||||
$auth = array( $this, 'meta_auth' );
|
||||
$args = array(
|
||||
'auth_callback' => $auth,
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
);
|
||||
register_meta( 'post', '_et_pb_use_builder', $args );
|
||||
$args = array(
|
||||
'auth_callback' => $auth,
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
);
|
||||
register_meta( 'post', '_et_pb_old_content', $args );
|
||||
$args = array(
|
||||
'auth_callback' => $auth,
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
);
|
||||
register_meta( 'post', '_et_gb_content_width', $args );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( et_core_is_gutenberg_active() ) {
|
||||
new ET_Builder_Block_Editor_Integration();
|
||||
}
|
162
includes/builder/feature/BlockTemplates.php
Normal file
162
includes/builder/feature/BlockTemplates.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* Block Templates Compatibility.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Block Templates Compatibility Class.
|
||||
*
|
||||
* @since 4.9.8
|
||||
*/
|
||||
class ET_Builder_Block_Templates {
|
||||
/**
|
||||
* Instance of `ET_Builder_Block_Templates`.
|
||||
*
|
||||
* @var ET_Builder_Block_Templates
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* ET_Builder_Block_Templates constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->set_query_templates_filters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 4.9.8
|
||||
*
|
||||
* @return ET_Builder_Block_Templates
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set query templates filters to override block templates.
|
||||
*
|
||||
* @since 4.9.8
|
||||
*/
|
||||
public function set_query_templates_filters() {
|
||||
// Bail early if current active builder is not DBP.
|
||||
if ( ! et_is_builder_plugin_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail early if `locate_block_template` function doesn't exists (WP 5.8).
|
||||
if ( ! function_exists( 'locate_block_template' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add those filters only when current active theme supports `block-templates` or
|
||||
// has block templates index HTML.
|
||||
if ( ! current_theme_supports( 'block-templates' ) && ! is_readable( get_stylesheet_directory() . '/block-templates/index.html' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of possible hook names:
|
||||
* - `404_template`
|
||||
* - `archive_template`
|
||||
* - `attachment_template` (Not Included)
|
||||
* - `author_template`
|
||||
* - `category_template`
|
||||
* - `date_template`
|
||||
* - `embed_template` (Not Included)
|
||||
* - `frontpage_template`
|
||||
* - `home_template`
|
||||
* - `index_template`
|
||||
* - `page_template`
|
||||
* - `paged_template`
|
||||
* - `privacypolicy_template`
|
||||
* - `search_template`
|
||||
* - `single_template`
|
||||
* - `singular_template`
|
||||
* - `tag_template`
|
||||
* - `taxonomy_template`
|
||||
*
|
||||
* However we don't include `attachment`, `paged`, and `embed` because they are not
|
||||
* modified or attached to TB tempates.
|
||||
*/
|
||||
$template_types = array(
|
||||
'404_template',
|
||||
'archive_template',
|
||||
'author_template',
|
||||
'category_template',
|
||||
'date_template',
|
||||
'frontpage_template',
|
||||
'home_template',
|
||||
'index_template',
|
||||
'page_template',
|
||||
'privacypolicy_template',
|
||||
'search_template',
|
||||
'single_template',
|
||||
'singular_template',
|
||||
'tag_template',
|
||||
'taxonomy_template',
|
||||
);
|
||||
|
||||
foreach ( $template_types as $template ) {
|
||||
add_filter( $template, array( $this, 'get_custom_query_template' ), 30, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pre-defined query template to override block template (modified default template
|
||||
* or custom template).
|
||||
*
|
||||
* @since 4.9.8
|
||||
*
|
||||
* @param string $template Path to the template. See locate_template().
|
||||
* @param string $type Sanitized filename without extension.
|
||||
* @param array $templates A list of template candidates, in descending order of priority.
|
||||
*
|
||||
* @return string Modified path to the template.
|
||||
*/
|
||||
public function get_custom_query_template( $template, $type, $templates ) {
|
||||
// Bail early if there is no TB templates for current page request.
|
||||
if ( empty( et_theme_builder_get_template_layouts() ) ) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
// 1. Restore - Get pre-defined query template.
|
||||
$original_template = $template;
|
||||
$template = locate_template( $templates );
|
||||
|
||||
// If the `locate_template` return empty path because there is no template or theme
|
||||
// theme compat found, use builder block template canvas.
|
||||
if ( empty( $template ) && 'template-canvas.php' === basename( $original_template ) ) {
|
||||
$template = ET_BUILDER_DIR . 'templates/block-template-canvas.php';
|
||||
}
|
||||
|
||||
// 2. Remove hooks added for template canvas (block template).
|
||||
// Remove viewport meta tag.
|
||||
if ( function_exists( '_block_template_viewport_meta_tag' ) ) {
|
||||
remove_action( 'wp_head', '_block_template_viewport_meta_tag', 0 );
|
||||
}
|
||||
|
||||
// Render conditional title tag for `title-tag` support.
|
||||
add_action( 'wp_head', '_wp_render_title_tag', 1 );
|
||||
|
||||
// Remove unconditional title tag.
|
||||
if ( function_exists( '_block_template_render_title_tag' ) ) {
|
||||
remove_action( 'wp_head', '_block_template_render_title_tag', 1 );
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
|
||||
ET_Builder_Block_Templates::instance();
|
149
includes/builder/feature/ClassicEditor.php
Normal file
149
includes/builder/feature/ClassicEditor.php
Normal file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Classic Editor Enabler.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'ET_Builder_Classic_Editor' ) ) :
|
||||
/**
|
||||
* Load classic editor and disable Gutenberg/Block Editor
|
||||
*
|
||||
* Adapted from Classic Editor plugin by WordPress Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License version 2, as published by the Free Software Foundation. You may NOT assume
|
||||
* that you can use any other version of the GPL.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Classic Editor
|
||||
*
|
||||
* Copyright 2018 by WordPress Contributors
|
||||
*
|
||||
* Classic Editor is released under the GPL-2.0+
|
||||
*/
|
||||
class ET_Builder_Classic_Editor {
|
||||
/**
|
||||
* Instance of `ET_Builder_Classic_Editor`.
|
||||
*
|
||||
* @var ET_Builder_Classic_Editor
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* ET_Builder_Classic_Editor constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'init', array( $this, 'register_actions' ), 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 3.18
|
||||
*
|
||||
* @return ET_Builder_Classic_Editor
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add & remove necessary actions and filters needed to load Classic Editor back
|
||||
* These filters are based on Classic Editor plugin to ensure required filters & actions needed
|
||||
* to load Classic Editor on Gutenberg / Block Editor (WordPress 5.0). All conditiononal Block Editor
|
||||
* loader based on query string has been removed.
|
||||
*
|
||||
* @since 3.18
|
||||
*/
|
||||
public function register_actions() {
|
||||
$gutenberg = has_filter( 'replace_editor', 'gutenberg_init' );
|
||||
$block_editor = version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' );
|
||||
|
||||
if ( ! $gutenberg && ! $block_editor ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load classic editor.
|
||||
// phpcs:ignore WordPress.Security.NonceVerification -- This function does not change any state, and is therefore not susceptible to CSRF.
|
||||
$enable_classic_editor = apply_filters( 'et_builder_enable_classic_editor', isset( $_GET['et_classic_editor'] ) );
|
||||
|
||||
if ( $block_editor && $enable_classic_editor ) {
|
||||
add_filter( 'use_block_editor_for_post_type', '__return_false', 100 );
|
||||
}
|
||||
|
||||
if ( $gutenberg && $enable_classic_editor ) {
|
||||
// gutenberg.php.
|
||||
remove_action( 'admin_menu', 'gutenberg_menu' );
|
||||
remove_action( 'admin_notices', 'gutenberg_build_files_notice' );
|
||||
remove_action( 'admin_notices', 'gutenberg_wordpress_version_notice' );
|
||||
remove_action( 'admin_init', 'gutenberg_redirect_demo' );
|
||||
|
||||
remove_filter( 'replace_editor', 'gutenberg_init' );
|
||||
|
||||
// lib/client-assets.php.
|
||||
remove_action( 'wp_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 );
|
||||
remove_action( 'admin_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 );
|
||||
remove_action( 'wp_enqueue_scripts', 'gutenberg_common_scripts_and_styles' );
|
||||
remove_action( 'admin_enqueue_scripts', 'gutenberg_common_scripts_and_styles' );
|
||||
|
||||
// lib/compat.php.
|
||||
remove_filter( 'wp_refresh_nonces', 'gutenberg_add_rest_nonce_to_heartbeat_response_headers' );
|
||||
|
||||
// lib/rest-api.php.
|
||||
remove_action( 'rest_api_init', 'gutenberg_register_rest_routes' );
|
||||
remove_action( 'rest_api_init', 'gutenberg_add_taxonomy_visibility_field' );
|
||||
|
||||
remove_filter( 'rest_request_after_callbacks', 'gutenberg_filter_oembed_result' );
|
||||
remove_filter( 'registered_post_type', 'gutenberg_register_post_prepare_functions' );
|
||||
remove_filter( 'register_post_type_args', 'gutenberg_filter_post_type_labels' );
|
||||
|
||||
// lib/meta-box-partial-page.php.
|
||||
remove_action( 'do_meta_boxes', 'gutenberg_meta_box_save', 1000 );
|
||||
remove_action( 'submitpost_box', 'gutenberg_intercept_meta_box_render' );
|
||||
remove_action( 'submitpage_box', 'gutenberg_intercept_meta_box_render' );
|
||||
remove_action( 'edit_page_form', 'gutenberg_intercept_meta_box_render' );
|
||||
remove_action( 'edit_form_advanced', 'gutenberg_intercept_meta_box_render' );
|
||||
|
||||
remove_filter( 'redirect_post_location', 'gutenberg_meta_box_save_redirect' );
|
||||
remove_filter( 'filter_gutenberg_meta_boxes', 'gutenberg_filter_meta_boxes' );
|
||||
}
|
||||
|
||||
if ( $gutenberg && $enable_classic_editor ) {
|
||||
// gutenberg.php.
|
||||
remove_action( 'admin_init', 'gutenberg_add_edit_link_filters' );
|
||||
remove_action( 'admin_print_scripts-edit.php', 'gutenberg_replace_default_add_new_button' );
|
||||
|
||||
remove_filter( 'body_class', 'gutenberg_add_responsive_body_class' );
|
||||
remove_filter( 'admin_url', 'gutenberg_modify_add_new_button_url' );
|
||||
|
||||
// lib/compat.php.
|
||||
remove_action( 'admin_enqueue_scripts', 'gutenberg_check_if_classic_needs_warning_about_blocks' );
|
||||
|
||||
// lib/register.php.
|
||||
remove_action( 'edit_form_top', 'gutenberg_remember_classic_editor_when_saving_posts' );
|
||||
|
||||
remove_filter( 'redirect_post_location', 'gutenberg_redirect_to_classic_editor_when_saving_posts' );
|
||||
remove_filter( 'get_edit_post_link', 'gutenberg_revisions_link_to_editor' );
|
||||
remove_filter( 'wp_prepare_revision_for_js', 'gutenberg_revisions_restore' );
|
||||
remove_filter( 'display_post_states', 'gutenberg_add_gutenberg_post_state' );
|
||||
|
||||
// lib/plugin-compat.php.
|
||||
remove_filter( 'rest_pre_insert_post', 'gutenberg_remove_wpcom_markdown_support' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
ET_Builder_Classic_Editor::instance();
|
692
includes/builder/feature/CriticalCSS.php
Normal file
692
includes/builder/feature/CriticalCSS.php
Normal file
@ -0,0 +1,692 @@
|
||||
<?php
|
||||
/**
|
||||
* Extract Critical CSS
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Critical CSS
|
||||
*/
|
||||
class ET_Builder_Critical_CSS {
|
||||
// Include in Critical CSS the Required Assets (those which don't depends on Content).
|
||||
// To force some of the Required Assets in the BTF, check `maybe_defer_global_asset` method.
|
||||
const INCLUDE_REQUIRED = true;
|
||||
// Used to estimate height for percentage based units like `vh`,`em`, etc.
|
||||
const VIEWPORT_HEIGHT = 1000;
|
||||
const FONT_HEIGHT = 16;
|
||||
|
||||
/**
|
||||
* Is Critical CSS Threshold Height.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_above_the_fold_height;
|
||||
|
||||
/**
|
||||
* Root element.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $_root;
|
||||
|
||||
/**
|
||||
* Modules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_modules = [];
|
||||
|
||||
/**
|
||||
* Modules.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $_content;
|
||||
|
||||
/**
|
||||
* Above The Fold Sections.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_atf_sections = [];
|
||||
|
||||
/**
|
||||
* Builder Style Manager.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_builder_styles = [];
|
||||
|
||||
/**
|
||||
* Instance of `ET_Builder_Critical_CSS`.
|
||||
*
|
||||
* @var ET_Builder_Critical_CSS
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* ET_Builder_Critical_CSS constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
global $shortname;
|
||||
|
||||
if ( et_is_builder_plugin_active() ) {
|
||||
$options = get_option( 'et_pb_builder_options', array() );
|
||||
$critical_threshold_height = isset( $options['performance_main_critical_threshold_height'] ) ? $options['performance_main_critical_threshold_height'] : 'Medium';
|
||||
} else {
|
||||
$critical_threshold_height = et_get_option( $shortname . '_critical_threshold_height', 'Medium' );
|
||||
}
|
||||
|
||||
if ( 'High' === $critical_threshold_height ) {
|
||||
$this->_above_the_fold_height = 1500;
|
||||
} elseif ( 'Medium' === $critical_threshold_height ) {
|
||||
$this->_above_the_fold_height = 1000;
|
||||
} else {
|
||||
$this->_above_the_fold_height = 500;
|
||||
}
|
||||
|
||||
add_filter( 'et_builder_critical_css_enabled', '__return_true' );
|
||||
// Dynamic CSS content shortcode modules.
|
||||
add_filter( 'et_dynamic_assets_modules_atf', [ $this, 'dynamic_assets_modules_atf' ], 10, 2 );
|
||||
// Detect when renderining Above The Fold sections.
|
||||
add_filter( 'pre_do_shortcode_tag', [ $this, 'check_section_start' ], 99, 4 );
|
||||
add_filter( 'do_shortcode_tag', [ $this, 'check_section_end' ], 99, 2 );
|
||||
|
||||
// Analyze Builder style manager.
|
||||
add_filter( 'et_builder_module_style_manager', [ $this, 'enable_builder' ] );
|
||||
|
||||
// Dynamic CSS content shortcode.
|
||||
add_filter( 'et_global_assets_list', [ $this, 'maybe_defer_global_asset' ], 99 );
|
||||
|
||||
if ( self::INCLUDE_REQUIRED ) {
|
||||
add_filter( 'et_dynamic_assets_atf_includes_required', '__return_true' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer some global assets if threshold is met.
|
||||
*
|
||||
* @param array $assets assets to defer.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return array $assets assets to be deferred.
|
||||
*/
|
||||
public function maybe_defer_global_asset( $assets ) {
|
||||
$defer = [
|
||||
'et_divi_footer',
|
||||
'et_divi_gutters_footer',
|
||||
'et_divi_comments',
|
||||
];
|
||||
|
||||
foreach ( $defer as $key ) {
|
||||
if ( isset( $assets[ $key ] ) ) {
|
||||
$assets[ $key ]['maybe_defer'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a PageResource to write its content on file, even when empty
|
||||
*
|
||||
* @param bool $force Default value.
|
||||
* @param array $resource Critical/Deferred PageResources.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function force_resource_write( $force, $resource ) {
|
||||
$styles = $this->_builder_styles;
|
||||
if ( empty( $styles ) ) {
|
||||
return $force;
|
||||
}
|
||||
|
||||
$forced_slugs = [
|
||||
$styles['deferred']->slug,
|
||||
$styles['manager']->slug,
|
||||
];
|
||||
|
||||
return in_array( $resource->slug, $forced_slugs, true ) ? true : $force;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze Builder style manager.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param array $styles Style Managers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function enable_builder( $styles ) {
|
||||
$this->_builder_styles = $styles;
|
||||
|
||||
// There are cases where external assets generation might be disabled at runtime,
|
||||
// ensure Critical CSS and Dynamic Assets use the same logic to avoid side effects.
|
||||
if ( ! et_should_generate_dynamic_assets() ) {
|
||||
$this->disable();
|
||||
return $styles;
|
||||
}
|
||||
|
||||
add_filter( 'et_core_page_resource_force_write', [ $this, 'force_resource_write' ], 10, 2 );
|
||||
add_filter( 'et_core_page_resource_tag', [ $this, 'builder_style_tag' ], 10, 5 );
|
||||
if ( et_builder_is_mod_pagespeed_enabled() ) {
|
||||
// PageSpeed filters out `preload` links so we gotta use `prefetch` but
|
||||
// Safari doesn't support the latter....
|
||||
add_action( 'wp_body_open', [ $this, 'add_safari_prefetch_workaround' ], 1 );
|
||||
}
|
||||
|
||||
return $styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints deferred Critical CSS stlyesheet.
|
||||
*
|
||||
* @param string $tag stylesheet template.
|
||||
* @param string $slug stylesheet slug.
|
||||
* @param string $scheme stylesheet URL.
|
||||
* @param string $onload stylesheet onload attribute.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function builder_style_tag( $tag, $slug, $scheme, $onload ) {
|
||||
$deferred = $this->_builder_styles['deferred'];
|
||||
$inlined = $this->_builder_styles['manager'];
|
||||
|
||||
// reason: Stylsheet needs to be printed on demand.
|
||||
// phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
|
||||
// reason: Snake case requires refactor of PageResource.php.
|
||||
// phpcs:disable ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
switch ( $slug ) {
|
||||
case $deferred->slug:
|
||||
// Don't enqueue empty resources.
|
||||
if ( 0 === et_()->WPFS()->size( $deferred->path ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Use 'prefetch' when Mod PageSpeed is detected because it removes 'preload' links.
|
||||
$rel = et_builder_is_mod_pagespeed_enabled() ? 'prefetch' : 'preload';
|
||||
|
||||
/**
|
||||
* Filter deferred styles rel attribute.
|
||||
*
|
||||
* Mod PageSpeed removes 'preload' links and we attempt to fix that by trying to detect if
|
||||
* the 'x-mod-pagespeed' (Apache) or 'x-page-speed' (Nginx) header is present and if it is,
|
||||
* replace 'preload' with 'prefetch'. However, in some cases, like when the request goes through
|
||||
* a CDN first, we are unable to detect the header. This hook can be used to change the 'rel'
|
||||
* attribute to use 'prefetch' when our et_builder_is_mod_pagespeed_enabled() function fails
|
||||
* to detect Mod PageSpeed.
|
||||
*
|
||||
* With that out of the way, the only reason I wrote this detailed description is to make Fabio proud.
|
||||
*
|
||||
* @since 4.11.3
|
||||
*
|
||||
* @param string $rel
|
||||
*/
|
||||
$rel = apply_filters( 'et_deferred_styles_rel', $rel );
|
||||
|
||||
// Defer the stylesheet.
|
||||
$template = '<link rel="%4$s" as="style" id="%1$s" href="%2$s" onload="this.onload=null;this.rel=\'stylesheet\';%3$s" />';
|
||||
|
||||
return sprintf( $template, $slug, $scheme, $onload, $rel );
|
||||
case $inlined->slug:
|
||||
// Inline the stylesheet.
|
||||
$template = "<style id=\"et-critical-inline-css\">%1\$s</style>\n";
|
||||
$content = et_()->WPFS()->get_contents( $inlined->path );
|
||||
return sprintf( $template, $content );
|
||||
}
|
||||
// phpcs:enable
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safari doesn't support `prefetch`......
|
||||
*
|
||||
* @since 4.10.7
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_safari_prefetch_workaround() {
|
||||
// .... so we turn it into `preload` using JS.
|
||||
?>
|
||||
<script type="application/javascript">
|
||||
(function() {
|
||||
var relList = document.createElement('link').relList;
|
||||
if (!!(relList && relList.supports && relList.supports('prefetch'))) {
|
||||
// Browser supports `prefetch`, no workaround needed.
|
||||
return;
|
||||
}
|
||||
|
||||
var links = document.getElementsByTagName('link');
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
var link = links[i];
|
||||
if ('prefetch' === link.rel) {
|
||||
link.rel = 'preload';
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Add `set_style` filter when rendering an ATF section.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param false|string $value Short-circuit return value. Either false or the value to replace the shortcode with.
|
||||
* @param string $tag Shortcode name.
|
||||
* @param array|string $attr Shortcode attributes array or empty string.
|
||||
* @param array $m Regular expression match array.
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function check_section_start( $value, $tag, $attr, $m ) {
|
||||
if ( 'et_pb_section' !== $tag ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$attrs = $m[3];
|
||||
$action = 'et_builder_set_style';
|
||||
$filter = [ $this, 'set_style' ];
|
||||
$active = has_filter( $action, $filter );
|
||||
|
||||
if ( ! empty( $this->_atf_sections[ $attrs ] ) ) {
|
||||
$this->_atf_sections[ $attrs ]--;
|
||||
|
||||
if ( ! $active ) {
|
||||
add_filter( $action, [ $this, 'set_style' ], 10 );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove `set_style` filter after rendering an ATF section.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @param string $output Shortcode output.
|
||||
* @param string $tag Shortcode name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function check_section_end( $output, $tag ) {
|
||||
static $section = 0;
|
||||
|
||||
if ( 'et_pb_section' !== $tag ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
$action = 'et_builder_set_style';
|
||||
$filter = [ $this, 'set_style' ];
|
||||
|
||||
if ( has_filter( $action, $filter ) ) {
|
||||
remove_filter( $action, $filter, 10 );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter used to analize content coming from Dynamic Access Class.
|
||||
*
|
||||
* @param array $value Default shortcodes list (empty).
|
||||
* @param string $content TB/Post Content.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return array List of ATF shortcodes.
|
||||
*/
|
||||
public function dynamic_assets_modules_atf( $value, $content = '' ) {
|
||||
if ( empty( $content ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$modules = $this->extract( $content );
|
||||
|
||||
// Dynamic CSS content shortcode.
|
||||
add_filter( 'et_dynamic_assets_content', [ $this, 'dynamic_assets_content' ] );
|
||||
|
||||
return $modules;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns splitted (ATF/BFT) Content.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function dynamic_assets_content() {
|
||||
return $this->_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* While the filter is applied, any rendered style will be considered critical.
|
||||
*
|
||||
* @param array $style Style.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function set_style( $style ) {
|
||||
$style['critical'] = true;
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Content into shortcodes.
|
||||
*
|
||||
* @param string $content TB/Post Content.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return array|boolean
|
||||
*/
|
||||
public static function parse_shortcode( $content ) {
|
||||
static $regex;
|
||||
|
||||
if ( false === strpos( $content, '[' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $regex ) ) {
|
||||
$regex = '/' . get_shortcode_regex() . '/';
|
||||
|
||||
// Add missing child shortcodes (because dynamically added).
|
||||
$existing = 'et_pb_pricing_tables';
|
||||
$shortcodes = [
|
||||
$existing,
|
||||
'et_pb_pricing_item',
|
||||
];
|
||||
|
||||
$regex = str_replace( $existing, join( '|', $shortcodes ), $regex );
|
||||
}
|
||||
|
||||
preg_match_all( $regex, $content, $matches, PREG_SET_ORDER );
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimates height to split Content in ATF/BTF.
|
||||
*
|
||||
* @param string $content TB/Post Content.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return array List of ATF shortcodes.
|
||||
*/
|
||||
public function extract( $content ) {
|
||||
// Create root object when needed.
|
||||
if ( empty( $this->_root ) ) {
|
||||
$this->_root = (object) [
|
||||
'tag' => 'root',
|
||||
'height' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
if ( $this->_root->height >= $this->_above_the_fold_height ) {
|
||||
// Do nothing when root already exists and its height >= treshold.
|
||||
return [];
|
||||
}
|
||||
|
||||
$shortcodes = self::parse_shortcode( $content );
|
||||
|
||||
if ( ! is_array( $shortcodes ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$shortcodes = array_reverse( $shortcodes );
|
||||
$is_above_the_fold = true;
|
||||
$root = $this->_root;
|
||||
$root->count = count( $shortcodes );
|
||||
$stack = [ $root ];
|
||||
$parent = end( $stack );
|
||||
$tags = [];
|
||||
$atf_content = '';
|
||||
$btf_content = '';
|
||||
|
||||
$structure_slugs = [
|
||||
'et_pb_section',
|
||||
'et_pb_row',
|
||||
'et_pb_row_inner',
|
||||
'et_pb_column',
|
||||
'et_pb_column_inner',
|
||||
];
|
||||
|
||||
$section = '';
|
||||
$section_shortcode = '';
|
||||
|
||||
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
|
||||
while ( $is_above_the_fold && $shortcode = array_pop( $shortcodes ) ) {
|
||||
list( $raw,, $tag, $attrs,, $content ) = $shortcode;
|
||||
|
||||
$tags[] = $tag;
|
||||
$children = self::parse_shortcode( $content );
|
||||
$element = (object) [
|
||||
'tag' => $tag,
|
||||
'children' => [],
|
||||
'height' => 0,
|
||||
'margin' => 0,
|
||||
'padding' => 0,
|
||||
'attrs' => [],
|
||||
];
|
||||
|
||||
switch ( $tag ) {
|
||||
case 'et_pb_pricing_table':
|
||||
$lines = array_filter( explode( "\n", str_replace( array( '<p>', '</p>', '<br />' ), "\n", $content ) ) );
|
||||
$content = '';
|
||||
|
||||
foreach ( $lines as $line ) {
|
||||
$content .= sprintf( '[et_pb_pricing_item]%s[/et_pb_pricing_item]', trim( $line ) );
|
||||
}
|
||||
|
||||
$children = self::parse_shortcode( $content );
|
||||
break;
|
||||
case 'et_pb_section':
|
||||
$section = $attrs;
|
||||
$section_shortcode = $raw;
|
||||
break;
|
||||
}
|
||||
|
||||
$props = shortcode_parse_atts( $attrs );
|
||||
|
||||
if ( isset( $props['custom_margin'] ) ) {
|
||||
$margin = self::get_margin_padding_height( $props['custom_margin'] );
|
||||
$element->margin = $margin;
|
||||
if ( $margin > 0 ) {
|
||||
$element->height += $margin;
|
||||
$element->attrs[] = 'margin:' . $props['custom_margin'] . "-> $margin";
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $props['custom_padding'] ) ) {
|
||||
$padding = self::get_margin_padding_height( $props['custom_padding'] );
|
||||
$element->padding = $padding;
|
||||
if ( $padding > 0 ) {
|
||||
$element->height += $padding;
|
||||
$element->attrs[] = 'padding:' . $props['custom_padding'] . "-> $padding";
|
||||
}
|
||||
}
|
||||
|
||||
if ( false !== $children ) {
|
||||
// Non empty structure element.
|
||||
$element->count = count( $children );
|
||||
$stack[] = $element;
|
||||
$shortcodes = array_merge( $shortcodes, array_reverse( $children ) );
|
||||
} else {
|
||||
// Only add default content height for modules, not empty structure.
|
||||
if ( ! in_array( $tag, $structure_slugs, true ) ) {
|
||||
$element->height += 100;
|
||||
}
|
||||
do {
|
||||
$parent = end( $stack );
|
||||
|
||||
switch ( $element->tag ) {
|
||||
case 'et_pb_column':
|
||||
case 'et_pb_column_inner':
|
||||
// Do nothing.
|
||||
break;
|
||||
case 'et_pb_row':
|
||||
case 'et_pb_row_inner':
|
||||
// Row height is determined by its tallest column.
|
||||
$max = 0;
|
||||
|
||||
foreach ( $element->children as $column ) {
|
||||
$max = max( $max, $column->height );
|
||||
}
|
||||
|
||||
$element->height += $max;
|
||||
$parent->height += $element->height;
|
||||
break;
|
||||
case 'et_pb_section':
|
||||
// Update Above The Fold Sections.
|
||||
if ( isset( $this->_atf_sections[ $section ] ) ) {
|
||||
$this->_atf_sections[ $section ]++;
|
||||
} else {
|
||||
$this->_atf_sections[ $section ] = 1;
|
||||
}
|
||||
|
||||
$atf_content .= $section_shortcode;
|
||||
$root->height += $element->height;
|
||||
|
||||
if ( $root->height >= $this->_above_the_fold_height ) {
|
||||
$is_above_the_fold = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$parent->height += $element->height;
|
||||
}
|
||||
|
||||
$parent->children[] = $element;
|
||||
|
||||
if ( 0 !== --$parent->count ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$element = $parent;
|
||||
array_pop( $stack );
|
||||
if ( empty( $stack ) ) {
|
||||
break;
|
||||
}
|
||||
} while ( $is_above_the_fold && 0 !== --$parent->count );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $shortcodes as $shortcode ) {
|
||||
$btf_content .= $shortcode[0];
|
||||
}
|
||||
|
||||
$tags = array_unique( $tags );
|
||||
$this->_modules = array_unique( array_merge( $this->_modules, $tags ) );
|
||||
$this->_content = (object) [
|
||||
'atf' => $atf_content,
|
||||
'btf' => $btf_content,
|
||||
];
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate margin and padding.
|
||||
*
|
||||
* @param string $value Margin and padding values.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return int margin/padding height value.
|
||||
*/
|
||||
public static function get_margin_padding_height( $value ) {
|
||||
$values = explode( '|', $value );
|
||||
|
||||
if ( empty( $values ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only top/bottom values are needed.
|
||||
$values = array_map( 'trim', [ $values[0], $values[2] ] );
|
||||
$total = 0;
|
||||
|
||||
foreach ( $values as $value ) {
|
||||
if ( '' === $value ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$unit = et_pb_get_value_unit( $value );
|
||||
|
||||
// Remove the unit, if present.
|
||||
if ( false !== strpos( $value, $unit ) ) {
|
||||
$value = substr( $value, 0, -strlen( $unit ) );
|
||||
}
|
||||
|
||||
$value = (int) $value;
|
||||
|
||||
switch ( $unit ) {
|
||||
case 'rem':
|
||||
case 'em':
|
||||
$value *= self::FONT_HEIGHT;
|
||||
break;
|
||||
case 'vh':
|
||||
$value = ( $value * self::VIEWPORT_HEIGHT ) / 100;
|
||||
break;
|
||||
case 'px':
|
||||
break;
|
||||
default:
|
||||
$value = 0;
|
||||
}
|
||||
|
||||
$total += $value;
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable Critical CSS.
|
||||
*
|
||||
* @since 4.12.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disable() {
|
||||
remove_filter( 'et_builder_critical_css_enabled', '__return_true' );
|
||||
remove_filter( 'et_dynamic_assets_modules_atf', [ $this, 'dynamic_assets_modules_atf' ] );
|
||||
remove_filter( 'pre_do_shortcode_tag', [ $this, 'check_section_start' ] );
|
||||
remove_filter( 'do_shortcode_tag', [ $this, 'check_section_end' ] );
|
||||
remove_filter( 'et_builder_module_style_manager', [ $this, 'enable_builder' ] );
|
||||
remove_filter( 'et_global_assets_list', [ $this, 'maybe_defer_global_asset' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return ET_Builder_Critical_CSS
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
}
|
||||
|
||||
ET_Builder_Critical_CSS::instance();
|
188
includes/builder/feature/DoNotCachePage.php
Normal file
188
includes/builder/feature/DoNotCachePage.php
Normal file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/**
|
||||
* Prevent Page/Post from being cached.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to prevent Page/Post from being cached.
|
||||
*/
|
||||
class ET_Builder_Do_Not_Cache_Page {
|
||||
/**
|
||||
* Instance of `ET_Builder_Do_Not_Cache_Page`.
|
||||
*
|
||||
* @var ET_Builder_Do_Not_Cache_Page
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* Instance of `ET_Builder_Do_Not_Cache_Page`.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_processed = false;
|
||||
|
||||
/**
|
||||
* ET_Builder_Do_Not_Cache_Page constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'get_header', [ $this, 'maybe_prevent_cache' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* When a page loads for the first time, Builder CSS is generated during the request and then
|
||||
* printed inline in the footer which causes CLS issues because the CSS is loading late.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prevent_cache() {
|
||||
// Ensure this only runs once.
|
||||
if ( $this->_processed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_processed = true;
|
||||
|
||||
// Disable several plugins which do not honor `DONOTCACHEPAGE` (set in `PageResource.php`).
|
||||
if ( ! headers_sent() ) {
|
||||
// Sending `no-cache` header should prevent CDNs from caching the first request.
|
||||
header( 'Cache-Control: no-store, no-cache' );
|
||||
// Disable SiteGround Optimizer Dynamic Cache.
|
||||
header( 'X-Cache-Enabled: False' );
|
||||
}
|
||||
|
||||
// Disable LiteSpeed Cache.
|
||||
$reason = esc_html__( 'Generating CSS', 'et_builder' );
|
||||
do_action( 'litespeed_control_set_nocache', $reason );
|
||||
|
||||
// Disable WP Fastest Cache.
|
||||
if ( class_exists( 'WpFastestCacheCreateCache' ) ) {
|
||||
// This Plugin has no hook/API to disable cache programmatically....
|
||||
// The only way we can do this is by setting the `exclude_current_page_text` public property
|
||||
// to a non empty value... except the class instance is not made available anywhere in the code....
|
||||
// However, the instance also adds itself to the `wp` hook so we can find it by scanning the list
|
||||
// of all registered actions.
|
||||
$hooks = et_()->array_get( $GLOBALS, 'wp_filter.wp.10', [] );
|
||||
if ( is_array( $hooks ) ) {
|
||||
foreach ( $hooks as $key => $hook ) {
|
||||
if (
|
||||
isset( $hook['function'] ) &&
|
||||
is_array( $hook['function'] ) &&
|
||||
is_a( $hook['function'][0], 'WpFastestCacheCreateCache' )
|
||||
) {
|
||||
$wp_fastest_cache = $hook['function'][0];
|
||||
$wp_fastest_cache->exclude_current_page_text = "<!-- $reason -->";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable Breeze Cache.
|
||||
if ( function_exists( 'breeze_cache' ) ) {
|
||||
// This Plugin has no hook/API to disable cache programmatically....
|
||||
// The only way we can do this is by overwriting its configuration
|
||||
// which is exposed as global variable.
|
||||
global $breeze_config;
|
||||
if ( isset( $breeze_config['cache_options'] ) ) {
|
||||
$cache_options =& $breeze_config['cache_options'];
|
||||
if ( is_array( $cache_options ) ) {
|
||||
$cache_options['breeze-browser-cache'] = 0;
|
||||
$cache_options['breeze-desktop-cache'] = 0;
|
||||
$cache_options['breeze-mobile-cache'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable Hyper Cache.
|
||||
if ( function_exists( 'hyper_cache_callback' ) ) {
|
||||
global $hyper_cache_stop;
|
||||
$hyper_cache_stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable Cache on first page request.
|
||||
*
|
||||
* @see prevent_cache()
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_prevent_cache() {
|
||||
// Bail if the magic already happened.
|
||||
if ( $this->_processed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable in the Visual Builder
|
||||
if ( et_fb_is_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_id = et_core_page_resource_get_the_ID();
|
||||
$is_preview = is_preview() || is_et_pb_preview();
|
||||
$forced_in_footer = $post_id && et_builder_setting_is_on( 'et_pb_css_in_footer', $post_id );
|
||||
$forced_inline = (
|
||||
! $post_id ||
|
||||
$is_preview ||
|
||||
$forced_in_footer ||
|
||||
et_builder_setting_is_off( 'et_pb_static_css_file', $post_id ) ||
|
||||
et_core_is_safe_mode_active() ||
|
||||
ET_GB_Block_Layout::is_layout_block_preview()
|
||||
);
|
||||
|
||||
// If the post is password protected and a password has not been provided yet,
|
||||
// no content (including any custom style) will be printed.
|
||||
// When static css file option is enabled this will result in missing styles.
|
||||
if ( ! $forced_inline && post_password_required( $post_id ? $post_id : null ) ) {
|
||||
$forced_inline = true;
|
||||
}
|
||||
|
||||
// Bail if using inline styles, page content won't be changing between requests anyway.
|
||||
if ( $forced_inline ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$unified = ! $forced_inline && ! $forced_in_footer;
|
||||
$owner = $unified ? 'core' : 'builder';
|
||||
$slug = $unified ? 'unified' : 'module-design';
|
||||
$slug .= $unified && et_builder_post_is_of_custom_post_type( $post_id ) ? '-cpt' : '';
|
||||
$slug = et_theme_builder_decorate_page_resource_slug( $post_id, $slug );
|
||||
|
||||
$resource = et_core_page_resource_get( $owner, $slug, $post_id );
|
||||
|
||||
// Bail if Builder CSS already exists in external file, this is the request we want to cache.
|
||||
if ( $resource->has_file() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->prevent_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @return ET_Builder_Do_Not_Cache_Page
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ET_Builder_Do_Not_Cache_Page::instance();
|
419
includes/builder/feature/ErrorReport.php
Normal file
419
includes/builder/feature/ErrorReport.php
Normal file
@ -0,0 +1,419 @@
|
||||
<?php
|
||||
/**
|
||||
* Handle error report
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
// get_plugins() is only available on dashboard; Manually require it needed.
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to send an error report.
|
||||
*/
|
||||
class ET_Builder_Error_Report {
|
||||
/**
|
||||
* Instance of `ET_Core_Data_Utils`.
|
||||
*
|
||||
* @var ET_Core_Data_Utils
|
||||
*/
|
||||
protected static $_;
|
||||
|
||||
/**
|
||||
* Instance of `ET_Builder_Error_Report`.
|
||||
*
|
||||
* @var ET_Builder_Error_Report
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* ET_Builder_Error_Report constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_ajax_et_fb_error_report', array( 'ET_Builder_Error_Report', 'endpoint' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get json_decode data and stripslashes if needed.
|
||||
*
|
||||
* @since 3.24
|
||||
*
|
||||
* @param string $data Data to be decoded.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function json_decode_maybe_stripslashes( $data ) {
|
||||
$decoded = json_decode( $data, true );
|
||||
if ( null === $decoded ) {
|
||||
$decoded = json_decode( stripslashes( $data ), true );
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 3.21.4
|
||||
*
|
||||
* @return ET_Builder_Error_Report
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
self::$_ = ET_Core_Data_Utils::instance();
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information sent for error reporting
|
||||
*
|
||||
* @since 3.21.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_debug_info() {
|
||||
$info = array(
|
||||
'user' => array(
|
||||
'role',
|
||||
),
|
||||
'errors' => array(
|
||||
'error_message',
|
||||
'error_message_stack',
|
||||
'error_stack',
|
||||
'component_info',
|
||||
'notes',
|
||||
),
|
||||
'page' => array(
|
||||
'post_type',
|
||||
'builder_settings',
|
||||
'builder_history',
|
||||
'preferences',
|
||||
),
|
||||
'installation' => array(
|
||||
'product_name',
|
||||
'product_version',
|
||||
'builder_version',
|
||||
'wp_version',
|
||||
'installed_plugins',
|
||||
'active_plugins',
|
||||
'must_use_plugins',
|
||||
),
|
||||
);
|
||||
|
||||
// If the site uses divi builder plugin, provide the theme information.
|
||||
if ( et_is_builder_plugin_active() ) {
|
||||
array_unshift(
|
||||
$info['installation'],
|
||||
'theme_name'
|
||||
);
|
||||
}
|
||||
|
||||
// If the site uses child theme, provide the child theme information.
|
||||
if ( is_child_theme() ) {
|
||||
array_unshift(
|
||||
$info['installation'],
|
||||
'is_child_theme',
|
||||
'child_theme_name',
|
||||
'child_theme_version'
|
||||
);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current product name
|
||||
*
|
||||
* @since 3.21.4
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function _get_product() {
|
||||
if ( et_is_builder_plugin_active() ) {
|
||||
return 'divi-builder';
|
||||
}
|
||||
|
||||
if ( function_exists( 'et_divi_fonts_url' ) ) {
|
||||
return 'Divi';
|
||||
}
|
||||
|
||||
if ( function_exists( 'et_extra_fonts_url' ) ) {
|
||||
return 'Extra';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get debug item value
|
||||
*
|
||||
* @since 3.21.4
|
||||
*
|
||||
* @param string $info_name debug info item name.
|
||||
* @param object $post alias for $_POST.
|
||||
*
|
||||
* @return string|array|object
|
||||
*/
|
||||
protected function _get_debug_value( $info_name, $post ) {
|
||||
switch ( $info_name ) {
|
||||
case 'role':
|
||||
$current_user = wp_get_current_user();
|
||||
$value = esc_html( implode( ', ', $current_user->roles ) );
|
||||
break;
|
||||
|
||||
case 'error_message':
|
||||
case 'error_message_stack':
|
||||
case 'error_stack':
|
||||
case 'notes':
|
||||
case 'post_type':
|
||||
// this will be saved into a text report, no need to convert entities.
|
||||
$value = self::$_->array_get( $post, $info_name, '' );
|
||||
break;
|
||||
|
||||
case 'latest_content':
|
||||
case 'loaded_content':
|
||||
$value = et_fb_process_to_shortcode( self::$_->array_get( $post, $info_name, array() ) );
|
||||
break;
|
||||
|
||||
case 'builder_settings':
|
||||
case 'builder_history':
|
||||
case 'component_info':
|
||||
$value = wp_json_encode( self::$_->array_get( $post, $info_name, array() ) );
|
||||
break;
|
||||
|
||||
case 'preferences':
|
||||
$value = array();
|
||||
foreach ( et_fb_app_preferences() as $name => $preference ) {
|
||||
$value[ $name ] = $preference['value'];
|
||||
}
|
||||
$value = wp_json_encode( $value );
|
||||
break;
|
||||
|
||||
case 'product_name':
|
||||
$value = $this->_get_product();
|
||||
break;
|
||||
|
||||
case 'product_version':
|
||||
$value = et_is_builder_plugin_active() ?
|
||||
self::$_->array_get( get_plugin_data( WP_PLUGIN_DIR . '/divi-builder/divi-builder.php' ), 'Version', '' ) :
|
||||
et_get_theme_version();
|
||||
|
||||
$value = esc_html( $value );
|
||||
break;
|
||||
|
||||
case 'builder_version':
|
||||
$value = ET_BUILDER_PRODUCT_VERSION;
|
||||
break;
|
||||
|
||||
case 'wp_version':
|
||||
$value = esc_html( get_bloginfo( 'version' ) );
|
||||
break;
|
||||
|
||||
case 'installed_plugins':
|
||||
$all_plugins = get_plugins();
|
||||
$value = wp_json_encode( array_keys( $all_plugins ), true );
|
||||
break;
|
||||
|
||||
case 'active_plugins':
|
||||
$all_plugins = get_plugins();
|
||||
$active_plugins_saved = get_option( 'active_plugins' );
|
||||
$active_plugins_keys = is_array( $active_plugins_saved ) ? $active_plugins_saved : array();
|
||||
$active_plugins = array_intersect_key( $all_plugins, array_flip( $active_plugins_keys ) );
|
||||
$value = wp_json_encode( $active_plugins, true );
|
||||
break;
|
||||
|
||||
case 'must_use_plugins':
|
||||
$value = wp_json_encode( get_mu_plugins(), true );
|
||||
break;
|
||||
|
||||
case 'theme_name':
|
||||
case 'child_theme_name':
|
||||
$value = esc_html( wp_get_theme()->get( 'Name' ) );
|
||||
break;
|
||||
|
||||
case 'theme_version':
|
||||
case 'child_theme_version':
|
||||
$value = esc_html( wp_get_theme()->get( 'Version' ) );
|
||||
break;
|
||||
|
||||
case 'is_child_theme':
|
||||
$value = is_child_theme() ? 'yes' : 'no';
|
||||
break;
|
||||
|
||||
default:
|
||||
$value = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get error report content
|
||||
*
|
||||
* @since 3.21.4
|
||||
*
|
||||
* @param string $data Report data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _get_report_content( $data ) {
|
||||
$report_content = '';
|
||||
|
||||
$debug_info = self::get_debug_info();
|
||||
|
||||
$report_content = array();
|
||||
|
||||
foreach ( $debug_info as $items_title => $debug_items ) {
|
||||
$item_key = 'group_title-' . $items_title;
|
||||
$items_title = ucwords( $items_title );
|
||||
|
||||
$report_content[ $item_key ] = $items_title;
|
||||
|
||||
foreach ( $debug_items as $debug_item ) {
|
||||
$item_value = et_core_esc_previously( $this->_get_debug_value( $debug_item, $data, 'array' ) );
|
||||
|
||||
$report_content[ $debug_item ] = $item_value;
|
||||
}
|
||||
}
|
||||
|
||||
return $report_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachment data as string to be passed into endpoint
|
||||
*
|
||||
* @since 3.21.4
|
||||
*
|
||||
* @param string $data Report data.
|
||||
* @param string $field Debug info item name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _get_exported_layout_content( $data, $field ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification -- Nonce has been verified in the {@see self::endpoint()}.
|
||||
// Set faux $_POST value that is required by portability.
|
||||
$_POST['post'] = isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : '';
|
||||
$_POST['content'] = self::$_instance->_get_debug_value( $field, $data );
|
||||
|
||||
// Remove page value if it is equal to `false`, avoiding paginated images not accidentally triggered.
|
||||
if ( isset( $_POST['page'] ) && false === $_POST['page'] ) {
|
||||
unset( $_POST['page'] );
|
||||
}
|
||||
|
||||
$portability = et_core_portability_load( 'et_builder' );
|
||||
// Export the content.
|
||||
$result = $portability->export( true );
|
||||
// Delete temp files or else the same content will be used for all exports.
|
||||
$portability->delete_temp_files( 'et_core_export' );
|
||||
return $result;
|
||||
// phpcs:enable
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint for sending error report request
|
||||
*
|
||||
* @since 3.21.4
|
||||
*/
|
||||
public static function endpoint() {
|
||||
// Check for valid permission. Only administrator role can send error report.
|
||||
if ( ! et_core_security_check_passed( 'manage_options', 'et_fb_send_error_report' ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => esc_html__( 'You do not have valid permission to send error report', 'et_builder' ),
|
||||
)
|
||||
);
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Check valid post id.
|
||||
$post_id = self::$_->array_get( $_POST, 'post_id', false );
|
||||
|
||||
if ( ! $post_id ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => esc_html__( 'No valid post id found', 'et_builder' ),
|
||||
)
|
||||
);
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Check report data.
|
||||
$data = self::$_->array_get( $_POST, 'data', false );
|
||||
|
||||
if ( ! $data ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => esc_html__( 'No valid report data found', 'et_builder' ),
|
||||
)
|
||||
);
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Check for Elegant Themes username & API Key.
|
||||
$updates_options = get_site_option( 'et_automatic_updates_options', array() );
|
||||
$et_username = self::$_->array_get( $updates_options, 'username', '' );
|
||||
$et_api_key = self::$_->array_get( $updates_options, 'api_key', '' );
|
||||
|
||||
if ( '' === $et_username || '' === $et_api_key ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => esc_html__( 'No Elegant Themes username or API key found', 'et_builder' ),
|
||||
)
|
||||
);
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Check for account status.
|
||||
$et_account_status = get_site_option( 'et_account_status', 'not_active' );
|
||||
|
||||
if ( 'active' !== $et_account_status ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => esc_html__( 'Your Elegant Themes account is inactive', 'et_builder' ),
|
||||
)
|
||||
);
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$data = self::json_decode_maybe_stripslashes( $data );
|
||||
$et_endpoint = apply_filters( 'et_builder_report_endpoint', 'https://www.elegantthemes.com/api/reportV2.php' );
|
||||
|
||||
// Crafting reports and send to end endpoint.
|
||||
$request_settings = array(
|
||||
'timeout' => 30,
|
||||
'body' => array(
|
||||
'username' => $et_username,
|
||||
'api_key' => $et_api_key,
|
||||
'error_report' => self::$_instance->_get_report_content( $data ),
|
||||
'site_url' => site_url(),
|
||||
'attachments' => array(
|
||||
'latest' => self::$_instance->_get_exported_layout_content( $data, 'latest_content' ),
|
||||
'loaded' => self::$_instance->_get_exported_layout_content( $data, 'loaded_content' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$request = wp_remote_post( $et_endpoint, $request_settings );
|
||||
$request_response_code = wp_remote_retrieve_response_code( $request );
|
||||
$request_body = wp_remote_retrieve_body( $request );
|
||||
|
||||
if ( 200 === $request_response_code ) {
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error( json_decode( $request_body ) );
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
}
|
||||
|
||||
ET_Builder_Error_Report::instance();
|
125
includes/builder/feature/I18n.php
Normal file
125
includes/builder/feature/I18n.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* Cached common translation.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Commonly used translations.
|
||||
*/
|
||||
class ET_Builder_I18n {
|
||||
|
||||
/**
|
||||
* Retrieve a commonly used translation.
|
||||
*
|
||||
* @since 4.4.9
|
||||
*
|
||||
* @param string $key Translation key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get( $key ) {
|
||||
// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.SpaceBeforeColonCASE
|
||||
// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLineCASE
|
||||
switch ( $key ) {
|
||||
// To avoid breaking tests:
|
||||
// 1. Do not remove `i18-list-begin` / `i18-list-end` tags.
|
||||
// 2. One traslation per line.
|
||||
// 3. `et_builder` Text Domain only.
|
||||
// 4. No comments / empty lines.
|
||||
// 5. Keep the list ordered, if can't do with your IDE, switch to Emacs.
|
||||
// i18-list-begin.
|
||||
case 'Admin Label' : return esc_html__( 'Admin Label', 'et_builder' );
|
||||
case 'Advanced' : return esc_html__( 'Advanced', 'et_builder' );
|
||||
case 'After' : return esc_html__( 'After', 'et_builder' );
|
||||
case 'Background' : return esc_html__( 'Background', 'et_builder' );
|
||||
case 'Before' : return esc_html__( 'Before', 'et_builder' );
|
||||
case 'Blur' : return esc_html__( 'Blur', 'et_builder' );
|
||||
case 'Body' : return esc_html__( 'Body', 'et_builder' );
|
||||
case 'Bottom Center' : return esc_html__( 'Bottom Center', 'et_builder' );
|
||||
case 'Bottom Left' : return esc_html__( 'Bottom Left', 'et_builder' );
|
||||
case 'Bottom Right' : return esc_html__( 'Bottom Right', 'et_builder' );
|
||||
case 'Bottom' : return esc_html__( 'Bottom', 'et_builder' );
|
||||
case 'Button' : return esc_html__( 'Button', 'et_builder' );
|
||||
case 'Cancel' : return esc_html__( 'Cancel', 'et_builder' );
|
||||
case 'Center Center' : return esc_html__( 'Center Center', 'et_builder' );
|
||||
case 'Center Left' : return esc_html__( 'Center Left', 'et_builder' );
|
||||
case 'Center Right' : return esc_html__( 'Center Right', 'et_builder' );
|
||||
case 'Center' : return esc_html__( 'Center', 'et_builder' );
|
||||
case 'Circle' : return esc_html__( 'Circle', 'et_builder' );
|
||||
case 'Color Burn' : return esc_html__( 'Color Burn', 'et_builder' );
|
||||
case 'Color Dodge' : return esc_html__( 'Color Dodge', 'et_builder' );
|
||||
case 'Color' : return esc_html__( 'Color', 'et_builder' );
|
||||
case 'Content' : return esc_html__( 'Content', 'et_builder' );
|
||||
case 'Custom CSS' : return esc_html__( 'Custom CSS', 'et_builder' );
|
||||
case 'Dark' : return esc_html__( 'Dark', 'et_builder' );
|
||||
case 'Darken' : return esc_html__( 'Darken', 'et_builder' );
|
||||
case 'Default' : return esc_html__( 'Default', 'et_builder' );
|
||||
case 'Design' : return esc_html__( 'Design', 'et_builder' );
|
||||
case 'Desktop' : return esc_html__( 'Desktop', 'et_builder' );
|
||||
case 'Difference' : return esc_html__( 'Difference', 'et_builder' );
|
||||
case 'Disc' : return esc_html__( 'Disc', 'et_builder' );
|
||||
case 'Down' : return esc_html__( 'Down', 'et_builder' );
|
||||
case 'Ease' : return esc_html__( 'Ease', 'et_builder' );
|
||||
case 'Ease-In' : return esc_html__( 'Ease-In', 'et_builder' );
|
||||
case 'Ease-In-Out' : return esc_html__( 'Ease-In-Out', 'et_builder' );
|
||||
case 'Ease-Out' : return esc_html__( 'Ease-Out', 'et_builder' );
|
||||
case 'Elements' : return esc_html__( 'Elements', 'et_builder' );
|
||||
case 'Exclusion' : return esc_html__( 'Exclusion', 'et_builder' );
|
||||
case 'Expand' : return esc_html__( 'Expand', 'et_builder' );
|
||||
case 'Fade' : return esc_html__( 'Fade', 'et_builder' );
|
||||
case 'Flip' : return esc_html__( 'Flip', 'et_builder' );
|
||||
case 'Hard Light' : return esc_html__( 'Hard Light', 'et_builder' );
|
||||
case 'Hue' : return esc_html__( 'Hue', 'et_builder' );
|
||||
case 'Image' : return esc_html__( 'Image', 'et_builder' );
|
||||
case 'Inside' : return esc_html__( 'Inside', 'et_builder' );
|
||||
case 'Layout' : return esc_html__( 'Layout', 'et_builder' );
|
||||
case 'Left' : return esc_html__( 'Left', 'et_builder' );
|
||||
case 'Light' : return esc_html__( 'Light', 'et_builder' );
|
||||
case 'Lighten' : return esc_html__( 'Lighten', 'et_builder' );
|
||||
case 'Linear' : return esc_html__( 'Linear', 'et_builder' );
|
||||
case 'Link' : return esc_html__( 'Link', 'et_builder' );
|
||||
case 'Luminosity' : return esc_html__( 'Luminosity', 'et_builder' );
|
||||
case 'Main Element' : return esc_html__( 'Main Element', 'et_builder' );
|
||||
case 'Multiply' : return esc_html__( 'Multiply', 'et_builder' );
|
||||
case 'No' : return esc_html__( 'No', 'et_builder' );
|
||||
case 'None' : return esc_html__( 'None', 'et_builder' );
|
||||
case 'Normal' : return esc_html__( 'Normal', 'et_builder' );
|
||||
case 'Off' : return esc_html__( 'Off', 'et_builder' );
|
||||
case 'On' : return esc_html__( 'On', 'et_builder' );
|
||||
case 'Outside' : return esc_html__( 'Outside', 'et_builder' );
|
||||
case 'Overlay' : return esc_html__( 'Overlay', 'et_builder' );
|
||||
case 'Phone' : return esc_html__( 'Phone', 'et_builder' );
|
||||
case 'Position' : return esc_html__( 'Position', 'et_builder' );
|
||||
case 'Radial' : return esc_html__( 'Radial', 'et_builder' );
|
||||
case 'Right' : return esc_html__( 'Right', 'et_builder' );
|
||||
case 'Saturation' : return esc_html__( 'Saturation', 'et_builder' );
|
||||
case 'Screen' : return esc_html__( 'Screen', 'et_builder' );
|
||||
case 'Sizing' : return esc_html__( 'Sizing', 'et_builder' );
|
||||
case 'Slide' : return esc_html__( 'Slide', 'et_builder' );
|
||||
case 'Soft Light' : return esc_html__( 'Soft Light', 'et_builder' );
|
||||
case 'Space' : return esc_html__( 'Space', 'et_builder' );
|
||||
case 'Square' : return esc_html__( 'Square', 'et_builder' );
|
||||
case 'Tablet' : return esc_html__( 'Tablet', 'et_builder' );
|
||||
case 'Text' : return esc_html__( 'Text', 'et_builder' );
|
||||
case 'Title' : return esc_html__( 'Title', 'et_builder' );
|
||||
case 'Top Center' : return esc_html__( 'Top Center', 'et_builder' );
|
||||
case 'Top Left' : return esc_html__( 'Top Left', 'et_builder' );
|
||||
case 'Top Right' : return esc_html__( 'Top Right', 'et_builder' );
|
||||
case 'Top' : return esc_html__( 'Top', 'et_builder' );
|
||||
case 'Up' : return esc_html__( 'Up', 'et_builder' );
|
||||
case 'Upload an image' : return esc_attr__( 'Upload an image', 'et_builder' );
|
||||
case 'Visibility' : return esc_attr__( 'Visibility', 'et_builder' );
|
||||
case 'Yes' : return esc_html__( 'Yes', 'et_builder' );
|
||||
// i18-list-end.
|
||||
}
|
||||
// phpcs:enable
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
352
includes/builder/feature/JQueryBody.php
Normal file
352
includes/builder/feature/JQueryBody.php
Normal file
@ -0,0 +1,352 @@
|
||||
<?php
|
||||
/**
|
||||
* Move JQuery from head to body.
|
||||
*
|
||||
* @package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to move JQuery from head to body.
|
||||
*/
|
||||
class ET_Builder_JQuery_Body {
|
||||
/**
|
||||
* Cache.
|
||||
*
|
||||
* @var array.
|
||||
*/
|
||||
protected $_has_jquery_dep = [];
|
||||
|
||||
/**
|
||||
* Should move jquery.
|
||||
*
|
||||
* @var bool|null.
|
||||
*/
|
||||
protected static $_should_move_jquery = null;
|
||||
|
||||
/**
|
||||
* Instance of `ET_Builder_JQuery_Body`.
|
||||
*
|
||||
* @var ET_Builder_JQuery_Body
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* ET_Builder_JQuery_Body constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_print_scripts', [ $this, 'wp_print_scripts' ], 99 );
|
||||
|
||||
add_action( 'wp_head', [ $this, 'add_jquery_sub' ], 1 );
|
||||
add_action( 'wp_enqueue_scripts', [ $this, 'remove_jquery_sub' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post content from Theme Builder templates.
|
||||
* Combine it with the post content from the current post and integration code.
|
||||
*
|
||||
* @return string
|
||||
* @since 4.10.0
|
||||
*/
|
||||
public function get_all_content() {
|
||||
static $all_content;
|
||||
|
||||
// Cache the value.
|
||||
if ( ! empty( $all_content ) ) {
|
||||
return $all_content;
|
||||
}
|
||||
|
||||
global $post, $shortname;
|
||||
|
||||
$all_content = empty( $post ) ? '' : $post->post_content;
|
||||
$tb_layouts = et_theme_builder_get_template_layouts();
|
||||
|
||||
// Add TB templates content.
|
||||
if ( ! empty( $tb_layouts ) ) {
|
||||
$post_types = [
|
||||
ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE,
|
||||
ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE,
|
||||
ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE,
|
||||
];
|
||||
|
||||
foreach ( $post_types as $post_type ) {
|
||||
$layout = $tb_layouts[ $post_type ];
|
||||
if ( $layout['override'] && ! empty( $layout['enabled'] ) ) {
|
||||
$template = get_post( intval( $layout['id'] ) );
|
||||
$all_content .= $template->post_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$integrations = [
|
||||
'head',
|
||||
'body',
|
||||
'single_top',
|
||||
'single_bottom',
|
||||
];
|
||||
|
||||
// Add Integration code.
|
||||
foreach ( $integrations as $integration ) {
|
||||
$all_content .= et_get_option( $shortname . '_integration_' . $integration );
|
||||
}
|
||||
|
||||
return $all_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively check if a script (or its deps) depends on JQuery.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $script Script Handle.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_jquery_dep( $script ) {
|
||||
global $wp_scripts;
|
||||
|
||||
$registered = $wp_scripts->registered;
|
||||
$handles = [ $script ];
|
||||
$stack = [];
|
||||
$result = false;
|
||||
|
||||
while ( false === $result && $handles ) {
|
||||
foreach ( $handles as $handle ) {
|
||||
if ( ! empty( $this->_has_jquery_dep[ $handle ] ) ) {
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isset( $registered[ $handle ] ) ) {
|
||||
$deps = $registered[ $handle ]->deps;
|
||||
if ( $deps ) {
|
||||
if ( in_array( 'jquery-core', $deps, true ) ) {
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
array_push( $stack, $deps );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$handles = array_pop( $stack );
|
||||
}
|
||||
|
||||
$this->_has_jquery_dep[ $script ] = $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get script deps.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $script Script Handle.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_deps( $script ) {
|
||||
global $wp_scripts;
|
||||
|
||||
$registered = $wp_scripts->registered;
|
||||
$handles = is_array( $script ) ? $script : [ $script ];
|
||||
$all_deps = $handles;
|
||||
$stack = [];
|
||||
$done = [];
|
||||
|
||||
while ( $handles ) {
|
||||
foreach ( $handles as $handle ) {
|
||||
if ( ! isset( $done[ $handle ] ) && isset( $registered[ $handle ] ) ) {
|
||||
$deps = $registered[ $handle ]->deps;
|
||||
if ( $deps ) {
|
||||
$all_deps = array_merge( $all_deps, $deps );
|
||||
array_push( $stack, $deps );
|
||||
}
|
||||
$done[ $handle ] = true;
|
||||
}
|
||||
}
|
||||
$handles = array_pop( $stack );
|
||||
}
|
||||
|
||||
return array_unique( $all_deps );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a script is currently enqueued in HEAD.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $handle Script Handle.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function in_head( $handle ) {
|
||||
global $wp_scripts;
|
||||
|
||||
if ( empty( $wp_scripts->registered[ $handle ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$script = $wp_scripts->registered[ $handle ];
|
||||
|
||||
if ( isset( $script->args ) && 1 === $script->args ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $script->extra['group'] ) && 1 === $script->extra['group'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether some content includes jQuery or not.
|
||||
*
|
||||
* @since 4.10.0
|
||||
* @param string $content Content.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_jquery_content( $content ) {
|
||||
$has_jquery_regex = '/\(jQuery|jQuery\.|jQuery\)/';
|
||||
return 1 === preg_match( $has_jquery_regex, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Move jQuery / migrate / 3P scripts in BODY.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wp_print_scripts() {
|
||||
global $shortname;
|
||||
|
||||
if ( $this->should_move_jquery() ) {
|
||||
global $wp_scripts;
|
||||
$queue = $this->get_deps( $wp_scripts->queue );
|
||||
$head = in_array( 'jquery-migrate', $queue, true ) ? [ 'jquery-migrate' ] : [];
|
||||
$mode = 'on' === et_get_option( $shortname . '_enable_jquery_body_super' ) ? 'super' : 'safe';
|
||||
|
||||
// Find all head scripts that depends on JQuery.
|
||||
foreach ( $queue as $handle ) {
|
||||
if ( $this->in_head( $handle ) && $this->has_jquery_dep( $handle ) ) {
|
||||
if ( 'safe' === $mode && 'jquery' !== $handle && 'jquery-migrate' !== $handle ) {
|
||||
// Bail out when a script requiring jQuery is found in head.
|
||||
return;
|
||||
}
|
||||
$head[] = $handle;
|
||||
}
|
||||
}
|
||||
|
||||
$registered = $wp_scripts->registered;
|
||||
|
||||
// Disable the feature when finding a script which does not depend on jQuery
|
||||
// but still uses it inside its inlined content (before/after).
|
||||
foreach ( $queue as $handle ) {
|
||||
if ( ! $this->has_jquery_dep( $handle ) ) {
|
||||
$script = $registered[ $handle ];
|
||||
$data = '';
|
||||
|
||||
if ( isset( $script->extra['data'] ) ) {
|
||||
$data .= $script->extra['data'];
|
||||
}
|
||||
if ( isset( $script->extra['before'] ) ) {
|
||||
$data .= join( '', $script->extra['before'] );
|
||||
}
|
||||
if ( isset( $script->extra['after'] ) ) {
|
||||
$data .= join( '', $script->extra['after'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $data ) && self::has_jquery_content( $data ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the feature when jQuery is found in TB/Post Content.
|
||||
if ( self::has_jquery_content( $this->get_all_content() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $head ) ) {
|
||||
foreach ( $this->get_deps( $head ) as $handle ) {
|
||||
$wp_scripts->add_data( $handle, 'group', 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class instance.
|
||||
*
|
||||
* @since 4.10.0
|
||||
*
|
||||
* @return ET_Builder_JQuery_Body
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fake jQuery in head when jQuery body option is true.
|
||||
*/
|
||||
public function add_jquery_sub() {
|
||||
global $shortname;
|
||||
|
||||
$jquery_compatibility_enabled = 'on' === et_get_option( $shortname . '_enable_jquery_compatibility', 'on' ) ? true : false;
|
||||
|
||||
if ( $this->should_move_jquery() && $jquery_compatibility_enabled ) {
|
||||
echo '<script type="text/javascript">
|
||||
let jqueryParams=[],jQuery=function(r){return jqueryParams=[...jqueryParams,r],jQuery},$=function(r){return jqueryParams=[...jqueryParams,r],$};window.jQuery=jQuery,window.$=jQuery;let customHeadScripts=!1;jQuery.fn=jQuery.prototype={},$.fn=jQuery.prototype={},jQuery.noConflict=function(r){if(window.jQuery)return jQuery=window.jQuery,$=window.jQuery,customHeadScripts=!0,jQuery.noConflict},jQuery.ready=function(r){jqueryParams=[...jqueryParams,r]},$.ready=function(r){jqueryParams=[...jqueryParams,r]},jQuery.load=function(r){jqueryParams=[...jqueryParams,r]},$.load=function(r){jqueryParams=[...jqueryParams,r]},jQuery.fn.ready=function(r){jqueryParams=[...jqueryParams,r]},$.fn.ready=function(r){jqueryParams=[...jqueryParams,r]};</script>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the Fake jQuery in head when jQuery body option is true.
|
||||
*/
|
||||
public function remove_jquery_sub() {
|
||||
global $shortname;
|
||||
|
||||
$jquery_compatibility_enabled = 'on' === et_get_option( $shortname . '_enable_jquery_compatibility', 'on' ) ? true : false;
|
||||
|
||||
if ( $this->should_move_jquery() && $jquery_compatibility_enabled ) {
|
||||
$script = 'jqueryParams.length&&$.each(jqueryParams,function(e,r){if("function"==typeof r){var n=String(r);n.replace("$","jQuery");var a=new Function("return "+n)();$(document).ready(a)}});';
|
||||
|
||||
wp_add_inline_script( 'jquery', $script, 'after' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if jQuery should be moved to the body.
|
||||
*/
|
||||
public function should_move_jquery() {
|
||||
global $shortname;
|
||||
|
||||
if ( null === self::$_should_move_jquery ) {
|
||||
/**
|
||||
* Filters whether JQuery Body feature is enabled or not.
|
||||
*
|
||||
* @since 4.10.5
|
||||
*
|
||||
* @param bool $enabled JQuery Body enabled value.
|
||||
* @param string $content TB/Post Content.
|
||||
*/
|
||||
if ( false === apply_filters( 'et_builder_enable_jquery_body', true, $this->get_all_content() ) ) {
|
||||
// Bail out if disabled by filter.
|
||||
self::$_should_move_jquery = false;
|
||||
return false;
|
||||
}
|
||||
self::$_should_move_jquery = ! ( is_admin() || wp_doing_ajax() || et_is_builder_plugin_active() || is_customize_preview() || is_et_pb_preview() || 'wp-login.php' === $GLOBALS['pagenow'] || et_fb_is_enabled() ) && 'on' === et_get_option( $shortname . '_enable_jquery_body', 'on' );
|
||||
}
|
||||
|
||||
return self::$_should_move_jquery;
|
||||
}
|
||||
}
|
||||
|
||||
ET_Builder_JQuery_Body::instance();
|
1164
includes/builder/feature/Library.php
Normal file
1164
includes/builder/feature/Library.php
Normal file
File diff suppressed because it is too large
Load Diff
408
includes/builder/feature/ajax-data/AjaxData.php
Normal file
408
includes/builder/feature/ajax-data/AjaxData.php
Normal file
@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/**
|
||||
* Serves the data to various AJAX requests.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @package Divi
|
||||
* @sub-package Builder
|
||||
*/
|
||||
|
||||
namespace Feature\AjaxData;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use ET_Builder_Module_Fields_Factory;
|
||||
|
||||
/**
|
||||
* AJAX Data class.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*/
|
||||
class ET_Builder_Ajax_Data {
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @var Class
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Registers the AJAX actions when class is constructed.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_ajax_et_builder_ajax_get_post_types', array( $this, 'et_builder_ajax_get_post_types' ) );
|
||||
add_action( 'wp_ajax_et_builder_ajax_get_authors', array( $this, 'et_builder_ajax_get_authors' ) );
|
||||
add_action( 'wp_ajax_et_builder_ajax_get_user_roles', array( $this, 'et_builder_ajax_get_user_roles' ) );
|
||||
add_action( 'wp_ajax_et_builder_ajax_get_categories', array( $this, 'et_builder_ajax_get_categories' ) );
|
||||
add_action( 'wp_ajax_et_builder_ajax_get_tags', array( $this, 'et_builder_ajax_get_tags' ) );
|
||||
add_action( 'wp_ajax_et_builder_ajax_search_products', array( $this, 'et_builder_ajax_search_products' ) );
|
||||
add_action( 'wp_ajax_et_builder_ajax_get_display_conditions_status', array( $this, 'et_builder_ajax_get_display_conditions_status' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of the Class
|
||||
*
|
||||
* @return Class Instance
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for Display Conditions Status.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_get_display_conditions_status() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_get_display_conditions_status', 'nonce', '_POST' );
|
||||
|
||||
// $_POST['conditions'] is a JSON so there is no effective way to sanitize it at this level.
|
||||
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput -- Conditions is not stored or displayed therefore XSS safe.
|
||||
$conditions = isset( $_POST['conditions'] ) ? $_POST['conditions'] : '';
|
||||
$conditions = json_decode( stripslashes( $conditions ), true );
|
||||
|
||||
$status = ET_Builder_Module_Fields_Factory::get( 'DisplayConditions' )->is_displayable( $conditions, true );
|
||||
|
||||
if ( ! $status ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
wp_send_json_success( $status );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for Searching within Products.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_search_products() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_search_products', 'nonce', '_GET' );
|
||||
|
||||
$current_page = isset( $_GET['page'] ) ? (int) $_GET['page'] : 0;
|
||||
$current_page = max( $current_page, 1 );
|
||||
$search = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
|
||||
$results_per_page = 20;
|
||||
$results = [
|
||||
'results' => [],
|
||||
'meta' => [],
|
||||
];
|
||||
|
||||
$query = [
|
||||
'post_type' => 'product',
|
||||
'posts_per_page' => $results_per_page,
|
||||
'post_status' => 'publish',
|
||||
's' => $search,
|
||||
'orderby' => 'date',
|
||||
'order' => 'desc',
|
||||
'paged' => $current_page,
|
||||
];
|
||||
|
||||
$query = new \WP_Query( $query );
|
||||
|
||||
if ( ! empty( $query->posts ) ) {
|
||||
foreach ( $query->posts as $post ) {
|
||||
$results['results'][] = [
|
||||
'value' => (int) $post->ID,
|
||||
'label' => et_core_intentionally_unescaped( wp_strip_all_tags( $post->post_title ), 'react_jsx' ),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$results['meta']['pagination'] = array(
|
||||
'results' => array(
|
||||
'per_page' => (int) $results_per_page,
|
||||
'total' => (int) $query->found_posts,
|
||||
),
|
||||
'pages' => array(
|
||||
'current' => (int) $current_page,
|
||||
'total' => (int) $query->max_num_pages,
|
||||
),
|
||||
);
|
||||
|
||||
// Only reset if the query is successful to avoid resetting previous query by mistake.
|
||||
if ( ! empty( $query->posts ) ) {
|
||||
wp_reset_postdata();
|
||||
}
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for getting a list of all Categories (All Taxonomies Terms) except excluded taxonomies.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_get_categories() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_get_categories', 'nonce', '_GET' );
|
||||
|
||||
$data = [];
|
||||
$search = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
|
||||
$excluded_taxonomies = [ 'post_tag', 'project_tag', 'product_tag', 'nav_menu', 'link_category', 'post_format', 'layout_category', 'layout_pack', 'layout_type', 'scope', 'module_width' ];
|
||||
|
||||
/**
|
||||
* Filters excluded taxonomies for `et_builder_ajax_get_categories` ajax action.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $excluded_taxonomies
|
||||
*/
|
||||
$excluded_taxonomies = apply_filters( 'et_builder_ajax_get_categories_excluded_taxonomies', $excluded_taxonomies );
|
||||
|
||||
$taxonomies = array_diff( get_taxonomies(), $excluded_taxonomies );
|
||||
$categories = get_terms(
|
||||
[
|
||||
'taxonomy' => $taxonomies,
|
||||
'hide_empty' => false,
|
||||
'search' => $search,
|
||||
]
|
||||
);
|
||||
|
||||
foreach ( $categories as $cat ) {
|
||||
$tax_name = get_taxonomy( $cat->taxonomy )->label;
|
||||
$tax_slug = get_taxonomy( $cat->taxonomy )->name;
|
||||
$data[ $cat->taxonomy ][] = [
|
||||
'name' => et_core_intentionally_unescaped( wp_strip_all_tags( $cat->name ), 'react_jsx' ),
|
||||
'id' => $cat->term_id,
|
||||
'taxonomyName' => et_core_intentionally_unescaped( wp_strip_all_tags( $tax_name ), 'react_jsx' ),
|
||||
'taxonomySlug' => $tax_slug,
|
||||
];
|
||||
}
|
||||
|
||||
$results = [
|
||||
'results' => $data,
|
||||
];
|
||||
|
||||
if ( is_wp_error( $categories ) ) {
|
||||
wp_send_json_error( $categories );
|
||||
}
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for getting a list of Divi registered Tags.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_get_tags() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_get_tags', 'nonce', '_GET' );
|
||||
|
||||
$data = [];
|
||||
$search = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
|
||||
$included_taxonomies = [ 'post_tag', 'project_tag', 'product_tag' ];
|
||||
|
||||
/**
|
||||
* Filters included taxonomies for `et_builder_ajax_get_tags` ajax action.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $included_taxonomies
|
||||
*/
|
||||
$included_taxonomies = apply_filters( 'et_builder_ajax_get_tags_included_taxonomies', $included_taxonomies );
|
||||
|
||||
$included_taxonomies = array_filter(
|
||||
$included_taxonomies,
|
||||
function( $taxonomy_slug ) {
|
||||
return taxonomy_exists( $taxonomy_slug );
|
||||
}
|
||||
);
|
||||
|
||||
$tags = get_terms(
|
||||
[
|
||||
'taxonomy' => $included_taxonomies,
|
||||
'hide_empty' => false,
|
||||
'search' => $search,
|
||||
]
|
||||
);
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$tax_name = get_taxonomy( $tag->taxonomy )->label;
|
||||
$tax_slug = get_taxonomy( $tag->taxonomy )->name;
|
||||
$data[ $tag->taxonomy ][] = [
|
||||
'name' => et_core_intentionally_unescaped( wp_strip_all_tags( $tag->name ), 'react_jsx' ),
|
||||
'id' => $tag->term_id,
|
||||
'taxonomyName' => et_core_intentionally_unescaped( wp_strip_all_tags( $tax_name ), 'react_jsx' ),
|
||||
'taxonomySlug' => $tax_slug,
|
||||
];
|
||||
}
|
||||
|
||||
$results = [
|
||||
'results' => $data,
|
||||
];
|
||||
|
||||
if ( is_wp_error( $tags ) ) {
|
||||
wp_send_json_error( $tags );
|
||||
}
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for getting a list of Post Types.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_get_post_types() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_get_post_types', 'nonce', '_GET' );
|
||||
|
||||
$current_page = isset( $_GET['page'] ) ? (int) $_GET['page'] : 0;
|
||||
$current_page = max( $current_page, 1 );
|
||||
$post_types = array_values( get_post_types( [ 'public' => true ], 'objects' ) );
|
||||
|
||||
/**
|
||||
* Filters included post types for `et_builder_ajax_get_post_types` ajax action.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $post_types
|
||||
*/
|
||||
$post_types = apply_filters( 'et_builder_ajax_get_post_types', $post_types );
|
||||
|
||||
$total = count( $post_types );
|
||||
$results_per_page = 20;
|
||||
$pages_total = 1;
|
||||
|
||||
$post_types_data = array_map(
|
||||
function( $item ) {
|
||||
return [
|
||||
'label' => et_core_intentionally_unescaped( wp_strip_all_tags( $item->labels->name ), 'react_jsx' ),
|
||||
'singular_label' => et_core_intentionally_unescaped( wp_strip_all_tags( $item->labels->singular_name ), 'react_jsx' ),
|
||||
'value' => $item->name,
|
||||
];
|
||||
},
|
||||
$post_types
|
||||
);
|
||||
|
||||
$results = [
|
||||
'results' => $post_types_data,
|
||||
'meta' => [],
|
||||
];
|
||||
$results['meta']['pagination'] = array(
|
||||
'results' => array(
|
||||
'per_page' => $results_per_page,
|
||||
'total' => $total,
|
||||
),
|
||||
'pages' => array(
|
||||
'current' => $current_page,
|
||||
'total' => $pages_total,
|
||||
),
|
||||
);
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for getting a list of Authors.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_get_authors() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_get_authors', 'nonce', '_GET' );
|
||||
|
||||
$current_page = isset( $_GET['page'] ) ? (int) $_GET['page'] : 0;
|
||||
$current_page = max( $current_page, 1 );
|
||||
$results_per_page = 10;
|
||||
$users_data = [];
|
||||
$role__in = [];
|
||||
|
||||
foreach ( wp_roles()->roles as $role_slug => $role ) {
|
||||
if ( ! empty( $role['capabilities']['publish_posts'] ) ) {
|
||||
$role__in[] = $role_slug;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters included roles for `et_builder_ajax_get_authors` ajax action.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $role__in
|
||||
*/
|
||||
$role__in = apply_filters( 'et_builder_ajax_get_authors_included_roles', $role__in );
|
||||
|
||||
$user_query = new \WP_User_Query(
|
||||
[
|
||||
'role__in' => $role__in,
|
||||
'fields' => [ 'ID', 'user_login' ],
|
||||
'number' => $results_per_page,
|
||||
'paged' => 1,
|
||||
]
|
||||
);
|
||||
$found_users = $user_query->get_results();
|
||||
|
||||
if ( ! empty( $found_users ) ) {
|
||||
$users_data = array_map(
|
||||
function( $item ) {
|
||||
return [
|
||||
'label' => et_core_intentionally_unescaped( wp_strip_all_tags( $item->user_login ), 'react_jsx' ),
|
||||
'value' => $item->ID,
|
||||
];
|
||||
},
|
||||
$found_users
|
||||
);
|
||||
}
|
||||
|
||||
$total = $user_query->get_total();
|
||||
$pages_total = max( $total / $results_per_page, 1 );
|
||||
|
||||
$results = [
|
||||
'results' => $users_data,
|
||||
'meta' => [],
|
||||
];
|
||||
$results['meta']['pagination'] = array(
|
||||
'results' => array(
|
||||
'per_page' => (int) $results_per_page,
|
||||
'total' => (int) $total,
|
||||
),
|
||||
'pages' => array(
|
||||
'current' => (int) $current_page,
|
||||
'total' => (int) $pages_total,
|
||||
),
|
||||
);
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX Action for getting a list of User Roles.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_builder_ajax_get_user_roles() {
|
||||
et_core_security_check( 'edit_posts', 'et_builder_ajax_get_user_roles', 'nonce', '_GET' );
|
||||
|
||||
$user_roles = [];
|
||||
|
||||
foreach ( wp_roles()->roles as $key => $value ) {
|
||||
$user_roles[] = [
|
||||
'label' => et_core_intentionally_unescaped( wp_strip_all_tags( $value['name'] ), 'react_jsx' ),
|
||||
'value' => $key,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters included user roles for `et_builder_ajax_get_user_roles` ajax action.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $user_roles
|
||||
*/
|
||||
$user_roles = apply_filters( 'et_builder_ajax_get_user_roles_included_roles', $user_roles );
|
||||
|
||||
$results = [
|
||||
'results' => $user_roles,
|
||||
];
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ET_Builder_Ajax_Data::get_instance();
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Content Retriever is home for functions which return non-ajax WordPress Content.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @package Divi
|
||||
* @sub-package Builder
|
||||
*/
|
||||
|
||||
namespace Feature\ContentRetriever;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Load traits, No autoloader yet :sad_pepe:
|
||||
*/
|
||||
require_once __DIR__ . '/retrievers/PageContentRetriever.php';
|
||||
|
||||
/**
|
||||
* Class ET_Builder_Content_Retriever
|
||||
*/
|
||||
class ET_Builder_Content_Retriever {
|
||||
|
||||
/**
|
||||
* Import traits dependencies.
|
||||
* Keep the code clean and the logic separated.
|
||||
*/
|
||||
use PageContentRetriever;
|
||||
|
||||
/**
|
||||
* Holds the class instance.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Initialize ET_Builder_Content_Retriever class.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( null === self::$_instance ) {
|
||||
self::$_instance = new ET_Builder_Content_Retriever();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ET_Builder_Content_Retriever::init();
|
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Page Content Retriever is used to get Page related Contents from WordPress.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @package Divi
|
||||
* @sub-package Builder
|
||||
*/
|
||||
|
||||
namespace Feature\ContentRetriever;
|
||||
|
||||
/**
|
||||
* PageContentRetriever Trait.
|
||||
*/
|
||||
trait PageContentRetriever {
|
||||
|
||||
/**
|
||||
* Holds a Cache reference for every page content retrieved.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_cache = [];
|
||||
|
||||
/**
|
||||
* Gets the entire page content, including TB Header, TB Body Layout, Post Content and TB Footer.
|
||||
*
|
||||
* Parameter $post must be given as a variable, since it is passed by reference.
|
||||
* If $post is not given, It then uses global $post if available.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param WP_Post|int $post Optional. WP_Post instance or Post ID. Default null.
|
||||
*
|
||||
* @return null|string null on failure, string on success.
|
||||
*/
|
||||
public function get_entire_page_content( $post = null ) {
|
||||
|
||||
/**
|
||||
* Validation Checks.
|
||||
*/
|
||||
$is_using_global_post = false;
|
||||
|
||||
if ( empty( $post ) && isset( $GLOBALS['post'] ) ) {
|
||||
$post = $GLOBALS['post'];
|
||||
$is_using_global_post = true;
|
||||
}
|
||||
|
||||
if ( $post instanceof \WP_Post ) {
|
||||
$wp_post = $post;
|
||||
} else {
|
||||
$wp_post = \WP_Post::get_instance( $post );
|
||||
}
|
||||
|
||||
if ( ! $wp_post ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core mechanics for retrieving content.
|
||||
*/
|
||||
if ( $this->_cache && isset( $this->_cache[ $wp_post->ID ] ) ) {
|
||||
return $this->_cache[ $wp_post->ID ];
|
||||
}
|
||||
|
||||
if ( $is_using_global_post ) {
|
||||
$layouts = et_theme_builder_get_template_layouts();
|
||||
} else {
|
||||
$layouts = et_theme_builder_get_template_layouts( \ET_Theme_Builder_Request::from_post( $wp_post->ID ) );
|
||||
}
|
||||
|
||||
$entire_page_content = '';
|
||||
$enabled_layout_ids = [
|
||||
ET_THEME_BUILDER_HEADER_LAYOUT_POST_TYPE => null,
|
||||
ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE => null,
|
||||
'content' => 'content',
|
||||
ET_THEME_BUILDER_FOOTER_LAYOUT_POST_TYPE => null,
|
||||
];
|
||||
|
||||
foreach ( $layouts as $key => $layout ) {
|
||||
$is_layout_enabled = isset( $layout['enabled'], $layout['override'] ) && true === $layout['enabled'] && true === $layout['override'];
|
||||
$enabled_layout_ids[ $key ] = ( array_key_exists( $key, $enabled_layout_ids ) && $is_layout_enabled ) ? $layout['id'] : null;
|
||||
}
|
||||
|
||||
$enabled_layout_ids = array_filter( $enabled_layout_ids );
|
||||
|
||||
/**
|
||||
* $enabled_layout_ids will be in the following order, (assuming each are present):
|
||||
* header, body, footer.
|
||||
* We're intentionally adding the post content so that it's appended
|
||||
* right after the body layout, making the final order of $entire_page_content:
|
||||
* header, body, post content, footer.
|
||||
* They need to be in order for Critical CSS. Otherwise we don't know what
|
||||
* content comes first and is above the fold.
|
||||
*/
|
||||
foreach ( $enabled_layout_ids as $key => $layout_id ) {
|
||||
if ( 'content' === $layout_id ) {
|
||||
$entire_page_content .= $wp_post->post_content;
|
||||
} else {
|
||||
$layout = get_post( $layout_id );
|
||||
$entire_page_content .= $layout->post_content;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_cache = array_replace( $this->_cache, [ $wp_post->ID => $entire_page_content ] );
|
||||
|
||||
return $entire_page_content;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,367 @@
|
||||
<?php
|
||||
/**
|
||||
* Display Conditions functionalities (tracking post visits etc.) used site wide.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @package Divi
|
||||
* @sub-package Builder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Conditions functionalities to be used site wide.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*/
|
||||
class ET_Builder_Display_Conditions {
|
||||
|
||||
/**
|
||||
* Hold the class instance.
|
||||
*
|
||||
* @var Class
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Get the singleton instance.
|
||||
*
|
||||
* @return ET_Builder_Display_Conditions
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init actions and filters needed for Display Condition's functionality
|
||||
*/
|
||||
public function __construct() {
|
||||
// No Display Conditions related Hooks if below WordPress 5.3.
|
||||
if ( version_compare( get_bloginfo( 'version' ), '5.3', '>=' ) ) {
|
||||
add_action( 'wp', array( $this, 'et_display_conditions_post_visit_set_cookie' ) );
|
||||
add_action( 'template_redirect', array( $this, 'et_display_conditions_number_of_views_set_cookie' ) );
|
||||
add_action( 'save_post', array( $this, 'et_display_conditions_save_tracking_post_ids' ), 10, 3 );
|
||||
add_action( 'delete_post', array( $this, 'et_display_conditions_delete_tracking_post_ids' ), 10, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves Post IDs selected in PageVisit/PostVisit Display Conditions into WP Options.
|
||||
*
|
||||
* This data will be used to only track the Posts which are selected by the user
|
||||
* It is to keep the PageVisit/PostVisit related Cookie minimal and under 4KB limitation.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param int $post_id Post ID which is being saved.
|
||||
* @param WP_Post $post Post object which is being saved.
|
||||
* @param bool $update Whether this is an existing post being updated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_display_conditions_save_tracking_post_ids( $post_id, $post, $update ) {
|
||||
|
||||
/**
|
||||
* Validation and Security Checks.
|
||||
*/
|
||||
if ( ! $post || ! $post instanceof WP_Post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type = get_post_type_object( $post->post_type );
|
||||
if ( ! $post_type instanceof WP_Post_Type || ! current_user_can( $post_type->cap->edit_post, $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST['et_fb_save_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_POST['et_fb_save_nonce'] ), 'et_fb_save_nonce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup Prerequisites.
|
||||
*/
|
||||
$tracking_post_ids = [];
|
||||
$content = get_the_content( null, false, $post );
|
||||
$preg_match = preg_match_all( '/display_conditions="[^"]*"/mi', $content, $matches, PREG_SET_ORDER ); // Return format: `display_conditions="base_64_encoded_data"`.
|
||||
$display_conditions_attrs = array_reduce( $matches, 'array_merge', [] ); // Flatten and Store All `display_conditions` attributes found.
|
||||
|
||||
/**
|
||||
* Decode each `display_conditions` attribute, and store post IDs used in PageVisit/PostVisit conditions.
|
||||
*/
|
||||
foreach ( $display_conditions_attrs as $display_condition_attr ) {
|
||||
$display_condition_base64 = substr( $display_condition_attr, strpos( $display_condition_attr, '"' ), -1 );
|
||||
$display_conditions = json_decode( base64_decode( $display_condition_base64 ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- The returned data is an array and necessary validation checks are performed.
|
||||
|
||||
if ( ! is_array( $display_conditions ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $display_conditions as $display_condition ) {
|
||||
$condition_name = $display_condition['condition'];
|
||||
$condition_settings = $display_condition['conditionSettings'];
|
||||
|
||||
if ( 'pageVisit' !== $condition_name && 'postVisit' !== $condition_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pages_raw = isset( $condition_settings['pages'] ) ? $condition_settings['pages'] : [];
|
||||
$pages_ids = array_map(
|
||||
function( $item ) {
|
||||
return isset( $item['value'] ) ? (int) $item['value'] : null;
|
||||
},
|
||||
$pages_raw
|
||||
);
|
||||
$pages_ids = array_filter( $pages_ids );
|
||||
$tracking_post_ids = array_merge( $pages_ids, $tracking_post_ids );
|
||||
}
|
||||
}
|
||||
|
||||
$tracking_post_ids = array_unique( $tracking_post_ids );
|
||||
|
||||
if ( $tracking_post_ids ) {
|
||||
$result = [ (int) $post_id => $tracking_post_ids ];
|
||||
} else {
|
||||
$result = null;
|
||||
}
|
||||
|
||||
$wp_option = get_option( 'et_display_conditions_tracking_post_ids', null );
|
||||
|
||||
// If option exist, Either update it OR remove from it.
|
||||
if ( is_array( $wp_option ) ) {
|
||||
if ( $result ) {
|
||||
$result = array_replace( $wp_option, $result );
|
||||
} else {
|
||||
$result = array_filter(
|
||||
$wp_option,
|
||||
function( $key ) use ( $post_id ) {
|
||||
return $key !== $post_id;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $wp_option === $result ) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_option( 'et_display_conditions_tracking_post_ids', $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes Post IDs selected in PageVisit/PostVisit Display Conditions from WP Options.
|
||||
*
|
||||
* This data will be used to only track the Posts which are selected by the user
|
||||
* It is to keep the PageVisit/PostVisit related Cookie minimal and under 4KB limitation.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param int $post_id Post ID which is being deleted.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_display_conditions_delete_tracking_post_ids( $post_id ) {
|
||||
$post = get_post( $post_id );
|
||||
$wp_option = get_option( 'et_display_conditions_tracking_post_ids', null );
|
||||
$is_wp_option_exist = is_array( $wp_option ) && ! empty( $wp_option );
|
||||
|
||||
if ( ! $is_wp_option_exist ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $post || ! $post instanceof WP_Post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get real Post ID if Revision ID is passed, Using `Empty Trash` button will set $post_id to revision id.
|
||||
$revision_parent_id = wp_is_post_revision( $post_id );
|
||||
if ( $revision_parent_id ) {
|
||||
$post_id = $revision_parent_id;
|
||||
}
|
||||
|
||||
$post_type = get_post_type_object( $post->post_type );
|
||||
if ( ! current_user_can( $post_type->cap->delete_post, $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = array_filter(
|
||||
$wp_option,
|
||||
function( $key ) use ( $post_id ) {
|
||||
return (int) $key !== (int) $post_id;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
if ( $wp_option === $result ) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_option( 'et_display_conditions_tracking_post_ids', $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a cookie based on page visits so Page/Post Visit Display Conditions would function as expected.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_display_conditions_post_visit_set_cookie() {
|
||||
if ( ! is_singular() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_post_id = get_queried_object_id();
|
||||
$new_cookie = [];
|
||||
$has_visited_page_before = false;
|
||||
$wp_option = get_option( 'et_display_conditions_tracking_post_ids', null );
|
||||
$is_wp_option_exist = is_array( $wp_option ) && ! empty( $wp_option );
|
||||
$flatten_wp_option = is_array( $wp_option ) ? array_unique( array_reduce( $wp_option, 'array_merge', [] ) ) : [];
|
||||
$is_post_id_in_wp_option = array_search( $current_post_id, $flatten_wp_option, true ) !== false;
|
||||
|
||||
if ( ! $is_wp_option_exist || ! $is_post_id_in_wp_option ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $_COOKIE['divi_post_visit'] ) ) {
|
||||
$new_cookie = json_decode( base64_decode( $_COOKIE['divi_post_visit'] ), true ); // phpcs:ignore ET.Sniffs.ValidatedSanitizedInput, WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Cookie is not stored or displayed therefore XSS safe, base64_decode returned data is an array and necessary validation checks are performed.
|
||||
$has_visited_page_before = array_search( $current_post_id, array_column( $new_cookie, 'id' ), true );
|
||||
}
|
||||
|
||||
if ( false === $has_visited_page_before ) {
|
||||
$new_cookie[] = [
|
||||
'id' => $current_post_id,
|
||||
];
|
||||
$new_cookie = base64_encode( wp_json_encode( $new_cookie ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- base64_encode data is an array.
|
||||
setrawcookie( 'divi_post_visit', $new_cookie, time() + 3600 * 24 * 365, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a cookie based on how many times a module is displayed so "Number of Views" Condition would function as expected.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function et_display_conditions_number_of_views_set_cookie() {
|
||||
|
||||
// Do not run on VB itself.
|
||||
if ( et_core_is_fb_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is to ensure that network request such as '/favicon.ico' won't change the cookie
|
||||
* since those requests do trigger these functions to run again without the proper context
|
||||
* resulting updating cookie >=2 times on 1 page load.
|
||||
*/
|
||||
$is_existing_wp_query = ( is_home() || is_404() || is_archive() || is_search() );
|
||||
if ( get_queried_object_id() === 0 && ! $is_existing_wp_query ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup prerequisite.
|
||||
$display_conditions_attrs = [];
|
||||
$cookie = [];
|
||||
$entire_page_content = \Feature\ContentRetriever\ET_Builder_Content_Retriever::init()->get_entire_page_content( get_queried_object_id() );
|
||||
|
||||
// Find all display conditions used in the page, flat the results, filter to only include NumberOfViews conditions.
|
||||
if ( preg_match_all( '/(?<=display_conditions=")[^"]*/mi', $entire_page_content, $matches, PREG_SET_ORDER ) ) {
|
||||
$display_conditions_attrs = array_reduce( $matches, 'array_merge', [] ); // Flatten and Store All `display_conditions` attributes found.
|
||||
$cookie = $this->number_of_views_process_conditions( $display_conditions_attrs );
|
||||
if ( false === $cookie ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode cookie content and set cookie only if quired object id can be retrieved.
|
||||
* `serrawcookie` is used to ignore automatic `urlencode` with `setcookie` since it corrupts base64 data.
|
||||
*/
|
||||
if ( ! empty( $cookie ) ) {
|
||||
$cookie = base64_encode( wp_json_encode( $cookie ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- base64_encode data is an array.
|
||||
setrawcookie( 'divi_module_views', $cookie, time() + 3600 * 24 * 365, COOKIEPATH, COOKIE_DOMAIN );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks "NumberOFViews" conditions against respective $_COOKIE content and updates/reset the
|
||||
* condition when necessary.
|
||||
*
|
||||
* @since 4.11.0
|
||||
*
|
||||
* @param array $display_conditions_attrs Array of conditions as base64 encoded data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function number_of_views_process_conditions( $display_conditions_attrs ) {
|
||||
$is_cookie_set = isset( $_COOKIE['divi_module_views'] ) ? true : false;
|
||||
$current_datetime = current_datetime();
|
||||
$cookie = $is_cookie_set ? json_decode( base64_decode( $_COOKIE['divi_module_views'] ), true ) : []; // phpcs:ignore ET.Sniffs.ValidatedSanitizedInput, WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Cookie is not stored or displayed therefore XSS safe, The returned data is an array and necessary validation checks are performed.
|
||||
|
||||
// Decode NumberOfViews conditions one by one then set or update cookie.
|
||||
foreach ( $display_conditions_attrs as $condition_base64 ) {
|
||||
$display_conditions = json_decode( base64_decode( $condition_base64 ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- The returned data is an array and necessary validation checks are performed.
|
||||
|
||||
if ( ! is_array( $display_conditions ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $display_conditions as $display_condition ) {
|
||||
$condition_id = $display_condition['id'];
|
||||
$condition_name = $display_condition['condition'];
|
||||
$condition_settings = $display_condition['conditionSettings'];
|
||||
|
||||
if ( 'numberOfViews' !== $condition_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_reset_on = 'on' === $condition_settings['resetAfterDuration'] ? true : false;
|
||||
$reset_time = $condition_settings['displayAgainAfter'] . ' ' . $condition_settings['displayAgainAfterUnit'];
|
||||
$is_condition_id_in_cookie = array_search( $condition_id, array_column( $cookie, 'id' ), true ) !== false ? true : false;
|
||||
|
||||
if ( $is_reset_on && $is_cookie_set && isset( $cookie[ $condition_id ] ) ) {
|
||||
$first_visit_timestamp = $cookie[ $condition_id ]['first_visit_timestamp'];
|
||||
$first_visit_datetime = $current_datetime->setTimestamp( $first_visit_timestamp );
|
||||
$reset_datetime = $first_visit_datetime->modify( $reset_time );
|
||||
if ( $current_datetime > $reset_datetime ) {
|
||||
$cookie[ $condition_id ]['visit_count'] = 1;
|
||||
$cookie[ $condition_id ]['first_visit_timestamp'] = $current_datetime->getTimestamp();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $is_cookie_set && $is_condition_id_in_cookie ) {
|
||||
$cookie[ $condition_id ]['visit_count'] += 1;
|
||||
} else {
|
||||
$cookie[ $condition_id ] = [
|
||||
'id' => $condition_id,
|
||||
'visit_count' => 1,
|
||||
'first_visit_timestamp' => $current_datetime->getTimestamp(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ET_Builder_Display_Conditions::get_instance();
|
@ -0,0 +1 @@
|
||||
.et_pb_accordion.et_pb_text_align_left .et_pb_toggle_title,.et_pb_accordion.et_pb_text_align_left h5.et_pb_toggle_title,.et_pb_accordion .et_pb_toggle.et_pb_text_align_left .et_pb_toggle_title,.et_pb_accordion .et_pb_toggle.et_pb_text_align_left h5.et_pb_toggle_title{cursor:pointer;position:relative;padding:0 50px 0 0}.et_pb_accordion .et_pb_toggle_title:before{right:0;left:auto}.et_pb_accordion .et_pb_toggle{margin-bottom:10px;position:relative}.et_pb_accordion .et_pb_toggle:last-child{margin-bottom:0}.et_pb_accordion .et_pb_toggle_open .et_pb_toggle_title:before{display:none}@media (max-width:980px){.et_pb_accordion.et_pb_text_align_left-tablet .et_pb_toggle_title,.et_pb_accordion.et_pb_text_align_left-tablet h5.et_pb_toggle_title,.et_pb_accordion .et_pb_toggle.et_pb_text_align_left-tablet .et_pb_toggle_title,.et_pb_accordion .et_pb_toggle.et_pb_text_align_left-tablet h5.et_pb_toggle_title{cursor:pointer;position:relative;padding:0 50px 0 0}}@media (max-width:767px){.et_pb_accordion.et_pb_text_align_left-phone .et_pb_toggle_title,.et_pb_accordion.et_pb_text_align_left-phone h5.et_pb_toggle_title,.et_pb_accordion .et_pb_toggle.et_pb_text_align_left-phone .et_pb_toggle_title,.et_pb_accordion .et_pb_toggle.et_pb_text_align_left-phone h5.et_pb_toggle_title{cursor:pointer;position:relative;padding:0 50px 0 0}}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_accordion.et_pb_text_align_left .et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion.et_pb_text_align_left h5.et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle.et_pb_text_align_left .et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle.et_pb_text_align_left h5.et_pb_toggle_title{cursor:pointer;position:relative;padding:0 50px 0 0}.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle_title:before{right:0;left:auto}.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle{margin-bottom:10px;position:relative}.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle:last-child{margin-bottom:0}.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle_open .et_pb_toggle_title:before{display:none}@media (max-width:980px){.et-db #et-boc .et-l .et_pb_accordion.et_pb_text_align_left-tablet .et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion.et_pb_text_align_left-tablet h5.et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle.et_pb_text_align_left-tablet .et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle.et_pb_text_align_left-tablet h5.et_pb_toggle_title{cursor:pointer;position:relative;padding:0 50px 0 0}}@media (max-width:767px){.et-db #et-boc .et-l .et_pb_accordion.et_pb_text_align_left-phone .et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion.et_pb_text_align_left-phone h5.et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle.et_pb_text_align_left-phone .et_pb_toggle_title,.et-db #et-boc .et-l .et_pb_accordion .et_pb_toggle.et_pb_text_align_left-phone h5.et_pb_toggle_title{cursor:pointer;position:relative;padding:0 50px 0 0}}
|
@ -0,0 +1 @@
|
||||
.et_animated{opacity:0;animation-duration:1s;animation-fill-mode:both!important}.et_animated.infinite{animation-iteration-count:infinite}.et_had_animation{position:relative}@keyframes et_pb_fade{to{opacity:1}}.et_animated.fade{animation-name:et_pb_fade}@keyframes et_pb_fadeTop{0%{transform:translate3d(0,-100%,0)}to{opacity:1;transform:none}}.et_animated.fadeTop{animation-name:et_pb_fadeTop}@keyframes et_pb_fadeRight{0%{transform:translate3d(100%,0,0)}to{opacity:1;transform:none}}.et_animated.fadeRight{animation-name:et_pb_fadeRight}@keyframes et_pb_fadeBottom{0%{transform:translate3d(0,100%,0)}to{opacity:1;transform:none}}.et_animated.fadeBottom{animation-name:et_pb_fadeBottom}@keyframes et_pb_fadeLeft{0%{transform:translate3d(-100%,0,0)}to{opacity:1;transform:none}}.et_animated.fadeLeft{animation-name:et_pb_fadeLeft}.et_animated.slide{animation-name:et_pb_zoomLeft}.et_animated.slideBottom,.et_animated.slideRight,.et_animated.slideTop{animation-name:et_pb_slideLeft}@keyframes et_pb_slideLeft{to{transform:translateZ(0);opacity:1}}.et_animated.slideLeft{animation-name:et_pb_slideLeft}@keyframes et_pb_bounce{0%,20%,40%,60%,80%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{transform:scale3d(.3,.3,.3)}20%{transform:scale3d(1.1,1.1,1.1)}40%{transform:scale3d(.9,.9,.9)}60%{transform:scale3d(1.03,1.03,1.03)}80%{transform:scale3d(.97,.97,.97)}to{opacity:1;transform:scaleX(1)}}.et_animated.bounce{animation-name:et_pb_bounce}@keyframes et_pb_bounceTop{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{transform:translate3d(0,-200px,0)}60%{transform:translate3d(0,25px,0)}75%{transform:translate3d(0,-10px,0)}90%{transform:translate3d(0,5px,0)}to{transform:none;opacity:1}}.et_animated.bounceTop{animation-name:et_pb_bounceTop}@keyframes et_pb_bounceRight{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{transform:translate3d(200px,0,0)}60%{transform:translate3d(-25px,0,0)}75%{transform:translate3d(10px,0,0)}90%{transform:translate3d(-5px,0,0)}to{transform:none;opacity:1}}.et_animated.bounceRight{animation-name:et_pb_bounceRight}@keyframes et_pb_bounceBottom{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{transform:translate3d(0,200px,0)}60%{transform:translate3d(0,-20px,0)}75%{transform:translate3d(0,10px,0)}90%{transform:translate3d(0,-5px,0)}to{transform:translateZ(0);opacity:1}}.et_animated.bounceBottom{animation-name:et_pb_bounceBottom}@keyframes et_pb_bounceLeft{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{transform:translate3d(-200px,0,0)}60%{transform:translate3d(25px,0,0)}75%{transform:translate3d(-10px,0,0)}90%{transform:translate3d(5px,0,0)}to{transform:none;opacity:1}}.et_animated.bounceLeft{animation-name:et_pb_bounceLeft}.et_animated.zoom,.et_animated.zoomTop{animation-name:et_pb_zoomLeft}.et_animated.zoomTop{transform-origin:top}.et_animated.zoomRight{animation-name:et_pb_zoomLeft;transform-origin:right}.et_animated.zoomBottom{animation-name:et_pb_zoomLeft;transform-origin:bottom}@keyframes et_pb_zoomLeft{to{transform:scaleX(1);opacity:1}}.et_animated.zoomLeft{animation-name:et_pb_zoomLeft;transform-origin:left}.et_animated.flip,.et_animated.flipTop{animation-name:et_pb_foldBottom}.et_animated.flipRight,.et_animated.flipTop{transform-origin:center}.et_animated.flipRight{animation-name:et_pb_foldLeft}.et_animated.flipBottom{animation-name:et_pb_foldBottom;transform-origin:center}.et_animated.flipLeft,.et_animated.fold{animation-name:et_pb_foldLeft;transform-origin:center}.et_animated.foldTop{transform-origin:top;animation-name:et_pb_foldBottom}.et_animated.foldRight{transform-origin:right;animation-name:et_pb_foldLeft}@keyframes et_pb_foldBottom{to{opacity:1;transform:rotateX(0deg)}}.et_animated.foldBottom{transform-origin:bottom;animation-name:et_pb_foldBottom}@keyframes et_pb_foldLeft{to{opacity:1;transform:rotateY(0deg)}}.et_animated.foldLeft{transform-origin:left;animation-name:et_pb_foldLeft}@keyframes et_pb_roll{0%{transform-origin:center}to{transform-origin:center;transform:none;opacity:1}}.et_animated.roll{animation-name:et_pb_roll}@keyframes et_pb_rollTop{0%{transform-origin:top}to{transform-origin:top;transform:none;opacity:1}}.et_animated.rollTop{animation-name:et_pb_rollTop}@keyframes et_pb_rollRight{0%{transform-origin:right}to{transform-origin:right;transform:none;opacity:1}}.et_animated.rollRight{animation-name:et_pb_rollRight}@keyframes et_pb_rollBottom{0%{transform-origin:bottom}to{transform-origin:bottom;transform:none;opacity:1}}.et_animated.rollBottom{animation-name:et_pb_rollBottom}@keyframes et_pb_rollLeft{0%{transform-origin:left}to{transform-origin:left;transform:none;opacity:1}}.et_animated.rollLeft{animation-name:et_pb_rollLeft}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.et_pb_audio_module{position:relative}.et_pb_audio_cover_art{position:absolute;top:0;left:0;height:100%;width:220px;background-size:cover;background-repeat:no-repeat;background-position:50%;transition:inherit}.et_pb_with_border .et_pb_audio_cover_art{border:0 solid #333}.et_pb_column_1_2 .et_pb_audio_cover_art,.et_pb_column_1_3 .et_pb_audio_cover_art,.et_pb_column_1_4 .et_pb_audio_cover_art,.et_pb_column_1_5 .et_pb_audio_cover_art,.et_pb_column_1_6 .et_pb_audio_cover_art,.et_pb_column_2_5 .et_pb_audio_cover_art,.et_pb_column_3_5 .et_pb_audio_cover_art,.et_pb_column_3_8 .et_pb_audio_cover_art{float:none;width:100%;position:relative}.et_pb_column_1_2 .et_pb_audio_cover_art,.et_pb_column_3_5 .et_pb_audio_cover_art{height:380px}.et_pb_column_3_8 .et_pb_audio_cover_art{height:275px}.et_pb_column_1_3 .et_pb_audio_cover_art,.et_pb_column_2_5 .et_pb_audio_cover_art{height:240px}.et_pb_column_1_4 .et_pb_audio_cover_art,.et_pb_column_1_5 .et_pb_audio_cover_art,.et_pb_column_1_6 .et_pb_audio_cover_art{height:170px}.et_audio_module_meta{margin-bottom:17px;color:#fff}.et_pb_audio_module_content{text-align:center;word-wrap:break-word;position:relative;padding:50px 60px;margin-left:220px}.et_pb_audio_module_content h2{color:#fff!important}.et_pb_text_color_dark .et_pb_audio_module_content h2{color:#666!important}.et_pb_text_color_dark.et_pb_audio_module_content h2{color:#bbb!important}.et_pb_audio_module_content h2{margin-top:0}.et_pb_column_2_3 .et_pb_audio_module_content{padding:40px 40px 45px}.et_pb_column_1_2 .et_pb_audio_module_content,.et_pb_column_3_5 .et_pb_audio_module_content{padding:40px 40px 35px}.et_pb_column_1_3 .et_pb_audio_module_content,.et_pb_column_1_4 .et_pb_audio_module_content,.et_pb_column_3_8 .et_pb_audio_module_content{padding:30px}.et_pb_audio_no_image .et_pb_audio_module_content,.et_pb_column_1_2 .et_pb_audio_module_content,.et_pb_column_1_3 .et_pb_audio_module_content,.et_pb_column_1_4 .et_pb_audio_module_content,.et_pb_column_1_5 .et_pb_audio_module_content,.et_pb_column_1_6 .et_pb_audio_module_content,.et_pb_column_2_5 .et_pb_audio_module_content,.et_pb_column_3_5 .et_pb_audio_module_content,.et_pb_column_3_8 .et_pb_audio_module_content{margin-left:0}@media (min-width:981px){.et_pb_column_4_4 .et_pb_audio_cover_art.has-box-shadow-overlay{position:absolute}}@media (min-width:981px) and (max-width:1100px){.et_pb_column_1_2 .et_pb_audio_cover_art,.et_pb_column_3_5 .et_pb_audio_cover_art{height:340px}.et_pb_column_3_8 .et_pb_audio_cover_art{height:242px}.et_pb_column_1_3 .et_pb_audio_cover_art,.et_pb_column_2_5 .et_pb_audio_cover_art{height:210px}.et_pb_column_1_4 .et_pb_audio_cover_art,.et_pb_column_1_5 .et_pb_audio_cover_art,.et_pb_column_1_6 .et_pb_audio_cover_art{height:145px}}@media (max-width:980px){.et_pb_text_color_dark_tablet.et_pb_audio_module_content h2{color:#bbb!important}}@media (min-width:768px) and (max-width:980px){.et_audio_content h2{font-size:26px!important;line-height:44px!important;margin-bottom:24px!important}.et_pb_blog_grid .et_audio_content h2{font-size:20px!important;line-height:26px!important}.et_pb_audio_cover_art{float:none!important;width:100%!important;position:relative;height:400px!important}.et_pb_audio_module_content{margin-left:0!important;padding:55px 60px!important}.et_pb_audio_module_content h2{font-size:36px}.et_pb_column_1_4 .et_audio_module_meta,.et_pb_column_1_5 .et_audio_module_meta,.et_pb_column_1_6 .et_audio_module_meta{font-size:14px!important}}@media (max-width:767px){.et_pb_audio_module_content{margin-left:0!important;padding:30px!important}.et_pb_audio_module_content h2{font-size:26px}.et_pb_column_1_4 .et_audio_module_meta,.et_pb_column_1_5 .et_audio_module_meta,.et_pb_column_1_6 .et_audio_module_meta{font-size:14px!important}.et_pb_text_color_dark_phone.et_pb_audio_module_content h2{color:#bbb!important}.et_pb_audio_cover_art{float:none!important;width:100%!important;position:relative;height:300px!important}}@media (max-width:479px){.et_pb_audio_module_content h2{font-size:20px}.et_pb_column_1_4 .et_audio_module_meta,.et_pb_column_1_5 .et_audio_module_meta,.et_pb_column_1_6 .et_audio_module_meta{font-size:14px!important}.et_pb_audio_cover_art{float:none!important;width:100%!important;height:210px!important}}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total,body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-controls .mejs-time-rail .mejs-time-total,body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-controls a.mejs-horizontal-volume-slider{left:0;right:auto}body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-controls a.mejs-horizontal-volume-slider{margin-left:0}body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-time{margin-left:90px;margin-right:10px}body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-android .mejs-time,body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-ios .mejs-time,body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-ipad .mejs-time,body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-iphone .mejs-time{margin-left:0}body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-button.mejs-volume-button{right:auto;left:59px}body.rtl.et-db:not(.et-fb-no-rtl) .et_audio_container .mejs-controls div.mejs-time-rail{margin-right:42px;margin-left:5px}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total,body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-controls .mejs-time-rail .mejs-time-total,body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-controls a.mejs-horizontal-volume-slider{left:0;right:auto}body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-controls a.mejs-horizontal-volume-slider{margin-left:0}body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-time{margin-left:90px;margin-right:10px}body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-android .mejs-time,body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-ios .mejs-time,body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-ipad .mejs-time,body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-iphone .mejs-time{margin-left:0}body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-button.mejs-volume-button{right:auto;left:59px}body.rtl.et-db:not(.et-fb-no-rtl).et-db #et-boc .et-l .et_audio_container .mejs-controls div.mejs-time-rail{margin-right:42px;margin-left:5px}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.rtl .et_pb_blog_grid .column{float:right}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.rtl.et-db #et-boc .et-l .et_pb_blog_grid .column{float:right}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.et_pb_bg_layout_light.et_pb_module.et_pb_button{color:#2ea3f2}.et_pb_module.et_pb_button{display:inline-block;color:inherit}.et_pb_button_module_wrapper.et_pb_button_alignment_left{text-align:left}.et_pb_button_module_wrapper.et_pb_button_alignment_right{text-align:right}.et_pb_button_module_wrapper.et_pb_button_alignment_center{text-align:center}.et_pb_button_module_wrapper>a{display:inline-block}@media (max-width:980px){.et_pb_button_module_wrapper.et_pb_button_alignment_tablet_left{text-align:left}.et_pb_button_module_wrapper.et_pb_button_alignment_tablet_right{text-align:right}.et_pb_button_module_wrapper.et_pb_button_alignment_tablet_center{text-align:center}}@media (max-width:767px){.et_pb_button_module_wrapper.et_pb_button_alignment_phone_left{text-align:left}.et_pb_button_module_wrapper.et_pb_button_alignment_phone_right{text-align:right}.et_pb_button_module_wrapper.et_pb_button_alignment_phone_center{text-align:center}}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_bg_layout_light.et_pb_module.et_pb_button{color:#2ea3f2}.et-db #et-boc .et-l .et_pb_module.et_pb_button{display:inline-block;color:inherit}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_left{text-align:left}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_right{text-align:right}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_center{text-align:center}.et-db #et-boc .et-l .et_pb_button_module_wrapper>a{display:inline-block}@media (max-width:980px){.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_tablet_left{text-align:left}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_tablet_right{text-align:right}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_tablet_center{text-align:center}}@media (max-width:767px){.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_phone_left{text-align:left}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_phone_right{text-align:right}.et-db #et-boc .et-l .et_pb_button_module_wrapper.et_pb_button_alignment_phone_center{text-align:center}}
|
@ -0,0 +1 @@
|
||||
.et_pb_button[data-icon]:not([data-icon=""]):after{content:attr(data-icon)}@media (max-width:980px){.et_pb_button[data-icon-tablet]:not([data-icon-tablet=""]):after{content:attr(data-icon-tablet)}}@media (max-width:767px){.et_pb_button[data-icon-phone]:not([data-icon-phone=""]):after{content:attr(data-icon-phone)}}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_button[data-icon]:not([data-icon=""]):after{content:attr(data-icon)}@media (max-width:980px){.et-db #et-boc .et-l .et_pb_button[data-icon-tablet]:not([data-icon-tablet=""]):after{content:attr(data-icon-tablet)}}@media (max-width:767px){.et-db #et-boc .et-l .et_pb_button[data-icon-phone]:not([data-icon-phone=""]):after{content:attr(data-icon-phone)}}
|
@ -0,0 +1 @@
|
||||
.et_pb_circle_counter{word-wrap:break-word;margin:0 auto 30px;position:relative;text-align:center;max-width:225px}.et_pb_circle_counter_inner{position:relative;display:block}.et_pb_circle_counter canvas{position:absolute;top:0;left:0;width:100%!important;height:auto!important}.et_pb_circle_counter .percent{word-wrap:normal;position:relative;z-index:2}.et_pb_circle_counter .percent p{visibility:hidden;font-size:40px;font-weight:500;position:relative;line-height:.1em;padding:49% 0}.et_pb_circle_counter h3{font-size:18px;position:relative}.et_pb_circle_counter .et_pb_module_header{position:relative}.et_pb_circle_counter.et_pb_with_title .percent{margin-bottom:20px}.et_pb_slide_content .et_pb_circle_counter .percent p:last-of-type{font-size:40px;font-weight:500;position:relative;line-height:.1em;padding:49% 0}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_circle_counter{word-wrap:break-word;margin:0 auto 30px;position:relative;text-align:center;max-width:225px}.et-db #et-boc .et-l .et_pb_circle_counter_inner{position:relative;display:block}.et-db #et-boc .et-l .et_pb_circle_counter canvas{position:absolute;top:0;left:0;width:100%!important;height:auto!important}.et-db #et-boc .et-l .et_pb_circle_counter .percent{word-wrap:normal;position:relative;z-index:2}.et-db #et-boc .et-l .et_pb_circle_counter .percent p{visibility:hidden;font-size:40px;font-weight:500;position:relative;line-height:.1em;padding:49% 0}.et-db #et-boc .et-l .et_pb_circle_counter h3{font-size:18px;position:relative}.et-db #et-boc .et-l .et_pb_circle_counter .et_pb_module_header{position:relative}.et-db #et-boc .et-l .et_pb_circle_counter.et_pb_with_title .percent{margin-bottom:20px}.et-db #et-boc .et-l .et_pb_slide_content .et_pb_circle_counter .percent p:last-of-type{font-size:40px;font-weight:500;position:relative;line-height:.1em;padding:49% 0}
|
@ -0,0 +1 @@
|
||||
.et_pb_code_inner{position:relative}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_code_inner{position:relative}
|
@ -0,0 +1 @@
|
||||
.et_pb_with_border.et_pb_comments_module .commentlist li img.avatar,.et_pb_with_border.et_pb_comments_module input,.et_pb_with_border.et_pb_comments_module textarea{border:0 solid #333}.et_pb_comments_module #comment-wrap{padding-top:0;position:relative}.et_pb_comments_module.et_pb_no_avatar .comment_avatar{display:none}.et_pb_comments_module.et_pb_no_avatar .comment-body{padding-left:0!important;min-height:0!important}.et_pb_comments_module.et_pb_no_avatar.et_pb_no_reply_button .comment-body{margin-bottom:15px!important}.et_pb_comments_module.et_pb_no_reply_button span.reply-container{display:none}.et_pb_comments_module.et_pb_no_reply_button .comment-body{padding-right:0!important}.et_pb_comments_module.et_pb_no_comments_count #comments{display:none}.et_pb_bg_layout_dark .comment_postinfo a,.et_pb_bg_layout_dark .comment_postinfo span{color:#fff}@media (min-width:480px){.et_pb_column_1_4 .et_pb_comments_module .comment_avatar img,.et_pb_column_1_5 .et_pb_comments_module .comment_avatar img,.et_pb_column_1_6 .et_pb_comments_module .comment_avatar img{max-width:50%}.et_pb_column_1_4 .et_pb_comments_module .comment-body,.et_pb_column_1_5 .et_pb_comments_module .comment-body,.et_pb_column_1_6 .et_pb_comments_module .comment-body{padding:0 0 0 50px}.et_pb_column_1_4 .et_pb_comments_module .comment .children,.et_pb_column_1_5 .et_pb_comments_module .comment .children,.et_pb_column_1_6 .et_pb_comments_module .comment .children{margin-left:0}.et_pb_column_1_4 .et_pb_comments_module .comment-reply-link,.et_pb_column_1_5 .et_pb_comments_module .comment-reply-link,.et_pb_column_1_6 .et_pb_comments_module .comment-reply-link{position:relative!important;float:right;bottom:-10px;top:auto!important}}@media (min-width:981px){.et_pb_column_1_2 .et_pb_comments_module .comment_avatar img,.et_pb_column_1_3 .et_pb_comments_module .comment_avatar img,.et_pb_column_1_4 .et_pb_comments_module .comment_avatar img,.et_pb_column_1_5 .et_pb_comments_module .comment_avatar img,.et_pb_column_1_6 .et_pb_comments_module .comment_avatar img,.et_pb_column_2_5 .et_pb_comments_module .comment_avatar img,.et_pb_column_3_5 .et_pb_comments_module .comment_avatar img{max-width:50%}.et_pb_column_1_2 .et_pb_comments_module .comment-body,.et_pb_column_1_3 .et_pb_comments_module .comment-body,.et_pb_column_1_4 .et_pb_comments_module .comment-body,.et_pb_column_1_5 .et_pb_comments_module .comment-body,.et_pb_column_1_6 .et_pb_comments_module .comment-body,.et_pb_column_2_5 .et_pb_comments_module .comment-body,.et_pb_column_3_5 .et_pb_comments_module .comment-body{padding:0 0 0 50px}.et_pb_column_1_2 .et_pb_comments_module .comment .children,.et_pb_column_1_3 .et_pb_comments_module .comment .children,.et_pb_column_1_4 .et_pb_comments_module .comment .children,.et_pb_column_1_5 .et_pb_comments_module .comment .children,.et_pb_column_1_6 .et_pb_comments_module .comment .children,.et_pb_column_2_5 .et_pb_comments_module .comment .children,.et_pb_column_3_5 .et_pb_comments_module .comment .children{margin-left:25px}.et_pb_column_1_2 .et_pb_comments_module .comment-reply-link,.et_pb_column_1_3 .et_pb_comments_module .comment-reply-link,.et_pb_column_1_4 .et_pb_comments_module .comment-reply-link,.et_pb_column_1_5 .et_pb_comments_module .comment-reply-link,.et_pb_column_1_6 .et_pb_comments_module .comment-reply-link,.et_pb_column_2_5 .et_pb_comments_module .comment-reply-link,.et_pb_column_3_5 .et_pb_comments_module .comment-reply-link{position:relative!important;float:right;bottom:-10px;top:auto!important}.et_pb_column_1_2 .et_pb_comments_module #commentform [class*=comment-form-] input,.et_pb_column_1_3 .et_pb_comments_module #commentform [class*=comment-form-] input,.et_pb_column_1_4 .et_pb_comments_module #commentform [class*=comment-form-] input,.et_pb_column_1_5 .et_pb_comments_module #commentform [class*=comment-form-] input,.et_pb_column_1_6 .et_pb_comments_module #commentform [class*=comment-form-] input,.et_pb_column_2_5 .et_pb_comments_module #commentform [class*=comment-form-] input,.et_pb_column_3_5 .et_pb_comments_module #commentform [class*=comment-form-] input{box-sizing:border-box;width:100%}}.single-project #comment-wrap{padding-top:0}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
#comment-wrap{padding-top:75px}.comment-body{position:relative;padding:0 110px 0 100px;margin-bottom:48px;min-height:87px}.comment_avatar{left:0;position:absolute;top:7px}.comment_avatar img{display:block;height:auto;max-width:100%;width:auto}.comment_postinfo{margin-bottom:8px}span.fn,span.fn a{color:#000;font-weight:700;text-decoration:none;font-size:16px;display:inline-block}span.comment_date{color:#000;font-size:14px;font-weight:300}.comment_area .comment-reply-link{position:absolute;top:7px;right:0;display:block}.comment-reply-link:hover,.form-submit:hover{text-decoration:none}.comment .children{margin-left:100px;padding-left:0!important}#comment-wrap li.comment.depth-5 article{padding-right:0}.comment #respond{margin:-30px 0 0}#respond{padding-top:17px}#commentform{padding-bottom:50px}#commentform input[type=email],#commentform input[type=text],#commentform input[type=url]{width:47%}#commentform textarea{width:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}#commentform input[type=email],#commentform input[type=text],#commentform input[type=url],#commentform textarea{padding:12px;color:#999;line-height:1em;background-color:#eee;font-size:18px;border-width:0}.form-submit{text-align:right}.form-submit .et_pb_button{display:inline-block;cursor:pointer;color:#2ea3f2}#reply-title small{display:block;font-size:14px;font-weight:400}@media (max-width:767px){#comment-wrap li.comment article{padding-right:0}.comment-body{padding:0 0 0 100px}.comment-reply-link{position:relative!important;float:right;bottom:-10px;top:auto!important}#commentform input[type=email],#commentform input[type=text],#commentform input[type=url]{width:100%;box-sizing:border-box;margin-left:0}.comment .children{margin-left:50px}}@media (max-width:479px){.comment_avatar img{max-width:50%}.comment-body{padding:0 0 0 50px}.comment .children{margin-left:25px}a.comment-reply-link.et_pb_button{font-size:15px}a.comment-reply-link.et_pb_button:after{font-size:25px}}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l #comment-wrap{padding-top:75px}.et-db #et-boc .et-l .comment-body{position:relative;padding:0 110px 0 100px;margin-bottom:48px;min-height:87px}.et-db #et-boc .et-l .comment_avatar{left:0;position:absolute;top:7px}.et-db #et-boc .et-l .comment_avatar img{display:block;height:auto;max-width:100%;width:auto}.et-db #et-boc .et-l .comment_postinfo{margin-bottom:8px}.et-db #et-boc .et-l span.fn,.et-db #et-boc .et-l span.fn a{color:#000;font-weight:700;text-decoration:none;font-size:16px;display:inline-block}.et-db #et-boc .et-l span.comment_date{color:#000;font-size:14px;font-weight:300}.et-db #et-boc .et-l .comment_area .comment-reply-link{position:absolute;top:7px;right:0;display:block}.et-db #et-boc .et-l .comment-reply-link:hover,.et-db #et-boc .et-l .form-submit:hover{text-decoration:none}.et-db #et-boc .et-l .comment .children{margin-left:100px;padding-left:0!important}.et-db #et-boc .et-l #comment-wrap li.comment.depth-5 article{padding-right:0}.et-db #et-boc .et-l .comment #respond{margin:-30px 0 0}.et-db #et-boc .et-l #respond{padding-top:17px}.et-db #et-boc .et-l #commentform{padding-bottom:50px}.et-db #et-boc .et-l #commentform input[type=email],.et-db #et-boc .et-l #commentform input[type=text],.et-db #et-boc .et-l #commentform input[type=url]{width:47%}.et-db #et-boc .et-l #commentform textarea{width:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.et-db #et-boc .et-l #commentform input[type=email],.et-db #et-boc .et-l #commentform input[type=text],.et-db #et-boc .et-l #commentform input[type=url],.et-db #et-boc .et-l #commentform textarea{padding:12px;color:#999;line-height:1em;background-color:#eee;font-size:18px;border-width:0}.et-db #et-boc .et-l .form-submit{text-align:right}.et-db #et-boc .et-l .form-submit .et_pb_button{display:inline-block;cursor:pointer;color:#2ea3f2}.et-db #et-boc .et-l #reply-title small{display:block;font-size:14px;font-weight:400}@media (max-width:767px){.et-db #et-boc .et-l #comment-wrap li.comment article{padding-right:0}.et-db #et-boc .et-l .comment-body{padding:0 0 0 100px}.et-db #et-boc .et-l .comment-reply-link{position:relative!important;float:right;bottom:-10px;top:auto!important}.et-db #et-boc .et-l #commentform input[type=email],.et-db #et-boc .et-l #commentform input[type=text],.et-db #et-boc .et-l #commentform input[type=url]{width:100%;box-sizing:border-box;margin-left:0}.et-db #et-boc .et-l .comment .children{margin-left:50px}}@media (max-width:479px){.et-db #et-boc .et-l .comment_avatar img{max-width:50%}.et-db #et-boc .et-l .comment-body{padding:0 0 0 50px}.et-db #et-boc .et-l .comment .children{margin-left:25px}.et-db #et-boc .et-l a.comment-reply-link.et_pb_button{font-size:15px}.et-db #et-boc .et-l a.comment-reply-link.et_pb_button:after{font-size:25px}}
|
@ -0,0 +1 @@
|
||||
.rtl .et_pb_contact_select,.rtl .et_pb_contact p input[type=checkbox]+label i,.rtl .et_pb_contact p input[type=radio]+label i{padding:16px 16px 16px 20px}.rtl .et_pb_contact_field[data-type=select]:after{right:auto;left:42px}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.rtl .et-db #et-boc .et-l .et_pb_contact_select,.rtl .et-db #et-boc .et-l .et_pb_contact p input[type=checkbox]+label i,.rtl .et-db #et-boc .et-l .et_pb_contact p input[type=radio]+label i{padding:16px 16px 16px 20px}.rtl .et-db #et-boc .et-l .et_pb_contact_field[data-type=select]:after{right:auto;left:42px}.rtl.et-db #et-boc .et-l .et_pb_contact_select,.rtl.et-db #et-boc .et-l .et_pb_contact p input[type=checkbox]+label i,.rtl.et-db #et-boc .et-l .et_pb_contact p input[type=radio]+label i{padding:16px 16px 16px 20px}.rtl.et-db #et-boc .et-l .et_pb_contact_field[data-type=select]:after{right:auto;left:42px}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.et_pb_countdown_timer_container{word-wrap:break-word}.et_pb_countdown_timer{padding:4%}.et_pb_countdown_timer .et_pb_countdown_timer_container{width:100%;text-align:center;position:relative;vertical-align:top}.et_pb_countdown_timer .title{font-weight:500;margin:0 0 30px;padding:0;text-align:center}.et_pb_countdown_timer h4.title{font-size:26px}.et_pb_countdown_timer .section{display:inline-block;position:relative}.et_pb_countdown_timer .section.values{width:17%;max-width:160px;vertical-align:top}.et_pb_countdown_timer .section p{font-size:54px;line-height:54px;padding-bottom:0;text-align:center;display:inline-block}.et_pb_countdown_timer .section.zero p{opacity:.4}.et_pb_countdown_timer .section p.value{min-width:100%}.et_pb_countdown_timer .section p.label{text-align:center;font-size:14px;line-height:25px;display:block}.et_pb_countdown_timer .sep{position:relative}.et_pb_countdown_timer .sep.sep.sep.sep.sep p{text-decoration:none!important}.et_pb_column_1_2 .et_pb_countdown_timer .section p,.et_pb_column_3_5 .et_pb_countdown_timer .section p{font-size:38px;line-height:38px}.et_pb_column_1_2 .et_pb_countdown_timer .section p.label,.et_pb_column_3_5 .et_pb_countdown_timer .section p.label{font-size:12px;line-height:20px}.et_pb_column_1_3 .et_pb_countdown_timer .title,.et_pb_column_1_4 .et_pb_countdown_timer .title,.et_pb_column_1_5 .et_pb_countdown_timer .title,.et_pb_column_1_6 .et_pb_countdown_timer .title,.et_pb_column_2_5 .et_pb_countdown_timer .title{font-size:22px;margin-bottom:20px}.et_pb_column_1_3 .et_pb_countdown_timer .section p,.et_pb_column_2_5 .et_pb_countdown_timer .section p,.et_pb_column_3_8 .et_pb_countdown_timer .section p{font-size:28px;line-height:28px}.et_pb_column_1_4 .et_pb_countdown_timer .section p,.et_pb_column_1_5 .et_pb_countdown_timer .section p,.et_pb_column_1_6 .et_pb_countdown_timer .section p{font-size:20px;line-height:20px}.et_pb_column_1_3 .et_pb_countdown_timer .section p.label,.et_pb_column_1_4 .et_pb_countdown_timer .section p.label,.et_pb_column_1_5 .et_pb_countdown_timer .section p.label,.et_pb_column_1_6 .et_pb_countdown_timer .section p.label,.et_pb_column_2_5 .et_pb_countdown_timer .section p.label,.et_pb_column_3_8 .et_pb_countdown_timer .section p.label{font-size:11px;line-height:19px}@media (max-width:980px){.et_pb_countdown_timer .title{font-size:22px!important}.et_pb_countdown_timer .section p{font-size:64px!important;line-height:64px!important}.et_pb_countdown_timer .section p.label{font-size:14px!important;line-height:25px!important}.et_pb_countdown_timer .sep.sep.sep.sep.sep p{text-decoration:none!important}.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p{font-size:32px!important;line-height:32px!important}.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p.label{font-size:14px!important;line-height:25px!important}}@media (min-width:768px) and (max-width:800px){.et_pb_countdown_timer .section p{font-size:50px!important;line-height:50px!important}.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p{font-size:25px!important;line-height:25px!important}}@media (max-width:767px){.et_pb_countdown_timer .title{font-size:22px!important;margin-bottom:20px!important}.et_pb_countdown_timer .section p{font-size:32px!important;line-height:32px!important}.et_pb_countdown_timer .section p.label{font-size:14px!important;line-height:25px!important}.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p{font-size:16px!important;line-height:16px!important}.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p.label{font-size:14px!important;line-height:25px!important}}@media (max-width:479px){.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p{font-size:32px!important;line-height:32px!important}}@media (max-width:380px){.et_pb_countdown_timer .section p,.et_pb_row_1-4_1-4 .et_pb_column_1_4 .et_pb_countdown_timer .section p{font-size:24px!important;line-height:24px!important}.et_pb_countdown_timer .section p.label{font-size:12px!important;line-height:25px!important}}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.et_pb_counter_title{word-wrap:break-word}.et_pb_counter_amount{background-color:#2ea3f2}.et_pb_counters .et_pb_counter_container{background-size:cover;background-position:50%;background-repeat:no-repeat}.et_pb_with_border .et_pb_counter_container{border:0 solid #333}.et_pb_counter_title{font-size:12px;line-height:1.6em;display:block}.et_pb_bg_layout_light .et_pb_counter_title{color:#666}.et_pb_counter_container{background-color:#ddd;color:#fff;margin-bottom:10px;overflow:hidden;position:relative;display:block}.et_pb_counter_amount{opacity:0;float:left;font-size:12px;font-weight:600;line-height:1.6em;text-align:right;padding:1px;display:block;min-height:6px;z-index:2;overflow:hidden}.et_pb_counter_amount.overlay{background-color:transparent!important;color:#2ea3f2;position:absolute!important;top:0;left:0;z-index:1;overflow:visible}.et_pb_counters span.et_pb_counter_amount_number{display:inline-block;padding:0 10px}.et_pb_counters span.et_pb_counter_amount_number:after,.et_pb_counters span.et_pb_counter_amount_number:before{content:"";display:block;max-width:20px;min-width:5px}.et_pb_counters.et_pb_section_video>li,.et_pb_counters>li.et_pb_section_video .et_pb_counter_amount{position:relative}.et_pb_counters li:last-of-type .et_pb_counter_container{margin-bottom:0}.et_pb_text_align_left .et_pb_counter_amount{text-align:left}.et_pb_text_align_center .et_pb_counter_amount{text-align:center}.et_pb_text_align_right .et_pb_counter_amount{text-align:right}.et_pb_text_align_justified .et_pb_counter_amount{text-align:justify}.et_pb_counters{list-style:none!important;padding:0!important;line-height:inherit!important}.et-animated li span .et_pb_counter_amount{opacity:1;animation:slideWidth 1s 1 cubic-bezier(.77,0,.175,1);position:relative}.et_pb_bg_layout_light_tablet .et_pb_counter_title{color:#666}.et_pb_bg_layout_dark_tablet .et_pb_counter_title{color:#fff}@keyframes slideWidth{0%{width:0}}@media (max-width:767px){.et_pb_text_align_left-tablet .et_pb_counter_amount{text-align:left}.et_pb_text_align_center-tablet .et_pb_counter_amount{text-align:center}.et_pb_text_align_right-tablet .et_pb_counter_amount{text-align:right}.et_pb_text_align_justified-tablet .et_pb_counter_amount{text-align:justify}}@media (min-width:768px) and (max-width:980px){.et_pb_bg_layout_light_phone .et_pb_counter_title{color:#666}.et_pb_bg_layout_dark_phone .et_pb_counter_title{color:#fff}.et_pb_text_align_left-phone .et_pb_counter_amount{text-align:left}.et_pb_text_align_center-phone .et_pb_counter_amount{text-align:center}.et_pb_text_align_right-phone .et_pb_counter_amount{text-align:right}.et_pb_text_align_justified-phone .et_pb_counter_amount{text-align:justify}}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_counter_title{word-wrap:break-word}.et-db #et-boc .et-l .et_pb_counter_amount{background-color:#2ea3f2}.et-db #et-boc .et-l .et_pb_counters .et_pb_counter_container{background-size:cover;background-position:50%;background-repeat:no-repeat}.et-db #et-boc .et-l .et_pb_with_border .et_pb_counter_container{border:0 solid #333}.et-db #et-boc .et-l .et_pb_counter_title{font-size:12px;line-height:1.6em;display:block}.et-db #et-boc .et-l .et_pb_bg_layout_light .et_pb_counter_title{color:#666}.et-db #et-boc .et-l .et_pb_counter_container{background-color:#ddd;color:#fff;margin-bottom:10px;overflow:hidden;position:relative;display:block}.et-db #et-boc .et-l .et_pb_counter_amount{opacity:0;float:left;font-size:12px;font-weight:600;line-height:1.6em;text-align:right;padding:1px;display:block;min-height:6px;z-index:2;overflow:hidden}.et-db #et-boc .et-l .et_pb_counter_amount.overlay{background-color:transparent!important;color:#2ea3f2;position:absolute!important;top:0;left:0;z-index:1;overflow:visible}.et-db #et-boc .et-l .et_pb_counters span.et_pb_counter_amount_number{display:inline-block;padding:0 10px}.et-db #et-boc .et-l .et_pb_counters span.et_pb_counter_amount_number:after,.et-db #et-boc .et-l .et_pb_counters span.et_pb_counter_amount_number:before{content:"";display:block;max-width:20px;min-width:5px}.et-db #et-boc .et-l .et_pb_counters.et_pb_section_video>li,.et-db #et-boc .et-l .et_pb_counters>li.et_pb_section_video .et_pb_counter_amount{position:relative}.et-db #et-boc .et-l .et_pb_counters li:last-of-type .et_pb_counter_container{margin-bottom:0}.et-db #et-boc .et-l .et_pb_text_align_left .et_pb_counter_amount{text-align:left}.et-db #et-boc .et-l .et_pb_text_align_center .et_pb_counter_amount{text-align:center}.et-db #et-boc .et-l .et_pb_text_align_right .et_pb_counter_amount{text-align:right}.et-db #et-boc .et-l .et_pb_text_align_justified .et_pb_counter_amount{text-align:justify}.et-db #et-boc .et-l .et_pb_counters{list-style:none!important;padding:0!important;line-height:inherit!important}.et-db #et-boc .et-l .et-animated li span .et_pb_counter_amount{opacity:1;animation:slideWidth 1s 1 cubic-bezier(.77,0,.175,1);position:relative}.et-db #et-boc .et-l .et_pb_bg_layout_light_tablet .et_pb_counter_title{color:#666}.et-db #et-boc .et-l .et_pb_bg_layout_dark_tablet .et_pb_counter_title{color:#fff}@keyframes slideWidth{0%{width:0}}@media (max-width:767px){.et-db #et-boc .et-l .et_pb_text_align_left-tablet .et_pb_counter_amount{text-align:left}.et-db #et-boc .et-l .et_pb_text_align_center-tablet .et_pb_counter_amount{text-align:center}.et-db #et-boc .et-l .et_pb_text_align_right-tablet .et_pb_counter_amount{text-align:right}.et-db #et-boc .et-l .et_pb_text_align_justified-tablet .et_pb_counter_amount{text-align:justify}}@media (min-width:768px) and (max-width:980px){.et-db #et-boc .et-l .et_pb_bg_layout_light_phone .et_pb_counter_title{color:#666}.et-db #et-boc .et-l .et_pb_bg_layout_dark_phone .et_pb_counter_title{color:#fff}.et-db #et-boc .et-l .et_pb_text_align_left-phone .et_pb_counter_amount{text-align:left}.et-db #et-boc .et-l .et_pb_text_align_center-phone .et_pb_counter_amount{text-align:center}.et-db #et-boc .et-l .et_pb_text_align_right-phone .et_pb_counter_amount{text-align:right}.et-db #et-boc .et-l .et_pb_text_align_justified-phone .et_pb_counter_amount{text-align:justify}}
|
@ -0,0 +1 @@
|
||||
.et_pb_bg_layout_light .et_pb_promo_button{color:#2ea3f2}.et-promo{background-color:#1f6581;padding:40px 0 25px}.et-promo-description{float:left;padding:0 60px;word-wrap:break-word;width:754px}.et-promo-description p{color:#fff}.et-promo-button{padding-right:60px;display:inline-block;font-weight:500;font-size:20px;color:#fff;background-color:rgba(0,0,0,.35);border-radius:5px;padding:14px 20px;margin-top:20px;float:left}.et_pb_promo{padding:40px 60px;text-align:center}.et_pb_promo_description{padding-bottom:20px;position:relative}.et_pb_promo_description p:last-of-type{padding-bottom:0}.et_pb_promo_button{display:inline-block;color:inherit}.et_pb_promo_button:hover{text-decoration:none}.et_pb_promo_button:hover:after{opacity:1;margin-left:0}.et_pb_column_1_2 .et_pb_promo,.et_pb_column_1_3 .et_pb_promo,.et_pb_column_1_4 .et_pb_promo,.et_pb_column_1_5 .et_pb_promo,.et_pb_column_1_6 .et_pb_promo,.et_pb_column_2_5 .et_pb_promo,.et_pb_column_3_5 .et_pb_promo{padding:40px}.et_pb_has_bg_hover.et_pb_promo:hover{padding:40px 60px!important;transition:padding .4s ease-in-out}.et_pb_column_1_2 .et_pb_has_bg_hover.et_pb_promo:hover,.et_pb_column_1_3 .et_pb_has_bg_hover.et_pb_promo:hover,.et_pb_column_1_4 .et_pb_has_bg_hover.et_pb_promo:hover,.et_pb_column_1_5 .et_pb_has_bg_hover.et_pb_promo:hover,.et_pb_column_1_6 .et_pb_has_bg_hover.et_pb_promo:hover,.et_pb_column_2_5 .et_pb_has_bg_hover.et_pb_promo:hover,.et_pb_column_3_5 .et_pb_has_bg_hover.et_pb_promo:hover{padding:40px!important}.et_pb_no_bg_hover.et_pb_promo:hover{padding:0!important}@media (max-width:980px){.et_pb_has_bg_tablet.et_pb_promo{padding:40px!important}.et_pb_no_bg_tablet.et_pb_promo{padding:0!important}.et_pb_bg_layout_light_tablet .et_pb_promo_button{color:#2ea3f2}.et_pb_bg_layout_dark_tablet .et_pb_promo_button{color:inherit}}@media (max-width:767px){.et_pb_promo{padding:40px}.et_pb_has_bg_phone.et_pb_promo{padding:40px!important}.et_pb_no_bg_phone.et_pb_promo{padding:0!important}.et_pb_bg_layout_light_phone .et_pb_promo_button{color:#2ea3f2}.et_pb_bg_layout_dark_phone .et_pb_promo_button{color:inherit}}@media (max-width:479px){.et_pb_promo{padding:40px}}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_bg_layout_light .et_pb_promo_button{color:#2ea3f2}.et-db #et-boc .et-l .et-promo{background-color:#1f6581;padding:40px 0 25px}.et-db #et-boc .et-l .et-promo-description{float:left;padding:0 60px;word-wrap:break-word;width:754px}.et-db #et-boc .et-l .et-promo-description p{color:#fff}.et-db #et-boc .et-l .et-promo-button{padding-right:60px;display:inline-block;font-weight:500;font-size:20px;color:#fff;background-color:rgba(0,0,0,.35);border-radius:5px;padding:14px 20px;margin-top:20px;float:left}.et-db #et-boc .et-l .et_pb_promo{padding:40px 60px;text-align:center}.et-db #et-boc .et-l .et_pb_promo_description{padding-bottom:20px;position:relative}.et-db #et-boc .et-l .et_pb_promo_description p:last-of-type{padding-bottom:0}.et-db #et-boc .et-l .et_pb_promo_button{display:inline-block;color:inherit}.et-db #et-boc .et-l .et_pb_promo_button:hover{text-decoration:none}.et-db #et-boc .et-l .et_pb_promo_button:hover:after{opacity:1;margin-left:0}.et-db #et-boc .et-l .et_pb_column_1_2 .et_pb_promo,.et-db #et-boc .et-l .et_pb_column_1_3 .et_pb_promo,.et-db #et-boc .et-l .et_pb_column_1_4 .et_pb_promo,.et-db #et-boc .et-l .et_pb_column_1_5 .et_pb_promo,.et-db #et-boc .et-l .et_pb_column_1_6 .et_pb_promo,.et-db #et-boc .et-l .et_pb_column_2_5 .et_pb_promo,.et-db #et-boc .et-l .et_pb_column_3_5 .et_pb_promo{padding:40px}.et-db #et-boc .et-l .et_pb_has_bg_hover.et_pb_promo:hover{padding:40px 60px!important;transition:padding .4s ease-in-out}.et-db #et-boc .et-l .et_pb_column_1_2 .et_pb_has_bg_hover.et_pb_promo:hover,.et-db #et-boc .et-l .et_pb_column_1_3 .et_pb_has_bg_hover.et_pb_promo:hover,.et-db #et-boc .et-l .et_pb_column_1_4 .et_pb_has_bg_hover.et_pb_promo:hover,.et-db #et-boc .et-l .et_pb_column_1_5 .et_pb_has_bg_hover.et_pb_promo:hover,.et-db #et-boc .et-l .et_pb_column_1_6 .et_pb_has_bg_hover.et_pb_promo:hover,.et-db #et-boc .et-l .et_pb_column_2_5 .et_pb_has_bg_hover.et_pb_promo:hover,.et-db #et-boc .et-l .et_pb_column_3_5 .et_pb_has_bg_hover.et_pb_promo:hover{padding:40px!important}.et-db #et-boc .et-l .et_pb_no_bg_hover.et_pb_promo:hover{padding:0!important}@media (max-width:980px){.et-db #et-boc .et-l .et_pb_has_bg_tablet.et_pb_promo{padding:40px!important}.et-db #et-boc .et-l .et_pb_no_bg_tablet.et_pb_promo{padding:0!important}.et-db #et-boc .et-l .et_pb_bg_layout_light_tablet .et_pb_promo_button{color:#2ea3f2}.et-db #et-boc .et-l .et_pb_bg_layout_dark_tablet .et_pb_promo_button{color:inherit}}@media (max-width:767px){.et-db #et-boc .et-l .et_pb_promo{padding:40px}.et-db #et-boc .et-l .et_pb_has_bg_phone.et_pb_promo{padding:40px!important}.et-db #et-boc .et-l .et_pb_no_bg_phone.et_pb_promo{padding:0!important}.et-db #et-boc .et-l .et_pb_bg_layout_light_phone .et_pb_promo_button{color:#2ea3f2}.et-db #et-boc .et-l .et_pb_bg_layout_dark_phone .et_pb_promo_button{color:inherit}}@media (max-width:479px){.et-db #et-boc .et-l .et_pb_promo{padding:40px}}
|
@ -0,0 +1 @@
|
||||
.et_pb_space{box-sizing:content-box;height:23px}.et_pb_divider_hidden{margin-bottom:0!important}.et_pb_divider_internal{display:inline-block;width:100%}.et_pb_divider{margin:0 0 30px;position:relative}.et_pb_divider:before{content:"";width:100%;height:1px;border-top-color:#eee;border-top-color:rgba(0,0,0,.1);border-top-width:1px;border-top-style:solid;position:absolute;left:0;top:0;z-index:10}.et_pb_divider:after,.et_pb_space:after{content:"";display:table}.et_pb_divider_position_bottom:before{top:auto!important;bottom:0!important}.et_pb_divider_position_center:before{top:50%!important}@media (max-width:980px){.et_pb_divider_position_top_tablet:before{top:0!important;bottom:auto!important}.et_pb_divider_position_bottom_tablet:before{top:auto!important;bottom:0!important}.et_pb_divider_position_center_tablet:before{top:50%!important}.et_pb_space.et-hide-mobile{display:none}}@media (max-width:767px){.et_pb_divider_position_top_phone:before{top:0!important;bottom:auto!important}.et_pb_divider_position_bottom_phone:before{top:auto!important;bottom:0!important}.et_pb_divider_position_center_phone:before{top:50%!important}}.ie .et_pb_divider{overflow:visible}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_space{box-sizing:content-box;height:23px}.et-db #et-boc .et-l .et_pb_divider_hidden{margin-bottom:0!important}.et-db #et-boc .et-l .et_pb_divider_internal{display:inline-block;width:100%}.et-db #et-boc .et-l .et_pb_divider{margin:0 0 30px;position:relative}.et-db #et-boc .et-l .et_pb_divider:before{content:"";width:100%;height:1px;border-top-color:#eee;border-top-color:rgba(0,0,0,.1);border-top-width:1px;border-top-style:solid;position:absolute;left:0;top:0;z-index:10}.et-db #et-boc .et-l .et_pb_divider:after,.et-db #et-boc .et-l .et_pb_space:after{content:"";display:table}.et-db #et-boc .et-l .et_pb_divider_position_bottom:before{top:auto!important;bottom:0!important}.et-db #et-boc .et-l .et_pb_divider_position_center:before{top:50%!important}@media (max-width:980px){.et-db #et-boc .et-l .et_pb_divider_position_top_tablet:before{top:0!important;bottom:auto!important}.et-db #et-boc .et-l .et_pb_divider_position_bottom_tablet:before{top:auto!important;bottom:0!important}.et-db #et-boc .et-l .et_pb_divider_position_center_tablet:before{top:50%!important}.et-db #et-boc .et-l .et_pb_space.et-hide-mobile{display:none}}@media (max-width:767px){.et-db #et-boc .et-l .et_pb_divider_position_top_phone:before{top:0!important;bottom:auto!important}.et-db #et-boc .et-l .et_pb_divider_position_bottom_phone:before{top:auto!important;bottom:0!important}.et-db #et-boc .et-l .et_pb_divider_position_center_phone:before{top:50%!important}}.ie .et_pb_divider{overflow:visible}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.et_pb_fullwidth_code.et_pb_module{z-index:9;position:relative}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_fullwidth_code.et_pb_module{z-index:9;position:relative}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.et_pb_fullwidth_image{position:relative;line-height:0}.et_pb_fullwidth_image img{width:100%;position:relative}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_fullwidth_image{position:relative;line-height:0}.et-db #et-boc .et-l .et_pb_fullwidth_image img{width:100%;position:relative}
|
@ -0,0 +1 @@
|
||||
.et_pb_fullwidth_section .et_pb_map_container{margin:0}
|
@ -0,0 +1 @@
|
||||
.et-db #et-boc .et-l .et_pb_fullwidth_section .et_pb_map_container{margin:0}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user