Сравнение meta_query в аргументах get_posts

13 нояб. 2014 г., 13:04:26
Просмотры: 33.7K
Голосов: 12

Я хочу исключить определенные записи с пользовательским полем. То есть если my_custom_field_ignore установлено И равно 1 - игнорировать эту запись. Если не установлено - включить её.

Вот что у меня есть:

    $args = array(
        'post_type' => $post_type,
        'offset' => $offset,
        'meta_query' => array(
            array(
                'key' => 'my_custom_field_ignore',
                'value' => '1',
                'compare' => '!=',
            )
        )
    );

Это работает только для записей, где my_custom_field_ignore установлено в значение, отличное от 1

Как мне включить все записи (конечно, кроме тех, где my_custom_field_ignore = 1)?

Редактирование:

Вот как это работает в WP 3.5+

    'meta_query' => array(
        array(
            'key' => 'my_custom_field_ignore',
            'compare' => 'NOT EXISTS',
        )
    )

Это просто ищет наличие my_custom_field_ignore, поэтому значение будет игнорироваться. Хотя это могло бы работать изначально, пользователи могут запутаться, когда они изменят 1 на 0 и ожидают, что запись будет включена.

Похоже, что версии 3.3 и 3.4 требуют некоторой условной проверки.

Редактирование 2

Похоже, что отмеченный ответ решает проблему (по крайней мере для 3.5+). По какой-то странной причине игнорируется самая первая запись "Hello World". После добавления my_custom_field_ignore и последующего его удаления всё работает

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

Если мы определим условия:

A: my_custom_field_ignore СУЩЕСТВУЕТ
B: my_custom_field_ignore = 1

тогда NOT ( A && B ) эквивалентно:

NOT ( A ) || NOT ( B )

что в нашем случае означает:

( my_custom_field_ignore НЕ СУЩЕСТВУЕТ ) ||  ( my_custom_field_ignore != 1 ) 

Поэтому мы можем попробовать следующий код для WP 3.5+ (не тестировалось):

 $args = array(
    'post_type'  => $post_type,
    'offset'     => $offset,
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'my_custom_field_ignore',
            'value'   => '1',
            'compare' => '!=',
        ),
        array(
            'key'     => 'my_custom_field_ignore',
            'compare' => 'NOT EXISTS',
            'value'   => '1',     #<-- просто какое-то значение как исправление бага для версий до 3.9 (Codex)
        ),
    )
);
13 нояб. 2014 г. 13:19:08
Комментарии

Спасибо, я проверю, но должно работать с версии 3.3+

Xaver Xaver
13 нояб. 2014 г. 13:20:12

Я обновил ответ, NOT EXISTS поддерживается только для WP 3.5+ согласно Codex.

birgire birgire
13 нояб. 2014 г. 13:24:34

извините, это не работает с версии 3.3 до 4.0

Xaver Xaver
13 нояб. 2014 г. 14:39:53

Я только что протестировал это на чистой установке WP 4.0, где это работает как ожидалось. Каков ваш вывод? Как выглядит SQL-запрос в вашем случае?

birgire birgire
13 нояб. 2014 г. 15:05:07

http://pastebin.com/bLSHErMH а у вас? (У меня также 'numberposts => 1', но думаю, это не имеет значения)

Xaver Xaver
13 нояб. 2014 г. 15:15:13

да, я получил такой же SQL-запрос, за исключением лимита. У вас есть лишние пробелы в значениях метаполей? Вы вообще не получаете результат? Ваш тип записи правильный? Вы тестируете это в WP 4.0?

birgire birgire
13 нояб. 2014 г. 15:31:16

нет, я передаю аргументы в функцию get_posts. Я проведу несколько тестов и сообщу вам о результатах. Спасибо вам пока что!

Xaver Xaver
13 нояб. 2014 г. 16:01:41

Я обновил свои вопросы с возможным решением, но у него есть некоторые недостатки

Xaver Xaver
13 нояб. 2014 г. 16:17:50

Странно, я не уверен, почему у вас не работает. Убедитесь, что ваши сохранённые мета-значения не содержат лишних пробелов. На моей чистой установке WP 4.0 я создал 10 записей. Затем я обновил 3 из них, добавив произвольное поле my_custom_field_ignore: двум присвоил значение 1, а одной - 0. Затем я выполнил указанный запрос с posts_per_page=10 и получил 8 записей в результате. Записи со значением произвольного поля равным 1 были исключены, как и ожидалось.

birgire birgire
13 нояб. 2014 г. 18:58:08

хорошо, я проверю это еще раз - возможно

Xaver Xaver
13 нояб. 2014 г. 20:01:56

Запись, которая не отображалась, была записью "Hello World". Все работает нормально, если я добавляю my_custom_field_ignore к этой записи и затем удаляю его. Странная ситуация, однако.

Xaver Xaver
13 нояб. 2014 г. 20:31:12

это странно, но рад слышать, что у тебя все заработало ;-)

birgire birgire
13 нояб. 2014 г. 21:15:09
Показать остальные 7 комментариев
0

необходимо использовать функцию serialize, если вы работаете с целыми числами:

$args = array(
    'meta_query' => array(
        array(
            'key' => 'my_meta_key',
            'value' => serialize(strval($my_vale)),
            'compare' => 'LIKE'
        )
    )
);
$posts = get_posts( $args );

и готово,

print_r($posts); 

чтобы увидеть результаты

15 июл. 2015 г. 16:51:55