WP_Query не работает как ожидалось для вложений и пользовательского meta_query

15 мая 2012 г., 15:56:20
Просмотры: 3.08K
Голосов: 2

Если я использую get_posts() следующим образом, я получаю несколько результатов со значением 1 для метаполя my_key:

$posts = get_posts( 
    array( 
        'post_type'  => 'attachment', 
        'meta_key'   => 'my_key', 
        'meta_value' => '1' 
    ) 
);

//это возвращает несколько результатов, как и ожидалось
print_r($posts);

Однако если я создаю аналогичный запрос с помощью WP_Query, я получаю пустой массив результатов

$args = array(
   'post_type' => 'attachment',
   'meta_query' => array(
       array(
       'key'     => 'my_key',
       'value'   => '1',
       'compare' => '=',
       'type'    => 'BINARY'
      )
   )
);

$query = new WP_Query();
$results = $query->query($args);
//это возвращает пустой массив
print_r($results);

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

8
Комментарии

Вы забыли ' после value в своем коде, или это опечатка специфичная для WPSE?

mor7ifer mor7ifer
15 мая 2012 г. 15:59:13

Нет, но спасибо, я недоумевал, почему код не форматировался.

Mike Mike
15 мая 2012 г. 16:04:37

Что будет, если полностью убрать compare и type?

mor7ifer mor7ifer
15 мая 2012 г. 16:06:40

следую за @m0r7if3r: что произойдет, если изменить BINARY на NUMERIC?

moraleida moraleida
15 мая 2012 г. 16:09:07

Удаление compare и type не меняет результат... Numeric тоже не подходит

Mike Mike
15 мая 2012 г. 16:12:10

Если сделать print_r() созданного экземпляра WP_Query, это покажет точный SQL-запрос, который формируется, и даст представление о том, что нужно исправить в запросе.

EAMann EAMann
16 мая 2012 г. 17:01:15

Не уверен, откуда взялись минусы, это вполне законный вопрос (который, честно говоря, поставил меня в тупик, пока я не загрузил Debug Bar Console и не покопался в самом экземпляре WP_Query). Постарайтесь не принимать -1 на свой счет...

EAMann EAMann
16 мая 2012 г. 20:30:46

Спасибо. Ничего личного, просто немного странно видеть, как здесь все казалось довольно цивильным. Ну да ладно. Я посмотрел на объект WP_Query, но все еще был в тупике. Было бы интересно понять логику использования 'inherit' для опубликованных вложений...

Mike Mike
16 мая 2012 г. 21:00:59
Показать остальные 3 комментариев
Все ответы на вопрос 2
3
12

Во-первых, просто передайте свои аргументы в конструктор WP_Query, так как это более чисто и соответствует документации Codex для этого класса.

Вы должны создавать запросы следующим образом:

$my_key_query_args = array(
   'post_type'   => 'attachment', // Тип записи - вложение
   'post_status' => 'inherit',    // Статус записи - наследуемый
   'meta_query'  => array(        // Мета-запрос
       array(
           'key'     => 'my_key', // Ключ метаполя
           'value'   => '1',      // Значение для сравнения
           'compare' => '=',      // Оператор сравнения
           'type'    => 'BINARY'  // Тип сравнения
      )
   )
);

$my_key_query = new WP_Query( $my_key_query_args );

Во-вторых, обратите внимание на добавленный параметр post_status в моем массиве. По умолчанию вложения добавляются со статусом "inherit", но WP_Query ищет записи со статусом "published", "draft" или "pending". (См. также документацию по этому параметру).

Таким образом, здесь нет ошибки, мы просто забыли проверить значения по умолчанию для всех параметров, передаваемых в объект.

В документации для параметра post_type со значением "attachment" есть примечание, которое указывает на это требование:

По умолчанию WP_Query устанавливает 'post_status'=>'published', но для вложений по умолчанию используется 'post_status'=>'inherit', поэтому вам нужно установить статус в 'inherit' или 'any'.

15 мая 2012 г. 18:50:04
Комментарии

Смотрите мое обновление. Этот обновленный код протестирован и работает.

EAMann EAMann
16 мая 2012 г. 17:00:17

разве post_status не должен быть publish?

Mike Mike
16 мая 2012 г. 18:00:32

Значение по умолчанию - publish, но посмотрите в вашей базе данных, статус поста для вложений - "inherit".

EAMann EAMann
16 мая 2012 г. 18:17:10
2

Я думаю, ваша проблема в том, что вы пытаетесь использовать WP_Query как get_posts(). Вполне возможно, что запрос работает, но вы просто не видите результаты. WP_Query возвращает объект запроса, который нужно перебирать в цикле следующим образом:

...
$my_query = WP_Query( $args );
while( $my_query->have_posts() ) : $my_query->the_post();

// делайте что вам нужно

endwhile;

Также обратите внимание, что я использовал $my_query. Я не совсем уверен в этом, но кажется, что $query может быть зарезервированной переменной в WordPress, и в любом случае лучше делать запрос более читаемым (например, $attachment_meta_query или что-то подобное).

15 мая 2012 г. 17:50:50
Комментарии

Спасибо, но ваш код по сути такой же, как и мой. Вы просто используете сокращенный вариант. Так что это не решает проблему. Я действительно думаю, что у нас может быть баг.

Mike Mike
15 мая 2012 г. 18:18:40

Это не сокращение, а правильный синтаксис для вызова new WP_Query(). Передавайте массив $args напрямую в WP_Query(). Также: я настоятельно рекомендую использовать более описательные имена переменных, чтобы избежать конфликтов именования.

Chip Bennett Chip Bennett
15 мая 2012 г. 19:45:14