<strong>Question 1:</strong>
Here's the code I'm using for my Authors page that lists the contributors on my site. It's currently showing every single author on a page, including the ones that doesn't even have/written a post yet. What I need is a way to filter the list so that it shows only the ones that have at least one published post on the blog.
<ul>
<li>
<?php
global $wpdb;
$query = "SELECT ID, user_nicename from $wpdb->users ORDER BY user_nicename";
$author_ids = $wpdb->get_results($query);
foreach($author_ids as $author) :
$curauth = get_userdata($author->ID);
if($curauth->user_level > 0 || $curauth->user_login == 'admin') :
$user_link = get_author_posts_url($curauth->ID);
$avatar = 'identicon';
?>
<div class="authors-info">
<a href="<?php echo $user_link; ?>" title="Articles by <?php echo $curauth->display_name; ?>">
<?php echo get_avatar($curauth->user_email, '80', $avatar); ?></a>
<h2><a href="<?php echo $user_link; ?>" title="Articles by <?php echo $curauth->display_name; ?>"><?php echo $curauth->display_name; ?></a></h2>
<?php echo $curauth->description; ?>
<div style="clear:both;"></div>
<div class="authors-info2">
<h3><img src="http://rshahin.com/wp-content/themes/rs/images/author-site.jpg"><a href="<?php echo $curauth->user_url; ?>">Author Website</a></h3>
</div>
<div class="authors-info2">
<h3><img src="http://rshahin.com/wp-content/themes/rs/images/author-twitter.jpg"><a href="<?php echo $curauth->twitter; ?>">Author Twitter</a></h3>
</div>
<div class="authors-info2">
<h3><img src="http://rshahin.com/wp-content/themes/rs/images/author-rss.jpg"><a href="http://rshahin.com/?feed=rss2&author=<?php echo $curauth->ID; ?>">Author RSS</a></h3>
</div>
<div style="clear:both;"></div>
<div class="author-info-line"></div>
<div class="authors-posts">
<h2>Latest Posts by the Author</h2>
<ul>
<?php sobeks_posts_by_author($author->ID) ; ?>
</ul>
</div>
</div>
<?php endif; ?>
<?php endforeach; ?>
</li>
</ul>
<strong>Question 2:</strong>
As you can tell I used a plugin/function to list the latest post from each author, the problem is, it's listing all of the posts an author has written to date, what I want is to limit the post count to 10/5 or whatever. I know it can be done, just don't know how, but I'm sure someone here does. So thanks in advance.
function sobeks_posts_by_author() {
//-----------------------------------------------
// Definitions
global $wpdb;
$wp_tp = $wpdb->prefix;
$number_of_args = func_num_args();
$list_of_args = func_get_args();
$order_posts_by = "{$wp_tp}posts.post_title ASC";
$display_post_count = 0;
$display_comment_count = 0;
$cstm_err_msg = '<b style="color:#f00;">Error:</b> Please enter the ID of at least one category';
//-----------------------------------------------
// Checking
// if there are arguments
if ($number_of_args != 0) {
// if there are any "display" arguments
if(!is_bool(array_search('commentsort',$list_of_args))) { $order_posts_by = "{$wp_tp}posts.comment_count DESC"; }
if(!is_bool(array_search('date',$list_of_args))) { $order_posts_by = "{$wp_tp}posts.post_date DESC"; }
if(!is_bool(array_search('count',$list_of_args))) { $display_post_count = 1; }
if(!is_bool(array_search('comments',$list_of_args))) { $display_comment_count = 1; }
$list_of_args = array_diff($list_of_args, array('', ' ', 'commentsort', 'date', 'count', 'comments'));
$number_of_args = func_num_args($list_of_args);
// if, after having dealt with the "display arguments", there are any left
if ($number_of_args != 0) {
// if there is more than one category
if($number_of_args != 1) {
$the_author_result = "AND ( ";
for ($i = 0; $i < $number_of_args; $i++) {
if($i != 0) { $the_author_result .= " OR "; }
$the_author_result .= "{$wp_tp}users.ID = '" . $list_of_args[$i] . "'";
}
$the_author_result .= " )";
// if there is one category
} else { $the_author_result = "AND {$wp_tp}users.ID = '" . $list_of_args[0] ."'"; }
// after having dealt with the "display arguments" there are no arguments left
} else { echo $cstm_err_msg; exit; }
// there are no arguments
} else { echo $cstm_err_msg; exit; }
//-----------------------------------------------
// Code to execute after having done the checking
$posts_by_author = $wpdb->get_results("SELECT {$wp_tp}posts.ID, {$wp_tp}posts.post_author, {$wp_tp}posts.post_title, {$wp_tp}posts.comment_count, {$wp_tp}users.display_name FROM {$wp_tp}posts, {$wp_tp}users WHERE {$wp_tp}posts.post_status = 'publish' AND {$wp_tp}posts.post_author = {$wp_tp}users.ID " . $the_author_result . " AND {$wp_tp}posts.post_date < NOW( ) ORDER BY " . $order_posts_by);
$posts_by_author = array_values($posts_by_author);
if ($display_post_count != 0) {
$number_of_posts = count($posts_by_author);
if($number_of_posts != 1) {
$post_count_statement = $number_of_posts . ' posts';
} else { $post_count_statement = 'one post'; }
echo 'This author wrote ' . $post_count_statement . '<br />';
}
foreach ($posts_by_author as $posts) {
echo '<li><a href="' . get_permalink($posts->ID) . '">' . $posts->post_title . '</a>';
if($display_comment_count != 0){ echo ' (' . $posts->comment_count . ')'; }
echo '</li>';
}
}
Andrzej answers:
Possible workarounds...
1)
after
<blockquote>
foreach($author_ids as $author) :
$curauth = get_userdata($author->ID);</blockquote>
add
<blockquote>if ( $wpdb->get_var("SELECT COUNT(*) as count FROM wp_posts WHERE post_author = " . $author->ID ) == 0 ) continue;</blockquote>
2)
change
<blockquote>$posts_by_author = $wpdb->get_results("SELECT {$wp_tp}posts.ID, {$wp_tp}posts.post_author, {$wp_tp}posts.post_title, {$wp_tp}posts.comment_count, {$wp_tp}users.display_name FROM {$wp_tp}posts, {$wp_tp}users WHERE {$wp_tp}posts.post_status = 'publish' AND {$wp_tp}posts.post_author = {$wp_tp}users.ID " . $the_author_result . " AND {$wp_tp}posts.post_date < NOW( ) ORDER BY " . $order_posts_by);</blockquote>
to
<blockquote>$posts_by_author = $wpdb->get_results("SELECT {$wp_tp}posts.ID, {$wp_tp}posts.post_author, {$wp_tp}posts.post_title, {$wp_tp}posts.comment_count, {$wp_tp}users.display_name FROM {$wp_tp}posts, {$wp_tp}users WHERE {$wp_tp}posts.post_status = 'publish' AND {$wp_tp}posts.post_author = {$wp_tp}users.ID " . $the_author_result . " AND {$wp_tp}posts.post_date < NOW( ) ORDER BY " . $order_posts_by . " LIMIT 5");</blockquote>
Rofikul Islam Shahin comments:
Thanks Andrzej. Both of the solutions worked!
paul de wouters answers:
to get the list of authors that have a post assiciated, you can modify the query :
SELECT distinct user_nicename FROM `wp_users` inner join wp_posts
on wp_users.ID = wp_posts.post_author
Lew Ayotte answers:
Your second question:
It doesn't look like he allows that in his function... so you'll probably have to modify the function. I'd modify the $wpdb->get_results line and added " limit 10" to the end of the string.
Your first question, change your first query section to this:
<?php
global $wpdb;
$query = "SELECT ID, user_nicename from $wpdb->users ORDER BY user_nicename";
$author_ids = $wpdb->get_results($query);
$author_count = array();
foreach ( (array) $wpdb->get_results("SELECT DISTINCT post_author, COUNT(ID) AS count FROM $wpdb->posts WHERE post_type = 'post' AND " . get_private_posts_cap_sql( 'post' ) . " GROUP BY post_author") as $row )
$author_count[$row->post_author] = $row->count;
foreach($author_ids as $author) :
$curauth = get_userdata($author->ID);
$posts = (isset($author_count[$author->ID])) ? $author_count[$author->ID] : 0;
if(($curauth->user_level > 0 || $curauth->user_login == 'admin') && $posts > 0) :
$user_link = get_author_posts_url($curauth->ID);
$avatar = 'identicon';
?>
Lew