Méta-requête avec valeur booléenne true / false

11

J'essaie de montrer toutes les propriétés locatives, d'abord par toutes les propriétés qui n'ont pas été louées, puis par toutes les propriétés qui sont actuellement louées. Il existe un type de publication personnalisé 'rent' avec une méta de publication personnalisée pour le prix loué (_price_rented) qui est une case à cocher (renvoie vrai ou faux ... vrai s'il a été loué). Je dois modifier la requête pour afficher toutes les propriétés avec les propriétés disponibles (non louées) apparaissant en premier, puis les propriétés louées apparaissant.

Voici ma requête:

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

Pour une raison quelconque, cette requête affiche toutes les propriétés qui ont été louées. Lorsque je passe la valeur de «false» à «true» dans la méta-requête, elle n'affiche aucune propriété.

Alors, j'ai pensé que la valeur de retour est soit false (pour les propriétés qui sont louées) ou NULL (pour les propriétés qui ne sont PAS louées), mais je ne sais pas comment demander un résultat NULL (pas faux), j'ai ajouté un ' comparez 'argument à meta_query et définissez la valeur sur'! = 'mais cela n'a pas fonctionné non plus.

EDIT: var_dump renvoie les informations suivantes pour un appartement disponible non loué: string(0) ""et pour un appartement non disponible loué:string(1) "1"

Kegan Quimby
la source
en utilisant les valeurs 1 et 0 peut-être?
reikyoushin
meta_query type => chaîne. Les valeurs possibles sont 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. La valeur par défaut est 'CHAR'.
iEmanuele
@reikyoushin: l'utilisation d'un «1» renvoie toutes les propriétés louées et un «0» ne renvoie aucune propriété.
Kegan Quimby
1
@iEmanuele: changer cela semble n'avoir aucun effet (je pensais la même chose). J'ai vu cela à partir de cet article: thethemefoundry.com/blog/…
Kegan Quimby
1
Est-il _price_rentedréellement défini pour les valeurs trueet false, ou est-il uniquement défini pour true? Vérifiez la base de données s'il vous plaît. J'ai demandé parce qu'une case à cocher non cochée n'est pas du tout passée, POSTdonc je me demande si la valeur est définie pour ces cas.
s_ha_dum

Réponses:

4

WP_Meta_Query est en quelque sorte une partie "pas si stable" du noyau et si vous ne faites pas très attention à verrry, il peut facilement se détacher de la confusion.

Lorsque vous faites un new WP_Query()et que vous avez des meta_query => array()arguments ou ses équivalents de paire clé / valeur unique, puis new WP_Meta_Query()saute, suivi instantanément par l'analyse.

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

Valeurs autorisées

Lorsque vous interrogez des métadonnées, il y a une booloption. Et si vous l'utilisiez, il se replierait CHAR, sur lequel la valeur par défaut en tant que tableau de valeurs autorisées est:

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

NUMERICsera réinitialisé SIGNED.

Débogage

Il existe de nombreux filtres qui peuvent affecter le processus de post-sauvegarde, donc la première chose à faire est de vérifier les différentes valeurs à l'intérieur d'une boucle:

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

Ensuite, selon la valeur de retour, vous devrez soit utiliser SIGNED, si le résultat est 0ou 1, ou "true"ou "false"si le résultat est une chaîne. Si c'est vraiment booléen, alors je suggérerais toujours de l'utiliser stringjuste pour vous assurer qu'il passe $GLOBALS['wpdb'], qui ne peut que passer %schaîne et %dchiffre.

Notes complémentaires

Comme je l' ai juste mis à jour l'entrée du Codex pourWP_Meta_Query aujourd'hui, j'ai vu qu'il ya beaucoup de différentes êtes les sorties ( en ajoutant de nombreuses quantités de inutiles JOINS, qui sont discutés sur Trac ici et ici avec en un seul patch déplacé dans le noyau) possible. (Ticket de suivi pour les ANDpièces ici ) Le fait est qu'il est possible d'utiliser une combinaison d' meta_*arguments à côté du meta_querytableau et de ses sous-réseaux. Le résultat est à peu près inconnu à moins que vous ne le vidiez, donc à mon humble avis, vous feriez mieux d'utiliser l'une ou l'autre façon d'ajouter des entrées. Surtout quand tu es seulementen utilisant meta_key, car cela entraîne une "requête clé uniquement" dans certains cas.

Solution

Comme indiqué dans les commentaires:

(...) var_dumpretourne ce qui suit pour un appartement non loué disponible: string(0) ""et pour un appartement non loué:string(1) "1"

Maintenant, meta_queryil faut utiliser

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

Si vous souhaitez obtenir les "appartements non disponibles, loués" ou utiliser '!='pour récupérer les appartements "non loués".

Remarque: Les valeurs possibles pour meta_comparesont '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'ou 'RLIKE'. La valeur par défaut est '='.

kaiser
la source
3

J'ai rencontré le même problème et après une heure de recherche, j'ai trouvé la valeur "NOT EXISTS"et . Donc pas besoin de demander une méta-valeur, il suffit de vérifier si la méta-clé existe:"EXISTS"( only in WP >= 3.5 )

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

Cela fonctionne parfaitement pour moi.

Thibaut
la source
3

TL; DR: Ce problème se produit probablement surtout lorsqu'un champ booléen est créé comme facultatif. Vous pouvez le corriger en le rendant obligatoire ou en utilisant une requête plus complexe pour récupérer le cas par défaut.

Plus de détails:

Il y a deux problèmes de représentation des données en cours ici: l'un est quelles valeurs de données sont utilisées pour représenter vrai / faux et l'autre est de savoir si le champ est stocké du tout s'il s'agit de la valeur par défaut (généralement fausse).

Partie 1: J'ai regardé le SQL généré par WP_Meta_Querypour des comparaisons avec vrai et faux, et j'ai trouvé que pour vrai il remplace '1' et pour faux '' (la chaîne vide). Donc, tout ce que vous écrivez dans la base de données doit être d'accord avec cela si vous allez faire des requêtes en les comparant aux vraies et vraies valeurs. En particulier, vous ne voulez pas écrire «0» pour faux. Il pourrait être plus à toute épreuve d'écrire et de tester à la place 0 et 1 (et de nombreux constructeurs de formulaires le font). Mais vérifiez ce qui est écrit dans la base de données et gardez cela à l'esprit lors de la création de votre requête.

Partie 2: En supposant que false est la valeur par défaut, il est facile de trouver des enregistrements dont la valeur est vraie:

... 'meta_key' => 'my_key', 'meta_value' => 1 (ou vrai)

Mais l'autre côté est difficile: il peut y avoir une fausse valeur, ou il peut ne pas y en avoir du tout. Cela peut se produire si la valeur a été répertoriée comme facultative dans un formulaire --- tant que l'utilisateur ne la définit pas explicitement ou ne la modifie pas, elle ne sera pas ajoutée à la base de données. Notez que si vous l'utilisez uniquement, get_post_metacela fonctionnera très bien de cette façon: renvoyer une valeur fausse et ne retourner aucune valeur accomplira la même chose.

Mais lorsque vous utilisez WP_Query, ce n'est pas si facile. (Ou si c'est le cas, je n'ai pas encore compris comment).

Vous avez deux (ou peut-être trois) options:

  1. Assurez-vous que le champ est toujours explicitement initialisé à une valeur réelle. Dans certains générateurs de formulaires, vous faites cela en rendant le champ obligatoire et en lui donnant une valeur par défaut. Ensuite, vous pouvez tester de ...'meta_value' => 0 manière fiable.

  2. Faites deux requêtes, la première qui teste une fausse valeur et la seconde qui teste aucune valeur. Ceux-ci peuvent être combinés en une seule WP_Query comme ceci:

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

Ce n'est probablement pas une requête efficace. En fonction de nombreux facteurs, il peut être préférable de renvoyer tous les objets et de les filtrer dans votre propre code.

  1. Il est possible d'utiliser «aucune valeur» pour signifier faux. Pour ce faire, chaque fois que la valeur doit être définie sur false, vous devez supprimer la méta-valeur au lieu de la mettre à jour .

Dans ce cas, une seule 'NOT EXISTS'requête retournera de manière fiable les objets corrects. (Je ne pense pas que de nombreux créateurs de formulaires ou plugins prennent en charge ce comportement, donc je ne l'utiliserais que dans du code purement personnalisé.)

Denise Draper
la source