meta_query по ключу и значению из массива

19 мая 2016 г., 12:29:32
Просмотры: 21.5K
Голосов: 3

У меня есть произвольный тип записи 'game' с несколькими ACF полями. Одно из полей - это Post Object (называется review_link), которое принимает записи из категории 'reviews'. Другое поле - это поле таксономии (называется gametags), связанное с таксономией post_tag для 'posts'.

Вот что я пытаюсь достичь:

  1. Когда вы читаете запись (post_type=post) в категории Reviews, добавить в сайдбар информацию из Game (post_type=game), у которой эта конкретная запись указана в поле Post Object.

  2. Когда вы читаете запись (post_type=post) из любой категории, получить теги этой записи и искать в полях ACF Games (post_type=game), конкретно в поле таксономии, любые совпадающие теги, а затем показывать информацию об игре.

Мой код для случая 1 работает отлично:

$reviewID = $post->ID;
if(in_category('reviews') ) {

    $reviewArgs = array(
      'post_type'    => 'game',
      'meta_query' => array(
         array(
           'key' => 'review_link',
           'value' => ''.$reviewID.'',
           'compare' => 'LIKE'
         )
       )
    );

}

Теперь для случая 2 я попробовал следующее:

$tag_ids = wp_get_post_tags( $post->ID, array( 'fields' => 'ids' ) );

$reviewArgs = array(
   'post_type' => 'game',
   'meta_query' => array(
         array(
             'key' => 'gametags',
             'value' => $tag_ids,
             'compare' => 'IN'
         )
    ) 
);

Значения $tag_ids для примера записи: 818,436,435,43,46,77. Если я заменяю $tag_ids в коде выше на 435, это работает. Но если я пытаюсь добавить его как массив - не работает. Я также пробовал сериализовать массив, перебирать его и т.д. Ничего не работает. Я мог бы создать массив meta_queries, но проблема в том, что количество тегов в каждой записи случайное. Я также пробовал преобразовать массив в строку и использовать 'LIKE' вместо 'IN', но безрезультатно.

Фактически, приведенный выше код выдает предупреждение: Warning: trim() expects parameter 1 to be string, array given in /.../public_html/wp-includes/class-wp-meta-query.php on line 594

Я перепробовал почти все, чтобы заставить случай 2 работать, но не смог. Как я понимаю, meta_query не работает должным образом, когда значение meta является массивом, хотя в Codex указано, что это может быть массив. Весь приведенный выше код находится в sidebar.php.

Буду благодарен за любые подсказки

Заранее спасибо

0
Все ответы на вопрос 2
10

Не уверен, можно ли напрямую сравнить один массив с другим, но можно создать цикл для формирования массива meta_query, который будет проверять каждый ID в поле отдельно:

$tag_ids = wp_get_post_tags( $post->ID, array( 'fields' => 'ids' ) );

$meta_query = array('relation' => 'OR');

foreach ($tags_ids as $tag_id) {
    $meta_query[] = array(
        'key' => 'gametags',
        'value' => $tag_id,
        'compare' => 'IN'
    );
}

$reviewArgs = array(
   'post_type' => 'game',
   'meta_query' => $meta_query
);

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

РЕДАКТИРОВАНИЕ: попробуйте этот вариант для проверки точных совпадений позже...

$review_query = new WP_Query( $reviewArgs ); 
while( $review_query->have_posts() ) { 
    $review_query->the_post(); 
    global $post; $checkmatch = false;
    $gametags = get_post_meta($post->ID,'gametags');
    if (!is_array($gametags)) {$gametags = explode(',',$gametags);}
    foreach ($tags_ids as $tag_id) {
        if (in_array($tag_id,$gametags)) {$checkmatch = true;}
    }
    if ($checkmatch) {
         // вывод данных
    }
}
19 мая 2016 г. 13:12:04
Комментарии

Спасибо большое! Такой способ работает!

Есть ли способ сделать сравнение более точным? Потому что IN возвращает и '152', и '1524'?

Pantso Pantso
19 мая 2016 г. 14:05:56

Попробуйте использовать = или EQUALS вместо IN, если вам нужно точное совпадение

majick majick
19 мая 2016 г. 14:09:26

Подождите, нет, вы уверены? Разве LIKE не подойдет лучше, чем IN?

majick majick
19 мая 2016 г. 14:12:16

Да, прямо сейчас на живом примере, если я использую IN, он получает '14739' и '14885'! LIKE и = не работают! Хм, может быть проблема в моей логике? В любом случае, спасибо за ваше время :)

Pantso Pantso
19 мая 2016 г. 14:18:39

извините, моя ошибка, IN действительно должен подходить, но вы передаёте gametags как массив или строку? это может иметь значение, потому что 152 есть в строке 1524, но нет в array('1525'), если вы понимаете, о чём я.

majick majick
19 мая 2016 г. 14:19:28

вот пример массива $tag_ids:

Array ( [0] => 818 [1] => 436 [2] => 435 [3] => 43 [4] => 46 [5] => 77 )

Я пробовал изменить 'value' => '"'. $tag_id .'"', но это тоже не сработало :P

Pantso Pantso
19 мая 2016 г. 14:21:58

нет, я понимаю, что это массив $tag_ids, но как устанавливается метаполе gametags - как массив или как строка? т.е. если выполнить get_post_meta($post->ID,'gametags'); для вашего примера, что вы получите?

majick majick
19 мая 2016 г. 14:25:05

На самом деле пустой массив. Хм, что за чертовщина. В любом случае, я сам разберусь дальше, не хочу вас больше беспокоить

Pantso Pantso
19 мая 2016 г. 14:29:51

:-) не переживайте, попробуйте дополнительный код, который я добавил, чтобы перепроверить совпадения после выполнения.

majick majick
19 мая 2016 г. 14:40:50

Если твой путь приведёт тебя в Грецию, я должен тебе пиво! :) Ещё раз спасибо

Pantso Pantso
19 мая 2016 г. 14:43:30
Показать остальные 5 комментариев
1

Поскольку $tag_ids = wp_get_post_tags( $post->ID, array( 'fields' => 'ids' ) ); возвращает массив, вы можете использовать его следующим образом:

$reviewArgs = array(
   'post_type' => 'game',
   'meta_query' => array(
         array(
             'key' => 'gametags',
             'value' => $tag_ids,
             'compare' => 'IN'
         )
    ) 
);

У вас есть метаполя gametags для типа записей games? Также вы используете WP_Query или get_posts()?

19 мая 2016 г. 13:45:41
Комментарии

Да, остальная часть кода:

$review_query = new WP_Query( $reviewArgs ); while( $review_query->have_posts() ) { $review_query->the_post();

Pantso Pantso
19 мая 2016 г. 14:04:24