Próbuję wyświetlić wszystkie nieruchomości do wynajęcia, najpierw wszystkie nieruchomości, które nie zostały wynajęte, a następnie wszystkie nieruchomości, które są obecnie wynajmowane. Istnieje niestandardowy typ posta „czynsz” z niestandardowym meta postem dla wynajmowanej ceny (_price_rented), który jest polem wyboru (zwraca wartość prawda lub fałsz ... prawda, jeśli został WYNAJMOWANY). Muszę zmienić zapytanie, aby wyświetlić wszystkie właściwości z dostępnymi (niewynajętymi) właściwościami pojawiającymi się najpierw, a następnie z wynajętymi właściwościami.
Oto moje zapytanie:
$ts_properties = new WP_Query(
array(
'post_type' => 'rent',
'paged' => $paged,
'posts_per_page' => -1,
'meta_key' => '_price_rented',
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => '_price_rented',
'value' => false,
'type' => 'BOOLEAN',
),
)
)
);
Z jakiegoś powodu to zapytanie pokazuje wszystkie właściwości, które zostały wynajęte. Gdy zmienię wartość z „false” na „true” w meta_query, nie wyświetla żadnych właściwości.
Pomyślałem więc, że zwracana wartość to false (dla nieruchomości, które są wynajmowane) lub NULL (dla nieruchomości, które NIE są wynajmowane), ale nie jestem pewien, jak zapytać o wynik NULL (nie fałsz), dodałem „ porównaj argument z meta_query i ustaw wartość na „! =”, ale to też nie zadziałało.
EDYCJA: var_dump zwraca następujące dane dla dostępnego, nie wynajętego mieszkania: string(0) ""
oraz dla niedostępnego, wynajętego mieszkania:string(1) "1"
źródło
_price_rented
właściwie ustawiony dla obutrue
ifalse
wartości, czy jest to tylko ustawionytrue
? Proszę sprawdzić bazę danych. Zapytałem, ponieważ niezaznaczone pole wyboru w ogóle nie zostało przekazane,POST
więc zastanawiam się, czy wartość jest w ogóle ustawiona dla tych przypadków.Odpowiedzi:
WP_Meta_Query
jest w pewnym sensie „niezbyt stabilną” częścią rdzenia i jeśli nie poświęcisz zbyt wiele uwagi, może łatwo oderwać się od pomieszania.Kiedy wykonujesz a
new WP_Query()
i maszmeta_query => array()
argumenty lub ich ekwiwalent pojedynczej pary klucz / wartość, wtedynew WP_Meta_Query()
wskakujesz, natychmiast następuje parsowanie.Dozwolone wartości
Gdy przeszukujesz metadane, istnieje
bool
opcja. A jeśli go użyjesz, wróci do tegoCHAR
, do czego domyślna wartość jako tablica dozwolonych wartości to:gdzie
NUMERIC
zostanie zresetowany doSIGNED
.Debugowanie
Istnieje wiele filtrów, które mogą wpływać na proces zapisu po zapisaniu, więc pierwszą rzeczą do zrobienia jest sprawdzenie różnych wartości w pewnej pętli:
Następnie, w zależności od wartości zwracanej, będziesz musiał użyć
SIGNED
, jeśli wynikiem jest0
lub1
,"true"
lub"false"
jeśli wynikiem jest ciąg. Jeśli to naprawdę boolean, to nadal sugerowałbym, aby użyć,string
aby upewnić się, że przechodzi$GLOBALS['wpdb']
, który może przepuszczać tylko%s
ciąg znaków i%d
cyfrę.Dodatkowe uwagi
Jak już aktualizowany wpis Codexu
WP_Meta_Query
dzisiaj, widziałem, że są tam wiele różnych wyjść (dodając liczne ilości niepotrzebnychJOINS
, które są omawiane na Tractutaji tutaj zzewnątrzjednym plastrze przeniesiona do rdzenia) możliwych. (Kontynuacja bilet naAND
części tutaj ) Chodzi o to, że jest możliwe, aby użyć kombinacjimeta_*
argumentów obok tejmeta_query
tablicy i jej subarrays. Wynik jest prawie nieznany, chyba że go zrzucisz , więc IMHO lepiej jest użyć jednego lub drugiego sposobu dodawania danych wejściowych. Zwłaszcza gdy jesteś tylkoprzy użyciumeta_key
, ponieważ w niektórych przypadkach powoduje to „zapytanie tylko z kluczem”.Rozwiązanie
Jak wskazano w komentarzach:
Teraz
meta_query
musi użyćJeśli chcesz uzyskać „niedostępne, wynajmowane apartamenty” lub użyć,
'!='
aby odzyskać „nie wynajmowane” apartamenty.Uwaga: Możliwe wartości
meta_compare
to'=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'
lub'RLIKE'
. Wartość domyślna to'='
.źródło
I w obliczu tego samego problemu i po godzinie poszukiwań znaleźli
"NOT EXISTS"
i"EXISTS"
wartości( only in WP >= 3.5 )
. Nie musisz więc pytać o wartość meta, po prostu sprawdź, czy istnieje meta_key:Działa dla mnie idealnie.
źródło
Więcej szczegółów:
Występują tutaj dwa problemy z reprezentacją danych: jeden z nich, które wartości danych są używane do przedstawienia wartości prawda / fałsz, a drugi to, czy pole jest w ogóle przechowywane, czy jest to wartość domyślna (zazwyczaj fałsz).
Część 1: Spojrzałem na SQL wygenerowany przez
WP_Meta_Query
dla porównań na prawdę i fałsz, i stwierdziłem, że dla prawdy zastępuje „1” i fałsz ”(pusty ciąg znaków). Więc cokolwiek napiszesz do bazy danych, musi się z tym zgodzić, jeśli będziesz robił zapytania w porównaniu do rzeczywistych wartości prawdziwych i fałszywych. W szczególności nie chcesz pisać „0” dla fałszu. Zamiast tego może być bardziej niezawodny pisać i testować na 0 i 1 (i robi to wielu konstruktorów formularzy). Sprawdź jednak, co jest zapisywane w bazie danych i miej to na uwadze podczas tworzenia zapytania.Część 2: Zakładając, że fałsz jest wartością domyślną, znalezienie rekordów, których wartością jest prawda, jest łatwe:
... 'meta_key' => 'my_key', 'meta_value' => 1
(lub prawda)Ale druga strona stanowi wyzwanie: może istnieć fałszywa wartość lub może nie być żadnej wartości. Może się tak zdarzyć, jeśli wartość została wymieniona jako opcjonalna w formularzu --- wówczas, dopóki użytkownik nie ustawi jej wprost ani nie zmieni, nie zostanie dodana do bazy danych. Zauważ, że jeśli tylko
get_post_meta
go używasz , będzie dobrze działać w ten sposób: zwracanie fałszywej wartości i zwracanie żadnej wartości nie spowoduje tego samego.Ale kiedy używasz
WP_Query
, nie jest to takie proste. (A jeśli tak, to nie wiem, jak to zrobić).Masz dwie (a może trzy) opcje:
Upewnij się, że pole jest zawsze jawnie inicjowane na rzeczywistą wartość. W niektórych konstruktorach formularzy można to zrobić, wprowadzając wymagane pole i nadając mu wartość domyślną. Następnie możesz
...'meta_value' => 0
rzetelnie przetestować .Wykonaj dwa zapytania, pierwsze, które sprawdza pod kątem fałszywej wartości, a drugie, które sprawdza pod kątem braku wartości. Można je połączyć w jeden WP_Query, taki jak ten:
To prawdopodobnie nie jest wydajne zapytanie. W zależności od wielu czynników lepszym rozwiązaniem może być zwrócenie wszystkich obiektów i przefiltrowanie ich we własnym kodzie.
W takim przypadku pojedyncze
'NOT EXISTS'
zapytanie niezawodnie zwróci prawidłowe obiekty. (Nie sądzę, aby wiele konstruktorów formularzy lub wtyczek obsługiwało to zachowanie, więc użyłbym go tylko w kodzie czysto niestandardowym).źródło