Posts com pelo menos 3 tags de uma lista de tags

12

Por exemplo, existem as tags { foo , bar , chocolate , mango , hammock , leaf }

Gostaria de encontrar todas as postagens com pelo menos 3 dessas tags .

Uma postagem com tags { foo , mango , vannilla , nuts , leaf } corresponderá a ela porque tem { foo , mango , leaf } - menos 3 tags do conjunto necessário de tags.

Portanto, seria na lista das postagens correspondentes.

Existe uma maneira simples de fazer isso, sem fazer vários loops em todas as postagens?

    
por Cedric 15.06.2013 / 18:36

3 respostas

8

A resposta abaixo é simplificada e pode ser estendida para verificar se qualquer postagens tem 3 tags correspondentes antes de gerar a lista. Usando uma consulta e supondo que você tenha pelo menos uma postagem com três tags correspondentes:

//List of tag slugs
$tags = array('foo', 'bar', 'chocolate', 'mango', 'hammock', 'leaf');

$args = array(
    'tag_slug__in' => $tags
    //Add other arguments here
);

// This query contains posts with at least one matching tag
$tagged_posts = new WP_Query($args);

echo '<ul>';
while ( $tagged_posts->have_posts() ) : $tagged_posts->the_post();
   // Check each single post for up to 3 matching tags and output <li>
   $tag_count = 0;
   $tag_min_match = 3;
   foreach ( $tags as $tag ) {
      if ( has_tag( $tag ) && $tag_count < $tag_min_match ) {
         $tag_count ++;
      }
   }
   if ($tag_count == $tag_min_match) {
      //Echo list style here
      echo '<li><a href="'. get_permalink() .'" title="'. get_the_title() .'">'. get_the_title() .'</a></li>';
   }
endwhile;
wp_reset_query();
echo '</ul>';

EDIT: Ajustar a variável $tag_min_match definirá o número de correspondências.

    
por stellarcowboy 15.06.2013 / 20:34
2

Aqui está uma maneira de fazer isso:

Dado um conjunto de 5 tags, {a, b, c, d, e} :

1) No PHP, gere todos os subconjuntos possíveis contendo 3 elementos, sem repetição:

{a, b, c}
{a, b, d}
{a, b, e}
{a, c, d}
{a, c, e}
{b, c, d}
{b, c, e}
{c, d, e}

2) Converta esses subconjuntos em uma consulta de taxonomia massiva:

$q = new WP_Query( array(
  'tax_query' => array(
    'relation' => 'OR',
    array(
      'terms' => array( 'a', 'b', 'c' ),
      'field' => 'slug',
      'operator' => 'AND'
    ),
    array(
      'terms' => array( 'a', 'b', 'd' ),
      'field' => 'slug',
      'operator' => 'AND'
    ),
    ...
  )
) );
    
por scribu 16.06.2013 / 00:35
1

A abordagem de sprclldr é a que eu usei. Quanto ao loop while, aqui está o que eu usei:

$relatedPosts = $tagged_posts->posts;
$indexForSort = array();

for ($i = count($relatedPosts) - 1; $i >= 0; $i--) {
  $relatedPostTags = get_tags($relatedPosts[$i]->ID);
  //get the ids of each related post
  $relatedPostTags = $this->my_array_column($relatedPostTags, 'term_id');
  $relatedPostTagsInPostTag = array_intersect($tags, $relatedPostTags);
  $indexForSort[$i] = count($relatedPostTagsInPostTag);
}

//sort by popularity, using indexForSort
array_multisort($indexForSort, $relatedPosts, SORT_DESC);

Eu, então, pego os posts principais:

$a_relatedPosts = array_slice($relatedPosts, 0, $this->numberRelatedPosts);

my_array_column é uma função semelhante à array_column do PHP 5.5:

  protected function my_array_column($array, $column) {
    if (is_array($array) && !empty($array)) {
      foreach ($array as &$value) {
        //it also get the object's attribute, not only array's values
        $value = is_object($value) ? $value->$column : $value[$column];
      }
      return $array;
    }
    else
      return array();
  }

Não responde a pergunta inicial (mas resolve o meu problema raiz ), como  : se não houver posts relacionados com 3 tags comuns, então isso vai dar algumas postagens.

    
por Cedric 16.06.2013 / 21:58

Tags