[wp-trac] [WordPress Trac] #56256: The 'capability' parameter in the get_users function may not give the expected results.
WordPress Trac
noreply at wordpress.org
Wed Jul 20 12:51:07 UTC 2022
#56256: The 'capability' parameter in the get_users function may not give the
expected results.
--------------------------+-----------------------------
Reporter: tmatsuur | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Users | Version: 6.0
Severity: normal | Keywords: has-patch
Focuses: |
--------------------------+-----------------------------
Specifying multiple different capabilities for the 'capability',
'capability__in', and 'capability__not_in' parameters of the get_users
function may not produce the expected results.
The user's metadata is as follows
{{{
mysql> select * from wp_usermeta where meta_key='wp_capabilities';
+----------+---------+-----------------+---------------------------------+
| umeta_id | user_id | meta_key | meta_value |
+----------+---------+-----------------+---------------------------------+
| 12 | 1 | wp_capabilities | a:1:{s:13:"administrator";b:1;} |
| 54 | 2 | wp_capabilities | a:1:{s:6:"author";b:1;} |
+----------+---------+-----------------+---------------------------------+
}}}
In this situation, run the following PHP script
{{{
var_dump( get_users( [ 'capability' => ['edit_posts', 'edit_pages'],
'fields' => 'ID' ] ) );
}}}
The output is as follows, and no matching user ID can be obtained.
{{{
array(0) {
}
}}}
The cause is in the code after line 481 of `class-wp-user-query.php`.
{{{
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;
}
}
}
}}}
Because the loop process is terminated immediately after storing the
"role" of the first "capability" in the array, the "roles" of the second
and subsequent "capabilities" are not stored.
Therefore, the 'role' of the second and subsequent 'capability' is no
longer included in the search criteria, and the expected results are not
obtained.
Specifically, the search query looks like this
{{{
WHERE 1=1 AND (
(
(
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"edit\\_posts\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"administrator\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"editor\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"author\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"contributor\"%' )
)
AND
(
( mt1.meta_key = 'wp_capabilities' AND mt1.meta_value LIKE
'%\"edit\\_pages\"%' )
)
)
)
}}}
Remove the break statement for confirmation.
The search query then changes as follows
{{{
WHERE 1=1 AND (
(
(
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"edit\\_posts\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"administrator\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"editor\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"author\"%' )
OR
( wp_usermeta.meta_key = 'wp_capabilities' AND
wp_usermeta.meta_value LIKE '%\"contributor\"%' )
)
AND
(
( mt1.meta_key = 'wp_capabilities' AND mt1.meta_value LIKE
'%\"edit\\_pages\"%' )
OR
( mt1.meta_key = 'wp_capabilities' AND mt1.meta_value LIKE
'%\"administrator\"%' )
OR
( mt1.meta_key = 'wp_capabilities' AND mt1.meta_value LIKE
'%\"editor\"%' )
)
)
)
}}}
The return value of the get_users function is as follows
{{{
array(1) {
[0]=>
string(1) "1"
}
}}}
Something similar occurs with the 'capability__in' and
'capability__not_in' parameters.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/56256>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list