obtenir toutes les valeurs pour une clé de champ personnalisée (cross-post)

44

Je sais comment obtenir une valeur de champ personnalisé pour un article spécifique.

get_post_meta($post_id, $key, $single);

Ce dont j'ai besoin, c'est d'obtenir toutes les valeurs associées à une clé de publication personnalisée, dans toutes les publications .

Quelqu'un sait d'un moyen efficace de le faire? Je ne voudrais pas parcourir tous les identifiants de post dans la base de données.

Exemple:

4 publications, toutes avec des valeurs différentes pour un champ personnalisé appelé "Humeur". 2 messages ont la valeur 'heureux', 1 article 'en colère' et 1 article a 'triste'

Je veux publier: dans tous les articles que nous avons: deux auteurs heureux, un auteur en colère et un auteur triste.

Mais pour BEAUCOUP de messages.

Ce que je recherche, c'est soit:

  • une fonction WP pour l'obtenir. ou
  • une requête personnalisée pour obtenir cela aussi efficacement que possible.
Mikkelbreum
la source
5
On dirait que vous utilisez cela comme une taxonomie. Pourquoi ne pas simplement ajouter (automatiquement) un terme à ces publications lors de la sauvegarde? Interroger beaucoup plus facilement.
Kaiser
@ Kaiser Je ne saurais trop vous remercier d'être un génie!
user2128576

Réponses:

58

Une approche possible serait d'utiliser l'une des méthodes d'assistance de la classe WPDB pour effectuer une requête méta plus précise. Toutefois, l’utilisation de certaines de ces fonctions a pour inconvénient de ne pas récupérer un simple tableau de données et de devoir faire des références inutiles aux propriétés d’un objet, même si vous n’appelez qu’une colonne ou une ligne.

Bien sûr, toutes les fonctions ne sont pas identiques, et une mention utile va à la méthode WPDB , get_colqui renvoie un simple tableau plat des données interrogées, j’en fais cette mention spécifiquement parce que l’exemple suivant fera appel à cette méthode. .

WordPress - WPDB Sélection d'une colonne de données
$ wpdb-> get_col ()

Voici un exemple de fonction qui interroge la base de données pour toutes les publications d'un type de publication choisi, d'un statut de publication et avec une clé méta spécifique (ou un champ personnalisé pour les moins avisés du point de vue technique).

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

Ainsi, par exemple, si vous souhaitez savoir quelles publications ont une méta-clé d’ évaluation , pour les films de type publication et que vous souhaitez stocker ces informations dans une variable, un exemple d’un tel appel serait ..

$movie_ratings = get_meta_values( 'rating', 'movies' );

Si vous ne voulez rien faire d’autre que d’imprimer ces données à l’écran, la fonction implode de PHP peut rapidement fusionner ce simple tableau en lignes de données.

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

Vous pouvez également utiliser les données renvoyées pour déterminer le nombre de publications ayant ces méta-valeurs en effectuant une boucle simple sur les données renvoyées et en créant un tableau des nombres, par exemple.

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

Cette logique pourrait être appliquée à divers types de données et étendue pour fonctionner de différentes manières. J'espère donc que mes exemples ont été utiles et simples à suivre.

t31os
la source
3
Aussi amusant pour les futurs téléspectateurs, si vous souhaitez extraire uniquement des méta-valeurs uniques, vous saisissez DISTINCTjuste après la SELECTdans la fonction ci-dessus. Pourrait être utile.
Howdy_McGee
Je pense que cela est extrêmement utile
Pablo SG Pacheco
Comment cela, et retourner les valeurs triées ?, Je pense que l' utilisation Classez par mais je ne peux pas comprendre comment l'utiliser
efirvida
14

Je voudrais juste ajouter une petite chose au code de t31os ci-dessus. J'ai changé "SELECT" en "SELECT DISTINCT" pour éliminer les entrées en double lorsque j'ai utilisé ce code moi-même.

Lehooo
la source
1
Je peux imaginer des cas où il serait valide d'avoir plusieurs méta-valeurs de la même valeur, et donc de ne pas ajouter cet ajout à mon code. Si vous voulez des valeurs distinctes, ce serait la voie à suivre. En outre, vous pouvez également ajouter cela en tant qu'argument de la fonction (pour pouvoir l'utiliser ou non, selon le cas).
T31 le
10

Il n'est ni bon ni nécessaire d'utiliser la somme globale $ wpdb:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );
Leon Francis Shelhamer
la source
Ce serait ma méthode préférée pour le faire, dans la plupart des cas. Il effectue cinq requêtes, plutôt qu'une, mais, comme il utilise les procédures standard de WordPress pour les générer et les soumettre, toute mise en cache spécifique à la plate-forme (telle que la mise en cache d'objets de WP Engine ou un plugin aléatoire) sera lancée. Les données seront également activées. être stocké dans le cache interne de WordPress pendant toute la durée de la demande; il n’aura donc pas besoin d’être extrait de la base de données, si nécessaire.
Andrew Dinmore
Tous les filtres seront également appliqués aux données, ce qui pourrait être extrêmement important, par exemple sur un site multilingue. Enfin, comme il utilise uniquement les fonctions de base de WordPress standard, il est beaucoup moins susceptible d’être cassé par une mise à jour future.
Andrew Dinmore
4

le moyen le plus rapide serait une requête personnalisée SQL et je ne suis pas sûr, mais vous pouvez essayer

$wpdb->get_results("
  SELECT posts.* , COUNT(*) 'moodcount'
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'Mood'
  GROUP BY postmeta.meta_key
");

Si quelque chose alors c'est un début.

Bainternet
la source
1
merci, mais les questions personnalisées ne doivent-elles pas être évitées "à tout prix"? Je préférerais utiliser la couche d'abstraction WP (est-ce que ça s'appelle?) ... mais bien sûr si ce n'est pas possible ...
mikkelbreum le
Les requêtes personnalisées, si elles sont écrites correctement, peuvent être meilleures et vous ne devriez les éviter que si vous ne savez pas ce que vous faites.
Bainternet
1
Je suis d'accord avec mwb. Les requêtes personnalisées sont très utiles et pratiques, mais je pense qu'elles sont aussi beaucoup plus lourdes sur la base de données .. en particulier avec les fonctions SRT ..
krembo99
3

Pour obtenir toutes les méta-valeurs par une méta-clé

Vérifiez wp-> db wordpress codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
Wiki
la source
3
Le problème avec cette approche est le manque de spécificité, vous obtiendrez de nombreux résultats à partir d'une telle requête, notamment des brouillons, des éléments mis à la corbeille, des publications, des pages et tout autre type de publication existant. Vous ne devriez jamais demander ce dont vous n'avez pas besoin, la spécificité est certainement requise ici.
t31os
S'il est vrai que vous pouvez obtenir des valeurs d'autres types de publications et de statuts, il arrive parfois que tout ce dont vous avez besoin soient les valeurs et que vous n'ayez utilisé cette méta_key nulle part, mais là où vous en avez besoin. Si toutes / la plupart des valeurs sont uniques, cela peut être la meilleure solution.
Luke Gedeon
2

Il n'y a aucune raison pour que vous ne puissiez pas fusionner t31os et le code de Bainternet pour obtenir une instruction préparée réutilisable (style wordpress) qui renvoie le nombre et les valeurs en une seule opération efficace.

C'est une requête personnalisée, mais elle utilise toujours la couche d'abstraction de la base de données wordpress - ainsi, par exemple, le nom des tables n'a pas d'importance, ou si elles changent, il s'agit d'une instruction préparée, ce qui nous protège d'autant mieux des attaques SQL, etc. .

Dans ce cas, je ne vérifie plus le type de message et j'exclus les chaînes vides:

    $r = $wpdb->get_results(  $wpdb->prepare( "
        SELECT pm.meta_value AS name, count(*) AS count  FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s'
        AND pm.meta_value != '' 
        AND p.post_type = '%s'
        GROUP BY pm.meta_value
        ORDER BY pm.meta_value          
        ", $key, $type) 
        );
    return $r;

Dans ce cas particulier

Cela retournera un tableau d'objets comme ceci:

array  
 0 => 
 object(stdClass)[359]
  public 'name' => string 'Hamish' (length=6)
  public 'count' => string '3' (length=1)
 1 => 
 object(stdClass)[360]
  public 'name' => string 'Ida' (length=11)
  public 'count' => string '1' (length=1)
 2 => 
 object(stdClass)[361]
  public 'name' => string 'John' (length=12)
  public 'count' => string '1' (length=1)
benz001
la source
0

Utilisez ce qui suit avec foreach

 $key = get_post_custom_values( 'key' );

Suppose que le nom de votre clé de champ personnalisé est

Dev
la source
Notez que ceci est la publication par défaut de la publication actuelle, quand aucun post_id n'est spécifié.
Birgire