Users in WordPress
Basic information you need to know about WordPress users.
Table wp_users

- ID(number)
- User ID. Specified only if you need to update data for an existing user. All required parameters become optional.
- user_login(string) (required)
- Login of the new user. To perform additional validation of the login before creation/update, you can use the filter: pre_user_login.
- user_pass(string) (required)
- Password for the created user. Hashed.
- user_nicename(string)
- User's name. If not specified, it will be the same as the login. Contains a sanitized login for use in the URL - sanitized through sanitize_title(). For example, if the email [email protected] is provided in the login field during registration, it will result in userexample-com. Used in the link to the author's archive page, so the field value must be unique for each user.
- user_email(string)
- Email. Checked for existence in the database.
- user_url(string)
- Website. Filter: pre_user_url.
- user_registered(DATETIME)
- Registration date. Format: Y-m-d H:i:s. If not specified when creating a user, the current date within the GMT range is taken.
- user_activation_key
- Hash key for password recovery, created when requested. See get_password_reset_key().
- user_status(not used)
This field is no longer used by the WordPress core, which was previously used in Multisite when moving a user to spam (this functionality has been removed). See more in the function: update_user_status().
You can use the column for your own purposes, but it's better to leave it alone.
- display_name(string)
- Display name. If empty, it will be the same as the login.
Table wp_usermeta

Important meta-data (meta-fields)
- wp_capabilities(array)
User role and capabilities:
a:1:{s:13:"administrator";b:1;}
.IMPORTANT! The prefix of this option
wp_
must match the prefix of the database tables$wpdb->prefix
or$wpdb->get_blog_prefix()
for multisite.For example, if the table prefix is changed on the live site in
wp-config.php
, then the prefix in this option also needs to be manually changed, otherwise all users will lose their rights because after changing the prefix, for example, towk_
, WordPress will look for rights in the meta-fieldwk_capabilities
.- session_tokens
- Active sessions. Created when logging into the account.
Other data stored in the metadata table
- nickname(string)
- Nickname. If empty, it will be the same as the login.
- first_name(string)
- First name.
- last_name(string)
- Last name.
- description(string)
- A little about yourself.
- rich_editing(string/bool)
- Enable (true) or disable (false) the visual editor. See user_can_richedit().
Default - 'true' - syntax_highlighting(string/bool)
- Whether to enable syntax highlighting for the visual editor.
- comment_shortcuts(string/bool)
- Whether to enable comment moderation shortcuts for the user. Whether to enqueue the script
enqueue_comment_hotkeys_js
. See enqueue_comment_hotkeys_js().
Default - 'false' - use_ssl(string/bool)
- Whether the user should always log in via https.
Default - 'false' - show_admin_bar_front(string)
- Whether to show the admin bar on the site or not.
Default - 'true' - role(string)
- User role.
Default is taken from the settings: get_option('default_role') - locale(string)
- User's language (locale). For example: ru_RU. Since WP 4.7.
Default - '' - default_password_nag(true/false)
- true - means that the default password is set.
Also, the metadata contains Admin Panel Options — these are settings for admin pages and more. For example: saved choices of metaboxes on different pages.
meta_key | meta_value |
---|---|
admin_color | midnight |
closedpostboxes_dashboard | a:0:{} |
metaboxhidden_dashboard | a:4:{i:0;s:17:"dashboard_primary";i:1;s:24:"tinypng_dashboard_widget";i:2;s:18:"dashboard_activity";i:3;s:21:"dashboard_quick_press";} |
closedpostboxes_{POST_TYPE} | a:1:{i:0;s:11:"commentsdiv";} |
metaboxhidden_{POST_TYPE} | a:3:{i:0;s:7:"slugdiv";i:1;s:13:"trackbacksdiv";i:2;s:11:"commentsdiv";} |
meta-box-order_dashboard | |
meta-box-order_{POST_TYPE} | |
meta-box-order | |
wp_media_library_mode | Can be: list or grid. See upload.php |
show_welcome_panel | 0 |
show_admin_bar_front | true |
wp_user-settings deprecated: wp_usersettings |
editor=tinymce&editor_expand=off&libraryContent=browse&dtmenuRight=1&mfold=o&posts_list_mode=list |
wp_user-settings-time deprecated: wp_usersettingstime |
1604820217 |
dismissed_wp_pointers | Various notes that need to be shown to the user in the admin panel. Can store the following keys: theme_editor_notice,wp330_toolbar,wp330_media_uploader,wp330_saving_widgets,wp340_customize_current_theme_link,wp340_choose_image_from_library,wp350_media,wp360_revisions,wp360_locks,wp390_widgets,wp410_dfw,wp496_privacy |
{PAGE_KEY}_per_page | On WP_List_Table pages, how many items to display in the table. Examples of option names: edit_post_per_page, users_per_page, edit_comments_per_page, upload_per_page |
User Roles and Capabilities
User Role Editor - a plugin for managing roles. WordPress user role editor, the plugin allows easy modification of user roles and capabilities.
There are 6 roles in WordPress by default:
Super Admin | Super Administrator. Has rights to manage the network sites. This role appears only in multisite installation. |
administrator | The administrator of the site (a separate site in the network multisite). |
editor | Editor. Has access to all posts, pages, comments, categories, tags, and links. |
author | Author. Can create, upload photos, edit and publish his posts. |
contributor | Contributor. Can create posts, which are then published by an editor or administrator. |
subscriber | Subscriber. Can't do anything except edit profile. |
Which role the new user gets is specified in Settings > General
. The data is saved in an options: users_can_register and default_role:

List of Capabilities by Roles
A list of primitive (fundamental) user caps. These are capabilities that the specified roles (users) have by default. This list of caps is set once, when you install WordPress - it is stored in the database wp_options
table in the wp_user_roles
option.
Capability | Super-admin | Admin | Editor | Author | Contributor | Subscriber |
---|---|---|---|---|---|---|
read | yes | yes | yes | yes | yes | yes |
delete_posts | yes | yes | yes | yes | yes | |
edit_posts | yes | yes | yes | yes | yes | |
delete_published_posts | yes | yes | yes | yes | ||
edit_published_posts | yes | yes | yes | yes | ||
publish_posts | yes | yes | yes | yes | ||
upload_files | yes | yes | yes | yes | ||
delete_others_pages | yes | yes | yes | |||
delete_others_posts | yes | yes | yes | |||
delete_pages | yes | yes | yes | |||
delete_private_pages | yes | yes | yes | |||
delete_private_posts | yes | yes | yes | |||
delete_published_pages | yes | yes | yes | |||
edit_others_pages | yes | yes | yes | |||
edit_others_posts | yes | yes | yes | |||
edit_pages | yes | yes | yes | |||
edit_private_pages | yes | yes | yes | |||
edit_private_posts | yes | yes | yes | |||
edit_published_pages | yes | yes | yes | |||
manage_categories | yes | yes | yes | |||
manage_links | yes | yes | yes | |||
moderate_comments | yes | yes | yes | |||
publish_pages | yes | yes | yes | |||
read_private_pages | yes | yes | yes | |||
read_private_posts | yes | yes | yes | |||
unfiltered_html | yes | yes ¹ | yes ¹ | |||
activate_plugins | yes | yes ² | ||||
create_users | yes | yes ¹ | ||||
deactivate_plugins | yes | yes | ||||
delete_plugins | yes | yes ¹ | ||||
delete_themes | yes | yes ¹ | ||||
delete_users | yes | yes ¹ | ||||
edit_dashboard | yes | yes | ||||
edit_files | yes | yes ¹ | ||||
edit_plugins | yes | yes ¹ | ||||
edit_theme_options | yes | yes | ||||
edit_themes | yes | yes ¹ | ||||
edit_users | yes | yes ¹ | ||||
export | yes | yes | ||||
import | yes | yes | ||||
install_languages | yes | yes ¹ | ||||
install_plugins | yes | yes ¹ | ||||
install_themes | yes | yes ¹ | ||||
list_users | yes | yes | ||||
manage_options | yes | yes | ||||
promote_users | yes | yes | ||||
remove_users | yes | yes | ||||
switch_themes | yes | yes | ||||
update_core | yes | yes ¹ | ||||
update_languages | yes | yes ¹ | ||||
update_plugins | yes | yes ¹ | ||||
update_themes | yes | yes ¹ | ||||
unfiltered_upload | yes ³ | yes ³ | ||||
manage_network_options | yes | |||||
manage_network_plugins | yes | |||||
manage_network_themes | yes | |||||
manage_network_users | yes | |||||
manage_network | yes | |||||
manage_sites | yes | |||||
setup_network | yes | |||||
upgrade_network | yes |
¹
— when one site (not a multisite).²
— when one site (not a multisite). Or enabled in the network settings.³
— this right must be included separately, more below.
Meta Capabilities
Above is a list of primitive (fundamental) rights. But there are also so-called meta-rights. They are not saved anywhere, but are computed "on the fly" and eventually turn into a primitive right.
List of meta-rights:
activate_plugin activate_plugins add_comment_meta add_post_meta add_term_meta add_user_meta add_users assign_categories assign_post_tags assign_term create_app_password create_sites create_users customize deactivate_plugin deactivate_plugins delete_app_password delete_app_passwords delete_categories delete_comment_meta delete_page delete_page delete_plugins delete_post delete_post delete_post_meta delete_post_tags delete_site delete_sites delete_term delete_term_meta delete_themes delete_user delete_user delete_user_meta delete_users edit_app_password edit_categories edit_comment edit_comment edit_comment_meta edit_css edit_files edit_page edit_page edit_plugins edit_post edit_post edit_post_meta edit_post_tags edit_term edit_term_meta edit_themes edit_user edit_user edit_user_meta edit_users erase_others_personal_data export_others_personal_data install_languages install_plugins install_themes list_app_passwords manage_links manage_network manage_network_options manage_network_plugins manage_network_themes manage_network_users manage_post_tags manage_privacy_options manage_sites promote_user promote_user publish_post read_app_password read_page read_page read_post read_post remove_user remove_user resume_plugin resume_theme setup_network unfiltered_html unfiltered_upload update_core update_https update_languages update_php update_plugins update_themes upgrade_network upload_plugins upload_themes edit_term — WP 4.7 — It does not check who created the term - it only checks if the specified term and taxonomy exist. delete_term — WP 4.7 — assign_term — WP 4.7 — activate_plugin — WP 4.9 — current_user_can( 'activate_plugin', 'my-plugin/my-plugin.php' ) deactivate_plugin — WP 4.9 — current_user_can( 'deactivate_plugin', 'my-plugin/my-plugin.php' ) export_others_personal_data — WP 4.9.6 — is_multisite() ? 'manage_network' : 'manage_options' erase_others_personal_data — WP 4.9.6 — is_multisite() ? 'manage_network' : 'manage_options' manage_privacy_options — WP 4.9.6 — is_multisite() ? 'manage_network' : 'manage_options' update_php — WP 5.0 — is_multisite() ? is_super_admin() : update_core update_https — WP 5.7 — is_multisite() ? is_super_admin() : manage_options | update_core create_app_password — WP 5.7 — map_meta_cap( 'edit_user', $user_id ) list_app_passwords — WP 5.7 — map_meta_cap( 'edit_user', $user_id ) read_app_password — WP 5.7 — map_meta_cap( 'edit_user', $user_id ) edit_app_password — WP 5.7 — map_meta_cap( 'edit_user', $user_id ) delete_app_passwords — WP 5.7 — map_meta_cap( 'edit_user', $user_id ) delete_app_password — WP 5.7 — map_meta_cap( 'edit_user', $user_id )
To check such rights, you need to pass additional parameters, such as the ID of the post for which you want to check whether the user can edit it. For example:
if( current_user_can( 'edit_post', 123 ) ){ echo 'The current user can edit post 123'; }
In this case, WP checks on the fly whether the user is the author of that post, or has the primitive right to edit all posts. As a result, if the check is passed, this meta right turns into a similar primitive right edit_posts
that allows the action to be performed.
Read more about meta rights in map_meta_cap().
Dynamic Capabilities
These are caps that are not stored in the database but are calculated on the fly based on certain conditions. This calculation is done on the hook user_has_cap.
install_languages — WP 4.9 — update_core || install_plugins || install_themes resume_plugins — WP 5.2 — activate_plugins resume_themes — WP 5.2 — switch_themes view_site_health_checks — WP 5.2 — install_plugins && is_super_admin (multisite)
See wp_maybe_grant_install_languages_cap()
See wp_maybe_grant_resume_extensions_caps()
See wp_maybe_grant_site_health_caps()
unfiltered_upload
By default, the unfiltered_upload
capability is available to the administrator. However, this right is locked by default, i.e. roles will not pass the if( current_user_can('unfiltered_upload') )
despite having this right.
To make the unfiltered_upload capability start working as expected, you need to add following constant in wp-config.php:
define( 'ALLOW_UNFILTERED_UPLOADS', true );
With the definition of this constant, roles with unfiltered_upload
permission will be able to upload files with any extension (without checking the file type).
For multisite, only the Super Administrator has the unfiltered_upload
right. If another role has the unfiltered_upload
right, it will simply be ignored. See checking the meta-right in map_meta_cap() for details:
case 'unfiltered_upload': if ( defined( 'ALLOW_UNFILTERED_UPLOADS' ) && ALLOW_UNFILTERED_UPLOADS && ( ! is_multisite() || is_super_admin( $user_id ) ) ) { $caps[] = $cap; } else { $caps[] = 'do_not_allow'; } break;
PHP Functions
See the full list of functions here. Here are some of the functions:
current_user_can() | Whether the current user has a specific capability. |
wp_get_current_user() | Retrieve the current authorized user data (WP_User object). Sets current user, if not set yet. |
get_current_user_id() | Get the current user's ID. |
is_user_logged_in() | Checks if the current visitor is a logged in user. |
get_userdata() | Retrieve user data by user ID as WP_User object. |
get_user_by() | Gets the user by the specified field and the value of this field (by ID, login, mail). |
get_users() | Gets users according to the passed parameters. |
update_user_meta() | Update user meta field based on user ID. |
get_user_meta() | Gets an single meta field or all meta fields of the specified user. |
delete_user_meta() | Remove metadata matching criteria from a user. |
map_meta_cap() | Map meta capabilities to primitive capabilities. |
wp_insert_user() | Creates a WordPress user in the Database. |
wp_update_user() | Update a user data in the database. Work with both tables wp_usermeta and wp_users. |
wp_create_user() | A simpler way of inserting a user into the database. |
register_new_user() | Handles registering a new user. |
wp_login_url() | Retrieves the login URL. |
wp_signon() | Authenticates and logs a user in with 'remember' capability. |
wp_set_password() | Updates the user's password with a new encrypted one. Updates the specified password in the database and resets the user's cache. |
wp_check_password() | Checks the plaintext password against the encrypted Password. |
WP_User::add_cap() | Add capability and grant or deny access to capability. |
User Authorization (Setting) Process
To set the current user in the core, the following functions are hooked onto the determine_current_user hook. Each of them sets the current user for different types of requests (front, REST request).
add_filter( 'determine_current_user', 'wp_validate_auth_cookie' ); add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 ); add_filter( 'determine_current_user', 'wp_validate_application_password', 20 );
The hook determine_current_user is triggered upon the first call of the function wp_get_current_user(), which is based on the function _wp_get_current_user().
_wp_get_current_user() sets the current user in the global variable $current_user
upon the first call and retrieves data from there on subsequent calls.
The earliest the function wp_get_current_user() can be called is the plugins_loaded event (preferably with a high priority, so it runs at the end), i.e., after all plugins are loaded and their basic initialization is completed.
In general, it is recommended to call it on the init hook, i.e., after the core and all plugins are loaded and their basic code is executed, and the next step is to display data on the screen.