wake-up-neo.com

Beiträge mit mindestens 3 Tags aus einer Liste von Tags

Zum Beispiel gibt es die Tags {foo, bar, chocolate, mango, hammock, leaf}

Ich möchte alle Beiträge mit mindestens 3 dieser Tags finden.

Ein Beitrag mit Tags {foo, mango, vannilla, nuts, leaf} wird mit diesem übereinstimmen, da er {foo, mango, leaf} enthält - also mindestens 3 Tags aus dem erforderlichen Satz von Tags.

Daher wäre es in der Liste der übereinstimmenden Beiträge.

Gibt es eine einfache Möglichkeit, dies zu tun, ohne mehrere Schleifen durch alle Beiträge zu machen?

12
Cedric

Die Antwort unten ist vereinfacht und kann erweitert werden, um zu prüfen, ob any posts 3 übereinstimmende Tags haben, bevor die Liste ausgegeben wird. Wenn Sie eine Abfrage verwenden und davon ausgehen, dass Sie mindestens einen Beitrag mit 3 passenden Tags haben:

//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>';

BEARBEITEN: Durch Anpassen der Variablen $tag_min_match wird die Anzahl der Übereinstimmungen festgelegt.

8
stellarcowboy

Hier ist eine Möglichkeit, dies zu tun:

Bei einem Satz von 5 Tags {a, b, c, d, e}:

1) Generieren Sie in PHP alle möglichen Teilmengen mit 3 Elementen ohne Wiederholung:

{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) Konvertieren Sie diese Teilmengen in eine umfangreiche Taxonomie-Abfrage:

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

Der Ansatz von sprclldr ist der, den ich verwendet habe. Für die while-Schleife habe ich stattdessen Folgendes verwendet:

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

Ich nehme dann die Top-Beiträge:

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

my_array_column ist eine ähnliche Funktion wie die array_column von 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();
  }

Es beantwortet nicht die anfängliche Frage (aber es löst mein Grundproblem ), als: wenn es keine verwandten Beiträge mit 3 gemeinsamen Tags gibt, dann wird dies trotzdem einige Beiträge geben.

1
Cedric