meta_query с несколькими значениями
Мне нужна ваша помощь.
Вот моя проблема: у меня есть произвольный тип записи "Игрок". У этого CPT есть произвольное поле "Сезоны". Сезоны могут содержать несколько значений, разделенных запятой - например "2014,2015,2016" и т.д.
Теперь мне нужно отфильтровать список игроков, которые играли в определенные сезоны - например 2015 и 2016.
И сейчас мне нужна помощь с этим wp_query
. Я пробовал этот код, но он не работает :-/
query_posts(
array(
'post_type' => 'player',
'meta_query' => array(
array(
'key' => 'seasons',
'value' => array( '2015','2016'),
'compare' => 'IN',
),
),
)
);
Пожалуйста, помогите.
Спасибо,
libor

Расширяя ответ от @dgarceran:
Как правило, использование класса WP_Query
- это хорошая идея для запросов к записям.
Нам нужно передать аргументы в этот запрос.
В вашем случае, вероятно, стоит использовать один из следующих вариантов:
- "Параметры произвольных полей" -
meta_query
- "Параметры таксономий" -
tax_query
Для почти полного примера всех вариантов мне нравится ссылаться на этот gist: https://gist.github.com/luetkemj/2023628.
Также см. Кодекс: https://codex.wordpress.org/Class_Reference/WP_Query
Оба принимают массив ассоциативных массивов, например:
Примечание: Я буду использовать синтаксис, совместимый с PHP 5.4+
$meta_query_args = [
[
'key' => 'season',
'value' => [ '2015', '2016' ],
'compare' => 'IN',
],
];
Мы можем включить эти аргументы в наш экземпляр WP_Query
$args = [
'post_type' => 'player',
'posts_per_page' => 100, // Установите разумный лимит
'meta_query' => $meta_query_args,
];
$the_query = new WP_Query( $args );
Что происходит в этот момент: WordPress проверит все записи, соответствующие вашему пользовательскому типу записи player
. Затем он запросит метаданные, которые вы установили с ключом season
. Будут возвращены любые записи, соответствующие 2015
или 2016
.
Примечание: использование meta_query
таким образом обычно не рекомендуется, потому что это создает нагрузку на базу данных. Общее мнение заключается в том, что запросы к таксономиям более производительны (не цитируйте меня, не могу найти источник).
В качестве быстрой альтернативы я рекомендую следующий пример:
$tax_query_args = [
[
'taxonomy' => 'season',
'field' => 'slug',
'terms' => [ '2015', '2016' ],
'operator' => 'IN',
],
];
$args = [
'post_type' => 'player',
'posts_per_page' => 100, // Установите разумный лимит
'tax_query' => $tax_query_args,
];
$the_query = new WP_Query( $args );
Теперь мы можем пройтись по данным в цикле, вот пример разметки:
<section class="season-list">
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
$post_id = get_the_ID();
// $season = get_post_meta( $post_id, 'season', true ); // пример, если вы все еще используете метаданные
$season = wp_get_object_terms( $post_id, 'season', [ 'fields' => 'names' ] );
?>
<h3><?php the_title(); ?></h3>
<p><?php echo __( 'Сезон: ' ) . sanitize_text_field( implode( $season ) ); ?></p>
<?php endwhile; ?>
</section>
Когда вы используете WP_Query
, особенно в шаблонах, убедитесь, что завершаете вызовом wp_reset_postdata();
Собираем все вместе (tl;dr)
$tax_query_args = [
[
'taxonomy' => 'season',
'field' => 'slug',
'terms' => [ '2015', '2016' ],
'operator' => 'IN',
],
];
$args = [
'post_type' => 'player',
'posts_per_page' => 100, // Установите разумный лимит
'tax_query' => $tax_query_args,
];
$the_query = new WP_Query( $args );
?>
<section class="season-list">
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
$post_id = get_the_ID();
// $season = get_post_meta( $post_id, 'season', true ); // пример, если вы все еще используете метаданные
$season = wp_get_object_terms( $post_id, 'season', [ 'fields' => 'names' ] );
?>
<h3><?php the_title(); ?></h3>
<p><?php echo __( 'Сезон: ' ) . sanitize_text_field( implode( $season ) ); ?></p>
<?php endwhile; ?>
</section>
<?php
wp_reset_postdata();
Вид на фронтенде нашего запроса:
Вид записей типа Player в админке:
Надеюсь, это немного проясняет ситуацию

Вот как я бы сделал это с использованием Цикла WordPress и примеров из Кодекса.
$args = array(
'post_type' => 'player',
'meta_key' => 'age',
'meta_query' => array(
array(
'key' => 'seasons',
'value' => array( 2015, 2016 ), // или array( '2015', '2016' )
'compare' => 'IN',
),
),
);
// Запрос
$query = new WP_Query( $args );
// Цикл
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
// делаем что-то
}
} else {
// записи не найдены
}
// Восстанавливаем оригинальные данные поста
wp_reset_postdata();
Ваша проблема в том, что вы добавляете значения в одной строке типа "2015,2016,2017"... а вам следует разделять каждое значение в отдельное поле. С помощью ACF у вас есть возможность добавить повторяющееся поле для сезонов, а также можно создать пользовательскую таксономию для хранения этих значений вместо произвольных полей. Если вы не хотите это менять, вам следует сначала получить метаданные поста с помощью get_post_meta, а затем использовать explode в PHP.
