Является ли «orderby» в WP Meta Query противоречащим Meta Query?

Я пытаюсь написать мета-запрос, который ищет либо события, начинающиеся в следующем году (event_start_date между 52 и 52 неделями), либо события, которые все еще происходят (event_end_date между теперь и 52 неделями), а затем сортирует их вместе через event_start_date в один запрос, чтобы сделать список хронологических событий.

Мой код успешно запрашивает оба и возвращает результаты, но не сортирует их вместе. Они отображаются в следующем порядке:

12 сентября
13 сентября
18 сентября
11-13 сентября (дата окончания)
20 сентября
27 сентября
25 сентября
26 сентября
20 сентября
19 сентября

Вот мой код:

$date_1 = date('Ymd', strtotime("now")); $date_2 = date('Ymd', strtotime("52 weeks")); $args = array( 'post_type' => 'event', 'order' => 'ASC', 'meta_key' => 'event_start_date', 'posts_per_page' => 10, 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'event_start_date', 'value' => array( $date_1, $date_2 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), array( 'key' => 'event_end_date', 'value' => array( $date_1, $date_2 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), ), 'orderby' => 'meta_value_num' ); $wp_query = new WP_Query( $args ); while( $wp_query->have_posts() ) { $wp_query->the_post(); } 

Стандартный запрос WordPress засасывает с несколькими мета-запросами, когда orderby установлен в мета-ключ.

После многих головных болей и потерянного времени я написал специальный класс, который позволяет мне лучше справляться с такими вещами. Здесь есть упрощенная версия моего класса, но она будет работать для ваших целей:

 class EventQuery { private $args; private $order; private $query; static function query( Array $args, \WP_Query $query = NULL ) { if ( is_null( $query ) ) { $query = new \WP_Query; } $class = __CLASS__; $eventquery = new $class( $args, $query ); return $eventquery->enable()->run()->disable()->getQuery(); } function __construct( Array $args, \WP_Query $query ) { $this->args = $args; $this->order = isset( $args['order'] ) && strtoupper( $args['order'] === 'DESC' ) ? 'DESC' : 'ASC'; $this->query = $query; } function enable() { add_filter( 'posts_fields_request', array( $this, 'filterFiels' ) ); add_filter( 'posts_join_request', array( $this, 'filterJoin' ) ); add_filter( 'posts_where_request', array( $this, 'filterWhere' ) ); add_filter( 'posts_orderby_request', array( $this, 'filterOrder' ) ); return $this; } function disable() { remove_filter( 'posts_fields_request', array( $this, 'filterFiels' ) ); remove_filter( 'posts_join_request', array( $this, 'filterJoin' ) ); remove_filter( 'posts_where_request', array( $this, 'filterWhere' ) ); remove_filter( 'posts_orderby_request', array( $this, 'filterOrder' ) ); return $this; } function filterFiels( $sql ) { return $sql . ", metastartdate.meta_value as start_date"; } function filterJoin( $sql ) { global $wpdb; return $sql . " INNER JOIN {$wpdb->postmeta} AS metastartdate ON ({$wpdb->posts}.ID = metastartdate.post_id)"; } function filterWhere( $sql ) { return $sql . " AND metastartdate.meta_key = 'event_start_date'"; } function filterOrder( $sql ) { return "start_date {$this->order}"; } function run() { $this->query->query( $this->args ); return $this; } function getQuery() { return $this->query; } } 

Его можно использовать так:

 $args = array ( 'post_type' => 'post', 'posts_per_page' => 10, 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'event_start_date', 'value' => array( $date_1, $date_2 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), array( 'key' => 'event_end_date', 'value' => array( $date_1, $date_2 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), ), 'orderby' => 'custom', // <-- NOTE THIS 'order' => 'ASC' // <-- AND THIS ); $query = EventQuery::query( $args ); // return a WP_Query if ( $query->have_posts( ) ) { // loop here } 

Конечно, вы можете использовать «DESC» для заказа по дате начала.