Secure logins with passwords that are salted and hashed
User records with an email address, username, display name, avatar, and bio
Administrator views to browse, search, add, edit, and delete users
User roles to separate administrators from editors, authors, contributors, and subscribers
Pages for users to log in, register, and reset passwords
Add and manage user meta or profile fields for each user.
Define custom roles and capabilities for finer control over which users can access which areas.
How to access user data in your code
How to add custom fields to users
How to customize the user profiles and reports in the dashboard
How to add, update, and delete users
How to define custom roles and capabilities
How to extend the WordPress
User
class to create your own user-focused classes
Getting User Data
// get the WP_User object WordPress creates for the currently logged-in user
global
$current_user
;
// get the currently logged-in user with the wp_get_current_user() function
$user
=
wp_get_current_user
();
// set some variables
$user_id
=
1
;
$username
=
'jason'
;
=
This email address is being protected from spambots. You need JavaScript enabled to view it.'
;
// get a user by ID
$user
=
wp_getuserdata
(
$user_id
);
// get a user by another field
$user1
=
wp_get_user_by
(
'login'
,
$username
);
$user2
=
wp_get_user_by
(
'email'
,
);
// use the WP_User constructor directly
$user
=
new
WP_User
(
$user_id
);
//use the WP_User constructor with a username
$user
=
new
WP_User
(
$username
);
// get the currently logged-in user
$user
=
wp_get_current_user
();
// echo the user's display_name
echo
$user
->
display_name
;
// use user's email address to send an email
wp_mail
(
$user
->
user_email
,
'Email Subject'
,
'Email Body'
);
// get any user meta value
echo
'Department: '
.
$user
->
department
;
<?
php
$full_name
=
trim
(
$user
->
first_name
.
' '
.
$user
->
last_name
);
$full_name
=
trim
(
get_user_meta
(
$user
->
ID
,
'first_name'
)
.
' '
.
get_user_meta
(
$user
->
ID
,
'last_name'
)
);
?>
function
__get
(
$key
)
{
if
(
isset
(
$this
->
data
->
$key
)
)
{
$value
=
$this
->
data
->
$key
;
}
else
{
$value
=
get_user_meta
(
$this
->
ID
,
$key
,
true
);
}
return
$value
;
}
// dump all metadata for a user
$user_meta
=
get_user_meta
(
$user_id
);
foreach
(
$user_meta
as
$key
=>
$value
)
echo
$key
.
': '
.
$value
.
'<br />'
;
// Split assignments into multiple lines when using magic methods.
$user
->
graduation_year
=
'2012'
;
$year
=
'2012'
;
//To test if a meta value is empty, set a local variable first.
$year
=
$user
->
graduation_year
;
if
(
empty
(
$year
)
)
$year
=
'2012'
;
Add, Update, and Delete Users
// insert user from values we've gathered
$user_id
=
wp_insert_user
(
array
(
'user_login'
=>
$username
,
'user_pass'
=>
$password
,
'user_email'
=>
,
'first_name'
=>
$firstname
,
'last_name'
=>
$lastname
)
);
// check if username or email has already been used
if
(
is_wp_error
(
$user_id
)
){
echo
$return
->
get_error_message
();
}
else
{
// continue on with whatever you want to do with the new $user_id
}
// okay, log them in to WP
$creds
=
array
();
$creds
[
'user_login'
]
=
$username
;
$creds
[
'user_password'
]
=
$password
;
$creds
[
'remember'
]
=
true
;
$user
=
wp_signon
(
$creds
,
false
);
// this will update a user's email and leave other values alone
$userdata
=
array
(
'ID'
=>
1
,
'user_email'
=>
This email address is being protected from spambots. You need JavaScript enabled to view it.'
);
wp_update_user
(
$userdata
);
// this function is also perfect for updating multiple user meta fields at once
wp_update_user
(
array
(
'ID'
=>
1
,
'company'
=>
'Stranger Studios'
,
'title'
=>
'CEO'
,
'personality'
=>
'crescent fresh'
));
Note
update_user_meta
(
$user_id
,
$meta_key
,
$meta_value
,
$prev_value
)
// arrays will get serialized
$children
=
array
(
'Isaac'
,
'Marin'
);
update_user_meta
(
$user_id
,
'children'
,
$children
);
// you can also store an array by storing multiple values with the same key
add_user_meta
(
$user_id
,
'children'
,
'Isaac'
);
add_user_meta
(
$user_id
,
'children'
,
'Marin'
);
// when storing multiple values, specify the $prev_value parameter
// to select which one changes
update_user_meta
(
$user_id
,
'children'
,
'Isaac Ford'
,
'Isaac'
);
update_user_meta
(
$user_id
,
'children'
,
'Marin Josephine'
,
'Marin'
);
//delete all user meta by key
delete_user_meta
(
$user_id
,
'children'
);
//delete just one row when there are multiple values for one key
delete_user_meta
(
$user_id
,
'children'
,
'Isaac Ford'
);
<?
php
// get the IDs of all users with children named Isaac
$parents_of_isaac
=
$wpdb
->
get_col
(
"SELECT user_id
FROM
$wpdb->usermeta
WHERE meta_key = 'children'
AND meta_value = 'Isaac'"
);
?>
//this file contains wp_delete_user and is not always loaded, so let's make sure
require_once
(
ABSPATH
.
'/wp-admin/includes/user.php'
);
//delete the user
wp_delete_user
(
$user_id
);
//or delete a user and reassign their posts to user with ID #1
wp_delete_user
(
$user_id
,
1
);
// I want to make sure we really delete the user.
if
(
is_multisite
()
)
wp_delete_user
(
$user_id
);
else
wpmu_delete_user
(
$user_id
);
Hooks and Filters
//create a new "course" CPT when a teacher registers
function
sp_user_register
(
$user_id
){
// check if the new user is a teacher
if
(
pmpro_hasMembershipLevel
(
'teacher'
,
$user_id
)
)
{
// add a new "course" CPT with this user as author
wp_insert_post
(
array
(
'post_title'
=>
'My First Course'
,
'post_content'
=>
'This is a sample course...'
,
'post_author'
=>
$user_id
,
'post_status'
=>
'draft'
,
'post_type'
=>
'course'
)
);
}
}
add_action
(
'user_register'
,
'sp_user_register'
);
If you hook on
delete_user
early enough, you might be able to abort the user delete.If you hook on
deleted_user
, some user data and connections may already be gone and unavailable:
<?
php
// send an email when a user is being deleted
function
sp_delete_user
(
$user_id
){
$user
=
get_userdata
(
$user_id
);
wp_mail
(
$user
->
user_email
,
"You've been deleted."
,
'Your account at SchoolPress has been deleted.'
);
}
// want to be able to get user_email so hook in early
add_action
(
'delete_user'
,
'sp_delete_user'
);
?>
What Are Roles and Capabilities?
Checking a User’s Role and Capabilities
if
(
current_user_can
(
'manage_options'
)
)
{
// has the manage options capability, typically an admin
}
if
(
current_user_can
(
'edit_user'
,
$user_id
)
)
{
// can edit the user with ID = $user_id.
// typically either the user himself or an admin
}
if
(
current_user_can
(
'edit_post'
,
$post_id
)
)
{
// can edit the post with ID = $post_id.
// typically the author of the post or an admin or editor
}
if
(
current_user_can
(
'subscriber'
)
)
{
// one way to check if the current user is a subscriber
}
<?
php
/*
Output comments for the current post,
highlighting anyone who has capabilities to edit it.
*/
global
$post
;
// current post we are looking at
$comments
=
get_comments
(
'post_id='
.
$post
->
ID
);
foreach
(
$comments
as
$comment
)
{
// default CSS classes for all comments
$classes
=
'comment'
;
// add can-edit CSS class to authors
if
(
user_can
(
$comment
->
user_id
,
'edit_post'
,
$post
->
ID
)
)
{
$classes
.=
' can-edit'
;
}
?>
<div id="comment-
<?php
echo
$comment
->
comment_ID
;
?>
"
class="
<?php
echo
$classes
;
?>
">
Comment by
<?php
echo
$comment
->
comment_author
;
?>
:
<?php
echo
wpautop
(
$comment
->
comment_content
);
?>
</div>
<?php
}
function
upgradeSubscriberToAuthor
(
$user_id
)
{
$user
=
new
WP_User
(
$user_id
);
if
(
in_array
(
'subscriber'
,
$user
->
roles
)
)
{
$user
->
set_role
(
'author'
);
}
}
Creating Custom Roles and Capabilities
function
sp_roles_and_caps
()
{
// Office Manager Role
remove_role
(
'office'
);
// in case we updated the caps below
add_role
(
'office'
,
'Office Manager'
,
array
(
'read'
=>
true
,
'create_users'
=>
true
,
'delete_users'
=>
true
,
'edit_users'
=>
true
,
'list_users'
=>
true
,
'promote_users'
=>
true
,
'remove_users'
=>
true
,
'office_report'
=>
true
// new cap for our custom report
));
}
// run this function on plugin activation
register_activation_hook
(
__FILE__
,
'sp_roles_and_caps'
);
Note
// give admins our office_report cap to let them view that report
$role
=
get_role
(
'administrator'
);
$role
->
add_cap
(
'office_report'
);
// don't let editors edit pages
$role
=
get_role
(
'editor'
);
$role
->
remove_cap
(
'edit_pages'
);
Extending the WP_User Class
<?
php
// Student is a class that extends WP_User
$student
=
new
Student
();
foreach
(
$student
->
getAssignments
()
as
$assignment
)
{
// assignment here is an instance of a class that extends WP_Post
$assignment
->
();
}
?>
$student
=
wp_get_current_user
();
// return WP_User object for current user
foreach
(
sp_getAssignmentsByUser
(
$student
->
ID
)
as
$assignment
)
{
sp_printAssignment
(
$assignment
->
ID
);
}
<?
php
class
Student
extends
WP_User
{
// no constructor so WP_User's constructor is used
// method to get assignments for this Student
function
getAssignments
()
{
// get assignments via get_posts if we haven't yet
if
(
!
isset
(
$this
->
data
->
assignments
)
)
$this
->
data
->
assignments
=
get_posts
(
array
(
'post_type'
=>
'assignment'
,
// assignments
'numberposts'
=>
-
1
,
// all posts
'author'
=>
$this
->
ID
// user ID for this Student
));
return
$this
->
data
->
assignments
;
}
// magic method to detect $student->assignments
function
__get
(
$key
)
{
if
(
$key
==
'assignments'
)
{
return
$this
->
getAssignments
();
}
else
{
// fallback to default WP_User magic method
return
parent
::
__get
(
$key
);
}
}
}
?>
Adding Registration and Profile Fields
Example 6-1. Registering additional fields for users
<?
php
function
ps_registration_fields
(){
// store fields in an array
$fields
=
array
();
// fields for all users
$fields
[]
=
new
PMProRH_Field
(
'gender'
,
'select'
,
array
(
'options'
=>
array
(
''
=>
'Choose One'
,
'male'
=>
'Male'
,
'female'
=>
'Female'
,
'other'
=>
'Other'
,
'undisclosed'
=>
'Prefer not to say'
),
'profile'
=>
true
,
'required'
=>
true
)
);
$fields
[]
=
new
PMProRH_Field
(
'age'
,
'text'
,
array
(
'size'
=>
10
,
'profile'
=>
true
,
'required'
=>
true
)
);
$fields
[]
=
new
PMProRH_Field
(
'phone'
,
'text'
,
array
(
'size'
=>
20
,
'label'
=>
'Phone Number'
,
'profile'
=>
true
,
'required'
=>
true
)
);
// fields for teachers
$fields
[]
=
new
PMProRH_Field
(
'department'
,
'text'
,
array
(
'size'
=>
40
,
'profile'
=>
true
,
'required'
=>
true
)
);
$fields
[]
=
new
PMProRH_Field
(
'office'
,
'text'
,
array
(
'size'
=>
40
,
'profile'
=>
true
,
'required'
=>
true
)
);
// fields for students
$fields
[]
=
new
PMProRH_Field
(
'graduation_year'
,
'text'
,
array
(
'label'
=>
'Expected Graduation year'
,
'size'
=>
10
,
'profile'
=>
true
,
'required'
=>
true
)
);
$fields
[]
=
new
PMProRH_Field
(
'major'
,
'text'
,
array
(
'size'
=>
40
,
'profile'
=>
true
,
'required'
=>
true
)
);
$fields
[]
=
new
PMProRH_Field
(
'minor'
,
'text'
,
array
(
'size'
=>
40
,
'profile'
=>
true
)
);
// add fields to the registration page
foreach
(
$fields
as
$field
)
{
pmprorh_add_registration_field
(
'after_password'
,
$field
);
}
}
add_action
(
'init'
,
'ps_registration_fields'
);
?>
Add our field to the registration page:
<?
php
function
sp_register_form
(){
// get the age value passed into the form
if
(
!
empty
(
$_REQUEST
[
'age'
]
)
)
$age
=
intval
(
$_REQUEST
[
'age'
]
);
else
$age
=
''
;
// show input
?>
<p>
<label for="age">Age<br />
<input type="text" name="age" id="age" class="input"
value="
<?php
echo
esc_attr
(
$age
);
?>
" />
</label>
</p>
<?php
}
add_action
(
'register_form'
,
'sp_register_form'
);
?>
Note
We check
if ( ! empty( $_REQUEST['age'] ) )
to avoid a PHP warning when users first visit the registration page and there isn’t any form data in$REQUEST
yet. We also use theesc_attr()
function when outputting the age into the value attribute of the input field. Escape functions are covered in detail in This Blog.Update our user’s age after registering:
function
sp_register_user
(
$user_id
){
// get the age value passed into the form
$age
=
intval
(
$_REQUEST
[
'age'
]
);
// update user meta
update_user_meta
(
$user_id
,
'age'
,
$age
);
}
add_action
(
'register_user'
,
'sp_register_user'
);
Add the
age
field to the user profile page. We need to hook into bothshow_user_profile
andedit_user_profile
to show our custom field both when users are viewing their own profile and when administrators are editing other users’ profiles:<?
php
function
sp_user_profile
(
$user
){
// show input
$age
=
$user
->
age
;
?>
<table class="form-table">
<tbody>
<tr>
<th><label for="age">Age</label></th>
<td>
<input type="text" name="age" id="age" class="input"
value="
<?php
echo
esc_attr
(
$age
);
?>
"/>
</td>
</tr>
</tbody>
</table>
<?php
}
//user's own profile
add_action
(
'show_user_profile'
,
'sp_user_profile'
);
//admins editing user profiles
add_action
(
'edit_user_profile'
,
'sp_user_profile'
);
?>
Note how the default WordPress registration page HTML uses
<p>
tags to separate fields, whereas the default profile HTML in the dashboard uses table rows.Update our field when updating a profile:
<?
php
function
sp_profile_update
(
$user_id
){
//make sure the current user can edit this user
if
(
!
current_user_can
(
'edit_user'
,
$user_id
)
)
{
return
false
;
}
// check if value has been posted
if
(
isset
(
$_POST
[
'age'
]
)
){
// update user meta
update_user_meta
(
$user_id
,
'age'
,
intval
(
$_POST
[
'age'
]
)
);
}
}
// user's own profile
add_action
(
'personal_options_update'
,
'sp_profile_update'
);
// admins editing
add_action
(
'edit_user_profile_update'
,
'sp_profile_update'
);
?>
Customizing the Users Table in the Dashboard
// add our column to the table
function
sp_manage_users_columns
(
$columns
){
$columns
[
'age'
]
=
'Age'
;
return
$columns
;
}
add_filter
(
'manage_users_columns'
,
'sp_manage_users_columns'
);
// tell WordPress how to populate the column
function
sp_manage_users_custom_column
(
$value
,
$column_name
,
$user_id
){
$user
=
get_userdata
(
$user_id
);
if
(
$column_name
==
'age'
)
$value
=
$user
->
age
;
return
$value
;
}
add_filter
(
'manage_users_custom_column'
,
'sp_manage_users_custom_column'
,
10
,
3
);
<?
php
// make the column sortable
function
sp_manage_users_sortable_columns
(
$columns
){
$columns
[
'age'
]
=
'Age'
;
return
$columns
;
}
add_filter
(
'manage_users_sortable_columns'
,
'sp_manage_users_sortable_columns'
);
// update user_query if sorting by Age
function
sp_pre_user_query
(
$user_query
){
global
$wpdb
,
$current_screen
;
// make sure we are viewing the users list in the dashboard
if
(
$current_screen
->
id
!=
'users'
)
{
return
;
}
// order by age
if
(
$user_query
->
query_vars
[
'orderby'
]
==
'Age'
)
{
$user_query
->
query_from
.=
" INNER JOIN
$wpdb->usermeta
m1
ON
$wpdb->users
u1
AND (u1.ID = m1.user_id)
AND (m1.meta_key = 'age')"
;
$user_query
->
query_orderby
=
" ORDER BY m1.meta_value
"
.
esc_sql
(
$user_query
->
query_vars
[
'order'
]
);
}
}
add_action
(
'pre_user_query'
,
'sp_pre_user_query'
);
?>
Plugins
Theme My Login
Hide the Admin Bar from Nonadministrators
Paid Memberships Pro
PMPro Register Helper
<?
php
$text
=
new
PMProRH_Field
(
'company'
,
'text'
,
array
(
'size'
=>
40
,
'class'
=>
'company'
,
'profile'
=>
true
,
'required'
=>
true
)
);
pmprorh_add_registration_field
(
'after_billing_fields'
,
$text
);
?>
Members
WP User Fields
1 Any class method starting with two underscores is considered a magic method in PHP because it is magically kicked off during certain events.
2 For clarity, we took out parts of the method that were for reverse compatibility and filtering in certain circumstances. The preceding code contains the spirit of the method.
3 This is how the Paid Memberships Pro plugin registers users from the checkout page.
4 When we talk about teachers and students as people, we will leave them lowercase. When talking about our Teacher and Student user types and objects, we capitalize these words.
5 Paid Memberships Pro Register Helper was built to work with Paid Memberships Pro, but will work without it as well.