Answers:
这是使用一个SQL查询执行类似操作的另一种方法:
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;
}
print_r(get_terms_by_post_type(array('category') , array('event') ));
节目Warning: Missing argument 2 for wpdb::prepare()
因此,碰巧的是,我正在从事的项目需要这样的东西。我只写了一个查询以选择一个自定义类型的所有帖子,然后检查它们使用的分类法的实际术语是什么。
然后,我使用了该分类法的所有术语,get_terms()
然后只使用了两个列表中的那些术语,将其包装在一个函数中,然后完成。
但是之后我需要的不仅仅是ID:我需要名称,所以我添加了一个名为的新参数,$fields
以便可以告诉函数返回什么。然后我想到了get_terms
可以接受许多参数,并且我的功能仅限于帖子类型使用的术语,因此我又添加了一条if
语句,然后您就可以了:
/* 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;
}
}
如果您只需要一个术语ID列表,则:
$terms = get_terms_by_post_type('tag','','snippet','ID');
如果仅需要术语名称列表,则:
$terms = get_terms_by_post_type('tag','','snippet','name');
如果仅需要术语对象列表,则:
$terms = get_terms_by_post_type('tag','','snippet');
如果您需要使用get_terms的额外参数,例如:orderby,order,hierarchy ...
$args = array('orderby' => 'count', 'order' => 'DESC', 'hide_empty' => 1);
$terms = get_terms_by_post_type('tag',$args,'snippet','get_terms');
请享用!
更新:
要将术语计数固定为特定的职位类型更改:
foreach ($current_terms as $t){
//avoid duplicates
if (!in_array($t,$terms)){
$terms[] = $t;
}
}
至:
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;
}
}
(array) $args
而不是4个$ vars的列表会更好吗?这将使您不必关心输入参数的顺序,例如get_terms_by_post_type( $args = array( 'taxonomies', 'args', 'post_type', 'fields' => 'all') )
,然后使用调用它们$args['taxonomies']
。这将帮助您避免添加空值,而不必记住参数的顺序。我还建议使用单引号而不是双引号。我看到它们的蜂鸣速度提高了五倍。
'this is my mood: '.$value
过"this is my mood: $value"
,因为可读性。关于速度:不会太慢-我最多测量了五次。而且,当您在整个主题中的所有地方都使用双引号时,当您收到大量请求时,它们会迅速总结。无论如何,你说得很清楚。
"
vs. 的速度,但'
我错了。区别远没有任何人会注意到。
我写了一个函数,允许您post_type
将$args
数组传递给get_terms()
功能:
HT到@braydon以编写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);
好问题和可靠答案。
我真的很喜欢@jessica使用terms_clauses过滤器的方法,因为它以非常合理的方式扩展了get_terms函数。
我的代码是她想法的延续,并使用@braydon中的一些sql来减少重复。它还允许一个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);
因为get_terms没有GROUPY BY的子句,所以我必须将其添加到WHERE子句的末尾。请注意,我已将过滤器优先级设置为很高,希望它总是排在最后。
我无法使get_terms参数与上面的Gavin版本的代码一起使用,但最终通过更改
$terms2 = get_terms( $taxonomy );
至
$terms2 = get_terms( $taxonomy, $args );
就像Bainternet最初的功能一样。
@Bainternet:谢谢!我不得不稍微修改一下功能,因为它不起作用(有些错字)。现在唯一的问题是术语计数已关闭。计数没有考虑发布类型,因此我认为您不能在其中使用get_terms()。
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;
}
}
编辑:添加了修复。但是以某种方式,它仍然对我不起作用。计数仍显示不正确的值。
print_r(get_terms_by_post_typea(array('event','category','',array()));
这个给Warning: Invalid argument supplied for foreach()
了台词foreach ($current_terms as $t){
避免重复:
//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;
}