Metaabfrage mit booleschem True / False-Wert

11

Ich versuche, alle Mietobjekte anzuzeigen, zuerst nach allen Objekten, die nicht vermietet wurden, und dann nach allen Objekten, die derzeit vermietet sind. Es gibt einen benutzerdefinierten Beitragstyp 'rent' mit benutzerdefiniertem Beitrags-Meta für den gemieteten Preis (_price_rented), der ein Kontrollkästchen darstellt (gibt entweder true oder false zurück ... true, wenn er gemietet wurde). Ich muss die Abfrage ändern, um alle Immobilien anzuzeigen, wobei zuerst die verfügbaren (nicht vermieteten) Eigenschaften und dann die gemieteten Eigenschaften angezeigt werden.

Hier ist meine Frage:

$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',
        ),
    ) 
) 
);

Aus irgendeinem Grund zeigt diese Abfrage alle Immobilien, die gemietet wurden. Wenn ich den Wert in der meta_query von 'false' auf 'true' ändere, werden keine Eigenschaften angezeigt.

Also dachte ich, der Rückgabewert ist entweder falsch (für Immobilien, die vermietet sind) oder NULL (für Immobilien, die NICHT vermietet sind), aber ich bin nicht sicher, wie ich nach einem NULL-Ergebnis fragen soll (nicht falsch). Ich fügte ein 'hinzu Vergleichen Sie das Argument mit der meta_query und setzen Sie den Wert auf '! =', aber das hat auch nicht funktioniert.

BEARBEITEN: var_dump gibt Folgendes für eine verfügbare, nicht gemietete Wohnung zurück: string(0) ""und für eine nicht verfügbare, gemietete Wohnung:string(1) "1"

Kegan Quimby
quelle
vielleicht mit den Werten 1 und 0?
Reikyoushin
meta_query type => string. Mögliche Werte sind 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. Der Standardwert ist 'CHAR'.
iEmanuele
@reikyoushin: Wenn Sie eine '1' verwenden, werden alle gemieteten Immobilien zurückgegeben, und eine '0' gibt keine Immobilien zurück.
Kegan Quimby
1
@iEmanuele: Änderungen, die keine Wirkung zu haben scheinen (ich dachte das Gleiche). Ich habe das aus diesem Artikel gesehen: thethemefoundry.com/blog/…
Kegan Quimby
1
Ist _price_rentedtatsächlich für beide trueund falseWerte festgelegt, oder ist es nur für festgelegt true? Überprüfen Sie bitte die Datenbank. Ich habe gefragt, weil ein deaktiviertes Kontrollkästchen überhaupt nicht durchlaufen wird POST, und ich frage mich, ob der Wert für diese Fälle überhaupt festgelegt ist.
s_ha_dum

Antworten:

4

WP_Meta_Query ist ein irgendwie "nicht so stabiler" Teil im Kern und wenn Sie nicht sehr viel Aufmerksamkeit schenken, kann es leicht aus der Verwirrung heraus brechen.

Wenn Sie a ausführen new WP_Query()und meta_query => array()Argumente oder deren einzelne Schlüssel / Wert-Paar-Äquivalente haben new WP_Meta_Query(), springen Sie ein und folgen sofort dem Parsen.

$this->meta_query = new WP_Meta_Query();
$this->meta_query->parse_query_vars( $q );

Zulässige Werte

Wenn Sie Metadaten abfragen, gibt es eine boolOption. Und wenn Sie es verwenden würden, würde es auf Folgendes zurückgreifen. CHARDer Standardwert als Array zulässiger Werte lautet:

'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'

wo NUMERICwird zurückgesetzt SIGNED.

Debuggen

Es gibt zahlreiche Filter, die sich auf den Post-Save-Prozess auswirken können. Überprüfen Sie daher zunächst die verschiedenen Werte in einer Schleife:

var_dump( get_post_meta( get_the_ID(), '_price_rented', true ) );

Abhängig vom Rückgabewert müssen Sie dann entweder verwenden SIGNED, ob das Ergebnis 0oder 1ist "true"oder "false"ob das Ergebnis eine Zeichenfolge ist. Wenn es wirklich boolesch ist, würde ich immer noch empfehlen, es stringnur zu verwenden, um sicherzustellen, dass es durchläuft $GLOBALS['wpdb'], was nur %sZeichenfolge und %dZiffer durchlassen kann .

Zusätzliche Bemerkungen

Wie ich gerade aktualisiert die Codex - Eintrag fürWP_Meta_Query heute, sah ich , dass es sind viele verschiedene Ausgänge (zahlreiche Mengen an nicht benötigten Zugabe JOINS, die auf diskutiert Trac hier und hier mit aus einem einzigen Patch zog in Kern) möglich. (Follow - up - Ticket für ANDTeile hier ) Punkt ist , dass es ist möglich , eine Kombination zu verwenden meta_*Argumente neben dem meta_queryArray und seinen Sub - Arrays. Das Ergebnis ist so gut wie unbekannt, es sei denn, Sie sichern es. Meiner Meinung nach ist es besser, entweder die eine oder die andere Art des Hinzufügens von Eingaben zu verwenden. Besonders wenn du nur bistVerwenden meta_key, da dies in einigen Fällen zu einer "Nur-Schlüssel-Abfrage" führt.

Lösung

Wie in den Kommentaren ausgeführt:

(...) var_dumpgibt Folgendes für eine verfügbare, nicht gemietete Wohnung zurück: string(0) ""und für eine nicht verfügbare, gemietete Wohnung:string(1) "1"

Jetzt meta_querymuss das verwendet werden

'meta_query' => array( 'relation' => 'OR', array(
    'meta_key'     => '_price_rented',
    'meta_value'   => '1',
    'meta_compare' => '='
) );

Wenn Sie die "nicht verfügbaren, gemieteten Wohnungen" erhalten oder '!='zum Abrufen der "nicht vermieteten" Wohnungen verwenden möchten .

Hinweis: Mögliche Werte für meta_comparesind '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'oder 'RLIKE'. Standardwert ist '='.

Kaiser
quelle
3

Ich hatte das gleiche Problem und fand nach einer Stunde Suche den "NOT EXISTS"und "EXISTS"Wert ( only in WP >= 3.5 ). Sie müssen also nicht nach einem Metawert fragen, sondern müssen nur prüfen, ob der meta_key vorhanden ist:

'meta_key'     =>   '_price_rented'  ,
'meta_compare' =>   'NOT EXISTS'     ,

Es funktioniert perfekt für mich.

Thibaut
quelle
3

TL; DR: Dieses Problem tritt wahrscheinlich meistens auf, wenn ein boolesches Feld als optional erstellt wird. Sie können das Problem beheben, indem Sie es erforderlich machen oder eine komplexere Abfrage verwenden, um den Standardfall abzurufen.

Mehr Details:

Hier treten zwei Probleme mit der Datendarstellung auf: Zum einen werden die Datenwerte verwendet, um wahr / falsch darzustellen, und zum anderen wird angegeben, ob das Feld überhaupt gespeichert wird oder nicht, wenn es sich um den Standardwert (normalerweise falsch) handelt.

Teil 1: Ich habe mir das SQL angesehen, das von WP_Meta_Queryfür Vergleiche mit true und false generiert wurde , und festgestellt, dass es für true '1' und false '' (die leere Zeichenfolge) ersetzt. Was auch immer Sie in die Datenbank schreiben, muss damit übereinstimmen, wenn Sie Abfragen durchführen, die mit tatsächlichen wahren und falschen Werten verglichen werden. Insbesondere möchten Sie nicht '0' für false schreiben. Es ist möglicherweise kinderleichter, stattdessen für 0 und 1 zu schreiben und zu testen (und viele Formularersteller tun dies). Überprüfen Sie jedoch, was in die Datenbank geschrieben wird, und berücksichtigen Sie dies beim Erstellen Ihrer Abfrage.

Teil 2: Unter der Annahme, dass false der Standardwert ist, ist es einfach, Datensätze zu finden, deren Wert true ist:

... 'meta_key' => 'my_key', 'meta_value' => 1 (oder wahr)

Aber die andere Seite ist herausfordernd: Es könnte einen falschen Wert geben oder es könnte überhaupt keinen Wert geben. Dies kann passieren, wenn der Wert in einem Formular als optional aufgeführt wurde. Solange der Benutzer ihn nicht explizit festlegt oder ändert, wird er nicht zur Datenbank hinzugefügt. Beachten Sie, dass, wenn Sie es nur verwenden, get_post_metadies auf diese Weise einwandfrei funktioniert: Wenn Sie einen falschen Wert und keinen Wert zurückgeben, wird dasselbe erreicht.

Aber wenn Sie verwenden WP_Query, ist es nicht so einfach. (Oder wenn ja, ich habe noch nicht herausgefunden, wie).

Sie haben zwei (oder vielleicht drei) Optionen:

  1. Stellen Sie sicher, dass das Feld immer explizit auf einen realen Wert initialisiert wird. In einigen Formularerstellern tun Sie dies, indem Sie das erforderliche Feld festlegen und ihm einen Standardwert geben. Dann können Sie ...'meta_value' => 0 zuverlässig testen .

  2. Führen Sie zwei Abfragen durch, die erste prüft auf einen falschen Wert und die zweite prüft auf keinen Wert. Diese können wie folgt zu einer einzigen WP_Query kombiniert werden:

    meta_query => {
        relation => 'OR'
        array(
            'key'     => 'my_key',
            'value'   => 0,
            'compare' => '='
        ),
        array(
            'key'     => 'my_key',
            'compare' => 'NOT EXISTS',
        ),
    )

Dies ist wahrscheinlich keine effiziente Abfrage. Abhängig von vielen Faktoren ist es möglicherweise besser, alle Objekte zurückzugeben und sie in Ihrem eigenen Code zu filtern.

  1. Es ist möglich, "kein Wert" zu verwenden, um "falsch" zu bedeuten. Wenn der Wert auf false gesetzt werden soll, müssen Sie dazu den Metawert löschen, anstatt ihn zu aktualisieren .

In diesem Fall gibt eine einzelne 'NOT EXISTS'Abfrage zuverlässig die richtigen Objekte zurück. (Ich glaube nicht, dass viele Form Builder oder Plugins dieses Verhalten unterstützen, daher würde ich es nur in rein benutzerdefiniertem Code verwenden.)

Denise Draper
quelle