WordPress.org

Make WordPress Core

Ticket #22212: 22212.5.patch

File 22212.5.patch, 11.1 KB (added by swissspidy, 6 years ago)
  • src/wp-includes/class-wp-user-query.php

    diff --git src/wp-includes/class-wp-user-query.php src/wp-includes/class-wp-user-query.php
    index 1bc08aa..ea7fc5f 100644
    class WP_User_Query { 
    127127         *     Optional. Array or string of Query parameters.
    128128         *
    129129         *     @type int          $blog_id             The site ID. Default is the global blog id.
    130          *     @type string       $role                Role name. Default empty.
     130         *     @type string|array $role                An array or a comma-separated list of role names to include (AND in).
     131         *                                             Default empty array.
     132         *     @type array        $role__in            An array of role names (OR in). Default empty array.
     133         *     @type array        $role__not_in        An array of role names to exclude (AND in). Default empty array.
    131134         *     @type string       $meta_key            User meta key. Default empty.
    132135         *     @type string       $meta_value          User meta value. Default empty.
    133136         *     @type string       $meta_compare        Comparison operator to test the `$meta_value`. Accepts '=', '!=',
    class WP_User_Query { 
    259262                $this->meta_query = new WP_Meta_Query();
    260263                $this->meta_query->parse_query_vars( $qv );
    261264
    262                 $role = '';
     265                $roles = array();
    263266                if ( isset( $qv['role'] ) ) {
    264                         $role = trim( $qv['role'] );
     267                        if ( is_array( $qv['role'] ) ) {
     268                                $roles = $qv['role'];
     269                        } elseif ( is_string( $qv['role'] ) && ! empty( $qv['role'] ) ) {
     270                                $roles = array_map( 'trim', explode( ',', $qv['role'] ) );
     271                        }
     272                }
     273
     274                $role__in = array();
     275                if ( isset( $qv['role__in'] ) ) {
     276                        $role__in = (array) $qv['role__in'];
     277                }
     278
     279                $role__not_in = array();
     280                if ( isset( $qv['role__not_in'] ) ) {
     281                        $role__not_in = (array) $qv['role__not_in'];
    265282                }
    266283
    267                 if ( $blog_id && ( $role || is_multisite() ) ) {
    268                         $cap_meta_query = array();
    269                         $cap_meta_query['key'] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities';
     284                if ( $blog_id && ( ! empty( $roles ) || ! empty( $role__in ) || ! empty( $role__not_in ) || is_multisite() ) ) {
     285                        $cap_meta_query = array( 'relation' => 'AND' );
     286                        $role__in_query = array( 'relation' => 'OR' );
     287
     288                        if ( ! empty( $roles ) ) {
     289                                foreach ( $roles as $role ) {
     290                                        $cap_meta_query[] = array(
     291                                                'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     292                                                'value'   => $role,
     293                                                'compare' => 'LIKE',
     294                                        );
     295                                }
     296                        }
     297
     298                        if ( ! empty( $role__in ) ) {
     299                                foreach ( $role__in as $role ) {
     300                                        $role__in_query[] = array(
     301                                                'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     302                                                'value'   => $role,
     303                                                'compare' => 'LIKE',
     304                                        );
     305                                }
     306                        }
    270307
    271                         if ( $role ) {
    272                                 $cap_meta_query['value'] = '"' . $role . '"';
    273                                 $cap_meta_query['compare'] = 'like';
     308                        if ( ! empty( $role__not_in ) ) {
     309                                foreach ( $role__not_in as $role ) {
     310                                        $cap_meta_query[] = array(
     311                                                'key'     => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
     312                                                'value'   => $role,
     313                                                'compare' => 'NOT LIKE',
     314                                        );
     315                                }
    274316                        }
    275317
    276318                        if ( empty( $this->meta_query->queries ) ) {
    277                                 $this->meta_query->queries = array( $cap_meta_query );
     319                                $this->meta_query->queries = $cap_meta_query;
    278320                        } elseif ( ! in_array( $cap_meta_query, $this->meta_query->queries, true ) ) {
    279321                                // Append the cap query to the original queries and reparse the query.
    280322                                $this->meta_query->queries = array(
    class WP_User_Query { 
    283325                                );
    284326                        }
    285327
     328                        if ( ! empty( $role__in ) ) {
     329                                $this->meta_query->queries[1][] = $role__in_query;
     330                        }
     331
    286332                        $this->meta_query->parse_query_vars( $this->meta_query->queries );
    287333                }
    288334
  • tests/phpunit/tests/user/query.php

    diff --git tests/phpunit/tests/user/query.php tests/phpunit/tests/user/query.php
    index 064c73f..ffff030 100644
    class Tests_User_Query extends WP_UnitTestCase { 
    896896                        unset( $q->query_vars[ $k ] );
    897897                }
    898898        }
     899
     900        /**
     901         * @ticket 22212
     902         */
     903        function test_get_single_role_by_user_query() {
     904                $this->factory->user->create_many( 2, array(
     905                        'role' => 'subscriber',
     906                ) );
     907
     908                $wp_user_search = new WP_User_Query( array( 'role' => 'subscriber' ) );
     909                $users          = $wp_user_search->get_results();
     910
     911                $this->assertEquals( 2, count( $users ) );
     912        }
     913
     914        /**
     915         * @ticket 22212
     916         */
     917        function test_get_multiple_roles_by_user_query() {
     918                $this->factory->user->create_many( 2, array(
     919                        'role' => 'subscriber',
     920                ) );
     921
     922                $this->factory->user->create_many( 3, array(
     923                        'role' => 'editor',
     924                ) );
     925
     926                $wp_user_search = new WP_User_Query( array( 'role__in' => array( 'subscriber', 'editor' ) ) );
     927                $users          = $wp_user_search->get_results();
     928                $this->assertEquals( 5, count( $users ) );
     929        }
     930
     931        /**
     932         * @ticket 22212
     933         */
     934        function test_get_single_role_by_string() {
     935                $this->factory->user->create_many( 2, array(
     936                        'role' => 'subscriber',
     937                ) );
     938
     939                $users = get_users( array(
     940                        'role' => 'subscriber',
     941                ) );
     942
     943                $this->assertEquals( 2, count( $users ) );
     944        }
     945
     946        /**
     947         * @ticket 22212
     948         */
     949        function test_get_single_role_by_array() {
     950                $this->factory->user->create_many( 2, array(
     951                        'role' => 'subscriber',
     952                ) );
     953
     954                $users = get_users( array(
     955                        'role' => array( 'subscriber' ),
     956                ) );
     957
     958                $this->assertEquals( 2, count( $users ) );
     959        }
     960
     961        /**
     962         * @ticket 22212
     963         */
     964        function test_get_multiple_roles_and() {
     965                $subscribers = $this->factory->user->create_many( 2, array(
     966                        'role' => 'subscriber',
     967                ) );
     968
     969                $this->factory->user->create_many( 3, array(
     970                        'role' => 'editor',
     971                ) );
     972
     973                $this->factory->user->create_many( 2, array(
     974                        'role' => 'administrator',
     975                ) );
     976
     977                $users = new WP_User_Query( array( 'role' => array( 'subscriber', 'editor' ) ) );
     978                $users = $users->get_results();
     979
     980                $this->assertEmpty( $users );
     981
     982                foreach ( $subscribers as $subscriber ) {
     983                        $subscriber = get_user_by( 'ID', $subscriber );
     984                        $subscriber->add_role( 'editor' );
     985                }
     986
     987                $users = new WP_User_Query( array( 'role' => array( 'subscriber', 'editor' ) ) );
     988                $users = $users->get_results();
     989
     990                $this->assertEquals( 2, count( $users ) );
     991
     992                foreach ( $users as $user ) {
     993                        $this->assertInstanceOf( 'WP_User', $user );
     994                }
     995        }
     996
     997        /**
     998         * @ticket 22212
     999         */
     1000        function test_get_multiple_roles_or() {
     1001                $this->factory->user->create_many( 2, array(
     1002                        'role' => 'subscriber',
     1003                ) );
     1004
     1005                $this->factory->user->create_many( 3, array(
     1006                        'role' => 'editor',
     1007                ) );
     1008
     1009                $this->factory->user->create_many( 2, array(
     1010                        'role' => 'administrator',
     1011                ) );
     1012
     1013                $users = new WP_User_Query( array( 'role__in' => array( 'subscriber', 'editor', 'administrator' ) ) );
     1014                $users = $users->get_results();
     1015
     1016                // +1 for the default user created during installation.
     1017                $this->assertEquals( 8, count( $users ) );
     1018                foreach ( $users as $user ) {
     1019                        $this->assertInstanceOf( 'WP_User', $user );
     1020                }
     1021        }
     1022
     1023        /**
     1024         * @ticket 22212
     1025         */
     1026        function test_get_multiple_roles_by_string() {
     1027                $subscribers = $this->factory->user->create_many( 2, array(
     1028                        'role' => 'subscriber',
     1029                ) );
     1030
     1031                $this->factory->user->create_many( 3, array(
     1032                        'role' => 'editor',
     1033                ) );
     1034
     1035                $users = get_users( array(
     1036                        'role' => 'subscriber, editor',
     1037                ) );
     1038
     1039                $this->assertEmpty( $users );
     1040
     1041                foreach ( $subscribers as $subscriber ) {
     1042                        $subscriber = get_user_by( 'ID', $subscriber );
     1043                        $subscriber->add_role( 'editor' );
     1044                }
     1045
     1046                $users = get_users( array(
     1047                        'role' => 'subscriber, editor',
     1048                ) );
     1049
     1050                $this->assertEquals( 2, count( $users ) );
     1051        }
     1052
     1053        /**
     1054         * @ticket 22212
     1055         */
     1056        function test_get_multiple_roles_with_meta() {
     1057                // Create administrator user + meta
     1058                $administrator_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
     1059                update_user_meta( $administrator_id, 'mk1', 1 );
     1060                update_user_meta( $administrator_id, 'mk2', 1 );
     1061
     1062                // Create editor user + meta
     1063                $editor_id = $this->factory->user->create( array( 'role' => 'editor' ) );
     1064                update_user_meta( $editor_id, 'mk1', 1 );
     1065                update_user_meta( $editor_id, 'mk2', 2 );
     1066
     1067                // Create subscriber user + meta
     1068                $subscriber_id = $this->factory->user->create( array( 'role' => 'subscriber' ) );
     1069                update_user_meta( $subscriber_id, 'mk1', 1 );
     1070                update_user_meta( $subscriber_id, 'mk2', 1 );
     1071
     1072                // Fetch users
     1073                $users = get_users( array(
     1074                        'role__in'   => array( 'administrator', 'editor', 'subscriber' ),
     1075                        'meta_query' => array(
     1076                                'relation' => 'AND',
     1077                                array(
     1078                                        'key'     => 'mk1',
     1079                                        'value'   => '1',
     1080                                        'compare' => "=",
     1081                                        'type'    => 'numeric',
     1082                                ),
     1083                                array(
     1084                                        'key'     => 'mk2',
     1085                                        'value'   => '2',
     1086                                        'compare' => "=",
     1087                                        'type'    => 'numeric',
     1088                                ),
     1089                        ),
     1090                ) );
     1091
     1092                // Check results
     1093                $this->assertEquals( 1, count( $users ) );
     1094        }
     1095
     1096        /**
     1097         * @ticket 22212
     1098         */
     1099        function test_role_exclusion() {
     1100                $this->factory->user->create_many( 2, array(
     1101                        'role' => 'subscriber',
     1102                ) );
     1103
     1104                $this->factory->user->create_many( 3, array(
     1105                        'role' => 'editor',
     1106                ) );
     1107
     1108                $users = get_users( array(
     1109                        'role__not_in' => 'subscriber',
     1110                ) );
     1111
     1112                // +1 for the default user created during installation.
     1113                $this->assertEquals( 4, count( $users ) );
     1114
     1115                $users = get_users( array(
     1116                        'role__not_in' => 'editor',
     1117                ) );
     1118
     1119                // +1 for the default user created during installation.
     1120                $this->assertEquals( 3, count( $users ) );
     1121        }
     1122
     1123        /**
     1124         * @ticket 22212
     1125         */
     1126        function test_role__in_role__not_in_combined() {
     1127                $subscribers = $this->factory->user->create_many( 2, array(
     1128                        'role' => 'subscriber',
     1129                ) );
     1130
     1131                $this->factory->user->create_many( 3, array(
     1132                        'role' => 'editor',
     1133                ) );
     1134
     1135                foreach ( $subscribers as $subscriber ) {
     1136                        $subscriber = get_user_by( 'ID', $subscriber );
     1137                        $subscriber->add_role( 'editor' );
     1138                }
     1139
     1140                $users = get_users( array(
     1141                        'role__in'     => 'editor',
     1142                ) );
     1143
     1144                $this->assertEquals( 5, count( $users ) );
     1145
     1146                $users = get_users( array(
     1147                        'role__in'     => 'editor',
     1148                        'role__not_in' => 'subscriber',
     1149                ) );
     1150
     1151                $this->assertEquals( 3, count( $users ) );
     1152        }
     1153
     1154        /**
     1155         * @ticket 22212
     1156         */
     1157        function test_role__in_role_combined() {
     1158                $subscribers = $this->factory->user->create_many( 2, array(
     1159                        'role' => 'subscriber',
     1160                ) );
     1161
     1162                $this->factory->user->create_many( 3, array(
     1163                        'role' => 'editor',
     1164                ) );
     1165
     1166                $subscriber = get_user_by( 'ID', $subscribers[0] );
     1167                $subscriber->add_role( 'editor' );
     1168
     1169                $users = get_users( array(
     1170                        'role'         => 'subscriber',
     1171                        'role__not_in' => array( 'editor' ),
     1172                ) );
     1173
     1174                $this->assertEquals( 1, count( $users ) );
     1175        }
     1176
     1177        /**
     1178         * @ticket 22212
     1179         */
     1180        function test_role__not_in_user_without_role() {
     1181                $user_without_rule = $this->factory->user->get_object_by_id( $this->factory->user->create( array(
     1182                        'role' => 'subscriber',
     1183                ) ) );
     1184
     1185                $user_without_rule->remove_role( 'subscriber' );
     1186
     1187                $this->factory->user->create_many( 3, array(
     1188                        'role' => 'editor',
     1189                ) );
     1190
     1191                $users = get_users( array(
     1192                        'role__not_in' => 'subscriber',
     1193                ) );
     1194
     1195                // +1 for the default user created during installation.
     1196                $this->assertEquals( 5, count( $users ) );
     1197
     1198                $users = get_users( array(
     1199                        'role__not_in' => 'editor',
     1200                ) );
     1201
     1202                // +1 for the default user created during installation.
     1203                $this->assertEquals( 2, count( $users ) );
     1204        }
    8991205}