web-dev-qa-db-ja.com

特定の分類法を持つ特定の投稿タイプの投稿数を数える

モデレータのメモ: 元のタイトルは「特定の分類法を持つカスタムタイプの投稿の数を知る方法」でした)

私は関数wp_count_posts()で立ち往生しています!

ギャラリーにアートワークを表示するために'artwork'というカスタム投稿タイプを作成しました。各アートワークを特定のカテゴリ('artworkcat''webdesign''logo')に分類するために、'print'というカスタム分類法も作成しました。

特定のカテゴリで、'artwork'カスタム投稿タイプを使用している投稿の数を知るためにwp_count_posts()を使用します。

それが明確でない場合は、私はあなたに実際的な例を挙げる:私はこの'artwork'カスタム投稿タイプにいくつの投稿があるかを知りたいのですが、 'artworkcat'分類法で 'webdesign'と呼びます。

いくつかのパラメータを追加して、wp_count_posts()はこれのために働きますか?

助けてくれてありがとう !

3
Pierre

Somaticは最も明確な回答を得ましたが、1つ失敗しました。 numberpostsを-1に指定して、それらすべてを数えるようにする必要があります。このような:

$args = array(
    'post_type' => 'artwork',
    'post_status' => 'published',
    'genre' => 'romantic',
    'numberposts' => -1
);
$num = count( get_posts( $args ) );

一般的にあなたの分類スラッグとロマンチックに特定の用語で置き換えます。

3
Nick Powers

wp_count_posts()はこれのために働かないでしょう、それは分類学パラメータを受け入れません。次のことができます。

$taxonomy = 'artworkcat';
$term_slug = 'webdesign';
$post_type = 'artwork';

$term = get_term_by( 'slug', $term_slug, $taxonomy_type );

$count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->posts
INNER JOIN $wpdb->term_relationships
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->term_taxonomy
ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->posts.post_type = $post_type
AND $wpdb->term_taxonomy.taxonomy = $taxonomy
AND $wpdb->term_taxonomy.term_id = {$term->term_id};"));

分類内の用語のリストを取得するには、 get_terms() を使用します。例:get_terms('artworkcat')

2
sorich87

Sorichのコードは、SQLクエリを快適に操作できる場合に最適です。単純なクエリを作成したい場合は、get_posts()を使用して目的のクエリパラメータと一致するpostオブジェクトの配列を返し、同時にそれらを数えて値を返すことができます。変更は簡単なので、これを使ってあらゆる種類の組み合わせを数えました。

$args = array(
    'post_type' => 'artwork',
    'post_status' => 'any',
    'genre' => 'romantic'
);
$num = count( get_posts( $args ) );

公開済みアイテムのみをカウントする場合は、post_status引数を "publish"に変更します。

そして、あなたがインストールされているscribuによるQuery Multiple Taxonomiesプラグインを持っているなら、あなたはargsに複数のtaxonomiesを追加することができます...

2
somatic

あなたの分類法が特定の投稿タイプにのみ存在する場合は、コアのwp_count_terms関数を使用するだけです。

0
WPExplorer

@ somaticの答えはおそらくほとんどのサイトに最適です。それは確かに最も簡単です。また、SQLに非常に慣れている場合は、@ sorich87の回答を使用できます。または、以下のハイブリッドソリューションを使用できます。

先週聞かれた非常によく似た質問がありました(私がここにあなたのために残した答えを読む前にその質問の答えを間違いなく読んでください):

それから答えを取り、それをわずかに変更すると、次のような呼び出しが行われます。

$post_counts = CountPostsForPostTypeAndCategory::count('artwork','artworkcat');
foreach($post_counts as $post_counts) {
  echo "{$post_counts->term_name}: {$post_counts->post_count}<br/>";
}

そして、このクラスは、テーマのfunctions.phpファイルにコピーしたり、作成しているプラ​​グインの.phpファイルで使用したりできます。それはおそらくあなたのニーズには過剰(そしておそらく過度に複雑です)ですが、ハイブリッドソリューションが必要な場合はあなたが望むものを提供し、多くの投稿がある場合は(hundreds?)カウントするためだけに、すべての投稿を配列にロードするよりもパフォーマンスが向上します。

class CountPostsForPostTypeAndCategory {
  static $term_ids;
  static $taxonomy;
  static function count($post_type,$taxonomy) {
    self::$taxonomy = $taxonomy;

    add_action('posts_fields',array(__CLASS__,'posts_fields'));
    add_action('posts_where',array(__CLASS__,'posts_where'));
    add_action('posts_join',array(__CLASS__,'posts_join'));
    add_action('posts_groupby',array(__CLASS__,'posts_groupby'));

    $term_ids = get_terms($taxonomy,'fields=ids');
    $query = new WP_Query(array(
      'post_type' => $post_type,
      'posts_per_page' => '-1',
      'category__in' => $term_ids,
    ));

    remove_action('posts_fields',$array(__CLASS__,'posts_fields'));
    remove_action('posts_where',array(__CLASS__,'posts_where'));
    remove_action('posts_join',array(__CLASS__,'posts_join'));
    remove_action('posts_groupby',array(__CLASS__,'posts_groupby'));

    return $query->posts;
  }
  static function posts_where($where) {
    global $wpdb;
    $taxonomy = self::$taxonomy;
    $where = preg_replace("#({$wpdb->term_taxonomy}.taxonomy) = 'category'#","\\1 = '{$taxonomy}'",$where);
    return $where;
  }
  static function posts_join($join) {
    global $wpdb;
    $join .= " INNER JOIN {$wpdb->terms} ON {$wpdb->terms}.term_id = {$wpdb->term_taxonomy}.term_id ";
    return $join;
  }
  static function posts_groupby($groupby) {
    global $wpdb;
    $groupby = " {$wpdb->posts}.post_type, {$wpdb->terms}.term_id";
    return $groupby;
  }
  static function posts_fields($field_list) {
    global $wpdb;
    $field_list =<<<SQL
{$wpdb->terms}.term_id,
{$wpdb->terms}.name AS term_name,
{$wpdb->terms}.slug AS term_slug,
COUNT(*) as post_count
SQL;
    return $field_list;
  }
}

説明するいくつかのこと。 WP_Query()では、分類用語IDのリストを照会することはできませんが、カテゴリIDのリストを照会することはできます。しかし、カテゴリーとは何ですか?それらは'category'という名前の分類法ですか?そのため、分類用語IDを使用してカテゴリIDでクエリするようWP_Query()を設定しますが、posts_whereフックで文字列を置き換えて'category''{$taxonomy}'に置き換えます。または'artworkcat'を使用する場合。

add_action()remove_action()にまつわる明らかな複雑さは、必要な場合にのみそれらのフックを使用できるようにすることであり、他のクエリに影響を与える可能性のある場所に置いておくことではありません。

0
MikeSchinkel