web-dev-qa-db-fra.com

Utilisation de $ wpdb pour interroger des publications avec une méta-valeur contenant le post_id actuel

J'essaie d'utiliser $ wpdb pour récupérer une liste de publications de la base de données où la méta_value de la table wp_postmeta contient le post_ID actuel entre guillemets. par exemple. "dix"

Les guillemets indiquent que 10 ne correspond pas à 100, etc.

Je peux le faire fonctionner lorsque j’exécute la méta-valeur exacte, c’est-à-dire: a: 1: {i: 0; s: 2: "10";}, mais elle renvoie également toutes les révisions, pas seulement les plus récentes. poster.

Voici le code que j'utilise actuellement:

 $ id = get_the_ID (); 
 $ rows = $ wpdb-> get_results ($ wpdb-> prepare (
 "
 SELECT * 
 FROM wp_postmeta 
 WHERE meta_key LIKE% s 
 AND meta_value =% s 
 ", 
 'Rôles _% _ production', 
 '%"'. $ id. '"%' 
)); 
 
 // parcourez les résultats 
 if ($ rows) {
 ... ... 
} 

Toutes les idées seraient grandement appréciées.

Merci

2
Matt Edwards

Dans le code que vous avez publié, vous ne récupérez pas la "liste des publications" comme vous le dites, mais une liste de lignes dans la table méta. Si vous voulez vraiment récupérer une liste de publications, utilisez WP_Query en utilisant meta_query param.

Quelque chose comme:

$id = '10'; // unserialized value

$args = array(
  'post_type' => 'post',
  'post_status' => 'publish',
  'posts_per_page' => -1,
  'meta_query' => array(
    array(
      'key' => 'roles_%_production',
      'value' => $id,
      'compare' => 'LIKE'
    )
  )
);
$query = new WP_Query( $args );
$rows = $query->get_posts();

Si vous voulez utiliser $ wpdb (je ne sais pas pourquoi), la requête correcte est quelque chose comme:

<?php
$id = '10'; // unserialized value

global $wpdb;
$rows = $wpdb->get_col( $wpdb->prepare(
  "SELECT DISTINCT $wpdb->posts.ID FROM $wpdb->posts, $wpdb->postmeta
  WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id AND
  $wpdb->posts.post_status = 'publish' AND
  $wpdb->posts.post_type = 'post' AND
  $wpdb->postmeta.meta_key = %s AND
  meta_value = %s",
  'roles_%_production',
  $id
) );
?>

$rows contiendra un tableau d'identifiants de publications. J'ai fait ce changement pour donner un sens à l'utilisation de $ wpdb. Si vous souhaitez récupérer tous les champs, utilisez SELECT * au lieu de SELECT DISTINCT $wpdb->posts.ID, utilisez $wpdb->get_results au lieu de $wpdb->get_col et ajoutez la ligne GROUP BY $wpdb->posts.ID à la requête.

6
gmazzap

Deux notes:

Recherche de métadonnées

La règle est simple: métadonnées sérialisées (comme un tableau converti en a:1:{i:0;s:2:"10";})n'est pas destiné à être interrogeable. Vous devrez convertir votre ensemble de données en valeurs uniques afin de pouvoir effectuer les recherches meta_query appropriées.

Le seul moyen efficace de rechercher ceci consiste à interroger toutes les données, puis à les désérialiser, à les restituer si elles correspondent à vos critères, ou à les ignorer. Il y a assez de discussions et de questions/réponses sur SO couvrant ce sujet .

Déclarations préparées

Il y a like_escape() , qui doit être utilisé comme ceci:

"%".like_escape( $string )."%"

La raison pour laquelle vous devez pré-ajouter et ajouter les caractères % est simple: vous pouvez décider vous-même si la LIKE doit se produire aux deux extrémités ou à une seule (début, fin, des deux côtés).

1
kaiser

Les guillemets indiquent que 10 ne correspond pas à 100, etc.

Je peux faire en sorte que ça marche quand je colle la valeur exacte de la méta valeur, à savoir: a: 1: {i: 0; s: 2: "10";}

En effet, dans votre requête WHERE, vous avez utilisé = où la valeur contient %. Utiliser LIKE à la place résoudrait ce problème particulier. Remplacez meta_value = %s par meta_value LIKE %s et votre requête devrait fonctionner de la même manière que si vous utilisiez la chaîne sérialisée complète.

il renvoie également toutes les révisions, pas seulement le post le plus récent.

Assurez-vous de spécifier le type et le statut de publication lorsque vous interrogez vos résultats. Si vous souhaitez inclure toutes les publications qui ne sont pas des révisions, vous devez vous assurer de rejoindre la table des publications (avant votre déclaration WHERE).

LEFT JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->postmeta.post_id

et incluez la ligne suivante dans votre instruction WHERE (liée par un AND).

$wpdb->posts.post_type NOT IN ('revision')
0
Shaun Cockerill