skip to Main Content

In my WordPress v5.9.1, I have custom post types (song, poet) and custom taxonomy (genre).

In the Authors page, I wanted to show the top 5 taxonomies from both pots types of a particular author with below code:

    <?php
                    $args = array(
                        'author' => 1,
                        'post_type' => array('song', 'poem'),
                        'number' => 5,
                        'orderby' => 'count', // categories with most posts first
                        'order' => 'DESC',
                        'taxonomy' => 'genre'
                    );
                    $categories = get_terms($args);
                    foreach ($categories as $cat) {
                        echo $cat->name . ' - ' . $cat->count;
                    }
                    wp_reset_postdata(); // reset query
                    ?>

The above code lists 5 random taxonomies than from the authors posts in the given post-types.

Update 1

Considering my objective cannot be achieved with above approach, I have tried below code using SQL Query and than wp_get_object_terms:

global $wpdb;

$SQLquery = "
SELECT $wpdb->posts.ID FROM $wpdb->posts 
WHERE $wpdb->posts.post_type IN ('song', 'poem') 
AND $wpdb->posts.post_author = $curauth->ID 
AND $wpdb->posts.post_status = 'publish'";

$SQLqueryResult = $wpdb->get_results($SQLquery, ARRAY_A); // array of all posts IDs of an author for the post_type's

$SQL_post_ids = wp_list_pluck($SQLqueryResult, 'ID');

$SQL_get_terms = wp_get_object_terms($SQL_post_ids, 'genre');

echo '<ul>';
foreach ($SQL_get_terms as $term) {
    echo '<li>' . $term->name . ' - ' . $term->count . '</li>';
}
echo '</ul>';

The above code results terms only from a particular author as expected, however what I am not able to achieve is:

  1. Total posts count of particular author ($curauth->ID) for each genre term, expected in $term->count in the echo
  2. Order the top 5 terms by most posts in each term.

How can I achieve the above two objectives?

Update 2

Below is the expected outcome from the working code:

(Name of the Genre [custom taxonomy] – Posts count [post_type = songs+poem] by an author in that genre)

  1. Classic songs – 10
  2. Romantic Poems – 8
  3. Devotional songs – 6
  4. Folk poems – 3
  5. Patriot songs – 2

2

Answers


  1. If you have only two genres, then we can expect maximum two rows. Also, you can convert your query into a group by:

    $SQLquery = "
    SELECT count($wpdb->posts.ID) FROM $wpdb->posts 
    WHERE $wpdb->posts.post_type IN ('song', 'poem') 
    AND $wpdb->posts.post_author = $curauth->ID 
    AND $wpdb->posts.post_status = 'publish'
    group by $wpdb->posts.post_type
    order by count(*) desc;";
    
    Login or Signup to reply.
  2. What you can do is to count the post for each term and then sort them by posts count:

    $terms_with_posts_count_by_author = array();
    foreach ($SQL_get_terms as $term) {
        $args = array(
             'nopaging' => true,
             'author' => $curauth->ID,
             'post_type' => array('song', 'poem'),
             'tax_query' => array(
                array(
                    'taxonomy' => 'genre',
                    'field' => 'slug',
                    'terms' => $term->slug
                ),
            ),
            'fields' => 'ids'
        );
        $posts_by_term = get_posts( $args );
        
        $terms_with_posts_count_by_author[] = array('term_name' => $term->name, 'term_posts_count' => count( $posts_by_term ));
    }
    

    Sort the $terms_with_posts_count_by_author by term_posts_count and then print it.

    usort($terms_with_posts_count_by_author, function ($a, $b) { return ($a["term_posts_count"] < $b["term_posts_count"]) ? 1 : -1; });
    
    echo '<ul>';
    foreach( $terms_with_posts_count_by_author as $term_with_post_count ){
        echo '<li>' . $term_with_post_count["term_name"] . ' - ' . $term_with_post_count["term_posts_count"] . '</li>';
    }
    echo '</ul>';
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search