version 4.13.0

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

View File

@ -0,0 +1,156 @@
<?php
/**
* Provide utilities to interact and replace the current post akin to setup_postdata()
* but in a stacking manner.
*
* @since 4.0
*/
class ET_Post_Stack {
/**
* Post override stack.
*
* @var (WP_Post|null)[]
*/
protected static $stack = array();
/**
* Get the top post from the stack or the current one if the stack is empty.
*
* @since 4.0
*
* @param integer $offset Offset from the end of the array, 0 being the last post. Use negative integers.
*
* @return WP_Post|null
*/
public static function get( $offset = 0 ) {
global $post;
$index = count( self::$stack ) - 1 + $offset;
if ( empty( self::$stack ) && 0 === $index ) {
return $post;
}
return isset( self::$stack[ $index ] ) ? self::$stack[ $index ] : null;
}
/**
* Pop the top post off of the stack.
*
* @since 4.0
*
* @return void
*/
public static function pop() {
array_pop( self::$stack );
}
/**
* Setup a post as the global $post.
*
* @since 4.0
*
* @param WP_Post|null $with
* @param boolean $force
*
* @return void
*/
protected static function setup( $with, $force = false ) {
global $post;
if ( $force || ! ( $with && $post && $with->ID === $post->ID ) ) {
$post = $with;
setup_postdata( $post );
}
}
/**
* Equivalent to setup_postdata() but keeps a stack of posts so it can be nested.
* Pushes the specified post on the stack.
*
* @since 4.0
*
* @param WP_Post $with
*
* @return void
*/
public static function replace( $with ) {
global $post;
$force = empty( self::$stack );
if ( empty( self::$stack ) ) {
// Add the current post as the first in the stack even if it does not exist.
self::$stack[] = $post;
}
self::$stack[] = $with;
self::setup( $with, $force );
}
/**
* Restores the last post from the stack.
* The final restore will setup the post that was setup when the stack was last empty.
*
* @since 4.0
*
* @return void
*/
public static function restore() {
self::pop();
self::reset();
}
/**
* Resets the post to the one at the top of the stack.
*
* @since 4.0
*
* @return void
*/
public static function reset() {
if ( ! empty( self::$stack ) ) {
self::setup( self::get() );
}
}
/**
* Returns the $post for the current true WordPress query post ignoring any posts that may be
* forced using setup_postdata().
*
* @since 4.0
*
* @return WP_Post|null
*/
public static function get_main_post() {
global $wp_query;
if ( ! $wp_query || 0 === $wp_query->post_count ) {
// Handle special case where there is no current post but once the_content()
// gets called the global $post is polluted and will no longer reset to null.
return null;
}
if ( empty( $wp_query->post ) ) {
return null;
}
return $wp_query->post;
}
/**
* Returns the post ID for the current true WordPress query post.
* See ::get_main_post() for more information.
*
* @since 4.0
*
* @return integer
*/
public static function get_main_post_id() {
$post = self::get_main_post();
return $post ? (int) $post->ID : 0;
}
}

View File

@ -0,0 +1,79 @@
<?php
class ET_Builder_Post_Query_Layouts extends ET_Core_Post_Query {
/**
* Whether or not to automatically exclude product tour layouts from the results.
*
* @since 3.0.99
* @var bool
*/
protected $_exclude_product_tour = true;
/**
* @inheritDoc
*/
protected function _add_tax_query( $tax_name, $args, $negate = null ) {
$args = self::$_->array_flatten( $args );
$negate = $this->_reset_negate();
if ( ! $args ) {
return $this;
}
parent::_add_tax_query( $tax_name, $args, $negate );
return $this;
}
public function in_pack() {
$args = func_get_args();
return $this->with_tag( $args );
}
public function is_fullwidth() {
$tax_name = ET_Builder_Post_Taxonomy_LayoutWidth::instance()->name;
return $this->_add_tax_query( $tax_name, array( 'fullwidth' ) );
}
public function is_type() {
$tax_name = ET_Builder_Post_Taxonomy_LayoutType::instance()->name;
$args = func_get_args();
return $this->_add_tax_query( $tax_name, $args );
}
/**
* @inheritDoc
*/
public function run( $args = array() ) {
$exclude_product_tour = apply_filters( 'et_builder_layout_query_exclude_product_tour', $this->_exclude_product_tour );
if ( $exclude_product_tour ) {
$this->not()->with_meta( '_et_pb_layout_applicability', 'product_tour' );
}
return parent::run( $args );
}
/**
* @inheritDoc
*/
public function with_meta( $key, $value = null ) {
if ( '_et_pb_layout_applicability' === $key && 'product_tour' === $value ) {
$this->_exclude_product_tour = false;
}
return parent::with_meta( $key, $value );
}
public function with_scope() {
$tax_name = ET_Builder_Post_Taxonomy_LayoutScope::instance()->name;
$args = func_get_args();
return $this->_add_tax_query( $tax_name, $args );
}
}

View File

@ -0,0 +1,54 @@
<?php
class ET_Builder_Post_Taxonomy_LayoutCategory extends ET_Core_Post_Taxonomy {
/**
* @inheritDoc
*/
protected $_owner = 'builder';
/**
* @inheritDoc
*/
public $name = 'layout_category';
/**
* @inheritDoc
*/
protected function _get_args() {
return array(
'hierarchical' => true,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'show_in_nav_menus' => false,
'publicly_queryable' => ET_Builder_Post_Type_Layout::is_publicly_queryable(),
);
}
/**
* @inheritDoc
*/
protected function _get_labels() {
return array();
}
/**
* Get the class instance.
*
* @since 3.0.99
*
* @param string $type See {@see self::$wp_type} for accepted values. Default is 'taxonomy'.
* @param string $name The name/slug of the post object. Default is {@see self::$name}.
*
* @return self|null
*/
public static function instance( $type = 'taxonomy', $name = 'layout_category' ) {
if ( ! $instance = parent::instance( $type, $name ) ) {
$instance = new self();
}
return $instance;
}
}

View File

@ -0,0 +1,70 @@
<?php
class ET_Builder_Post_Taxonomy_LayoutPack extends ET_Core_Post_Taxonomy {
/**
* @inheritDoc
*/
protected $_owner = 'builder';
/**
* @inheritDoc
*/
public $name = 'layout_pack';
/**
* @inheritDoc
*/
protected function _get_args() {
return array(
'hierarchical' => false,
'show_ui' => false,
'show_admin_column' => false,
'query_var' => true,
'show_in_nav_menus' => false,
'publicly_queryable' => ET_Builder_Post_Type_Layout::is_publicly_queryable(),
);
}
/**
* @inheritDoc
*/
protected function _get_labels() {
return array(
'add_new' => esc_html_x( 'Add New', 'Layout Pack', 'et_builder' ),
'add_new_item' => esc_html__( 'Add New Layout Pack', 'et_builder' ),
'all_items' => esc_html__( 'All Layout Packs', 'et_builder' ),
'choose_from_most_used' => esc_html__( 'Choose from the most used layout packs', 'et_builder' ),
'edit_item' => esc_html__( 'Edit Layout Pack', 'et_builder' ),
'name' => esc_html__( 'Packs', 'et_builder' ),
'new_item' => esc_html__( 'New Layout Pack', 'et_builder' ),
'new_item_name' => esc_html__( 'New Layout Pack Name', 'et_builder' ),
'no_terms' => esc_html__( 'No layout packs', 'et_builder' ),
'not_found' => esc_html__( 'No layout packs found', 'et_builder' ),
'search_items' => esc_html__( 'Search Layout Packs', 'et_builder' ),
'separate_items_with_commas' => esc_html__( 'Separate layout packs with commas', 'et_builder' ),
'singular_name' => esc_html__( 'Layout Pack', 'et_builder' ),
'update_item' => esc_html__( 'Update Layout Pack', 'et_builder' ),
'view_item' => esc_html__( 'View Layout Pack', 'et_builder' ),
);
}
/**
* Get the class instance.
*
* @since 3.0.99
*
* @param string $type See {@see self::$wp_type} for accepted values. Default is 'taxonomy'.
* @param string $name The name/slug of the post object. Default is {@see self::$name}.
*
* @return self|null
*/
public static function instance( $type = 'taxonomy', $name = 'layout_pack' ) {
if ( ! $instance = parent::instance( $type, $name ) ) {
$instance = new self();
}
return $instance;
}
}

View File

@ -0,0 +1,56 @@
<?php
class ET_Builder_Post_Taxonomy_LayoutScope extends ET_Core_Post_Taxonomy {
/**
* @inheritDoc
*/
protected $_owner = 'builder';
/**
* @inheritDoc
*/
public $name = 'scope';
/**
* @inheritDoc
*/
protected function _get_args() {
return array(
'hierarchical' => false,
'show_ui' => false,
'show_admin_column' => false,
'query_var' => true,
'show_in_nav_menus' => false,
'publicly_queryable' => ET_Builder_Post_Type_Layout::is_publicly_queryable(),
);
}
/**
* @inheritDoc
*/
protected function _get_labels() {
return array(
'name' => esc_html__( 'Scope', 'et_builder' ),
);
}
/**
* Get the class instance.
*
* @since 3.0.99
*
* @param string $type See {@see self::$wp_type} for accepted values. Default is 'taxonomy'.
* @param string $name The name/slug of the post object. Default is {@see self::$name}.
*
* @return self|null
*/
public static function instance( $type = 'taxonomy', $name = 'scope' ) {
if ( ! $instance = parent::instance( $type, $name ) ) {
$instance = new self();
}
return $instance;
}
}

View File

@ -0,0 +1,56 @@
<?php
class ET_Builder_Post_Taxonomy_LayoutType extends ET_Core_Post_Taxonomy {
/**
* @inheritDoc
*/
protected $_owner = 'builder';
/**
* @inheritDoc
*/
public $name = 'layout_type';
/**
* @inheritDoc
*/
protected function _get_args() {
return array(
'hierarchical' => false,
'show_ui' => false,
'show_admin_column' => true,
'query_var' => true,
'show_in_nav_menus' => false,
'publicly_queryable' => ET_Builder_Post_Type_Layout::is_publicly_queryable(),
);
}
/**
* @inheritDoc
*/
protected function _get_labels() {
return array(
'name' => esc_html__( 'Type', 'et_builder' ),
);
}
/**
* Get the class instance.
*
* @since 3.0.99
*
* @param string $type See {@see self::$wp_type} for accepted values. Default is 'taxonomy'.
* @param string $name The name/slug of the post object. Default is {@see self::$name}.
*
* @return self|null
*/
public static function instance( $type = 'taxonomy', $name = 'layout_type' ) {
if ( ! $instance = parent::instance( $type, $name ) ) {
$instance = new self();
}
return $instance;
}
}

View File

@ -0,0 +1,56 @@
<?php
class ET_Builder_Post_Taxonomy_LayoutWidth extends ET_Core_Post_Taxonomy {
/**
* @inheritDoc
*/
protected $_owner = 'builder';
/**
* @inheritDoc
*/
public $name = 'module_width';
/**
* @inheritDoc
*/
protected function _get_args() {
return array(
'hierarchical' => false,
'show_ui' => false,
'show_admin_column' => false,
'query_var' => true,
'show_in_nav_menus' => false,
'publicly_queryable' => ET_Builder_Post_Type_Layout::is_publicly_queryable(),
);
}
/**
* @inheritDoc
*/
protected function _get_labels() {
return array(
'name' => esc_html__( 'Module Width', 'et_builder' ),
);
}
/**
* Get the class instance.
*
* @since 3.0.99
*
* @param string $type See {@see self::$wp_type} for accepted values. Default is 'taxonomy'.
* @param string $name The name/slug of the post object. Default is {@see self::$name}.
*
* @return self|null
*/
public static function instance( $type = 'taxonomy', $name = 'module_width' ) {
if ( ! $instance = parent::instance( $type, $name ) ) {
$instance = new self();
}
return $instance;
}
}

View File

@ -0,0 +1,235 @@
<?php
if ( ! defined( 'ET_BUILDER_LAYOUT_POST_TYPE' ) ) {
define( 'ET_BUILDER_LAYOUT_POST_TYPE', 'et_pb_layout' );
}
require_once ET_BUILDER_DIR . 'post/query/Layouts.php';
class ET_Builder_Post_Type_Layout extends ET_Core_Post_Type {
/**
* @inheritDoc
*/
protected $_category_tax = 'layout_category';
/**
* @inheritDoc
*/
protected $_owner = 'builder';
/**
* @inheritDoc
*/
protected $_tag_tax = 'layout_pack';
/**
* @inheritDoc
*/
public $name = ET_BUILDER_LAYOUT_POST_TYPE;
/**
* ET_Builder_Post_Type_Layout constructor.
*/
public function __construct() {
parent::__construct();
add_action( "add_meta_boxes_{$this->name}", array( $this, 'wp_hook_add_meta_boxes' ) );
add_action( "manage_{$this->name}_posts_custom_column", array( $this, 'wp_hook_manage_posts_custom_column' ), 10, 2 );
add_filter( "manage_{$this->name}_posts_columns", array( $this, 'wp_hook_manage_posts_columns' ) );
}
/**
* @inheritDoc
*/
protected function _before_register() {
/**
* Filters {@see register_post_type()} args for the et_pb_layout post type.
*
* @deprecated Use {@see 'et_core_cpt_et_pb_layout_args'} instead.
*
* @since 3.1 Deprecated. See {@see 'et_core_cpt_et_pb_layout_args'}.
* @since 1.0
*
* @param $args
*/
$this->_args = apply_filters( 'et_pb_layout_args', $this->_args );
}
/**
* @inheritDoc
*/
protected function _get_args() {
return array(
'can_export' => true,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => false,
'map_meta_cap' => true,
'public' => false,
'publicly_queryable' => self::is_publicly_queryable(),
'query_var' => false,
'show_in_menu' => false,
'show_ui' => true,
'supports' => array(
'editor',
'excerpt',
'revisions',
'thumbnail',
'title',
),
'taxonomies' => array(
'layout_category',
'layout_pack',
'layout_type',
'module_width',
'scope',
),
);
}
/**
* @inheritDoc
*/
protected function _get_labels() {
return array(
'add_new' => esc_html_x( 'Add New', 'Layout', 'et_builder' ),
'add_new_item' => esc_html__( 'Add New Layout', 'et_builder' ),
'all_items' => esc_html__( 'All Layouts', 'et_builder' ),
'edit_item' => esc_html__( 'Edit Layout', 'et_builder' ),
'name' => esc_html__( 'Layouts', 'et_builder' ),
'new_item' => esc_html__( 'New Layout', 'et_builder' ),
'not_found' => esc_html__( 'Nothing found', 'et_builder' ),
'not_found_in_trash' => esc_html__( 'Nothing found in Trash', 'et_builder' ),
'parent_item_colon' => '',
'search_items' => esc_html__( 'Search Layouts', 'et_builder' ),
'singular_name' => et_builder_i18n( 'Layout' ),
'view_item' => esc_html__( 'View Layout', 'et_builder' ),
);
}
/**
* Get the class instance.
*
* @since 3.0.99
*
* @param string $type See {@see self::$wp_type} for accepted values. Default is 'cpt'.
* @param string $name The name/slug of the post object. Default is {@see self::$name}.
*
* @return self|null
*/
public static function instance( $type = 'cpt', $name = 'et_pb_layout' ) {
if ( ! $instance = parent::instance( $type, $name ) ) {
$instance = new self();
}
return $instance;
}
/**
* Whether or not a layout is global.
*
* @param $post_id
*
* @return bool
*/
public function is_global( $post_id ) {
$tax_name = ET_Builder_Post_Taxonomy_LayoutScope::instance()->name;
if ( $terms = get_the_terms( $post_id, $tax_name ) ) {
foreach ( $terms as $term ) {
if ( 'global' === $term->name ) {
return true;
}
}
}
return false;
}
/**
* Determines if the Library's CPT and taxonomies should be publicly queryable for the current request.
*
* @sine ??
*
* @return bool
*/
public static function is_publicly_queryable() {
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
$get = $_GET;
$actions = array(
'et_fb_update_builder_assets',
'et_fb_retrieve_builder_data',
);
$is_ajax = isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], $actions );
$is_VB = ( '1' === self::$_->array_get( $get, 'et_fb' ) || $is_ajax ) && et_pb_is_allowed( 'use_visual_builder' );
// phpcs:enable
$is_wpcli = defined( 'WP_CLI' ) && WP_CLI;
$has_preview = ! $is_VB && ! is_null( self::$_->array_get( $get, 'et_pb_preview', null ) );
$is_preview = $has_preview && et_core_security_check_passed( '', 'et_pb_preview_nonce', '', '_GET' );
return $is_VB || $is_preview || $is_wpcli;
}
/**
* @return ET_Builder_Post_Query_Layouts
*/
public function query() {
return new ET_Builder_Post_Query_Layouts( $this->name, $this->_category_tax, $this->_tag_tax );
}
/**
* Moves the excerpt meta box into the side column for this post type.
* {@see 'add_meta_boxes_{$type}'}
*
* @since 3.0.99
*/
public function wp_hook_add_meta_boxes() {
remove_meta_box( 'postexcerpt', null, 'normal' );
add_meta_box( 'postexcerpt', __( 'Description' ), 'post_excerpt_meta_box', null, 'side', 'default' );
}
/**
* Adds custom columns to the Divi Library admin page.
* {@see 'manage_{$post_type}_posts_columns'}
*
* @since 3.1 Relocated from `builder/layouts.php`.
* @since 2.5.7
*/
public function wp_hook_manage_posts_columns( $columns ) {
$_new_columns = array();
foreach ( $columns as $column_key => $column ) {
$_new_columns[ $column_key ] = $column;
if ( 'taxonomy-layout_type' === $column_key ) {
$_new_columns['layout_global'] = esc_html__( 'Global', 'et_builder' );
}
}
return $_new_columns;
}
/**
* Sets the content of our custom columns for each row on the Divi Library admin page.
* {@see 'manage_posts_custom_column'}
*
* @since 3.1 Relocated from `builder/layouts.php`.
* @since 2.5.7
*/
public function wp_hook_manage_posts_custom_column( $column_key, $post_id ) {
switch ( $column_key ) {
case 'layout_global':
if ( $this->is_global( $post_id ) ) {
echo '<span class="et-builder-library__icon--global" aria-label="Global"/>';
} else {
echo '<span aria-label="Not Global"/>';
}
break;
}
}
}