obtendo todos os valores para uma chave de campo personalizada (cross-post)

38

Eu sei como obter um valor de campo personalizado para uma postagem específica.

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

O que preciso é obter todos os valores associados a uma chave de postagem personalizada específica, em todas as postagens .

Alguém sabe de uma maneira eficiente de fazer isso? Eu não gostaria de percorrer todos os ids do post no banco de dados.

Exemplo:

4 postagens, todas com valores diferentes para um campo personalizado chamado 'Mood'. 2 postagens têm o valor 'feliz', 1 post tem 'raivoso' e 1 post tem 'triste'

Eu quero produzir: em todos os posts que temos: dois felizes, um zangado e um triste autor (es).

Mas para muitas postagens.

O que estou procurando é:

  • uma função WP para obter isso. ou
  • uma consulta personalizada para obter isso da maneira mais eficiente possível.
por mikkelbreum 15.02.2011 / 14:01
fonte

7 respostas

53

Uma abordagem possível seria usar um dos métodos auxiliares na classe WPDB para fazer uma consulta baseada em meta mais refinada. A ressalva de usar algumas dessas funções, entretanto, é que você normalmente não recebe de volta uma simples matriz de dados e geralmente precisa fazer referências desnecessárias às propriedades do objeto, mesmo se você estiver chamando apenas uma coluna ou linha.

Naturalmente, nem todas as funções são a mesma e a mesma, e uma menção intencional vai para o método WPDB , get_col que retorna uma matriz simples e simples dos dados consultados, i faça essa menção especificamente porque o exemplo a seguir vai chamar esse método.

WordPress - WPDB Selecionando uma coluna de dados
$ wpdb- > get_col ( )

Aqui está uma função de exemplo que consulta o banco de dados para todas as postagens de um tipo de postagem escolhido, postar status e com uma meta-chave específica (ou campo personalizado para os menos tecnicamente ocupados).

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;
}

Por exemplo, se você quiser descobrir quais postagens têm uma meta-chave de classificação , para o tipo de postagem filmes e você gostaria de armazenar essa informação dentro de uma variável, um exemplo de tal chamada seria ..

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

Se você não quisesse fazer nada além de imprimir esses dados para a tela, a função implodir do PHP pode rapidamente unir essa matriz simples em linhas de dados.

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

Você também pode usar os dados retornados para calcular quantos posts possuem esses meta values, fazendo um loop simples sobre os dados retornados e construindo uma matriz das contagens, por exemplo.

$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.
*/

Essa lógica pode ser aplicada a vários tipos de dados e estendida para funcionar de várias formas diferentes. Então, espero que meus exemplos tenham sido úteis e simples o suficiente para seguir.

    
por t31os 15.02.2011 / 23:48
fonte
14

Gostaria apenas de adicionar uma coisa minúscula ao código t31os acima. Eu mudei "SELECT" para "SELECT DISTINCT" para eliminar entradas duplicadas quando eu usei este código eu mesmo.

    
por Lehooo 05.06.2011 / 20:52
fonte
9

Não é bom nem necessário usar o $ wpdb global:

// 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 );
    
por Leon Francis Shelhamer 03.10.2015 / 23:32
fonte
4

o caminho mais rápido seria uma consulta SQL personalizada e não tenho certeza, mas você pode tentar

$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
");

Se qualquer coisa, então é um começo.

    
por Bainternet 15.02.2011 / 16:01
fonte
3

Para obter todos os meta-valores por uma meta-chave

Marque o wp- > db wordpress codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
    
por Wiki 07.09.2013 / 13:07
fonte
2

Não há nenhuma razão pela qual você não pode mesclar o t31os e o código da Bainternet para ter uma instrução preparada reutilizável (estilo wordpress) que retorna a contagem e os valores em uma operação eficiente.

É uma consulta personalizada, mas ainda está usando a camada de abstração de banco de dados wordpress - por exemplo, não importa quais sejam os nomes das tabelas, ou se eles mudam, e é uma declaração preparada, então estamos muito mais seguros Ataques SQL etc.

Neste exemplo, não estou mais verificando o tipo de postagem e estou excluindo as sequências vazias:

    $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;

Neste particular, é

Isso retornará uma matriz de objetos assim:

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)
    
por benz001 31.01.2012 / 14:23
fonte
0

Use o seguinte para foreach

 $key = get_post_custom_values( 'key' );

Considera que o nome da sua chave de campo personalizada é

    
por Dev 29.07.2017 / 13:06
fonte