web-dev-qa-db-fra.com

query_posts -> using meta_compare/où meta value est plus petit ou plus grand ou est égal à

J'utilise query_posts( $args ) pour filtrer la boucle. Je souhaite filtrer les publications en fonction de leur "vote" meta_value, parfois inférieur à, parfois égal, etc.

Je souhaite vraiment utiliser la fonction query_posts() et transmettre mon filtre par $args! Je ne souhaite pas utiliser add_filter('posts_where', 'filter_where');, puis ajouter une instruction AND à la requête.

Je souhaite utiliser la fonctionnalité donnée de WordPress pour filtrer les publications avec meta_key, meta_value et meta_compare comme ceci:

$args = array( 'meta_key'=>'vote', 'meta_compare'=>'>=', 'meta_value'=>5, 'posts_per_page'=>100 ) )

query_posts( $args );

Le résultat de ceci est:

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND wp_postmeta.meta_key = 'vote' AND wp_postmeta.meta_value >= '5' GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 100

Le problème de cela est:

wp_postmeta.meta_value >= '5' 

CA devrait etre:

wp_postmeta.meta_value >= 5

Ensuite, cela fonctionnerait bien.

Je ne comprends pas pourquoi WordPress ajoute des guillemets.

J'utilise le paramètre prédéfini de WordPress (<, >, <=, >=) et il est évident que cela fonctionnera uniquement avec des nombres et non avec des chaînes qui devraient être entre guillemets.

La documentation dit:

Renvoie les publications avec une clé de champ personnalisée de 'miles' avec une valeur de champ personnalisée inférieure à OR ÉGAL À 22

query_posts('meta_key=miles&meta_compare=<=&meta_value=22');

3
Joakim

Depuis WP 3.1, vous pouvez transtyper la méta valeur comme bon vous semble en utilisant l'argument 'type' dans 'meta_query':

$args = array(
  'meta_query'=> array(
    array(
      'key' => 'vote',
      'compare' => '>=',
      'value' => 5,
      'type' => 'numeric',
    )
  )
  'posts_per_page' => 100
) );

query_posts( $args );
11
scribu

D'après la documentation rapide, meta_value semble être conçu pour les chaînes et pour les valeurs numériques, il s'agit de meta_value_num.

Voir Paramètres Orderby

Mise à jour

J'ai creusé.

meta_value_num est en effet ignoré aux fins du filtrage. Je pense qu'ils ont simplement oublié d'ajouter cette partie. :)

Le problème est que WP_Query reçoit correctement le nombre sous la forme int (le passage sous forme de tableau importe peu), mais il transmet la condition meta_compare générée à travers $wpdb->prepare() et marque explicitement la valeur comme chaîne %s. Dans ce cas, prepare le cite de force.

Il semble donc que vous devrez filtrer posts_where après tout. Vous pouvez simplement essayer d'annuler cette chaîne spécifique au lieu de générer la condition manuellement.

3
Rarst

Je vous recommande d'analyser votre tableau $args et de le convertir en chaîne avant de le transmettre en query_posts. Lorsque vous créez le tableau $args, le système convertit automatiquement le nombre 5 en chaîne "5" lorsque le tableau est reconverti en chaîne.

Alors utilisez ceci à la place:

query_posts('meta_key=vote&meta_compare=>=&meta_value=5&posts_per_page=100');

Cela transmet toujours les mêmes informations à query_posts, mais doit passer le nombre 5 plutôt que la chaîne "5".


Mettre à jour

Depuis que nous avons découvert que meta_value stocke des chaînes plutôt que des nombres, il est impossible d'effectuer une comparaison supérieure/inférieure à la comparaison avec des chaînes. Cependant, après quelques recherches supplémentaires je suis tombé sur l'indicateur de requête meta_value_num.

Si vous exécutez l'appel query_posts suivant:

query_posts('meta_key=vote&meta_compare=>=&meta_value=5&posts_per_page=100&orderby=meta_value_num');

Ensuite, vous devriez avoir le comportement que vous voulez. meta_value_num indique à WordPress d'évaluer votre meta_values sous forme de nombres plutôt que de chaînes.

0
EAMann