WordPressのタクソノミー/ターム関係の関数

WordPressのタクソノミー/ターム関係の関数が、あまりにも欲しい機能のものが乏しかったので、書いてみました。

まずは比較的コアな部分から。

get_term_object()

function get_term_object($term, $taxonomy='category') {
 $term = (array) $term; $term = $term[0];
 $t = NULL ;
 $sup_term = get_term($term, $taxonomy); // $term supposed to be an id
 if (is_wp_error($sup_term) || !$sup_term) { // $term is not an id, $taxonomy does not exist, or else
  if ($t = get_term_by('slug', $term, $taxonomy)) return $t;
  elseif ($t = get_term_by('name', $term, $taxonomy)) return $t;
  return FALSE ;
 }
 else { return $sup_term; }
 return FALSE ;
}

idかslugかnameを入れると、Taxonomy Termオブジェクトを返します。該当しなければfalse。

get_queried_terms()(※未完成)

function get_queried_terms($taxonomy=NULL, $return_object=TRUE, $field='slug') {
 global $wp_query;
 $taxonomies = array(); $objects = array();
 $slugs = array(); $names = array(); $ids = array();

 if ( is_array($wp_query->query_vars) ) {
  if ( isset($taxonomies['category']) ) $taxonomies['category'] = array();
  if ( isset($taxonomies['tag']) ) $taxonomies['tag'] = array();

  // if $wp_query->query_vars['category_name'] is set
  if ( $c = $wp_query->query_vars['category_name'] ) $taxonomies['category'][] = $c;
 
  // $wp_query->query_vars[category__in],
  // $wp_query->query_vars[category__and],
  // $wp_query->query_vars[tag__in],
  // $wp_query->query_vars[tag__and]
  foreach (array('tag', 'category') as $tax) {
   foreach ( array_unique( array_merge( $wp_query->query_vars[$tax.'__in'], $wp_query->query_vars[$tax.'__and'] ) ) as $id ) {
    $taxonomies[$tax][] = get_term_by('id', $id, $tax)->slug ;
   }
  }
  
  // $wp_query->query_vars[tag_slug__in], $wp_query->query_vars[tag_slug__and]
  foreach ( array_unique( array_merge( $wp_query->query_vars['tag_slug__in'], $wp_query->query_vars['tag_slug__and'] ) ) as $s ) {
   $taxonomies['tag'][] = $s;
  }
 }
 // $wp_query->tax_query 
 if (!empty( $wp_query->tax_query->queries ) ) {
  foreach ( $wp_query->tax_query->queries as $q ) {
   if (!is_array($q)) continue ;
   if ( !isset($taxonomies[$q['taxonomy']]) ) $taxonomies[$q['taxonomy']] = array();
   foreach( $q['terms'] as $t ) {
    $f = $q['field']; if ($f == 'term_id') $f = 'id';
    $taxonomies[$q['taxonomy']][] = get_term_by($f, $t, $q['taxonomy'])->slug ;
   }
  }
 }
 // $wp_query->query
 if ( isset($wp_query->query['term']) && !empty($wp_query->query['term']) && isset($wp_query->query['taxonomy'] && $tax = $wp_query->query['taxonomy']) ) {
  $taxonomies[$tax][] = $wp_query->query['term'];
 }
 
 // $wp_query->queried_object
 if ( !empty($wp_query->queried_object) && $wp_query->queried_object->taxonomy && $wp_query->queried_object->slug ) {
  $tax = $wp_query->queried_object->taxonomy;
  if (!isset($taxonomies[$tax])) $taxonomies[$tax] = array();
  $taxonomies[$wp_query->queried_object->taxonomy][] = $wp_query->queried_object->slug
  ;
 }

 // remove redundancy
 foreach ($taxonomies as $tax=>$t) {
  $slugs[$tax] = array_unique($t);
  if ($return_object) {
   $objects[$tax] = array();
   foreach ($slugs[$tax] as $term) {
    $objects[$tax][] = get_term_object($term, $tax);
   }
  }
 }
 $result = $taxonomy ? 
  ( $return_object ?
   (array) isset($objects[$taxonomy]) ? $objects[$taxonomy] : NULL
   :
   (array) isset($slugs[$taxonomy]) ? $slugs[$taxonomy] : NULL
  )
  :
  ( $return_object ? $objects : $slugs )
 ;
 return  $result
 ;
}

任意のタクソノミーがクエリーされてるかどうか判断して、オブジェクトかslugの配列を返す。
パラメータでidも返すようにしたい。

post_is_in_descendant_taxonomy_term()

function post_is_in_descendant_taxonomy_term($terms, $taxonomy, $post=null) {
 $post = get_post($post);
 foreach ((array) $terms as $t) {
  $t = get_term_object($t,$taxonomy);
  if (!$t || is_wp_error($t)) continue;

  $ts = array($t); 
  if (is_taxonomy_hierarchical($taxonomy)) {
   $children = get_terms($taxonomy, array('child_of'=>$t->term_id));
   $ts = array_merge($ts, $children);
  }

  foreach ($ts as $tt) {
   if (has_term($tt->term_id, $taxonomy, $post)) return true;
  }
 }
 return false;
}

post_is_in_descendant_categoryの改造版。

is_specific_taxonomy_term() と is_specific_taxonomy_term_archive()

function is_specific_taxonomy_term($term, $taxonomy='category', $post=NULL, $ignore_descendant_terms=FALSE) {
 if ($post === NULL && is_archive()) {
  return is_specific_taxonomy_term_archive($term, $taxonomy, $ignore_descendant_terms);
 }
 if ( $post = get_post($post) ) {
  if (!$ignore_descendant_terms) return post_is_in_descendant_taxonomy_term($term,$taxonomy,$post);
  return has_term($term, $taxonomy, $post);
 }
 return FALSE
 ;
}
<br />function is_specific_taxonomy_term_archive($term, $taxonomy='category', $ignore_descendant_terms=FALSE) {
 $term = get_term_object($term, $taxonomy);
 if (!$term) return FALSE ;
 
 $terms = ( is_taxonomy_hierarchical($taxonomy) &amp;&amp; !$ignore_descendant_terms ) ? 
  (array) $term-&gt;term_id + get_term_children($term-&gt;term_id, $taxonomy) // &lt;= id list
  :
  $terms = (array) $term-&gt;term_id
 ;
 $queried_terms = get_queried_terms($taxonomy);
 foreach ($queried_terms as $t) {
  if ( in_array($t-&gt;term_id, $terms)) return TRUE ;
 }
  return FALSE ;
}

現在クエリされているタームまたは現在表示されているポストが、

  1. 任意のタームに該当するか
  2. 任意のタームの子孫にあるか
  3. ポストが任意のタームを持っているか
  4. ポストが持っているタームが任意のタームの子孫にあるか

を判断します。(1,2はis_archive()の場合、3,4はシングルポストか$postが渡された場合)

すべてβ版扱いなので、仕様は自己責任でお願いします。
とくにget_queried_terms()は足りない部分がたくさんありそうですが、とりあえず自分が必要としている部分は間に合うので当面おk。

Leave a Reply