2024-05-06 11:04:37 +07:00

569 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace ElementorPro\Modules\QueryControl\Controls;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Base;
use ElementorPro\Core\Utils;
use ElementorPro\Modules\QueryControl\Module as Query_Module;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Group_Control_Query extends Group_Control_Base {
protected static $presets;
protected static $fields;
public static function get_type() {
return 'query-group';
}
protected function init_args( $args ) {
parent::init_args( $args );
$args = $this->get_args();
static::$fields = $this->init_fields_by_name( $args['name'] );
}
protected function init_fields() {
$args = $this->get_args();
return $this->init_fields_by_name( $args['name'] );
}
protected function get_fields_array( $name ) {
$fields = [];
$tab_keys = $this->get_tabs_keys( $name );
$name .= '_';
$fields['post_type'] = [
'label' => esc_html__( 'Source', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'by_id' => esc_html__( 'Manual Selection', 'elementor-pro' ),
'current_query' => esc_html__( 'Current Query', 'elementor-pro' ),
],
];
$fields['query_args'] = [
'type' => Controls_Manager::TABS,
];
$tabs_wrapper = $tab_keys['tabs_wrapper'];
$include_wrapper = $tab_keys['include_wrapper'];
$exclude_wrapper = $tab_keys['exclude_wrapper'];
$fields['query_include'] = [
'type' => Controls_Manager::TAB,
'label' => esc_html__( 'Include', 'elementor-pro' ),
'tabs_wrapper' => $tabs_wrapper,
'condition' => [
'post_type!' => [
'current_query',
'by_id',
],
],
];
$fields['posts_ids'] = [
'label' => esc_html__( 'Search & Select', 'elementor-pro' ),
'type' => Query_Module::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'multiple' => true,
'autocomplete' => [
'object' => Query_Module::QUERY_OBJECT_POST,
],
'condition' => [
'post_type' => 'by_id',
],
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $include_wrapper,
'export' => false,
];
$fields['include'] = [
'label' => esc_html__( 'Include By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT2,
'multiple' => true,
'options' => [
'terms' => esc_html__( 'Term', 'elementor-pro' ),
'authors' => esc_html__( 'Author', 'elementor-pro' ),
],
'condition' => [
'post_type!' => [
'by_id',
'current_query',
],
],
'label_block' => true,
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $include_wrapper,
];
$fields['include_term_ids'] = [
'label' => esc_html__( 'Term', 'elementor-pro' ),
'description' => esc_html__( 'Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'elementor-pro' ),
'type' => Query_Module::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'multiple' => true,
'autocomplete' => [
'object' => Query_Module::QUERY_OBJECT_CPT_TAX,
'display' => 'detailed',
],
'group_prefix' => $name,
'condition' => [
'include' => 'terms',
'post_type!' => [
'by_id',
'current_query',
],
],
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $include_wrapper,
];
$fields['include_authors'] = [
'label' => esc_html__( 'Author', 'elementor-pro' ),
'label_block' => true,
'type' => Query_Module::QUERY_CONTROL_ID,
'multiple' => true,
'default' => [],
'options' => [],
'autocomplete' => [
'object' => Query_Module::QUERY_OBJECT_AUTHOR,
],
'condition' => [
'include' => 'authors',
'post_type!' => [
'by_id',
'current_query',
],
],
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $include_wrapper,
'export' => false,
];
$fields['query_exclude'] = [
'type' => Controls_Manager::TAB,
'label' => esc_html__( 'Exclude', 'elementor-pro' ),
'tabs_wrapper' => $tabs_wrapper,
'condition' => [
'post_type!' => [
'by_id',
'current_query',
],
],
];
$fields['exclude'] = [
'label' => esc_html__( 'Exclude By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT2,
'multiple' => true,
'options' => [
'current_post' => esc_html__( 'Current Post', 'elementor-pro' ),
'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ),
'terms' => esc_html__( 'Term', 'elementor-pro' ),
'authors' => esc_html__( 'Author', 'elementor-pro' ),
],
'condition' => [
'post_type!' => [
'by_id',
'current_query',
],
],
'label_block' => true,
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $exclude_wrapper,
];
$fields['exclude_ids'] = [
'label' => esc_html__( 'Search & Select', 'elementor-pro' ),
'type' => Query_Module::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'multiple' => true,
'autocomplete' => [
'object' => Query_Module::QUERY_OBJECT_POST,
],
'condition' => [
'exclude' => 'manual_selection',
'post_type!' => [
'by_id',
'current_query',
],
],
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $exclude_wrapper,
'export' => false,
];
$fields['exclude_term_ids'] = [
'label' => esc_html__( 'Term', 'elementor-pro' ),
'type' => Query_Module::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'multiple' => true,
'autocomplete' => [
'object' => Query_Module::QUERY_OBJECT_CPT_TAX,
'display' => 'detailed',
],
'group_prefix' => $name,
'condition' => [
'exclude' => 'terms',
'post_type!' => [
'by_id',
'current_query',
],
],
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $exclude_wrapper,
'export' => false,
];
$fields['exclude_authors'] = [
'label' => esc_html__( 'Author', 'elementor-pro' ),
'type' => Query_Module::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'multiple' => true,
'autocomplete' => [
'object' => Query_Module::QUERY_OBJECT_AUTHOR,
'display' => 'detailed',
],
'condition' => [
'exclude' => 'authors',
'post_type!' => [
'by_id',
'current_query',
],
],
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $exclude_wrapper,
'export' => false,
];
$fields['avoid_duplicates'] = [
'label' => esc_html__( 'Avoid Duplicates', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => '',
'description' => esc_html__( 'Set to Yes to avoid duplicate posts from showing up. This only effects the frontend.', 'elementor-pro' ),
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $exclude_wrapper,
'condition' => [
'post_type!' => [
'by_id',
'current_query',
],
],
];
$fields['offset'] = [
'label' => esc_html__( 'Offset', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'default' => 0,
'condition' => [
'post_type!' => [
'by_id',
'current_query',
],
],
'description' => esc_html__( 'Use this setting to skip over posts (e.g. \'2\' to skip over 2 posts).', 'elementor-pro' ),
'tabs_wrapper' => $tabs_wrapper,
'inner_tab' => $exclude_wrapper,
];
$fields['select_date'] = [
'label' => esc_html__( 'Date', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'post_type' => '',
'options' => [
'anytime' => esc_html__( 'All', 'elementor-pro' ),
'today' => esc_html__( 'Past Day', 'elementor-pro' ),
'week' => esc_html__( 'Past Week', 'elementor-pro' ),
'month' => esc_html__( 'Past Month', 'elementor-pro' ),
'quarter' => esc_html__( 'Past Quarter', 'elementor-pro' ),
'year' => esc_html__( 'Past Year', 'elementor-pro' ),
'exact' => esc_html__( 'Custom', 'elementor-pro' ),
],
'default' => 'anytime',
'multiple' => false,
'condition' => [
'post_type!' => [
'by_id',
'current_query',
],
],
'separator' => 'before',
];
$fields['date_before'] = [
'label' => esc_html__( 'Before', 'elementor-pro' ),
'type' => Controls_Manager::DATE_TIME,
'post_type' => '',
'label_block' => false,
'multiple' => false,
'placeholder' => esc_html__( 'Choose', 'elementor-pro' ),
'condition' => [
'select_date' => 'exact',
'post_type!' => [
'by_id',
'current_query',
],
],
'description' => esc_html__( 'Setting a Before date will show all the posts published until the chosen date (inclusive).', 'elementor-pro' ),
];
$fields['date_after'] = [
'label' => esc_html__( 'After', 'elementor-pro' ),
'type' => Controls_Manager::DATE_TIME,
'post_type' => '',
'label_block' => false,
'multiple' => false,
'placeholder' => esc_html__( 'Choose', 'elementor-pro' ),
'condition' => [
'select_date' => 'exact',
'post_type!' => [
'by_id',
'current_query',
],
],
'description' => esc_html__( 'Setting an After date will show all the posts published since the chosen date (inclusive).', 'elementor-pro' ),
];
$fields['orderby'] = [
'label' => esc_html__( 'Order By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'post_date',
'options' => [
'post_date' => esc_html__( 'Date', 'elementor-pro' ),
'post_title' => esc_html__( 'Title', 'elementor-pro' ),
'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ),
'modified' => esc_html__( 'Last Modified', 'elementor-pro' ),
'comment_count' => esc_html__( 'Comment Count', 'elementor-pro' ),
'rand' => esc_html__( 'Random', 'elementor-pro' ),
],
'condition' => [
'post_type!' => 'current_query',
],
];
$fields['order'] = [
'label' => esc_html__( 'Order', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'desc',
'options' => [
'asc' => esc_html__( 'ASC', 'elementor-pro' ),
'desc' => esc_html__( 'DESC', 'elementor-pro' ),
],
'condition' => [
'post_type!' => 'current_query',
],
];
$fields['posts_per_page'] = [
'label' => esc_html__( 'Posts Per Page', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'default' => 3,
'condition' => [
'post_type!' => 'current_query',
],
];
$fields['ignore_sticky_posts'] = [
'label' => esc_html__( 'Ignore Sticky Posts', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => 'yes',
'condition' => [
'post_type' => 'post',
],
'description' => esc_html__( 'Sticky-posts ordering is visible on frontend only', 'elementor-pro' ),
];
$fields['query_id'] = [
'label' => esc_html__( 'Query ID', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => '',
'ai' => [
'active' => false,
],
'description' => esc_html__( 'Give your Query a custom unique id to allow server side filtering', 'elementor-pro' ),
'separator' => 'before',
'dynamic' => [
'active' => true,
],
];
return $fields;
}
/**
* Build the group-controls array
* Note: this method completely overrides any settings done in Group_Control_Posts
* @param string $name
*
* @return array
*/
protected function init_fields_by_name( $name ) {
$fields = $this->get_fields_array( $name );
static::init_presets();
return $fields;
}
/**
* Presets: filter controls subsets to be be used by the specific Group_Control_Query instance.
*
* Possible values:
* 'full' : (default) all presets
* 'include' : the 'include' tab - by id, by taxonomy, by author
* 'exclude': the 'exclude' tab - by id, by taxonomy, by author
* 'advanced_exclude': extend the 'exclude' preset with 'avoid-duplicates' & 'offset'
* 'date': date query controls
* 'pagination': posts per-page
* 'order': sort & ordering controls
* 'query_id': allow saving a specific query for future usage.
*
* Usage:
* full: build a Group_Controls_Query with all possible controls,
* when 'full' is passed, the Group_Controls_Query will ignore all other preset values.
* $this->add_group_control(
* Group_Control_Query::get_type(),
* [
* ...
* 'presets' => [ 'full' ],
* ...
* ] );
*
* Subset: build a Group_Controls_Query with subset of the controls,
* in the following example, the Query controls will set only the 'include' & 'date' query args.
* $this->add_group_control(
* Group_Control_Query::get_type(),
* [
* ...
* 'presets' => [ 'include', 'date' ],
* ...
* ] );
*/
protected static function init_presets() {
$tabs = [
'query_args',
'query_include',
'query_exclude',
];
static::$presets['include'] = array_merge( $tabs, [
'include',
'include_ids',
'include_term_ids',
'include_authors',
] );
static::$presets['exclude'] = array_merge( $tabs, [
'exclude',
'exclude_ids',
'exclude_term_ids',
'exclude_authors',
] );
static::$presets['advanced_exclude'] = array_merge( static::$presets['exclude'], [
'avoid_duplicates',
'offset',
] );
static::$presets['date'] = [
'select_date',
'date_before',
'date_after',
];
static::$presets['pagination'] = [
'posts_per_page',
'ignore_sticky_posts',
];
static::$presets['order'] = [
'orderby',
'order',
];
static::$presets['query_id'] = [
'query_id',
];
}
private function filter_by_presets( $presets, $fields ) {
if ( in_array( 'full', $presets, true ) ) {
return $fields;
}
$control_ids = [];
foreach ( static::$presets as $key => $preset ) {
$control_ids = array_merge( $control_ids, $preset );
}
foreach ( $presets as $preset ) {
if ( array_key_exists( $preset, static::$presets ) ) {
$control_ids = array_diff( $control_ids, static::$presets[ $preset ] );
}
}
foreach ( $control_ids as $remove ) {
unset( $fields[ $remove ] );
}
return $fields;
}
protected function prepare_fields( $fields ) {
$args = $this->get_args();
if ( ! empty( $args['presets'] ) ) {
$fields = $this->filter_by_presets( $args['presets'], $fields );
}
$post_type_args = [];
if ( ! empty( $args['post_type'] ) ) {
$post_type_args['post_type'] = $args['post_type'];
}
$post_types = Utils::get_public_post_types( $post_type_args );
$fields['post_type']['options'] = array_merge( $post_types, $fields['post_type']['options'] );
$fields['post_type']['default'] = key( $post_types );
$fields['posts_ids']['object_type'] = array_keys( $post_types );
//skip parent, go directly to grandparent
return Group_Control_Base::prepare_fields( $fields );
}
protected function get_child_default_args() {
$args = parent::get_child_default_args();
$args['presets'] = [ 'full' ];
return $args;
}
protected function get_default_options() {
return [
'popover' => false,
];
}
protected function get_tabs_keys( $name ) {
return [
'tabs_wrapper' => $name . '_query_args',
'include_wrapper' => $name . '_query_include',
'exclude_wrapper' => $name . '_query_exclude',
];
}
}