wp/wp-includes/class-wp-user-query.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    23 	 * @var array
    23 	 * @var array
    24 	 */
    24 	 */
    25 	public $query_vars = array();
    25 	public $query_vars = array();
    26 
    26 
    27 	/**
    27 	/**
    28 	 * List of found user ids
    28 	 * List of found user IDs.
    29 	 *
    29 	 *
    30 	 * @since 3.1.0
    30 	 * @since 3.1.0
    31 	 * @var array
    31 	 * @var array
    32 	 */
    32 	 */
    33 	private $results;
    33 	private $results;
    56 	 */
    56 	 */
    57 	public $request;
    57 	public $request;
    58 
    58 
    59 	private $compat_fields = array( 'results', 'total_users' );
    59 	private $compat_fields = array( 'results', 'total_users' );
    60 
    60 
    61 	// SQL clauses
    61 	// SQL clauses.
    62 	public $query_fields;
    62 	public $query_fields;
    63 	public $query_from;
    63 	public $query_from;
    64 	public $query_where;
    64 	public $query_where;
    65 	public $query_orderby;
    65 	public $query_orderby;
    66 	public $query_limit;
    66 	public $query_limit;
   157 	 *     @type array        $include             An array of user IDs to include. Default empty array.
   157 	 *     @type array        $include             An array of user IDs to include. Default empty array.
   158 	 *     @type array        $exclude             An array of user IDs to exclude. Default empty array.
   158 	 *     @type array        $exclude             An array of user IDs to exclude. Default empty array.
   159 	 *     @type string       $search              Search keyword. Searches for possible string matches on columns.
   159 	 *     @type string       $search              Search keyword. Searches for possible string matches on columns.
   160 	 *                                             When `$search_columns` is left empty, it tries to determine which
   160 	 *                                             When `$search_columns` is left empty, it tries to determine which
   161 	 *                                             column to search in based on search string. Default empty.
   161 	 *                                             column to search in based on search string. Default empty.
   162 	 *     @type array        $search_columns      Array of column names to be searched. Accepts 'ID', 'login',
   162 	 *     @type array        $search_columns      Array of column names to be searched. Accepts 'ID', 'user_login',
   163 	 *                                             'nicename', 'email', 'url'. Default empty array.
   163 	 *                                             'user_email', 'user_url', 'user_nicename', 'display_name'.
       
   164 	 *                                             Default empty array.
   164 	 *     @type string|array $orderby             Field(s) to sort the retrieved users by. May be a single value,
   165 	 *     @type string|array $orderby             Field(s) to sort the retrieved users by. May be a single value,
   165 	 *                                             an array of values, or a multi-dimensional array with fields as
   166 	 *                                             an array of values, or a multi-dimensional array with fields as
   166 	 *                                             keys and orders ('ASC' or 'DESC') as values. Accepted values are
   167 	 *                                             keys and orders ('ASC' or 'DESC') as values. Accepted values are
   167 	 *                                             'ID', 'display_name' (or 'name'), 'include', 'user_login'
   168 	 *                                             'ID', 'display_name' (or 'name'), 'include', 'user_login'
   168 	 *                                             (or 'login'), 'login__in', 'user_nicename' (or 'nicename'),
   169 	 *                                             (or 'login'), 'login__in', 'user_nicename' (or 'nicename'),
   177 	 *     @type int          $offset              Number of users to offset in retrieved results. Can be used in
   178 	 *     @type int          $offset              Number of users to offset in retrieved results. Can be used in
   178 	 *                                             conjunction with pagination. Default 0.
   179 	 *                                             conjunction with pagination. Default 0.
   179 	 *     @type int          $number              Number of users to limit the query for. Can be used in
   180 	 *     @type int          $number              Number of users to limit the query for. Can be used in
   180 	 *                                             conjunction with pagination. Value -1 (all) is supported, but
   181 	 *                                             conjunction with pagination. Value -1 (all) is supported, but
   181 	 *                                             should be used with caution on larger sites.
   182 	 *                                             should be used with caution on larger sites.
   182 	 *                                             Default empty (all users).
   183 	 *                                             Default -1 (all users).
   183 	 *     @type int          $paged               When used with number, defines the page of results to return.
   184 	 *     @type int          $paged               When used with number, defines the page of results to return.
   184 	 *                                             Default 1.
   185 	 *                                             Default 1.
   185 	 *     @type bool         $count_total         Whether to count the total number of users found. If pagination
   186 	 *     @type bool         $count_total         Whether to count the total number of users found. If pagination
   186 	 *                                             is not needed, setting this to false can improve performance.
   187 	 *                                             is not needed, setting this to false can improve performance.
   187 	 *                                             Default true.
   188 	 *                                             Default true.
   239 			foreach ( $qv['fields'] as $field ) {
   240 			foreach ( $qv['fields'] as $field ) {
   240 				$field                = 'ID' === $field ? 'ID' : sanitize_key( $field );
   241 				$field                = 'ID' === $field ? 'ID' : sanitize_key( $field );
   241 				$this->query_fields[] = "$wpdb->users.$field";
   242 				$this->query_fields[] = "$wpdb->users.$field";
   242 			}
   243 			}
   243 			$this->query_fields = implode( ',', $this->query_fields );
   244 			$this->query_fields = implode( ',', $this->query_fields );
   244 		} elseif ( 'all' == $qv['fields'] ) {
   245 		} elseif ( 'all' === $qv['fields'] ) {
   245 			$this->query_fields = "$wpdb->users.*";
   246 			$this->query_fields = "$wpdb->users.*";
   246 		} else {
   247 		} else {
   247 			$this->query_fields = "$wpdb->users.ID";
   248 			$this->query_fields = "$wpdb->users.ID";
   248 		}
   249 		}
   249 
   250 
   317 
   318 
   318 		// Meta query.
   319 		// Meta query.
   319 		$this->meta_query = new WP_Meta_Query();
   320 		$this->meta_query = new WP_Meta_Query();
   320 		$this->meta_query->parse_query_vars( $qv );
   321 		$this->meta_query->parse_query_vars( $qv );
   321 
   322 
   322 		if ( isset( $qv['who'] ) && 'authors' == $qv['who'] && $blog_id ) {
   323 		if ( isset( $qv['who'] ) && 'authors' === $qv['who'] && $blog_id ) {
   323 			$who_query = array(
   324 			$who_query = array(
   324 				'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'user_level',
   325 				'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'user_level',
   325 				'value'   => 0,
   326 				'value'   => 0,
   326 				'compare' => '!=',
   327 				'compare' => '!=',
   327 			);
   328 			);
   328 
   329 
   329 			// Prevent extra meta query.
   330 			// Prevent extra meta query.
   330 			$qv['blog_id'] = $blog_id = 0;
   331 			$qv['blog_id'] = 0;
       
   332 			$blog_id       = 0;
   331 
   333 
   332 			if ( empty( $this->meta_query->queries ) ) {
   334 			if ( empty( $this->meta_query->queries ) ) {
   333 				$this->meta_query->queries = array( $who_query );
   335 				$this->meta_query->queries = array( $who_query );
   334 			} else {
   336 			} else {
   335 				// Append the cap query to the original queries and reparse the query.
   337 				// Append the cap query to the original queries and reparse the query.
   435 			if ( $this->meta_query->has_or_relation() ) {
   437 			if ( $this->meta_query->has_or_relation() ) {
   436 				$this->query_fields = 'DISTINCT ' . $this->query_fields;
   438 				$this->query_fields = 'DISTINCT ' . $this->query_fields;
   437 			}
   439 			}
   438 		}
   440 		}
   439 
   441 
   440 		// sorting
   442 		// Sorting.
   441 		$qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : '';
   443 		$qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : '';
   442 		$order       = $this->parse_order( $qv['order'] );
   444 		$order       = $this->parse_order( $qv['order'] );
   443 
   445 
   444 		if ( empty( $qv['orderby'] ) ) {
   446 		if ( empty( $qv['orderby'] ) ) {
   445 			// Default order is by 'user_login'.
   447 			// Default order is by 'user_login'.
   485 			$orderby_array[] = "user_login $order";
   487 			$orderby_array[] = "user_login $order";
   486 		}
   488 		}
   487 
   489 
   488 		$this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array );
   490 		$this->query_orderby = 'ORDER BY ' . implode( ', ', $orderby_array );
   489 
   491 
   490 		// limit
   492 		// Limit.
   491 		if ( isset( $qv['number'] ) && $qv['number'] > 0 ) {
   493 		if ( isset( $qv['number'] ) && $qv['number'] > 0 ) {
   492 			if ( $qv['offset'] ) {
   494 			if ( $qv['offset'] ) {
   493 				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] );
   495 				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $qv['number'] );
   494 			} else {
   496 			} else {
   495 				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] );
   497 				$this->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $qv['number'] );
   534 			}
   536 			}
   535 
   537 
   536 			/**
   538 			/**
   537 			 * Filters the columns to search in a WP_User_Query search.
   539 			 * Filters the columns to search in a WP_User_Query search.
   538 			 *
   540 			 *
   539 			 * The default columns depend on the search term, and include 'user_email',
   541 			 * The default columns depend on the search term, and include 'ID', 'user_login',
   540 			 * 'user_login', 'ID', 'user_url', 'display_name', and 'user_nicename'.
   542 			 * 'user_email', 'user_url', 'user_nicename', and 'display_name'.
   541 			 *
   543 			 *
   542 			 * @since 3.6.0
   544 			 * @since 3.6.0
   543 			 *
   545 			 *
   544 			 * @param string[]      $search_columns Array of column names to be searched.
   546 			 * @param string[]      $search_columns Array of column names to be searched.
   545 			 * @param string        $search         Text being searched.
   547 			 * @param string        $search         Text being searched.
   610 		$this->results = apply_filters_ref_array( 'users_pre_query', array( null, &$this ) );
   612 		$this->results = apply_filters_ref_array( 'users_pre_query', array( null, &$this ) );
   611 
   613 
   612 		if ( null === $this->results ) {
   614 		if ( null === $this->results ) {
   613 			$this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit";
   615 			$this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit";
   614 
   616 
   615 			if ( is_array( $qv['fields'] ) || 'all' == $qv['fields'] ) {
   617 			if ( is_array( $qv['fields'] ) || 'all' === $qv['fields'] ) {
   616 				$this->results = $wpdb->get_results( $this->request );
   618 				$this->results = $wpdb->get_results( $this->request );
   617 			} else {
   619 			} else {
   618 				$this->results = $wpdb->get_col( $this->request );
   620 				$this->results = $wpdb->get_col( $this->request );
   619 			}
   621 			}
   620 
   622 
   638 
   640 
   639 		if ( ! $this->results ) {
   641 		if ( ! $this->results ) {
   640 			return;
   642 			return;
   641 		}
   643 		}
   642 
   644 
   643 		if ( 'all_with_meta' == $qv['fields'] ) {
   645 		if ( 'all_with_meta' === $qv['fields'] ) {
   644 			cache_users( $this->results );
   646 			cache_users( $this->results );
   645 
   647 
   646 			$r = array();
   648 			$r = array();
   647 			foreach ( $this->results as $userid ) {
   649 			foreach ( $this->results as $userid ) {
   648 				$r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] );
   650 				$r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] );
   649 			}
   651 			}
   650 
   652 
   651 			$this->results = $r;
   653 			$this->results = $r;
   652 		} elseif ( 'all' == $qv['fields'] ) {
   654 		} elseif ( 'all' === $qv['fields'] ) {
   653 			foreach ( $this->results as $key => $user ) {
   655 			foreach ( $this->results as $key => $user ) {
   654 				$this->results[ $key ] = new WP_User( $user, '', $qv['blog_id'] );
   656 				$this->results[ $key ] = new WP_User( $user, '', $qv['blog_id'] );
   655 			}
   657 			}
   656 		}
   658 		}
   657 	}
   659 	}
   676 	 * Set query variable.
   678 	 * Set query variable.
   677 	 *
   679 	 *
   678 	 * @since 3.5.0
   680 	 * @since 3.5.0
   679 	 *
   681 	 *
   680 	 * @param string $query_var Query variable key.
   682 	 * @param string $query_var Query variable key.
   681 	 * @param mixed $value Query variable value.
   683 	 * @param mixed  $value     Query variable value.
   682 	 */
   684 	 */
   683 	public function set( $query_var, $value ) {
   685 	public function set( $query_var, $value ) {
   684 		$this->query_vars[ $query_var ] = $value;
   686 		$this->query_vars[ $query_var ] = $value;
   685 	}
   687 	}
   686 
   688 
   699 	 */
   701 	 */
   700 	protected function get_search_sql( $string, $cols, $wild = false ) {
   702 	protected function get_search_sql( $string, $cols, $wild = false ) {
   701 		global $wpdb;
   703 		global $wpdb;
   702 
   704 
   703 		$searches      = array();
   705 		$searches      = array();
   704 		$leading_wild  = ( 'leading' == $wild || 'both' == $wild ) ? '%' : '';
   706 		$leading_wild  = ( 'leading' === $wild || 'both' === $wild ) ? '%' : '';
   705 		$trailing_wild = ( 'trailing' == $wild || 'both' == $wild ) ? '%' : '';
   707 		$trailing_wild = ( 'trailing' === $wild || 'both' === $wild ) ? '%' : '';
   706 		$like          = $leading_wild . $wpdb->esc_like( $string ) . $trailing_wild;
   708 		$like          = $leading_wild . $wpdb->esc_like( $string ) . $trailing_wild;
   707 
   709 
   708 		foreach ( $cols as $col ) {
   710 		foreach ( $cols as $col ) {
   709 			if ( 'ID' == $col ) {
   711 			if ( 'ID' === $col ) {
   710 				$searches[] = $wpdb->prepare( "$col = %s", $string );
   712 				$searches[] = $wpdb->prepare( "$col = %s", $string );
   711 			} else {
   713 			} else {
   712 				$searches[] = $wpdb->prepare( "$col LIKE %s", $like );
   714 				$searches[] = $wpdb->prepare( "$col LIKE %s", $like );
   713 			}
   715 			}
   714 		}
   716 		}
   752 		global $wpdb;
   754 		global $wpdb;
   753 
   755 
   754 		$meta_query_clauses = $this->meta_query->get_clauses();
   756 		$meta_query_clauses = $this->meta_query->get_clauses();
   755 
   757 
   756 		$_orderby = '';
   758 		$_orderby = '';
   757 		if ( in_array( $orderby, array( 'login', 'nicename', 'email', 'url', 'registered' ) ) ) {
   759 		if ( in_array( $orderby, array( 'login', 'nicename', 'email', 'url', 'registered' ), true ) ) {
   758 			$_orderby = 'user_' . $orderby;
   760 			$_orderby = 'user_' . $orderby;
   759 		} elseif ( in_array( $orderby, array( 'user_login', 'user_nicename', 'user_email', 'user_url', 'user_registered' ) ) ) {
   761 		} elseif ( in_array( $orderby, array( 'user_login', 'user_nicename', 'user_email', 'user_url', 'user_registered' ), true ) ) {
   760 			$_orderby = $orderby;
   762 			$_orderby = $orderby;
   761 		} elseif ( 'name' == $orderby || 'display_name' == $orderby ) {
   763 		} elseif ( 'name' === $orderby || 'display_name' === $orderby ) {
   762 			$_orderby = 'display_name';
   764 			$_orderby = 'display_name';
   763 		} elseif ( 'post_count' == $orderby ) {
   765 		} elseif ( 'post_count' === $orderby ) {
   764 			// todo: avoid the JOIN
   766 			// @todo Avoid the JOIN.
   765 			$where             = get_posts_by_author_sql( 'post' );
   767 			$where             = get_posts_by_author_sql( 'post' );
   766 			$this->query_from .= " LEFT OUTER JOIN (
   768 			$this->query_from .= " LEFT OUTER JOIN (
   767 				SELECT post_author, COUNT(*) as post_count
   769 				SELECT post_author, COUNT(*) as post_count
   768 				FROM $wpdb->posts
   770 				FROM $wpdb->posts
   769 				$where
   771 				$where
   770 				GROUP BY post_author
   772 				GROUP BY post_author
   771 			) p ON ({$wpdb->users}.ID = p.post_author)
   773 			) p ON ({$wpdb->users}.ID = p.post_author)
   772 			";
   774 			";
   773 			$_orderby          = 'post_count';
   775 			$_orderby          = 'post_count';
   774 		} elseif ( 'ID' == $orderby || 'id' == $orderby ) {
   776 		} elseif ( 'ID' === $orderby || 'id' === $orderby ) {
   775 			$_orderby = 'ID';
   777 			$_orderby = 'ID';
   776 		} elseif ( 'meta_value' == $orderby || $this->get( 'meta_key' ) == $orderby ) {
   778 		} elseif ( 'meta_value' === $orderby || $this->get( 'meta_key' ) == $orderby ) {
   777 			$_orderby = "$wpdb->usermeta.meta_value";
   779 			$_orderby = "$wpdb->usermeta.meta_value";
   778 		} elseif ( 'meta_value_num' == $orderby ) {
   780 		} elseif ( 'meta_value_num' === $orderby ) {
   779 			$_orderby = "$wpdb->usermeta.meta_value+0";
   781 			$_orderby = "$wpdb->usermeta.meta_value+0";
   780 		} elseif ( 'include' === $orderby && ! empty( $this->query_vars['include'] ) ) {
   782 		} elseif ( 'include' === $orderby && ! empty( $this->query_vars['include'] ) ) {
   781 			$include     = wp_parse_id_list( $this->query_vars['include'] );
   783 			$include     = wp_parse_id_list( $this->query_vars['include'] );
   782 			$include_sql = implode( ',', $include );
   784 			$include_sql = implode( ',', $include );
   783 			$_orderby    = "FIELD( $wpdb->users.ID, $include_sql )";
   785 			$_orderby    = "FIELD( $wpdb->users.ID, $include_sql )";
   824 	 *
   826 	 *
   825 	 * @param string $name Property to get.
   827 	 * @param string $name Property to get.
   826 	 * @return mixed Property.
   828 	 * @return mixed Property.
   827 	 */
   829 	 */
   828 	public function __get( $name ) {
   830 	public function __get( $name ) {
   829 		if ( in_array( $name, $this->compat_fields ) ) {
   831 		if ( in_array( $name, $this->compat_fields, true ) ) {
   830 			return $this->$name;
   832 			return $this->$name;
   831 		}
   833 		}
   832 	}
   834 	}
   833 
   835 
   834 	/**
   836 	/**
   839 	 * @param string $name  Property to check if set.
   841 	 * @param string $name  Property to check if set.
   840 	 * @param mixed  $value Property value.
   842 	 * @param mixed  $value Property value.
   841 	 * @return mixed Newly-set property.
   843 	 * @return mixed Newly-set property.
   842 	 */
   844 	 */
   843 	public function __set( $name, $value ) {
   845 	public function __set( $name, $value ) {
   844 		if ( in_array( $name, $this->compat_fields ) ) {
   846 		if ( in_array( $name, $this->compat_fields, true ) ) {
   845 			return $this->$name = $value;
   847 			return $this->$name = $value;
   846 		}
   848 		}
   847 	}
   849 	}
   848 
   850 
   849 	/**
   851 	/**
   853 	 *
   855 	 *
   854 	 * @param string $name Property to check if set.
   856 	 * @param string $name Property to check if set.
   855 	 * @return bool Whether the property is set.
   857 	 * @return bool Whether the property is set.
   856 	 */
   858 	 */
   857 	public function __isset( $name ) {
   859 	public function __isset( $name ) {
   858 		if ( in_array( $name, $this->compat_fields ) ) {
   860 		if ( in_array( $name, $this->compat_fields, true ) ) {
   859 			return isset( $this->$name );
   861 			return isset( $this->$name );
   860 		}
   862 		}
   861 	}
   863 	}
   862 
   864 
   863 	/**
   865 	/**
   866 	 * @since 4.0.0
   868 	 * @since 4.0.0
   867 	 *
   869 	 *
   868 	 * @param string $name Property to unset.
   870 	 * @param string $name Property to unset.
   869 	 */
   871 	 */
   870 	public function __unset( $name ) {
   872 	public function __unset( $name ) {
   871 		if ( in_array( $name, $this->compat_fields ) ) {
   873 		if ( in_array( $name, $this->compat_fields, true ) ) {
   872 			unset( $this->$name );
   874 			unset( $this->$name );
   873 		}
   875 		}
   874 	}
   876 	}
   875 
   877 
   876 	/**
   878 	/**
   877 	 * Make private/protected methods readable for backward compatibility.
   879 	 * Make private/protected methods readable for backward compatibility.
   878 	 *
   880 	 *
   879 	 * @since 4.0.0
   881 	 * @since 4.0.0
   880 	 *
   882 	 *
   881 	 * @param string   $name      Method to call.
   883 	 * @param string $name      Method to call.
   882 	 * @param array    $arguments Arguments to pass when calling.
   884 	 * @param array  $arguments Arguments to pass when calling.
   883 	 * @return mixed Return value of the callback, false otherwise.
   885 	 * @return mixed Return value of the callback, false otherwise.
   884 	 */
   886 	 */
   885 	public function __call( $name, $arguments ) {
   887 	public function __call( $name, $arguments ) {
   886 		if ( 'get_search_sql' === $name ) {
   888 		if ( 'get_search_sql' === $name ) {
   887 			return call_user_func_array( array( $this, $name ), $arguments );
   889 			return $this->get_search_sql( ...$arguments );
   888 		}
   890 		}
   889 		return false;
   891 		return false;
   890 	}
   892 	}
   891 }
   893 }