web/wp-admin/includes/ms.php
changeset 194 32102edaa81b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
       
     1 <?php
       
     2 /**
       
     3  * Multisite administration functions.
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage Multisite
       
     7  * @since 3.0.0
       
     8  */
       
     9 
       
    10 /**
       
    11  * Determine if uploaded file exceeds space quota.
       
    12  *
       
    13  * @since 3.0.0
       
    14  *
       
    15  * @param array $file $_FILES array for a given file.
       
    16  * @return array $_FILES array with 'error' key set if file exceeds quota. 'error' is empty otherwise.
       
    17  */
       
    18 function check_upload_size( $file ) {
       
    19 	if ( get_site_option( 'upload_space_check_disabled' ) )
       
    20 		return $file;
       
    21 
       
    22 	if ( $file['error'] != '0' ) // there's already an error
       
    23 		return $file;
       
    24 
       
    25 	if ( defined( 'WP_IMPORTING' ) )
       
    26 		return $file;
       
    27 
       
    28 	$space_allowed = 1048576 * get_space_allowed();
       
    29 	$space_used = get_dirsize( BLOGUPLOADDIR );
       
    30 	$space_left = $space_allowed - $space_used;
       
    31 	$file_size = filesize( $file['tmp_name'] );
       
    32 	if ( $space_left < $file_size )
       
    33 		$file['error'] = sprintf( __( 'Not enough space to upload. %1$s KB needed.' ), number_format( ($file_size - $space_left) /1024 ) );
       
    34 	if ( $file_size > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) )
       
    35 		$file['error'] = sprintf(__('This file is too big. Files must be less than %1$s KB in size.'), get_site_option( 'fileupload_maxk', 1500 ) );
       
    36 	if ( upload_is_user_over_quota( false ) ) {
       
    37 		$file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
       
    38 	}
       
    39 	if ( $file['error'] != '0' && !isset($_POST['html-upload']) )
       
    40 		wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
       
    41 
       
    42 	return $file;
       
    43 }
       
    44 add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' );
       
    45 
       
    46 /**
       
    47  * Delete a blog
       
    48  *
       
    49  * @since 3.0.0
       
    50  *
       
    51  * @param int $blog_id Blog ID
       
    52  * @param bool $drop True if blog's table should be dropped. Default is false.
       
    53  * @return void
       
    54  */
       
    55 function wpmu_delete_blog( $blog_id, $drop = false ) {
       
    56 	global $wpdb, $current_site;
       
    57 
       
    58 	$switch = false;
       
    59 	if ( $blog_id != $wpdb->blogid ) {
       
    60 		$switch = true;
       
    61 		switch_to_blog( $blog_id );
       
    62 		$blog = get_blog_details( $blog_id );
       
    63 	} else {
       
    64 		$blog = $GLOBALS['current_blog'];
       
    65 	}
       
    66 
       
    67 	do_action( 'delete_blog', $blog_id, $drop );
       
    68 
       
    69 	$users = get_users( array( 'blog_id' => $blog_id, 'fields' => 'ids' ) );
       
    70 
       
    71 	// Remove users from this blog.
       
    72 	if ( ! empty( $users ) ) {
       
    73 		foreach ( $users as $user_id ) {
       
    74 			remove_user_from_blog( $user_id, $blog_id );
       
    75 		}
       
    76 	}
       
    77 
       
    78 	update_blog_status( $blog_id, 'deleted', 1 );
       
    79 
       
    80 	// Don't destroy the initial, main, or root blog.
       
    81 	if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_site->path && $blog->domain == $current_site->domain ) ) )
       
    82 		$drop = false;
       
    83 
       
    84 	if ( $drop ) {
       
    85 
       
    86 		$drop_tables = apply_filters( 'wpmu_drop_tables', $wpdb->tables( 'blog' ) );
       
    87 
       
    88 		foreach ( (array) $drop_tables as $table ) {
       
    89 			$wpdb->query( "DROP TABLE IF EXISTS `$table`" );
       
    90 		}
       
    91 
       
    92 		$wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) );
       
    93 
       
    94 		$dir = apply_filters( 'wpmu_delete_blog_upload_dir', WP_CONTENT_DIR . "/blogs.dir/{$blog_id}/files/", $blog_id );
       
    95 		$dir = rtrim( $dir, DIRECTORY_SEPARATOR );
       
    96 		$top_dir = $dir;
       
    97 		$stack = array($dir);
       
    98 		$index = 0;
       
    99 
       
   100 		while ( $index < count( $stack ) ) {
       
   101 			# Get indexed directory from stack
       
   102 			$dir = $stack[$index];
       
   103 
       
   104 			$dh = @opendir( $dir );
       
   105 			if ( $dh ) {
       
   106 				while ( ( $file = @readdir( $dh ) ) !== false ) {
       
   107 					if ( $file == '.' || $file == '..' )
       
   108 						continue;
       
   109 
       
   110 					if ( @is_dir( $dir . DIRECTORY_SEPARATOR . $file ) )
       
   111 						$stack[] = $dir . DIRECTORY_SEPARATOR . $file;
       
   112 					else if ( @is_file( $dir . DIRECTORY_SEPARATOR . $file ) )
       
   113 						@unlink( $dir . DIRECTORY_SEPARATOR . $file );
       
   114 				}
       
   115 			}
       
   116 			$index++;
       
   117 		}
       
   118 
       
   119 		$stack = array_reverse( $stack ); // Last added dirs are deepest
       
   120 		foreach( (array) $stack as $dir ) {
       
   121 			if ( $dir != $top_dir)
       
   122 			@rmdir( $dir );
       
   123 		}
       
   124 	}
       
   125 
       
   126 	if ( $switch )
       
   127 		restore_current_blog();
       
   128 }
       
   129 
       
   130 // @todo Merge with wp_delete_user() ?
       
   131 function wpmu_delete_user( $id ) {
       
   132 	global $wpdb;
       
   133 
       
   134 	$id = (int) $id;
       
   135 	$user = new WP_User( $id );
       
   136 
       
   137 	do_action( 'wpmu_delete_user', $id );
       
   138 
       
   139 	$blogs = get_blogs_of_user( $id );
       
   140 
       
   141 	if ( ! empty( $blogs ) ) {
       
   142 		foreach ( $blogs as $blog ) {
       
   143 			switch_to_blog( $blog->userblog_id );
       
   144 			remove_user_from_blog( $id, $blog->userblog_id );
       
   145 
       
   146 			$post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) );
       
   147 			foreach ( (array) $post_ids as $post_id ) {
       
   148 				wp_delete_post( $post_id );
       
   149 			}
       
   150 
       
   151 			// Clean links
       
   152 			$link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) );
       
   153 
       
   154 			if ( $link_ids ) {
       
   155 				foreach ( $link_ids as $link_id )
       
   156 					wp_delete_link( $link_id );
       
   157 			}
       
   158 
       
   159 			restore_current_blog();
       
   160 		}
       
   161 	}
       
   162 
       
   163 	$meta = $wpdb->get_col( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d", $id ) );
       
   164 	foreach ( $meta as $mid )
       
   165 		delete_metadata_by_mid( 'user', $mid );
       
   166 
       
   167 	$wpdb->delete( $wpdb->users, array( 'ID' => $id ) );
       
   168 
       
   169 	clean_user_cache( $user );
       
   170 
       
   171 	// allow for commit transaction
       
   172 	do_action( 'deleted_user', $id );
       
   173 
       
   174 	return true;
       
   175 }
       
   176 
       
   177 function update_option_new_admin_email( $old_value, $value ) {
       
   178 	$email = get_option( 'admin_email' );
       
   179 	if ( $value == get_option( 'admin_email' ) || !is_email( $value ) )
       
   180 		return;
       
   181 
       
   182 	$hash = md5( $value. time() .mt_rand() );
       
   183 	$new_admin_email = array(
       
   184 		'hash' => $hash,
       
   185 		'newemail' => $value
       
   186 	);
       
   187 	update_option( 'adminhash', $new_admin_email );
       
   188 
       
   189 	$content = apply_filters( 'new_admin_email_content', __( "Dear user,
       
   190 
       
   191 You recently requested to have the administration email address on
       
   192 your site changed.
       
   193 If this is correct, please click on the following link to change it:
       
   194 ###ADMIN_URL###
       
   195 
       
   196 You can safely ignore and delete this email if you do not want to
       
   197 take this action.
       
   198 
       
   199 This email has been sent to ###EMAIL###
       
   200 
       
   201 Regards,
       
   202 All at ###SITENAME###
       
   203 ###SITEURL### "), $new_admin_email );
       
   204 
       
   205 	$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'options.php?adminhash='.$hash ) ), $content );
       
   206 	$content = str_replace( '###EMAIL###', $value, $content );
       
   207 	$content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
       
   208 	$content = str_replace( '###SITEURL###', network_home_url(), $content );
       
   209 
       
   210 	wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), get_option( 'blogname' ) ), $content );
       
   211 }
       
   212 add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
       
   213 add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
       
   214 
       
   215 function send_confirmation_on_profile_email() {
       
   216 	global $errors, $wpdb;
       
   217 	$current_user = wp_get_current_user();
       
   218 	if ( ! is_object($errors) )
       
   219 		$errors = new WP_Error();
       
   220 
       
   221 	if ( $current_user->ID != $_POST['user_id'] )
       
   222 		return false;
       
   223 
       
   224 	if ( $current_user->user_email != $_POST['email'] ) {
       
   225 		if ( !is_email( $_POST['email'] ) ) {
       
   226 			$errors->add( 'user_email', __( "<strong>ERROR</strong>: The e-mail address isn't correct." ), array( 'form-field' => 'email' ) );
       
   227 			return;
       
   228 		}
       
   229 
       
   230 		if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM {$wpdb->users} WHERE user_email=%s", $_POST['email'] ) ) ) {
       
   231 			$errors->add( 'user_email', __( "<strong>ERROR</strong>: The e-mail address is already used." ), array( 'form-field' => 'email' ) );
       
   232 			delete_option( $current_user->ID . '_new_email' );
       
   233 			return;
       
   234 		}
       
   235 
       
   236 		$hash = md5( $_POST['email'] . time() . mt_rand() );
       
   237 		$new_user_email = array(
       
   238 				'hash' => $hash,
       
   239 				'newemail' => $_POST['email']
       
   240 				);
       
   241 		update_option( $current_user->ID . '_new_email', $new_user_email );
       
   242 
       
   243 		$content = apply_filters( 'new_user_email_content', __( "Dear user,
       
   244 
       
   245 You recently requested to have the email address on your account changed.
       
   246 If this is correct, please click on the following link to change it:
       
   247 ###ADMIN_URL###
       
   248 
       
   249 You can safely ignore and delete this email if you do not want to
       
   250 take this action.
       
   251 
       
   252 This email has been sent to ###EMAIL###
       
   253 
       
   254 Regards,
       
   255 All at ###SITENAME###
       
   256 ###SITEURL###" ), $new_user_email );
       
   257 
       
   258 		$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail='.$hash ) ), $content );
       
   259 		$content = str_replace( '###EMAIL###', $_POST['email'], $content);
       
   260 		$content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
       
   261 		$content = str_replace( '###SITEURL###', network_home_url(), $content );
       
   262 
       
   263 		wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), get_option( 'blogname' ) ), $content );
       
   264 		$_POST['email'] = $current_user->user_email;
       
   265 	}
       
   266 }
       
   267 add_action( 'personal_options_update', 'send_confirmation_on_profile_email' );
       
   268 
       
   269 function new_user_email_admin_notice() {
       
   270 	if ( strpos( $_SERVER['PHP_SELF'], 'profile.php' ) && isset( $_GET['updated'] ) && $email = get_option( get_current_user_id() . '_new_email' ) )
       
   271 		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>";
       
   272 }
       
   273 add_action( 'admin_notices', 'new_user_email_admin_notice' );
       
   274 
       
   275 /**
       
   276  * Determines if there is any upload space left in the current blog's quota.
       
   277  *
       
   278  * @since 3.0.0
       
   279  * @return bool True if space is available, false otherwise.
       
   280  */
       
   281 function is_upload_space_available() {
       
   282 	if ( get_site_option( 'upload_space_check_disabled' ) )
       
   283 		return true;
       
   284 
       
   285 	if ( !( $space_allowed = get_upload_space_available() ) )
       
   286 		return false;
       
   287 
       
   288 	return true;
       
   289 }
       
   290 
       
   291 /**
       
   292  * @since 3.0.0
       
   293  *
       
   294  * @return int of upload size limit in bytes
       
   295  */
       
   296 function upload_size_limit_filter( $size ) {
       
   297 	$fileupload_maxk = 1024 * get_site_option( 'fileupload_maxk', 1500 );
       
   298 	if ( get_site_option( 'upload_space_check_disabled' ) )
       
   299 		return min( $size, $fileupload_maxk );
       
   300 
       
   301 	return min( $size, $fileupload_maxk, get_upload_space_available() );
       
   302 }
       
   303 /**
       
   304  * Determines if there is any upload space left in the current blog's quota.
       
   305  *
       
   306  * @return int of upload space available in bytes
       
   307  */
       
   308 function get_upload_space_available() {
       
   309 	$space_allowed = get_space_allowed() * 1024 * 1024;
       
   310 	if ( get_site_option( 'upload_space_check_disabled' ) )
       
   311 		return $space_allowed;
       
   312 
       
   313 	$dir_name = trailingslashit( BLOGUPLOADDIR );
       
   314 	if ( !( is_dir( $dir_name) && is_readable( $dir_name ) ) )
       
   315 		return $space_allowed;
       
   316 
       
   317   	$dir = dir( $dir_name );
       
   318    	$size = 0;
       
   319 
       
   320 	while ( $file = $dir->read() ) {
       
   321 		if ( $file != '.' && $file != '..' ) {
       
   322 			if ( is_dir( $dir_name . $file) ) {
       
   323 				$size += get_dirsize( $dir_name . $file );
       
   324 			} else {
       
   325 				$size += filesize( $dir_name . $file );
       
   326 			}
       
   327 		}
       
   328 	}
       
   329 	$dir->close();
       
   330 
       
   331 	if ( ( $space_allowed - $size ) <= 0 )
       
   332 		return 0;
       
   333 
       
   334 	return $space_allowed - $size;
       
   335 }
       
   336 
       
   337 /**
       
   338  * Returns the upload quota for the current blog.
       
   339  *
       
   340  * @return int Quota
       
   341  */
       
   342 function get_space_allowed() {
       
   343 	$space_allowed = get_option( 'blog_upload_space' );
       
   344 
       
   345 	if ( ! is_numeric( $space_allowed ) )
       
   346 		$space_allowed = get_site_option( 'blog_upload_space' );
       
   347 
       
   348 	if ( empty( $space_allowed ) || ! is_numeric( $space_allowed ) )
       
   349 		$space_allowed = 50;
       
   350 
       
   351 	return $space_allowed;
       
   352 }
       
   353 
       
   354 function display_space_usage() {
       
   355 	$space = get_space_allowed();
       
   356 	$used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024;
       
   357 
       
   358 	$percentused = ( $used / $space ) * 100;
       
   359 
       
   360 	if ( $space > 1000 ) {
       
   361 		$space = number_format( $space / 1024 );
       
   362 		/* translators: Gigabytes */
       
   363 		$space .= __( 'GB' );
       
   364 	} else {
       
   365 		/* translators: Megabytes */
       
   366 		$space .= __( 'MB' );
       
   367 	}
       
   368 	?>
       
   369 	<strong><?php printf( __( 'Used: %1s%% of %2s' ), number_format( $percentused ), $space ); ?></strong>
       
   370 	<?php
       
   371 }
       
   372 
       
   373 // Edit blog upload space setting on Edit Blog page
       
   374 function upload_space_setting( $id ) {
       
   375 	$quota = get_blog_option( $id, 'blog_upload_space' );
       
   376 	if ( !$quota )
       
   377 		$quota = '';
       
   378 
       
   379 	?>
       
   380 	<tr>
       
   381 		<th><?php _e( 'Site Upload Space Quota '); ?></th>
       
   382 		<td><input type="number" step="1" min="0" style="width: 100px" name="option[blog_upload_space]" value="<?php echo $quota; ?>" /> <?php _e( 'MB (Leave blank for network default)' ); ?></td>
       
   383 	</tr>
       
   384 	<?php
       
   385 }
       
   386 add_action( 'wpmueditblogaction', 'upload_space_setting' );
       
   387 
       
   388 function update_user_status( $id, $pref, $value, $deprecated = null ) {
       
   389 	global $wpdb;
       
   390 
       
   391 	if ( null !== $deprecated )
       
   392 		_deprecated_argument( __FUNCTION__, '3.1' );
       
   393 
       
   394 	$wpdb->update( $wpdb->users, array( $pref => $value ), array( 'ID' => $id ) );
       
   395 
       
   396 	$user = new WP_User( $id );
       
   397 	clean_user_cache( $user );
       
   398 
       
   399 	if ( $pref == 'spam' ) {
       
   400 		if ( $value == 1 )
       
   401 			do_action( 'make_spam_user', $id );
       
   402 		else
       
   403 			do_action( 'make_ham_user', $id );
       
   404 	}
       
   405 
       
   406 	return $value;
       
   407 }
       
   408 
       
   409 function refresh_user_details( $id ) {
       
   410 	$id = (int) $id;
       
   411 
       
   412 	if ( !$user = get_userdata( $id ) )
       
   413 		return false;
       
   414 
       
   415 	clean_user_cache( $user );
       
   416 
       
   417 	return $id;
       
   418 }
       
   419 
       
   420 function format_code_lang( $code = '' ) {
       
   421 	$code = strtolower( substr( $code, 0, 2 ) );
       
   422 	$lang_codes = array(
       
   423 		'aa' => 'Afar', 'ab' => 'Abkhazian', 'af' => 'Afrikaans', 'ak' => 'Akan', 'sq' => 'Albanian', 'am' => 'Amharic', 'ar' => 'Arabic', 'an' => 'Aragonese', 'hy' => 'Armenian', 'as' => 'Assamese', 'av' => 'Avaric', 'ae' => 'Avestan', 'ay' => 'Aymara', 'az' => 'Azerbaijani', 'ba' => 'Bashkir', 'bm' => 'Bambara', 'eu' => 'Basque', 'be' => 'Belarusian', 'bn' => 'Bengali',
       
   424 		'bh' => 'Bihari', 'bi' => 'Bislama', 'bs' => 'Bosnian', 'br' => 'Breton', 'bg' => 'Bulgarian', 'my' => 'Burmese', 'ca' => 'Catalan; Valencian', 'ch' => 'Chamorro', 'ce' => 'Chechen', 'zh' => 'Chinese', 'cu' => 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic', 'cv' => 'Chuvash', 'kw' => 'Cornish', 'co' => 'Corsican', 'cr' => 'Cree',
       
   425 		'cs' => 'Czech', 'da' => 'Danish', 'dv' => 'Divehi; Dhivehi; Maldivian', 'nl' => 'Dutch; Flemish', 'dz' => 'Dzongkha', 'en' => 'English', 'eo' => 'Esperanto', 'et' => 'Estonian', 'ee' => 'Ewe', 'fo' => 'Faroese', 'fj' => 'Fijjian', 'fi' => 'Finnish', 'fr' => 'French', 'fy' => 'Western Frisian', 'ff' => 'Fulah', 'ka' => 'Georgian', 'de' => 'German', 'gd' => 'Gaelic; Scottish Gaelic',
       
   426 		'ga' => 'Irish', 'gl' => 'Galician', 'gv' => 'Manx', 'el' => 'Greek, Modern', 'gn' => 'Guarani', 'gu' => 'Gujarati', 'ht' => 'Haitian; Haitian Creole', 'ha' => 'Hausa', 'he' => 'Hebrew', 'hz' => 'Herero', 'hi' => 'Hindi', 'ho' => 'Hiri Motu', 'hu' => 'Hungarian', 'ig' => 'Igbo', 'is' => 'Icelandic', 'io' => 'Ido', 'ii' => 'Sichuan Yi', 'iu' => 'Inuktitut', 'ie' => 'Interlingue',
       
   427 		'ia' => 'Interlingua (International Auxiliary Language Association)', 'id' => 'Indonesian', 'ik' => 'Inupiaq', 'it' => 'Italian', 'jv' => 'Javanese', 'ja' => 'Japanese', 'kl' => 'Kalaallisut; Greenlandic', 'kn' => 'Kannada', 'ks' => 'Kashmiri', 'kr' => 'Kanuri', 'kk' => 'Kazakh', 'km' => 'Central Khmer', 'ki' => 'Kikuyu; Gikuyu', 'rw' => 'Kinyarwanda', 'ky' => 'Kirghiz; Kyrgyz',
       
   428 		'kv' => 'Komi', 'kg' => 'Kongo', 'ko' => 'Korean', 'kj' => 'Kuanyama; Kwanyama', 'ku' => 'Kurdish', 'lo' => 'Lao', 'la' => 'Latin', 'lv' => 'Latvian', 'li' => 'Limburgan; Limburger; Limburgish', 'ln' => 'Lingala', 'lt' => 'Lithuanian', 'lb' => 'Luxembourgish; Letzeburgesch', 'lu' => 'Luba-Katanga', 'lg' => 'Ganda', 'mk' => 'Macedonian', 'mh' => 'Marshallese', 'ml' => 'Malayalam',
       
   429 		'mi' => 'Maori', 'mr' => 'Marathi', 'ms' => 'Malay', 'mg' => 'Malagasy', 'mt' => 'Maltese', 'mo' => 'Moldavian', 'mn' => 'Mongolian', 'na' => 'Nauru', 'nv' => 'Navajo; Navaho', 'nr' => 'Ndebele, South; South Ndebele', 'nd' => 'Ndebele, North; North Ndebele', 'ng' => 'Ndonga', 'ne' => 'Nepali', 'nn' => 'Norwegian Nynorsk; Nynorsk, Norwegian', 'nb' => 'Bokmål, Norwegian, Norwegian Bokmål',
       
   430 		'no' => 'Norwegian', 'ny' => 'Chichewa; Chewa; Nyanja', 'oc' => 'Occitan, Provençal', 'oj' => 'Ojibwa', 'or' => 'Oriya', 'om' => 'Oromo', 'os' => 'Ossetian; Ossetic', 'pa' => 'Panjabi; Punjabi', 'fa' => 'Persian', 'pi' => 'Pali', 'pl' => 'Polish', 'pt' => 'Portuguese', 'ps' => 'Pushto', 'qu' => 'Quechua', 'rm' => 'Romansh', 'ro' => 'Romanian', 'rn' => 'Rundi', 'ru' => 'Russian',
       
   431 		'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',
       
   432 		'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',
       
   433 		've' => 'Venda', 'vi' => 'Vietnamese', 'vo' => 'Volapük', 'cy' => 'Welsh','wa' => 'Walloon','wo' => 'Wolof', 'xh' => 'Xhosa', 'yi' => 'Yiddish', 'yo' => 'Yoruba', 'za' => 'Zhuang; Chuang', 'zu' => 'Zulu' );
       
   434 	$lang_codes = apply_filters( 'lang_codes', $lang_codes, $code );
       
   435 	return strtr( $code, $lang_codes );
       
   436 }
       
   437 
       
   438 function sync_category_tag_slugs( $term, $taxonomy ) {
       
   439 	if ( global_terms_enabled() && ( $taxonomy == 'category' || $taxonomy == 'post_tag' ) ) {
       
   440 		if ( is_object( $term ) ) {
       
   441 			$term->slug = sanitize_title( $term->name );
       
   442 		} else {
       
   443 			$term['slug'] = sanitize_title( $term['name'] );
       
   444 		}
       
   445 	}
       
   446 	return $term;
       
   447 }
       
   448 add_filter( 'get_term', 'sync_category_tag_slugs', 10, 2 );
       
   449 
       
   450 function _access_denied_splash() {
       
   451 	if ( ! is_user_logged_in() || is_network_admin() )
       
   452 		return;
       
   453 
       
   454 	$blogs = get_blogs_of_user( get_current_user_id() );
       
   455 
       
   456 	if ( wp_list_filter( $blogs, array( 'userblog_id' => get_current_blog_id() ) ) )
       
   457 		return;
       
   458 
       
   459 	$blog_name = get_bloginfo( 'name' );
       
   460 
       
   461 	if ( empty( $blogs ) )
       
   462 		wp_die( sprintf( __( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ), $blog_name ) );
       
   463 
       
   464 	$output = '<p>' . sprintf( __( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ), $blog_name ) . '</p>';
       
   465 	$output .= '<p>' . __( 'If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.' ) . '</p>';
       
   466 
       
   467 	$output .= '<h3>' . __('Your Sites') . '</h3>';
       
   468 	$output .= '<table>';
       
   469 
       
   470 	foreach ( $blogs as $blog ) {
       
   471 		$output .= "<tr>";
       
   472 		$output .= "<td valign='top'>";
       
   473 		$output .= "{$blog->blogname}";
       
   474 		$output .= "</td>";
       
   475 		$output .= "<td valign='top'>";
       
   476 		$output .= "<a href='" . esc_url( get_admin_url( $blog->userblog_id ) ) . "'>" . __( 'Visit Dashboard' ) . "</a> | <a href='" . esc_url( get_home_url( $blog->userblog_id ) ). "'>" . __( 'View Site' ) . "</a>" ;
       
   477 		$output .= "</td>";
       
   478 		$output .= "</tr>";
       
   479 	}
       
   480 	$output .= '</table>';
       
   481 
       
   482 	wp_die( $output );
       
   483 }
       
   484 add_action( 'admin_page_access_denied', '_access_denied_splash', 99 );
       
   485 
       
   486 function check_import_new_users( $permission ) {
       
   487 	if ( !is_super_admin() )
       
   488 		return false;
       
   489 	return true;
       
   490 }
       
   491 add_filter( 'import_allow_create_users', 'check_import_new_users' );
       
   492 // See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too.
       
   493 
       
   494 function mu_dropdown_languages( $lang_files = array(), $current = '' ) {
       
   495 	$flag = false;
       
   496 	$output = array();
       
   497 
       
   498 	foreach ( (array) $lang_files as $val ) {
       
   499 		$code_lang = basename( $val, '.mo' );
       
   500 
       
   501 		if ( $code_lang == 'en_US' ) { // American English
       
   502 			$flag = true;
       
   503 			$ae = __( 'American English' );
       
   504 			$output[$ae] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $ae . '</option>';
       
   505 		} elseif ( $code_lang == 'en_GB' ) { // British English
       
   506 			$flag = true;
       
   507 			$be = __( 'British English' );
       
   508 			$output[$be] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $be . '</option>';
       
   509 		} else {
       
   510 			$translated = format_code_lang( $code_lang );
       
   511 			$output[$translated] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . esc_html ( $translated ) . '</option>';
       
   512 		}
       
   513 
       
   514 	}
       
   515 
       
   516 	if ( $flag === false ) // WordPress english
       
   517 		$output[] = '<option value=""' . selected( $current, '', false ) . '>' . __( 'English' ) . "</option>";
       
   518 
       
   519 	// Order by name
       
   520 	uksort( $output, 'strnatcasecmp' );
       
   521 
       
   522 	$output = apply_filters( 'mu_dropdown_languages', $output, $lang_files, $current );
       
   523 	echo implode( "\n\t", $output );
       
   524 }
       
   525 
       
   526 /* Warn the admin if SECRET SALT information is missing from wp-config.php */
       
   527 function secret_salt_warning() {
       
   528 	if ( !is_super_admin() )
       
   529 		return;
       
   530 	$secret_keys = array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT' );
       
   531 	$out = '';
       
   532 	foreach( $secret_keys as $key ) {
       
   533 		if ( ! defined( $key ) )
       
   534 			$out .= "define( '$key', '" . esc_html( wp_generate_password( 64, true, true ) ) . "' );<br />";
       
   535 	}
       
   536 	if ( $out != '' ) {
       
   537 		$msg  = __( 'Warning! WordPress encrypts user cookies, but you must add the following lines to <strong>wp-config.php</strong> for it to be more secure.' );
       
   538 		$msg .= '<br/>' . __( "Before the line <code>/* That's all, stop editing! Happy blogging. */</code> please add this code:" );
       
   539 		$msg .= "<br/><br/><code>$out</code>";
       
   540 
       
   541 		echo "<div class='update-nag'>$msg</div>";
       
   542 	}
       
   543 }
       
   544 add_action( 'network_admin_notices', 'secret_salt_warning' );
       
   545 
       
   546 function site_admin_notice() {
       
   547 	global $wp_db_version;
       
   548 	if ( !is_super_admin() )
       
   549 		return false;
       
   550 	if ( get_site_option( 'wpmu_upgrade_site' ) != $wp_db_version )
       
   551 		echo "<div class='update-nag'>" . sprintf( __( 'Thank you for Updating! Please visit the <a href="%s">Update Network</a> page to update all your sites.' ), esc_url( network_admin_url( 'upgrade.php' ) ) ) . "</div>";
       
   552 }
       
   553 add_action( 'admin_notices', 'site_admin_notice' );
       
   554 add_action( 'network_admin_notices', 'site_admin_notice' );
       
   555 
       
   556 function avoid_blog_page_permalink_collision( $data, $postarr ) {
       
   557 	if ( is_subdomain_install() )
       
   558 		return $data;
       
   559 	if ( $data['post_type'] != 'page' )
       
   560 		return $data;
       
   561 	if ( !isset( $data['post_name'] ) || $data['post_name'] == '' )
       
   562 		return $data;
       
   563 	if ( !is_main_site() )
       
   564 		return $data;
       
   565 
       
   566 	$post_name = $data['post_name'];
       
   567 	$c = 0;
       
   568 	while( $c < 10 && get_id_from_blogname( $post_name ) ) {
       
   569 		$post_name .= mt_rand( 1, 10 );
       
   570 		$c ++;
       
   571 	}
       
   572 	if ( $post_name != $data['post_name'] ) {
       
   573 		$data['post_name'] = $post_name;
       
   574 	}
       
   575 	return $data;
       
   576 }
       
   577 add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 );
       
   578 
       
   579 function choose_primary_blog() {
       
   580 	?>
       
   581 	<table class="form-table">
       
   582 	<tr>
       
   583 	<?php /* translators: My sites label */ ?>
       
   584 		<th scope="row"><?php _e( 'Primary Site' ); ?></th>
       
   585 		<td>
       
   586 		<?php
       
   587 		$all_blogs = get_blogs_of_user( get_current_user_id() );
       
   588 		$primary_blog = get_user_meta( get_current_user_id(), 'primary_blog', true );
       
   589 		if ( count( $all_blogs ) > 1 ) {
       
   590 			$found = false;
       
   591 			?>
       
   592 			<select name="primary_blog">
       
   593 				<?php foreach( (array) $all_blogs as $blog ) {
       
   594 					if ( $primary_blog == $blog->userblog_id )
       
   595 						$found = true;
       
   596 					?><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
       
   597 				} ?>
       
   598 			</select>
       
   599 			<?php
       
   600 			if ( !$found ) {
       
   601 				$blog = array_shift( $all_blogs );
       
   602 				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
       
   603 			}
       
   604 		} elseif ( count( $all_blogs ) == 1 ) {
       
   605 			$blog = array_shift( $all_blogs );
       
   606 			echo $blog->domain;
       
   607 			if ( $primary_blog != $blog->userblog_id ) // Set the primary blog again if it's out of sync with blog list.
       
   608 				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
       
   609 		} else {
       
   610 			echo "N/A";
       
   611 		}
       
   612 		?>
       
   613 		</td>
       
   614 	</tr>
       
   615 	<?php if ( in_array( get_site_option( 'registration' ), array( 'all', 'blog' ) ) ) : ?>
       
   616 		<tr>
       
   617 			<th scope="row" colspan="2" class="th-full">
       
   618 				<a href="<?php echo apply_filters( 'wp_signup_location', network_home_url( 'wp-signup.php' ) ); ?>"><?php _e( 'Create a New Site' ); ?></a>
       
   619 			</th>
       
   620 		</tr>
       
   621 	<?php endif; ?>
       
   622 	</table>
       
   623 	<?php
       
   624 }
       
   625 
       
   626 function ms_deprecated_blogs_file() {
       
   627 	if ( ! is_super_admin() )
       
   628 		return;
       
   629 	if ( ! file_exists( WP_CONTENT_DIR . '/blogs.php' ) )
       
   630 		return;
       
   631 	echo '<div class="update-nag">' . sprintf( __( 'The <code>%1$s</code> file is deprecated. Please remove it and update your server rewrite rules to use <code>%2$s</code> instead.' ), 'wp-content/blogs.php', 'wp-includes/ms-files.php' ) . '</div>';
       
   632 }
       
   633 add_action( 'network_admin_notices', 'ms_deprecated_blogs_file' );
       
   634 
       
   635 /**
       
   636  * Grants super admin privileges.
       
   637  *
       
   638  * @since 3.0.0
       
   639  * @param int $user_id
       
   640  */
       
   641 function grant_super_admin( $user_id ) {
       
   642 	global $super_admins;
       
   643 
       
   644 	// If global super_admins override is defined, there is nothing to do here.
       
   645 	if ( isset($super_admins) )
       
   646 		return false;
       
   647 
       
   648 	do_action( 'grant_super_admin', $user_id );
       
   649 
       
   650 	// Directly fetch site_admins instead of using get_super_admins()
       
   651 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
       
   652 
       
   653 	$user = new WP_User( $user_id );
       
   654 	if ( ! in_array( $user->user_login, $super_admins ) ) {
       
   655 		$super_admins[] = $user->user_login;
       
   656 		update_site_option( 'site_admins' , $super_admins );
       
   657 		do_action( 'granted_super_admin', $user_id );
       
   658 		return true;
       
   659 	}
       
   660 	return false;
       
   661 }
       
   662 
       
   663 /**
       
   664  * Revokes super admin privileges.
       
   665  *
       
   666  * @since 3.0.0
       
   667  * @param int $user_id
       
   668  */
       
   669 function revoke_super_admin( $user_id ) {
       
   670 	global $super_admins;
       
   671 
       
   672 	// If global super_admins override is defined, there is nothing to do here.
       
   673 	if ( isset($super_admins) )
       
   674 		return false;
       
   675 
       
   676 	do_action( 'revoke_super_admin', $user_id );
       
   677 
       
   678 	// Directly fetch site_admins instead of using get_super_admins()
       
   679 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
       
   680 
       
   681 	$user = new WP_User( $user_id );
       
   682 	if ( $user->user_email != get_site_option( 'admin_email' ) ) {
       
   683 		if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) {
       
   684 			unset( $super_admins[$key] );
       
   685 			update_site_option( 'site_admins', $super_admins );
       
   686 			do_action( 'revoked_super_admin', $user_id );
       
   687 			return true;
       
   688 		}
       
   689 	}
       
   690 	return false;
       
   691 }
       
   692 
       
   693 /**
       
   694  * Whether or not we can edit this network from this page
       
   695  *
       
   696  * By default editing of network is restricted to the Network Admin for that site_id this allows for this to be overridden
       
   697  *
       
   698  * @since 3.1.0
       
   699  * @param integer $site_id The network/site id to check.
       
   700  */
       
   701 function can_edit_network( $site_id ) {
       
   702 	global $wpdb;
       
   703 
       
   704 	if ($site_id == $wpdb->siteid )
       
   705 		$result = true;
       
   706 	else
       
   707 		$result = false;
       
   708 
       
   709 	return apply_filters( 'can_edit_network', $result, $site_id );
       
   710 }
       
   711 
       
   712 /**
       
   713  * Thickbox image paths for Network Admin.
       
   714  *
       
   715  * @since 3.1.0
       
   716  * @access private
       
   717  */
       
   718 function _thickbox_path_admin_subfolder() {
       
   719 ?>
       
   720 <script type="text/javascript">
       
   721 //<![CDATA[
       
   722 var tb_pathToImage = "../../wp-includes/js/thickbox/loadingAnimation.gif";
       
   723 var tb_closeImage = "../../wp-includes/js/thickbox/tb-close.png";
       
   724 //]]>
       
   725 </script>
       
   726 <?php
       
   727 }
       
   728 
       
   729 /**
       
   730  * Whether or not we have a large network.
       
   731  *
       
   732  * The default criteria for a large network is either more than 10,000 users or more than 10,000 sites.
       
   733  * Plugins can alter this criteria using the 'wp_is_large_network' filter.
       
   734  *
       
   735  * @since 3.3.0
       
   736  * @param string $using 'sites or 'users'. Default is 'sites'.
       
   737  * @return bool True if the network meets the criteria for large. False otherwise.
       
   738  */
       
   739 function wp_is_large_network( $using = 'sites' ) {
       
   740 	if ( 'users' == $using ) {
       
   741 		$count = get_user_count();
       
   742 		return apply_filters( 'wp_is_large_network', $count > 10000, 'users', $count );
       
   743 	}
       
   744 
       
   745 	$count = get_blog_count();
       
   746 	return apply_filters( 'wp_is_large_network', $count > 10000, 'sites', $count );
       
   747 }