obtendo todos os valores para uma chave de campo personalizada (postagem cruzada)

44

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

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

O que eu 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 de postagem no banco de dados.

Exemplo:

4 postagens, todas com valores diferentes para um campo personalizado chamado 'Humor'. 2 mensagens têm o valor 'feliz', 1 mensagem tem 'raiva' e 1 mensagem tem 'triste'

Eu quero mostrar: em todos os posts que temos: dois autores felizes, um irritado e um triste.

Mas para muitas postagens.

O que estou procurando é:

  • uma função WP para conseguir isso. ou
  • uma consulta personalizada para obter isso da maneira mais eficiente possível.
mikkelbreum
fonte
5
Parece que você está usando isso como uma taxonomia. Por que não simplesmente (automaticamente) adicionar um termo a essas postagens ao salvar? Tornaria a consulta muito mais fácil.
Kaiser
@ Kaiser Não posso agradecer o suficiente por ser um gênio!
user2128576

Respostas:

58

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, no entanto, é que você normalmente não recebe uma matriz simples de dados e geralmente precisa fazer referências desnecessárias às propriedades do objeto, mesmo que esteja apenas chamando por uma coluna ou linha.

Obviamente, nem todas as funções são a mesma, e uma menção proposital sai para o método WPDB , get_colque retorna uma matriz simples e simples dos dados consultados, faço essa menção especificamente porque o exemplo a seguir irá recorrer a esse método .

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

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

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ê deseja descobrir quais postagens têm uma meta-chave de classificação , para os filmes do tipo post e gostaria de armazenar essas informações em uma variável, um exemplo dessa chamada seria ..

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

Se você quiser fazer nada além de imprimir esses dados na tela, a função implode do PHP pode rapidamente dividir 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 descobrir quantas postagens têm esses meta-valores executando um loop simples sobre os dados retornados e criando uma matriz de 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 maneiras diferentes. Espero que meus exemplos tenham sido úteis e simples o suficiente para serem seguidos.

t31os
fonte
3
Também é interessante para os futuros espectadores, se você deseja extrair apenas meta-valores exclusivos - você digita DISTINCTlogo após o SELECTna função acima. Pode ser útil.
Howdy_McGee
Eu acho que isso é extremamente útil
Pablo SG Pacheco
Como fazer isso, e devolver os valores ordenados ?, Eu acho que o uso de ORDER BY, mas eu não consigo descobrir como usá-lo
efirvida
14

Eu gostaria de adicionar uma coisinha ao código do t31os acima. Alterei "SELECT" para "SELECT DISTINCT" para eliminar entradas duplicadas quando eu mesmo usei esse código.

Lehooo
fonte
1
Posso imaginar casos em que seria válido ter vários meta-valores com o mesmo valor e, portanto, não fizeram essa adição ao meu código. Se você deseja valores distintos, esse seria o caminho a seguir. Além disso, você também pode adicioná-lo como argumento para a função (para que você possa usá-lo ou não, conforme apropriado).
t31os 24/01
10

Não é bom ou 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 );
Leon Francis Shelhamer
fonte
Este seria o meu método preferido de fazê-lo, na maioria dos casos. Ele faz cinco consultas, em vez de apenas uma, mas, como ele usa os procedimentos padrão do WordPress para gerá-los e enviá-los, qualquer cache específico da plataforma (como o Cache de Objetos do WP Engine ou algum plugin aleatório) será ativado. Os dados também ser armazenado no cache interno do WordPress durante a solicitação, portanto não precisará ser recuperado do banco de dados novamente, se necessário.
Andrew Dinmore 2/06
Quaisquer filtros também serão aplicados aos dados, o que pode ser extremamente importante em, por exemplo, um site multilíngue. Por fim, como ele usa apenas as principais funções padrão do WordPress, é muito menos provável que seja quebrado por uma atualização futura.
Andrew Dinmore 2/06
4

a maneira mais rápida 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 alguma coisa, então é um começo.

Bainternet
fonte
1
obrigado, mas as perguntas personalizadas não devem ser evitadas "a todo custo"? Eu prefiro usar a camada de abstração WP (é isso que ele é chamado?) ... mas é claro que se isso não for possível ..
mikkelbreum
As consultas personalizadas, se escritas da maneira correta, podem ser melhores e você deve evitá-las apenas se não souber o que está fazendo.
Bainternet
1
Concordo com consultas .custom MWB são muito útil e prático, mas eu acho que eles também são muito mais pesados do DB .. especialmente usando funções SRT ..
krembo99
3

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

Verifique wp-> db wordpress codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
Wiki
fonte
3
O problema dessa abordagem é a falta de especificidade. Você obterá vários resultados dessa consulta, que podem incluir rascunhos, itens na lixeira, postagens, páginas e qualquer outro tipo de postagem existente. Você nunca deve consultar o que não precisa, pois a especificidade é certamente necessária aqui.
t31os 24/01
Embora seja verdade que você possa obter valores de outros tipos e status de postagens, há momentos em que tudo que você precisa são os valores e você não usou essa meta_key em nenhum lugar, mas onde precisar. Se todos / a maioria dos valores forem únicos, esta pode ser a melhor solução.
Luke Gedeon
2

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

É uma consulta personalizada, mas ainda está usando a camada de abstração do banco de dados wordpress - por exemplo, não importa quais são os nomes das tabelas, ou se eles mudam. .

Nesse caso, não estou mais verificando o tipo de postagem e excluindo cadeias 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)
benz001
fonte
0

Use o seguinte com foreach

 $key = get_post_custom_values( 'key' );

Supõe que o nome da sua chave de campo personalizada seja

Dev
fonte
Observe que esse padrão é a postagem atual, quando nenhum post_id é especificado.
22817 birgire