Make WordPress Core


Ignore:
Timestamp:
10/08/2015 09:27:04 PM (9 years ago)
Author:
boonebgorges
Message:

WP_User_Query role improvement redux.

It's back, and it's better than ever: an overhaul of role-related arguments
in WP_User_Query. This updated version of the previously-reverted [34875]
includes support for the use of $blog_id without specifying a $role, for
a 99.7% reduced chance of breaking wordpress.org and other large sites.

Props boonebgorges, swissspidy.
Fixes #22212.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-user-query.php

    r34956 r34959  
    4949     * @since 4.2.0
    5050     * @access public
    51      * @var object WP_Meta_Query
     51     * @var WP_Meta_Query
    5252     */
    5353    public $meta_query = false;
     
    9898            'blog_id' => $GLOBALS['blog_id'],
    9999            'role' => '',
     100            'role__in' => array(),
     101            'role__not_in' => array(),
    100102            'meta_key' => '',
    101103            'meta_value' => '',
     
    127129     *              for `$orderby` parameter.
    128130     * @since 4.3.0 Added 'has_published_posts' parameter.
    129      * @since 4.4.0 Added 'paged' parameter.
     131     * @since 4.4.0 Added 'paged', 'role__in', and 'role__not_in' parameters. 'role' parameter was updated to
     132     *              permit an array or comma-separated list of values.
    130133     * @access public
    131134     *
     
    137140     *
    138141     *     @type int          $blog_id             The site ID. Default is the global blog id.
    139      *     @type string       $role                Role name. Default empty.
     142     *     @type string|array $role                An array or a comma-separated list of role names that users must match
     143     *                                             to be included in results. Note that this is an inclusive list: users
     144     *                                             must match *each* role. Default empty.
     145     *     @type array        $role__in            An array of role names. Matched users must have at least one of these
     146     *                                             roles. Default empty array.
     147     *     @type array        $role__not_in        An array of role names to exclude. Users matching one or more of these
     148     *                                             roles will not be included in results. Default empty array.
    140149     *     @type string       $meta_key            User meta key. Default empty.
    141150     *     @type string       $meta_value          User meta value. Default empty.
     
    269278        $this->meta_query->parse_query_vars( $qv );
    270279
    271         $role = '';
     280        $roles = array();
    272281        if ( isset( $qv['role'] ) ) {
    273             $role = trim( $qv['role'] );
    274         }
    275 
    276         if ( $blog_id && ( $role || is_multisite() ) ) {
    277             $cap_meta_query = array();
    278             $cap_meta_query['key'] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities';
    279 
    280             if ( $role ) {
    281                 $cap_meta_query['value'] = '"' . $role . '"';
    282                 $cap_meta_query['compare'] = 'like';
    283             }
     282            if ( is_array( $qv['role'] ) ) {
     283                $roles = $qv['role'];
     284            } elseif ( is_string( $qv['role'] ) && ! empty( $qv['role'] ) ) {
     285                $roles = array_map( 'trim', explode( ',', $qv['role'] ) );
     286            }
     287        }
     288
     289        $role__in = array();
     290        if ( isset( $qv['role__in'] ) ) {
     291            $role__in = (array) $qv['role__in'];
     292        }
     293
     294        $role__not_in = array();
     295        if ( isset( $qv['role__not_in'] ) ) {
     296            $role__not_in = (array) $qv['role__not_in'];
     297        }
     298
     299        if ( $blog_id && ( ! empty( $roles ) || ! empty( $role__in ) || ! empty( $role__not_in ) || is_multisite() ) ) {
     300            $role_queries  = array();
     301
     302            $roles_clauses = array( 'relation' => 'AND' );
     303            if ( ! empty( $roles ) ) {
     304                foreach ( $roles as $role ) {
     305                    $roles_clauses[] = array(
     306                        'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     307                        'value'   => $role,
     308                        'compare' => 'LIKE',
     309                    );
     310                }
     311
     312                $role_queries[] = $roles_clauses;
     313            }
     314
     315            $role__in_clauses = array( 'relation' => 'OR' );
     316            if ( ! empty( $role__in ) ) {
     317                foreach ( $role__in as $role ) {
     318                    $role__in_clauses[] = array(
     319                        'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     320                        'value'   => $role,
     321                        'compare' => 'LIKE',
     322                    );
     323                }
     324
     325                $role_queries[] = $role__in_clauses;
     326            }
     327
     328            $role__not_in_clauses = array( 'relation' => 'AND' );
     329            if ( ! empty( $role__not_in ) ) {
     330                foreach ( $role__not_in as $role ) {
     331                    $role__not_in_clauses[] = array(
     332                        'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     333                        'value'   => $role,
     334                        'compare' => 'NOT LIKE',
     335                    );
     336                }
     337
     338                $role_queries[] = $role__not_in_clauses;
     339            }
     340
     341            // If there are no specific roles named, make sure the user is a member of the site.
     342            if ( empty( $role_queries ) ) {
     343                $role_queries[] = array(
     344                    'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     345                    'compare' => 'EXISTS',
     346                );
     347            }
     348
     349            // Specify that role queries should be joined with AND.
     350            $role_queries['relation'] = 'AND';
    284351
    285352            if ( empty( $this->meta_query->queries ) ) {
    286                 $this->meta_query->queries = array( $cap_meta_query );
    287             } elseif ( ! in_array( $cap_meta_query, $this->meta_query->queries, true ) ) {
     353                $this->meta_query->queries = $role_queries;
     354            } else {
    288355                // Append the cap query to the original queries and reparse the query.
    289356                $this->meta_query->queries = array(
    290357                    'relation' => 'AND',
    291                     array( $this->meta_query->queries, $cap_meta_query ),
     358                    array( $this->meta_query->queries, $role_queries ),
    292359                );
    293360            }
Note: See TracChangeset for help on using the changeset viewer.