$per_page, 'paged' => max( 1, absint( $args['page'] ?? 1 ) ), 'orderby' => $by_name ? 'display_name' : 'registered', 'order' => $by_name ? 'ASC' : 'DESC', 'count_total' => true, 'fields' => 'all', 'exclude' => self::excluded_ids(), // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Short list of pending, blocked or hidden users. ); if ( '' !== $search ) { $query_args['search'] = '*' . $search . '*'; $query_args['search_columns'] = array( 'display_name', 'user_nicename' ); } /** * Filters the member directory query arguments. * * @since 1.0.0 * * @param array $query_args WP_User_Query arguments. * @param array $args Request arguments. */ $query = new WP_User_Query( apply_filters( 'spacebay_member_directory_args', $query_args, $args ) ); $users = (array) $query->get_results(); return array( 'items' => self::format_many( $users ), 'total' => (int) $query->get_total(), ); } /** * Users left out of the directory: pending or blocked, and members who hid * their profile (community managers still see hidden members). * * @return int[] */ private static function excluded_ids() { $ids = Profiles::inactive_ids(); if ( ! SpaceAccess::is_manager( get_current_user_id() ) ) { $ids = array_merge( $ids, array_diff( Profiles::hidden_ids(), array( get_current_user_id() ) ) ); } return array_values( array_unique( $ids ) ); } /** * Full profile of one member for a viewer. * * @param WP_User $user Member. * @param array|null $profile Profile row. * @param int $viewer_id Viewer. * @return array */ public static function profile( WP_User $user, $profile, $viewer_id ) { $base = self::format( $user, $profile ); $is_self = (int) $viewer_id === (int) $user->ID; $hidden = $profile && 'hidden' === $profile['privacy'] && ! $is_self && ! SpaceAccess::is_manager( $viewer_id ); $base['cover'] = $hidden ? '' : Profiles::image_url( $profile, 'cover' ); $base['hidden'] = $hidden; $base['is_self'] = $is_self; if ( $hidden ) { $base['headline'] = ''; $base['level'] = ''; $base['level_rank'] = 0; return $base; } return array_merge( $base, array( 'bio' => $profile ? (string) $profile['bio'] : '', 'website' => $profile ? (string) $profile['website'] : '', 'location' => $profile ? (string) $profile['location'] : '', 'fields' => self::display_fields( $profile ? $profile['custom_fields'] : array() ), 'last_active' => $profile ? Time::iso( $profile['last_activity_at'] ) : null, 'privacy' => $is_self && $profile ? $profile['privacy'] : null, 'custom_values' => $is_self && $profile ? $profile['custom_fields'] : null, ) ); } /** * Formats several users with one profile query. * * @param WP_User[] $users Users. * @return array[] */ public static function format_many( array $users ) { $profiles = Profiles::get_many( wp_list_pluck( $users, 'ID' ) ); $items = array(); foreach ( $users as $user ) { $items[] = self::format( $user, $profiles[ $user->ID ] ?? null ); } return $items; } /** * Formats one member. Never includes the email address or login name. * * @param WP_User $user User. * @param array|null $profile Profile row. * @return array */ public static function format( WP_User $user, $profile = null ) { $level = \SpaceBay\Gamification\Gamification::enabled() ? \SpaceBay\Gamification\Levels::for_points( $profile ? (int) $profile['points'] : 0 ) : null; return array( 'id' => $user->ID, 'name' => $user->display_name, 'slug' => $user->user_nicename, 'avatar' => get_avatar_url( $user->ID, array( 'size' => 128 ) ), 'headline' => $profile && self::shows_details( $user->ID, $profile ) ? (string) $profile['headline'] : '', 'is_manager' => SpaceAccess::is_manager( $user->ID ), 'joined_at' => Time::iso( $user->user_registered ), 'level' => $level ? $level['name'] : '', 'level_rank' => $level ? $level['number'] : 0, ); } /** * Whether the viewer may see the details of a hidden profile. * * @param int $user_id Member. * @param array $profile Profile row. * @return bool */ private static function shows_details( $user_id, array $profile ) { $viewer = get_current_user_id(); return 'hidden' !== ( $profile['privacy'] ?? 'members' ) || (int) $user_id === $viewer || SpaceAccess::is_manager( $viewer ); } /** * Answers to extra profile fields, ready to show: label and value. * * @param array $values Stored answers keyed by field key. * @return array[] */ public static function display_fields( $values ) { /** * Filters the extra profile fields shown on a profile (SpaceBay Pro). * * @since 1.0.0 * * @param array[] $fields Fields with key, label, type and value. * @param array $values Stored answers keyed by field key. */ return array_values( (array) apply_filters( 'spacebay_profile_display_fields', array(), (array) $values ) ); } }