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. |
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 } |
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 )"; |
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 /** |
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 } |