<?php if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly if( ! class_exists('ACF_Ajax_Query_Users') ) : class ACF_Ajax_Query_Users extends ACF_Ajax_Query { /** @var string The AJAX action name. */ var $action = 'acf/ajax/query_users'; /** * init_request * * Called at the beginning of a request to setup properties. * * @date 23/5/19 * @since 5.8.1 * * @param array $request The request args. * @return void */ function init_request( $request ) { parent::init_request( $request ); // Customize query. add_filter( 'user_search_columns', array( $this, 'filter_search_columns' ), 10, 3 ); /** * Fires when a request is made. * * @date 21/5/19 * @since 5.8.1 * * @param array $request The query request. * @param ACF_Ajax_Query $query The query object. */ do_action( "acf/ajax/query_users/init", $request, $this ); } /** * get_args * * Returns an array of args for this query. * * @date 31/7/18 * @since 5.7.2 * * @param array $request The request args. * @return array */ function get_args( $request ) { $args = parent::get_args( $request ); $args['number'] = $this->per_page; $args['paged'] = $this->page; if( $this->is_search ) { $args['search'] = "*{$this->search}*"; } /** * Filters the query args. * * @date 21/5/19 * @since 5.8.1 * * @param array $args The query args. * @param array $request The query request. * @param ACF_Ajax_Query $query The query object. */ return apply_filters( "acf/ajax/query_users/args", $args, $request, $this ); } /** * Prepares args for the get_results() method. * * @date 23/3/20 * @since 5.8.9 * * @param array args The query args. * @return array */ function prepare_args( $args ) { // Parse pagination args that may have been modified. if( isset($args['users_per_page']) ) { $this->per_page = intval($args['users_per_page']); unset( $args['users_per_page'] ); } elseif( isset($args['number']) ) { $this->per_page = intval($args['number']); } if( isset($args['paged']) ) { $this->page = intval($args['paged']); unset( $args['paged'] ); } // Set pagination args for fine control. $args['number'] = $this->per_page; $args['offset'] = $this->per_page * ($this->page - 1); $args['count_total'] = true; return $args; } /** * get_results * * Returns an array of results for the given args. * * @date 31/7/18 * @since 5.7.2 * * @param array args The query args. * @return array */ function get_results( $args ) { $results = array(); // Prepare args for quey. $args = $this->prepare_args( $args ); // Get result groups. if( !empty( $args['role__in']) ) { $roles = acf_get_user_role_labels( $args['role__in'] ); } else { $roles = acf_get_user_role_labels(); } // Return a flat array of results when searching or when queriying one group only. if( $this->is_search || count($roles) === 1 ) { // Query users and append to results. $wp_user_query = new WP_User_Query( $args ); $users = (array) $wp_user_query->get_results(); $total_users = $wp_user_query->get_total(); foreach( $users as $user ) { $results[] = $this->get_result( $user ); } // Determine if more results exist. // As this query does not return grouped results, the calculation can be exact (">"). $this->more = ( $total_users > count($users) + $args['offset'] ); // Otherwise, group results via role. } else { // Unset args that will interfer with query results. unset( $args['role__in'], $args['role__not_in'] ); // Loop over each role. foreach( $roles as $role => $role_label ) { // Query users (for this role only). $args['role'] = $role; $wp_user_query = new WP_User_Query( $args ); $users = (array) $wp_user_query->get_results(); $total_users = $wp_user_query->get_total(); //acf_log( $args ); //acf_log( '- ', count($users) ); //acf_log( '- ', $total_users ); // If users were found for this query... if( $users ) { // Append optgroup of results. $role_results = array(); foreach( $users as $user ) { $role_results[] = $this->get_result( $user ); } $results[] = array( 'text' => $role_label, 'children' => $role_results ); // End loop when enough results have been found. if( count($users) === $args['number'] ) { // Determine if more results exist. // As this query does return grouped results, the calculation is best left fuzzy to avoid querying the next group (">="). $this->more = ( $total_users >= count($users) + $args['offset'] ); break; // Otherwise, modify the args so that the next query can continue on correctly. } else { $args['offset'] = 0; $args['number'] -= count($users); } // If no users were found (for the current pagination args), but there were users found for previous pages... // Modify the args so that the next query is offset slightly less (the number of total users) and can continue on correctly. } elseif( $total_users ) { $args['offset'] -= $total_users; continue; // Ignore roles that will never return a result. } else { continue; } } } /** * Filters the query results. * * @date 21/5/19 * @since 5.8.1 * * @param array $results The query results. * @param array $args The query args. * @param ACF_Ajax_Query $query The query object. */ return apply_filters( "acf/ajax/query_users/results", $results, $args, $this ); } /** * get_result * * Returns a single result for the given item object. * * @date 31/7/18 * @since 5.7.2 * * @param mixed $item A single item from the queried results. * @return string */ function get_result( $user ) { $item = acf_get_user_result( $user ); /** * Filters the result item. * * @date 21/5/19 * @since 5.8.1 * * @param array $item The choice id and text. * @param ACF_User $user The user object. * @param ACF_Ajax_Query $query The query object. */ return apply_filters( "acf/ajax/query_users/result", $item, $user, $this ); } /** * Filters the WP_User_Query search columns. * * @date 9/3/20 * @since 5.8.8 * * @param array $columns An array of column names to be searched. * @param string $search The search term. * @param WP_User_Query $WP_User_Query The WP_User_Query instance. * @return array */ function filter_search_columns( $columns, $search, $WP_User_Query ) { /** * Filters the column names to be searched. * * @date 21/5/19 * @since 5.8.1 * * @param array $columns An array of column names to be searched. * @param string $search The search term. * @param WP_User_Query $WP_User_Query The WP_User_Query instance. * @param ACF_Ajax_Query $query The query object. */ return apply_filters( "acf/ajax/query_users/search_columns", $columns, $search, $WP_User_Query, $this ); } } acf_new_instance('ACF_Ajax_Query_Users'); endif; // class_exists check