274 lines
7.4 KiB
PHP
274 lines
7.4 KiB
PHP
|
<?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
|