wp/wp-includes/ms-functions.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     8  */
     8  */
     9 
     9 
    10 /**
    10 /**
    11  * Gets the network's site and user counts.
    11  * Gets the network's site and user counts.
    12  *
    12  *
    13  * @since MU 1.0
    13  * @since MU (3.0.0)
    14  *
    14  *
    15  * @return array Site and user count for the network.
    15  * @return array Site and user count for the network.
    16  */
    16  */
    17 function get_sitestats() {
    17 function get_sitestats() {
    18 	$stats = array(
    18 	$stats = array(
    22 
    22 
    23 	return $stats;
    23 	return $stats;
    24 }
    24 }
    25 
    25 
    26 /**
    26 /**
    27  * Get the admin for a domain/path combination.
       
    28  *
       
    29  * @since MU 1.0
       
    30  *
       
    31  * @param string $sitedomain Optional. Site domain.
       
    32  * @param string $path Optional. Site path.
       
    33  * @return array The network admins
       
    34  */
       
    35 function get_admin_users_for_domain( $sitedomain = '', $path = '' ) {
       
    36 	global $wpdb;
       
    37 
       
    38 	if ( ! $sitedomain )
       
    39 		$site_id = $wpdb->siteid;
       
    40 	else
       
    41 		$site_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE domain = %s AND path = %s", $sitedomain, $path ) );
       
    42 
       
    43 	if ( $site_id )
       
    44 		return $wpdb->get_results( $wpdb->prepare( "SELECT u.ID, u.user_login, u.user_pass FROM $wpdb->users AS u, $wpdb->sitemeta AS sm WHERE sm.meta_key = 'admin_user_id' AND u.ID = sm.meta_value AND sm.site_id = %d", $site_id ), ARRAY_A );
       
    45 
       
    46 	return false;
       
    47 }
       
    48 
       
    49 /**
       
    50  * Get one of a user's active blogs
    27  * Get one of a user's active blogs
    51  *
    28  *
    52  * Returns the user's primary blog, if they have one and
    29  * Returns the user's primary blog, if they have one and
    53  * it is active. If it's inactive, function returns another
    30  * it is active. If it's inactive, function returns another
    54  * active blog of the user. If none are found, the user
    31  * active blog of the user. If none are found, the user
    55  * is added as a Subscriber to the Dashboard Blog and that blog
    32  * is added as a Subscriber to the Dashboard Blog and that blog
    56  * is returned.
    33  * is returned.
    57  *
    34  *
    58  * @since MU 1.0
    35  * @since MU (3.0.0)
    59  *
    36  *
    60  * @param int $user_id The unique ID of the user
    37  * @param int $user_id The unique ID of the user
    61  * @return object The blog object
    38  * @return WP_Site|void The blog object
    62  */
    39  */
    63 function get_active_blog_for_user( $user_id ) {
    40 function get_active_blog_for_user( $user_id ) {
    64 	global $wpdb;
       
    65 	$blogs = get_blogs_of_user( $user_id );
    41 	$blogs = get_blogs_of_user( $user_id );
    66 	if ( empty( $blogs ) )
    42 	if ( empty( $blogs ) )
    67 		return null;
    43 		return;
    68 
    44 
    69 	if ( !is_multisite() )
    45 	if ( ! is_multisite() ) {
    70 		return $blogs[$wpdb->blogid];
    46 		return $blogs[ get_current_blog_id() ];
       
    47 	}
    71 
    48 
    72 	$primary_blog = get_user_meta( $user_id, 'primary_blog', true );
    49 	$primary_blog = get_user_meta( $user_id, 'primary_blog', true );
    73 	$first_blog = current($blogs);
    50 	$first_blog = current($blogs);
    74 	if ( false !== $primary_blog ) {
    51 	if ( false !== $primary_blog ) {
    75 		if ( ! isset( $blogs[ $primary_blog ] ) ) {
    52 		if ( ! isset( $blogs[ $primary_blog ] ) ) {
    76 			update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id );
    53 			update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id );
    77 			$primary = get_blog_details( $first_blog->userblog_id );
    54 			$primary = get_site( $first_blog->userblog_id );
    78 		} else {
    55 		} else {
    79 			$primary = get_blog_details( $primary_blog );
    56 			$primary = get_site( $primary_blog );
    80 		}
    57 		}
    81 	} else {
    58 	} else {
    82 		//TODO Review this call to add_user_to_blog too - to get here the user must have a role on this blog?
    59 		//TODO Review this call to add_user_to_blog too - to get here the user must have a role on this blog?
    83 		add_user_to_blog( $first_blog->userblog_id, $user_id, 'subscriber' );
    60 		$result = add_user_to_blog( $first_blog->userblog_id, $user_id, 'subscriber' );
    84 		update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id );
    61 
    85 		$primary = $first_blog;
    62 		if ( ! is_wp_error( $result ) ) {
       
    63 			update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id );
       
    64 			$primary = $first_blog;
       
    65 		}
    86 	}
    66 	}
    87 
    67 
    88 	if ( ( ! is_object( $primary ) ) || ( $primary->archived == 1 || $primary->spam == 1 || $primary->deleted == 1 ) ) {
    68 	if ( ( ! is_object( $primary ) ) || ( $primary->archived == 1 || $primary->spam == 1 || $primary->deleted == 1 ) ) {
    89 		$blogs = get_blogs_of_user( $user_id, true ); // if a user's primary blog is shut down, check their other blogs.
    69 		$blogs = get_blogs_of_user( $user_id, true ); // if a user's primary blog is shut down, check their other blogs.
    90 		$ret = false;
    70 		$ret = false;
    91 		if ( is_array( $blogs ) && count( $blogs ) > 0 ) {
    71 		if ( is_array( $blogs ) && count( $blogs ) > 0 ) {
    92 			foreach ( (array) $blogs as $blog_id => $blog ) {
    72 			foreach ( (array) $blogs as $blog_id => $blog ) {
    93 				if ( $blog->site_id != $wpdb->siteid )
    73 				if ( $blog->site_id != get_current_network_id() )
    94 					continue;
    74 					continue;
    95 				$details = get_blog_details( $blog_id );
    75 				$details = get_site( $blog_id );
    96 				if ( is_object( $details ) && $details->archived == 0 && $details->spam == 0 && $details->deleted == 0 ) {
    76 				if ( is_object( $details ) && $details->archived == 0 && $details->spam == 0 && $details->deleted == 0 ) {
    97 					$ret = $blog;
    77 					$ret = $blog;
    98 					if ( get_user_meta( $user_id , 'primary_blog', true ) != $blog_id )
    78 					if ( get_user_meta( $user_id , 'primary_blog', true ) != $blog_id )
    99 						update_user_meta( $user_id, 'primary_blog', $blog_id );
    79 						update_user_meta( $user_id, 'primary_blog', $blog_id );
   100 					if ( !get_user_meta($user_id , 'source_domain', true) )
    80 					if ( !get_user_meta($user_id , 'source_domain', true) )
   101 						update_user_meta( $user_id, 'source_domain', $blog->domain );
    81 						update_user_meta( $user_id, 'source_domain', $blog->domain );
   102 					break;
    82 					break;
   103 				}
    83 				}
   104 			}
    84 			}
   105 		} else {
    85 		} else {
   106 			return null;
    86 			return;
   107 		}
    87 		}
   108 		return $ret;
    88 		return $ret;
   109 	} else {
    89 	} else {
   110 		return $primary;
    90 		return $primary;
   111 	}
    91 	}
   114 /**
    94 /**
   115  * The number of active users in your installation.
    95  * The number of active users in your installation.
   116  *
    96  *
   117  * The count is cached and updated twice daily. This is not a live count.
    97  * The count is cached and updated twice daily. This is not a live count.
   118  *
    98  *
   119  * @since MU 2.7
    99  * @since MU (3.0.0)
   120  *
   100  * @since 4.8.0 The $network_id parameter has been added.
   121  * @return int
   101  *
   122  */
   102  * @param int|null $network_id ID of the network. Default is the current network.
   123 function get_user_count() {
   103  * @return int Number of active users on the network.
   124 	return get_site_option( 'user_count' );
   104  */
       
   105 function get_user_count( $network_id = null ) {
       
   106 	return get_network_option( $network_id, 'user_count' );
   125 }
   107 }
   126 
   108 
   127 /**
   109 /**
   128  * The number of active sites on your installation.
   110  * The number of active sites on your installation.
   129  *
   111  *
   130  * The count is cached and updated twice daily. This is not a live count.
   112  * The count is cached and updated twice daily. This is not a live count.
   131  *
   113  *
   132  * @since MU 1.0
   114  * @since MU (3.0.0)
   133  *
   115  * @since 3.7.0 The $network_id parameter has been deprecated.
   134  * @param int $network_id Deprecated, not supported.
   116  * @since 4.8.0 The $network_id parameter is now being used.
   135  * @return int
   117  *
   136  */
   118  * @param int|null $network_id ID of the network. Default is the current network.
   137 function get_blog_count( $network_id = 0 ) {
   119  * @return int Number of active sites on the network.
   138 	if ( func_num_args() )
   120  */
   139 		_deprecated_argument( __FUNCTION__, '3.1' );
   121 function get_blog_count( $network_id = null ) {
   140 
   122 	return get_network_option( $network_id, 'blog_count' );
   141 	return get_site_option( 'blog_count' );
       
   142 }
   123 }
   143 
   124 
   144 /**
   125 /**
   145  * Get a blog post from any site on the network.
   126  * Get a blog post from any site on the network.
   146  *
   127  *
   147  * @since MU 1.0
   128  * @since MU (3.0.0)
   148  *
   129  *
   149  * @param int $blog_id ID of the blog.
   130  * @param int $blog_id ID of the blog.
   150  * @param int $post_id ID of the post you're looking for.
   131  * @param int $post_id ID of the post you're looking for.
   151  * @return WP_Post|null WP_Post on success or null on failure
   132  * @return WP_Post|null WP_Post on success or null on failure
   152  */
   133  */
   157 
   138 
   158 	return $post;
   139 	return $post;
   159 }
   140 }
   160 
   141 
   161 /**
   142 /**
   162  * Add a user to a blog.
   143  * Adds a user to a blog.
   163  *
   144  *
   164  * Use the 'add_user_to_blog' action to fire an event when
   145  * Use the {@see 'add_user_to_blog'} action to fire an event when users are added to a blog.
   165  * users are added to a blog.
   146  *
   166  *
   147  * @since MU (3.0.0)
   167  * @since MU 1.0
   148  *
   168  *
   149  * @param int    $blog_id ID of the blog you're adding the user to.
   169  * @param int $blog_id ID of the blog you're adding the user to.
   150  * @param int    $user_id ID of the user you're adding.
   170  * @param int $user_id ID of the user you're adding.
   151  * @param string $role    The role you want the user to have
   171  * @param string $role The role you want the user to have
   152  * @return true|WP_Error
   172  * @return bool
       
   173  */
   153  */
   174 function add_user_to_blog( $blog_id, $user_id, $role ) {
   154 function add_user_to_blog( $blog_id, $user_id, $role ) {
   175 	switch_to_blog($blog_id);
   155 	switch_to_blog($blog_id);
   176 
   156 
   177 	$user = get_userdata( $user_id );
   157 	$user = get_userdata( $user_id );
   179 	if ( ! $user ) {
   159 	if ( ! $user ) {
   180 		restore_current_blog();
   160 		restore_current_blog();
   181 		return new WP_Error( 'user_does_not_exist', __( 'The requested user does not exist.' ) );
   161 		return new WP_Error( 'user_does_not_exist', __( 'The requested user does not exist.' ) );
   182 	}
   162 	}
   183 
   163 
       
   164 	/**
       
   165 	 * Filters whether a user should be added to a site.
       
   166 	 *
       
   167 	 * @since 4.9.0
       
   168 	 *
       
   169 	 * @param bool|WP_Error $retval  True if the user should be added to the site, false
       
   170 	 *                               or error object otherwise.
       
   171 	 * @param int           $user_id User ID.
       
   172 	 * @param string        $role    User role.
       
   173 	 * @param int           $blog_id Site ID.
       
   174 	 */
       
   175 	$can_add_user = apply_filters( 'can_add_user_to_blog', true, $user_id, $role, $blog_id );
       
   176 
       
   177 	if ( true !== $can_add_user ) {
       
   178 		restore_current_blog();
       
   179 
       
   180 		if ( is_wp_error( $can_add_user ) ) {
       
   181 			return $can_add_user;
       
   182 		}
       
   183 
       
   184 		return new WP_Error( 'user_cannot_be_added', __( 'User cannot be added to this site.' ) );
       
   185 	}
       
   186 
   184 	if ( !get_user_meta($user_id, 'primary_blog', true) ) {
   187 	if ( !get_user_meta($user_id, 'primary_blog', true) ) {
   185 		update_user_meta($user_id, 'primary_blog', $blog_id);
   188 		update_user_meta($user_id, 'primary_blog', $blog_id);
   186 		$details = get_blog_details($blog_id);
   189 		$site = get_site( $blog_id );
   187 		update_user_meta($user_id, 'source_domain', $details->domain);
   190 		update_user_meta( $user_id, 'source_domain', $site->domain );
   188 	}
   191 	}
   189 
   192 
   190 	$user->set_role($role);
   193 	$user->set_role($role);
   191 
   194 
   192 	/**
   195 	/**
   193 	 * Fires immediately after a user is added to a site.
   196 	 * Fires immediately after a user is added to a site.
   194 	 *
   197 	 *
   195 	 * @since MU
   198 	 * @since MU (3.0.0)
   196 	 *
   199 	 *
   197 	 * @param int    $user_id User ID.
   200 	 * @param int    $user_id User ID.
   198 	 * @param string $role    User role.
   201 	 * @param string $role    User role.
   199 	 * @param int    $blog_id Blog ID.
   202 	 * @param int    $blog_id Blog ID.
   200 	 */
   203 	 */
   201 	do_action( 'add_user_to_blog', $user_id, $role, $blog_id );
   204 	do_action( 'add_user_to_blog', $user_id, $role, $blog_id );
   202 	wp_cache_delete( $user_id, 'users' );
   205 	wp_cache_delete( $user_id, 'users' );
       
   206 	wp_cache_delete( $blog_id . '_user_count', 'blog-details' );
   203 	restore_current_blog();
   207 	restore_current_blog();
   204 	return true;
   208 	return true;
   205 }
   209 }
   206 
   210 
   207 /**
   211 /**
   208  * Remove a user from a blog.
   212  * Remove a user from a blog.
   209  *
   213  *
   210  * Use the 'remove_user_from_blog' action to fire an event when
   214  * Use the {@see 'remove_user_from_blog'} action to fire an event when
   211  * users are removed from a blog.
   215  * users are removed from a blog.
   212  *
   216  *
   213  * Accepts an optional $reassign parameter, if you want to
   217  * Accepts an optional `$reassign` parameter, if you want to
   214  * reassign the user's blog posts to another user upon removal.
   218  * reassign the user's blog posts to another user upon removal.
   215  *
   219  *
   216  * @since MU 1.0
   220  * @since MU (3.0.0)
   217  *
   221  *
   218  * @param int $user_id ID of the user you're removing.
   222  * @global wpdb $wpdb WordPress database abstraction object.
   219  * @param int $blog_id ID of the blog you're removing the user from.
   223  *
       
   224  * @param int    $user_id  ID of the user you're removing.
       
   225  * @param int    $blog_id  ID of the blog you're removing the user from.
   220  * @param string $reassign Optional. A user to whom to reassign posts.
   226  * @param string $reassign Optional. A user to whom to reassign posts.
   221  * @return bool
   227  * @return true|WP_Error
   222  */
   228  */
   223 function remove_user_from_blog($user_id, $blog_id = '', $reassign = '') {
   229 function remove_user_from_blog($user_id, $blog_id = '', $reassign = '') {
   224 	global $wpdb;
   230 	global $wpdb;
   225 	switch_to_blog($blog_id);
   231 	switch_to_blog($blog_id);
   226 	$user_id = (int) $user_id;
   232 	$user_id = (int) $user_id;
   227 	/**
   233 	/**
   228 	 * Fires before a user is removed from a site.
   234 	 * Fires before a user is removed from a site.
   229 	 *
   235 	 *
   230 	 * @since MU
   236 	 * @since MU (3.0.0)
   231 	 *
   237 	 *
   232 	 * @param int $user_id User ID.
   238 	 * @param int $user_id User ID.
   233 	 * @param int $blog_id Blog ID.
   239 	 * @param int $blog_id Blog ID.
   234 	 */
   240 	 */
   235 	do_action( 'remove_user_from_blog', $user_id, $blog_id );
   241 	do_action( 'remove_user_from_blog', $user_id, $blog_id );
   288 
   294 
   289 	return true;
   295 	return true;
   290 }
   296 }
   291 
   297 
   292 /**
   298 /**
   293  * Create an empty blog.
       
   294  *
       
   295  * @since MU 1.0
       
   296  *
       
   297  * @param string $domain The new blog's domain.
       
   298  * @param string $path The new blog's path.
       
   299  * @param string $weblog_title The new blog's title.
       
   300  * @param int $site_id Optional. Defaults to 1.
       
   301  * @return int The ID of the newly created blog
       
   302  */
       
   303 function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) {
       
   304 	if ( empty($path) )
       
   305 		$path = '/';
       
   306 
       
   307 	// Check if the domain has been used already. We should return an error message.
       
   308 	if ( domain_exists($domain, $path, $site_id) )
       
   309 		return __( '<strong>ERROR</strong>: Site URL already taken.' );
       
   310 
       
   311 	// Need to back up wpdb table names, and create a new wp_blogs entry for new blog.
       
   312 	// Need to get blog_id from wp_blogs, and create new table names.
       
   313 	// Must restore table names at the end of function.
       
   314 
       
   315 	if ( ! $blog_id = insert_blog($domain, $path, $site_id) )
       
   316 		return __( '<strong>ERROR</strong>: problem creating site entry.' );
       
   317 
       
   318 	switch_to_blog($blog_id);
       
   319 	install_blog($blog_id);
       
   320 	restore_current_blog();
       
   321 
       
   322 	return $blog_id;
       
   323 }
       
   324 
       
   325 /**
       
   326  * Get the permalink for a post on another blog.
   299  * Get the permalink for a post on another blog.
   327  *
   300  *
   328  * @since MU 1.0
   301  * @since MU (3.0.0) 1.0
   329  *
   302  *
   330  * @param int $blog_id ID of the source blog.
   303  * @param int $blog_id ID of the source blog.
   331  * @param int $post_id ID of the desired post.
   304  * @param int $post_id ID of the desired post.
   332  * @return string The post's permalink
   305  * @return string The post's permalink
   333  */
   306  */
   345  * On a subdirectory installation like example.com/blog1/,
   318  * On a subdirectory installation like example.com/blog1/,
   346  * $domain will be the root 'example.com' and $path the
   319  * $domain will be the root 'example.com' and $path the
   347  * subdirectory '/blog1/'. With subdomains like blog1.example.com,
   320  * subdirectory '/blog1/'. With subdomains like blog1.example.com,
   348  * $domain is 'blog1.example.com' and $path is '/'.
   321  * $domain is 'blog1.example.com' and $path is '/'.
   349  *
   322  *
   350  * @since MU 2.6.5
   323  * @since MU (3.0.0)
       
   324  *
       
   325  * @global wpdb $wpdb WordPress database abstraction object.
   351  *
   326  *
   352  * @param string $domain
   327  * @param string $domain
   353  * @param string $path Optional. Not required for subdomain installations.
   328  * @param string $path   Optional. Not required for subdomain installations.
   354  * @return int 0 if no blog found, otherwise the ID of the matching blog
   329  * @return int 0 if no blog found, otherwise the ID of the matching blog
   355  */
   330  */
   356 function get_blog_id_from_url( $domain, $path = '/' ) {
   331 function get_blog_id_from_url( $domain, $path = '/' ) {
   357 	global $wpdb;
       
   358 
       
   359 	$domain = strtolower( $domain );
   332 	$domain = strtolower( $domain );
   360 	$path = strtolower( $path );
   333 	$path = strtolower( $path );
   361 	$id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' );
   334 	$id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' );
   362 
   335 
   363 	if ( $id == -1 ) // blog does not exist
   336 	if ( $id == -1 ) // blog does not exist
   364 		return 0;
   337 		return 0;
   365 	elseif ( $id )
   338 	elseif ( $id )
   366 		return (int) $id;
   339 		return (int) $id;
   367 
   340 
   368 	$id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s and path = %s /* get_blog_id_from_url */", $domain, $path ) );
   341 	$args = array(
       
   342 		'domain' => $domain,
       
   343 		'path' => $path,
       
   344 		'fields' => 'ids',
       
   345 		'number' => 1,
       
   346 	);
       
   347 	$result = get_sites( $args );
       
   348 	$id = array_shift( $result );
   369 
   349 
   370 	if ( ! $id ) {
   350 	if ( ! $id ) {
   371 		wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' );
   351 		wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' );
   372 		return 0;
   352 		return 0;
   373 	}
   353 	}
   385  * This function checks against the Banned Email Domains list
   365  * This function checks against the Banned Email Domains list
   386  * at wp-admin/network/settings.php. The check is only run on
   366  * at wp-admin/network/settings.php. The check is only run on
   387  * self-registrations; user creation at wp-admin/network/users.php
   367  * self-registrations; user creation at wp-admin/network/users.php
   388  * bypasses this check.
   368  * bypasses this check.
   389  *
   369  *
   390  * @since MU
   370  * @since MU (3.0.0)
   391  *
   371  *
   392  * @param string $user_email The email provided by the user at registration.
   372  * @param string $user_email The email provided by the user at registration.
   393  * @return bool Returns true when the email address is banned.
   373  * @return bool Returns true when the email address is banned.
   394  */
   374  */
   395 function is_email_address_unsafe( $user_email ) {
   375 function is_email_address_unsafe( $user_email ) {
   397 	if ( $banned_names && ! is_array( $banned_names ) )
   377 	if ( $banned_names && ! is_array( $banned_names ) )
   398 		$banned_names = explode( "\n", $banned_names );
   378 		$banned_names = explode( "\n", $banned_names );
   399 
   379 
   400 	$is_email_address_unsafe = false;
   380 	$is_email_address_unsafe = false;
   401 
   381 
   402 	if ( $banned_names && is_array( $banned_names ) ) {
   382 	if ( $banned_names && is_array( $banned_names ) && false !== strpos( $user_email, '@', 1 ) ) {
   403 		$banned_names = array_map( 'strtolower', $banned_names );
   383 		$banned_names = array_map( 'strtolower', $banned_names );
   404 		$normalized_email = strtolower( $user_email );
   384 		$normalized_email = strtolower( $user_email );
   405 
   385 
   406 		list( $email_local_part, $email_domain ) = explode( '@', $normalized_email );
   386 		list( $email_local_part, $email_domain ) = explode( '@', $normalized_email );
   407 
   387 
   421 			}
   401 			}
   422 		}
   402 		}
   423 	}
   403 	}
   424 
   404 
   425 	/**
   405 	/**
   426 	 * Filter whether an email address is unsafe.
   406 	 * Filters whether an email address is unsafe.
   427 	 *
   407 	 *
   428 	 * @since 3.5.0
   408 	 * @since 3.5.0
   429 	 *
   409 	 *
   430 	 * @param bool   $is_email_address_unsafe Whether the email address is "unsafe". Default false.
   410 	 * @param bool   $is_email_address_unsafe Whether the email address is "unsafe". Default false.
   431 	 * @param string $user_email              User email address.
   411 	 * @param string $user_email              User email address.
   443  * process. The value $result, which is passed to the hook, contains both the user-provided
   423  * process. The value $result, which is passed to the hook, contains both the user-provided
   444  * info and the error messages created by the function. {@see 'wpmu_validate_user_signup'}
   424  * info and the error messages created by the function. {@see 'wpmu_validate_user_signup'}
   445  * allows you to process the data in any way you'd like, and unset the relevant errors if
   425  * allows you to process the data in any way you'd like, and unset the relevant errors if
   446  * necessary.
   426  * necessary.
   447  *
   427  *
   448  * @since MU
   428  * @since MU (3.0.0)
       
   429  *
       
   430  * @global wpdb $wpdb WordPress database abstraction object.
   449  *
   431  *
   450  * @param string $user_name  The login name provided by the user.
   432  * @param string $user_name  The login name provided by the user.
   451  * @param string $user_email The email provided by the user.
   433  * @param string $user_email The email provided by the user.
   452  * @return array Contains username, email, and error messages.
   434  * @return array Contains username, email, and error messages.
   453  */
   435  */
   458 
   440 
   459 	$orig_username = $user_name;
   441 	$orig_username = $user_name;
   460 	$user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
   442 	$user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
   461 
   443 
   462 	if ( $user_name != $orig_username || preg_match( '/[^a-z0-9]/', $user_name ) ) {
   444 	if ( $user_name != $orig_username || preg_match( '/[^a-z0-9]/', $user_name ) ) {
   463 		$errors->add( 'user_name', __( 'Only lowercase letters (a-z) and numbers are allowed.' ) );
   445 		$errors->add( 'user_name', __( 'Usernames can only contain lowercase letters (a-z) and numbers.' ) );
   464 		$user_name = $orig_username;
   446 		$user_name = $orig_username;
   465 	}
   447 	}
   466 
   448 
   467 	$user_email = sanitize_email( $user_email );
   449 	$user_email = sanitize_email( $user_email );
   468 
   450 
   469 	if ( empty( $user_name ) )
   451 	if ( empty( $user_name ) )
   470 	   	$errors->add('user_name', __( 'Please enter a username.' ) );
   452 	   	$errors->add('user_name', __( 'Please enter a username.' ) );
   471 
   453 
   472 	$illegal_names = get_site_option( 'illegal_names' );
   454 	$illegal_names = get_site_option( 'illegal_names' );
   473 	if ( is_array( $illegal_names ) == false ) {
   455 	if ( ! is_array( $illegal_names ) ) {
   474 		$illegal_names = array(  'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
   456 		$illegal_names = array(  'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
   475 		add_site_option( 'illegal_names', $illegal_names );
   457 		add_site_option( 'illegal_names', $illegal_names );
   476 	}
   458 	}
   477 	if ( in_array( $user_name, $illegal_names ) == true )
   459 	if ( in_array( $user_name, $illegal_names ) ) {
   478 		$errors->add('user_name',  __( 'That username is not allowed.' ) );
   460 		$errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
   479 
   461 	}
   480 	if ( is_email_address_unsafe( $user_email ) )
   462 
   481 		$errors->add('user_email',  __('You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.'));
   463 	/** This filter is documented in wp-includes/user.php */
       
   464 	$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
       
   465 
       
   466 	if ( in_array( strtolower( $user_name ), array_map( 'strtolower', $illegal_logins ) ) ) {
       
   467 		$errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
       
   468 	}
       
   469 
       
   470 	if ( ! is_email( $user_email ) ) {
       
   471 		$errors->add( 'user_email', __( 'Please enter a valid email address.' ) );
       
   472 	} elseif ( is_email_address_unsafe( $user_email ) ) {
       
   473 		$errors->add( 'user_email', __( 'You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.' ) );
       
   474 	}
   482 
   475 
   483 	if ( strlen( $user_name ) < 4 )
   476 	if ( strlen( $user_name ) < 4 )
   484 		$errors->add('user_name',  __( 'Username must be at least 4 characters.' ) );
   477 		$errors->add('user_name',  __( 'Username must be at least 4 characters.' ) );
   485 
   478 
   486 	if ( strpos( ' ' . $user_name, '_' ) != false )
   479 	if ( strlen( $user_name ) > 60 ) {
   487 		$errors->add( 'user_name', __( 'Sorry, usernames may not contain the character &#8220;_&#8221;!' ) );
   480 		$errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) );
       
   481 	}
   488 
   482 
   489 	// all numeric?
   483 	// all numeric?
   490 	if ( preg_match( '/^[0-9]*$/', $user_name ) )
   484 	if ( preg_match( '/^[0-9]*$/', $user_name ) )
   491 		$errors->add('user_name', __('Sorry, usernames must have letters too!'));
   485 		$errors->add('user_name', __('Sorry, usernames must have letters too!'));
   492 
   486 
   493 	if ( !is_email( $user_email ) )
       
   494 		$errors->add('user_email', __( 'Please enter a valid email address.' ) );
       
   495 
       
   496 	$limited_email_domains = get_site_option( 'limited_email_domains' );
   487 	$limited_email_domains = get_site_option( 'limited_email_domains' );
   497 	if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) {
   488 	if ( is_array( $limited_email_domains ) && ! empty( $limited_email_domains ) ) {
   498 		$emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
   489 		$emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
   499 		if ( in_array( $emaildomain, $limited_email_domains ) == false )
   490 		if ( ! in_array( $emaildomain, $limited_email_domains ) ) {
   500 			$errors->add('user_email', __('Sorry, that email address is not allowed!'));
   491 			$errors->add('user_email', __('Sorry, that email address is not allowed!'));
       
   492 		}
   501 	}
   493 	}
   502 
   494 
   503 	// Check if the username has been used already.
   495 	// Check if the username has been used already.
   504 	if ( username_exists($user_name) )
   496 	if ( username_exists($user_name) )
   505 		$errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
   497 		$errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
   532 	}
   524 	}
   533 
   525 
   534 	$result = array('user_name' => $user_name, 'orig_username' => $orig_username, 'user_email' => $user_email, 'errors' => $errors);
   526 	$result = array('user_name' => $user_name, 'orig_username' => $orig_username, 'user_email' => $user_email, 'errors' => $errors);
   535 
   527 
   536 	/**
   528 	/**
   537 	 * Filter the validated user registration details.
   529 	 * Filters the validated user registration details.
   538 	 *
   530 	 *
   539 	 * This does not allow you to override the username or email of the user during
   531 	 * This does not allow you to override the username or email of the user during
   540 	 * registration. The values are solely used for validation and error handling.
   532 	 * registration. The values are solely used for validation and error handling.
   541 	 *
   533 	 *
   542 	 * @since MU
   534 	 * @since MU (3.0.0)
   543 	 *
   535 	 *
   544 	 * @param array $result {
   536 	 * @param array $result {
   545 	 *     The array of user name, email and the error messages.
   537 	 *     The array of user name, email and the error messages.
   546 	 *
   538 	 *
   547 	 *     @type string   $user_name     Sanitized and unique username.
   539 	 *     @type string   $user_name     Sanitized and unique username.
   562  * This function prevents the current user from registering a new site
   554  * This function prevents the current user from registering a new site
   563  * with a blogname equivalent to another user's login name. Passing the
   555  * with a blogname equivalent to another user's login name. Passing the
   564  * $user parameter to the function, where $user is the other user, is
   556  * $user parameter to the function, where $user is the other user, is
   565  * effectively an override of this limitation.
   557  * effectively an override of this limitation.
   566  *
   558  *
   567  * Filter 'wpmu_validate_blog_signup' if you want to modify
   559  * Filter {@see 'wpmu_validate_blog_signup'} if you want to modify
   568  * the way that WordPress validates new site signups.
   560  * the way that WordPress validates new site signups.
   569  *
   561  *
   570  * @since MU
   562  * @since MU (3.0.0)
   571  *
   563  *
   572  * @param string $blogname The blog name provided by the user. Must be unique.
   564  * @global wpdb   $wpdb
   573  * @param string $blog_title The blog title provided by the user.
   565  * @global string $domain
       
   566  *
       
   567  * @param string         $blogname   The blog name provided by the user. Must be unique.
       
   568  * @param string         $blog_title The blog title provided by the user.
       
   569  * @param WP_User|string $user       Optional. The user object to check against the new site name.
   574  * @return array Contains the new site data and error messages.
   570  * @return array Contains the new site data and error messages.
   575  */
   571  */
   576 function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) {
   572 function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) {
   577 	global $wpdb, $domain;
   573 	global $wpdb, $domain;
   578 
   574 
   579 	$current_site = get_current_site();
   575 	$current_network = get_network();
   580 	$base = $current_site->path;
   576 	$base = $current_network->path;
   581 
   577 
   582 	$blog_title = strip_tags( $blog_title );
   578 	$blog_title = strip_tags( $blog_title );
   583 	$blog_title = substr( $blog_title, 0, 50 );
       
   584 
   579 
   585 	$errors = new WP_Error();
   580 	$errors = new WP_Error();
   586 	$illegal_names = get_site_option( 'illegal_names' );
   581 	$illegal_names = get_site_option( 'illegal_names' );
   587 	if ( $illegal_names == false ) {
   582 	if ( $illegal_names == false ) {
   588 		$illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
   583 		$illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
   589 		add_site_option( 'illegal_names', $illegal_names );
   584 		add_site_option( 'illegal_names', $illegal_names );
   590 	}
   585 	}
   591 
   586 
   592 	/*
   587 	/*
   593 	 * On sub dir installs, some names are so illegal, only a filter can
   588 	 * On sub dir installations, some names are so illegal, only a filter can
   594 	 * spring them from jail.
   589 	 * spring them from jail.
   595 	 */
   590 	 */
   596 	if ( ! is_subdomain_install() ) {
   591 	if ( ! is_subdomain_install() ) {
   597 		$illegal_names = array_merge(
   592 		$illegal_names = array_merge( $illegal_names, get_subdirectory_reserved_names() );
   598 			$illegal_names,
       
   599 			/**
       
   600 			 * Filter reserved site names on a sub-directory Multisite install.
       
   601 			 *
       
   602 			 * @since 3.0.0
       
   603 			 *
       
   604 			 * @param array $subdirectory_reserved_names Array of reserved names.
       
   605 			 */
       
   606 			apply_filters( 'subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' ) )
       
   607 		);
       
   608 	}
   593 	}
   609 
   594 
   610 	if ( empty( $blogname ) )
   595 	if ( empty( $blogname ) )
   611 		$errors->add('blogname', __( 'Please enter a site name.' ) );
   596 		$errors->add('blogname', __( 'Please enter a site name.' ) );
   612 
   597 
   613 	if ( preg_match( '/[^a-z0-9]+/', $blogname ) )
   598 	if ( preg_match( '/[^a-z0-9]+/', $blogname ) ) {
   614 		$errors->add('blogname', __( 'Only lowercase letters (a-z) and numbers are allowed.' ) );
   599 		$errors->add( 'blogname', __( 'Site names can only contain lowercase letters (a-z) and numbers.' ) );
   615 
   600 	}
   616 	if ( in_array( $blogname, $illegal_names ) == true )
   601 
       
   602 	if ( in_array( $blogname, $illegal_names ) )
   617 		$errors->add('blogname',  __( 'That name is not allowed.' ) );
   603 		$errors->add('blogname',  __( 'That name is not allowed.' ) );
   618 
   604 
   619 	if ( strlen( $blogname ) < 4 && !is_super_admin() )
   605 	/**
   620 		$errors->add('blogname',  __( 'Site name must be at least 4 characters.' ) );
   606 	 * Filters the minimum site name length required when validating a site signup.
   621 
   607 	 *
   622 	if ( strpos( $blogname, '_' ) !== false )
   608 	 * @since 4.8.0
   623 		$errors->add( 'blogname', __( 'Sorry, site names may not contain the character &#8220;_&#8221;!' ) );
   609 	 *
       
   610 	 * @param int $length The minimum site name length. Default 4.
       
   611 	 */
       
   612 	$minimum_site_name_length = apply_filters( 'minimum_site_name_length', 4 );
       
   613 
       
   614 	if ( strlen( $blogname ) < $minimum_site_name_length ) {
       
   615 		/* translators: %s: minimum site name length */
       
   616 		$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 ) ) );
       
   617 	}
   624 
   618 
   625 	// do not allow users to create a blog that conflicts with a page on the main blog.
   619 	// do not allow users to create a blog that conflicts with a page on the main blog.
   626 	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 ) ) )
   620 	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 ) ) )
   627 		$errors->add( 'blogname', __( 'Sorry, you may not use that site name.' ) );
   621 		$errors->add( 'blogname', __( 'Sorry, you may not use that site name.' ) );
   628 
   622 
   629 	// all numeric?
   623 	// all numeric?
   630 	if ( preg_match( '/^[0-9]*$/', $blogname ) )
   624 	if ( preg_match( '/^[0-9]*$/', $blogname ) )
   631 		$errors->add('blogname', __('Sorry, site names must have letters too!'));
   625 		$errors->add('blogname', __('Sorry, site names must have letters too!'));
   632 
   626 
   633 	/**
   627 	/**
   634 	 * Filter the new site name during registration.
   628 	 * Filters the new site name during registration.
   635 	 *
   629 	 *
   636 	 * The name is the site's subdomain or the site's subdirectory
   630 	 * The name is the site's subdomain or the site's subdirectory
   637 	 * path depending on the network settings.
   631 	 * path depending on the network settings.
   638 	 *
   632 	 *
   639 	 * @since MU
   633 	 * @since MU (3.0.0)
   640 	 *
   634 	 *
   641 	 * @param string $blogname Site name.
   635 	 * @param string $blogname Site name.
   642 	 */
   636 	 */
   643 	$blogname = apply_filters( 'newblogname', $blogname );
   637 	$blogname = apply_filters( 'newblogname', $blogname );
   644 
   638 
   653 		$path = $base;
   647 		$path = $base;
   654 	} else {
   648 	} else {
   655 		$mydomain = "$domain";
   649 		$mydomain = "$domain";
   656 		$path = $base.$blogname.'/';
   650 		$path = $base.$blogname.'/';
   657 	}
   651 	}
   658 	if ( domain_exists($mydomain, $path, $current_site->id) )
   652 	if ( domain_exists($mydomain, $path, $current_network->id) )
   659 		$errors->add( 'blogname', __( 'Sorry, that site already exists!' ) );
   653 		$errors->add( 'blogname', __( 'Sorry, that site already exists!' ) );
   660 
   654 
   661 	if ( username_exists( $blogname ) ) {
   655 	if ( username_exists( $blogname ) ) {
   662 		if ( is_object( $user ) == false || ( is_object($user) && ( $user->user_login != $blogname ) ) )
   656 		if ( ! is_object( $user ) || ( is_object($user) && ( $user->user_login != $blogname ) ) )
   663 			$errors->add( 'blogname', __( 'Sorry, that site is reserved!' ) );
   657 			$errors->add( 'blogname', __( 'Sorry, that site is reserved!' ) );
   664 	}
   658 	}
   665 
   659 
   666 	// Has someone already signed up for this domain?
   660 	// Has someone already signed up for this domain?
   667 	$signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); // TODO: Check email too?
   661 	$signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); // TODO: Check email too?
   675 	}
   669 	}
   676 
   670 
   677 	$result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
   671 	$result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors);
   678 
   672 
   679 	/**
   673 	/**
   680 	 * Filter site details and error messages following registration.
   674 	 * Filters site details and error messages following registration.
   681 	 *
   675 	 *
   682 	 * @since MU
   676 	 * @since MU (3.0.0)
   683 	 *
   677 	 *
   684 	 * @param array $result {
   678 	 * @param array $result {
   685 	 *     Array of domain, path, blog name, blog title, user and error messages.
   679 	 *     Array of domain, path, blog name, blog title, user and error messages.
   686 	 *
   680 	 *
   687 	 *     @type string   $domain     Domain for the site.
   681 	 *     @type string         $domain     Domain for the site.
   688 	 *     @type string   $path       Path for the site. Used in subdirectory installs.
   682 	 *     @type string         $path       Path for the site. Used in subdirectory installations.
   689 	 *     @type string   $blogname   The unique site name (slug).
   683 	 *     @type string         $blogname   The unique site name (slug).
   690 	 *     @type string   $blog_title Blog title.
   684 	 *     @type string         $blog_title Blog title.
   691 	 *     @type string   $user       User email address.
   685 	 *     @type string|WP_User $user       By default, an empty string. A user object if provided.
   692 	 *     @type WP_Error $errors     WP_Error containing any errors found.
   686 	 *     @type WP_Error       $errors     WP_Error containing any errors found.
   693 	 * }
   687 	 * }
   694 	 */
   688 	 */
   695 	return apply_filters( 'wpmu_validate_blog_signup', $result );
   689 	return apply_filters( 'wpmu_validate_blog_signup', $result );
   696 }
   690 }
   697 
   691 
   698 /**
   692 /**
   699  * Record site signup information for future activation.
   693  * Record site signup information for future activation.
   700  *
   694  *
   701  * @since MU
   695  * @since MU (3.0.0)
   702  *
   696  *
   703  * @param string $domain The requested domain.
   697  * @global wpdb $wpdb WordPress database abstraction object.
   704  * @param string $path The requested path.
   698  *
   705  * @param string $title The requested site title.
   699  * @param string $domain     The requested domain.
   706  * @param string $user The user's requested login name.
   700  * @param string $path       The requested path.
       
   701  * @param string $title      The requested site title.
       
   702  * @param string $user       The user's requested login name.
   707  * @param string $user_email The user's email address.
   703  * @param string $user_email The user's email address.
   708  * @param array $meta By default, contains the requested privacy setting and lang_id.
   704  * @param array  $meta       Optional. Signup meta data. By default, contains the requested privacy setting and lang_id.
   709  */
   705  */
   710 function wpmu_signup_blog( $domain, $path, $title, $user, $user_email, $meta = array() )  {
   706 function wpmu_signup_blog( $domain, $path, $title, $user, $user_email, $meta = array() )  {
   711 	global $wpdb;
   707 	global $wpdb;
   712 
   708 
   713 	$key = substr( md5( time() . rand() . $domain ), 0, 16 );
   709 	$key = substr( md5( time() . wp_rand() . $domain ), 0, 16 );
   714 	$meta = serialize($meta);
   710 
       
   711 	/**
       
   712 	 * Filters the metadata for a site signup.
       
   713 	 *
       
   714 	 * The metadata will be serialized prior to storing it in the database.
       
   715 	 *
       
   716 	 * @since 4.8.0
       
   717 	 *
       
   718 	 * @param array  $meta       Signup meta data. Default empty array.
       
   719 	 * @param string $domain     The requested domain.
       
   720 	 * @param string $path       The requested path.
       
   721 	 * @param string $title      The requested site title.
       
   722 	 * @param string $user       The user's requested login name.
       
   723 	 * @param string $user_email The user's email address.
       
   724 	 * @param string $key        The user's activation key.
       
   725 	 */
       
   726 	$meta = apply_filters( 'signup_site_meta', $meta, $domain, $path, $title, $user, $user_email, $key );
   715 
   727 
   716 	$wpdb->insert( $wpdb->signups, array(
   728 	$wpdb->insert( $wpdb->signups, array(
   717 		'domain' => $domain,
   729 		'domain' => $domain,
   718 		'path' => $path,
   730 		'path' => $path,
   719 		'title' => $title,
   731 		'title' => $title,
   720 		'user_login' => $user,
   732 		'user_login' => $user,
   721 		'user_email' => $user_email,
   733 		'user_email' => $user_email,
   722 		'registered' => current_time('mysql', true),
   734 		'registered' => current_time('mysql', true),
   723 		'activation_key' => $key,
   735 		'activation_key' => $key,
   724 		'meta' => $meta
   736 		'meta' => serialize( $meta )
   725 	) );
   737 	) );
   726 
   738 
   727 	wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta);
   739 	/**
       
   740 	 * Fires after site signup information has been written to the database.
       
   741 	 *
       
   742 	 * @since 4.4.0
       
   743 	 *
       
   744 	 * @param string $domain     The requested domain.
       
   745 	 * @param string $path       The requested path.
       
   746 	 * @param string $title      The requested site title.
       
   747 	 * @param string $user       The user's requested login name.
       
   748 	 * @param string $user_email The user's email address.
       
   749 	 * @param string $key        The user's activation key.
       
   750 	 * @param array  $meta       Signup meta data. By default, contains the requested privacy setting and lang_id.
       
   751 	 */
       
   752 	do_action( 'after_signup_site', $domain, $path, $title, $user, $user_email, $key, $meta );
   728 }
   753 }
   729 
   754 
   730 /**
   755 /**
   731  * Record user signup information for future activation.
   756  * Record user signup information for future activation.
   732  *
   757  *
   733  * This function is used when user registration is open but
   758  * This function is used when user registration is open but
   734  * new site registration is not.
   759  * new site registration is not.
   735  *
   760  *
   736  * @since MU
   761  * @since MU (3.0.0)
   737  *
   762  *
   738  * @param string $user The user's requested login name.
   763  * @global wpdb $wpdb WordPress database abstraction object.
       
   764  *
       
   765  * @param string $user       The user's requested login name.
   739  * @param string $user_email The user's email address.
   766  * @param string $user_email The user's email address.
   740  * @param array $meta By default, this is an empty array.
   767  * @param array  $meta       Optional. Signup meta data. Default empty array.
   741  */
   768  */
   742 function wpmu_signup_user( $user, $user_email, $meta = array() ) {
   769 function wpmu_signup_user( $user, $user_email, $meta = array() ) {
   743 	global $wpdb;
   770 	global $wpdb;
   744 
   771 
   745 	// Format data
   772 	// Format data
   746 	$user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) );
   773 	$user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) );
   747 	$user_email = sanitize_email( $user_email );
   774 	$user_email = sanitize_email( $user_email );
   748 	$key = substr( md5( time() . rand() . $user_email ), 0, 16 );
   775 	$key = substr( md5( time() . wp_rand() . $user_email ), 0, 16 );
   749 	$meta = serialize($meta);
   776 
       
   777 	/**
       
   778 	 * Filters the metadata for a user signup.
       
   779 	 *
       
   780 	 * The metadata will be serialized prior to storing it in the database.
       
   781 	 *
       
   782 	 * @since 4.8.0
       
   783 	 *
       
   784 	 * @param array  $meta       Signup meta data. Default empty array.
       
   785 	 * @param string $user       The user's requested login name.
       
   786 	 * @param string $user_email The user's email address.
       
   787 	 * @param string $key        The user's activation key.
       
   788 	 */
       
   789 	$meta = apply_filters( 'signup_user_meta', $meta, $user, $user_email, $key );
   750 
   790 
   751 	$wpdb->insert( $wpdb->signups, array(
   791 	$wpdb->insert( $wpdb->signups, array(
   752 		'domain' => '',
   792 		'domain' => '',
   753 		'path' => '',
   793 		'path' => '',
   754 		'title' => '',
   794 		'title' => '',
   755 		'user_login' => $user,
   795 		'user_login' => $user,
   756 		'user_email' => $user_email,
   796 		'user_email' => $user_email,
   757 		'registered' => current_time('mysql', true),
   797 		'registered' => current_time('mysql', true),
   758 		'activation_key' => $key,
   798 		'activation_key' => $key,
   759 		'meta' => $meta
   799 		'meta' => serialize( $meta )
   760 	) );
   800 	) );
   761 
   801 
   762 	wpmu_signup_user_notification($user, $user_email, $key, $meta);
   802 	/**
   763 }
   803 	 * Fires after a user's signup information has been written to the database.
   764 
   804 	 *
   765 /**
   805 	 * @since 4.4.0
   766  * Notify user of signup success.
   806 	 *
       
   807 	 * @param string $user       The user's requested login name.
       
   808 	 * @param string $user_email The user's email address.
       
   809 	 * @param string $key        The user's activation key.
       
   810 	 * @param array  $meta       Signup meta data. Default empty array.
       
   811 	 */
       
   812 	do_action( 'after_signup_user', $user, $user_email, $key, $meta );
       
   813 }
       
   814 
       
   815 /**
       
   816  * Send a confirmation request email to a user when they sign up for a new site. The new site will not become active
       
   817  * until the confirmation link is clicked.
   767  *
   818  *
   768  * This is the notification function used when site registration
   819  * This is the notification function used when site registration
   769  * is enabled.
   820  * is enabled.
   770  *
   821  *
   771  * Filter 'wpmu_signup_blog_notification' to bypass this function or
   822  * Filter {@see 'wpmu_signup_blog_notification'} to bypass this function or
   772  * replace it with your own notification behavior.
   823  * replace it with your own notification behavior.
   773  *
   824  *
   774  * Filter 'wpmu_signup_blog_notification_email' and
   825  * Filter {@see 'wpmu_signup_blog_notification_email'} and
   775  * 'wpmu_signup_blog_notification_subject' to change the content
   826  * {@see 'wpmu_signup_blog_notification_subject'} to change the content
   776  * and subject line of the email sent to newly registered users.
   827  * and subject line of the email sent to newly registered users.
   777  *
   828  *
   778  * @since MU
   829  * @since MU (3.0.0)
   779  *
   830  *
   780  * @param string $domain The new blog domain.
   831  * @param string $domain     The new blog domain.
   781  * @param string $path The new blog path.
   832  * @param string $path       The new blog path.
   782  * @param string $title The site title.
   833  * @param string $title      The site title.
   783  * @param string $user The user's login name.
   834  * @param string $user_login The user's login name.
   784  * @param string $user_email The user's email address.
   835  * @param string $user_email The user's email address.
   785  * @param string $key The activation key created in wpmu_signup_blog()
   836  * @param string $key        The activation key created in wpmu_signup_blog()
   786  * @param array $meta By default, contains the requested privacy setting and lang_id.
   837  * @param array  $meta       Optional. Signup meta data. By default, contains the requested privacy setting and lang_id.
   787  * @return bool
   838  * @return bool
   788  */
   839  */
   789 function wpmu_signup_blog_notification( $domain, $path, $title, $user, $user_email, $key, $meta = array() ) {
   840 function wpmu_signup_blog_notification( $domain, $path, $title, $user_login, $user_email, $key, $meta = array() ) {
   790 	/**
   841 	/**
   791 	 * Filter whether to bypass the new site email notification.
   842 	 * Filters whether to bypass the new site email notification.
   792 	 *
   843 	 *
   793 	 * @since MU
   844 	 * @since MU (3.0.0)
   794 	 *
   845 	 *
   795 	 * @param string|bool $domain     Site domain.
   846 	 * @param string|bool $domain     Site domain.
   796 	 * @param string      $path       Site path.
   847 	 * @param string      $path       Site path.
   797 	 * @param string      $title      Site title.
   848 	 * @param string      $title      Site title.
   798 	 * @param string      $user       User login name.
   849 	 * @param string      $user_login User login name.
   799 	 * @param string      $user_email User email address.
   850 	 * @param string      $user_email User email address.
   800 	 * @param string      $key        Activation key created in wpmu_signup_blog().
   851 	 * @param string      $key        Activation key created in wpmu_signup_blog().
   801 	 * @param array       $meta       By default, contains the requested privacy setting and lang_id.
   852 	 * @param array       $meta       Signup meta data. By default, contains the requested privacy setting and lang_id.
   802 	 */
   853 	 */
   803 	if ( ! apply_filters( 'wpmu_signup_blog_notification', $domain, $path, $title, $user, $user_email, $key, $meta ) ) {
   854 	if ( ! apply_filters( 'wpmu_signup_blog_notification', $domain, $path, $title, $user_login, $user_email, $key, $meta ) ) {
   804 		return false;
   855 		return false;
   805 	}
   856 	}
   806 
   857 
   807 	// Send email with activation link.
   858 	// Send email with activation link.
   808 	if ( !is_subdomain_install() || get_current_site()->id != 1 )
   859 	if ( !is_subdomain_install() || get_current_network_id() != 1 )
   809 		$activate_url = network_site_url("wp-activate.php?key=$key");
   860 		$activate_url = network_site_url("wp-activate.php?key=$key");
   810 	else
   861 	else
   811 		$activate_url = "http://{$domain}{$path}wp-activate.php?key=$key"; // @todo use *_url() API
   862 		$activate_url = "http://{$domain}{$path}wp-activate.php?key=$key"; // @todo use *_url() API
   812 
   863 
   813 	$activate_url = esc_url($activate_url);
   864 	$activate_url = esc_url($activate_url);
   814 	$admin_email = get_site_option( 'admin_email' );
   865 	$admin_email = get_site_option( 'admin_email' );
   815 	if ( $admin_email == '' )
   866 	if ( $admin_email == '' )
   816 		$admin_email = 'support@' . $_SERVER['SERVER_NAME'];
   867 		$admin_email = 'support@' . $_SERVER['SERVER_NAME'];
   817 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
   868 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
   818 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
   869 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
       
   870 
       
   871 	$user = get_user_by( 'login', $user_login );
       
   872 	$switched_locale = switch_to_locale( get_user_locale( $user ) );
       
   873 
   819 	$message = sprintf(
   874 	$message = sprintf(
   820 		/**
   875 		/**
   821 		 * Filter the message content of the new blog notification email.
   876 		 * Filters the message content of the new blog notification email.
   822 		 *
   877 		 *
   823 		 * Content should be formatted for transmission via wp_mail().
   878 		 * Content should be formatted for transmission via wp_mail().
   824 		 *
   879 		 *
   825 		 * @since MU
   880 		 * @since MU (3.0.0)
   826 		 *
   881 		 *
   827 		 * @param string $content    Content of the notification email.
   882 		 * @param string $content    Content of the notification email.
   828 		 * @param string $domain     Site domain.
   883 		 * @param string $domain     Site domain.
   829 		 * @param string $path       Site path.
   884 		 * @param string $path       Site path.
   830 		 * @param string $title      Site title.
   885 		 * @param string $title      Site title.
   831 		 * @param string $user       User login name.
   886 		 * @param string $user_login User login name.
   832 		 * @param string $user_email User email address.
   887 		 * @param string $user_email User email address.
   833 		 * @param string $key        Activation key created in wpmu_signup_blog().
   888 		 * @param string $key        Activation key created in wpmu_signup_blog().
   834 		 * @param array  $meta       By default, contains the requested privacy setting and lang_id.
   889 		 * @param array  $meta       Signup meta data. By default, contains the requested privacy setting and lang_id.
   835 		 */
   890 		 */
   836 		apply_filters( 'wpmu_signup_blog_notification_email',
   891 		apply_filters( 'wpmu_signup_blog_notification_email',
   837 			__( "To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your site here:\n\n%s" ),
   892 			__( "To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your site here:\n\n%s" ),
   838 			$domain, $path, $title, $user, $user_email, $key, $meta
   893 			$domain, $path, $title, $user_login, $user_email, $key, $meta
   839 		),
   894 		),
   840 		$activate_url,
   895 		$activate_url,
   841 		esc_url( "http://{$domain}{$path}" ),
   896 		esc_url( "http://{$domain}{$path}" ),
   842 		$key
   897 		$key
   843 	);
   898 	);
   844 	// TODO: Don't hard code activation link.
   899 	// TODO: Don't hard code activation link.
   845 	$subject = sprintf(
   900 	$subject = sprintf(
   846 		/**
   901 		/**
   847 		 * Filter the subject of the new blog notification email.
   902 		 * Filters the subject of the new blog notification email.
   848 		 *
   903 		 *
   849 		 * @since MU
   904 		 * @since MU (3.0.0)
   850 		 *
   905 		 *
   851 		 * @param string $subject    Subject of the notification email.
   906 		 * @param string $subject    Subject of the notification email.
   852 		 * @param string $domain     Site domain.
   907 		 * @param string $domain     Site domain.
   853 		 * @param string $path       Site path.
   908 		 * @param string $path       Site path.
   854 		 * @param string $title      Site title.
   909 		 * @param string $title      Site title.
   855 		 * @param string $user       User login name.
   910 		 * @param string $user_login User login name.
   856 		 * @param string $user_email User email address.
   911 		 * @param string $user_email User email address.
   857 		 * @param string $key        Activation key created in wpmu_signup_blog().
   912 		 * @param string $key        Activation key created in wpmu_signup_blog().
   858 		 * @param array  $meta       By default, contains the requested privacy setting and lang_id.
   913 		 * @param array  $meta       Signup meta data. By default, contains the requested privacy setting and lang_id.
   859 		 */
   914 		 */
   860 		apply_filters( 'wpmu_signup_blog_notification_subject',
   915 		apply_filters( 'wpmu_signup_blog_notification_subject',
   861 			__( '[%1$s] Activate %2$s' ),
   916 			/* translators: New site notification email subject. 1: Network name, 2: New site URL */
   862 			$domain, $path, $title, $user, $user_email, $key, $meta
   917 			_x( '[%1$s] Activate %2$s', 'New site notification email subject' ),
       
   918 			$domain, $path, $title, $user_login, $user_email, $key, $meta
   863 		),
   919 		),
   864 		$from_name,
   920 		$from_name,
   865 		esc_url( 'http://' . $domain . $path )
   921 		esc_url( 'http://' . $domain . $path )
   866 	);
   922 	);
   867 	wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
   923 	wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
       
   924 
       
   925 	if ( $switched_locale ) {
       
   926 		restore_previous_locale();
       
   927 	}
       
   928 
   868 	return true;
   929 	return true;
   869 }
   930 }
   870 
   931 
   871 /**
   932 /**
   872  * Notify user of signup success.
   933  * Send a confirmation request email to a user when they sign up for a new user account (without signing up for a site
       
   934  * at the same time). The user account will not become active until the confirmation link is clicked.
   873  *
   935  *
   874  * This is the notification function used when no new site has
   936  * This is the notification function used when no new site has
   875  * been requested.
   937  * been requested.
   876  *
   938  *
   877  * Filter 'wpmu_signup_user_notification' to bypass this function or
   939  * Filter {@see 'wpmu_signup_user_notification'} to bypass this function or
   878  * replace it with your own notification behavior.
   940  * replace it with your own notification behavior.
   879  *
   941  *
   880  * Filter 'wpmu_signup_user_notification_email' and
   942  * Filter {@see 'wpmu_signup_user_notification_email'} and
   881  * 'wpmu_signup_user_notification_subject' to change the content
   943  * {@see 'wpmu_signup_user_notification_subject'} to change the content
   882  * and subject line of the email sent to newly registered users.
   944  * and subject line of the email sent to newly registered users.
   883  *
   945  *
   884  * @since MU
   946  * @since MU (3.0.0)
   885  *
   947  *
   886  * @param string $user The user's login name.
   948  * @param string $user_login The user's login name.
   887  * @param string $user_email The user's email address.
   949  * @param string $user_email The user's email address.
   888  * @param string $key The activation key created in wpmu_signup_user()
   950  * @param string $key        The activation key created in wpmu_signup_user()
   889  * @param array $meta By default, an empty array.
   951  * @param array  $meta       Optional. Signup meta data. Default empty array.
   890  * @return bool
   952  * @return bool
   891  */
   953  */
   892 function wpmu_signup_user_notification( $user, $user_email, $key, $meta = array() ) {
   954 function wpmu_signup_user_notification( $user_login, $user_email, $key, $meta = array() ) {
   893 	/**
   955 	/**
   894 	 * Filter whether to bypass the email notification for new user sign-up.
   956 	 * Filters whether to bypass the email notification for new user sign-up.
   895 	 *
   957 	 *
   896 	 * @since MU
   958 	 * @since MU (3.0.0)
   897 	 *
   959 	 *
   898 	 * @param string $user       User login name.
   960 	 * @param string $user_login User login name.
   899 	 * @param string $user_email User email address.
   961 	 * @param string $user_email User email address.
   900 	 * @param string $key        Activation key created in wpmu_signup_user().
   962 	 * @param string $key        Activation key created in wpmu_signup_user().
   901 	 * @param array  $meta       Signup meta data.
   963 	 * @param array  $meta       Signup meta data. Default empty array.
   902 	 */
   964 	 */
   903 	if ( ! apply_filters( 'wpmu_signup_user_notification', $user, $user_email, $key, $meta ) )
   965 	if ( ! apply_filters( 'wpmu_signup_user_notification', $user_login, $user_email, $key, $meta ) )
   904 		return false;
   966 		return false;
       
   967 
       
   968 	$user = get_user_by( 'login', $user_login );
       
   969 	$switched_locale = switch_to_locale( get_user_locale( $user ) );
   905 
   970 
   906 	// Send email with activation link.
   971 	// Send email with activation link.
   907 	$admin_email = get_site_option( 'admin_email' );
   972 	$admin_email = get_site_option( 'admin_email' );
   908 	if ( $admin_email == '' )
   973 	if ( $admin_email == '' )
   909 		$admin_email = 'support@' . $_SERVER['SERVER_NAME'];
   974 		$admin_email = 'support@' . $_SERVER['SERVER_NAME'];
   910 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
   975 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
   911 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
   976 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
   912 	$message = sprintf(
   977 	$message = sprintf(
   913 		/**
   978 		/**
   914 		 * Filter the content of the notification email for new user sign-up.
   979 		 * Filters the content of the notification email for new user sign-up.
   915 		 *
   980 		 *
   916 		 * Content should be formatted for transmission via wp_mail().
   981 		 * Content should be formatted for transmission via wp_mail().
   917 		 *
   982 		 *
   918 		 * @since MU
   983 		 * @since MU (3.0.0)
   919 		 *
   984 		 *
   920 		 * @param string $content    Content of the notification email.
   985 		 * @param string $content    Content of the notification email.
   921 		 * @param string $user       User login name.
   986 		 * @param string $user_login User login name.
   922 		 * @param string $user_email User email address.
   987 		 * @param string $user_email User email address.
   923 		 * @param string $key        Activation key created in wpmu_signup_user().
   988 		 * @param string $key        Activation key created in wpmu_signup_user().
   924 		 * @param array  $meta       Signup meta data.
   989 		 * @param array  $meta       Signup meta data. Default empty array.
   925 		 */
   990 		 */
   926 		apply_filters( 'wpmu_signup_user_notification_email',
   991 		apply_filters( 'wpmu_signup_user_notification_email',
   927 			__( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login." ),
   992 			__( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login." ),
   928 			$user, $user_email, $key, $meta
   993 			$user_login, $user_email, $key, $meta
   929 		),
   994 		),
   930 		site_url( "wp-activate.php?key=$key" )
   995 		site_url( "wp-activate.php?key=$key" )
   931 	);
   996 	);
   932 	// TODO: Don't hard code activation link.
   997 	// TODO: Don't hard code activation link.
   933 	$subject = sprintf(
   998 	$subject = sprintf(
   934 		/**
   999 		/**
   935 		 * Filter the subject of the notification email of new user signup.
  1000 		 * Filters the subject of the notification email of new user signup.
   936 		 *
  1001 		 *
   937 		 * @since MU
  1002 		 * @since MU (3.0.0)
   938 		 *
  1003 		 *
   939 		 * @param string $subject    Subject of the notification email.
  1004 		 * @param string $subject    Subject of the notification email.
   940 		 * @param string $user       User login name.
  1005 		 * @param string $user_login User login name.
   941 		 * @param string $user_email User email address.
  1006 		 * @param string $user_email User email address.
   942 		 * @param string $key        Activation key created in wpmu_signup_user().
  1007 		 * @param string $key        Activation key created in wpmu_signup_user().
   943 		 * @param array  $meta       Signup meta data.
  1008 		 * @param array  $meta       Signup meta data. Default empty array.
   944 		 */
  1009 		 */
   945 		apply_filters( 'wpmu_signup_user_notification_subject',
  1010 		apply_filters( 'wpmu_signup_user_notification_subject',
   946 			__( '[%1$s] Activate %2$s' ),
  1011 			/* translators: New user notification email subject. 1: Network name, 2: New user login */
   947 			$user, $user_email, $key, $meta
  1012 			_x( '[%1$s] Activate %2$s', 'New user notification email subject' ),
       
  1013 			$user_login, $user_email, $key, $meta
   948 		),
  1014 		),
   949 		$from_name,
  1015 		$from_name,
   950 		$user
  1016 		$user_login
   951 	);
  1017 	);
   952 	wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
  1018 	wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
       
  1019 
       
  1020 	if ( $switched_locale ) {
       
  1021 		restore_previous_locale();
       
  1022 	}
       
  1023 
   953 	return true;
  1024 	return true;
   954 }
  1025 }
   955 
  1026 
   956 /**
  1027 /**
   957  * Activate a signup.
  1028  * Activate a signup.
   958  *
  1029  *
   959  * Hook to 'wpmu_activate_user' or 'wpmu_activate_blog' for events
  1030  * Hook to {@see 'wpmu_activate_user'} or {@see 'wpmu_activate_blog'} for events
   960  * that should happen only when users or sites are self-created (since
  1031  * that should happen only when users or sites are self-created (since
   961  * those actions are not called when users and sites are created
  1032  * those actions are not called when users and sites are created
   962  * by a Super Admin).
  1033  * by a Super Admin).
   963  *
  1034  *
   964  * @since MU
  1035  * @since MU (3.0.0)
       
  1036  *
       
  1037  * @global wpdb $wpdb WordPress database abstraction object.
   965  *
  1038  *
   966  * @param string $key The activation key provided to the user.
  1039  * @param string $key The activation key provided to the user.
   967  * @return array An array containing information about the activated user and/or blog
  1040  * @return array|WP_Error An array containing information about the activated user and/or blog
   968  */
  1041  */
   969 function wpmu_activate_signup($key) {
  1042 function wpmu_activate_signup($key) {
   970 	global $wpdb;
  1043 	global $wpdb;
   971 
  1044 
   972 	$signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) );
  1045 	$signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) );
  1000 		$wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
  1073 		$wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
  1001 
  1074 
  1002 		if ( isset( $user_already_exists ) )
  1075 		if ( isset( $user_already_exists ) )
  1003 			return new WP_Error( 'user_already_exists', __( 'That username is already activated.' ), $signup);
  1076 			return new WP_Error( 'user_already_exists', __( 'That username is already activated.' ), $signup);
  1004 
  1077 
  1005 		wpmu_welcome_user_notification( $user_id, $password, $meta );
       
  1006 		/**
  1078 		/**
  1007 		 * Fires immediately after a new user is activated.
  1079 		 * Fires immediately after a new user is activated.
  1008 		 *
  1080 		 *
  1009 		 * @since MU
  1081 		 * @since MU (3.0.0)
  1010 		 *
  1082 		 *
  1011 		 * @param int   $user_id  User ID.
  1083 		 * @param int   $user_id  User ID.
  1012 		 * @param int   $password User password.
  1084 		 * @param int   $password User password.
  1013 		 * @param array $meta     Signup meta data.
  1085 		 * @param array $meta     Signup meta data.
  1014 		 */
  1086 		 */
  1015 		do_action( 'wpmu_activate_user', $user_id, $password, $meta );
  1087 		do_action( 'wpmu_activate_user', $user_id, $password, $meta );
  1016 		return array( 'user_id' => $user_id, 'password' => $password, 'meta' => $meta );
  1088 		return array( 'user_id' => $user_id, 'password' => $password, 'meta' => $meta );
  1017 	}
  1089 	}
  1018 
  1090 
  1019 	$blog_id = wpmu_create_blog( $signup->domain, $signup->path, $signup->title, $user_id, $meta, $wpdb->siteid );
  1091 	$blog_id = wpmu_create_blog( $signup->domain, $signup->path, $signup->title, $user_id, $meta, get_current_network_id() );
  1020 
  1092 
  1021 	// TODO: What to do if we create a user but cannot create a blog?
  1093 	// TODO: What to do if we create a user but cannot create a blog?
  1022 	if ( is_wp_error($blog_id) ) {
  1094 	if ( is_wp_error($blog_id) ) {
  1023 		// If blog is taken, that means a previous attempt to activate this blog failed in between creating the blog and
  1095 		// If blog is taken, that means a previous attempt to activate this blog failed in between creating the blog and
  1024 		// setting the activation flag. Let's just set the active flag and instruct the user to reset their password.
  1096 		// setting the activation flag. Let's just set the active flag and instruct the user to reset their password.
  1028 		}
  1100 		}
  1029 		return $blog_id;
  1101 		return $blog_id;
  1030 	}
  1102 	}
  1031 
  1103 
  1032 	$wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
  1104 	$wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
  1033 	wpmu_welcome_notification($blog_id, $user_id, $password, $signup->title, $meta);
       
  1034 	/**
  1105 	/**
  1035 	 * Fires immediately after a site is activated.
  1106 	 * Fires immediately after a site is activated.
  1036 	 *
  1107 	 *
  1037 	 * @since MU
  1108 	 * @since MU (3.0.0)
  1038 	 *
  1109 	 *
  1039 	 * @param int    $blog_id       Blog ID.
  1110 	 * @param int    $blog_id       Blog ID.
  1040 	 * @param int    $user_id       User ID.
  1111 	 * @param int    $user_id       User ID.
  1041 	 * @param int    $password      User password.
  1112 	 * @param int    $password      User password.
  1042 	 * @param string $signup_title  Site title.
  1113 	 * @param string $signup_title  Site title.
  1043 	 * @param array  $meta          Signup meta data.
  1114 	 * @param array  $meta          Signup meta data. By default, contains the requested privacy setting and lang_id.
  1044 	 */
  1115 	 */
  1045 	do_action( 'wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta );
  1116 	do_action( 'wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta );
  1046 
  1117 
  1047 	return array('blog_id' => $blog_id, 'user_id' => $user_id, 'password' => $password, 'title' => $signup->title, 'meta' => $meta);
  1118 	return array('blog_id' => $blog_id, 'user_id' => $user_id, 'password' => $password, 'title' => $signup->title, 'meta' => $meta);
  1048 }
  1119 }
  1049 
  1120 
  1050 /**
  1121 /**
  1051  * Create a user.
  1122  * Create a user.
  1052  *
  1123  *
  1053  * This function runs when a user self-registers as well as when
  1124  * This function runs when a user self-registers as well as when
  1054  * a Super Admin creates a new user. Hook to 'wpmu_new_user' for events
  1125  * a Super Admin creates a new user. Hook to {@see 'wpmu_new_user'} for events
  1055  * that should affect all new users, but only on Multisite (otherwise
  1126  * that should affect all new users, but only on Multisite (otherwise
  1056  * use 'user_register').
  1127  * use {@see'user_register'}).
  1057  *
  1128  *
  1058  * @since MU
  1129  * @since MU (3.0.0)
  1059  *
  1130  *
  1060  * @param string $user_name The new user's login name.
  1131  * @param string $user_name The new user's login name.
  1061  * @param string $password The new user's password.
  1132  * @param string $password  The new user's password.
  1062  * @param string $email The new user's email address.
  1133  * @param string $email     The new user's email address.
  1063  * @return int|bool Returns false on failure, or int $user_id on success
  1134  * @return int|false Returns false on failure, or int $user_id on success
  1064  */
  1135  */
  1065 function wpmu_create_user( $user_name, $password, $email ) {
  1136 function wpmu_create_user( $user_name, $password, $email ) {
  1066 	$user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
  1137 	$user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
  1067 
  1138 
  1068 	$user_id = wp_create_user( $user_name, $password, $email );
  1139 	$user_id = wp_create_user( $user_name, $password, $email );
  1074 	delete_user_option( $user_id, 'user_level' );
  1145 	delete_user_option( $user_id, 'user_level' );
  1075 
  1146 
  1076 	/**
  1147 	/**
  1077 	 * Fires immediately after a new user is created.
  1148 	 * Fires immediately after a new user is created.
  1078 	 *
  1149 	 *
  1079 	 * @since MU
  1150 	 * @since MU (3.0.0)
  1080 	 *
  1151 	 *
  1081 	 * @param int $user_id User ID.
  1152 	 * @param int $user_id User ID.
  1082 	 */
  1153 	 */
  1083 	do_action( 'wpmu_new_user', $user_id );
  1154 	do_action( 'wpmu_new_user', $user_id );
  1084 
  1155 
  1087 
  1158 
  1088 /**
  1159 /**
  1089  * Create a site.
  1160  * Create a site.
  1090  *
  1161  *
  1091  * This function runs when a user self-registers a new site as well
  1162  * This function runs when a user self-registers a new site as well
  1092  * as when a Super Admin creates a new site. Hook to 'wpmu_new_blog'
  1163  * as when a Super Admin creates a new site. Hook to {@see 'wpmu_new_blog'}
  1093  * for events that should affect all new sites.
  1164  * for events that should affect all new sites.
  1094  *
  1165  *
  1095  * On subdirectory installs, $domain is the same as the main site's
  1166  * On subdirectory installations, $domain is the same as the main site's
  1096  * domain, and the path is the subdirectory name (eg 'example.com'
  1167  * domain, and the path is the subdirectory name (eg 'example.com'
  1097  * and '/blog1/'). On subdomain installs, $domain is the new subdomain +
  1168  * and '/blog1/'). On subdomain installations, $domain is the new subdomain +
  1098  * root domain (eg 'blog1.example.com'), and $path is '/'.
  1169  * root domain (eg 'blog1.example.com'), and $path is '/'.
  1099  *
  1170  *
  1100  * @since MU
  1171  * @since MU (3.0.0)
  1101  *
  1172  *
  1102  * @param string $domain The new site's domain.
  1173  * @param string $domain     The new site's domain.
  1103  * @param string $path The new site's path.
  1174  * @param string $path       The new site's path.
  1104  * @param string $title The new site's title.
  1175  * @param string $title      The new site's title.
  1105  * @param int $user_id The user ID of the new site's admin.
  1176  * @param int    $user_id    The user ID of the new site's admin.
  1106  * @param array $meta Optional. Used to set initial site options.
  1177  * @param array  $meta       Optional. Array of key=>value pairs used to set initial site options.
  1107  * @param int $site_id Optional. Only relevant on multi-network installs.
  1178  *                           If valid status keys are included ('public', 'archived', 'mature',
  1108  * @return mixed Returns WP_Error object on failure, int $blog_id on success
  1179  *                           'spam', 'deleted', or 'lang_id') the given site status(es) will be
  1109  */
  1180  *                           updated. Otherwise, keys and values will be used to set options for
  1110 function wpmu_create_blog( $domain, $path, $title, $user_id, $meta = array(), $site_id = 1 ) {
  1181  *                           the new site. Default empty array.
  1111 	$defaults = array( 'public' => 0 );
  1182  * @param int    $network_id Optional. Network ID. Only relevant on multi-network installations.
       
  1183  * @return int|WP_Error Returns WP_Error object on failure, the new site ID on success.
       
  1184  */
       
  1185 function wpmu_create_blog( $domain, $path, $title, $user_id, $meta = array(), $network_id = 1 ) {
       
  1186 	$defaults = array(
       
  1187 		'public' => 0,
       
  1188 		'WPLANG' => get_network_option( $network_id, 'WPLANG' ),
       
  1189 	);
  1112 	$meta = wp_parse_args( $meta, $defaults );
  1190 	$meta = wp_parse_args( $meta, $defaults );
  1113 
  1191 
  1114 	$domain = preg_replace( '/\s+/', '', sanitize_user( $domain, true ) );
  1192 	$domain = preg_replace( '/\s+/', '', sanitize_user( $domain, true ) );
  1115 
  1193 
  1116 	if ( is_subdomain_install() )
  1194 	if ( is_subdomain_install() )
  1121 
  1199 
  1122 	if ( empty($path) )
  1200 	if ( empty($path) )
  1123 		$path = '/';
  1201 		$path = '/';
  1124 
  1202 
  1125 	// Check if the domain has been used already. We should return an error message.
  1203 	// Check if the domain has been used already. We should return an error message.
  1126 	if ( domain_exists($domain, $path, $site_id) )
  1204 	if ( domain_exists($domain, $path, $network_id) )
  1127 		return new WP_Error( 'blog_taken', __( 'Sorry, that site already exists!' ) );
  1205 		return new WP_Error( 'blog_taken', __( 'Sorry, that site already exists!' ) );
  1128 
  1206 
  1129 	if ( !defined('WP_INSTALLING') )
  1207 	if ( ! wp_installing() ) {
  1130 		define( 'WP_INSTALLING', true );
  1208 		wp_installing( true );
  1131 
  1209 	}
  1132 	if ( ! $blog_id = insert_blog($domain, $path, $site_id) )
  1210 
       
  1211 	if ( ! $blog_id = insert_blog($domain, $path, $network_id) )
  1133 		return new WP_Error('insert_blog', __('Could not create site.'));
  1212 		return new WP_Error('insert_blog', __('Could not create site.'));
  1134 
  1213 
  1135 	switch_to_blog($blog_id);
  1214 	switch_to_blog($blog_id);
  1136 	install_blog($blog_id, $title);
  1215 	install_blog($blog_id, $title);
  1137 	wp_install_defaults($user_id);
  1216 	wp_install_defaults($user_id);
  1143 			update_blog_status( $blog_id, $key, $value );
  1222 			update_blog_status( $blog_id, $key, $value );
  1144 		else
  1223 		else
  1145 			update_option( $key, $value );
  1224 			update_option( $key, $value );
  1146 	}
  1225 	}
  1147 
  1226 
  1148 	add_option( 'WPLANG', get_site_option( 'WPLANG' ) );
       
  1149 	update_option( 'blog_public', (int) $meta['public'] );
  1227 	update_option( 'blog_public', (int) $meta['public'] );
  1150 
  1228 
  1151 	if ( ! is_super_admin( $user_id ) && ! get_user_meta( $user_id, 'primary_blog', true ) )
  1229 	if ( ! is_super_admin( $user_id ) && ! get_user_meta( $user_id, 'primary_blog', true ) )
  1152 		update_user_meta( $user_id, 'primary_blog', $blog_id );
  1230 		update_user_meta( $user_id, 'primary_blog', $blog_id );
  1153 
  1231 
  1154 	restore_current_blog();
  1232 	restore_current_blog();
  1155 	/**
  1233 	/**
  1156 	 * Fires immediately after a new site is created.
  1234 	 * Fires immediately after a new site is created.
  1157 	 *
  1235 	 *
  1158 	 * @since MU
  1236 	 * @since MU (3.0.0)
  1159 	 *
  1237 	 *
  1160 	 * @param int    $blog_id Blog ID.
  1238 	 * @param int    $blog_id    Site ID.
  1161 	 * @param int    $user_id User ID.
  1239 	 * @param int    $user_id    User ID.
  1162 	 * @param string $domain  Site domain.
  1240 	 * @param string $domain     Site domain.
  1163 	 * @param string $path    Site path.
  1241 	 * @param string $path       Site path.
  1164 	 * @param int    $site_id Site ID. Only relevant on multi-network installs.
  1242 	 * @param int    $network_id Network ID. Only relevant on multi-network installations.
  1165 	 * @param array  $meta    Meta data. Used to set initial site options.
  1243 	 * @param array  $meta       Meta data. Used to set initial site options.
  1166 	 */
  1244 	 */
  1167 	do_action( 'wpmu_new_blog', $blog_id, $user_id, $domain, $path, $site_id, $meta );
  1245 	do_action( 'wpmu_new_blog', $blog_id, $user_id, $domain, $path, $network_id, $meta );
       
  1246 
       
  1247 	wp_cache_set( 'last_changed', microtime(), 'sites' );
  1168 
  1248 
  1169 	return $blog_id;
  1249 	return $blog_id;
  1170 }
  1250 }
  1171 
  1251 
  1172 /**
  1252 /**
  1173  * Notifies the network admin that a new site has been activated.
  1253  * Notifies the network admin that a new site has been activated.
  1174  *
  1254  *
  1175  * Filter 'newblog_notify_siteadmin' to change the content of
  1255  * Filter {@see 'newblog_notify_siteadmin'} to change the content of
  1176  * the notification email.
  1256  * the notification email.
  1177  *
  1257  *
  1178  * @since MU
  1258  * @since MU (3.0.0)
  1179  *
  1259  *
  1180  * @param int $blog_id The new site's ID.
  1260  * @param int    $blog_id    The new site's ID.
       
  1261  * @param string $deprecated Not used.
  1181  * @return bool
  1262  * @return bool
  1182  */
  1263  */
  1183 function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) {
  1264 function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) {
  1184 	if ( get_site_option( 'registrationnotification' ) != 'yes' )
  1265 	if ( get_site_option( 'registrationnotification' ) != 'yes' )
  1185 		return false;
  1266 		return false;
  1193 	switch_to_blog( $blog_id );
  1274 	switch_to_blog( $blog_id );
  1194 	$blogname = get_option( 'blogname' );
  1275 	$blogname = get_option( 'blogname' );
  1195 	$siteurl = site_url();
  1276 	$siteurl = site_url();
  1196 	restore_current_blog();
  1277 	restore_current_blog();
  1197 
  1278 
       
  1279 	/* translators: New site notification email. 1: Site URL, 2: User IP address, 3: Settings screen URL */
  1198 	$msg = sprintf( __( 'New Site: %1$s
  1280 	$msg = sprintf( __( 'New Site: %1$s
  1199 URL: %2$s
  1281 URL: %2$s
  1200 Remote IP: %3$s
  1282 Remote IP address: %3$s
  1201 
  1283 
  1202 Disable these notifications: %4$s' ), $blogname, $siteurl, wp_unslash( $_SERVER['REMOTE_ADDR'] ), $options_site_url);
  1284 Disable these notifications: %4$s' ), $blogname, $siteurl, wp_unslash( $_SERVER['REMOTE_ADDR'] ), $options_site_url);
  1203 	/**
  1285 	/**
  1204 	 * Filter the message body of the new site activation email sent
  1286 	 * Filters the message body of the new site activation email sent
  1205 	 * to the network administrator.
  1287 	 * to the network administrator.
  1206 	 *
  1288 	 *
  1207 	 * @since MU
  1289 	 * @since MU (3.0.0)
  1208 	 *
  1290 	 *
  1209 	 * @param string $msg Email body.
  1291 	 * @param string $msg Email body.
  1210 	 */
  1292 	 */
  1211 	$msg = apply_filters( 'newblog_notify_siteadmin', $msg );
  1293 	$msg = apply_filters( 'newblog_notify_siteadmin', $msg );
  1212 
  1294 
  1215 }
  1297 }
  1216 
  1298 
  1217 /**
  1299 /**
  1218  * Notifies the network admin that a new user has been activated.
  1300  * Notifies the network admin that a new user has been activated.
  1219  *
  1301  *
  1220  * Filter 'newuser_notify_siteadmin' to change the content of
  1302  * Filter {@see 'newuser_notify_siteadmin'} to change the content of
  1221  * the notification email.
  1303  * the notification email.
  1222  *
  1304  *
  1223  * @since MU
  1305  * @since MU (3.0.0)
  1224  *
  1306  *
  1225  * @param int $user_id The new user's ID.
  1307  * @param int $user_id The new user's ID.
  1226  * @return bool
  1308  * @return bool
  1227  */
  1309  */
  1228 function newuser_notify_siteadmin( $user_id ) {
  1310 function newuser_notify_siteadmin( $user_id ) {
  1235 		return false;
  1317 		return false;
  1236 
  1318 
  1237 	$user = get_userdata( $user_id );
  1319 	$user = get_userdata( $user_id );
  1238 
  1320 
  1239 	$options_site_url = esc_url(network_admin_url('settings.php'));
  1321 	$options_site_url = esc_url(network_admin_url('settings.php'));
       
  1322 	/* translators: New user notification email. 1: User login, 2: User IP address, 3: Settings screen URL */
  1240 	$msg = sprintf(__('New User: %1$s
  1323 	$msg = sprintf(__('New User: %1$s
  1241 Remote IP: %2$s
  1324 Remote IP address: %2$s
  1242 
  1325 
  1243 Disable these notifications: %3$s'), $user->user_login, wp_unslash( $_SERVER['REMOTE_ADDR'] ), $options_site_url);
  1326 Disable these notifications: %3$s'), $user->user_login, wp_unslash( $_SERVER['REMOTE_ADDR'] ), $options_site_url);
  1244 
  1327 
  1245 	/**
  1328 	/**
  1246 	 * Filter the message body of the new user activation email sent
  1329 	 * Filters the message body of the new user activation email sent
  1247 	 * to the network administrator.
  1330 	 * to the network administrator.
  1248 	 *
  1331 	 *
  1249 	 * @since MU
  1332 	 * @since MU (3.0.0)
  1250 	 *
  1333 	 *
  1251 	 * @param string  $msg  Email body.
  1334 	 * @param string  $msg  Email body.
  1252 	 * @param WP_User $user WP_User instance of the new user.
  1335 	 * @param WP_User $user WP_User instance of the new user.
  1253 	 */
  1336 	 */
  1254 	$msg = apply_filters( 'newuser_notify_siteadmin', $msg, $user );
  1337 	$msg = apply_filters( 'newuser_notify_siteadmin', $msg, $user );
  1255 	wp_mail( $email, sprintf(__('New User Registration: %s'), $user->user_login), $msg );
  1338 	wp_mail( $email, sprintf(__('New User Registration: %s'), $user->user_login), $msg );
  1256 	return true;
  1339 	return true;
  1257 }
  1340 }
  1258 
  1341 
  1259 /**
  1342 /**
  1260  * Check whether a blogname is already taken.
  1343  * Checks whether a site name is already taken.
       
  1344  *
       
  1345  * The name is the site's subdomain or the site's subdirectory
       
  1346  * path depending on the network settings.
  1261  *
  1347  *
  1262  * Used during the new site registration process to ensure
  1348  * Used during the new site registration process to ensure
  1263  * that each blogname is unique.
  1349  * that each site name is unique.
  1264  *
  1350  *
  1265  * @since MU
  1351  * @since MU (3.0.0)
  1266  *
  1352  *
  1267  * @param string $domain The domain to be checked.
  1353  * @param string $domain     The domain to be checked.
  1268  * @param string $path The path to be checked.
  1354  * @param string $path       The path to be checked.
  1269  * @param int $site_id Optional. Relevant only on multi-network installs.
  1355  * @param int    $network_id Optional. Network ID. Relevant only on multi-network installations.
  1270  * @return int
  1356  * @return int|null The site ID if the site name exists, null otherwise.
  1271  */
  1357  */
  1272 function domain_exists($domain, $path, $site_id = 1) {
  1358 function domain_exists( $domain, $path, $network_id = 1 ) {
  1273 	global $wpdb;
       
  1274 	$path = trailingslashit( $path );
  1359 	$path = trailingslashit( $path );
  1275 	$result = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) );
  1360 	$args = array(
  1276 
  1361 		'network_id' => $network_id,
  1277 	/**
  1362 		'domain'     => $domain,
  1278 	 * Filter whether a blogname is taken.
  1363 		'path'       => $path,
       
  1364 		'fields'     => 'ids',
       
  1365 		'number'     => 1,
       
  1366 	);
       
  1367 	$result = get_sites( $args );
       
  1368 	$result = array_shift( $result );
       
  1369 
       
  1370 	/**
       
  1371 	 * Filters whether a site name is taken.
       
  1372 	 *
       
  1373 	 * The name is the site's subdomain or the site's subdirectory
       
  1374 	 * path depending on the network settings.
  1279 	 *
  1375 	 *
  1280 	 * @since 3.5.0
  1376 	 * @since 3.5.0
  1281 	 *
  1377 	 *
  1282 	 * @param int|null $result  The blog_id if the blogname exists, null otherwise.
  1378 	 * @param int|null $result     The site ID if the site name exists, null otherwise.
  1283 	 * @param string   $domain  Domain to be checked.
  1379 	 * @param string   $domain     Domain to be checked.
  1284 	 * @param string   $path    Path to be checked.
  1380 	 * @param string   $path       Path to be checked.
  1285 	 * @param int      $site_id Site ID. Relevant only on multi-network installs.
  1381 	 * @param int      $network_id Network ID. Relevant only on multi-network installations.
  1286 	 */
  1382 	 */
  1287 	return apply_filters( 'domain_exists', $result, $domain, $path, $site_id );
  1383 	return apply_filters( 'domain_exists', $result, $domain, $path, $network_id );
  1288 }
  1384 }
  1289 
  1385 
  1290 /**
  1386 /**
  1291  * Store basic site info in the blogs table.
  1387  * Store basic site info in the blogs table.
  1292  *
  1388  *
  1293  * This function creates a row in the wp_blogs table and returns
  1389  * This function creates a row in the wp_blogs table and returns
  1294  * the new blog's ID. It is the first step in creating a new blog.
  1390  * the new blog's ID. It is the first step in creating a new blog.
  1295  *
  1391  *
  1296  * @since MU
  1392  * @since MU (3.0.0)
  1297  *
  1393  *
  1298  * @param string $domain The domain of the new site.
  1394  * @global wpdb $wpdb WordPress database abstraction object.
  1299  * @param string $path The path of the new site.
  1395  *
  1300  * @param int $site_id Unless you're running a multi-network install, be sure to set this value to 1.
  1396  * @param string $domain     The domain of the new site.
  1301  * @return int The ID of the new row
  1397  * @param string $path       The path of the new site.
  1302  */
  1398  * @param int    $network_id Unless you're running a multi-network installation, be sure to set this value to 1.
  1303 function insert_blog($domain, $path, $site_id) {
  1399  * @return int|false The ID of the new row
       
  1400  */
       
  1401 function insert_blog($domain, $path, $network_id) {
  1304 	global $wpdb;
  1402 	global $wpdb;
  1305 
  1403 
  1306 	$path = trailingslashit($path);
  1404 	$path = trailingslashit($path);
  1307 	$site_id = (int) $site_id;
  1405 	$network_id = (int) $network_id;
  1308 
  1406 
  1309 	$result = $wpdb->insert( $wpdb->blogs, array('site_id' => $site_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')) );
  1407 	$result = $wpdb->insert( $wpdb->blogs, array('site_id' => $network_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')) );
  1310 	if ( ! $result )
  1408 	if ( ! $result )
  1311 		return false;
  1409 		return false;
  1312 
  1410 
  1313 	$blog_id = $wpdb->insert_id;
  1411 	$blog_id = $wpdb->insert_id;
  1314 	refresh_blog_details( $blog_id );
  1412 	clean_blog_cache( $blog_id );
  1315 
  1413 
  1316 	wp_maybe_update_network_site_counts();
  1414 	wp_maybe_update_network_site_counts( $network_id );
  1317 
  1415 
  1318 	return $blog_id;
  1416 	return $blog_id;
  1319 }
  1417 }
  1320 
  1418 
  1321 /**
  1419 /**
  1323  *
  1421  *
  1324  * Creates the new blog tables and options. If calling this function
  1422  * Creates the new blog tables and options. If calling this function
  1325  * directly, be sure to use switch_to_blog() first, so that $wpdb
  1423  * directly, be sure to use switch_to_blog() first, so that $wpdb
  1326  * points to the new blog.
  1424  * points to the new blog.
  1327  *
  1425  *
  1328  * @since MU
  1426  * @since MU (3.0.0)
  1329  *
  1427  *
  1330  * @param int $blog_id The value returned by insert_blog().
  1428  * @global wpdb     $wpdb
       
  1429  * @global WP_Roles $wp_roles
       
  1430  *
       
  1431  * @param int    $blog_id    The value returned by insert_blog().
  1331  * @param string $blog_title The title of the new site.
  1432  * @param string $blog_title The title of the new site.
  1332  */
  1433  */
  1333 function install_blog( $blog_id, $blog_title = '' ) {
  1434 function install_blog( $blog_id, $blog_title = '' ) {
  1334 	global $wpdb, $wp_roles;
  1435 	global $wpdb, $wp_roles;
  1335 
  1436 
  1351 	populate_roles();
  1452 	populate_roles();
  1352 
  1453 
  1353 	// populate_roles() clears previous role definitions so we start over.
  1454 	// populate_roles() clears previous role definitions so we start over.
  1354 	$wp_roles = new WP_Roles();
  1455 	$wp_roles = new WP_Roles();
  1355 
  1456 
  1356 	$url = untrailingslashit( $url );
  1457 	$siteurl = $home = untrailingslashit( $url );
  1357 
  1458 
  1358 	update_option( 'siteurl', $url );
  1459 	if ( ! is_subdomain_install() ) {
  1359 	update_option( 'home', $url );
  1460 
       
  1461  		if ( 'https' === parse_url( get_site_option( 'siteurl' ), PHP_URL_SCHEME ) ) {
       
  1462  			$siteurl = set_url_scheme( $siteurl, 'https' );
       
  1463  		}
       
  1464  		if ( 'https' === parse_url( get_home_url( get_network()->site_id ), PHP_URL_SCHEME ) ) {
       
  1465  			$home = set_url_scheme( $home, 'https' );
       
  1466  		}
       
  1467 
       
  1468 	}
       
  1469 
       
  1470 	update_option( 'siteurl', $siteurl );
       
  1471 	update_option( 'home', $home );
  1360 
  1472 
  1361 	if ( get_site_option( 'ms_files_rewriting' ) )
  1473 	if ( get_site_option( 'ms_files_rewriting' ) )
  1362 		update_option( 'upload_path', UPLOADBLOGSDIR . "/$blog_id/files" );
  1474 		update_option( 'upload_path', UPLOADBLOGSDIR . "/$blog_id/files" );
  1363 	else
  1475 	else
  1364 		update_option( 'upload_path', get_blog_option( get_current_site()->blog_id, 'upload_path' ) );
  1476 		update_option( 'upload_path', get_blog_option( get_network()->site_id, 'upload_path' ) );
  1365 
  1477 
  1366 	update_option( 'blogname', wp_unslash( $blog_title ) );
  1478 	update_option( 'blogname', wp_unslash( $blog_title ) );
  1367 	update_option( 'admin_email', '' );
  1479 	update_option( 'admin_email', '' );
  1368 
  1480 
  1369 	// remove all perms
  1481 	// remove all perms
  1375 /**
  1487 /**
  1376  * Set blog defaults.
  1488  * Set blog defaults.
  1377  *
  1489  *
  1378  * This function creates a row in the wp_blogs table.
  1490  * This function creates a row in the wp_blogs table.
  1379  *
  1491  *
  1380  * @since MU
  1492  * @since MU (3.0.0)
  1381  * @deprecated MU
  1493  * @deprecated MU
  1382  * @deprecated Use wp_install_defaults()
  1494  * @deprecated Use wp_install_defaults()
  1383  *
  1495  *
       
  1496  * @global wpdb $wpdb WordPress database abstraction object.
       
  1497  *
  1384  * @param int $blog_id Ignored in this function.
  1498  * @param int $blog_id Ignored in this function.
  1385  * @param int $user_id
  1499  * @param int $user_id
  1386  */
  1500  */
  1387 function install_blog_defaults($blog_id, $user_id) {
  1501 function install_blog_defaults($blog_id, $user_id) {
  1388 	global $wpdb;
  1502 	global $wpdb;
  1397 }
  1511 }
  1398 
  1512 
  1399 /**
  1513 /**
  1400  * Notify a user that their blog activation has been successful.
  1514  * Notify a user that their blog activation has been successful.
  1401  *
  1515  *
  1402  * Filter 'wpmu_welcome_notification' to disable or bypass.
  1516  * Filter {@see 'wpmu_welcome_notification'} to disable or bypass.
  1403  *
  1517  *
  1404  * Filter 'update_welcome_email' and 'update_welcome_subject' to
  1518  * Filter {@see 'update_welcome_email'} and {@see 'update_welcome_subject'} to
  1405  * modify the content and subject line of the notification email.
  1519  * modify the content and subject line of the notification email.
  1406  *
  1520  *
  1407  * @since MU
  1521  * @since MU (3.0.0)
  1408  *
  1522  *
  1409  * @param int $blog_id
  1523  * @param int    $blog_id  Blog ID.
  1410  * @param int $user_id
  1524  * @param int    $user_id  User ID.
  1411  * @param string $password
  1525  * @param string $password User password.
  1412  * @param string $title The new blog's title
  1526  * @param string $title    Site title.
  1413  * @param array $meta Optional. Not used in the default function, but is passed along to hooks for customization.
  1527  * @param array  $meta     Optional. Signup meta data. By default, contains the requested privacy setting and lang_id.
  1414  * @return bool
  1528  * @return bool
  1415  */
  1529  */
  1416 function wpmu_welcome_notification( $blog_id, $user_id, $password, $title, $meta = array() ) {
  1530 function wpmu_welcome_notification( $blog_id, $user_id, $password, $title, $meta = array() ) {
  1417 	$current_site = get_current_site();
  1531 	$current_network = get_network();
  1418 
  1532 
  1419 	/**
  1533 	/**
  1420 	 * Filter whether to bypass the welcome email after site activation.
  1534 	 * Filters whether to bypass the welcome email after site activation.
  1421 	 *
  1535 	 *
  1422 	 * Returning false disables the welcome email.
  1536 	 * Returning false disables the welcome email.
  1423 	 *
  1537 	 *
  1424 	 * @since MU
  1538 	 * @since MU (3.0.0)
  1425 	 *
  1539 	 *
  1426 	 * @param int|bool $blog_id  Blog ID.
  1540 	 * @param int|bool $blog_id  Blog ID.
  1427 	 * @param int      $user_id  User ID.
  1541 	 * @param int      $user_id  User ID.
  1428 	 * @param string   $password User password.
  1542 	 * @param string   $password User password.
  1429 	 * @param string   $title    Site title.
  1543 	 * @param string   $title    Site title.
  1430 	 * @param array    $meta     Signup meta data.
  1544 	 * @param array    $meta     Signup meta data. By default, contains the requested privacy setting and lang_id.
  1431 	 */
  1545 	 */
  1432 	if ( ! apply_filters( 'wpmu_welcome_notification', $blog_id, $user_id, $password, $title, $meta ) )
  1546 	if ( ! apply_filters( 'wpmu_welcome_notification', $blog_id, $user_id, $password, $title, $meta ) )
  1433 		return false;
  1547 		return false;
  1434 
  1548 
       
  1549 	$user = get_userdata( $user_id );
       
  1550 
       
  1551 	$switched_locale = switch_to_locale( get_user_locale( $user ) );
       
  1552 
  1435 	$welcome_email = get_site_option( 'welcome_email' );
  1553 	$welcome_email = get_site_option( 'welcome_email' );
  1436 	if ( $welcome_email == false )
  1554 	if ( $welcome_email == false ) {
       
  1555 		/* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */
  1437 		$welcome_email = __( 'Howdy USERNAME,
  1556 		$welcome_email = __( 'Howdy USERNAME,
  1438 
  1557 
  1439 Your new SITE_NAME site has been successfully set up at:
  1558 Your new SITE_NAME site has been successfully set up at:
  1440 BLOG_URL
  1559 BLOG_URL
  1441 
  1560 
  1446 Log in here: BLOG_URLwp-login.php
  1565 Log in here: BLOG_URLwp-login.php
  1447 
  1566 
  1448 We hope you enjoy your new site. Thanks!
  1567 We hope you enjoy your new site. Thanks!
  1449 
  1568 
  1450 --The Team @ SITE_NAME' );
  1569 --The Team @ SITE_NAME' );
       
  1570 	}
  1451 
  1571 
  1452 	$url = get_blogaddress_by_id($blog_id);
  1572 	$url = get_blogaddress_by_id($blog_id);
  1453 	$user = get_userdata( $user_id );
  1573 
  1454 
  1574 	$welcome_email = str_replace( 'SITE_NAME', $current_network->site_name, $welcome_email );
  1455 	$welcome_email = str_replace( 'SITE_NAME', $current_site->site_name, $welcome_email );
       
  1456 	$welcome_email = str_replace( 'BLOG_TITLE', $title, $welcome_email );
  1575 	$welcome_email = str_replace( 'BLOG_TITLE', $title, $welcome_email );
  1457 	$welcome_email = str_replace( 'BLOG_URL', $url, $welcome_email );
  1576 	$welcome_email = str_replace( 'BLOG_URL', $url, $welcome_email );
  1458 	$welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email );
  1577 	$welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email );
  1459 	$welcome_email = str_replace( 'PASSWORD', $password, $welcome_email );
  1578 	$welcome_email = str_replace( 'PASSWORD', $password, $welcome_email );
  1460 
  1579 
  1461 	/**
  1580 	/**
  1462 	 * Filter the content of the welcome email after site activation.
  1581 	 * Filters the content of the welcome email after site activation.
  1463 	 *
  1582 	 *
  1464 	 * Content should be formatted for transmission via wp_mail().
  1583 	 * Content should be formatted for transmission via wp_mail().
  1465 	 *
  1584 	 *
  1466 	 * @since MU
  1585 	 * @since MU (3.0.0)
  1467 	 *
  1586 	 *
  1468 	 * @param string $welcome_email Message body of the email.
  1587 	 * @param string $welcome_email Message body of the email.
  1469 	 * @param int    $blog_id       Blog ID.
  1588 	 * @param int    $blog_id       Blog ID.
  1470 	 * @param int    $user_id       User ID.
  1589 	 * @param int    $user_id       User ID.
  1471 	 * @param string $password      User password.
  1590 	 * @param string $password      User password.
  1472 	 * @param string $title         Site title.
  1591 	 * @param string $title         Site title.
  1473 	 * @param array  $meta          Signup meta data.
  1592 	 * @param array  $meta          Signup meta data. By default, contains the requested privacy setting and lang_id.
  1474 	 */
  1593 	 */
  1475 	$welcome_email = apply_filters( 'update_welcome_email', $welcome_email, $blog_id, $user_id, $password, $title, $meta );
  1594 	$welcome_email = apply_filters( 'update_welcome_email', $welcome_email, $blog_id, $user_id, $password, $title, $meta );
  1476 	$admin_email = get_site_option( 'admin_email' );
  1595 	$admin_email = get_site_option( 'admin_email' );
  1477 
  1596 
  1478 	if ( $admin_email == '' )
  1597 	if ( $admin_email == '' )
  1480 
  1599 
  1481 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
  1600 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
  1482 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
  1601 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
  1483 	$message = $welcome_email;
  1602 	$message = $welcome_email;
  1484 
  1603 
  1485 	if ( empty( $current_site->site_name ) )
  1604 	if ( empty( $current_network->site_name ) )
  1486 		$current_site->site_name = 'WordPress';
  1605 		$current_network->site_name = 'WordPress';
  1487 
  1606 
  1488 	/**
  1607 	/* translators: New site notification email subject. 1: Network name, 2: New site name */
  1489 	 * Filter the subject of the welcome email after site activation.
  1608 	$subject = __( 'New %1$s Site: %2$s' );
  1490 	 *
  1609 
  1491 	 * @since MU
  1610 	/**
       
  1611 	 * Filters the subject of the welcome email after site activation.
       
  1612 	 *
       
  1613 	 * @since MU (3.0.0)
  1492 	 *
  1614 	 *
  1493 	 * @param string $subject Subject of the email.
  1615 	 * @param string $subject Subject of the email.
  1494 	 */
  1616 	 */
  1495 	$subject = apply_filters( 'update_welcome_subject', sprintf( __( 'New %1$s Site: %2$s' ), $current_site->site_name, wp_unslash( $title ) ) );
  1617 	$subject = apply_filters( 'update_welcome_subject', sprintf( $subject, $current_network->site_name, wp_unslash( $title ) ) );
  1496 	wp_mail( $user->user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
  1618 	wp_mail( $user->user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
       
  1619 
       
  1620 	if ( $switched_locale ) {
       
  1621 		restore_previous_locale();
       
  1622 	}
       
  1623 
  1497 	return true;
  1624 	return true;
  1498 }
  1625 }
  1499 
  1626 
  1500 /**
  1627 /**
  1501  * Notify a user that their account activation has been successful.
  1628  * Notify a user that their account activation has been successful.
  1502  *
  1629  *
  1503  * Filter 'wpmu_welcome_user_notification' to disable or bypass.
  1630  * Filter {@see 'wpmu_welcome_user_notification'} to disable or bypass.
  1504  *
  1631  *
  1505  * Filter 'update_welcome_user_email' and 'update_welcome_user_subject' to
  1632  * Filter {@see 'update_welcome_user_email'} and {@see 'update_welcome_user_subject'} to
  1506  * modify the content and subject line of the notification email.
  1633  * modify the content and subject line of the notification email.
  1507  *
  1634  *
  1508  * @since MU
  1635  * @since MU (3.0.0)
  1509  *
  1636  *
  1510  * @param int $user_id
  1637  * @param int    $user_id  User ID.
  1511  * @param string $password
  1638  * @param string $password User password.
  1512  * @param array $meta Optional. Not used in the default function, but is passed along to hooks for customization.
  1639  * @param array  $meta     Optional. Signup meta data. Default empty array.
  1513  * @return bool
  1640  * @return bool
  1514  */
  1641  */
  1515 function wpmu_welcome_user_notification( $user_id, $password, $meta = array() ) {
  1642 function wpmu_welcome_user_notification( $user_id, $password, $meta = array() ) {
  1516 	$current_site = get_current_site();
  1643 	$current_network = get_network();
  1517 
  1644 
  1518 	/**
  1645 	/**
  1519  	 * Filter whether to bypass the welcome email after user activation.
  1646  	 * Filters whether to bypass the welcome email after user activation.
  1520 	 *
  1647 	 *
  1521 	 * Returning false disables the welcome email.
  1648 	 * Returning false disables the welcome email.
  1522 	 *
  1649 	 *
  1523 	 * @since MU
  1650 	 * @since MU (3.0.0)
  1524 	 *
  1651 	 *
  1525 	 * @param int    $user_id  User ID.
  1652 	 * @param int    $user_id  User ID.
  1526 	 * @param string $password User password.
  1653 	 * @param string $password User password.
  1527 	 * @param array  $meta     Signup meta data.
  1654 	 * @param array  $meta     Signup meta data. Default empty array.
  1528 	 */
  1655 	 */
  1529 	if ( ! apply_filters( 'wpmu_welcome_user_notification', $user_id, $password, $meta ) )
  1656 	if ( ! apply_filters( 'wpmu_welcome_user_notification', $user_id, $password, $meta ) )
  1530 		return false;
  1657 		return false;
  1531 
  1658 
  1532 	$welcome_email = get_site_option( 'welcome_user_email' );
  1659 	$welcome_email = get_site_option( 'welcome_user_email' );
  1533 
  1660 
  1534 	$user = get_userdata( $user_id );
  1661 	$user = get_userdata( $user_id );
  1535 
  1662 
  1536 	/**
  1663 	$switched_locale = switch_to_locale( get_user_locale( $user ) );
  1537 	 * Filter the content of the welcome email after user activation.
  1664 
       
  1665 	/**
       
  1666 	 * Filters the content of the welcome email after user activation.
  1538 	 *
  1667 	 *
  1539 	 * Content should be formatted for transmission via wp_mail().
  1668 	 * Content should be formatted for transmission via wp_mail().
  1540 	 *
  1669 	 *
  1541 	 * @since MU
  1670 	 * @since MU (3.0.0)
  1542 	 *
  1671 	 *
  1543 	 * @param type   $welcome_email The message body of the account activation success email.
  1672 	 * @param string $welcome_email The message body of the account activation success email.
  1544 	 * @param int    $user_id       User ID.
  1673 	 * @param int    $user_id       User ID.
  1545 	 * @param string $password      User password.
  1674 	 * @param string $password      User password.
  1546 	 * @param array  $meta          Signup meta data.
  1675 	 * @param array  $meta          Signup meta data. Default empty array.
  1547 	 */
  1676 	 */
  1548 	$welcome_email = apply_filters( 'update_welcome_user_email', $welcome_email, $user_id, $password, $meta );
  1677 	$welcome_email = apply_filters( 'update_welcome_user_email', $welcome_email, $user_id, $password, $meta );
  1549 	$welcome_email = str_replace( 'SITE_NAME', $current_site->site_name, $welcome_email );
  1678 	$welcome_email = str_replace( 'SITE_NAME', $current_network->site_name, $welcome_email );
  1550 	$welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email );
  1679 	$welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email );
  1551 	$welcome_email = str_replace( 'PASSWORD', $password, $welcome_email );
  1680 	$welcome_email = str_replace( 'PASSWORD', $password, $welcome_email );
  1552 	$welcome_email = str_replace( 'LOGINLINK', wp_login_url(), $welcome_email );
  1681 	$welcome_email = str_replace( 'LOGINLINK', wp_login_url(), $welcome_email );
  1553 
  1682 
  1554 	$admin_email = get_site_option( 'admin_email' );
  1683 	$admin_email = get_site_option( 'admin_email' );
  1558 
  1687 
  1559 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
  1688 	$from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) );
  1560 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
  1689 	$message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
  1561 	$message = $welcome_email;
  1690 	$message = $welcome_email;
  1562 
  1691 
  1563 	if ( empty( $current_site->site_name ) )
  1692 	if ( empty( $current_network->site_name ) )
  1564 		$current_site->site_name = 'WordPress';
  1693 		$current_network->site_name = 'WordPress';
  1565 
  1694 
  1566 	/**
  1695 	/* translators: New user notification email subject. 1: Network name, 2: New user login */
  1567 	 * Filter the subject of the welcome email after user activation.
  1696 	$subject = __( 'New %1$s User: %2$s' );
  1568 	 *
  1697 
  1569 	 * @since MU
  1698 	/**
       
  1699 	 * Filters the subject of the welcome email after user activation.
       
  1700 	 *
       
  1701 	 * @since MU (3.0.0)
  1570 	 *
  1702 	 *
  1571 	 * @param string $subject Subject of the email.
  1703 	 * @param string $subject Subject of the email.
  1572 	 */
  1704 	 */
  1573 	$subject = apply_filters( 'update_welcome_user_subject', sprintf( __( 'New %1$s User: %2$s' ), $current_site->site_name, $user->user_login) );
  1705 	$subject = apply_filters( 'update_welcome_user_subject', sprintf( $subject, $current_network->site_name, $user->user_login) );
  1574 	wp_mail( $user->user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
  1706 	wp_mail( $user->user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
       
  1707 
       
  1708 	if ( $switched_locale ) {
       
  1709 		restore_previous_locale();
       
  1710 	}
       
  1711 
  1575 	return true;
  1712 	return true;
  1576 }
  1713 }
  1577 
  1714 
  1578 /**
  1715 /**
  1579  * Get the current site info.
  1716  * Get the current network.
  1580  *
  1717  *
  1581  * Returns an object containing the 'id', 'domain', 'path', and 'site_name'
  1718  * Returns an object containing the 'id', 'domain', 'path', and 'site_name'
  1582  * properties of the site being viewed.
  1719  * properties of the network being viewed.
  1583  *
  1720  *
  1584  * @see wpmu_current_site()
  1721  * @see wpmu_current_site()
  1585  *
  1722  *
  1586  * @since MU
  1723  * @since MU (3.0.0)
  1587  *
  1724  *
  1588  * @return object
  1725  * @global WP_Network $current_site
       
  1726  *
       
  1727  * @return WP_Network
  1589  */
  1728  */
  1590 function get_current_site() {
  1729 function get_current_site() {
  1591 	global $current_site;
  1730 	global $current_site;
  1592 	return $current_site;
  1731 	return $current_site;
  1593 }
  1732 }
  1596  * Get a user's most recent post.
  1735  * Get a user's most recent post.
  1597  *
  1736  *
  1598  * Walks through each of a user's blogs to find the post with
  1737  * Walks through each of a user's blogs to find the post with
  1599  * the most recent post_date_gmt.
  1738  * the most recent post_date_gmt.
  1600  *
  1739  *
  1601  * @since MU
  1740  * @since MU (3.0.0)
       
  1741  *
       
  1742  * @global wpdb $wpdb WordPress database abstraction object.
  1602  *
  1743  *
  1603  * @param int $user_id
  1744  * @param int $user_id
  1604  * @return array Contains the blog_id, post_id, post_date_gmt, and post_gmt_ts
  1745  * @return array Contains the blog_id, post_id, post_date_gmt, and post_gmt_ts
  1605  */
  1746  */
  1606 function get_most_recent_post_of_user( $user_id ) {
  1747 function get_most_recent_post_of_user( $user_id ) {
  1642  * Get the size of a directory.
  1783  * Get the size of a directory.
  1643  *
  1784  *
  1644  * A helper function that is used primarily to check whether
  1785  * A helper function that is used primarily to check whether
  1645  * a blog has exceeded its allowed upload space.
  1786  * a blog has exceeded its allowed upload space.
  1646  *
  1787  *
  1647  * @since MU
  1788  * @since MU (3.0.0)
  1648  *
  1789  *
  1649  * @param string $directory
  1790  * @param string $directory Full path of a directory.
  1650  * @return int
  1791  * @return int Size of the directory in MB.
  1651  */
  1792  */
  1652 function get_dirsize( $directory ) {
  1793 function get_dirsize( $directory ) {
  1653 	$dirsize = get_transient( 'dirsize_cache' );
  1794 	$dirsize = get_transient( 'dirsize_cache' );
  1654 	if ( is_array( $dirsize ) && isset( $dirsize[ $directory ][ 'size' ] ) )
  1795 	if ( is_array( $dirsize ) && isset( $dirsize[ $directory ][ 'size' ] ) )
  1655 		return $dirsize[ $directory ][ 'size' ];
  1796 		return $dirsize[ $directory ][ 'size' ];
  1656 
  1797 
  1657 	if ( false == is_array( $dirsize ) )
  1798 	if ( ! is_array( $dirsize ) )
  1658 		$dirsize = array();
  1799 		$dirsize = array();
  1659 
  1800 
  1660 	$dirsize[ $directory ][ 'size' ] = recurse_dirsize( $directory );
  1801 	// Exclude individual site directories from the total when checking the main site,
       
  1802 	// as they are subdirectories and should not be counted.
       
  1803 	if ( is_main_site() ) {
       
  1804 		$dirsize[ $directory ][ 'size' ] = recurse_dirsize( $directory, $directory . '/sites' );
       
  1805 	} else {
       
  1806 		$dirsize[ $directory ][ 'size' ] = recurse_dirsize( $directory );
       
  1807 	}
  1661 
  1808 
  1662 	set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS );
  1809 	set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS );
  1663 	return $dirsize[ $directory ][ 'size' ];
  1810 	return $dirsize[ $directory ][ 'size' ];
  1664 }
  1811 }
  1665 
  1812 
  1667  * Get the size of a directory recursively.
  1814  * Get the size of a directory recursively.
  1668  *
  1815  *
  1669  * Used by get_dirsize() to get a directory's size when it contains
  1816  * Used by get_dirsize() to get a directory's size when it contains
  1670  * other directories.
  1817  * other directories.
  1671  *
  1818  *
  1672  * @since MU
  1819  * @since MU (3.0.0)
  1673  *
  1820  * @since 4.3.0 $exclude parameter added.
  1674  * @param string $directory
  1821  *
  1675  * @return int
  1822  * @param string $directory Full path of a directory.
  1676  */
  1823  * @param string $exclude   Optional. Full path of a subdirectory to exclude from the total.
  1677 function recurse_dirsize( $directory ) {
  1824  * @return int|false Size in MB if a valid directory. False if not.
       
  1825  */
       
  1826 function recurse_dirsize( $directory, $exclude = null ) {
  1678 	$size = 0;
  1827 	$size = 0;
  1679 
  1828 
  1680 	$directory = untrailingslashit( $directory );
  1829 	$directory = untrailingslashit( $directory );
  1681 
  1830 
  1682 	if ( !file_exists($directory) || !is_dir( $directory ) || !is_readable( $directory ) )
  1831 	if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) || $directory === $exclude ) {
  1683 		return false;
  1832 		return false;
       
  1833 	}
  1684 
  1834 
  1685 	if ($handle = opendir($directory)) {
  1835 	if ($handle = opendir($directory)) {
  1686 		while(($file = readdir($handle)) !== false) {
  1836 		while(($file = readdir($handle)) !== false) {
  1687 			$path = $directory.'/'.$file;
  1837 			$path = $directory.'/'.$file;
  1688 			if ($file != '.' && $file != '..') {
  1838 			if ($file != '.' && $file != '..') {
  1689 				if (is_file($path)) {
  1839 				if (is_file($path)) {
  1690 					$size += filesize($path);
  1840 					$size += filesize($path);
  1691 				} elseif (is_dir($path)) {
  1841 				} elseif (is_dir($path)) {
  1692 					$handlesize = recurse_dirsize($path);
  1842 					$handlesize = recurse_dirsize( $path, $exclude );
  1693 					if ($handlesize > 0)
  1843 					if ($handlesize > 0)
  1694 						$size += $handlesize;
  1844 						$size += $handlesize;
  1695 				}
  1845 				}
  1696 			}
  1846 			}
  1697 		}
  1847 		}
  1707  * which is defined in wp-includes/functions.php in
  1857  * which is defined in wp-includes/functions.php in
  1708  * get_allowed_mime_types(). This function is used to filter
  1858  * get_allowed_mime_types(). This function is used to filter
  1709  * that list against the filetype whitelist provided by Multisite
  1859  * that list against the filetype whitelist provided by Multisite
  1710  * Super Admins at wp-admin/network/settings.php.
  1860  * Super Admins at wp-admin/network/settings.php.
  1711  *
  1861  *
  1712  * @since MU
  1862  * @since MU (3.0.0)
  1713  *
  1863  *
  1714  * @param array $mimes
  1864  * @param array $mimes
  1715  * @return array
  1865  * @return array
  1716  */
  1866  */
  1717 function check_upload_mimes( $mimes ) {
  1867 function check_upload_mimes( $mimes ) {
  1729 /**
  1879 /**
  1730  * Update a blog's post count.
  1880  * Update a blog's post count.
  1731  *
  1881  *
  1732  * WordPress MS stores a blog's post count as an option so as
  1882  * WordPress MS stores a blog's post count as an option so as
  1733  * to avoid extraneous COUNTs when a blog's details are fetched
  1883  * to avoid extraneous COUNTs when a blog's details are fetched
  1734  * with get_blog_details(). This function is called when posts
  1884  * with get_site(). This function is called when posts are published
  1735  * are published or unpublished to make sure the count stays current.
  1885  * or unpublished to make sure the count stays current.
  1736  *
  1886  *
  1737  * @since MU
  1887  * @since MU (3.0.0)
       
  1888  *
       
  1889  * @global wpdb $wpdb WordPress database abstraction object.
       
  1890  *
       
  1891  * @param string $deprecated Not used.
  1738  */
  1892  */
  1739 function update_posts_count( $deprecated = '' ) {
  1893 function update_posts_count( $deprecated = '' ) {
  1740 	global $wpdb;
  1894 	global $wpdb;
  1741 	update_option( 'post_count', (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ) );
  1895 	update_option( 'post_count', (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ) );
  1742 }
  1896 }
  1743 
  1897 
  1744 /**
  1898 /**
  1745  * Logs user registrations.
  1899  * Logs the user email, IP, and registration date of a new site.
  1746  *
  1900  *
  1747  * @since MU
  1901  * @since MU (3.0.0)
       
  1902  *
       
  1903  * @global wpdb $wpdb WordPress database abstraction object.
  1748  *
  1904  *
  1749  * @param int $blog_id
  1905  * @param int $blog_id
  1750  * @param int $user_id
  1906  * @param int $user_id
  1751  */
  1907  */
  1752 function wpmu_log_new_registrations( $blog_id, $user_id ) {
  1908 function wpmu_log_new_registrations( $blog_id, $user_id ) {
  1761  *
  1917  *
  1762  * @since 3.0.0
  1918  * @since 3.0.0
  1763  *
  1919  *
  1764  * @see term_id_filter
  1920  * @see term_id_filter
  1765  *
  1921  *
  1766  * @param int $term_id An ID for a term on the current blog.
  1922  * @global wpdb $wpdb WordPress database abstraction object.
       
  1923  * @staticvar int $global_terms_recurse
       
  1924  *
       
  1925  * @param int    $term_id    An ID for a term on the current blog.
       
  1926  * @param string $deprecated Not used.
  1767  * @return int An ID from the global terms table mapped from $term_id.
  1927  * @return int An ID from the global terms table mapped from $term_id.
  1768  */
  1928  */
  1769 function global_terms( $term_id, $deprecated = '' ) {
  1929 function global_terms( $term_id, $deprecated = '' ) {
  1770 	global $wpdb;
  1930 	global $wpdb;
  1771 	static $global_terms_recurse = null;
  1931 	static $global_terms_recurse = null;
  1818 		$wpdb->update( $wpdb->term_taxonomy, array('term_id' => $global_id), array('term_id' => $term_id) );
  1978 		$wpdb->update( $wpdb->term_taxonomy, array('term_id' => $global_id), array('term_id' => $term_id) );
  1819 		$wpdb->update( $wpdb->term_taxonomy, array('parent' => $global_id), array('parent' => $term_id) );
  1979 		$wpdb->update( $wpdb->term_taxonomy, array('parent' => $global_id), array('parent' => $term_id) );
  1820 
  1980 
  1821 		clean_term_cache($term_id);
  1981 		clean_term_cache($term_id);
  1822 	}
  1982 	}
  1823 	if( $recurse_start )
  1983 	if ( $recurse_start )
  1824 		$global_terms_recurse = null;
  1984 		$global_terms_recurse = null;
  1825 
  1985 
  1826 	return $global_id;
  1986 	return $global_id;
  1827 }
  1987 }
  1828 
  1988 
  1829 /**
  1989 /**
  1830  * Ensure that the current site's domain is listed in the allowed redirect host list.
  1990  * Ensure that the current site's domain is listed in the allowed redirect host list.
  1831  *
  1991  *
  1832  * @see wp_validate_redirect()
  1992  * @see wp_validate_redirect()
  1833  * @since MU
  1993  * @since MU (3.0.0)
  1834  *
  1994  *
       
  1995  * @param array|string $deprecated Not used.
  1835  * @return array The current site's domain
  1996  * @return array The current site's domain
  1836  */
  1997  */
  1837 function redirect_this_site( $deprecated = '' ) {
  1998 function redirect_this_site( $deprecated = '' ) {
  1838 	return array( get_current_site()->domain );
  1999 	return array( get_network()->domain );
  1839 }
  2000 }
  1840 
  2001 
  1841 /**
  2002 /**
  1842  * Check whether an upload is too big.
  2003  * Check whether an upload is too big.
  1843  *
  2004  *
  1844  * @since MU
  2005  * @since MU (3.0.0)
       
  2006  *
       
  2007  * @blessed
  1845  *
  2008  *
  1846  * @param array $upload
  2009  * @param array $upload
  1847  * @return mixed If the upload is under the size limit, $upload is returned. Otherwise returns an error message.
  2010  * @return string|array If the upload is under the size limit, $upload is returned. Otherwise returns an error message.
  1848  */
  2011  */
  1849 function upload_is_file_too_big( $upload ) {
  2012 function upload_is_file_too_big( $upload ) {
  1850 	if ( is_array( $upload ) == false || defined( 'WP_IMPORTING' ) || get_site_option( 'upload_space_check_disabled' ) )
  2013 	if ( ! is_array( $upload ) || defined( 'WP_IMPORTING' ) || get_site_option( 'upload_space_check_disabled' ) )
  1851 		return $upload;
  2014 		return $upload;
  1852 
  2015 
  1853 	if ( strlen( $upload['bits'] )  > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) )
  2016 	if ( strlen( $upload['bits'] )  > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
  1854 		return sprintf( __( 'This file is too big. Files must be less than %d KB in size.' ) . '<br />', get_site_option( 'fileupload_maxk', 1500 ));
  2017 		return sprintf( __( 'This file is too big. Files must be less than %d KB in size.' ) . '<br />', get_site_option( 'fileupload_maxk', 1500 ) );
       
  2018 	}
  1855 
  2019 
  1856 	return $upload;
  2020 	return $upload;
  1857 }
  2021 }
  1858 
  2022 
  1859 /**
  2023 /**
  1860  * Add a nonce field to the signup page.
  2024  * Add a nonce field to the signup page.
  1861  *
  2025  *
  1862  * @since MU
  2026  * @since MU (3.0.0)
  1863  */
  2027  */
  1864 function signup_nonce_fields() {
  2028 function signup_nonce_fields() {
  1865 	$id = mt_rand();
  2029 	$id = mt_rand();
  1866 	echo "<input type='hidden' name='signup_form_id' value='{$id}' />";
  2030 	echo "<input type='hidden' name='signup_form_id' value='{$id}' />";
  1867 	wp_nonce_field('signup_form_' . $id, '_signup_form', false);
  2031 	wp_nonce_field('signup_form_' . $id, '_signup_form', false);
  1868 }
  2032 }
  1869 
  2033 
  1870 /**
  2034 /**
  1871  * Process the signup nonce created in signup_nonce_fields().
  2035  * Process the signup nonce created in signup_nonce_fields().
  1872  *
  2036  *
  1873  * @since MU
  2037  * @since MU (3.0.0)
  1874  *
  2038  *
  1875  * @param array $result
  2039  * @param array $result
  1876  * @return array
  2040  * @return array
  1877  */
  2041  */
  1878 function signup_nonce_check( $result ) {
  2042 function signup_nonce_check( $result ) {
  1886 }
  2050 }
  1887 
  2051 
  1888 /**
  2052 /**
  1889  * Correct 404 redirects when NOBLOGREDIRECT is defined.
  2053  * Correct 404 redirects when NOBLOGREDIRECT is defined.
  1890  *
  2054  *
  1891  * @since MU
  2055  * @since MU (3.0.0)
  1892  */
  2056  */
  1893 function maybe_redirect_404() {
  2057 function maybe_redirect_404() {
  1894 	/**
  2058 	/**
  1895 	 * Filter the redirect URL for 404s on the main site.
  2059 	 * Filters the redirect URL for 404s on the main site.
  1896 	 *
  2060 	 *
  1897 	 * The filter is only evaluated if the NOBLOGREDIRECT constant is defined.
  2061 	 * The filter is only evaluated if the NOBLOGREDIRECT constant is defined.
  1898 	 *
  2062 	 *
  1899 	 * @since 3.0.0
  2063 	 * @since 3.0.0
  1900 	 *
  2064 	 *
  1907 		exit();
  2071 		exit();
  1908 	}
  2072 	}
  1909 }
  2073 }
  1910 
  2074 
  1911 /**
  2075 /**
  1912  * Add a new user to a blog by visiting /newbloguser/username/.
  2076  * Add a new user to a blog by visiting /newbloguser/{key}/.
  1913  *
  2077  *
  1914  * This will only work when the user's details are saved as an option
  2078  * This will only work when the user's details are saved as an option
  1915  * keyed as 'new_user_x', where 'x' is the username of the user to be
  2079  * keyed as 'new_user_{key}', where '{key}' is a hash generated for the user to be
  1916  * added, as when a user is invited through the regular WP Add User interface.
  2080  * added, as when a user is invited through the regular WP Add User interface.
  1917  *
  2081  *
  1918  * @since MU
  2082  * @since MU (3.0.0)
  1919  */
  2083  */
  1920 function maybe_add_existing_user_to_blog() {
  2084 function maybe_add_existing_user_to_blog() {
  1921 	if ( false === strpos( $_SERVER[ 'REQUEST_URI' ], '/newbloguser/' ) )
  2085 	if ( false === strpos( $_SERVER[ 'REQUEST_URI' ], '/newbloguser/' ) )
  1922 		return false;
  2086 		return;
  1923 
  2087 
  1924 	$parts = explode( '/', $_SERVER[ 'REQUEST_URI' ] );
  2088 	$parts = explode( '/', $_SERVER[ 'REQUEST_URI' ] );
  1925 	$key = array_pop( $parts );
  2089 	$key = array_pop( $parts );
  1926 
  2090 
  1927 	if ( $key == '' )
  2091 	if ( $key == '' )
  1938 }
  2102 }
  1939 
  2103 
  1940 /**
  2104 /**
  1941  * Add a user to a blog based on details from maybe_add_existing_user_to_blog().
  2105  * Add a user to a blog based on details from maybe_add_existing_user_to_blog().
  1942  *
  2106  *
  1943  * @since MU
  2107  * @since MU (3.0.0)
  1944  *
  2108  *
  1945  * @param array $details
  2109  * @param array $details
       
  2110  * @return true|WP_Error|void
  1946  */
  2111  */
  1947 function add_existing_user_to_blog( $details = false ) {
  2112 function add_existing_user_to_blog( $details = false ) {
  1948 	global $blog_id;
       
  1949 
       
  1950 	if ( is_array( $details ) ) {
  2113 	if ( is_array( $details ) ) {
       
  2114 		$blog_id = get_current_blog_id();
  1951 		$result = add_user_to_blog( $blog_id, $details[ 'user_id' ], $details[ 'role' ] );
  2115 		$result = add_user_to_blog( $blog_id, $details[ 'user_id' ], $details[ 'role' ] );
       
  2116 
  1952 		/**
  2117 		/**
  1953 		 * Fires immediately after an existing user is added to a site.
  2118 		 * Fires immediately after an existing user is added to a site.
  1954 		 *
  2119 		 *
  1955 		 * @since MU
  2120 		 * @since MU (3.0.0)
  1956 		 *
  2121 		 *
  1957 		 * @param int   $user_id User ID.
  2122 		 * @param int   $user_id User ID.
  1958 		 * @param mixed $result  True on success or a WP_Error object if the user doesn't exist.
  2123 		 * @param mixed $result  True on success or a WP_Error object if the user doesn't exist
       
  2124 		 *                       or could not be added.
  1959 		 */
  2125 		 */
  1960 		do_action( 'added_existing_user', $details['user_id'], $result );
  2126 		do_action( 'added_existing_user', $details['user_id'], $result );
  1961 	}
  2127 
  1962 	return $result;
  2128 		return $result;
  1963 }
  2129 	}
  1964 
  2130 }
  1965 /**
  2131 
  1966  * Add a newly created user to the appropriate blog
  2132 /**
       
  2133  * Adds a newly created user to the appropriate blog
  1967  *
  2134  *
  1968  * To add a user in general, use add_user_to_blog(). This function
  2135  * To add a user in general, use add_user_to_blog(). This function
  1969  * is specifically hooked into the wpmu_activate_user action.
  2136  * is specifically hooked into the {@see 'wpmu_activate_user'} action.
  1970  *
  2137  *
  1971  * @since MU
  2138  * @since MU (3.0.0)
  1972  * @see add_user_to_blog()
  2139  * @see add_user_to_blog()
  1973  *
  2140  *
  1974  * @param int $user_id
  2141  * @param int   $user_id
  1975  * @param mixed $password Ignored.
  2142  * @param mixed $password Ignored.
  1976  * @param array $meta
  2143  * @param array $meta
  1977  */
  2144  */
  1978 function add_new_user_to_blog( $user_id, $password, $meta ) {
  2145 function add_new_user_to_blog( $user_id, $password, $meta ) {
  1979 	if ( !empty( $meta[ 'add_to_blog' ] ) ) {
  2146 	if ( !empty( $meta[ 'add_to_blog' ] ) ) {
  1980 		$blog_id = $meta[ 'add_to_blog' ];
  2147 		$blog_id = $meta[ 'add_to_blog' ];
  1981 		$role = $meta[ 'new_role' ];
  2148 		$role = $meta[ 'new_role' ];
  1982 		remove_user_from_blog($user_id, get_current_site()->blog_id); // remove user from main blog.
  2149 		remove_user_from_blog( $user_id, get_network()->site_id ); // remove user from main blog.
  1983 		add_user_to_blog( $blog_id, $user_id, $role );
  2150 
  1984 		update_user_meta( $user_id, 'primary_blog', $blog_id );
  2151 		$result = add_user_to_blog( $blog_id, $user_id, $role );
       
  2152 
       
  2153 		if ( ! is_wp_error( $result ) ) {
       
  2154 			update_user_meta( $user_id, 'primary_blog', $blog_id );
       
  2155 		}
  1985 	}
  2156 	}
  1986 }
  2157 }
  1987 
  2158 
  1988 /**
  2159 /**
  1989  * Correct From host on outgoing mail to match the site domain
  2160  * Correct From host on outgoing mail to match the site domain
  1990  *
  2161  *
  1991  * @since MU
  2162  * @since MU (3.0.0)
       
  2163  *
       
  2164  * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
  1992  */
  2165  */
  1993 function fix_phpmailer_messageid( $phpmailer ) {
  2166 function fix_phpmailer_messageid( $phpmailer ) {
  1994 	$phpmailer->Hostname = get_current_site()->domain;
  2167 	$phpmailer->Hostname = get_network()->domain;
  1995 }
  2168 }
  1996 
  2169 
  1997 /**
  2170 /**
  1998  * Check to see whether a user is marked as a spammer, based on user login.
  2171  * Check to see whether a user is marked as a spammer, based on user login.
  1999  *
  2172  *
  2000  * @since MU
  2173  * @since MU (3.0.0)
  2001  *
  2174  *
  2002  * @param string|WP_User $user Optional. Defaults to current user. WP_User object,
  2175  * @param string|WP_User $user Optional. Defaults to current user. WP_User object,
  2003  * 	or user login name as a string.
  2176  * 	                           or user login name as a string.
  2004  * @return bool
  2177  * @return bool
  2005  */
  2178  */
  2006 function is_user_spammy( $user = null ) {
  2179 function is_user_spammy( $user = null ) {
  2007     if ( ! ( $user instanceof WP_User ) ) {
  2180     if ( ! ( $user instanceof WP_User ) ) {
  2008 		if ( $user ) {
  2181 		if ( $user ) {
  2018 /**
  2191 /**
  2019  * Update this blog's 'public' setting in the global blogs table.
  2192  * Update this blog's 'public' setting in the global blogs table.
  2020  *
  2193  *
  2021  * Public blogs have a setting of 1, private blogs are 0.
  2194  * Public blogs have a setting of 1, private blogs are 0.
  2022  *
  2195  *
  2023  * @since MU
  2196  * @since MU (3.0.0)
  2024  *
  2197  *
  2025  * @param int $old_value
  2198  * @param int $old_value
  2026  * @param int $value The new public value
  2199  * @param int $value     The new public value
  2027  */
  2200  */
  2028 function update_blog_public( $old_value, $value ) {
  2201 function update_blog_public( $old_value, $value ) {
  2029 	update_blog_status( get_current_blog_id(), 'public', (int) $value );
  2202 	update_blog_status( get_current_blog_id(), 'public', (int) $value );
  2030 }
  2203 }
  2031 
  2204 
  2032 /**
  2205 /**
  2033  * Check whether a usermeta key has to do with the current blog.
       
  2034  *
       
  2035  * @since MU
       
  2036  *
       
  2037  * @param string $key
       
  2038  * @param int $user_id Optional. Defaults to current user.
       
  2039  * @param int $blog_id Optional. Defaults to current blog.
       
  2040  * @return bool
       
  2041  */
       
  2042 function is_user_option_local( $key, $user_id = 0, $blog_id = 0 ) {
       
  2043 	global $wpdb;
       
  2044 
       
  2045 	$current_user = wp_get_current_user();
       
  2046 	if ( $blog_id == 0 ) {
       
  2047 		$blog_id = $wpdb->blogid;
       
  2048 	}
       
  2049 	$local_key = $wpdb->get_blog_prefix( $blog_id ) . $key;
       
  2050 
       
  2051 	if ( isset( $current_user->$local_key ) )
       
  2052 		return true;
       
  2053 
       
  2054 	return false;
       
  2055 }
       
  2056 
       
  2057 /**
       
  2058  * Check whether users can self-register, based on Network settings.
  2206  * Check whether users can self-register, based on Network settings.
  2059  *
  2207  *
  2060  * @since MU
  2208  * @since MU (3.0.0)
  2061  *
  2209  *
  2062  * @return bool
  2210  * @return bool
  2063  */
  2211  */
  2064 function users_can_register_signup_filter() {
  2212 function users_can_register_signup_filter() {
  2065 	$registration = get_site_option('registration');
  2213 	$registration = get_site_option('registration');
  2066 	if ( $registration == 'all' || $registration == 'user' )
  2214 	return ( $registration == 'all' || $registration == 'user' );
  2067 		return true;
       
  2068 
       
  2069 	return false;
       
  2070 }
  2215 }
  2071 
  2216 
  2072 /**
  2217 /**
  2073  * Ensure that the welcome message is not empty. Currently unused.
  2218  * Ensure that the welcome message is not empty. Currently unused.
  2074  *
  2219  *
  2075  * @since MU
  2220  * @since MU (3.0.0)
  2076  *
  2221  *
  2077  * @param string $text
  2222  * @param string $text
  2078  * @return string
  2223  * @return string
  2079  */
  2224  */
  2080 function welcome_user_msg_filter( $text ) {
  2225 function welcome_user_msg_filter( $text ) {
  2081 	if ( !$text ) {
  2226 	if ( !$text ) {
  2082 		remove_filter( 'site_option_welcome_user_email', 'welcome_user_msg_filter' );
  2227 		remove_filter( 'site_option_welcome_user_email', 'welcome_user_msg_filter' );
       
  2228 
       
  2229 		/* translators: Do not translate USERNAME, PASSWORD, LOGINLINK, SITE_NAME: those are placeholders. */
  2083 		$text = __( 'Howdy USERNAME,
  2230 		$text = __( 'Howdy USERNAME,
  2084 
  2231 
  2085 Your new account is set up.
  2232 Your new account is set up.
  2086 
  2233 
  2087 You can log in with the following information:
  2234 You can log in with the following information:
  2100 /**
  2247 /**
  2101  * Whether to force SSL on content.
  2248  * Whether to force SSL on content.
  2102  *
  2249  *
  2103  * @since 2.8.5
  2250  * @since 2.8.5
  2104  *
  2251  *
  2105  * @param string|bool $force
  2252  * @staticvar bool $forced_content
       
  2253  *
       
  2254  * @param bool $force
  2106  * @return bool True if forced, false if not forced.
  2255  * @return bool True if forced, false if not forced.
  2107  */
  2256  */
  2108 function force_ssl_content( $force = '' ) {
  2257 function force_ssl_content( $force = '' ) {
  2109 	static $forced_content;
  2258 	static $forced_content = false;
  2110 
  2259 
  2111 	if ( '' != $force ) {
  2260 	if ( '' != $force ) {
  2112 		$old_forced = $forced_content;
  2261 		$old_forced = $forced_content;
  2113 		$forced_content = $force;
  2262 		$forced_content = $force;
  2114 		return $old_forced;
  2263 		return $old_forced;
  2122  *
  2271  *
  2123  * Useful as a filter.
  2272  * Useful as a filter.
  2124  *
  2273  *
  2125  * @since 2.8.5
  2274  * @since 2.8.5
  2126  *
  2275  *
  2127  * @param string URL
  2276  * @param string $url URL
  2128  * @return string URL with https as the scheme
  2277  * @return string URL with https as the scheme
  2129  */
  2278  */
  2130 function filter_SSL( $url ) {
  2279 function filter_SSL( $url ) {
  2131 	if ( ! is_string( $url ) )
  2280 	if ( ! is_string( $url ) )
  2132 		return get_bloginfo( 'url' ); // Return home blog url with proper scheme
  2281 		return get_bloginfo( 'url' ); // Return home blog url with proper scheme
  2144  */
  2293  */
  2145 function wp_schedule_update_network_counts() {
  2294 function wp_schedule_update_network_counts() {
  2146 	if ( !is_main_site() )
  2295 	if ( !is_main_site() )
  2147 		return;
  2296 		return;
  2148 
  2297 
  2149 	if ( !wp_next_scheduled('update_network_counts') && !defined('WP_INSTALLING') )
  2298 	if ( ! wp_next_scheduled('update_network_counts') && ! wp_installing() )
  2150 		wp_schedule_event(time(), 'twicedaily', 'update_network_counts');
  2299 		wp_schedule_event(time(), 'twicedaily', 'update_network_counts');
  2151 }
  2300 }
  2152 
  2301 
  2153 /**
  2302 /**
  2154  *  Update the network-wide counts for the current network.
  2303  * Update the network-wide counts for the current network.
  2155  *
  2304  *
  2156  *  @since 3.1.0
  2305  * @since 3.1.0
  2157  */
  2306  * @since 4.8.0 The $network_id parameter has been added.
  2158 function wp_update_network_counts() {
  2307  *
  2159 	wp_update_network_user_counts();
  2308  * @param int|null $network_id ID of the network. Default is the current network.
  2160 	wp_update_network_site_counts();
  2309  */
       
  2310 function wp_update_network_counts( $network_id = null ) {
       
  2311 	wp_update_network_user_counts( $network_id );
       
  2312 	wp_update_network_site_counts( $network_id );
  2161 }
  2313 }
  2162 
  2314 
  2163 /**
  2315 /**
  2164  * Update the count of sites for the current network.
  2316  * Update the count of sites for the current network.
  2165  *
  2317  *
  2166  * If enabled through the 'enable_live_network_counts' filter, update the sites count
  2318  * If enabled through the {@see 'enable_live_network_counts'} filter, update the sites count
  2167  * on a network when a site is created or its status is updated.
  2319  * on a network when a site is created or its status is updated.
  2168  *
  2320  *
  2169  * @since 3.7.0
  2321  * @since 3.7.0
  2170  */
  2322  * @since 4.8.0 The $network_id parameter has been added.
  2171 function wp_maybe_update_network_site_counts() {
  2323  *
  2172 	$is_small_network = ! wp_is_large_network( 'sites' );
  2324  * @param int|null $network_id ID of the network. Default is the current network.
  2173 
  2325  */
  2174 	/**
  2326 function wp_maybe_update_network_site_counts( $network_id = null ) {
  2175 	 * Filter whether to update network site or user counts when a new site is created.
  2327 	$is_small_network = ! wp_is_large_network( 'sites', $network_id );
       
  2328 
       
  2329 	/**
       
  2330 	 * Filters whether to update network site or user counts when a new site is created.
  2176 	 *
  2331 	 *
  2177 	 * @since 3.7.0
  2332 	 * @since 3.7.0
  2178 	 *
  2333 	 *
  2179 	 * @see wp_is_large_network()
  2334 	 * @see wp_is_large_network()
  2180 	 *
  2335 	 *
  2182 	 * @param string $context       Context. Either 'users' or 'sites'.
  2337 	 * @param string $context       Context. Either 'users' or 'sites'.
  2183 	 */
  2338 	 */
  2184 	if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'sites' ) )
  2339 	if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'sites' ) )
  2185 		return;
  2340 		return;
  2186 
  2341 
  2187 	wp_update_network_site_counts();
  2342 	wp_update_network_site_counts( $network_id );
  2188 }
  2343 }
  2189 
  2344 
  2190 /**
  2345 /**
  2191  * Update the network-wide users count.
  2346  * Update the network-wide users count.
  2192  *
  2347  *
  2193  * If enabled through the 'enable_live_network_counts' filter, update the users count
  2348  * If enabled through the {@see 'enable_live_network_counts'} filter, update the users count
  2194  * on a network when a user is created or its status is updated.
  2349  * on a network when a user is created or its status is updated.
  2195  *
  2350  *
  2196  * @since 3.7.0
  2351  * @since 3.7.0
  2197  */
  2352  * @since 4.8.0 The $network_id parameter has been added.
  2198 function wp_maybe_update_network_user_counts() {
  2353  *
  2199 	$is_small_network = ! wp_is_large_network( 'users' );
  2354  * @param int|null $network_id ID of the network. Default is the current network.
       
  2355  */
       
  2356 function wp_maybe_update_network_user_counts( $network_id = null ) {
       
  2357 	$is_small_network = ! wp_is_large_network( 'users', $network_id );
  2200 
  2358 
  2201 	/** This filter is documented in wp-includes/ms-functions.php */
  2359 	/** This filter is documented in wp-includes/ms-functions.php */
  2202 	if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) )
  2360 	if ( ! apply_filters( 'enable_live_network_counts', $is_small_network, 'users' ) )
  2203 		return;
  2361 		return;
  2204 
  2362 
  2205 	wp_update_network_user_counts();
  2363 	wp_update_network_user_counts( $network_id );
  2206 }
  2364 }
  2207 
  2365 
  2208 /**
  2366 /**
  2209  * Update the network-wide site count.
  2367  * Update the network-wide site count.
  2210  *
  2368  *
  2211  * @since 3.7.0
  2369  * @since 3.7.0
  2212  */
  2370  * @since 4.8.0 The $network_id parameter has been added.
  2213 function wp_update_network_site_counts() {
  2371  *
       
  2372  * @param int|null $network_id ID of the network. Default is the current network.
       
  2373  */
       
  2374 function wp_update_network_site_counts( $network_id = null ) {
       
  2375 	$network_id = (int) $network_id;
       
  2376 	if ( ! $network_id ) {
       
  2377 		$network_id = get_current_network_id();
       
  2378 	}
       
  2379 
       
  2380 	$count = get_sites( array(
       
  2381 		'network_id' => $network_id,
       
  2382 		'spam'       => 0,
       
  2383 		'deleted'    => 0,
       
  2384 		'archived'   => 0,
       
  2385 		'count'      => true,
       
  2386 	) );
       
  2387 
       
  2388 	update_network_option( $network_id, 'blog_count', $count );
       
  2389 }
       
  2390 
       
  2391 /**
       
  2392  * Update the network-wide user count.
       
  2393  *
       
  2394  * @since 3.7.0
       
  2395  * @since 4.8.0 The $network_id parameter has been added.
       
  2396  *
       
  2397  * @global wpdb $wpdb WordPress database abstraction object.
       
  2398  *
       
  2399  * @param int|null $network_id ID of the network. Default is the current network.
       
  2400  */
       
  2401 function wp_update_network_user_counts( $network_id = null ) {
  2214 	global $wpdb;
  2402 	global $wpdb;
  2215 
  2403 
  2216 	$count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $wpdb->siteid) );
       
  2217 	update_site_option( 'blog_count', $count );
       
  2218 }
       
  2219 
       
  2220 /**
       
  2221  * Update the network-wide user count.
       
  2222  *
       
  2223  * @since 3.7.0
       
  2224  */
       
  2225 function wp_update_network_user_counts() {
       
  2226 	global $wpdb;
       
  2227 
       
  2228 	$count = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
  2404 	$count = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" );
  2229 	update_site_option( 'user_count', $count );
  2405 	update_network_option( $network_id, 'user_count', $count );
  2230 }
  2406 }
  2231 
  2407 
  2232 /**
  2408 /**
  2233  * Returns the space used by the current blog.
  2409  * Returns the space used by the current blog.
  2234  *
  2410  *
  2236  *
  2412  *
  2237  * @return int Used space in megabytes
  2413  * @return int Used space in megabytes
  2238  */
  2414  */
  2239 function get_space_used() {
  2415 function get_space_used() {
  2240 	/**
  2416 	/**
  2241 	 * Filter the amount of storage space used by the current site.
  2417 	 * Filters the amount of storage space used by the current site.
  2242 	 *
  2418 	 *
  2243 	 * @since 3.5.0
  2419 	 * @since 3.5.0
  2244 	 *
  2420 	 *
  2245 	 * @param int|bool $space_used The amount of used space, in megabytes. Default false.
  2421 	 * @param int|bool $space_used The amount of used space, in megabytes. Default false.
  2246 	 */
  2422 	 */
  2247 	$space_used = apply_filters( 'pre_get_space_used', false );
  2423 	$space_used = apply_filters( 'pre_get_space_used', false );
  2248 	if ( false === $space_used ) {
  2424 	if ( false === $space_used ) {
  2249 		$upload_dir = wp_upload_dir();
  2425 		$upload_dir = wp_upload_dir();
  2250 		$space_used = get_dirsize( $upload_dir['basedir'] ) / 1024 / 1024;
  2426 		$space_used = get_dirsize( $upload_dir['basedir'] ) / MB_IN_BYTES;
  2251 	}
  2427 	}
  2252 
  2428 
  2253 	return $space_used;
  2429 	return $space_used;
  2254 }
  2430 }
  2255 
  2431 
  2256 /**
  2432 /**
  2257  * Returns the upload quota for the current blog.
  2433  * Returns the upload quota for the current blog.
  2258  *
  2434  *
  2259  * @since MU
  2435  * @since MU (3.0.0)
  2260  *
  2436  *
  2261  * @return int Quota in megabytes
  2437  * @return int Quota in megabytes
  2262  */
  2438  */
  2263 function get_space_allowed() {
  2439 function get_space_allowed() {
  2264 	$space_allowed = get_option( 'blog_upload_space' );
  2440 	$space_allowed = get_option( 'blog_upload_space' );
  2265 
  2441 
  2266 	if ( ! is_numeric( $space_allowed ) )
  2442 	if ( ! is_numeric( $space_allowed ) )
  2267 		$space_allowed = get_site_option( 'blog_upload_space' );
  2443 		$space_allowed = get_site_option( 'blog_upload_space' );
  2268 
  2444 
  2269 	if ( empty( $space_allowed ) || ! is_numeric( $space_allowed ) )
  2445 	if ( ! is_numeric( $space_allowed ) )
  2270 		$space_allowed = 100;
  2446 		$space_allowed = 100;
  2271 
  2447 
  2272 	/**
  2448 	/**
  2273 	 * Filter the upload quota for the current site.
  2449 	 * Filters the upload quota for the current site.
  2274 	 *
  2450 	 *
  2275 	 * @since 3.7.0
  2451 	 * @since 3.7.0
  2276 	 *
  2452 	 *
  2277 	 * @param int $space_allowed Upload quota in megabytes for the current blog.
  2453 	 * @param int $space_allowed Upload quota in megabytes for the current blog.
  2278 	 */
  2454 	 */
  2285  * @since 3.0.0
  2461  * @since 3.0.0
  2286  *
  2462  *
  2287  * @return int of upload space available in bytes
  2463  * @return int of upload space available in bytes
  2288  */
  2464  */
  2289 function get_upload_space_available() {
  2465 function get_upload_space_available() {
  2290 	$space_allowed = get_space_allowed() * 1024 * 1024;
  2466 	$allowed = get_space_allowed();
       
  2467 	if ( $allowed < 0 ) {
       
  2468 		$allowed = 0;
       
  2469 	}
       
  2470 	$space_allowed = $allowed * MB_IN_BYTES;
  2291 	if ( get_site_option( 'upload_space_check_disabled' ) )
  2471 	if ( get_site_option( 'upload_space_check_disabled' ) )
  2292 		return $space_allowed;
  2472 		return $space_allowed;
  2293 
  2473 
  2294 	$space_used = get_space_used() * 1024 * 1024;
  2474 	$space_used = get_space_used() * MB_IN_BYTES;
  2295 
  2475 
  2296 	if ( ( $space_allowed - $space_used ) <= 0 )
  2476 	if ( ( $space_allowed - $space_used ) <= 0 )
  2297 		return 0;
  2477 		return 0;
  2298 
  2478 
  2299 	return $space_allowed - $space_used;
  2479 	return $space_allowed - $space_used;
  2311 
  2491 
  2312 	return (bool) get_upload_space_available();
  2492 	return (bool) get_upload_space_available();
  2313 }
  2493 }
  2314 
  2494 
  2315 /**
  2495 /**
       
  2496  * Filters the maximum upload file size allowed, in bytes.
       
  2497  *
  2316  * @since 3.0.0
  2498  * @since 3.0.0
  2317  *
  2499  *
  2318  * @return int of upload size limit in bytes
  2500  * @param  int $size Upload size limit in bytes.
       
  2501  * @return int       Upload size limit in bytes.
  2319  */
  2502  */
  2320 function upload_size_limit_filter( $size ) {
  2503 function upload_size_limit_filter( $size ) {
  2321 	$fileupload_maxk = 1024 * get_site_option( 'fileupload_maxk', 1500 );
  2504 	$fileupload_maxk = KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 );
  2322 	if ( get_site_option( 'upload_space_check_disabled' ) )
  2505 	if ( get_site_option( 'upload_space_check_disabled' ) )
  2323 		return min( $size, $fileupload_maxk );
  2506 		return min( $size, $fileupload_maxk );
  2324 
  2507 
  2325 	return min( $size, $fileupload_maxk, get_upload_space_available() );
  2508 	return min( $size, $fileupload_maxk, get_upload_space_available() );
  2326 }
  2509 }
  2327 
  2510 
  2328 /**
  2511 /**
  2329  * Whether or not we have a large network.
  2512  * Whether or not we have a large network.
  2330  *
  2513  *
  2331  * The default criteria for a large network is either more than 10,000 users or more than 10,000 sites.
  2514  * The default criteria for a large network is either more than 10,000 users or more than 10,000 sites.
  2332  * Plugins can alter this criteria using the 'wp_is_large_network' filter.
  2515  * Plugins can alter this criteria using the {@see 'wp_is_large_network'} filter.
  2333  *
  2516  *
  2334  * @since 3.3.0
  2517  * @since 3.3.0
  2335  * @param string $using 'sites or 'users'. Default is 'sites'.
  2518  * @since 4.8.0 The $network_id parameter has been added.
       
  2519  *
       
  2520  * @param string   $using      'sites or 'users'. Default is 'sites'.
       
  2521  * @param int|null $network_id ID of the network. Default is the current network.
  2336  * @return bool True if the network meets the criteria for large. False otherwise.
  2522  * @return bool True if the network meets the criteria for large. False otherwise.
  2337  */
  2523  */
  2338 function wp_is_large_network( $using = 'sites' ) {
  2524 function wp_is_large_network( $using = 'sites', $network_id = null ) {
       
  2525 	$network_id = (int) $network_id;
       
  2526 	if ( ! $network_id ) {
       
  2527 		$network_id = get_current_network_id();
       
  2528 	}
       
  2529 
  2339 	if ( 'users' == $using ) {
  2530 	if ( 'users' == $using ) {
  2340 		$count = get_user_count();
  2531 		$count = get_user_count( $network_id );
  2341 		/**
  2532 		/**
  2342 		 * Filter whether the network is considered large.
  2533 		 * Filters whether the network is considered large.
  2343 		 *
  2534 		 *
  2344 		 * @since 3.3.0
  2535 		 * @since 3.3.0
       
  2536 		 * @since 4.8.0 The $network_id parameter has been added.
  2345 		 *
  2537 		 *
  2346 		 * @param bool   $is_large_network Whether the network has more than 10000 users or sites.
  2538 		 * @param bool   $is_large_network Whether the network has more than 10000 users or sites.
  2347 		 * @param string $component        The component to count. Accepts 'users', or 'sites'.
  2539 		 * @param string $component        The component to count. Accepts 'users', or 'sites'.
  2348 		 * @param int    $count            The count of items for the component.
  2540 		 * @param int    $count            The count of items for the component.
       
  2541 		 * @param int    $network_id       The ID of the network being checked.
  2349 		 */
  2542 		 */
  2350 		return apply_filters( 'wp_is_large_network', $count > 10000, 'users', $count );
  2543 		return apply_filters( 'wp_is_large_network', $count > 10000, 'users', $count, $network_id );
  2351 	}
  2544 	}
  2352 
  2545 
  2353 	$count = get_blog_count();
  2546 	$count = get_blog_count( $network_id );
  2354 	/** This filter is documented in wp-includes/ms-functions.php */
  2547 	/** This filter is documented in wp-includes/ms-functions.php */
  2355 	return apply_filters( 'wp_is_large_network', $count > 10000, 'sites', $count );
  2548 	return apply_filters( 'wp_is_large_network', $count > 10000, 'sites', $count, $network_id );
  2356 }
  2549 }
  2357 
  2550 
  2358 
  2551 /**
  2359 /**
  2552  * Retrieves a list of reserved site on a sub-directory Multisite installation.
  2360  * Return an array of sites for a network or networks.
  2553  *
  2361  *
  2554  * @since 4.4.0
  2362  * @since 3.7.0
  2555  *
  2363  *
  2556  * @return array $names Array of reserved subdirectory names.
  2364  * @param array $args {
  2557  */
  2365  *     Array of default arguments. Optional.
  2558 function get_subdirectory_reserved_names() {
  2366  *
  2559 	$names = array(
  2367  *     @type int|array $network_id A network ID or array of network IDs. Set to null to retrieve sites
  2560 		'page', 'comments', 'blog', 'files', 'feed', 'wp-admin',
  2368  *                                 from all networks. Defaults to current network ID.
  2561 		'wp-content', 'wp-includes', 'wp-json', 'embed'
  2369  *     @type int       $public     Retrieve public or non-public sites. Default null, for any.
       
  2370  *     @type int       $archived   Retrieve archived or non-archived sites. Default null, for any.
       
  2371  *     @type int       $mature     Retrieve mature or non-mature sites. Default null, for any.
       
  2372  *     @type int       $spam       Retrieve spam or non-spam sites. Default null, for any.
       
  2373  *     @type int       $deleted    Retrieve deleted or non-deleted sites. Default null, for any.
       
  2374  *     @type int       $limit      Number of sites to limit the query to. Default 100.
       
  2375  *     @type int       $offset     Exclude the first x sites. Used in combination with the $limit parameter. Default 0.
       
  2376  * }
       
  2377  * @return array An empty array if the install is considered "large" via wp_is_large_network(). Otherwise,
       
  2378  *               an associative array of site data arrays, each containing the site (network) ID, blog ID,
       
  2379  *               site domain and path, dates registered and modified, and the language ID. Also, boolean
       
  2380  *               values for whether the site is public, archived, mature, spam, and/or deleted.
       
  2381  */
       
  2382 function wp_get_sites( $args = array() ) {
       
  2383 	global $wpdb;
       
  2384 
       
  2385 	if ( wp_is_large_network() )
       
  2386 		return array();
       
  2387 
       
  2388 	$defaults = array(
       
  2389 		'network_id' => $wpdb->siteid,
       
  2390 		'public'     => null,
       
  2391 		'archived'   => null,
       
  2392 		'mature'     => null,
       
  2393 		'spam'       => null,
       
  2394 		'deleted'    => null,
       
  2395 		'limit'      => 100,
       
  2396 		'offset'     => 0,
       
  2397 	);
  2562 	);
  2398 
  2563 
  2399 	$args = wp_parse_args( $args, $defaults );
  2564 	/**
  2400 
  2565 	 * Filters reserved site names on a sub-directory Multisite installation.
  2401 	$query = "SELECT * FROM $wpdb->blogs WHERE 1=1 ";
  2566 	 *
  2402 
  2567 	 * @since 3.0.0
  2403 	if ( isset( $args['network_id'] ) && ( is_array( $args['network_id'] ) || is_numeric( $args['network_id'] ) ) ) {
  2568 	 * @since 4.4.0 'wp-admin', 'wp-content', 'wp-includes', 'wp-json', and 'embed' were added
  2404 		$network_ids = implode( ',', wp_parse_id_list( $args['network_id'] ) );
  2569 	 *              to the reserved names list.
  2405 		$query .= "AND site_id IN ($network_ids) ";
  2570 	 *
  2406 	}
  2571 	 * @param array $subdirectory_reserved_names Array of reserved names.
  2407 
  2572 	 */
  2408 	if ( isset( $args['public'] ) )
  2573 	return apply_filters( 'subdirectory_reserved_names', $names );
  2409 		$query .= $wpdb->prepare( "AND public = %d ", $args['public'] );
  2574 }
  2410 
  2575 
  2411 	if ( isset( $args['archived'] ) )
  2576 /**
  2412 		$query .= $wpdb->prepare( "AND archived = %d ", $args['archived'] );
  2577  * Send a confirmation request email when a change of network admin email address is attempted.
  2413 
  2578  *
  2414 	if ( isset( $args['mature'] ) )
  2579  * The new network admin address will not become active until confirmed.
  2415 		$query .= $wpdb->prepare( "AND mature = %d ", $args['mature'] );
  2580  *
  2416 
  2581  * @since 4.9.0
  2417 	if ( isset( $args['spam'] ) )
  2582  *
  2418 		$query .= $wpdb->prepare( "AND spam = %d ", $args['spam'] );
  2583  * @param string $old_value The old network admin email address.
  2419 
  2584  * @param string $value     The proposed new network admin email address.
  2420 	if ( isset( $args['deleted'] ) )
  2585  */
  2421 		$query .= $wpdb->prepare( "AND deleted = %d ", $args['deleted'] );
  2586 function update_network_option_new_admin_email( $old_value, $value ) {
  2422 
  2587 	if ( $value == get_site_option( 'admin_email' ) || ! is_email( $value ) ) {
  2423 	if ( isset( $args['limit'] ) && $args['limit'] ) {
  2588 		return;
  2424 		if ( isset( $args['offset'] ) && $args['offset'] )
  2589 	}
  2425 			$query .= $wpdb->prepare( "LIMIT %d , %d ", $args['offset'], $args['limit'] );
  2590 
  2426 		else
  2591 	$hash = md5( $value . time() . mt_rand() );
  2427 			$query .= $wpdb->prepare( "LIMIT %d ", $args['limit'] );
  2592 	$new_admin_email = array(
  2428 	}
  2593 		'hash'     => $hash,
  2429 
  2594 		'newemail' => $value,
  2430 	$site_results = $wpdb->get_results( $query, ARRAY_A );
  2595 	);
  2431 
  2596 	update_site_option( 'network_admin_hash', $new_admin_email );
  2432 	return $site_results;
  2597 
  2433 }
  2598 	$switched_locale = switch_to_locale( get_user_locale() );
       
  2599 
       
  2600 	/* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
       
  2601 	$email_text = __( 'Howdy ###USERNAME###,
       
  2602 
       
  2603 You recently requested to have the network admin email address on
       
  2604 your network changed.
       
  2605 
       
  2606 If this is correct, please click on the following link to change it:
       
  2607 ###ADMIN_URL###
       
  2608 
       
  2609 You can safely ignore and delete this email if you do not want to
       
  2610 take this action.
       
  2611 
       
  2612 This email has been sent to ###EMAIL###
       
  2613 
       
  2614 Regards,
       
  2615 All at ###SITENAME###
       
  2616 ###SITEURL###' );
       
  2617 
       
  2618 	/**
       
  2619 	 * Filters the text of the email sent when a change of network admin email address is attempted.
       
  2620 	 *
       
  2621 	 * The following strings have a special meaning and will get replaced dynamically:
       
  2622 	 * ###USERNAME###  The current user's username.
       
  2623 	 * ###ADMIN_URL### The link to click on to confirm the email change.
       
  2624 	 * ###EMAIL###     The proposed new network admin email address.
       
  2625 	 * ###SITENAME###  The name of the network.
       
  2626 	 * ###SITEURL###   The URL to the network.
       
  2627 	 *
       
  2628 	 * @since 4.9.0
       
  2629 	 *
       
  2630 	 * @param string $email_text      Text in the email.
       
  2631 	 * @param array  $new_admin_email {
       
  2632 	 *     Data relating to the new network admin email address.
       
  2633 	 *
       
  2634 	 *     @type string $hash     The secure hash used in the confirmation link URL.
       
  2635 	 *     @type string $newemail The proposed new network admin email address.
       
  2636 	 * }
       
  2637 	 */
       
  2638 	$content = apply_filters( 'new_network_admin_email_content', $email_text, $new_admin_email );
       
  2639 
       
  2640 	$current_user = wp_get_current_user();
       
  2641 	$content = str_replace( '###USERNAME###', $current_user->user_login, $content );
       
  2642 	$content = str_replace( '###ADMIN_URL###', esc_url( network_admin_url( 'settings.php?network_admin_hash=' . $hash ) ), $content );
       
  2643 	$content = str_replace( '###EMAIL###', $value, $content );
       
  2644 	$content = str_replace( '###SITENAME###', wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ), $content );
       
  2645 	$content = str_replace( '###SITEURL###', network_home_url(), $content );
       
  2646 
       
  2647 	wp_mail( $value, sprintf( __( '[%s] New Network Admin Email Address' ), wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ) ), $content );
       
  2648 
       
  2649 	if ( $switched_locale ) {
       
  2650 		restore_previous_locale();
       
  2651 	}
       
  2652 }
       
  2653 
       
  2654 /**
       
  2655  * Send an email to the old network admin email address when the network admin email address changes.
       
  2656  *
       
  2657  * @since 4.9.0
       
  2658  *
       
  2659  * @param string $option_name The relevant database option name.
       
  2660  * @param string $new_email   The new network admin email address.
       
  2661  * @param string $old_email   The old network admin email address.
       
  2662  * @param int    $network_id  ID of the network.
       
  2663  */
       
  2664 function wp_network_admin_email_change_notification( $option_name, $new_email, $old_email, $network_id ) {
       
  2665 	$send = true;
       
  2666 
       
  2667 	// Don't send the notification to the default 'admin_email' value.
       
  2668 	if ( 'you@example.com' === $old_email ) {
       
  2669 		$send = false;
       
  2670 	}
       
  2671 
       
  2672 	/**
       
  2673 	 * Filters whether to send the network admin email change notification email.
       
  2674 	 *
       
  2675 	 * @since 4.9.0
       
  2676 	 *
       
  2677 	 * @param bool   $send       Whether to send the email notification.
       
  2678 	 * @param string $old_email  The old network admin email address.
       
  2679 	 * @param string $new_email  The new network admin email address.
       
  2680 	 * @param int    $network_id ID of the network.
       
  2681 	 */
       
  2682 	$send = apply_filters( 'send_network_admin_email_change_email', $send, $old_email, $new_email, $network_id );
       
  2683 
       
  2684 	if ( ! $send ) {
       
  2685 		return;
       
  2686 	}
       
  2687 
       
  2688 	/* translators: Do not translate OLD_EMAIL, NEW_EMAIL, SITENAME, SITEURL: those are placeholders. */
       
  2689 	$email_change_text = __( 'Hi,
       
  2690 
       
  2691 This notice confirms that the network admin email address was changed on ###SITENAME###.
       
  2692 
       
  2693 The new network admin email address is ###NEW_EMAIL###.
       
  2694 
       
  2695 This email has been sent to ###OLD_EMAIL###
       
  2696 
       
  2697 Regards,
       
  2698 All at ###SITENAME###
       
  2699 ###SITEURL###' );
       
  2700 
       
  2701 	$email_change_email = array(
       
  2702 		'to'      => $old_email,
       
  2703 		/* translators: Network admin email change notification email subject. %s: Network title */
       
  2704 		'subject' => __( '[%s] Notice of Network Admin Email Change' ),
       
  2705 		'message' => $email_change_text,
       
  2706 		'headers' => '',
       
  2707 	);
       
  2708 	// get network name
       
  2709 	$network_name = wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES );
       
  2710 
       
  2711 	/**
       
  2712 	 * Filters the contents of the email notification sent when the network admin email address is changed.
       
  2713 	 *
       
  2714 	 * @since 4.9.0
       
  2715 	 *
       
  2716 	 * @param array $email_change_email {
       
  2717 	 *            Used to build wp_mail().
       
  2718 	 *
       
  2719 	 *            @type string $to      The intended recipient.
       
  2720 	 *            @type string $subject The subject of the email.
       
  2721 	 *            @type string $message The content of the email.
       
  2722 	 *                The following strings have a special meaning and will get replaced dynamically:
       
  2723 	 *                - ###OLD_EMAIL### The old network admin email address.
       
  2724 	 *                - ###NEW_EMAIL### The new network admin email address.
       
  2725 	 *                - ###SITENAME###  The name of the network.
       
  2726 	 *                - ###SITEURL###   The URL to the site.
       
  2727 	 *            @type string $headers Headers.
       
  2728 	 *        }
       
  2729 	 * @param string $old_email  The old network admin email address.
       
  2730 	 * @param string $new_email  The new network admin email address.
       
  2731 	 * @param int    $network_id ID of the network.
       
  2732 	 */
       
  2733 	$email_change_email = apply_filters( 'network_admin_email_change_email', $email_change_email, $old_email, $new_email, $network_id );
       
  2734 
       
  2735 	$email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email,    $email_change_email['message'] );
       
  2736 	$email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email,    $email_change_email['message'] );
       
  2737 	$email_change_email['message'] = str_replace( '###SITENAME###',  $network_name, $email_change_email['message'] );
       
  2738 	$email_change_email['message'] = str_replace( '###SITEURL###',   home_url(),    $email_change_email['message'] );
       
  2739 
       
  2740 	wp_mail( $email_change_email['to'], sprintf(
       
  2741 		$email_change_email['subject'],
       
  2742 		$network_name
       
  2743 	), $email_change_email['message'], $email_change_email['headers'] );
       
  2744 }