Использование meta_query: как фильтровать по одному произвольному полю и сортировать по другому?

17 июн. 2011 г., 07:29:41
Просмотры: 34.7K
Голосов: 10

При использовании следующего кода (в functions.php) мои записи (пользовательского типа event) сортируются по _end_date вместо _start_date. Какое правильное решение для WP 3.1.3? Конечно, хотелось бы избежать использования устаревшего meta_key.

add_filter( 'pre_get_posts', 'my_get_posts' );
function my_get_posts( $query ) {
if ( is_home() ) {
  $query->set( 'post_type', 'event' );
  $query->set( 'meta_key', '_start_date' );
  $query->set( 'orderby', 'meta_value_num' );
  $query->set( 'order', 'ASC' );
  $query->set( 'meta_query', array(
                                   array(
                                         'key' => '_end_date',
                                         'value' => time(),
                                         'compare' => '>=', // Больше или равно
                                         'type' => 'numeric' // Числовой тип
                                        )
                                   )
                              );
  }
  return $query;
}
0
Все ответы на вопрос 1
0
15

Похоже, это баг в WordPress. WordPress фактически изменяет meta_query, если вы указываете orderby и meta_key в параметрах запроса. Обычно это изменение добавляет новый meta_key в качестве первого элемента массива meta_query, и поэтому orderby применяется к первому meta_key, указанному в meta_query.

Но когда вы изменяете orderby, meta_key и meta_value в фильтре pre_get_posts, из-за (как мне кажется) бага в WordPress новый массив добавляется в существующий meta_query, но не вставляется первым элементом — он добавляется в конец существующего meta_query. А orderby всегда применяется к первому meta_key в meta_query.

В качестве временного решения, пока баг не исправлен, вы можете явно указать meta_key в meta_query в качестве первого элемента массива, как в следующем примере:

add_filter( 'pre_get_posts', 'my_get_posts' );
function my_get_posts( $query ) {
if ( is_home() ) {
  $query->set( 'post_type', 'event' );
  $query->set( 'meta_key', '_start_date' );
  $query->set( 'orderby', 'meta_value_num' );
  $query->set( 'order', 'ASC' );
  $query->set( 'meta_query', array(
        array(
              'key' => '_start_date'
        ),
        array(
              'key' => '_end_date',
              'value' => time(),
              'compare' => '>=',
              'type' => 'numeric'
        )
  ));
  }
  return $query;
}
17 июн. 2011 г. 13:07:34