Messages avec au moins 3 balises d'une liste de balises


13

Par exemple, il y a les balises { foo, bar, chocolate, mango, hammock, leaf}

Je voudrais trouver tous les messages contenant au moins 3 de ces balises .

Un poste avec des étiquettes { foo, mango, vannilla, nuts, leaf} t - il correspondre parce qu'il a { foo, mango, leaf} - donc au moins 3 balises de l'ensemble nécessaire de balises.

Il figurerait donc dans la liste des postes correspondants.

Existe-t-il un moyen simple de le faire, sans faire plusieurs boucles dans tous les messages?

Réponses:


8

La réponse ci-dessous est simplifiée et pourrait être étendue pour vérifier si des messages ont 3 balises correspondantes avant de sortir la liste. En utilisant une requête et en supposant que vous avez au moins un article avec 3 balises correspondantes:

//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: Ajuster la variable $tag_min_matchdéfinira le nombre de correspondances.


2

Voici une façon de procéder:

Étant donné un ensemble de 5 balises, {a, b, c, d, e}:

1) En PHP, générez tous les sous-ensembles possibles contenant 3 éléments, sans répétition:

{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) Convertissez ces sous-ensembles en une requête de taxonomie massive:

$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'
    ),
    ...
  )
) );

1

L'approche de sprclldr est celle que j'ai utilisée. En ce qui concerne la boucle while, voici ce que j'ai utilisé à la place:

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

Je prends ensuite les premiers postes:

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

my_array_column est une fonction similaire à la array_column de 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();
  }

Il ne répond pas à la question initiale (mais il résout mon problème racine ), comme: s'il n'y a pas de messages liés avec 3 balises communes, cela donnera quand même quelques messages.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.