WP_User_Query::prepare_query( string|array $query = array() )

Prepares the query variables.


Parameters

$query

(string|array) (Optional) Array or string of Query parameters.

  • 'blog_id'
    (int) The site ID. Default is the current site.
  • 'role'
    (string|string[]) An array or a comma-separated list of role names that users must match to be included in results. Note that this is an inclusive list: users must match *each* role.
  • 'role__in'
    (string[]) An array of role names. Matched users must have at least one of these roles.
  • 'role__not_in'
    (string[]) An array of role names to exclude. Users matching one or more of these roles will not be included in results.
  • 'meta_key'
    (string|string[]) Meta key or keys to filter by.
  • 'meta_value'
    (string|string[]) Meta value or values to filter by.
  • 'meta_compare'
    (string) MySQL operator used for comparing the meta value. See WP_Meta_Query::__construct for accepted values and default value.
  • 'meta_compare_key'
    (string) MySQL operator used for comparing the meta key. See WP_Meta_Query::__construct for accepted values and default value.
  • 'meta_type'
    (string) MySQL data type that the meta_value column will be CAST to for comparisons. See WP_Meta_Query::__construct for accepted values and default value.
  • 'meta_type_key'
    (string) MySQL data type that the meta_key column will be CAST to for comparisons. See WP_Meta_Query::__construct for accepted values and default value.
  • 'meta_query'
    (array) An associative array of WP_Meta_Query arguments. See WP_Meta_Query::__construct for accepted values.
  • 'capability'
    (string|string[]) An array or a comma-separated list of capability names that users must match to be included in results. Note that this is an inclusive list: users must match *each* capability. Does NOT work for capabilities not in the database or filtered via 'map_meta_cap'.
  • 'capability__in'
    (string[]) An array of capability names. Matched users must have at least one of these capabilities. Does NOT work for capabilities not in the database or filtered via 'map_meta_cap'.
  • 'capability__not_in'
    (string[]) An array of capability names to exclude. Users matching one or more of these capabilities will not be included in results. Does NOT work for capabilities not in the database or filtered via 'map_meta_cap'.
  • 'include'
    (int[]) An array of user IDs to include.
  • 'exclude'
    (int[]) An array of user IDs to exclude.
  • 'search'
    (string) Search keyword. Searches for possible string matches on columns. When $search_columns is left empty, it tries to determine which column to search in based on search string.
  • 'search_columns'
    (string[]) Array of column names to be searched. Accepts 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name'.
  • 'orderby'
    (string|array) Field(s) to sort the retrieved users by. May be a single value, an array of values, or a multi-dimensional array with fields as keys and orders ('ASC' or 'DESC') as values. Accepted values are:
    • 'ID'
    • 'display_name' (or 'name')
    • 'include'
    • 'user_login' (or 'login')
    • 'login__in'
    • 'user_nicename' (or 'nicename'),
    • 'nicename__in'
    • 'user_email (or 'email')
    • 'user_url' (or 'url'),
    • 'user_registered' (or 'registered')
    • 'post_count'
    • 'meta_value',
    • 'meta_value_num'
    • The value of $meta_key
    • An array key of $meta_query To use 'meta_value' or 'meta_value_num', $meta_key must be also be defined. Default 'user_login'.
  • 'order'
    (string) Designates ascending or descending order of users. Order values passed as part of an $orderby array take precedence over this parameter. Accepts 'ASC', 'DESC'. Default 'ASC'.
  • 'offset'
    (int) Number of users to offset in retrieved results. Can be used in conjunction with pagination. Default 0.
  • 'number'
    (int) Number of users to limit the query for. Can be used in conjunction with pagination. Value -1 (all) is supported, but should be used with caution on larger sites. Default -1 (all users).
  • 'paged'
    (int) When used with number, defines the page of results to return. Default 1.
  • 'count_total'
    (bool) Whether to count the total number of users found. If pagination is not needed, setting this to false can improve performance. Default true.
  • 'fields'
    (string|string[]) Which fields to return. Single or all fields (string), or array of fields. Accepts:
  • 'ID'
  • 'display_name'
  • 'user_login'
  • 'user_nicename'
  • 'user_email'
  • 'user_url'
  • 'user_registered'
  • 'user_pass'
  • 'user_activation_key'
  • 'user_status'
  • 'spam' (only available on multisite installs)
  • 'deleted' (only available on multisite installs)
  • 'all' for all fields
  • 'all_with_meta' to include meta fields. Default 'all'.
  • 'who'
    (string) Type of users to query. Accepts 'authors'. Default empty (all users).
  • 'has_published_posts'
    (bool|string[]) Pass an array of post types to filter results to users who have published posts in those post types. true is an alias for all public post types.
  • 'nicename'
    (string) The user nicename.
  • 'nicename__in'
    (string[]) An array of nicenames to include. Users matching one of these nicenames will be included in results.
  • 'nicename__not_in'
    (string[]) An array of nicenames to exclude. Users matching one of these nicenames will not be included in results.
  • 'login'
    (string) The user login.
  • 'login__in'
    (string[]) An array of logins to include. Users matching one of these logins will be included in results.
  • 'login__not_in'
    (string[]) An array of logins to exclude. Users matching one of these logins will not be included in results.
  • Default value: array()


    Top ↑

    Source

    File: wp-includes/class-wp-user-query.php

    	public function prepare_query( $query = array() ) {
    		global $wpdb;
    
    		if ( empty( $this->query_vars ) || ! empty( $query ) ) {
    			$this->query_limit = null;
    			$this->query_vars  = $this->fill_query_vars( $query );
    		}
    
    		/**
    		 * Fires before the WP_User_Query has been parsed.
    		 *
    		 * The passed WP_User_Query object contains the query variables,
    		 * not yet passed into SQL.
    		 *
    		 * @since 4.0.0
    		 *
    		 * @param WP_User_Query $query Current instance of WP_User_Query (passed by reference).
    		 */
    		do_action_ref_array( 'pre_get_users', array( &$this ) );
    
    		// Ensure that query vars are filled after 'pre_get_users'.
    		$qv =& $this->query_vars;
    		$qv = $this->fill_query_vars( $qv );
    
    		$allowed_fields = array(
    			'id',
    			'user_login',
    			'user_pass',
    			'user_nicename',
    			'user_email',
    			'user_url',
    			'user_registered',
    			'user_activation_key',
    			'user_status',
    			'display_name',
    		);
    		if ( is_multisite() ) {
    			$allowed_fields[] = 'spam';
    			$allowed_fields[] = 'deleted';
    		}
    
    		if ( is_array( $qv['fields'] ) ) {
    			$qv['fields'] = array_map( 'strtolower', $qv['fields'] );
    			$qv['fields'] = array_intersect( array_unique( $qv['fields'] ), $allowed_fields );
    
    			if ( empty( $qv['fields'] ) ) {
    				$qv['fields'] = array( 'id' );
    			}
    
    			$this->query_fields = array();
    			foreach ( $qv['fields'] as $field ) {
    				$field                = 'id' === $field ? 'ID' : sanitize_key( $field );
    				$this->query_fields[] = "$wpdb->users.$field";
    			}
    			$this->query_fields = implode( ',', $this->query_fields );
    		} elseif ( 'all' === $qv['fields'] ) {
    			$this->query_fields = "$wpdb->users.*";
    		} elseif ( ! in_array( $qv['fields'], $allowed_fields, true ) ) {
    			$this->query_fields = "$wpdb->users.ID";
    		} else {
    			$field              = 'id' === strtolower( $qv['fields'] ) ? 'ID' : sanitize_key( $qv['fields'] );
    			$this->query_fields = "$wpdb->users.$field";
    		}
    
    		if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
    			$this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields;
    		}
    
    		$this->query_from  = "FROM $wpdb->users";
    		$this->query_where = 'WHERE 1=1';
    
    		// Parse and sanitize 'include', for use by 'orderby' as well as 'include' below.
    		if ( ! empty( $qv['include'] ) ) {
    			$include = wp_parse_id_list( $qv['include'] );
    		} else {
    			$include = false;
    		}
    
    		$blog_id = 0;
    		if ( isset( $qv['blog_id'] ) ) {
    			$blog_id = absint( $qv['blog_id'] );
    		}
    
    		if ( $qv['has_published_posts'] && $blog_id ) {
    			if ( true === $qv['has_published_posts'] ) {
    				$post_types = get_post_types( array( 'public' => true ) );
    			} else {
    				$post_types = (array) $qv['has_published_posts'];
    			}
    
    			foreach ( $post_types as &$post_type ) {
    				$post_type = $wpdb->prepare( '%s', $post_type );
    			}
    
    			$posts_table        = $wpdb->get_blog_prefix( $blog_id ) . 'posts';
    			$this->query_where .= " AND $wpdb->users.ID IN ( SELECT DISTINCT $posts_table.post_author FROM $posts_table WHERE $posts_table.post_status = 'publish' AND $posts_table.post_type IN ( " . implode( ', ', $post_types ) . ' ) )';
    		}
    
    		// nicename
    		if ( '' !== $qv['nicename'] ) {
    			$this->query_where .= $wpdb->prepare( ' AND user_nicename = %s', $qv['nicename'] );
    		}
    
    		if ( ! empty( $qv['nicename__in'] ) ) {
    			$sanitized_nicename__in = array_map( 'esc_sql', $qv['nicename__in'] );
    			$nicename__in           = implode( "','", $sanitized_nicename__in );
    			$this->query_where     .= " AND user_nicename IN ( '$nicename__in' )";
    		}
    
    		if ( ! empty( $qv['nicename__not_in'] ) ) {
    			$sanitized_nicename__not_in = array_map( 'esc_sql', $qv['nicename__not_in'] );
    			$nicename__not_in           = implode( "','", $sanitized_nicename__not_in );
    			$this->query_where         .= " AND user_nicename NOT IN ( '$nicename__not_in' )";
    		}
    
    		// login
    		if ( '' !== $qv['login'] ) {
    			$this->query_where .= $wpdb->prepare( ' AND user_login = %s', $qv['login'] );
    		}
    
    		if ( ! empty( $qv['login__in'] ) ) {
    			$sanitized_login__in = array_map( 'esc_sql', $qv['login__in'] );
    			$login__in           = implode( "','", $sanitized_login__in );
    			$this->query_where  .= " AND user_login IN ( '$login__in' )";
    		}
    
    		if ( ! empty( $qv['login__not_in'] ) ) {
    			$sanitized_login__not_in = array_map( 'esc_sql', $qv['login__not_in'] );
    			$login__not_in           = implode( "','", $sanitized_login__not_in );
    			$this->query_where      .= " AND user_login NOT IN ( '$login__not_in' )";
    		}
    
    		// Meta query.
    		$this->meta_query = new WP_Meta_Query();
    		$this->meta_query->parse_query_vars( $qv );
    
    		if ( isset( $qv['who'] ) && 'authors' === $qv['who'] && $blog_id ) {
    			_deprecated_argument(
    				'WP_User_Query',
    				'5.9.0',
    				sprintf(
    					/* translators: 1: who, 2: capability */
    					__( '%1$s is deprecated. Use %2$s instead.' ),
    					'<code>who</code>',
    					'<code>capability</code>'
    				)
    			);
    
    			$who_query = array(
    				'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'user_level',
    				'value'   => 0,
    				'compare' => '!=',
    			);
    
    			// Prevent extra meta query.
    			$qv['blog_id'] = 0;
    			$blog_id       = 0;
    
    			if ( empty( $this->meta_query->queries ) ) {
    				$this->meta_query->queries = array( $who_query );
    			} else {
    				// Append the cap query to the original queries and reparse the query.
    				$this->meta_query->queries = array(
    					'relation' => 'AND',
    					array( $this->meta_query->queries, $who_query ),
    				);
    			}
    
    			$this->meta_query->parse_query_vars( $this->meta_query->queries );
    		}
    
    		// Roles.
    		$roles = array();
    		if ( isset( $qv['role'] ) ) {
    			if ( is_array( $qv['role'] ) ) {
    				$roles = $qv['role'];
    			} elseif ( is_string( $qv['role'] ) && ! empty( $qv['role'] ) ) {
    				$roles = array_map( 'trim', explode( ',', $qv['role'] ) );
    			}
    		}
    
    		$role__in = array();
    		if ( isset( $qv['role__in'] ) ) {
    			$role__in = (array) $qv['role__in'];
    		}
    
    		$role__not_in = array();
    		if ( isset( $qv['role__not_in'] ) ) {
    			$role__not_in = (array) $qv['role__not_in'];
    		}
    
    		// Capabilities.
    		$available_roles = array();
    
    		if ( ! empty( $qv['capability'] ) || ! empty( $qv['capability__in'] ) || ! empty( $qv['capability__not_in'] ) ) {
    			global $wp_roles;
    
    			$wp_roles->for_site( $blog_id );
    			$available_roles = $wp_roles->roles;
    		}
    
    		$capabilities = array();
    		if ( ! empty( $qv['capability'] ) ) {
    			if ( is_array( $qv['capability'] ) ) {
    				$capabilities = $qv['capability'];
    			} elseif ( is_string( $qv['capability'] ) ) {
    				$capabilities = array_map( 'trim', explode( ',', $qv['capability'] ) );
    			}
    		}
    
    		$capability__in = array();
    		if ( ! empty( $qv['capability__in'] ) ) {
    			$capability__in = (array) $qv['capability__in'];
    		}
    
    		$capability__not_in = array();
    		if ( ! empty( $qv['capability__not_in'] ) ) {
    			$capability__not_in = (array) $qv['capability__not_in'];
    		}
    
    		// Keep track of all capabilities and the roles they're added on.
    		$caps_with_roles = array();
    
    		foreach ( $available_roles as $role => $role_data ) {
    			$role_caps = array_keys( array_filter( $role_data['capabilities'] ) );
    
    			foreach ( $capabilities as $cap ) {
    				if ( in_array( $cap, $role_caps, true ) ) {
    					$caps_with_roles[ $cap ][] = $role;
    					break;
    				}
    			}
    
    			foreach ( $capability__in as $cap ) {
    				if ( in_array( $cap, $role_caps, true ) ) {
    					$role__in[] = $role;
    					break;
    				}
    			}
    
    			foreach ( $capability__not_in as $cap ) {
    				if ( in_array( $cap, $role_caps, true ) ) {
    					$role__not_in[] = $role;
    					break;
    				}
    			}
    		}
    
    		$role__in     = array_merge( $role__in, $capability__in );
    		$role__not_in = array_merge( $role__not_in, $capability__not_in );
    
    		$roles        = array_unique( $roles );
    		$role__in     = array_unique( $role__in );
    		$role__not_in = array_unique( $role__not_in );
    
    		// Support querying by capabilities added directly to users.
    		if ( $blog_id && ! empty( $capabilities ) ) {
    			$capabilities_clauses = array( 'relation' => 'AND' );
    
    			foreach ( $capabilities as $cap ) {
    				$clause = array( 'relation' => 'OR' );
    
    				$clause[] = array(
    					'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
    					'value'   => '"' . $cap . '"',
    					'compare' => 'LIKE',
    				);
    
    				if ( ! empty( $caps_with_roles[ $cap ] ) ) {
    					foreach ( $caps_with_roles[ $cap ] as $role ) {
    						$clause[] = array(
    							'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
    							'value'   => '"' . $role . '"',
    							'compare' => 'LIKE',
    						);
    					}
    				}
    
    				$capabilities_clauses[] = $clause;
    			}
    
    			$role_queries[] = $capabilities_clauses;
    
    			if ( empty( $this->meta_query->queries ) ) {
    				$this->meta_query->queries[] = $capabilities_clauses;
    			} else {
    				// Append the cap query to the original queries and reparse the query.
    				$this->meta_query->queries = array(
    					'relation' => 'AND',
    					array( $this->meta_query->queries, array( $capabilities_clauses ) ),
    				);
    			}
    
    			$this->meta_query->parse_query_vars( $this->meta_query->queries );
    		}
    
    		if ( $blog_id && ( ! empty( $roles ) || ! empty( $role__in ) || ! empty( $role__not_in ) || is_multisite() ) ) {
    			$role_queries = array();
    
    			$roles_clauses = array( 'relation' => 'AND' );
    			if ( ! empty( $roles ) ) {
    				foreach ( $roles as $role ) {
    					$roles_clauses[] = array(
    						'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
    						'value'   => '"' . $role . '"',
    						'compare' => 'LIKE',
    					);
    				}
    
    				$role_queries[] = $roles_clauses;
    			}
    
    			$role__in_clauses = array( 'relation' => 'OR' );
    			if ( ! empty( $role__in ) ) {
    				foreach ( $role__in as $role ) {
    					$role__in_clauses[] = array(
    						'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
    						'value'   => '"' . $role . '"',
    						'compare' => 'LIKE',
    					);
    				}
    
    				$role_queries[] = $role__in_clauses;
    			}
    
    			$role__not_in_clauses = array( 'relation' => 'AND' );
    			if ( ! empty( $role__not_in ) ) {
    				foreach ( $role__not_in as $role ) {
    					$role__not_in_clauses[] = array(
    						'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
    						'value'   => '"' . $role . '"',
    						'compare' => 'NOT LIKE',
    					);
    				}
    
    				$role_queries[] = $role__not_in_clauses;
    			}
    
    			// If there are no specific roles named, make sure the user is a member of the site.
    			if ( empty( $role_queries ) ) {
    				$role_queries[] = array(
    					'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
    					'compare' => 'EXISTS',
    				);
    			}
    
    			// Specify that role queries should be joined with AND.
    			$role_queries['relation'] = 'AND';
    
    			if ( empty( $this->meta_query->queries ) ) {
    				$this->meta_query->queries = $role_queries;
    			} else {
    				// Append the cap query to the original queries and reparse the query.
    				$this->meta_query->queries = array(
    					'relation' => 'AND',
    					array( $this->meta_query->queries, $role_queries ),
    				);
    			}
    
    			$this->meta_query->parse_query_vars( $this->meta_query->queries );
    		}
    
    		if ( ! empty( $this->meta_query->queries ) ) {
    			$clauses            = $this->meta_query->get_sql( 'user', $wpdb->users, 'ID', $this );
    			$this->query_from  .= $clauses['join'];
    			$this->query_where .= $clauses['where'];
    
    			if ( $this->meta_query->has_or_relation() ) {
    				$this->query_fields = 'DISTINCT ' . $this->query_fields;
    			}
    		}
    
    		// Sorting.
    		$qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : '';
    		$order       = $this->parse_order( $qv['order'] );
    
    		if ( empty( $qv['orderby'] ) ) {
    			// Default order is by 'user_login'.
    			$ordersby = array( 'user_login' => $order );
    		} elseif ( is_array( $qv['orderby'] ) ) {
    			$ordersby = $qv['orderby'];
    		} else {
    			// 'orderby' values may be a comma- or space-separated list.
    			$ordersby = preg_split( '/[,\s]+/', $qv['orderby'] );
    		}
    
    		$orderby_array = array();
    		foreach ( $ordersby as $_key => $_value ) {
    			if ( ! $_value ) {
    				continue;
    			}
    
    			if ( is_int( $_key ) ) {
    				// Integer key means this is a flat array of 'orderby' fields.
    				$_orderby = $_value;
    				$_order   = $order;
    			} else {
    				// Non-integer key means this the key is the field and the value is ASC/DESC.
    				$_orderby = $_key;
    				$_order   = $_value;
    			}
    
    			$parsed = $this->parse_orderby( $_orderby );
    
    			if ( ! $parsed ) {
    				continue;
    			}
    
    			if ( 'nicename__in' === $_orderby || 'login__in' === $_orderby ) {
    				$orderby_array[] = $parsed;
    			} else {
    				$orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
    			}
    		}
    
    		// If no valid clauses were found, order by user_login.
    		if ( empty( $orderby_array ) ) {
    			$orderby_array[] = "user_login $order";
    		}
    
    		$this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array );
    
    		// Limit.
    		if ( isset( $qv['number'] ) && $qv['number'] > 0 ) {
    			if ( $qv['offset'] ) {
    				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] );
    			} else {
    				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] );
    			}
    		}
    
    		$search = '';
    		if ( isset( $qv['search'] ) ) {
    			$search = trim( $qv['search'] );
    		}
    
    		if ( $search ) {
    			$leading_wild  = ( ltrim( $search, '*' ) != $search );
    			$trailing_wild = ( rtrim( $search, '*' ) != $search );
    			if ( $leading_wild && $trailing_wild ) {
    				$wild = 'both';
    			} elseif ( $leading_wild ) {
    				$wild = 'leading';
    			} elseif ( $trailing_wild ) {
    				$wild = 'trailing';
    			} else {
    				$wild = false;
    			}
    			if ( $wild ) {
    				$search = trim( $search, '*' );
    			}
    
    			$search_columns = array();
    			if ( $qv['search_columns'] ) {
    				$search_columns = array_intersect( $qv['search_columns'], array( 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name' ) );
    			}
    			if ( ! $search_columns ) {
    				if ( false !== strpos( $search, '@' ) ) {
    					$search_columns = array( 'user_email' );
    				} elseif ( is_numeric( $search ) ) {
    					$search_columns = array( 'user_login', 'ID' );
    				} elseif ( preg_match( '|^https?://|', $search ) && ! ( is_multisite() && wp_is_large_network( 'users' ) ) ) {
    					$search_columns = array( 'user_url' );
    				} else {
    					$search_columns = array( 'user_login', 'user_url', 'user_email', 'user_nicename', 'display_name' );
    				}
    			}
    
    			/**
    			 * Filters the columns to search in a WP_User_Query search.
    			 *
    			 * The default columns depend on the search term, and include 'ID', 'user_login',
    			 * 'user_email', 'user_url', 'user_nicename', and 'display_name'.
    			 *
    			 * @since 3.6.0
    			 *
    			 * @param string[]      $search_columns Array of column names to be searched.
    			 * @param string        $search         Text being searched.
    			 * @param WP_User_Query $query          The current WP_User_Query instance.
    			 */
    			$search_columns = apply_filters( 'user_search_columns', $search_columns, $search, $this );
    
    			$this->query_where .= $this->get_search_sql( $search, $search_columns, $wild );
    		}
    
    		if ( ! empty( $include ) ) {
    			// Sanitized earlier.
    			$ids                = implode( ',', $include );
    			$this->query_where .= " AND $wpdb->users.ID IN ($ids)";
    		} elseif ( ! empty( $qv['exclude'] ) ) {
    			$ids                = implode( ',', wp_parse_id_list( $qv['exclude'] ) );
    			$this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)";
    		}
    
    		// Date queries are allowed for the user_registered field.
    		if ( ! empty( $qv['date_query'] ) && is_array( $qv['date_query'] ) ) {
    			$date_query         = new WP_Date_Query( $qv['date_query'], 'user_registered' );
    			$this->query_where .= $date_query->get_sql();
    		}
    
    		/**
    		 * Fires after the WP_User_Query has been parsed, and before
    		 * the query is executed.
    		 *
    		 * The passed WP_User_Query object contains SQL parts formed
    		 * from parsing the given query.
    		 *
    		 * @since 3.1.0
    		 *
    		 * @param WP_User_Query $query Current instance of WP_User_Query (passed by reference).
    		 */
    		do_action_ref_array( 'pre_user_query', array( &$this ) );
    	}
    


    Top ↑

    Changelog

    Changelog
    Version Description
    5.9.0 Added 'capability', 'capability__in', and 'capability__not_in' parameters.
    5.3.0 Introduced the 'meta_type_key' parameter.
    5.1.0 Introduced the 'meta_compare_key' parameter.
    4.7.0 Added 'nicename', 'nicename__in', 'nicename__not_in', 'login', 'login__in', and 'login__not_in' parameters.
    4.4.0 Added 'paged', 'role__in', and 'role__not_in' parameters. The 'role' parameter was updated to permit an array or comma-separated list of values. The 'number' parameter was updated to support querying for all users with using -1.
    4.3.0 Added 'has_published_posts' parameter.
    4.2.0 Added 'meta_value_num' support for $orderby parameter. Added multi-dimensional array syntax for $orderby parameter.
    4.1.0 Added the ability to order by the include value.
    3.1.0 Introduced.

    Top ↑

    User Contributed Notes

    1. Skip to note 2 content
      Contributed by bcworkz

      The specification for providing meta_query keys as orderby parameters is confusing at best. The docs say to use “fields as keys” and an accepted value is “an array key of $meta_query“. In fact values must be the array key from the array returned by $WP_Meta_Query::get_clauses(). You could get this array by instantiating WP_Meta_Query with your meta_query arguments, then calling WP_Meta_Query::get_sql('user','wp_users','ID'), (provide your correct table name for wp_users) then calling $WP_Meta_Query::get_clauses(). The array keys in the returned array are the correct keys to assign to the orderby argument.

      A perhaps easier way to get the proper keys is to instantiate WP_User_Query with your meta_query arguments, then examining the SQL query in WP_User_Query::request. In particular the WHERE portion related to user meta. The keys are the table aliases used in the SQL query. The first meta_query argument’s key is always the table name, usually wp_usermeta unless you specified a different prefix in wp-config.php. Additional meta_query arguments are assigned aliases like mt1, mt2, etc. The related meta key name occurs to the right of the = sign in each case. Thus your orderby argument might be array('mt1', 'wp_usermeta',) or if you need differing order arguments, array('mt1'=>'ASC', 'wp_usermeta'=>'DESC',)

      For reference, the user_meta part of the SQL WHERE clause may look something like this:
      (( wp_usermeta.meta_key = 'foo' AND wp_usermeta.meta_value LIKE '%bar%' )
      AND
      ( mt1.meta_key = 'sna' AND mt1.meta_value LIKE '%fu%' ))

    2. Skip to note 6 content
      Contributed by Michael Nelson

      WordPress 5.9 added arguments “capability”, “capability__in” and “capability__not_in” and deprecated the “who” parameter.

      So if you want to write code that works with WordPress 5.8 and 5.9 without any deprecation warnings, you need to check the current WordPress version like in this trac ticket:

      // Capability queries were only introduced in WP 5.9.
      if ( version_compare( $GLOBALS['wp_version'], '5.9', '<' ) ) {
              $args['who'] = 'authors';
      } else {
              $args['capability'] = ['edit_posts'];
      }
      
    3. Skip to note 7 content
      Contributed by Kento

      You can use the date_query parameter to obtain users that have registered on a particular date, for example:

      $users = get_users( [
          'date_query' => [ 'day' => 1, 'month' => 6, 'year' => 2022 ]
      ] );

      It’s also possible to obtain users registered for a date range, as in this example:

      $users = get_users(
      	array(
              'fields' => 'ID',
              'date_query' => array(
                  'compare' => 'BETWEEN',
                  'day'     => [1,31],
                  'month'   => [1,12],
                  'year'    => [2022,2022]
              )
          )
      );

      Equivalent using the WP_User_Query class:

      $args = array(
          'date_query' => array(
              'compare' => 'BETWEEN',
              'day'     => [1,31],
              'month'   => [1,12],
              'year'    => [2022,2022]
          )
      );
      $user_query = new WP_User_Query( $args );
      $users = $user_query->get_results();

    You must log in before being able to contribute a note or feedback.