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

13

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 Post mit Tags { foo, mango, vannilla, nuts, leaf} wird es passen , weil es { foo, mango, leaf} - so zumindest 3 - Tags aus dem benötigten 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 Posts zu führen?

Cedric
quelle

Antworten:

8

Die Antwort unten vereinfacht und könnte , wenn überprüfen verlängert werden alle Beiträge vor der Ausgabe der Liste 3 passende Tags haben. Wenn Sie eine Abfrage verwenden und davon ausgehen, dass Sie mindestens einen Beitrag mit 3 übereinstimmenden 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_matchwird die Anzahl der Übereinstimmungen festgelegt.

stellarcowboy
quelle
2

Hier ist eine Möglichkeit, dies zu tun:

Bei einem Satz von 5 Tags gilt Folgendes {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'
    ),
    ...
  )
) );
scribu
quelle
1

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 erste Frage (aber es behebt mein Root-Problem ), als: Wenn es keine verwandten Beiträge mit 3 gemeinsamen Tags gibt, dann wird dies trotzdem einige Beiträge geben.

Cedric
quelle