function wp_get_session_token() {
$cookie = wp_parse_auth_cookie( '', 'logged_in' );
return ! empty( $cookie['token'] ) ? $cookie['token'] : '';
* Retrieve a list of sessions for the current user.
* @return array Array of sessions.
function wp_get_all_sessions() {
$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
return $manager->get_all();
* Remove the current session token from the database.
function wp_destroy_current_session() {
$token = wp_get_session_token();
$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
$manager->destroy( $token );
* Remove all but the current session token for the current user for the database.
function wp_destroy_other_sessions() {
$token = wp_get_session_token();
$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
$manager->destroy_others( $token );
* Remove all session tokens for the current user from the database.
function wp_destroy_all_sessions() {
$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
* Get the user IDs of all users with no role on this site.
* @since 4.9.0 The `$site_id` parameter was added to support multisite.
* @param int|null $site_id Optional. The site ID to get users with no role for. Defaults to the current site.
* @return string[] Array of user IDs as strings.
function wp_get_users_with_no_role( $site_id = null ) {
$site_id = get_current_blog_id();
$prefix = $wpdb->get_blog_prefix( $site_id );
if ( is_multisite() && get_current_blog_id() != $site_id ) {
switch_to_blog( $site_id );
$role_names = wp_roles()->get_names();
$role_names = wp_roles()->get_names();
$regex = implode( '|', array_keys( $role_names ) );
$regex = preg_replace( '/[^a-zA-Z_\|-]/', '', $regex );
WHERE meta_key = '{$prefix}capabilities'
AND meta_value NOT REGEXP %s
* Retrieves the current user object.
* Will set the current user, if the current user is not set. The current user
* will be set to the logged-in person. If no user is logged-in, then it will
* set the current user to 0, which is invalid and won't have any permissions.
* This function is used by the pluggable functions wp_get_current_user() and
* get_currentuserinfo(), the latter of which is deprecated but used for backward
* @see wp_get_current_user()
* @global WP_User $current_user Checks if the current user is set.
* @return WP_User Current WP_User instance.
function _wp_get_current_user() {
if ( ! empty( $current_user ) ) {
if ( $current_user instanceof WP_User ) {
// Upgrade stdClass to WP_User.
if ( is_object( $current_user ) && isset( $current_user->ID ) ) {
$cur_id = $current_user->ID;
wp_set_current_user( $cur_id );
// $current_user has a junk value. Force to WP_User with ID 0.
wp_set_current_user( 0 );
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
wp_set_current_user( 0 );
* Filters the current user.
* The default filters use this to determine the current user from the
* request's cookies, if available.
* Returning a value of false will effectively short-circuit setting
* @param int|false $user_id User ID if one has been determined, false otherwise.
$user_id = apply_filters( 'determine_current_user', false );
wp_set_current_user( 0 );
wp_set_current_user( $user_id );
* Send a confirmation request email when a change of user email address is attempted.
* @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
* @global WP_Error $errors WP_Error object.
function send_confirmation_on_profile_email() {
$current_user = wp_get_current_user();
if ( ! is_object( $errors ) ) {
$errors = new WP_Error();
if ( $current_user->ID != $_POST['user_id'] ) {
if ( $current_user->user_email != $_POST['email'] ) {
if ( ! is_email( $_POST['email'] ) ) {
__( '<strong>Error</strong>: The email address isn’t correct.' ),
if ( email_exists( $_POST['email'] ) ) {
__( '<strong>Error</strong>: The email address is already used.' ),
delete_user_meta( $current_user->ID, '_new_email' );
$hash = md5( $_POST['email'] . time() . wp_rand() );
'newemail' => $_POST['email'],
update_user_meta( $current_user->ID, '_new_email', $new_user_email );
$sitename = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
/* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
You recently requested to have the email address on your account changed.
If this is correct, please click on the following link to change it:
You can safely ignore and delete this email if you do not want to
This email has been sent to ###EMAIL###
* Filters the text of the email sent when a change of user email address is attempted.
* The following strings have a special meaning and will get replaced dynamically:
* - ###USERNAME### The current user's username.
* - ###ADMIN_URL### The link to click on to confirm the email change.
* - ###EMAIL### The new email.
* - ###SITENAME### The name of the site.
* - ###SITEURL### The URL to the site.
* @since 4.9.0 This filter is no longer Multisite specific.
* @param string $email_text Text in the email.
* @param array $new_user_email {
* Data relating to the new user email address.
* @type string $hash The secure hash used in the confirmation link URL.
* @type string $newemail The proposed new email address.
$content = apply_filters( 'new_user_email_content', $email_text, $new_user_email );
$content = str_replace( '###USERNAME###', $current_user->user_login, $content );
$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail=' . $hash ) ), $content );
$content = str_replace( '###EMAIL###', $_POST['email'], $content );
$content = str_replace( '###SITENAME###', $sitename, $content );
$content = str_replace( '###SITEURL###', home_url(), $content );
/* translators: New email address notification email subject. %s: Site title. */
wp_mail( $_POST['email'], sprintf( __( '[%s] Email Change Request' ), $sitename ), $content );
$_POST['email'] = $current_user->user_email;
* Adds an admin notice alerting the user to check for confirmation request email
* after email address change.
* @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
* @global string $pagenow
function new_user_email_admin_notice() {
if ( 'profile.php' === $pagenow && isset( $_GET['updated'] ) ) {
$email = get_user_meta( get_current_user_id(), '_new_email', true );
/* translators: %s: New email address. */
echo '<div class="notice notice-info"><p>' . sprintf( __( 'Your email address has not been updated yet. Please check your inbox at %s for a confirmation email.' ), '<code>' . esc_html( $email['newemail'] ) . '</code>' ) . '</p></div>';
* Get all personal data request types.
* @return array List of core privacy action types.
function _wp_privacy_action_request_types() {
* Registers the personal data exporter for users.
* @param array $exporters An array of personal data exporters.
* @return array An array of personal data exporters.
function wp_register_user_personal_data_exporter( $exporters ) {
$exporters['wordpress-user'] = array(
'exporter_friendly_name' => __( 'WordPress User' ),
'callback' => 'wp_user_personal_data_exporter',
* Finds and exports personal data associated with an email address from the user and user_meta table.
* @since 5.4.0 Added 'Community Events Location' group to the export data.
* @since 5.4.0 Added 'Session Tokens' group to the export data.
* @param string $email_address The user's email address.
* @return array An array of personal data.
function wp_user_personal_data_exporter( $email_address ) {
$email_address = trim( $email_address );
$data_to_export = array();
$user = get_user_by( 'email', $email_address );
$user_meta = get_user_meta( $user->ID );
$user_props_to_export = array(
'user_login' => __( 'User Login Name' ),
'user_nicename' => __( 'User Nice Name' ),
'user_email' => __( 'User Email' ),
'user_url' => __( 'User URL' ),
'user_registered' => __( 'User Registration Date' ),
'display_name' => __( 'User Display Name' ),
'nickname' => __( 'User Nickname' ),
'first_name' => __( 'User First Name' ),
'last_name' => __( 'User Last Name' ),
'description' => __( 'User Description' ),
$user_data_to_export = array();
foreach ( $user_props_to_export as $key => $name ) {
$value = $user->data->$key;
$value = $user_meta[ $key ][0];
if ( ! empty( $value ) ) {
$user_data_to_export[] = array(
// Get the list of reserved names.
$reserved_names = array_values( $user_props_to_export );
* Filter to extend the user's profile data for the privacy exporter.
* @param array $additional_user_profile_data {
* An array of name-value pairs of additional user data items. Default empty array.
* @type string $name The user-facing name of an item name-value pair,e.g. 'IP Address'.
* @type string $value The user-facing value of an item data pair, e.g. '50.60.70.0'.
* @param WP_User $user The user whose data is being exported.
* @param string[] $reserved_names An array of reserved names. Any item in `$additional_user_data`
* that uses one of these for its `name` will not be included in the export.
$_extra_data = apply_filters( 'wp_privacy_additional_user_profile_data', array(), $user, $reserved_names );
if ( is_array( $_extra_data ) && ! empty( $_extra_data ) ) {
// Remove items that use reserved names.
$extra_data = array_filter(
function( $item ) use ( $reserved_names ) {
return ! in_array( $item['name'], $reserved_names, true );
if ( count( $extra_data ) !== count( $_extra_data ) ) {
/* translators: %s: wp_privacy_additional_user_profile_data */
__( 'Filter %s returned items with reserved names.' ),
'<code>wp_privacy_additional_user_profile_data</code>'
if ( ! empty( $extra_data ) ) {
$user_data_to_export = array_merge( $user_data_to_export, $extra_data );
$data_to_export[] = array(
'group_label' => __( 'User' ),
'group_description' => __( 'User’s profile data.' ),
'item_id' => "user-{$user->ID}",
'data' => $user_data_to_export,
if ( isset( $user_meta['community-events-location'] ) ) {
$location = maybe_unserialize( $user_meta['community-events-location'][0] );
$location_props_to_export = array(
'description' => __( 'City' ),
'country' => __( 'Country' ),
'latitude' => __( 'Latitude' ),
'longitude' => __( 'Longitude' ),
$location_data_to_export = array();
foreach ( $location_props_to_export as $key => $name ) {
if ( ! empty( $location[ $key ] ) ) {
$location_data_to_export[] = array(
'value' => $location[ $key ],
$data_to_export[] = array(
'group_id' => 'community-events-location',
'group_label' => __( 'Community Events Location' ),
'group_description' => __( 'User’s location data used for the Community Events in the WordPress Events and News dashboard widget.' ),
'item_id' => "community-events-location-{$user->ID}",
'data' => $location_data_to_export,
if ( isset( $user_meta['session_tokens'] ) ) {
$session_tokens = maybe_unserialize( $user_meta['session_tokens'][0] );
$session_tokens_props_to_export = array(
'expiration' => __( 'Expiration' ),
'ua' => __( 'User Agent' ),
'login' => __( 'Last Login' ),