Сравнение meta_query в аргументах get_posts
Я хочу исключить определенные записи с пользовательским полем. То есть если 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
и последующего его удаления всё работает

Если мы определим условия:
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)
),
)
);

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

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

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

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

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

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

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

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

необходимо использовать функцию 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);
чтобы увидеть результаты
