Meta query con valore booleano vero / falso


11

Sto cercando di mostrare tutte le proprietà in affitto, prima per tutte le proprietà che non sono state affittate, quindi per tutte le proprietà che sono attualmente in affitto. Esiste un tipo di post personalizzato 'affitto' con meta post personalizzato per il prezzo noleggiato (_price_rented) che è una casella di controllo (restituisce vero o falso ... vero se è stato noleggiato). Devo modificare la query per mostrare tutte le proprietà con le proprietà disponibili (non in affitto) che appaiono prima e poi le proprietà in affitto che appaiono.

Ecco la mia domanda:

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

Per qualche motivo questa query mostra tutte le proprietà che sono state noleggiate. Quando cambio il valore da 'false' a 'true' nella meta_query non mostra alcuna proprietà.

Quindi, ho pensato, il valore di ritorno è falso (per le proprietà che SONO affittate) o NULL (per le proprietà NON affittate), ma non sono sicuro di come chiedere un risultato NULL (non falso), ho aggiunto un ' confronta 'argomento con la meta_query e imposta il valore su'! = 'ma neanche quello ha funzionato.

EDIT: var_dump restituisce quanto segue per un appartamento disponibile, non in affitto: string(0) ""e per un appartamento non disponibile, in affitto:string(1) "1"


usando i valori 1 e 0 forse?
reikyoushin,

meta_query type => stringa. I valori possibili sono 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. Il valore predefinito è "CHAR".
iEmanuele,

@reikyoushin: l'uso di un '1' restituisce tutte le proprietà in affitto e uno '0' non restituisce proprietà.
Kegan Quimby,

1
@iEmanuele: il cambiamento sembra non avere alcun effetto (ho pensato la stessa cosa). L'ho visto da questo articolo: thethemefoundry.com/blog/…
Kegan Quimby

1
È _price_rentedeffettivamente impostato per entrambi truee per i falsevalori o è impostato solo per true? Controlla il database per favore. Ho chiesto perché una casella di controllo non selezionata non è stata POSTaffatto visualizzata, quindi mi chiedo se il valore sia impostato per quei casi.
s_ha_dum,

Risposte:


4

WP_Meta_Query è in qualche modo una parte "non così stabile" nel nucleo e se non presti molta attenzione, può facilmente rompersi dall'essere confuso.

Quando stai eseguendo un new WP_Query()e hai meta_query => array()argomenti o i suoi equivalenti di coppia chiave / valore singolo, quindi new WP_Meta_Query()salta dentro, immediatamente seguito dall'analisi.

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

Valori ammessi

Quando richiedi metadati, allora c'è boolun'opzione. E se lo usassi, allora ricorrerebbe a CHARquale valore predefinito come array di valori consentiti è:

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

dove NUMERICverrà reimpostato SIGNED.

Debug

Esistono numerosi filtri che possono influire sul processo di post-salvataggio, quindi la prima cosa da fare è controllare i diversi valori all'interno di alcuni loop:

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

Quindi, a seconda del valore restituito, dovrai utilizzare SIGNED, se il risultato è 0o 1, o "true"o "false"se il risultato è una stringa. Se è davvero booleano, suggerirei comunque di usare stringsolo per assicurarmi che passi $GLOBALS['wpdb'], che può solo passare la %sstringa e la %dcifra.

Note aggiuntive

Come ho appena aggiornato la voce Codex perWP_Meta_Query oggi, ho visto che ci sei un sacco di diverse uscite (l'aggiunta di numerose quantità di non necessarie JOINS, che vengono discussi sul Trac qui e qui con fuori una singola patch spostato in core) possibile. (Biglietto di follow-up per le ANDparti qui ) Il punto è che è possibile usare una combinazione di meta_*argomenti accanto alla meta_querymatrice e ai suoi sottoparagrafi. Il risultato è praticamente sconosciuto a meno che non lo scarichi, quindi IMHO è meglio usare l'uno o l'altro modo di aggiungere input. Soprattutto quando sei soloutilizzando meta_key, in quanto ciò comporta in alcuni casi una "query solo chiave".

Soluzione

Come sottolineato nei commenti:

(...) var_dumprestituisce quanto segue per un appartamento disponibile, non in affitto: string(0) ""e per un appartamento non disponibile, in affitto:string(1) "1"

Ora meta_querydeve usare

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

Se si desidera ottenere gli "appartamenti disponibili, non disponibili" o utilizzare '!='per recuperare gli appartamenti "non disponibili".

Nota: i valori possibili per meta_comparesono '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'o 'RLIKE'. Il valore predefinito è '='.


3

Ho affrontato lo stesso problema e dopo un'ora di ricerca ho trovato il valore "NOT EXISTS"e . Quindi non c'è bisogno di chiedere un meta valore, controlla solo se esiste la meta_key:"EXISTS"( only in WP >= 3.5 )

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

Funziona perfettamente per me.


3

TL; DR: questo problema probabilmente si verifica principalmente quando un campo booleano viene creato come facoltativo. È possibile risolverlo rendendolo necessario o utilizzando una query più complessa per recuperare il caso predefinito.

Più dettagli:

Qui ci sono due problemi di rappresentazione dei dati: uno è quali valori di dati vengono utilizzati per rappresentare vero / falso e l'altro è se il campo viene archiviato o meno se è il valore predefinito (di solito falso).

Parte 1: ho esaminato l'SQL generato da WP_Meta_Queryconfronti con vero e falso e ho scoperto che per vero sostituisce '1' e falso '' (la stringa vuota). Pertanto, qualsiasi cosa tu scriva nel database deve concordare che, se stai per fare, fai delle query rispetto ai valori reali e falsi effettivi. In particolare, non si desidera scrivere '0' per falso. Invece potrebbe essere più sicuro scrivere e testare 0 e 1 (e molti costruttori di moduli lo fanno). Ma controlla per vedere cosa viene scritto nel database e tienilo a mente quando crei la tua query.

Parte 2: Supponendo che false sia il valore predefinito, è facile trovare record il cui valore è true:

... 'meta_key' => 'my_key', 'meta_value' => 1 (o vero)

Ma l'altro lato è impegnativo: potrebbe esserci un valore falso o potrebbe non esserci alcun valore. Ciò può accadere se il valore è stato elencato come facoltativo in un modulo --- quindi fino a quando l'utente non lo imposta esplicitamente o lo modifica, non verrà aggiunto al database. Si noti che se lo si utilizza solo get_post_metafunzionerà perfettamente in questo modo: restituire un valore falso e non restituire alcun valore compirà la stessa cosa.

Ma quando lo usi WP_Query, non è così facile. (O se lo è, non ho ancora capito come).

Hai due (o forse tre) opzioni:

  1. Assicurarsi che il campo sia sempre inizializzato esplicitamente su un valore reale. In alcuni compilatori di moduli, lo fai rendendo obbligatorio il campo e assegnandogli un valore predefinito. Quindi puoi testare in ...'meta_value' => 0 modo affidabile.

  2. Esegui due query, la prima che verifica un valore falso e la seconda che verifica alcun valore. Questi possono essere combinati in un singolo WP_Query in questo modo:

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

Questa probabilmente non è una query efficiente. A seconda di molti fattori, potrebbe essere meglio restituire tutti gli oggetti e filtrarli nel proprio codice.

  1. È possibile utilizzare "nessun valore" per indicare falso. Per fare ciò, ogni volta che il valore deve essere impostato su false, è necessario eliminare il meta valore invece di aggiornarlo .

In tal caso, una singola 'NOT EXISTS'query restituirà in modo affidabile gli oggetti corretti. (Non credo che molti compilatori di moduli o plugin supportino questo comportamento, quindi lo userei solo in codice puramente personalizzato.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.