50,
'type' => 'both',
'user_id' => 0,
);
$r = dpa_parse_args( $args, $defaults, 'get_user_avatar_link' );
extract( $r );
// Default to current user
if ( empty( $user_id ) && is_user_logged_in() )
$user_id = get_current_user_id();
// Assemble some link bits
$user_link = array();
// BuddyPress
if ( dpa_integrate_into_buddypress() ) {
$user_url = user_trailingslashit( bp_core_get_user_domain( $user_id ) . dpa_get_authors_endpoint() );
// WordPress
} else {
$user_url = user_trailingslashit( trailingslashit( get_author_posts_url( $user_id ) ) . dpa_get_authors_endpoint() );
/**
* Multisite, running network-wide.
*
* When this function is used by the "unlocked achievement" popup, if multisite + running network-wide + and not subdomains,
* we'll have already done switch_to_blog( DPA_ROOT_BLOG ) by the time that this function is called. This makes inspecting
* the current site ID, and is_main_site(), both useless as the globals will have already been changed.
*
* We need to find out if the user is likely to be on the "main site" in this situation. so we can modify our link.
* The main site's author URLs are prefixed with "/blog". We do this by inspecting the _wp_switched_stack global.
*
* I think this solution might result in a wrong link in multi-network configuration, or if the main site has been set
* to something non-default, but these are edge-cases for now.
*/
if ( is_multisite() && ! is_subdomain_install() && dpa_is_running_networkwide() && DPA_DATA_STORE === 1 && ! empty( $GLOBALS['_wp_switched_stack'] ) ) {
$last_element = count( $GLOBALS['_wp_switched_stack'] ) - 1;
if ( isset( $GLOBALS['_wp_switched_stack'][$last_element] ) && $GLOBALS['_wp_switched_stack'][$last_element] != 1 )
$user_url = str_replace( home_url(), home_url() . '/blog', $user_url );
}
}
// Get avatar
if ( 'avatar' === $type || 'both' === $type )
$user_link[] = sprintf( '%2$s', esc_url( $user_url ), get_avatar( $user_id, $size ) );
// Get display name
if ( 'avatar' !== $type )
$user_link[] = sprintf( '%2$s', esc_url( $user_url ), get_the_author_meta( 'display_name', $user_id ) );
// Maybe return user URL only
if ( 'url' === $type ) {
$user_link = $user_url;
// Otherwise piece together the link parts and return
} else {
$user_link = join( ' ', $user_link );
}
return apply_filters( 'dpa_get_user_avatar_link', $user_link, $args );
}
/**
* The leaderboard template loop.
*
* Doesn't use WP_Query, but the template loop and its data are structured in a vaguely similar
* way to the dpa_has_achievements() and dpa_has_progress() loops (which do use WP_Query).
*
* @param array $args Optional. Associative array of optional arguments. See function for details.
* @return bool Returns true if the query had any results to loop over
* @since Achievements (3.4)
*/
function dpa_has_leaderboard( $args = array() ) {
// If multisite and running network-wide, switch_to_blog to the data store site
if ( is_multisite() && dpa_is_running_networkwide() )
switch_to_blog( DPA_DATA_STORE );
$defaults = array(
'paged' => dpa_get_leaderboard_paged(), // Page number
'posts_per_page' => dpa_get_leaderboard_items_per_page(), // Users per page
'user_ids' => array(), // Get details for specific users; pass an array of ints.
);
$args = dpa_parse_args( $args, $defaults, 'has_leaderboard' );
// Run the query
achievements()->leaderboard_query = dpa_get_leaderboard( $args );
// Only add pagination if query returned results
if ( ( count( achievements()->leaderboard_query['results'] ) || achievements()->leaderboard_query['total'] ) && $args['posts_per_page'] ) {
// If a top-level /leaderboard/ rewrite is ever added, we can make this use pretty pagination. Also see dpa_get_leaderboard_paged().
$base = add_query_arg( 'leaderboard-page', '%#%' );
// Pagination settings with filter
$leaderboard_pagination = apply_filters( 'dpa_leaderboard_pagination', array(
'base' => $base,
'current' => $args['paged'],
'format' => '',
'mid_size' => 1,
'next_text' => is_rtl() ? '←' : '→',
'prev_text' => is_rtl() ? '→' : '←',
'total' => ( (int) $args['posts_per_page'] === achievements()->leaderboard_query['total'] ) ? 1 : ceil( achievements()->leaderboard_query['total'] / (int) $args['posts_per_page'] ),
) );
achievements()->leaderboard_query['paged'] = (int) $args['paged'];
achievements()->leaderboard_query['pagination_links'] = paginate_links( $leaderboard_pagination );
achievements()->leaderboard_query['posts_per_page'] = (int) $args['posts_per_page'];
}
// If multisite and running network-wide, undo the switch_to_blog
if ( is_multisite() && dpa_is_running_networkwide() )
restore_current_blog();
return apply_filters( 'dpa_has_leaderboard', ! empty( achievements()->leaderboard_query['results'] ) );
}
/**
* Whether there are more items available in the leaderboard loop
*
* @return bool True if there are more items in the loop
* @since Achievements (3.4)
*/
function dpa_leaderboard_has_users() {
$item_count = count( achievements()->leaderboard_query['results'] );
// Messy, messy...
if ( ! isset( achievements()->leaderboard_query['current_item'] ) )
achievements()->leaderboard_query['current_item'] = -1;
if ( achievements()->leaderboard_query['current_item'] + 1 < $item_count )
return true;
// Do some cleaning up after the loop
elseif ( achievements()->leaderboard_query['current_item'] + 1 === $item_count && $item_count > 0 )
achievements()->leaderboard_query['current_item'] = -1;
achievements()->leaderboard_query['in_the_loop'] = false;
return false;
}
/**
* Iterate the leaderboard user index in the loop. Retrieves the next item and sets the 'in the loop' property to true.
*
* @return object The next item in the leaderboard
* @since Achievements (3.4)
*/
function dpa_the_leaderboard_user() {
achievements()->leaderboard_query['current_item']++;
achievements()->leaderboard_query['in_the_loop'] = true;
return achievements()->leaderboard_query['results'][ achievements()->leaderboard_query['current_item'] ];
}
/**
* Output the ID of the current user in the leaderboard
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_user_id() {
echo dpa_get_leaderboard_user_id();
}
/**
* Return the ID of the current user in the leaderboard
*
* @return int User ID
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_user_id() {
$user_id = achievements()->leaderboard_query['results'][ achievements()->leaderboard_query['current_item'] ]->user_id;
return (int) apply_filters( 'dpa_get_leaderboard_user_id', (int) $user_id );
}
/**
* Output the karma of the current user in the leaderboard
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_user_karma() {
echo number_format_i18n( dpa_get_leaderboard_user_karma() );
}
/**
* Return the karma of the current user in the leaderboard
*
* @return int User's karma
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_user_karma() {
$karma = achievements()->leaderboard_query['results'][ achievements()->leaderboard_query['current_item'] ]->karma;
return (int) apply_filters( 'dpa_get_leaderboard_user_karma', (int) $karma );
}
/**
* Output the position of the current user in the leaderboard
*
* It is possible that multiple users may share the same rank position (e.g. "tie for third place!").
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_user_position() {
echo number_format_i18n( dpa_get_leaderboard_user_position() );
}
/**
* Return the rank position of the current user in the leaderboard
*
* It is possible that multiple users may share the same rank position (e.g. "tie for third place!").
*
* @return int User's rank
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_user_position() {
$rank = achievements()->leaderboard_query['results'][ achievements()->leaderboard_query['current_item'] ]->rank;
return (int) apply_filters( 'dpa_get_leaderboard_user_position', (int) $rank );
}
/**
* Output the display nme of the current user in the leaderboard
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_user_display_name() {
echo esc_html( dpa_get_leaderboard_user_display_name() );
}
/**
* Return the display nme of the current user in the leaderboard
*
* @return string User's display name
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_user_display_name() {
$display_name = achievements()->leaderboard_query['results'][ achievements()->leaderboard_query['current_item'] ]->display_name;
// Use wpcore's get_the_author()'s filter for any other plugins that may filter the name in some special way.
$display_name = apply_filters( 'the_author', $display_name );
return apply_filters( 'dpa_get_leaderboard_user_display_name', $display_name );
}
/**
* Output the row class of the current user in the leaderboard
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_user_class() {
echo dpa_get_leaderboard_user_class();
}
/**
* Return the row class of the current user in the leaderboard
*
* @return string Row class for the current user in the leaderboard
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_user_class() {
$classes = array();
$count = isset( achievements()->leaderboard_query['current_item'] ) ? achievements()->leaderboard_query['current_item'] : 1;
$classes[] = ( (int) $count % 2 ) ? 'even' : 'odd';
$classes[] = 'user-id-' . dpa_get_leaderboard_user_id();
// Is the leaderboard user the current logged in user?
if ( is_user_logged_in() && wp_get_current_user()->ID === dpa_get_leaderboard_user_id() )
$classes[] = 'logged-in-user';
$classes = apply_filters( 'dpa_get_leaderboard_user_class', $classes );
$classes = array_map( 'sanitize_html_class', array_merge( $classes, array() ) );
$classes = join( ' ', $classes );
return 'class="' . esc_attr( $classes ) . '"';
}
/**
* Leaderboard pagination
*/
/**
* Output the leaderboard pagination count
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_pagination_count() {
echo dpa_get_leaderboard_pagination_count();
}
/**
* Return the pagination count
*
* As of 3.4, this function isn't used in Achievements core, and you should probably be careful about using it.
* The problem is that though there may be (for example) 20 total users on the leaderboard, this function is
* going to say "viewing 1-20 leaderboard positions", but if more than one of the users have the exact
* same karma points, they'll both share a rank, so the rank number of the last user in the leaderboard won't
* match the pagination count.
*
* tl;dr This function creates pagination text for the users in the leaderboard text, not the distinct ranks.
* Don't use it.
*
* @return string Progress pagination count
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_pagination_count() {
if ( empty( achievements()->leaderboard_query ) )
return '';
$found_count = achievements()->leaderboard_query['total'];
$item_count = count( achievements()->leaderboard_query['results'] );
// Set pagination values
$start_num = intval( ( achievements()->leaderboard_query['paged'] - 1 ) * achievements()->leaderboard_query['posts_per_page'] ) + 1;
$from_num = number_format_i18n( $start_num );
$to_num = number_format_i18n( ( $start_num + ( achievements()->leaderboard_query['posts_per_page'] - 1 ) > $found_count ) ? $found_count : $start_num + ( achievements()->leaderboard_query['posts_per_page'] - 1 ) );
$total_int = (int) ! empty( $found_count ) ? $found_count : $item_count;
$total = number_format_i18n( $total_int );
// Several items within a single page
if ( empty( $to_num ) ) {
$retstr = sprintf( _n( 'Viewing %1$s user', 'Viewing %1$s users', $total_int, 'dpa' ), $total );
// Several items with several pages
} else {
$retstr = sprintf( _n( 'Viewing users %2$s (of %4$s total)', 'Viewing %1$s users - %2$s through %3$s (of %4$s total)', $total_int, 'dpa' ), $item_count, $from_num, $to_num, $total );
}
return apply_filters( 'dpa_get_leaderboard_pagination_count', $retstr );
}
/**
* Output leaderboard pagination links
*
* @since Achievements (3.4)
*/
function dpa_leaderboard_pagination_links() {
echo dpa_get_leaderboard_pagination_links();
}
/**
* Return leaderboard pagination links
*
* @return string Pagination links
* @since Achievements (3.4)
*/
function dpa_get_leaderboard_pagination_links() {
if ( empty( achievements()->leaderboard_query ) )
return '';
return apply_filters( 'dpa_get_leaderboard_pagination_links', achievements()->leaderboard_query['pagination_links'] );
}