wpmu_validate_blog_signup

The timeline below displays how wordpress function wpmu_validate_blog_signup has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The site name provided by the user. Must be unique.
 * @param string         $blog_title The site title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 *                                   Default empty string.
 * @return array {
 *     Array of domain, path, site name, site title, user and error messages.
 *
 *     @type string         $domain     Domain for the site.
 *     @type string         $path       Path for the site. Used in subdirectory installations.
 *     @type string         $blogname   The unique site name (slug).
 *     @type string         $blog_title Blog title.
 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
 *     @type WP_Error       $errors     WP_Error containing any errors found.
 * }
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if (false == $illegal_names) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names, true)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // Do not allow users to create a site that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // All numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = $domain;
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    /*
     * Do not allow users to create a site that matches an existing user's login name,
     * unless it's the user's own username.
     */
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    /*
     * Has someone already signed up for this domain?
     * TODO: Check email too?
     */
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    if ($signup instanceof stdClass) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, site name, site title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Site title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 6.2

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 *                                   Default empty string.
 * @return array {
 *     Array of domain, path, blog name, blog title, user and error messages.
 *
 *     @type string         $domain     Domain for the site.
 *     @type string         $path       Path for the site. Used in subdirectory installations.
 *     @type string         $blogname   The unique site name (slug).
 *     @type string         $blog_title Blog title.
 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
 *     @type WP_Error       $errors     WP_Error containing any errors found.
 * }
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if (false == $illegal_names) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names, true)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // Do not allow users to create a site that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // All numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = $domain;
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    /*
     * Do not allow users to create a site that matches an existing user's login name,
     * unless it's the user's own username.
     */
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    // TODO: Check email too?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    if ($signup instanceof stdClass) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 6.1

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array {
 *     Array of domain, path, blog name, blog title, user and error messages.
 *
 *     @type string         $domain     Domain for the site.
 *     @type string         $path       Path for the site. Used in subdirectory installations.
 *     @type string         $blogname   The unique site name (slug).
 *     @type string         $blog_title Blog title.
 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
 *     @type WP_Error       $errors     WP_Error containing any errors found.
 * }
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if (false == $illegal_names) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names, true)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // Do not allow users to create a site that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // All numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = $domain;
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    /*
     * Do not allow users to create a site that matches an existing user's login name,
     * unless it's the user's own username.
     */
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    // TODO: Check email too?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    if ($signup instanceof stdClass) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 5.6

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array {
 *     Array of domain, path, blog name, blog title, user and error messages.
 *
 *     @type string         $domain     Domain for the site.
 *     @type string         $path       Path for the site. Used in subdirectory installations.
 *     @type string         $blogname   The unique site name (slug).
 *     @type string         $blog_title Blog title.
 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
 *     @type WP_Error       $errors     WP_Error containing any errors found.
 * }
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if (false == $illegal_names) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names, true)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // Do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // All numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = $domain;
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    // TODO: Check email too?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    if ($signup instanceof stdClass) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 5.5

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array {
 *     Array of domain, path, blog name, blog title, user and error messages.
 *
 *     @type string         $domain     Domain for the site.
 *     @type string         $path       Path for the site. Used in subdirectory installations.
 *     @type string         $blogname   The unique site name (slug).
 *     @type string         $blog_title Blog title.
 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
 *     @type WP_Error       $errors     WP_Error containing any errors found.
 * }
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if (false == $illegal_names) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names, true)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // Do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // All numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    // TODO: Check email too?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    if (!empty($signup)) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 5.4

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array {
 *     Array of domain, path, blog name, blog title, user and error messages.
 *
 *     @type string         $domain     Domain for the site.
 *     @type string         $path       Path for the site. Used in subdirectory installations.
 *     @type string         $blogname   The unique site name (slug).
 *     @type string         $blog_title Blog title.
 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
 *     @type WP_Error       $errors     WP_Error containing any errors found.
 * }
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if (false == $illegal_names) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // Do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // All numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    // TODO: Check email too?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    if (!empty($signup)) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 5.3

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb   WordPress database abstraction object.
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: Minimum site name length. */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 5.2

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: minimum site name length */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = time() - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 5.1

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: minimum site name length */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare('SELECT post_name FROM ' . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.9

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU (3.0.0)
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installations, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: minimum site name length */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU (3.0.0)
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU (3.0.0)
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installations.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.8

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    /**
     * Filters the minimum site name length required when validating a site signup.
     *
     * @since 4.8.0
     *
     * @param int $length The minimum site name length. Default 4.
     */
    $minimum_site_name_length = apply_filters('minimum_site_name_length', 4);
    if (strlen($blogname) < $minimum_site_name_length) {
        /* translators: %s: minimum site name length */
        $errors->add('blogname', sprintf(_n('Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length), number_format_i18n($minimum_site_name_length)));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installs.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.7

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_network = get_network();
    $base = $current_network->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_network->site_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_network->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installs.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.6

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_site = get_current_site();
    $base = $current_site->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filters the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_site->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filters site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installs.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.4

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter 'wpmu_validate_blog_signup' if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string         $blogname   The blog name provided by the user. Must be unique.
 * @param string         $blog_title The blog title provided by the user.
 * @param WP_User|string $user       Optional. The user object to check against the new site name.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_site = get_current_site();
    $base = $current_site->path;
    $blog_title = strip_tags($blog_title);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, get_subdirectory_reserved_names());
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Site names can only contain lowercase letters (a-z) and numbers.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filter the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_site->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filter site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string         $domain     Domain for the site.
     *     @type string         $path       Path for the site. Used in subdirectory installs.
     *     @type string         $blogname   The unique site name (slug).
     *     @type string         $blog_title Blog title.
     *     @type string|WP_User $user       By default, an empty string. A user object if provided.
     *     @type WP_Error       $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.3

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter 'wpmu_validate_blog_signup' if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 *
 * @global wpdb   $wpdb
 * @global string $domain
 *
 * @param string $blogname   The blog name provided by the user. Must be unique.
 * @param string $blog_title The blog title provided by the user.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_site = get_current_site();
    $base = $current_site->path;
    $blog_title = strip_tags($blog_title);
    $blog_title = substr($blog_title, 0, 50);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge(
            $illegal_names,
            /**
             * Filter reserved site names on a sub-directory Multisite install.
             *
             * @since 3.0.0
             *
             * @param array $subdirectory_reserved_names Array of reserved names.
             */
            apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed'))
        );
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Only lowercase letters (a-z) and numbers are allowed.'));
    }
    if (in_array($blogname, $illegal_names)) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    if (strpos($blogname, '_') !== false) {
        $errors->add('blogname', __('Sorry, site names may not contain the character &#8220;_&#8221;!'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filter the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_site->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (!is_object($user) || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filter site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string   $domain     Domain for the site.
     *     @type string   $path       Path for the site. Used in subdirectory installs.
     *     @type string   $blogname   The unique site name (slug).
     *     @type string   $blog_title Blog title.
     *     @type string   $user       User email address.
     *     @type WP_Error $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 4.1

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter 'wpmu_validate_blog_signup' if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 *
 * @param string $blogname The blog name provided by the user. Must be unique.
 * @param string $blog_title The blog title provided by the user.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_site = get_current_site();
    $base = $current_site->path;
    $blog_title = strip_tags($blog_title);
    $blog_title = substr($blog_title, 0, 50);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge(
            $illegal_names,
            /**
             * Filter reserved site names on a sub-directory Multisite install.
             *
             * @since 3.0.0
             *
             * @param array $subdirectory_reserved_names Array of reserved names.
             */
            apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed'))
        );
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Only lowercase letters (a-z) and numbers are allowed.'));
    }
    if (in_array($blogname, $illegal_names) == true) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    if (strpos($blogname, '_') !== false) {
        $errors->add('blogname', __('Sorry, site names may not contain the character &#8220;_&#8221;!'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filter the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_site->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (is_object($user) == false || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filter site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string   $domain     Domain for the site.
     *     @type string   $path       Path for the site. Used in subdirectory installs.
     *     @type string   $blogname   The unique site name (slug).
     *     @type string   $blog_title Blog title.
     *     @type string   $user       User email address.
     *     @type WP_Error $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 3.8

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter 'wpmu_validate_blog_signup' if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 * @uses domain_exists()
 * @uses username_exists()
 *
 * @param string $blogname The blog name provided by the user. Must be unique.
 * @param string $blog_title The blog title provided by the user.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain;
    $current_site = get_current_site();
    $base = $current_site->path;
    $blog_title = strip_tags($blog_title);
    $blog_title = substr($blog_title, 0, 50);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    /*
     * On sub dir installs, some names are so illegal, only a filter can
     * spring them from jail.
     */
    if (!is_subdomain_install()) {
        $illegal_names = array_merge(
            $illegal_names,
            /**
             * Filter reserved site names on a sub-directory Multisite install.
             *
             * @since 3.0.0
             *
             * @param array $subdirectory_reserved_names Array of reserved names.
             */
            apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed'))
        );
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Only lowercase letters (a-z) and numbers are allowed.'));
    }
    if (in_array($blogname, $illegal_names) == true) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    if (strpos($blogname, '_') !== false) {
        $errors->add('blogname', __('Sorry, site names may not contain the character &#8220;_&#8221;!'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    /**
     * Filter the new site name during registration.
     *
     * The name is the site's subdomain or the site's subdirectory
     * path depending on the network settings.
     *
     * @since MU
     *
     * @param string $blogname Site name.
     */
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_site->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (is_object($user) == false || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    /**
     * Filter site details and error messages following registration.
     *
     * @since MU
     *
     * @param array $result {
     *     Array of domain, path, blog name, blog title, user and error messages.
     *
     *     @type string   $domain     Domain for the site.
     *     @type string   $path       Path for the site. Used in subdirectory installs.
     *     @type string   $blogname   The unique site name (slug).
     *     @type string   $blog_title Blog title.
     *     @type string   $user       User email address.
     *     @type WP_Error $errors     WP_Error containing any errors found.
     * }
     */
    return apply_filters('wpmu_validate_blog_signup', $result);
}

WordPress Version: 3.7

/**
 * Processes new site registrations.
 *
 * Checks the data provided by the user during blog signup. Verifies
 * the validity and uniqueness of blog paths and domains.
 *
 * This function prevents the current user from registering a new site
 * with a blogname equivalent to another user's login name. Passing the
 * $user parameter to the function, where $user is the other user, is
 * effectively an override of this limitation.
 *
 * Filter 'wpmu_validate_blog_signup' if you want to modify
 * the way that WordPress validates new site signups.
 *
 * @since MU
 * @uses domain_exists()
 * @uses username_exists()
 *
 * @param string $blogname The blog name provided by the user. Must be unique.
 * @param string $blog_title The blog title provided by the user.
 * @return array Contains the new site data and error messages.
 */
function wpmu_validate_blog_signup($blogname, $blog_title, $user = '')
{
    global $wpdb, $domain, $current_site;
    $base = $current_site->path;
    $blog_title = strip_tags($blog_title);
    $blog_title = substr($blog_title, 0, 50);
    $errors = new WP_Error();
    $illegal_names = get_site_option('illegal_names');
    if ($illegal_names == false) {
        $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator');
        add_site_option('illegal_names', $illegal_names);
    }
    // On sub dir installs, Some names are so illegal, only a filter can spring them from jail
    if (!is_subdomain_install()) {
        $illegal_names = array_merge($illegal_names, apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed')));
    }
    if (empty($blogname)) {
        $errors->add('blogname', __('Please enter a site name.'));
    }
    if (preg_match('/[^a-z0-9]+/', $blogname)) {
        $errors->add('blogname', __('Only lowercase letters (a-z) and numbers are allowed.'));
    }
    if (in_array($blogname, $illegal_names) == true) {
        $errors->add('blogname', __('That name is not allowed.'));
    }
    if (strlen($blogname) < 4 && !is_super_admin()) {
        $errors->add('blogname', __('Site name must be at least 4 characters.'));
    }
    if (strpos($blogname, '_') !== false) {
        $errors->add('blogname', __('Sorry, site names may not contain the character &#8220;_&#8221;!'));
    }
    // do not allow users to create a blog that conflicts with a page on the main blog.
    if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) {
        $errors->add('blogname', __('Sorry, you may not use that site name.'));
    }
    // all numeric?
    if (preg_match('/^[0-9]*$/', $blogname)) {
        $errors->add('blogname', __('Sorry, site names must have letters too!'));
    }
    $blogname = apply_filters('newblogname', $blogname);
    $blog_title = wp_unslash($blog_title);
    if (empty($blog_title)) {
        $errors->add('blog_title', __('Please enter a site title.'));
    }
    // Check if the domain/path has been used already.
    if (is_subdomain_install()) {
        $mydomain = $blogname . '.' . preg_replace('|^www\.|', '', $domain);
        $path = $base;
    } else {
        $mydomain = "{$domain}";
        $path = $base . $blogname . '/';
    }
    if (domain_exists($mydomain, $path, $current_site->id)) {
        $errors->add('blogname', __('Sorry, that site already exists!'));
    }
    if (username_exists($blogname)) {
        if (is_object($user) == false || is_object($user) && $user->user_login != $blogname) {
            $errors->add('blogname', __('Sorry, that site is reserved!'));
        }
    }
    // Has someone already signed up for this domain?
    $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path));
    // TODO: Check email too?
    if (!empty($signup)) {
        $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered);
        // If registered more than two days ago, cancel registration and let this signup go through.
        if ($diff > 2 * DAY_IN_SECONDS) {
            $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path));
        } else {
            $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.'));
        }
    }
    $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
    return apply_filters('wpmu_validate_blog_signup', $result);
}