wp/wp-admin/includes/ms.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    26 		return $file;
    26 		return $file;
    27 
    27 
    28 	$space_left = get_upload_space_available();
    28 	$space_left = get_upload_space_available();
    29 
    29 
    30 	$file_size = filesize( $file['tmp_name'] );
    30 	$file_size = filesize( $file['tmp_name'] );
    31 	if ( $space_left < $file_size )
    31 	if ( $space_left < $file_size ) {
    32 		$file['error'] = sprintf( __( 'Not enough space to upload. %1$s KB needed.' ), number_format( ($file_size - $space_left) /1024 ) );
    32 		/* translators: 1: Required disk space in kilobytes */
    33 	if ( $file_size > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) )
    33 		$file['error'] = sprintf( __( 'Not enough space to upload. %1$s KB needed.' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) );
    34 		$file['error'] = sprintf(__('This file is too big. Files must be less than %1$s KB in size.'), get_site_option( 'fileupload_maxk', 1500 ) );
    34 	}
       
    35 
       
    36 	if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
       
    37 		/* translators: 1: Maximum allowed file size in kilobytes */
       
    38 		$file['error'] = sprintf( __( 'This file is too big. Files must be less than %1$s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) );
       
    39 	}
       
    40 
    35 	if ( upload_is_user_over_quota( false ) ) {
    41 	if ( upload_is_user_over_quota( false ) ) {
    36 		$file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
    42 		$file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
    37 	}
    43 	}
    38 	if ( $file['error'] != '0' && ! isset( $_POST['html-upload'] ) && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
    44 
       
    45 	if ( $file['error'] != '0' && ! isset( $_POST['html-upload'] ) && ! wp_doing_ajax() ) {
    39 		wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
    46 		wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
    40 	}
    47 	}
    41 
    48 
    42 	return $file;
    49 	return $file;
    43 }
    50 }
    44 add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' );
    51 
    45 
    52 /**
    46 /**
    53  * Delete a site.
    47  * Delete a blog.
    54  *
    48  *
    55  * @since 3.0.0
    49  * @since 3.0.0
    56  *
    50  *
    57  * @global wpdb $wpdb WordPress database abstraction object.
    51  * @param int  $blog_id Blog ID.
    58  *
    52  * @param bool $drop    True if blog's table should be dropped. Default is false.
    59  * @param int  $blog_id Site ID.
       
    60  * @param bool $drop    True if site's database tables should be dropped. Default is false.
    53  */
    61  */
    54 function wpmu_delete_blog( $blog_id, $drop = false ) {
    62 function wpmu_delete_blog( $blog_id, $drop = false ) {
    55 	global $wpdb;
    63 	global $wpdb;
    56 
    64 
    57 	$switch = false;
    65 	$switch = false;
    58 	if ( get_current_blog_id() != $blog_id ) {
    66 	if ( get_current_blog_id() != $blog_id ) {
    59 		$switch = true;
    67 		$switch = true;
    60 		switch_to_blog( $blog_id );
    68 		switch_to_blog( $blog_id );
    61 	}
    69 	}
    62 
    70 
    63 	$blog = get_blog_details( $blog_id );
    71 	$blog = get_site( $blog_id );
    64 	/**
    72 	/**
    65 	 * Fires before a blog is deleted.
    73 	 * Fires before a site is deleted.
    66 	 *
    74 	 *
    67 	 * @since MU
    75 	 * @since MU (3.0.0)
    68 	 *
    76 	 *
    69 	 * @param int  $blog_id The blog ID.
    77 	 * @param int  $blog_id The site ID.
    70 	 * @param bool $drop    True if blog's table should be dropped. Default is false.
    78 	 * @param bool $drop    True if site's table should be dropped. Default is false.
    71 	 */
    79 	 */
    72 	do_action( 'delete_blog', $blog_id, $drop );
    80 	do_action( 'delete_blog', $blog_id, $drop );
    73 
    81 
    74 	$users = get_users( array( 'blog_id' => $blog_id, 'fields' => 'ids' ) );
    82 	$users = get_users( array( 'blog_id' => $blog_id, 'fields' => 'ids' ) );
    75 
    83 
    80 		}
    88 		}
    81 	}
    89 	}
    82 
    90 
    83 	update_blog_status( $blog_id, 'deleted', 1 );
    91 	update_blog_status( $blog_id, 'deleted', 1 );
    84 
    92 
    85 	$current_site = get_current_site();
    93 	$current_network = get_network();
    86 
    94 
    87 	// If a full blog object is not available, do not destroy anything.
    95 	// If a full blog object is not available, do not destroy anything.
    88 	if ( $drop && ! $blog ) {
    96 	if ( $drop && ! $blog ) {
    89 		$drop = false;
    97 		$drop = false;
    90 	}
    98 	}
    91 
    99 
    92 	// Don't destroy the initial, main, or root blog.
   100 	// Don't destroy the initial, main, or root blog.
    93 	if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_site->path && $blog->domain == $current_site->domain ) ) ) {
   101 	if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_network->path && $blog->domain == $current_network->domain ) ) ) {
    94 		$drop = false;
   102 		$drop = false;
    95 	}
   103 	}
    96 
   104 
    97 	$upload_path = trim( get_option( 'upload_path' ) );
   105 	$upload_path = trim( get_option( 'upload_path' ) );
    98 
   106 
   100 	if ( $drop && get_site_option( 'ms_files_rewriting' ) && empty( $upload_path ) ) {
   108 	if ( $drop && get_site_option( 'ms_files_rewriting' ) && empty( $upload_path ) ) {
   101 		$drop = false;
   109 		$drop = false;
   102 	}
   110 	}
   103 
   111 
   104 	if ( $drop ) {
   112 	if ( $drop ) {
   105 		$uploads = wp_upload_dir();
   113 		$uploads = wp_get_upload_dir();
   106 
   114 
   107 		$tables = $wpdb->tables( 'blog' );
   115 		$tables = $wpdb->tables( 'blog' );
   108 		/**
   116 		/**
   109 		 * Filter the tables to drop when the blog is deleted.
   117 		 * Filters the tables to drop when the site is deleted.
   110 		 *
   118 		 *
   111 		 * @since MU
   119 		 * @since MU (3.0.0)
   112 		 *
   120 		 *
   113 		 * @param array $tables  The blog tables to be dropped.
   121 		 * @param array $tables  The site tables to be dropped.
   114 		 * @param int   $blog_id The ID of the blog to drop tables for.
   122 		 * @param int   $blog_id The ID of the site to drop tables for.
   115 		 */
   123 		 */
   116 		$drop_tables = apply_filters( 'wpmu_drop_tables', $tables, $blog_id );
   124 		$drop_tables = apply_filters( 'wpmu_drop_tables', $tables, $blog_id );
   117 
   125 
   118 		foreach ( (array) $drop_tables as $table ) {
   126 		foreach ( (array) $drop_tables as $table ) {
   119 			$wpdb->query( "DROP TABLE IF EXISTS `$table`" );
   127 			$wpdb->query( "DROP TABLE IF EXISTS `$table`" );
   120 		}
   128 		}
   121 
   129 
   122 		$wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) );
   130 		$wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) );
   123 
   131 
   124 		/**
   132 		/**
   125 		 * Filter the upload base directory to delete when the blog is deleted.
   133 		 * Filters the upload base directory to delete when the site is deleted.
   126 		 *
   134 		 *
   127 		 * @since MU
   135 		 * @since MU (3.0.0)
   128 		 *
   136 		 *
   129 		 * @param string $uploads['basedir'] Uploads path without subdirectory. @see wp_upload_dir()
   137 		 * @param string $uploads['basedir'] Uploads path without subdirectory. @see wp_upload_dir()
   130 		 * @param int    $blog_id            The blog ID.
   138 		 * @param int    $blog_id            The site ID.
   131 		 */
   139 		 */
   132 		$dir = apply_filters( 'wpmu_delete_blog_upload_dir', $uploads['basedir'], $blog_id );
   140 		$dir = apply_filters( 'wpmu_delete_blog_upload_dir', $uploads['basedir'], $blog_id );
   133 		$dir = rtrim( $dir, DIRECTORY_SEPARATOR );
   141 		$dir = rtrim( $dir, DIRECTORY_SEPARATOR );
   134 		$top_dir = $dir;
   142 		$top_dir = $dir;
   135 		$stack = array($dir);
   143 		$stack = array($dir);
   155 			}
   163 			}
   156 			$index++;
   164 			$index++;
   157 		}
   165 		}
   158 
   166 
   159 		$stack = array_reverse( $stack ); // Last added dirs are deepest
   167 		$stack = array_reverse( $stack ); // Last added dirs are deepest
   160 		foreach( (array) $stack as $dir ) {
   168 		foreach ( (array) $stack as $dir ) {
   161 			if ( $dir != $top_dir)
   169 			if ( $dir != $top_dir)
   162 			@rmdir( $dir );
   170 			@rmdir( $dir );
   163 		}
   171 		}
   164 
   172 
   165 		clean_blog_cache( $blog );
   173 		clean_blog_cache( $blog );
   166 	}
   174 	}
   167 
   175 
       
   176 	/**
       
   177 	 * Fires after the site is deleted from the network.
       
   178 	 *
       
   179 	 * @since 4.8.0
       
   180 	 *
       
   181 	 * @param int  $blog_id The site ID.
       
   182 	 * @param bool $drop    True if site's tables should be dropped. Default is false.
       
   183 	 */
       
   184 	do_action( 'deleted_blog', $blog_id, $drop );
       
   185 
   168 	if ( $switch )
   186 	if ( $switch )
   169 		restore_current_blog();
   187 		restore_current_blog();
   170 }
   188 }
   171 
   189 
   172 /**
   190 /**
   174  *
   192  *
   175  * @since 3.0.0
   193  * @since 3.0.0
   176  *
   194  *
   177  * @todo Merge with wp_delete_user() ?
   195  * @todo Merge with wp_delete_user() ?
   178  *
   196  *
       
   197  * @global wpdb $wpdb WordPress database abstraction object.
       
   198  *
   179  * @param int $id The user ID.
   199  * @param int $id The user ID.
   180  * @return bool True if the user was deleted, otherwise false.
   200  * @return bool True if the user was deleted, otherwise false.
   181  */
   201  */
   182 function wpmu_delete_user( $id ) {
   202 function wpmu_delete_user( $id ) {
   183 	global $wpdb;
   203 	global $wpdb;
   184 
   204 
       
   205 	if ( ! is_numeric( $id ) ) {
       
   206 		return false;
       
   207 	}
       
   208 
   185 	$id = (int) $id;
   209 	$id = (int) $id;
   186 	$user = new WP_User( $id );
   210 	$user = new WP_User( $id );
   187 
   211 
   188 	if ( !$user->exists() )
   212 	if ( !$user->exists() )
   189 		return false;
   213 		return false;
       
   214 
       
   215 	// Global super-administrators are protected, and cannot be deleted.
       
   216 	$_super_admins = get_super_admins();
       
   217 	if ( in_array( $user->user_login, $_super_admins, true ) ) {
       
   218 		return false;
       
   219 	}
       
   220 
   190 	/**
   221 	/**
   191 	 * Fires before a user is deleted from the network.
   222 	 * Fires before a user is deleted from the network.
   192 	 *
   223 	 *
   193 	 * @since MU
   224 	 * @since MU (3.0.0)
   194 	 *
   225 	 *
   195 	 * @param int $id ID of the user about to be deleted from the network.
   226 	 * @param int $id ID of the user about to be deleted from the network.
   196 	 */
   227 	 */
   197 	do_action( 'wpmu_delete_user', $id );
   228 	do_action( 'wpmu_delete_user', $id );
   198 
   229 
   227 	$wpdb->delete( $wpdb->users, array( 'ID' => $id ) );
   258 	$wpdb->delete( $wpdb->users, array( 'ID' => $id ) );
   228 
   259 
   229 	clean_user_cache( $user );
   260 	clean_user_cache( $user );
   230 
   261 
   231 	/** This action is documented in wp-admin/includes/user.php */
   262 	/** This action is documented in wp-admin/includes/user.php */
   232 	do_action( 'deleted_user', $id );
   263 	do_action( 'deleted_user', $id, null );
   233 
   264 
   234 	return true;
   265 	return true;
   235 }
   266 }
   236 
   267 
   237 /**
   268 /**
   238  * Sends an email when a site administrator email address is changed.
   269  * Check whether a site has used its allotted upload space.
   239  *
   270  *
   240  * @since 3.0.0
   271  * @since MU (3.0.0)
   241  *
       
   242  * @param string $old_value The old email address. Not currently used.
       
   243  * @param string $value     The new email address.
       
   244  */
       
   245 function update_option_new_admin_email( $old_value, $value ) {
       
   246 	if ( $value == get_option( 'admin_email' ) || !is_email( $value ) )
       
   247 		return;
       
   248 
       
   249 	$hash = md5( $value. time() .mt_rand() );
       
   250 	$new_admin_email = array(
       
   251 		'hash' => $hash,
       
   252 		'newemail' => $value
       
   253 	);
       
   254 	update_option( 'adminhash', $new_admin_email );
       
   255 
       
   256 	$email_text = __( 'Howdy ###USERNAME###,
       
   257 
       
   258 You recently requested to have the administration email address on
       
   259 your site changed.
       
   260 
       
   261 If this is correct, please click on the following link to change it:
       
   262 ###ADMIN_URL###
       
   263 
       
   264 You can safely ignore and delete this email if you do not want to
       
   265 take this action.
       
   266 
       
   267 This email has been sent to ###EMAIL###
       
   268 
       
   269 Regards,
       
   270 All at ###SITENAME###
       
   271 ###SITEURL###' );
       
   272 
       
   273 	/**
       
   274 	 * Filter the email text sent when the site admin email is changed.
       
   275 	 *
       
   276 	 * The following strings have a special meaning and will get replaced dynamically:
       
   277 	 * ###USERNAME###  The current user's username.
       
   278 	 * ###ADMIN_URL### The link to click on to confirm the email change.
       
   279 	 * ###EMAIL###     The new email.
       
   280 	 * ###SITENAME###  The name of the site.
       
   281 	 * ###SITEURL###   The URL to the site.
       
   282 	 *
       
   283 	 * @since MU
       
   284 	 *
       
   285 	 * @param string $email_text      Text in the email.
       
   286 	 * @param string $new_admin_email New admin email that the current administration email was changed to.
       
   287 	 */
       
   288 	$content = apply_filters( 'new_admin_email_content', $email_text, $new_admin_email );
       
   289 
       
   290 	$content = str_replace( '###USERNAME###', $current_user->user_login, $content );
       
   291 	$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'options.php?adminhash='.$hash ) ), $content );
       
   292 	$content = str_replace( '###EMAIL###', $value, $content );
       
   293 	$content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
       
   294 	$content = str_replace( '###SITEURL###', network_home_url(), $content );
       
   295 
       
   296 	wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );
       
   297 }
       
   298 add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
       
   299 add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
       
   300 
       
   301 /**
       
   302  * Sends an email when an email address change is requested.
       
   303  *
       
   304  * @since 3.0.0
       
   305  *
       
   306  * @global object $errors WP_Error object.
       
   307  * @global object $wpdb   WordPress database object.
       
   308  */
       
   309 function send_confirmation_on_profile_email() {
       
   310 	global $errors, $wpdb;
       
   311 	$current_user = wp_get_current_user();
       
   312 	if ( ! is_object($errors) )
       
   313 		$errors = new WP_Error();
       
   314 
       
   315 	if ( $current_user->ID != $_POST['user_id'] )
       
   316 		return false;
       
   317 
       
   318 	if ( $current_user->user_email != $_POST['email'] ) {
       
   319 		if ( !is_email( $_POST['email'] ) ) {
       
   320 			$errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address isn&#8217;t correct." ), array( 'form-field' => 'email' ) );
       
   321 			return;
       
   322 		}
       
   323 
       
   324 		if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM {$wpdb->users} WHERE user_email=%s", $_POST['email'] ) ) ) {
       
   325 			$errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address is already used." ), array( 'form-field' => 'email' ) );
       
   326 			delete_option( $current_user->ID . '_new_email' );
       
   327 			return;
       
   328 		}
       
   329 
       
   330 		$hash = md5( $_POST['email'] . time() . mt_rand() );
       
   331 		$new_user_email = array(
       
   332 				'hash' => $hash,
       
   333 				'newemail' => $_POST['email']
       
   334 				);
       
   335 		update_option( $current_user->ID . '_new_email', $new_user_email );
       
   336 
       
   337 		$email_text = __( 'Howdy ###USERNAME###,
       
   338 
       
   339 You recently requested to have the email address on your account changed.
       
   340 
       
   341 If this is correct, please click on the following link to change it:
       
   342 ###ADMIN_URL###
       
   343 
       
   344 You can safely ignore and delete this email if you do not want to
       
   345 take this action.
       
   346 
       
   347 This email has been sent to ###EMAIL###
       
   348 
       
   349 Regards,
       
   350 All at ###SITENAME###
       
   351 ###SITEURL###' );
       
   352 
       
   353 		/**
       
   354 		 * Filter the email text sent when a user changes emails.
       
   355 		 *
       
   356 		 * The following strings have a special meaning and will get replaced dynamically:
       
   357 		 * ###USERNAME###  The current user's username.
       
   358 		 * ###ADMIN_URL### The link to click on to confirm the email change.
       
   359 		 * ###EMAIL###     The new email.
       
   360 		 * ###SITENAME###  The name of the site.
       
   361 		 * ###SITEURL###   The URL to the site.
       
   362 		 *
       
   363 		 * @since MU
       
   364 		 *
       
   365 		 * @param string $email_text     Text in the email.
       
   366 		 * @param string $new_user_email New user email that the current user has changed to.
       
   367 		 */
       
   368 		$content = apply_filters( 'new_user_email_content', $email_text, $new_user_email );
       
   369 
       
   370 		$content = str_replace( '###USERNAME###', $current_user->user_login, $content );
       
   371 		$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail='.$hash ) ), $content );
       
   372 		$content = str_replace( '###EMAIL###', $_POST['email'], $content);
       
   373 		$content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
       
   374 		$content = str_replace( '###SITEURL###', network_home_url(), $content );
       
   375 
       
   376 		wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );
       
   377 		$_POST['email'] = $current_user->user_email;
       
   378 	}
       
   379 }
       
   380 add_action( 'personal_options_update', 'send_confirmation_on_profile_email' );
       
   381 
       
   382 /**
       
   383  * Adds an admin notice alerting the user to check for confirmation email
       
   384  * after email address change.
       
   385  *
       
   386  * @since 3.0.0
       
   387  */
       
   388 function new_user_email_admin_notice() {
       
   389 	if ( strpos( $_SERVER['PHP_SELF'], 'profile.php' ) && isset( $_GET['updated'] ) && $email = get_option( get_current_user_id() . '_new_email' ) )
       
   390 		echo "<div class='update-nag'>" . sprintf( __( "Your email address has not been updated yet. Please check your inbox at %s for a confirmation email." ), $email['newemail'] ) . "</div>";
       
   391 }
       
   392 add_action( 'admin_notices', 'new_user_email_admin_notice' );
       
   393 
       
   394 /**
       
   395  * Check whether a blog has used its allotted upload space.
       
   396  *
       
   397  * @since MU
       
   398  *
   272  *
   399  * @param bool $echo Optional. If $echo is set and the quota is exceeded, a warning message is echoed. Default is true.
   273  * @param bool $echo Optional. If $echo is set and the quota is exceeded, a warning message is echoed. Default is true.
   400  * @return bool True if user is over upload space quota, otherwise false.
   274  * @return bool True if user is over upload space quota, otherwise false.
   401  */
   275  */
   402 function upload_is_user_over_quota( $echo = true ) {
   276 function upload_is_user_over_quota( $echo = true ) {
   403 	if ( get_site_option( 'upload_space_check_disabled' ) )
   277 	if ( get_site_option( 'upload_space_check_disabled' ) )
   404 		return false;
   278 		return false;
   405 
   279 
   406 	$space_allowed = get_space_allowed();
   280 	$space_allowed = get_space_allowed();
   407 	if ( empty( $space_allowed ) || !is_numeric( $space_allowed ) )
   281 	if ( ! is_numeric( $space_allowed ) ) {
   408 		$space_allowed = 10; // Default space allowed is 10 MB
   282 		$space_allowed = 10; // Default space allowed is 10 MB
   409 
   283 	}
   410 	$space_used = get_space_used();
   284 	$space_used = get_space_used();
   411 
   285 
   412 	if ( ( $space_allowed - $space_used ) < 0 ) {
   286 	if ( ( $space_allowed - $space_used ) < 0 ) {
   413 		if ( $echo )
   287 		if ( $echo )
   414 			_e( 'Sorry, you have used your space allocation. Please delete some files to upload more files.' );
   288 			_e( 'Sorry, you have used your space allocation. Please delete some files to upload more files.' );
   417 		return false;
   291 		return false;
   418 	}
   292 	}
   419 }
   293 }
   420 
   294 
   421 /**
   295 /**
   422  * Displays the amount of disk space used by the current blog. Not used in core.
   296  * Displays the amount of disk space used by the current site. Not used in core.
   423  *
   297  *
   424  * @since MU
   298  * @since MU (3.0.0)
   425  */
   299  */
   426 function display_space_usage() {
   300 function display_space_usage() {
   427 	$space_allowed = get_space_allowed();
   301 	$space_allowed = get_space_allowed();
   428 	$space_used = get_space_used();
   302 	$space_used = get_space_used();
   429 
   303 
   430 	$percent_used = ( $space_used / $space_allowed ) * 100;
   304 	$percent_used = ( $space_used / $space_allowed ) * 100;
   431 
   305 
   432 	if ( $space_allowed > 1000 ) {
   306 	if ( $space_allowed > 1000 ) {
   433 		$space = number_format( $space_allowed / 1024 );
   307 		$space = number_format( $space_allowed / KB_IN_BYTES );
   434 		/* translators: Gigabytes */
   308 		/* translators: Gigabytes */
   435 		$space .= __( 'GB' );
   309 		$space .= __( 'GB' );
   436 	} else {
   310 	} else {
   437 		$space = number_format( $space_allowed );
   311 		$space = number_format( $space_allowed );
   438 		/* translators: Megabytes */
   312 		/* translators: Megabytes */
   439 		$space .= __( 'MB' );
   313 		$space .= __( 'MB' );
   440 	}
   314 	}
   441 	?>
   315 	?>
   442 	<strong><?php printf( __( 'Used: %1$s%% of %2$s' ), number_format( $percent_used ), $space ); ?></strong>
   316 	<strong><?php
       
   317 		/* translators: Storage space that's been used. 1: Percentage of used space, 2: Total space allowed in megabytes or gigabytes */
       
   318 		printf( __( 'Used: %1$s%% of %2$s' ), number_format( $percent_used ), $space );
       
   319 	?></strong>
   443 	<?php
   320 	<?php
   444 }
   321 }
   445 
   322 
   446 /**
   323 /**
   447  * Get the remaining upload space for this blog.
   324  * Get the remaining upload space for this site.
   448  *
   325  *
   449  * @since MU
   326  * @since MU (3.0.0)
   450  *
   327  *
   451  * @param int $size Current max size in bytes
   328  * @param int $size Current max size in bytes
   452  * @return int Max size in bytes
   329  * @return int Max size in bytes
   453  */
   330  */
   454 function fix_import_form_size( $size ) {
   331 function fix_import_form_size( $size ) {
   455 	if ( upload_is_user_over_quota( false ) == true )
   332 	if ( upload_is_user_over_quota( false ) ) {
   456 		return 0;
   333 		return 0;
   457 
   334 	}
   458 	$available = get_upload_space_available();
   335 	$available = get_upload_space_available();
   459 	return min( $size, $available );
   336 	return min( $size, $available );
   460 }
   337 }
   461 
   338 
   462 /**
   339 /**
   463  * Displays the edit blog upload space setting form on the Edit Blog screen.
   340  * Displays the site upload space quota setting form on the Edit Site Settings screen.
   464  *
   341  *
   465  * @since 3.0.0
   342  * @since 3.0.0
   466  *
   343  *
   467  * @param int $id The ID of the blog to display the setting for.
   344  * @param int $id The ID of the site to display the setting for.
   468  */
   345  */
   469 function upload_space_setting( $id ) {
   346 function upload_space_setting( $id ) {
   470 	switch_to_blog( $id );
   347 	switch_to_blog( $id );
   471 	$quota = get_option( 'blog_upload_space' );
   348 	$quota = get_option( 'blog_upload_space' );
   472 	restore_current_blog();
   349 	restore_current_blog();
   482 			<span id="blog-upload-space-desc"><span class="screen-reader-text"><?php _e( 'Size in megabytes' ); ?></span> <?php _e( 'MB (Leave blank for network default)' ); ?></span>
   359 			<span id="blog-upload-space-desc"><span class="screen-reader-text"><?php _e( 'Size in megabytes' ); ?></span> <?php _e( 'MB (Leave blank for network default)' ); ?></span>
   483 		</td>
   360 		</td>
   484 	</tr>
   361 	</tr>
   485 	<?php
   362 	<?php
   486 }
   363 }
   487 add_action( 'wpmueditblogaction', 'upload_space_setting' );
       
   488 
   364 
   489 /**
   365 /**
   490  * Update the status of a user in the database.
   366  * Update the status of a user in the database.
   491  *
   367  *
   492  * Used in core to mark a user as spam or "ham" (not spam) in Multisite.
   368  * Used in core to mark a user as spam or "ham" (not spam) in Multisite.
   493  *
   369  *
   494  * @since 3.0.0
   370  * @since 3.0.0
       
   371  *
       
   372  * @global wpdb $wpdb WordPress database abstraction object.
   495  *
   373  *
   496  * @param int    $id         The user ID.
   374  * @param int    $id         The user ID.
   497  * @param string $pref       The column in the wp_users table to update the user's status
   375  * @param string $pref       The column in the wp_users table to update the user's status
   498  *                           in (presumably user_status, spam, or deleted).
   376  *                           in (presumably user_status, spam, or deleted).
   499  * @param int    $value      The new status for the user.
   377  * @param int    $value      The new status for the user.
   502  */
   380  */
   503 function update_user_status( $id, $pref, $value, $deprecated = null ) {
   381 function update_user_status( $id, $pref, $value, $deprecated = null ) {
   504 	global $wpdb;
   382 	global $wpdb;
   505 
   383 
   506 	if ( null !== $deprecated )
   384 	if ( null !== $deprecated )
   507 		_deprecated_argument( __FUNCTION__, '3.1' );
   385 		_deprecated_argument( __FUNCTION__, '3.0.2' );
   508 
   386 
   509 	$wpdb->update( $wpdb->users, array( sanitize_key( $pref ) => $value ), array( 'ID' => $id ) );
   387 	$wpdb->update( $wpdb->users, array( sanitize_key( $pref ) => $value ), array( 'ID' => $id ) );
   510 
   388 
   511 	$user = new WP_User( $id );
   389 	$user = new WP_User( $id );
   512 	clean_user_cache( $user );
   390 	clean_user_cache( $user );
   578 		'sg' => 'Sango', 'sa' => 'Sanskrit', 'sr' => 'Serbian', 'hr' => 'Croatian', 'si' => 'Sinhala; Sinhalese', 'sk' => 'Slovak', 'sl' => 'Slovenian', 'se' => 'Northern Sami', 'sm' => 'Samoan', 'sn' => 'Shona', 'sd' => 'Sindhi', 'so' => 'Somali', 'st' => 'Sotho, Southern', 'es' => 'Spanish; Castilian', 'sc' => 'Sardinian', 'ss' => 'Swati', 'su' => 'Sundanese', 'sw' => 'Swahili',
   456 		'sg' => 'Sango', 'sa' => 'Sanskrit', 'sr' => 'Serbian', 'hr' => 'Croatian', 'si' => 'Sinhala; Sinhalese', 'sk' => 'Slovak', 'sl' => 'Slovenian', 'se' => 'Northern Sami', 'sm' => 'Samoan', 'sn' => 'Shona', 'sd' => 'Sindhi', 'so' => 'Somali', 'st' => 'Sotho, Southern', 'es' => 'Spanish; Castilian', 'sc' => 'Sardinian', 'ss' => 'Swati', 'su' => 'Sundanese', 'sw' => 'Swahili',
   579 		'sv' => 'Swedish', 'ty' => 'Tahitian', 'ta' => 'Tamil', 'tt' => 'Tatar', 'te' => 'Telugu', 'tg' => 'Tajik', 'tl' => 'Tagalog', 'th' => 'Thai', 'bo' => 'Tibetan', 'ti' => 'Tigrinya', 'to' => 'Tonga (Tonga Islands)', 'tn' => 'Tswana', 'ts' => 'Tsonga', 'tk' => 'Turkmen', 'tr' => 'Turkish', 'tw' => 'Twi', 'ug' => 'Uighur; Uyghur', 'uk' => 'Ukrainian', 'ur' => 'Urdu', 'uz' => 'Uzbek',
   457 		'sv' => 'Swedish', 'ty' => 'Tahitian', 'ta' => 'Tamil', 'tt' => 'Tatar', 'te' => 'Telugu', 'tg' => 'Tajik', 'tl' => 'Tagalog', 'th' => 'Thai', 'bo' => 'Tibetan', 'ti' => 'Tigrinya', 'to' => 'Tonga (Tonga Islands)', 'tn' => 'Tswana', 'ts' => 'Tsonga', 'tk' => 'Turkmen', 'tr' => 'Turkish', 'tw' => 'Twi', 'ug' => 'Uighur; Uyghur', 'uk' => 'Ukrainian', 'ur' => 'Urdu', 'uz' => 'Uzbek',
   580 		've' => 'Venda', 'vi' => 'Vietnamese', 'vo' => 'Volapük', 'cy' => 'Welsh','wa' => 'Walloon','wo' => 'Wolof', 'xh' => 'Xhosa', 'yi' => 'Yiddish', 'yo' => 'Yoruba', 'za' => 'Zhuang; Chuang', 'zu' => 'Zulu' );
   458 		've' => 'Venda', 'vi' => 'Vietnamese', 'vo' => 'Volapük', 'cy' => 'Welsh','wa' => 'Walloon','wo' => 'Wolof', 'xh' => 'Xhosa', 'yi' => 'Yiddish', 'yo' => 'Yoruba', 'za' => 'Zhuang; Chuang', 'zu' => 'Zulu' );
   581 
   459 
   582 	/**
   460 	/**
   583 	 * Filter the language codes.
   461 	 * Filters the language codes.
   584 	 *
   462 	 *
   585 	 * @since MU
   463 	 * @since MU (3.0.0)
   586 	 *
   464 	 *
   587 	 * @param array  $lang_codes Key/value pair of language codes where key is the short version.
   465 	 * @param array  $lang_codes Key/value pair of language codes where key is the short version.
   588 	 * @param string $code       A two-letter designation of the language.
   466 	 * @param string $code       A two-letter designation of the language.
   589 	 */
   467 	 */
   590 	$lang_codes = apply_filters( 'lang_codes', $lang_codes, $code );
   468 	$lang_codes = apply_filters( 'lang_codes', $lang_codes, $code );
   595  * Synchronize category and post tag slugs when global terms are enabled.
   473  * Synchronize category and post tag slugs when global terms are enabled.
   596  *
   474  *
   597  * @since 3.0.0
   475  * @since 3.0.0
   598  *
   476  *
   599  * @param object $term     The term.
   477  * @param object $term     The term.
   600  * @param string $taxonomy The taxonomy for $term. Should be 'category' or 'post_tag', as these are
   478  * @param string $taxonomy The taxonomy for `$term`. Should be 'category' or 'post_tag', as these are
   601  *                         the only taxonomies which are processed by this function; anything else
   479  *                         the only taxonomies which are processed by this function; anything else
   602  *                         will be returned untouched.
   480  *                         will be returned untouched.
   603  * @return object|array Returns `$term`, after filtering the 'slug' field with {@see sanitize_title()}
   481  * @return object|array Returns `$term`, after filtering the 'slug' field with sanitize_title()
   604  *                      if $taxonomy is 'category' or 'post_tag'.
   482  *                      if $taxonomy is 'category' or 'post_tag'.
   605  */
   483  */
   606 function sync_category_tag_slugs( $term, $taxonomy ) {
   484 function sync_category_tag_slugs( $term, $taxonomy ) {
   607 	if ( global_terms_enabled() && ( $taxonomy == 'category' || $taxonomy == 'post_tag' ) ) {
   485 	if ( global_terms_enabled() && ( $taxonomy == 'category' || $taxonomy == 'post_tag' ) ) {
   608 		if ( is_object( $term ) ) {
   486 		if ( is_object( $term ) ) {
   611 			$term['slug'] = sanitize_title( $term['name'] );
   489 			$term['slug'] = sanitize_title( $term['name'] );
   612 		}
   490 		}
   613 	}
   491 	}
   614 	return $term;
   492 	return $term;
   615 }
   493 }
   616 add_filter( 'get_term', 'sync_category_tag_slugs', 10, 2 );
       
   617 
   494 
   618 /**
   495 /**
   619  * Displays an access denied message when a user tries to view a site's dashboard they
   496  * Displays an access denied message when a user tries to view a site's dashboard they
   620  * do not have access to.
   497  * do not have access to.
   621  *
   498  *
   652 
   529 
   653 	$output .= '</table>';
   530 	$output .= '</table>';
   654 
   531 
   655 	wp_die( $output, 403 );
   532 	wp_die( $output, 403 );
   656 }
   533 }
   657 add_action( 'admin_page_access_denied', '_access_denied_splash', 99 );
       
   658 
   534 
   659 /**
   535 /**
   660  * Checks if the current user has permissions to import new users.
   536  * Checks if the current user has permissions to import new users.
   661  *
   537  *
   662  * @since 3.0.0
   538  * @since 3.0.0
   663  *
   539  *
   664  * @param string $permission A permission to be checked. Currently not used.
   540  * @param string $permission A permission to be checked. Currently not used.
   665  * @return bool True if the user has proper permissions, false if they do not.
   541  * @return bool True if the user has proper permissions, false if they do not.
   666  */
   542  */
   667 function check_import_new_users( $permission ) {
   543 function check_import_new_users( $permission ) {
   668 	if ( !is_super_admin() )
   544 	if ( ! current_user_can( 'manage_network_users' ) ) {
   669 		return false;
   545 		return false;
       
   546 	}
       
   547 
   670 	return true;
   548 	return true;
   671 }
   549 }
   672 add_filter( 'import_allow_create_users', 'check_import_new_users' );
       
   673 // See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too.
   550 // See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too.
   674 
   551 
   675 /**
   552 /**
   676  * Generates and displays a drop-down of available languages.
   553  * Generates and displays a drop-down of available languages.
   677  *
   554  *
   707 
   584 
   708 	// Order by name
   585 	// Order by name
   709 	uksort( $output, 'strnatcasecmp' );
   586 	uksort( $output, 'strnatcasecmp' );
   710 
   587 
   711 	/**
   588 	/**
   712 	 * Filter the languages available in the dropdown.
   589 	 * Filters the languages available in the dropdown.
   713 	 *
   590 	 *
   714 	 * @since MU
   591 	 * @since MU (3.0.0)
   715 	 *
   592 	 *
   716 	 * @param array $output     HTML output of the dropdown.
   593 	 * @param array $output     HTML output of the dropdown.
   717 	 * @param array $lang_files Available language files.
   594 	 * @param array $lang_files Available language files.
   718 	 * @param string $current   The current language code.
   595 	 * @param string $current   The current language code.
   719 	 */
   596 	 */
   725 /**
   602 /**
   726  * Displays an admin notice to upgrade all sites after a core upgrade.
   603  * Displays an admin notice to upgrade all sites after a core upgrade.
   727  *
   604  *
   728  * @since 3.0.0
   605  * @since 3.0.0
   729  *
   606  *
   730  * @global int $wp_db_version The version number of the database.
   607  * @global int    $wp_db_version The version number of the database.
       
   608  * @global string $pagenow
       
   609  *
       
   610  * @return false False if the current user is not a super admin.
   731  */
   611  */
   732 function site_admin_notice() {
   612 function site_admin_notice() {
   733 	global $wp_db_version;
   613 	global $wp_db_version, $pagenow;
   734 	if ( !is_super_admin() )
   614 
       
   615 	if ( ! current_user_can( 'upgrade_network' ) ) {
   735 		return false;
   616 		return false;
   736 	if ( get_site_option( 'wpmu_upgrade_site' ) != $wp_db_version )
   617 	}
       
   618 
       
   619 	if ( 'upgrade.php' == $pagenow ) {
       
   620 		return;
       
   621 	}
       
   622 
       
   623 	if ( get_site_option( 'wpmu_upgrade_site' ) != $wp_db_version ) {
   737 		echo "<div class='update-nag'>" . sprintf( __( 'Thank you for Updating! Please visit the <a href="%s">Upgrade Network</a> page to update all your sites.' ), esc_url( network_admin_url( 'upgrade.php' ) ) ) . "</div>";
   624 		echo "<div class='update-nag'>" . sprintf( __( 'Thank you for Updating! Please visit the <a href="%s">Upgrade Network</a> page to update all your sites.' ), esc_url( network_admin_url( 'upgrade.php' ) ) ) . "</div>";
   738 }
   625 	}
   739 add_action( 'admin_notices', 'site_admin_notice' );
   626 }
   740 add_action( 'network_admin_notices', 'site_admin_notice' );
       
   741 
   627 
   742 /**
   628 /**
   743  * Avoids a collision between a site slug and a permalink slug.
   629  * Avoids a collision between a site slug and a permalink slug.
   744  *
   630  *
   745  * In a subdirectory install this will make sure that a site and a post do not use the
   631  * In a subdirectory installation this will make sure that a site and a post do not use the
   746  * same subdirectory by checking for a site with the same name as a new post.
   632  * same subdirectory by checking for a site with the same name as a new post.
   747  *
   633  *
   748  * @since 3.0.0
   634  * @since 3.0.0
   749  *
   635  *
   750  * @param array $data    An array of post data.
   636  * @param array $data    An array of post data.
   770 	if ( $post_name != $data['post_name'] ) {
   656 	if ( $post_name != $data['post_name'] ) {
   771 		$data['post_name'] = $post_name;
   657 		$data['post_name'] = $post_name;
   772 	}
   658 	}
   773 	return $data;
   659 	return $data;
   774 }
   660 }
   775 add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 );
       
   776 
   661 
   777 /**
   662 /**
   778  * Handles the display of choosing a user's primary site.
   663  * Handles the display of choosing a user's primary site.
   779  *
   664  *
   780  * This displays the user's primary site and allows the user to choose
   665  * This displays the user's primary site and allows the user to choose
   794 		$primary_blog = get_user_meta( get_current_user_id(), 'primary_blog', true );
   679 		$primary_blog = get_user_meta( get_current_user_id(), 'primary_blog', true );
   795 		if ( count( $all_blogs ) > 1 ) {
   680 		if ( count( $all_blogs ) > 1 ) {
   796 			$found = false;
   681 			$found = false;
   797 			?>
   682 			?>
   798 			<select name="primary_blog" id="primary_blog">
   683 			<select name="primary_blog" id="primary_blog">
   799 				<?php foreach( (array) $all_blogs as $blog ) {
   684 				<?php foreach ( (array) $all_blogs as $blog ) {
   800 					if ( $primary_blog == $blog->userblog_id )
   685 					if ( $primary_blog == $blog->userblog_id )
   801 						$found = true;
   686 						$found = true;
   802 					?><option value="<?php echo $blog->userblog_id ?>"<?php selected( $primary_blog, $blog->userblog_id ); ?>><?php echo esc_url( get_home_url( $blog->userblog_id ) ) ?></option><?php
   687 					?><option value="<?php echo $blog->userblog_id ?>"<?php selected( $primary_blog, $blog->userblog_id ); ?>><?php echo esc_url( get_home_url( $blog->userblog_id ) ) ?></option><?php
   803 				} ?>
   688 				} ?>
   804 			</select>
   689 			</select>
   807 				$blog = reset( $all_blogs );
   692 				$blog = reset( $all_blogs );
   808 				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
   693 				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
   809 			}
   694 			}
   810 		} elseif ( count( $all_blogs ) == 1 ) {
   695 		} elseif ( count( $all_blogs ) == 1 ) {
   811 			$blog = reset( $all_blogs );
   696 			$blog = reset( $all_blogs );
   812 			echo $blog->domain;
   697 			echo esc_url( get_home_url( $blog->userblog_id ) );
   813 			if ( $primary_blog != $blog->userblog_id ) // Set the primary blog again if it's out of sync with blog list.
   698 			if ( $primary_blog != $blog->userblog_id ) // Set the primary blog again if it's out of sync with blog list.
   814 				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
   699 				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
   815 		} else {
   700 		} else {
   816 			echo "N/A";
   701 			echo "N/A";
   817 		}
   702 		}
   818 		?>
   703 		?>
   819 		</td>
   704 		</td>
   820 	</tr>
   705 	</tr>
   821 	<?php if ( in_array( get_site_option( 'registration' ), array( 'all', 'blog' ) ) ) : ?>
       
   822 		<tr>
       
   823 			<th scope="row" colspan="2" class="th-full">
       
   824 				<?php
       
   825 				/** This filter is documented in wp-login.php */
       
   826 				$sign_up_url = apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) );
       
   827 				?>
       
   828 				<a href="<?php echo esc_url( $sign_up_url ); ?>"><?php _e( 'Create a New Site' ); ?></a>
       
   829 			</th>
       
   830 		</tr>
       
   831 	<?php endif; ?>
       
   832 	</table>
   706 	</table>
   833 	<?php
   707 	<?php
   834 }
   708 }
   835 
   709 
   836 /**
   710 /**
   837  * Grants Super Admin privileges.
       
   838  *
       
   839  * @since 3.0.0
       
   840  *
       
   841  * @param int $user_id ID of the user to be granted Super Admin privileges.
       
   842  * @return bool True on success, false on failure. This can fail when the user is
       
   843  *              already a super admin or when the `$super_admins` global is defined.
       
   844  */
       
   845 function grant_super_admin( $user_id ) {
       
   846 	// If global super_admins override is defined, there is nothing to do here.
       
   847 	if ( isset( $GLOBALS['super_admins'] ) ) {
       
   848 		return false;
       
   849 	}
       
   850 
       
   851 	/**
       
   852 	 * Fires before the user is granted Super Admin privileges.
       
   853 	 *
       
   854 	 * @since 3.0.0
       
   855 	 *
       
   856 	 * @param int $user_id ID of the user that is about to be granted Super Admin privileges.
       
   857 	 */
       
   858 	do_action( 'grant_super_admin', $user_id );
       
   859 
       
   860 	// Directly fetch site_admins instead of using get_super_admins()
       
   861 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
       
   862 
       
   863 	$user = get_userdata( $user_id );
       
   864 	if ( $user && ! in_array( $user->user_login, $super_admins ) ) {
       
   865 		$super_admins[] = $user->user_login;
       
   866 		update_site_option( 'site_admins' , $super_admins );
       
   867 
       
   868 		/**
       
   869 		 * Fires after the user is granted Super Admin privileges.
       
   870 		 *
       
   871 		 * @since 3.0.0
       
   872 		 *
       
   873 		 * @param int $user_id ID of the user that was granted Super Admin privileges.
       
   874 		 */
       
   875 		do_action( 'granted_super_admin', $user_id );
       
   876 		return true;
       
   877 	}
       
   878 	return false;
       
   879 }
       
   880 
       
   881 /**
       
   882  * Revokes Super Admin privileges.
       
   883  *
       
   884  * @since 3.0.0
       
   885  *
       
   886  * @param int $user_id ID of the user Super Admin privileges to be revoked from.
       
   887  * @return bool True on success, false on failure. This can fail when the user's email
       
   888  *              is the network admin email or when the `$super_admins` global is defined.
       
   889  */
       
   890 function revoke_super_admin( $user_id ) {
       
   891 	// If global super_admins override is defined, there is nothing to do here.
       
   892 	if ( isset( $GLOBALS['super_admins'] ) ) {
       
   893 		return false;
       
   894 	}
       
   895 
       
   896 	/**
       
   897 	 * Fires before the user's Super Admin privileges are revoked.
       
   898 	 *
       
   899 	 * @since 3.0.0
       
   900 	 *
       
   901 	 * @param int $user_id ID of the user Super Admin privileges are being revoked from.
       
   902 	 */
       
   903 	do_action( 'revoke_super_admin', $user_id );
       
   904 
       
   905 	// Directly fetch site_admins instead of using get_super_admins()
       
   906 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
       
   907 
       
   908 	$user = get_userdata( $user_id );
       
   909 	if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) {
       
   910 		if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) {
       
   911 			unset( $super_admins[$key] );
       
   912 			update_site_option( 'site_admins', $super_admins );
       
   913 
       
   914 			/**
       
   915 			 * Fires after the user's Super Admin privileges are revoked.
       
   916 			 *
       
   917 			 * @since 3.0.0
       
   918 			 *
       
   919 			 * @param int $user_id ID of the user Super Admin privileges were revoked from.
       
   920 			 */
       
   921 			do_action( 'revoked_super_admin', $user_id );
       
   922 			return true;
       
   923 		}
       
   924 	}
       
   925 	return false;
       
   926 }
       
   927 
       
   928 /**
       
   929  * Whether or not we can edit this network from this page.
   711  * Whether or not we can edit this network from this page.
   930  *
   712  *
   931  * By default editing of network is restricted to the Network Admin for that `$site_id`
   713  * By default editing of network is restricted to the Network Admin for that `$network_id`.
   932  * this allows for this to be overridden.
   714  * This function allows for this to be overridden.
   933  *
   715  *
   934  * @since 3.1.0
   716  * @since 3.1.0
   935  *
   717  *
   936  * @param int $site_id The network/site ID to check.
   718  * @param int $network_id The network ID to check.
   937  * @return bool True if network can be edited, otherwise false.
   719  * @return bool True if network can be edited, otherwise false.
   938  */
   720  */
   939 function can_edit_network( $site_id ) {
   721 function can_edit_network( $network_id ) {
   940 	global $wpdb;
   722 	if ( $network_id == get_current_network_id() )
   941 
       
   942 	if ( $site_id == $wpdb->siteid )
       
   943 		$result = true;
   723 		$result = true;
   944 	else
   724 	else
   945 		$result = false;
   725 		$result = false;
   946 
   726 
   947 	/**
   727 	/**
   948 	 * Filter whether this network can be edited from this page.
   728 	 * Filters whether this network can be edited from this page.
   949 	 *
   729 	 *
   950 	 * @since 3.1.0
   730 	 * @since 3.1.0
   951 	 *
   731 	 *
   952 	 * @param bool $result  Whether the network can be edited from this page.
   732 	 * @param bool $result     Whether the network can be edited from this page.
   953 	 * @param int  $site_id The network/site ID to check.
   733 	 * @param int  $network_id The network ID to check.
   954 	 */
   734 	 */
   955 	return apply_filters( 'can_edit_network', $result, $site_id );
   735 	return apply_filters( 'can_edit_network', $result, $network_id );
   956 }
   736 }
   957 
   737 
   958 /**
   738 /**
   959  * Thickbox image paths for Network Admin.
   739  * Thickbox image paths for Network Admin.
   960  *
   740  *
   967 <script type="text/javascript">
   747 <script type="text/javascript">
   968 var tb_pathToImage = "<?php echo includes_url( 'js/thickbox/loadingAnimation.gif', 'relative' ); ?>";
   748 var tb_pathToImage = "<?php echo includes_url( 'js/thickbox/loadingAnimation.gif', 'relative' ); ?>";
   969 </script>
   749 </script>
   970 <?php
   750 <?php
   971 }
   751 }
       
   752 
       
   753 /**
       
   754  *
       
   755  * @param array $users
       
   756  */
       
   757 function confirm_delete_users( $users ) {
       
   758 	$current_user = wp_get_current_user();
       
   759 	if ( ! is_array( $users ) || empty( $users ) ) {
       
   760 		return false;
       
   761 	}
       
   762 	?>
       
   763 	<h1><?php esc_html_e( 'Users' ); ?></h1>
       
   764 
       
   765 	<?php if ( 1 == count( $users ) ) : ?>
       
   766 		<p><?php _e( 'You have chosen to delete the user from all networks and sites.' ); ?></p>
       
   767 	<?php else : ?>
       
   768 		<p><?php _e( 'You have chosen to delete the following users from all networks and sites.' ); ?></p>
       
   769 	<?php endif; ?>
       
   770 
       
   771 	<form action="users.php?action=dodelete" method="post">
       
   772 	<input type="hidden" name="dodelete" />
       
   773 	<?php
       
   774 	wp_nonce_field( 'ms-users-delete' );
       
   775 	$site_admins = get_super_admins();
       
   776 	$admin_out = '<option value="' . esc_attr( $current_user->ID ) . '">' . $current_user->user_login . '</option>'; ?>
       
   777 	<table class="form-table">
       
   778 	<?php foreach ( ( $allusers = (array) $_POST['allusers'] ) as $user_id ) {
       
   779 		if ( $user_id != '' && $user_id != '0' ) {
       
   780 			$delete_user = get_userdata( $user_id );
       
   781 
       
   782 			if ( ! current_user_can( 'delete_user', $delete_user->ID ) ) {
       
   783 				wp_die( sprintf( __( 'Warning! User %s cannot be deleted.' ), $delete_user->user_login ) );
       
   784 			}
       
   785 
       
   786 			if ( in_array( $delete_user->user_login, $site_admins ) ) {
       
   787 				wp_die( sprintf( __( 'Warning! User cannot be deleted. The user %s is a network administrator.' ), '<em>' . $delete_user->user_login . '</em>' ) );
       
   788 			}
       
   789 			?>
       
   790 			<tr>
       
   791 				<th scope="row"><?php echo $delete_user->user_login; ?>
       
   792 					<?php echo '<input type="hidden" name="user[]" value="' . esc_attr( $user_id ) . '" />' . "\n"; ?>
       
   793 				</th>
       
   794 			<?php $blogs = get_blogs_of_user( $user_id, true );
       
   795 
       
   796 			if ( ! empty( $blogs ) ) {
       
   797 				?>
       
   798 				<td><fieldset><p><legend><?php printf(
       
   799 					/* translators: user login */
       
   800 					__( 'What should be done with content owned by %s?' ),
       
   801 					'<em>' . $delete_user->user_login . '</em>'
       
   802 				); ?></legend></p>
       
   803 				<?php
       
   804 				foreach ( (array) $blogs as $key => $details ) {
       
   805 					$blog_users = get_users( array( 'blog_id' => $details->userblog_id, 'fields' => array( 'ID', 'user_login' ) ) );
       
   806 					if ( is_array( $blog_users ) && !empty( $blog_users ) ) {
       
   807 						$user_site = "<a href='" . esc_url( get_home_url( $details->userblog_id ) ) . "'>{$details->blogname}</a>";
       
   808 						$user_dropdown = '<label for="reassign_user" class="screen-reader-text">' . __( 'Select a user' ) . '</label>';
       
   809 						$user_dropdown .= "<select name='blog[$user_id][$key]' id='reassign_user'>";
       
   810 						$user_list = '';
       
   811 						foreach ( $blog_users as $user ) {
       
   812 							if ( ! in_array( $user->ID, $allusers ) ) {
       
   813 								$user_list .= "<option value='{$user->ID}'>{$user->user_login}</option>";
       
   814 							}
       
   815 						}
       
   816 						if ( '' == $user_list ) {
       
   817 							$user_list = $admin_out;
       
   818 						}
       
   819 						$user_dropdown .= $user_list;
       
   820 						$user_dropdown .= "</select>\n";
       
   821 						?>
       
   822 						<ul style="list-style:none;">
       
   823 							<li><?php printf( __( 'Site: %s' ), $user_site ); ?></li>
       
   824 							<li><label><input type="radio" id="delete_option0" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID ?>]" value="delete" checked="checked" />
       
   825 							<?php _e( 'Delete all content.' ); ?></label></li>
       
   826 							<li><label><input type="radio" id="delete_option1" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID ?>]" value="reassign" />
       
   827 							<?php _e( 'Attribute all content to:' ); ?></label>
       
   828 							<?php echo $user_dropdown; ?></li>
       
   829 						</ul>
       
   830 						<?php
       
   831 					}
       
   832 				}
       
   833 				echo "</fieldset></td></tr>";
       
   834 			} else {
       
   835 				?>
       
   836 				<td><fieldset><p><legend><?php _e( 'User has no sites or content and will be deleted.' ); ?></legend></p>
       
   837 			<?php } ?>
       
   838 			</tr>
       
   839 		<?php
       
   840 		}
       
   841 	}
       
   842 
       
   843 	?>
       
   844 	</table>
       
   845 	<?php
       
   846 	/** This action is documented in wp-admin/users.php */
       
   847 	do_action( 'delete_user_form', $current_user, $allusers );
       
   848 
       
   849 	if ( 1 == count( $users ) ) : ?>
       
   850 		<p><?php _e( 'Once you hit &#8220;Confirm Deletion&#8221;, the user will be permanently removed.' ); ?></p>
       
   851 	<?php else : ?>
       
   852 		<p><?php _e( 'Once you hit &#8220;Confirm Deletion&#8221;, these users will be permanently removed.' ); ?></p>
       
   853 	<?php endif;
       
   854 
       
   855 	submit_button( __('Confirm Deletion'), 'primary' );
       
   856 	?>
       
   857 	</form>
       
   858 	<?php
       
   859 	return true;
       
   860 }
       
   861 
       
   862 /**
       
   863  * Print JavaScript in the header on the Network Settings screen.
       
   864  *
       
   865  * @since 4.1.0
       
   866  */
       
   867 function network_settings_add_js() {
       
   868 ?>
       
   869 <script type="text/javascript">
       
   870 jQuery(document).ready( function($) {
       
   871 	var languageSelect = $( '#WPLANG' );
       
   872 	$( 'form' ).submit( function() {
       
   873 		// Don't show a spinner for English and installed languages,
       
   874 		// as there is nothing to download.
       
   875 		if ( ! languageSelect.find( 'option:selected' ).data( 'installed' ) ) {
       
   876 			$( '#submit', this ).after( '<span class="spinner language-install-spinner is-active" />' );
       
   877 		}
       
   878 	});
       
   879 });
       
   880 </script>
       
   881 <?php
       
   882 }
       
   883 
       
   884 /**
       
   885  * Outputs the HTML for a network's "Edit Site" tabular interface.
       
   886  *
       
   887  * @since 4.6.0
       
   888  *
       
   889  * @param $args {
       
   890  *     Optional. Array or string of Query parameters. Default empty array.
       
   891  *
       
   892  *     @type int    $blog_id  The site ID. Default is the current site.
       
   893  *     @type array  $links    The tabs to include with (label|url|cap) keys.
       
   894  *     @type string $selected The ID of the selected link.
       
   895  * }
       
   896  */
       
   897 function network_edit_site_nav( $args = array() ) {
       
   898 
       
   899 	/**
       
   900 	 * Filters the links that appear on site-editing network pages.
       
   901 	 *
       
   902 	 * Default links: 'site-info', 'site-users', 'site-themes', and 'site-settings'.
       
   903 	 *
       
   904 	 * @since 4.6.0
       
   905 	 *
       
   906 	 * @param array $links {
       
   907 	 *     An array of link data representing individual network admin pages.
       
   908 	 *
       
   909 	 *     @type array $link_slug {
       
   910 	 *         An array of information about the individual link to a page.
       
   911 	 *
       
   912 	 *         $type string $label Label to use for the link.
       
   913 	 *         $type string $url   URL, relative to `network_admin_url()` to use for the link.
       
   914 	 *         $type string $cap   Capability required to see the link.
       
   915 	 *     }
       
   916 	 * }
       
   917 	 */
       
   918 	$links = apply_filters( 'network_edit_site_nav_links', array(
       
   919 		'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php',     'cap' => 'manage_sites' ),
       
   920 		'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php',    'cap' => 'manage_sites' ),
       
   921 		'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php',   'cap' => 'manage_sites' ),
       
   922 		'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php', 'cap' => 'manage_sites' )
       
   923 	) );
       
   924 
       
   925 	// Parse arguments
       
   926 	$r = wp_parse_args( $args, array(
       
   927 		'blog_id'  => isset( $_GET['blog_id'] ) ? (int) $_GET['blog_id'] : 0,
       
   928 		'links'    => $links,
       
   929 		'selected' => 'site-info',
       
   930 	) );
       
   931 
       
   932 	// Setup the links array
       
   933 	$screen_links = array();
       
   934 
       
   935 	// Loop through tabs
       
   936 	foreach ( $r['links'] as $link_id => $link ) {
       
   937 
       
   938 		// Skip link if user can't access
       
   939 		if ( ! current_user_can( $link['cap'], $r['blog_id'] ) ) {
       
   940 			continue;
       
   941 		}
       
   942 
       
   943 		// Link classes
       
   944 		$classes = array( 'nav-tab' );
       
   945 
       
   946 		// Selected is set by the parent OR assumed by the $pagenow global
       
   947 		if ( $r['selected'] === $link_id || $link['url'] === $GLOBALS['pagenow'] ) {
       
   948 			$classes[] = 'nav-tab-active';
       
   949 		}
       
   950 
       
   951 		// Escape each class
       
   952 		$esc_classes = implode( ' ', $classes );
       
   953 
       
   954 		// Get the URL for this link
       
   955 		$url = add_query_arg( array( 'id' => $r['blog_id'] ), network_admin_url( $link['url'] ) );
       
   956 
       
   957 		// Add link to nav links
       
   958 		$screen_links[ $link_id ] = '<a href="' . esc_url( $url ) . '" id="' . esc_attr( $link_id ) . '" class="' . $esc_classes . '">' . esc_html( $link['label'] ) . '</a>';
       
   959 	}
       
   960 
       
   961 	// All done!
       
   962 	echo '<h2 class="nav-tab-wrapper wp-clearfix">';
       
   963 	echo implode( '', $screen_links );
       
   964 	echo '</h2>';
       
   965 }
       
   966 
       
   967 /**
       
   968  * Returns the arguments for the help tab on the Edit Site screens.
       
   969  *
       
   970  * @since 4.9.0
       
   971  *
       
   972  * @return array Help tab arguments.
       
   973  */
       
   974 function get_site_screen_help_tab_args() {
       
   975 	return array(
       
   976 		'id'      => 'overview',
       
   977 		'title'   => __('Overview'),
       
   978 		'content' =>
       
   979 			'<p>' . __('The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.') . '</p>' .
       
   980 			'<p>' . __('<strong>Info</strong> &mdash; The site URL is rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.') . '</p>' .
       
   981 			'<p>' . __('<strong>Users</strong> &mdash; This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.') . '</p>' .
       
   982 			'<p>' . sprintf( __('<strong>Themes</strong> &mdash; This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site&#8217;s Appearance menu. To enable a theme for the entire network, see the <a href="%s">Network Themes</a> screen.' ), network_admin_url( 'themes.php' ) ) . '</p>' .
       
   983 			'<p>' . __('<strong>Settings</strong> &mdash; This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.') . '</p>'
       
   984 	);
       
   985 }
       
   986 
       
   987 /**
       
   988  * Returns the content for the help sidebar on the Edit Site screens.
       
   989  *
       
   990  * @since 4.9.0
       
   991  *
       
   992  * @return string Help sidebar content.
       
   993  */
       
   994 function get_site_screen_help_sidebar_content() {
       
   995 	return '<p><strong>' . __('For more information:') . '</strong></p>' .
       
   996 		'<p>' . __('<a href="https://codex.wordpress.org/Network_Admin_Sites_Screen">Documentation on Site Management</a>') . '</p>' .
       
   997 		'<p>' . __('<a href="https://wordpress.org/support/forum/multisite/">Support Forums</a>') . '</p>';
       
   998 }