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.

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.

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.

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()?

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:

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

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.

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 :)

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 notedit_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.

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.

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.

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.

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.

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 :)

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.

@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.

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.

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.

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.

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.

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?

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.

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.

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.

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.