Make WordPress Core

Opened 14 years ago

Closed 3 years ago

Last modified 3 years ago

#16841 closed defect (bug) (fixed)

Manually created user roles not showing in author dropdown regardless of assigned capabilities

Reported by: 10sexyapples's profile 10sexyapples Owned by: hellofromtonya's profile hellofromTonya
Milestone: 5.9 Priority: normal
Severity: normal Version: 3.1
Component: Role/Capability Keywords: has-patch commit needs-dev-note
Focuses: Cc:

Description (last modified by ocean90)

I posted the below on wp-testers hoping to verify or gain experiences from others in order to confirm this prior to reporting it as a bug, but, haven't received any further input, and it's just becoming more evident to me that perhaps it should be posted here, so, I hope I'm not creating a false report here. Please excuse me if I am.

I'm posting this as a link so that it will translate more clearly rather than just cluttering up this message with more text than necessary.
http://lists.automattic.com/pipermail/wp-testers/2011-March/014130.html

Upon further investigation I have also come across the following: #16451

I'm not an expert at debugging this sort of thing, but, I have attempted all within my knowledge thus far, and in looking at all of the returned objects and entries, the only difference I can spot between how the default user roles ( which show up properly in the dropdown ) and the custom created roles ( which do not ) are being returned is that the default user roles, editor for instance, correctly show the deprecated level_7 entry, and the custom user role ( with more assigned privileges than the editor ) does not show user levels in the capabilities array at all, and shows level_0 in the object.

This is leading me to think that perhaps there is something happening with those user levels in creating the author dropdown on the post editor that is blocking the custom user roles from showing up as expected.

When running the following code:

echo '<br /><br /><h3>Roles</h3>';
	foreach ( $wp_roles->role_names as $role => $name ) :
		echo '<br /> <br />';
		echo '<pre> Role displayed in Admin as ' . $name ;
		echo  '     Database entry: '  . $role . '</pre>';

		echo '<h5> Capabilities assigned to the role of ' . $name. '</h5>';
		// print_r( $caps);
		echo '<pre>';
		$rolename = get_role($role);
		$caps = $rolename->capabilities;
			foreach ($caps as $capability => $value):
				echo  $capability . ' '.  $value . "\n" ;
			endforeach;
		echo '</pre>';
	endforeach;

the default wp roles return the following capability value pairings

delete_published_posts 1

roles created with Justin Tadlock's members plugin return the following

delete_published_posts delete_published_posts

roles created manually in functions.php utilizing

add_role( 'test_role', 'Test Role' );

//saved and then removed before running the code below ...

$role = get_role('test_role');

$role->add_cap('read');
$role->add_cap('edit_posts);
$role->add_cap('edit_others_posts');
$role->add_cap('publish_posts');
$role->add_cap('read_private_posts');
$role->add_cap('delete_posts');
$role->add_cap('delete_private_posts');
$role->add_cap('delete_published_posts');
$role->add_cap('delete_others_posts');
$role->add_cap('edit_private_posts');
$role->add_cap('edit_published_posts');

return the following ...

delete_published_posts 1

but lack the user levels as mentioned above.

Let me know if there is any further info I can provide to help sort this out~

Attachments (1)

16841-twentyfourteen.diff (655 bytes) - added by swissspidy 3 years ago.

Download all attachments as: .zip

Change History (96)

#1 @10sexyapples
14 years ago

ahA! okay, I believe the use of user_level here is the culprit:
#15871

If user level is going to stick around in this way then shouldn't add_cap perhaps take this into consideration?

Last edited 14 years ago by scribu (previous) (diff)

#2 @scribu
14 years ago

  • Component changed from General to Role/Capability

The workaround would just be to add a 'level_1' cap to your role.

It's PITA, considering how user levels have been deprecated so long ago, but there you go.

#3 @scribu
14 years ago

PS: Instead of posting the full ticket url, just write #123, where 123 is the ticket number.

#4 @10sexyapples
14 years ago

Hmm. I actually tried adding the level caps, but, didn't see any change in the array after.
I was using add_cap.
Perhaps I saved, and then removed my code before it got picked up? I'm going to try it again.
And yes, definitely a PITA ... I saw your comments in having to put it there in the first place ...
As usual, thanks for the tips on proper posting etiquette ;-)
# 123 it is.

Last edited 14 years ago by 10sexyapples (previous) (diff)

#5 @scribu
14 years ago

Related: #16714

#6 @magicroundabout
13 years ago

Hello, this is my first post on Trac, so I hope it's useful.

I spotted that new users in roles added with add_role don't appear in the author dropdown list. This seems to have been introduced in #15871 when code was added to WP_User_Query->prepare_query to only select users with an old-school user-level of > 0 if 'who' => 'authors' was passed in the args.

I don't quite understand the discussion on the logic of this (in #15871). It seems to me that user levels are deprecated, so shouldn't this select users with the edit_posts capability?

Alternatively (additionally?), perhaps we could have a filter hook in wp_dropdown_users that lets us modify the arguments passed to get_users()?

#7 @scribu
13 years ago

We still use user levels there because we don't have a good way of getting the same list via capabilties. It's a mess.

#8 @lgladdy
13 years ago

And additional (imo) bug stops add_cap('level_1') from fixing this for existing users. I've posted a trac ticket for it #19747

Last edited 13 years ago by lgladdy (previous) (diff)

#9 @markoheijnen
13 years ago

  • Cc marko@… added

#10 @pauldewouters
13 years ago

  • Cc pauldewouters added

#11 @scottconnerly
12 years ago

  • Cc scott@… added

#12 @BandonRandon
12 years ago

  • Cc BandonRandon added

#13 @viniciusrtf
11 years ago

While trying to apply level_1 to my custom role, I didn't remember the custom role name (it is different from display name and it doesn't appear anywhere in backend), so I figured it out with this dirty SQL query:

SELECT meta_value FROM wp_usermeta WHERE user_id = user-id-here;
Last edited 11 years ago by viniciusrtf (previous) (diff)

#14 @jchristopher
11 years ago

  • Cc jonathan@… added

#15 @sterlo
10 years ago

To clarify, this is all tied into this particular section:

https://core.trac.wordpress.org/browser/tags/3.9.1/src/wp-includes/user.php#L649

$qv['meta_key'] = $wpdb->get_blog_prefix( $blog_id ) . 'user_level';
$qv['meta_value'] = 0;
$qv['meta_compare'] = '!=';

This will end up meaning "give me all users that have a wp_user_level that is not equal to 0".

If you go into MySQL and run something along the lines of this:

[mysql> select * from wp_usermeta WHERE user_id = 19;
+----------+---------+------------------------------+-------------------------------------------------------+
| umeta_id | user_id | meta_key                     | meta_value                                            |
+----------+---------+------------------------------+-------------------------------------------------------+
|      225 |      19 | first_name                   | John                                                 |
|      226 |      19 | last_name                    | Doe                                              |
|      227 |      19 | nickname                     | @jdoe                                            |
|      228 |      19 | description                  |                                                       |
|      229 |      19 | rich_editing                 | true                                                  |
|      230 |      19 | comment_shortcuts            | false                                                 |
|      231 |      19 | admin_color                  | fresh                                                 |
|      232 |      19 | use_ssl                      | 0                                                     |
|      233 |      19 | show_admin_bar_front         | true                                                  |
|      234 |      19 | wp_capabilities              | a:1:{s:15:"content-manager";b:1;}                     |
|      235 |      19 | wp_user_level                | 10                                                    |
|      236 |      19 | dismissed_wp_pointers        | wp350_media,wp360_revisions,wp360_locks,wp390_widgets |
|      429 |      19 | wpseo_title                  |                                                       |
|      430 |      19 | wpseo_metadesc               |                                                       |
|      431 |      19 | wpseo_metakey                |                                                       |
|      432 |      19 | _yoast_wpseo_profile_updated | 1400732591                                            |
|      433 |      19 | googleplus                   |                                                       |
|      434 |      19 | twitter                      |                                                       |
|      435 |      19 | facebook                     |                                                       |
+----------+---------+------------------------------+-------------------------------------------------------+
19 rows in set (0.00 sec)]

The line you need to pay attention to is:

|      235 |      19 | wp_user_level                | 10                                                    |

When you create your custom role, you need to add something that is > 0 in terms of wp_user_level.

Adjusting the role to increase the user_level is the end goal. To accomplish that you can use the $role->add_cap('level_1'); method explained by others - as long as it is not level_0.

It is important to note that you need to edit the user and re-save them with the add_cap change in place. This will update the database so that wp_user_level is no longer 0.

#16 @DrewAPicture
10 years ago

  • Summary changed from manually created user roles not showing in author dropdown irregardless of assigned capabilities to Manually created user roles not showing in author dropdown regardless of assigned capabilities

#17 @coolmann
10 years ago

Any chance to see this fixed in 4.1?

#18 @ckpicker
10 years ago

Would love to see this fixed in a future version.

#19 @juiceboxint
10 years ago

+1. 99.8% of users won't ever come across this, but it's a big deal to those of us who use WP as a serious CMS.

#20 follow-up: @lgladdy
10 years ago

The add_cap('level_1'); workaround will also apply to any existing users with the role you're adding to from r31190 / WordPress 4.2 which at least makes the workaround a little easier.

[Edit: Update typo - 4.2 not 3.2]

Last edited 10 years ago by lgladdy (previous) (diff)

#21 in reply to: ↑ 20 ; follow-up: @juiceboxint
10 years ago

Replying to lgladdy:

The add_cap('level_1'); workaround will also apply to any existing users with the role you're adding to from r31190 / WordPress 3.2 which at least makes the workaround a little easier.

Yep, the only thing is that you still have to change each user's role to something else and then back in order to update the actual user_level field in the database, if they were assigned that role before you added the level_1 cap. (tested a few minute ago on 4.1) So the workaround itself is pretty obscure, and the caveat for the workaround is even more obscure.

#22 in reply to: ↑ 21 @lgladdy
10 years ago

Replying to juiceboxint:

Yep, the only thing is that you still have to change each user's role to something else and then back in order to update the actual user_level field in the database, if they were assigned that role before you added the level_1 cap. (tested a few minute ago on 4.1) So the workaround itself is pretty obscure, and the caveat for the workaround is even more obscure.

That's what has been fixed and will be released in 4.2 - You won't need to do that anymore - add_cap will update any existing users :)

[Edit: Update typo - 4.2 not 3.2]

Last edited 10 years ago by lgladdy (previous) (diff)

This ticket was mentioned in Slack in #core by lgladdy. View the logs.


10 years ago

#24 @lgladdy
10 years ago

I'm going to write a patch for this one, with the hope of it being included in 4.2

As far as I see it, we should test if they have a level_* greater than 0, or if they have the edit_posts capability.

Is there any other roles that should result in a user being included in the dropdown?

#25 @juiceboxint
10 years ago

Awesome, thanks for tackling it! That would be a good quick fix - any built-in role that has an inherent user level > 1 will also have edit_posts, and authorship has never worked for custom roles prior to your patch (without the arcane workaround anyway) so this seems like a safe bet to me.

A more complete solution (maybe step 2?) would be to consider the post type context as well, though: if the user has the equivalent edit_ cap for a custom post type, they appear in the authors dropdown for those posts. This would allow a user to potentially appear in the authors list for a Post but not a Page, or one CPT but not another, etc.

Again, shouldn't have any BC issues with this because it's never worked before your patch makes it into core. The only thing I wonder about is whether the quick fix will actually create its own BC issues for the more complete fix if that one is done later on. For instance, after your patch, a user with edit_posts but not edit_cpt could be set as the author of a custom post type cpt, and later on when the contextual-author fix is in core, that user is no longer a valid or selectable author of cpt. This will be an extremely unlikely scenario, but it's worth thinking about whether it's worth skipping straight to the complete fix.

#26 @lgladdy
10 years ago

  • Keywords 2nd-opinion added

This is going to be harder than I originally thought.

As earlier in the post, the code at fault here is at https://core.trac.wordpress.org/browser/trunk/src/wp-includes/user.php#L714

If you provide a 'who'=>'authors' key to a get_users command it will return all users with a level greater than 0 using a meta query.

There is no nice way (that I can see) within WP_User_Query::prepare_query for us to do anything smart with capabilities, so i'm thinking there maybe 4 ways to try and fix this.

1) Not use the 'who'=>'authors' key at all, and do a get_users() query to get all the users and then loop through to check their capability. This probably has the potential to be seriously slow on sites with many users?

2) Loop over all the roles, figure out which have edit_posts cap on them and then do a get_users/WP_User_Query query, either using the role option (it currently only supports one role per query, so maybe that could be expanded to support an array of roles? or multiple queries and merge).

3) Add a new capability option into WP_User_Query. This would basically be number 2 anyway - we'd just need to get the wp_user_roles option to figure out the list of roles, and then run that as a query similar to a multiple role search, but someone more familiar with core coding standards, the WP_User_Query class or the Role/Capability component maintainer(s) should be able to say if this is a good idea.

4) Do something inside WP_Roles::add_cap or, more likely, WP_User::update_user_level_from_caps - We could also check if the user has edit_posts and if so, set their default level_* to 1, rather than 0. This seems a bit evil because it's a workaround to legacy/deprecated level_* syntax, and we probably don't want to introduce new code that touches that if the end goal is it not existing at all?

I think 3 actually is a the best idea, depending on how acceptable it would be to use get_option inside WP_User_Query. It would solve the problem, and give developers more functionality.

Thoughts?

#27 @boonebgorges
10 years ago

  • Keywords needs-patch needs-unit-tests added; 2nd-opinion removed
  • Milestone changed from Awaiting Review to Future Release

As scribu said earlier, this is a mess. @lgladdy, thanks for digging into it.

Something like 2 or 3 is probably worth exploring, at least for the short term. As you suggest, the only capability-related data we can easily query on a per-user basis is the deprecated level (which is the original problem here in the ticket) and wpX_capabilities, where wpX_ is the current blog prefix. The latter piece of usermeta stores a serialized array of a user's roles for that blog, and the 'role' param of WP_User_Query translates to a LIKE query against this data. Doing this multiple times is going to scale pretty poorly, but it's not a great deal worse performance-wise than what's already there, and it will allow us to fix the various role-related bugs raised in this ticket.

This ticket was mentioned in Slack in #core by boone. View the logs.


10 years ago

#29 @ocean90
9 years ago

  • Description modified (diff)

#30 @ocean90
9 years ago

#24985 was marked as a duplicate.

#31 @archon810
9 years ago

Any updates here?

#32 @hiddenpearls
9 years ago

Any update on this bug ?

#33 follow-up: @xfechx
8 years ago

I am looking to edit the author of the post, but I can't see any authors (added via members plugin) in the author dropdown.

Has there been any progress on this bug?

Kind regards,

#34 in reply to: ↑ 33 ; follow-up: @juiceboxint
8 years ago

Replying to xfechx:

I am looking to edit the author of the post, but I can't see any authors (added via members plugin) in the author dropdown.

The solution is to add a custom capability called 'level_1' to your custom role. Then users with that role will show up as authors. It won't show up in the capability list once it's been added, but it's there behind the scenes.

Last edited 8 years ago by juiceboxint (previous) (diff)

#35 in reply to: ↑ 34 @Gioni
8 years ago

Replying to juiceboxint:

Replying to xfechx:

I am looking to edit the author of the post, but I can't see any authors (added via members plugin) in the author dropdown.

The solution is to add a custom capability called 'level_1' to your custom role. Then users with that role will show up as authors. It won't show up in the capability list once it's been added, but it's there behind the scenes.

Thanks. That is not a solution for this bug. This is just a workaround.

#36 @juiceboxint
8 years ago

Right, I should have used a different term. The bug itself is still definitely open. I have just given up on waiting for a solution and have incorporated the workaround into my routine. I would encourage you to do the same :)

#37 @master412160
8 years ago

Will this be fixed in future wp version?

#38 @BandonRandon
8 years ago

Hi @master412160 this, like every bug in WordPress, is dependent on a community contribution for a fix. As the bug is open and set to be added to a Future Release this means that once a patch is submitted and verified to fix the issue without having any side effects the project leads will be able to merge into Core WordPress.

If this is a bug that's particularly important to you, I'd suggest writing a patch, or if coding isn't your style, hiring a WordPress developer to take a look at the issue and contribute a patch.

For now, you may use the workaround described in this ticket.

#39 @lukecavanagh
8 years ago

Seems like going with option three from comment 26 @lgladdy

Would be the way to go.

#40 @swissspidy
8 years ago

  • Owner set to swissspidy
  • Status changed from new to assigned

Just stumbled upon this whole user level handling now. Fun. I'll try to find some time to look into it properly.

Even just using a role query in post_author_meta_box() would already be a huge improvement, but I can see the benefits of capability queries.

By the way, for anyone using the Members plugin, add_filter( 'members_remove_old_levels', '__return_false' ); should help there.

#41 @DorZki
7 years ago

Hi all,
Is there anything new about this? this is a serious issue for some of the plugin developers and developers who use WordPress as a framework...

#42 @DekiGk
7 years ago

Is there any chance that we can resolve this?

#43 follow-up: @swissspidy
7 years ago

@DekiGk @DorZki my last comment still stands. I hope to have some time for this soon. If someone else wants to work on this as well, that would be awesome too.

#44 in reply to: ↑ 43 @DekiGk
7 years ago

Replying to swissspidy:

@DekiGk @DorZki my last comment still stands. I hope to have some time for this soon. If someone else wants to work on this as well, that would be awesome too.

Thank you very much for your quick response. Unfortunately, I am not yet confident enough in committing to core. It is, however, always on my mind, and it is something I will try and prepare myself for.

#45 @mcgoode
7 years ago

I have been looking into this and it is a rather deep issue since capabilities can be given to the user directly or to a role.

Roles and their capabilities live in the table wp_options.

select * from wp_options where option_name = wp_user_roles;

User capabilities and roles live in the table wp_usermeta.

select * from wp_usermeta where meta_key = wp_capabilties;

You are able to get users that have capability directly by:

$users = get_users(['role'=>'edit_others_posts']);

Which generates the following SQL

SELECT SQL_CALC_FOUND_ROWS wp_users.* FROM wp_users INNER JOIN wp_usermeta ON ( wp_users.ID = wp_usermeta.user_id ) WHERE 1=1 AND (
  (
    ( wp_usermeta.meta_key = 'wp_capabilities' AND wp_usermeta.meta_value LIKE '%\"edit\\_others\\_posts\"%' )
  )
) ORDER BY user_login ASC;

This works since its stored in the wp_capabilities array of the usermeta.

public 'allcaps' => 
        array (size=4)
          'read'              => boolean true
          'level_0'           => boolean true
          'subscriber'        => boolean true
          'edit_others_posts' => boolean true

But this does not check the roles assigned and their capabilities. Which is where I am guessing the improvement needs to be made. WP_User_Query needs to have additional functionality added.

As @lgladdy said:

3) Add a new capability option into WP_User_Query. This would basically be number 2 anyway - we'd just need to get the wp_user_roles option to figure out the list of roles, and then run that as a query similar to a multiple role search, but someone more familiar with core coding standards, the WP_User_Query class or the Role/Capability component maintainer(s) should be able to say if this is a good idea.

After looking at WP_User_Query and WP_Meta_Query, which is a helper to create joins, I am not sure you could implement a class like WP_Meta_Query to get the information from the database since you cannot effectively create a join on the two tables needed since both values are serialized.

So querying this from the database cannot be done effectively with how the data is stored currently. So there are two options change how Role and Capabilities are stored and mapped to users or do some PHP wizardry to make this work in the code.

I more for how the data is stored, since I am against storing any serialized code in a relational database, since that breaks the purpose of it being relational. However, I am not knowledgeable on the WordPress core so that might break a lot of thing already in place.

Maybe updating the get_users() function with a if switch that looks for a key in the args array like 'has_capabilities' that then gets all the users and their capabilities? Like someone else already said, sites with large numbers of users this would be an issue for.

Anyway this is something that effected a project I was working on a while back and just now decided to come take a second look. I want to help out, but I am still learning what makes WordPress tick.

#46 @swissspidy
7 years ago

@mcgoode

But this does not check the roles assigned and their capabilities. Which is where I am guessing the improvement needs to be made.

We don't need to check the roles. The dropdown could just show all users with the edit_posts capability. Since the caps are stored in user meta, this should work.

As mentioned before, I'll try to look into this as soon as possible.

#47 @swissspidy
7 years ago

  • Milestone changed from Future Release to 5.0

#48 @Brian_Milnes
7 years ago

This is still an issue. (Just encountered it when developing CPTs with Pods plugin.)
Must be tricky based on 7 years on, and not fettled, yet! :-o

Last edited 7 years ago by Brian_Milnes (previous) (diff)

#49 @swissspidy
7 years ago

I started a pull request for this one over at https://github.com/xwp/wordpress-develop/pull/286.

@boonebgorges I'd love your insight. Feel free to commit directly to that feature branch. You can ping Weston if you don't have access yet.

#50 @amibe
7 years ago

Found this solution/workaround from Justin Tadlock from Nov 2015: https://themehybrid.com/weblog/correcting-the-author-meta-box-drop-down

#51 @swissspidy
7 years ago

#43026 was marked as a duplicate.

#52 follow-up: @danielbachhuber
7 years ago

I'm -1 on the general idea of querying based on capabilities.

Capabilities can and are expected to be modified at runtime. As such, this makes them inherently unpredictable to query against.

Furthermore, edit_posts would only be applicable to post types that use it. Another post type could use something like edit_products. We'd be back at square one: users not appearing in the dropdown.

Truly solving the original problem described in this ticket would require refactoring WordPress' roles and capabilities system. Doing so is a non-trivial project and unlikely in the foreseeable future.

#53 in reply to: ↑ 52 @juiceboxint
7 years ago

Replying to danielbachhuber:

Furthermore, edit_posts would only be applicable to post types that use it. Another post type could use something like edit_products. We'd be back at square one: users not appearing in the dropdown.

Right, it would have to take into account the equivalent capability for whatever post type is being viewed, as set in the CPT definition function. So some CPTs may just map straight back to edit_posts for simplicity's sake, while another might create their own edit_staff_member capability to keep things separate.

At the end of the day, though, I don't know of a situation where a user who can view & edit this post (or page, or CPT) would not be allowed to be selected as an author. Is that correct? So I wonder if it is over-complicating the matter to look for any solution beyond "pull a list of people who are able to edit this particular post, using the same parameters that are used to determine whether they can view this particular edit screen in the first place".

So then it wouldn't really matter if capabilities can be modified at runtime, because the result has already been fully calculated by the very fact that this page is being viewed right now, so by the time the author box is rendered, we at least have a starting point - which can then be modified as needed by the existing filters.

#54 follow-up: @swissspidy
6 years ago

At the end of the day, though, I don't know of a situation where a user who can view & edit this post (or page, or CPT) would not be allowed to be selected as an author. Is that correct?

Not quite. That's the whole point of the ticket. This situationexists. Users with a custom role don't have the right user_level value. They can edit and view any post, but because of the user level they are not shown in the dropdown.

#55 in reply to: ↑ 54 @juiceboxint
6 years ago

Replying to swissspidy:

At the end of the day, though, I don't know of a situation where a user who can view & edit this post (or page, or CPT) would not be allowed to be selected as an author. Is that correct?

Not quite. That's the whole point of the ticket. This situation exists. Users with a custom role don't have the right user_level value. They can edit and view any post, but because of the user level they are not shown in the dropdown.

Yes - I apologize, I could have been more clear, upon reading it again. Rephrase it as "I don't know of a situation where a user who can view and edit this post should not be allowed to be selected as an author."

In other words: is there any reason that the authors dropdown can't just be "people who are allowed to edit this particular page" - a calculation which abandoned the user_level concept many years ago?

#56 @swissspidy
6 years ago

is there any reason that the authors dropdown can't just be "people who are allowed to edit this particular page"

It depends. I mean, this is the whole goal of the latest patches. To do exactly this. However, it's not as easy as one might think.

#57 @swissspidy
6 years ago

#44888 was marked as a duplicate.

This ticket was mentioned in Slack in #core by lakitteh. View the logs.


6 years ago

#59 @pento
6 years ago

  • Milestone changed from 5.0 to 5.1

#60 follow-up: @Mte90
6 years ago

To fix in your instance you have to run this piece of code and use the user role that you want.
After reading on Slack the problem is that usually usuers created manually (instead of registration screen) doesn't have this user_level configured.

Anyway in case your issue is different you can fix it running this code but you have to do it everytime until there is a fix for this problem.

Also this problem happen in REST API so this fix the problem also in Gutenberg.

$blogusers = get_users( 'role=instructor' );
foreach ( $blogusers as $user ) {
   $user->add_cap('level_1');
}

#61 @swissspidy
6 years ago

  • Milestone changed from 5.1 to 5.2

I'll try to get https://github.com/xwp/wordpress-develop/pull/286 up to date in order to fix this long-standing issue, but this won't happen in time for 5.1.

#62 in reply to: ↑ 60 @efi123
6 years ago

Replying to Mte90:

This snippet seems to have fixed the issue I was facing.
I use the "Super Socializer" plugin to create new users via Facebook login and assign them a custom role.

Until now authors showed as blank titles from the author dropdown menu.

After adding the code to my functions.php I could see author names showing in the quick edit section.

Thanks for that! I hope it will get fixed in 5.2.

To fix in your instance you have to run this piece of code and use the user role that you want.
After reading on Slack the problem is that usually usuers created manually (instead of registration screen) doesn't have this user_level configured.

Anyway in case your issue is different you can fix it running this code but you have to do it everytime until there is a fix for this problem.

Also this problem happen in REST API so this fix the problem also in Gutenberg.

$blogusers = get_users( 'role=instructor' );
foreach ( $blogusers as $user ) {
   $user->add_cap('level_1');
}
Last edited 6 years ago by efi123 (previous) (diff)

This ticket was mentioned in Slack in #core by audrasjb. View the logs.


6 years ago

#64 @audrasjb
6 years ago

  • Milestone changed from 5.2 to Future Release

Moving this ticket to Future Releaseas per today's bug scrub.

#65 @archon810
5 years ago

This bug is 9 years old, is there any solution in sight?

Plugins like https://themehybrid.com/plugins/members-role-levels exist with the sole purpose of fixing this issue, but are part of Members Pro which is $60/year.

#66 @scottconnerly
5 years ago

I’ve been Watching for almost the entire lifetime of the ticket (through the closes and reopens). I don’t use WP for much any more, but am SUPER curious if this ever does get prioritized :)

#67 @archon810
5 years ago

I just had to elevate a user to Editor status just to change the author because when he was Author, he wasn't showing up in the list, for whatever reason. And yes, we do use the Members plugin, though I don't quite understand why users set to Author, a built-in role, don't show up.

#68 @megabyterose
4 years ago

This is a ticket I often reference when assisting with internal tech support at my company. I'd love to see it become a priority because it creates extra work for us and encourages elevating access as a workaround, which is such a poor reason to elevate users' access.

#69 @stevenayers63
4 years ago

Please prioritize this issue as it has caused our dev team a world of pain. Thank you.

#70 @jdorner
4 years ago

I believe the cause of the issue is the post_author_meta_box() method in /wp-admin/includes/meta-boxes.php is calling wp_dropdown_users() with 'who' => 'authors'.
Which calls get_users with 'who' => 'authors' which calls WP_User_Query with 'who' => 'authors'.

SELECT [[wp_]users.ID,[wp_]users.user_login,[wp_]users.display_name FROM [wp_]users INNER JOIN [wp_]usermeta ON ( [wp_]users.ID = [wp_]usermeta.user_id ) WHERE 1=1 AND ( 
  ( [wp_]usermeta.meta_key = '[wp_]user_level' AND [wp_]usermeta.meta_value != '0' )
) ORDER BY display_name ASC


Why is WP_User_Query still using the deprecated field '[wp_]user_level'?

#71 @jdorner
4 years ago

If you are having the problem of users with a custom user role not being displayed as an option in the wp_dropdown_users list, you can change their role to any role other than subscriber(?) and then back. This will add a [wp_]user_level value other than 0 to their usermeta and they will be displayed.

#72 @swissspidy
3 years ago

#53909 was marked as a duplicate.

This ticket was mentioned in PR #1566 on WordPress/wordpress-develop by swissspidy.


3 years ago
#73

  • Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed

This PR adds capability options to WP_User_Query.

Basically, when querying for capabilities, it checks which roles do have these caps and queries for the roles instead. Plus, it queries for the capability as well in case it was added directly to a user.

Trac ticket: https://core.trac.wordpress.org/ticket/16841

swissspidy commented on PR #1566:


3 years ago
#74

Thanks for raising this!

Even with actually adding some of these caps to the database, they can always be filtered in some way or another (just like unfiltered_html and is_super_admin() checks, so I think the best way to handle this is by documenting this very very clearly and recommend developers to double check results with user_can() if needed.

The capability queries as implemented in this PR suffice for things like the author dropdown, but simply can't work for caps not added to the database, so some due diligence by the developer is unavoidable.

This ticket was mentioned in Slack in #core by swissspidy. View the logs.


3 years ago

#76 @swissspidy
3 years ago

  • Milestone changed from Future Release to 5.9

spacedmonkey commented on PR #1566:


3 years ago
#77

CC @TimothyBJacobs as this change includes REST API changes.

spacedmonkey commented on PR #1566:


3 years ago
#78

Has this been testing with say 10-50k users? I am little worried how well a meta query like search will scale.

swissspidy commented on PR #1566:


3 years ago
#79

Has this been testing with say 10-50k users? I am little worried how well a meta query like search will scale.

FWIW, all the role queries in WP_User_Query (i.e. role, role__in, role__not_in) already perform this kind of query on user meta. This ticket just expands this to capabilities as well.

While meta queries are not ideal performance-wise, these are the circumstances to work within.

It would be great if alternatives to user meta and meta queries could be explored in a dedicated ticket.

#80 @swissspidy
3 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 51943:

Role/Capability: Add support for capability queries in WP_User_Query.

Similar to the existing role/role__in/role__not_in query arguments, this adds support for three new query arguments in WP_User_Query:

  • capability
  • capability__in
  • capability__not_in

These can be used to fetch users with (or without) a specific set of capabilities, for example to get all users
with the capability to edit a certain post type.

Under the hood, this will check all existing roles on the site and perform a LIKE query against the capabilities user meta field to find:

  • all users with a role that has this capability
  • all users with the capability being assigned directly

Note: In WordPress, not all capabilities are stored in the database. Capabilities can also be modified using filters like map_meta_cap. These new query arguments do NOT work for such capabilities.

The prime use case for capability queries is to get all "authors", i.e. users with the capability to edit a certain post type.

Until now, 'who' => 'authors' was used for this, which relies on user levels. However, user levels were deprecated a long time ago and thus never added to custom roles. This led to constant frustration due to users with custom roles missing from places like author dropdowns.

This updates any usage of 'who' => 'authors' in core to use capability queries instead.

Subsequently, 'who' => 'authors' queries are being deprecated in favor of these new query arguments.

Also adds a new capabilities parameter (mapping to capability__in in WP_User_Query) to the REST API users controller.

Also updates twentyfourteen_list_authors() in Twenty Fourteen to make use of this new functionality, adding a new twentyfourteen_list_authors_query_args filter to make it easier to override this behavior.

Props scribu, lgladdly, boonebgorges, spacedmonkey, peterwilsoncc, SergeyBiryukov, swissspidy.
Fixes #16841.

#82 @johnbillion
3 years ago

  • Keywords needs-patch added; has-patch has-unit-tests removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

This change to the Twenty Fourteen theme means any new release of Twenty Fourteen will require WordPress 5.9 or higher. On WordPress 5.8 and earlier the query in twentyfourteen_list_authors() will return all users, not just authors.

The change to the theme needs revisiting.

#83 @swissspidy
3 years ago

Thanks for pointing that out!

WDYT about keeping both who=>authors and the new capability query in there at the same time? Or just keep who=>authors?

This ticket was mentioned in Slack in #core by audrasjb. View the logs.


3 years ago

#85 @johnbillion
3 years ago

Does capability override who? If so, let's put both in, If not, let's revert the change in the theme and stick with who=>authors.

#86 @desrosj
3 years ago

@swissspidy @johnbillion Are either of you able to get this one over the finish line before beta 1 (or shortly after).

#87 @swissspidy
3 years ago

I can take a look tomorrow Wednesday around the Beta 1 release.

To answer John's question:

who results in a query against user_level, capability in one against capabilities.
If both are provided, the query will be performed with "AND" relation.

I don't see any negative effects of keeping both, as the result would be the same as when only querying on of that.

#88 @swissspidy
3 years ago

Just uploaded a patch for Twenty Fourteen.

Went with a different route to avoid the deprecation warnings when using it on WP 5.9.

#89 @hellofromTonya
3 years ago

  • Keywords has-patch added; needs-patch removed

Hey @johnbillion, what do you think of 16841-twentyfourteen.diff for Twenty Fourteen?

#90 @johnbillion
3 years ago

  • Keywords commit added

LGTM and as Pascal says this avoids the deprecation warning in 5.9+.

#91 @hellofromTonya
3 years ago

  • Owner changed from swissspidy to hellofromTonya
  • Status changed from reopened to reviewing

Self-assigning for commit of 16841-twentyfourteen.diff.

#92 @hellofromTonya
3 years ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 52290:

Twenty Fourteen: Adjust capability queries when using version before WordPress 5.9-alpha.

As capability queries was introduced in 5.9, this commit allows for previous versions by assigning the "who" and unsetting "capability".

Follow-up to [51943].

Props johnbillion, swissspidy.
Fixes #16841.

#93 @swissspidy
3 years ago

  • Keywords needs-dev-note added

#94 @mnelson4
3 years ago

Just got the warning

Deprecated: WP_User_Query was called with an argument that is <strong>deprecated</strong> since version 5.9.0! <code>who</code> is deprecated. Use <code>capability</code> instead. in ...\wp-includes\functions.php on line 5600

Oups! Didn't realize I was even using it.

I noticed the new "capability" argument isn't listed on developer.wordpress.org yet. It probably should be, right? Sorry if this is the wrong place to mention that.

Also, for future similar situations, IMO it would have been nice to hold off deprecating the "who" argument for a few versions. Right now all plugins and themes that want to support WP 5.8 and 5.9 have to imitate @swissspidy's fix to twentytwnety theme if we want to avoid a warning; whereas if we held off deprecating "who" it until there were relatively few WP 5.8 users left, we could have just increased the plugin's minimum WordPress version to 5.9 and kept our code simpler.

Last edited 3 years ago by mnelson4 (previous) (diff)

#95 @johnbillion
3 years ago

In 52653:

Role/Capability: Correct the documented accepted types for the capability argument of WP_User_Query.

See #16841, #54729

Note: See TracTickets for help on using tickets.