dashboard_glance_items
is a filter hook, not an action hook. See here for an explanation of the difference.
Your at_glance()
function doesn’t include the existing values, so only the items you return will be present in the At A Glance widget items.
Something more like this:
function at_glance( $items ) {
$number_users = count_users();
$text = $number_users['total_users'];
$roles = $number_users['avail_roles'];
$items[] = '<a class="users-count" href="users.php">' . $text . ' total users</a>';
foreach( $roles as $role => $count ){
if($role == 'none'){
} else {
$items[] = '<span><a class="users-count" href="'.admin_url('users.php?role=".$role)."">' . $role . '( ' . $count . ' )</a></span>';
}
}
$args = array( 'public' => true, '_builtin' => false );
$post_types = get_post_types($args, 'object', 'and');
foreach ($post_types as $post_type) {
$num_posts = wp_count_posts($post_type->name);
$num = number_format_i18n($num_posts->publish);
$text = _n($post_type->labels->singular_name, $post_type->labels->name, intval($num_posts->publish));
if (current_user_can('edit_posts')) {
$glance="<a class="".$post_type->name.'-count" href="'.admin_url('edit.php?post_type=".$post_type->name)."">'.$num.' '.$text.'</a>';
} else {
$glance="<span class="".$post_type->name.'-count">'.$num.' '.$text.'</span>';
}
$items[] = $glance;
}
return $items;
}
add_filter('dashboard_glance_items', 'at_glance');
…might be closer to what you’re looking for. (I’ve combined your //second
and //first
code, and tried to get it to a point where it won’t throw a fatal error.)