Erhalten Sie Begriffe nach Taxonomie UND post_type

Ich habe 2 benutzerdefinierte Post-Typen “Lesezeichen” und “Snippets” und eine gemeinsame Taxonomie “Tag”. Ich kann eine Liste aller Begriffe in der Taxonomie mit get_terms () erzeugen, aber ich kann nicht herausfinden, wie man die Liste auf den Posttyp beschränkt. Was ich im Grunde suche, ist ungefähr so:

get_terms(array('taxonomy' => 'tag', 'post_type' => 'snippet')); 

Gibt es einen Weg, dies zu erreichen? Ideen werden sehr geschätzt !!

Oh, ich bin auf WP 3.1.1

Solutions Collecting From Web of "Erhalten Sie Begriffe nach Taxonomie UND post_type"

Hier ist eine andere Möglichkeit, etwas Ähnliches mit einer SQL-Abfrage zu tun:

 static public function get_terms_by_post_type( $taxonomies, $post_types ) { global $wpdb; $query = $wpdb->prepare( "SELECT t.*, COUNT(*) from $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id WHERE p.post_type IN('%s') AND tt.taxonomy IN('%s') GROUP BY t.term_id", join( "', '", $post_types ), join( "', '", $taxonomies ) ); $results = $wpdb->get_results( $query ); return $results; } 

Es ist einfach so, dass ich so etwas für ein Projekt brauchte, an dem ich gerade arbeite. Ich habe einfach eine Abfrage geschrieben, um alle Beiträge eines benutzerdefinierten Typs auszuwählen, und dann überprüfe ich, was die tatsächlichen Bedingungen meiner Taxonomie sind, die sie verwenden.

Dann habe ich alle Bedingungen dieser Taxonomie mit get_terms() und dann habe ich nur diejenigen, die in beiden Listen waren, in eine function verpackt und ich war fertig.

Aber dann brauchte ich mehr als nur die IDs: Ich brauchte die Namen, also fügte ich ein neues Argument namens $fields damit ich der function sagen konnte, was ich zurückgeben sollte. Dann dachte ich mir, dass get_terms viele Argumente akzeptiert und meine function auf einfache Begriffe beschränkt war, die von einem Post-Typ verwendet werden, so dass ich eine weitere if statement hinzufügte.

Die function:

 /* get terms limited to post type @ $taxonomies - (string|array) (required) The taxonomies to retrieve terms from. @ $args - (string|array) all Possible Arguments of get_terms http://codex.wordpress.org/Function_Reference/get_terms @ $post_type - (string|array) of post types to limit the terms to @ $fields - (string) What to return (default all) accepts ID,name,all,get_terms. if you want to use get_terms arguments then $fields must be set to 'get_terms' */ function get_terms_by_post_type($taxonomies,$args,$post_type,$fields = 'all'){ $args = array( 'post_type' => (array)$post_type, 'posts_per_page' => -1 ); $the_query = new WP_Query( $args ); $terms = array(); while ($the_query->have_posts()){ $the_query->the_post(); $curent_terms = wp_get_object_terms( $post->ID, $taxonomy); foreach ($curent_terms as $t){ //avoid duplicates if (!in_array($t,$terms)){ $terms[] = $c; } } } wp_reset_query(); //return array of term objects if ($fields == "all") return $terms; //return array of term ID's if ($fields == "ID"){ foreach ($terms as $t){ $re[] = $t->term_id; } return $re; } //return array of term names if ($fields == "name"){ foreach ($terms as $t){ $re[] = $t->name; } return $re; } // get terms with get_terms arguments if ($fields == "get_terms"){ $terms2 = get_terms( $taxonomies, $args ); foreach ($terms as $t){ if (in_array($t,$terms2)){ $re[] = $t; } } return $re; } } 

Verwendung:

Wenn Sie nur eine Liste von Begriffen benötigen, dann:

 $terms = get_terms_by_post_type('tag','','snippet','ID'); 

Wenn Sie nur eine Liste von Termnamen benötigen, dann:

 $terms = get_terms_by_post_type('tag','','snippet','name'); 

Wenn Sie nur eine Liste von Termobjekten benötigen, dann:

 $terms = get_terms_by_post_type('tag','','snippet'); 

Und wenn Sie zusätzliche Argumente von get_terms wie: orderby, order, hierarchic …

 $args = array('orderby' => 'count', 'order' => 'DESC', 'hide_empty' => 1); $terms = get_terms_by_post_type('tag',$args,'snippet','get_terms'); 

Genießen!

Aktualisieren:

So korrigieren Sie die Termanzahl für eine bestimmte Postartänderung:

 foreach ($current_terms as $t){ //avoid duplicates if (!in_array($t,$terms)){ $terms[] = $t; } } 

zu:

 foreach ($current_terms as $t){ //avoid duplicates if (!in_array($t,$terms)){ $t->count = 1; $terms[] = $t; }else{ $key = array_search($t, $terms); $terms[$key]->count = $terms[$key]->count + 1; } } 

Ich habe eine function geschrieben, die es ermöglicht, post_type im Array $args an die function get_terms() :

HT an @braydon zum Schreiben der SQL.

  /** * terms_clauses * * filter the terms clauses * * @param $clauses array * @param $taxonomy string * @param $args array * @return array **/ function terms_clauses($clauses, $taxonomy, $args) { global $wpdb; if ($args['post_type']) { $clauses['join'] .= " INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id"; $clauses['where'] .= " AND p.post_type='{$args['post_type']}'"; } return $clauses; } add_filter('terms_clauses', 'terms_clauses', 10, 3); 

Große Frage und solide Antworten.

Mir hat der Ansatz von @jessica mit dem Filter terms_clauses gefallen, weil er die function get_terms sehr sinnvoll erweitert.

Mein Code ist eine Fortsetzung ihrer Idee, mit einigen SQL von @braydon, um Duplikate zu reduzieren. Es erlaubt auch ein Array von post_types:

 /** * my_terms_clauses * * filter the terms clauses * * @param $clauses array * @param $taxonomy string * @param $args array * @return array **/ function my_terms_clauses($clauses, $taxonomy, $args) { global $wpdb; if ($args['post_types']) { $post_types = $args['post_types']; // allow for arrays if ( is_array($args['post_types']) ) { $post_types = implode("','", $args['post_types']); } $clauses['join'] .= " INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id"; $clauses['where'] .= " AND p.post_type IN ('". esc_sql( $post_types ). "') GROUP BY t.term_id"; } return $clauses; } add_filter('terms_clauses', 'my_terms_clauses', 99999, 3); 

Da get_terms keine Klausel für GROUPY BY hat, musste ich sie am Ende der WHERE-Klausel hinzufügen. Beachten Sie, dass ich die Filterpriorität sehr hoch gesetzt habe, in der Hoffnung, dass sie immer als letzte gehen wird.

Ich konnte die Argumente von get_terms nicht mit Gavins Version des obigen Codes arbeiten lassen, sondern habe sie schließlich geändert

 $terms2 = get_terms( $taxonomy ); 

zu

 $terms2 = get_terms( $taxonomy, $args ); 

wie es in der ursprünglichen function von Bainternet war.

@Bainnetnet: Danke! Ich musste die function etwas ändern, weil es nicht funktionierte (einige Tipperrors). Das einzige Problem ist jetzt, dass der Begriff count aus ist. Die Zählung berücksichtigt den Post-Typ nicht, daher glaube ich nicht, dass Sie get_terms () verwenden können.

 function get_terms_by_post_type($post_type,$taxonomy,$fields='all',$args){ $q_args = array( 'post_type' => (array)$post_type, 'posts_per_page' => -1 ); $the_query = new WP_Query( $q_args ); $terms = array(); while ($the_query->have_posts()) { $the_query->the_post(); global $post; $current_terms = get_the_terms( $post->ID, $taxonomy); foreach ($current_terms as $t){ //avoid duplicates if (!in_array($t,$terms)){ $t->count = 1; $terms[] = $t; }else{ $key = array_search($t, $terms); $terms[$key]->count = $terms[$key]->count + 1; } } } wp_reset_query(); //return array of term objects if ($fields == "all") return $terms; //return array of term ID's if ($fields == "ID"){ foreach ($terms as $t){ $re[] = $t->term_id; } return $re; } //return array of term names if ($fields == "name"){ foreach ($terms as $t){ $re[] = $t->name; } return $re; } // get terms with get_terms arguments if ($fields == "get_terms"){ $terms2 = get_terms( $taxonomy, $args ); foreach ($terms as $t){ if (in_array($t,$terms2)){ $re[] = $t; } } return $re; } } 

EDIT: Die Korrektur (en) hinzugefügt. Aber irgendwie funktioniert es immer noch nicht für mich. Die Zählung zeigt immer noch den falschen Wert an.

Duplikate vermeiden:

 //avoid duplicates $mivalor=$t->term_id; $arr=array_filter($terms, function ($item) use ($mivalor) {return isset($item->term_id) && $item->term_id == $mivalor;}); if (empty($arr)){ $t->count=1; $terms[] = $t; }else{ $key = array_search($t, $terms); $terms[$key]->count = $terms[$key]->count + 1; }