: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @param string $subject Subject of the notification email.
* @param string $domain Site domain.
* @param string $path Site path.
* @param string $title Site title.
* @param string $user_login User login name.
* @param string $user_email User email address.
* @param string $key Activation key created in wpmu_signup_blog().
* @param array $meta Signup meta data. By default, contains the requested privacy setting and lang_id.
'wpmu_signup_blog_notification_subject',
/* translators: New site notification email subject. 1: Network title, 2: New site URL. */
_x( '[%1$s] Activate %2$s', 'New site notification email subject' ),
esc_url( 'http://' . $domain . $path )
wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
if ( $switched_locale ) {
restore_previous_locale();
* Sends a confirmation request email to a user when they sign up for a new user account (without signing up for a site
* at the same time). The user account will not become active until the confirmation link is clicked.
* This is the notification function used when no new site has
* Filter {@see 'wpmu_signup_user_notification'} to bypass this function or
* replace it with your own notification behavior.
* Filter {@see 'wpmu_signup_user_notification_email'} and
* {@see 'wpmu_signup_user_notification_subject'} to change the content
* and subject line of the email sent to newly registered users.
* @param string $user_login The user's login name.
* @param string $user_email The user's email address.
* @param string $key The activation key created in wpmu_signup_user()
* @param array $meta Optional. Signup meta data. Default empty array.
function wpmu_signup_user_notification( $user_login, $user_email, $key, $meta = array() ) {
* Filters whether to bypass the email notification for new user sign-up.
* @param string $user_login User login name.
* @param string $user_email User email address.
* @param string $key Activation key created in wpmu_signup_user().
* @param array $meta Signup meta data. Default empty array.
if ( ! apply_filters( 'wpmu_signup_user_notification', $user_login, $user_email, $key, $meta ) ) {
$user = get_user_by( 'login', $user_login );
$switched_locale = $user && switch_to_user_locale( $user->ID );
// Send email with activation link.
$admin_email = get_site_option( 'admin_email' );
if ( '' === $admin_email ) {
$admin_email = 'support@' . wp_parse_url( network_home_url(), PHP_URL_HOST );
$from_name = ( '' !== get_site_option( 'site_name' ) ) ? esc_html( get_site_option( 'site_name' ) ) : 'WordPress';
$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . 'Content-Type: text/plain; charset="' . get_option( 'blog_charset' ) . "\"\n";
* Filters the content of the notification email for new user sign-up.
* Content should be formatted for transmission via wp_mail().
* @param string $content Content of the notification email.
* @param string $user_login User login name.
* @param string $user_email User email address.
* @param string $key Activation key created in wpmu_signup_user().
* @param array $meta Signup meta data. Default empty array.
'wpmu_signup_user_notification_email',
/* translators: New user notification email. %s: Activation URL. */
__( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login." ),
site_url( "wp-activate.php?key=$key" )
* Filters the subject of the notification email of new user signup.
* @param string $subject Subject of the notification email.
* @param string $user_login User login name.
* @param string $user_email User email address.
* @param string $key Activation key created in wpmu_signup_user().
* @param array $meta Signup meta data. Default empty array.
'wpmu_signup_user_notification_subject',
/* translators: New user notification email subject. 1: Network title, 2: New user login. */
_x( '[%1$s] Activate %2$s', 'New user notification email subject' ),
wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
if ( $switched_locale ) {
restore_previous_locale();
* Hook to {@see 'wpmu_activate_user'} or {@see 'wpmu_activate_blog'} for events
* that should happen only when users or sites are self-created (since
* those actions are not called when users and sites are created
* @global wpdb $wpdb WordPress database abstraction object.
* @param string $key The activation key provided to the user.
* @return array|WP_Error An array containing information about the activated user and/or blog.
function wpmu_activate_signup( $key ) {
$signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key ) );
if ( empty( $signup ) ) {
return new WP_Error( 'invalid_key', __( 'Invalid activation key.' ) );
if ( empty( $signup->domain ) ) {
return new WP_Error( 'already_active', __( 'The user is already active.' ), $signup );
return new WP_Error( 'already_active', __( 'The site is already active.' ), $signup );
$meta = maybe_unserialize( $signup->meta );
$password = wp_generate_password( 12, false );
$user_id = username_exists( $signup->user_login );
$user_id = wpmu_create_user( $signup->user_login, $password, $signup->user_email );
$user_already_exists = true;
return new WP_Error( 'create_user', __( 'Could not create user' ), $signup );
$now = current_time( 'mysql', true );
if ( empty( $signup->domain ) ) {
array( 'activation_key' => $key )
if ( isset( $user_already_exists ) ) {
return new WP_Error( 'user_already_exists', __( 'That username is already activated.' ), $signup );
* Fires immediately after a new user is activated.
* @param int $user_id User ID.
* @param string $password User password.
* @param array $meta Signup meta data.
do_action( 'wpmu_activate_user', $user_id, $password, $meta );
$blog_id = wpmu_create_blog( $signup->domain, $signup->path, $signup->title, $user_id, $meta, get_current_network_id() );
// TODO: What to do if we create a user but cannot create a blog?
if ( is_wp_error( $blog_id ) ) {
* If blog is taken, that means a previous attempt to activate this blog
* failed in between creating the blog and setting the activation flag.
* Let's just set the active flag and instruct the user to reset their password.
if ( 'blog_taken' === $blog_id->get_error_code() ) {
$blog_id->add_data( $signup );
array( 'activation_key' => $key )
array( 'activation_key' => $key )
* Fires immediately after a site is activated.
* @param int $blog_id Blog ID.
* @param int $user_id User ID.
* @param string $password User password.
* @param string $signup_title Site title.
* @param array $meta Signup meta data. By default, contains the requested privacy setting and lang_id.
do_action( 'wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta );
'title' => $signup->title,
* Deletes an associated signup entry when a user is deleted from the database.
* @global wpdb $wpdb WordPress database abstraction object.
* @param int $id ID of the user to delete.
* @param int|null $reassign ID of the user to reassign posts and links to.
* @param WP_User $user User object.
function wp_delete_signup_on_user_delete( $id, $reassign, $user ) {
$wpdb->delete( $wpdb->signups, array( 'user_login' => $user->user_login ) );
* This function runs when a user self-registers as well as when
* a Super Admin creates a new user. Hook to {@see 'wpmu_new_user'} for events
* that should affect all new users, but only on Multisite (otherwise
* use {@see 'user_register'}).
* @param string $user_name The new user's login name.
* @param string $password The new user's password.
* @param string $email The new user's email address.
* @return int|false Returns false on failure, or int $user_id on success.
function wpmu_create_user( $user_name, $password, $email ) {
$user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
$user_id = wp_create_user( $user_name, $password, $email );
if ( is_wp_error( $user_id ) ) {
// Newly created users have no roles or caps until they are added to a blog.
delete_user_option( $user_id, 'capabilities' );
delete_user_option( $user_id, 'user_level' );
* Fires immediately after a new user is created.
* @param int $user_id User ID.
do_action( 'wpmu_new_user', $user_id );
* This function runs when a user self-registers a new site as well
* as when a Super Admin creates a new site. Hook to {@see 'wpmu_new_blog'}
* for events that should affect all new sites.
* On subdirectory installations, $domain is the same as the main site's
* domain, and the path is the subdirectory name (eg 'example.com'
* and '/blog1/'). On subdomain installations, $domain is the new subdomain +
* root domain (eg 'blog1.example.com'), and $path is '/'.
* @param string $domain The new site's domain.
* @param string $path The new site's path.
* @param string $title The new site's title.
* @param int $user_id The user ID of the new site's admin.
* @param array $options Optional. Array of key=>value pairs used to set initial site options.
* If valid status keys are included ('public', 'archived', 'mature',
* 'spam', 'deleted', or 'lang_id') the given site status(es) will be
* updated. Otherwise, keys and values will be used to set options for
* the new site. Default empty array.
* @param int $network_id Optional. Network ID. Only relevant on multi-network installations.
* @return int|WP_Error Returns WP_Error object on failure, the new site ID on success.
function wpmu_create_blog( $domain, $path, $title, $user_id, $options = array(), $network_id = 1 ) {
$options = wp_parse_args( $options, $defaults );
$title = strip_tags( $title );
$user_id = (int) $user_id;
// Check if the domain has been used already. We should return an error message.
if ( domain_exists( $domain, $path, $network_id ) ) {
return new WP_Error( 'blog_taken', __( 'Sorry, that site already exists!' ) );
if ( ! wp_installing() ) {
$allowed_data_fields = array( 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' );
$site_data = array_merge(
'network_id' => $network_id,
array_intersect_key( $options, array_flip( $allowed_data_fields ) )
// Data to pass to wp_initialize_site().
$site_initialization_data = array(
'options' => array_diff_key( $options, array_flip( $allowed_data_fields ) ),
$blog_id = wp_insert_site( array_merge( $site_data, $site_initialization_data ) );
if ( is_wp_error( $blog_id ) ) {
wp_cache_set_sites_last_changed();
* Notifies the network admin that a new site has been activated.
* Filter {@see 'newblog_notify_siteadmin'} to change the content of
* the notification email.
* @since 5.1.0 $blog_id now supports input from the {@see 'wp_initialize_site'} action.
* @param WP_Site|int $blog_id The new site's object or ID.
* @param string $deprecated Not used.
function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) {
if ( is_object( $blog_id ) ) {
$blog_id = $blog_id->blog_id;
if ( 'yes' !== get_site_option( 'registrationnotification' ) ) {
$email = get_site_option( 'admin_email' );
if ( is_email( $email ) == false ) {
$options_site_url = esc_url( network_admin_url( 'settings.php' ) );
switch_to_blog( $blog_id );
$blogname = get_option( 'blogname' );
/* translators: New site notification email. 1: Site URL, 2: User IP address, 3: URL to Network Settings screen. */
Disable these notifications: %4$s'
wp_unslash( $_SERVER['REMOTE_ADDR'] ),
* Filters the message body of the new site activation email sent
* to the network administrator.
* @since 5.4.0 The `$blog_id` parameter was added.
* @param string $msg Email body.
* @param int|string $blog_id The new site's ID as an integer or numeric string.
$msg = apply_filters( 'newblog_notify_siteadmin', $msg, $blog_id );
/* translators: New site notification email subject. %s: New site URL. */
wp_mail( $email, sprintf( __( 'New Site Registration: %s' ), $siteurl ), $msg );
* Notifies the network admin that a new user has been activated.
* Filter {@see 'newuser_notify_siteadmin'} to change the content of
* the notification email.
* @param int $user_id The new user's ID.
function newuser_notify_siteadmin( $user_id ) {
if ( 'yes' !== get_site_option( 'registrationnotification' ) ) {
$email = get_site_option( 'admin_email' );
if ( is_email( $email ) == false ) {