WordPress User Levels were deprecated just partially

Do you remember what are the WordPress user levels? If you don’t, then read this “User Levels” article at the WordPress Codex. As you may noted, at the begin of the article author says that user levels were finally deprecated in WordPress 3.0. Is it the full true? It is not, at least for the moment I write this post or saying in terms of WordPress versions, WordPress 3.8 still partially uses user levels.

I discovered that searching the answer for “User Role Editor”‘s user support request. User alby54 complains there, that when he tries to change the author of the post, he does not see users with new custom role assigned at the “Authors” dropdown list menu.
After WordPress source code analysis I found that WordPress checks if user has user level higher then 0 in order to decide if include that user to the authors dropdown list or not.
So if you met with similar problem the decision is:
– turn on “deprecated” ‘level_0’, ‘level_1’, ‘level_2’ user capabilities for your custom role.
– reassign that role to your users in order to update the information about their user levels.

I included below the details of my investigation for those of you, who knows PHP and SQL and curious enough to look on the core of described issue.
Authors list at that menu is built by post_author_meta_box() function from wp-admin/includes/meta-boxes.php file, line #596:

/**
* Display form field with list of authors.
*
* @since 2.6.0
*
* @param object $post
*/
function post_author_meta_box($post) {
global $user_ID;
?>
<label class="screen-reader-text" for="post_author_override"><?php _e('Author'); ?></label>
<?php
wp_dropdown_users( array(
'who' => 'authors',
'name' => 'post_author_override',
'selected' => empty($post->ID) ? $user_ID : $post->post_author,
'include_selected' => true
) );
}

This function calls in turn wp_dropdown_users() function from wp-includes/user.php file. wp_dropdown_users() function has the ‘who’ parameter: “Which users to query. Currently only ‘authors’ is supported. Default is all users”. This parameter is interesting for our investigation purpose. It leads us to the WP_User_Query class from the same wp-includes/user.php file, where ‘who=authors’ parameter was converted into SQL command WHERE cluster part equal to

"WHERE 1=1 AND ( (wp_usermeta.meta_key = 'wp_user_level' AND CAST(wp_usermeta.meta_value AS CHAR) != '0') )"

Translating this to the human language – select users with user level not equal 0.

I think it’s time for WordPress developers to select some other strategy to differentiate users who can become the author of the post from the ordinal subscribers. Why do not check if the ‘edit_posts’ capability is available for the user? What do you think?

January 26th, 2022.
WordPress 5.9 changed this behavior.
‘who’ argument declared as deprecated. It’s recommended to use the ‘capability’ argument instead.

function post_author_meta_box( $post ) {
	global $user_ID;

	$post_type_object = get_post_type_object( $post->post_type );
	?>

	 array( $post_type_object->cap->edit_posts ),
			'name'             => 'post_author_override',
			'selected'         => empty( $post->ID ) ? $user_ID : $post->post_author,
			'include_selected' => true,
			'show'             => 'display_name_with_login',
		)
	);
}

Share