Description: Multisite administration functions.
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_left = get_upload_space_available(); 29 30 $file_size = filesize( $file['tmp_name'] ); 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 ) ); 33 if ( $file_size > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) ) 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 ) ); 35 if ( upload_is_user_over_quota( false ) ) { 36 $file['error'] = __( 'You have used your space quota. Please delete files before uploading.' ); 37 } 38 if ( $file['error'] != '0' && !isset($_POST['html-upload']) ) 39 wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' ); 40 41 return $file; 42 } 43 add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' ); 44 45 /** 46 * Delete a blog 47 * 48 * @since 3.0.0 49 * 50 * @param int $blog_id Blog ID 51 * @param bool $drop True if blog's table should be dropped. Default is false. 52 * @return void 53 */ 54 function wpmu_delete_blog( $blog_id, $drop = false ) { 55 global $wpdb, $current_site; 56 57 $switch = false; 58 if ( get_current_blog_id() != $blog_id ) { 59 $switch = true; 60 switch_to_blog( $blog_id ); 61 } 62 63 $blog = get_blog_details( $blog_id ); 64 65 do_action( 'delete_blog', $blog_id, $drop ); 66 67 $users = get_users( array( 'blog_id' => $blog_id, 'fields' => 'ids' ) ); 68 69 // Remove users from this blog. 70 if ( ! empty( $users ) ) { 71 foreach ( $users as $user_id ) { 72 remove_user_from_blog( $user_id, $blog_id ); 73 } 74 } 75 76 update_blog_status( $blog_id, 'deleted', 1 ); 77 78 // Don't destroy the initial, main, or root blog. 79 if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_site->path && $blog->domain == $current_site->domain ) ) ) 80 $drop = false; 81 82 if ( $drop ) { 83 $drop_tables = apply_filters( 'wpmu_drop_tables', $wpdb->tables( 'blog' ) ); 84 85 foreach ( (array) $drop_tables as $table ) { 86 $wpdb->query( "DROP TABLE IF EXISTS `$table`" ); 87 } 88 89 $wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) ); 90 91 $uploads = wp_upload_dir(); 92 $dir = apply_filters( 'wpmu_delete_blog_upload_dir', $uploads['basedir'], $blog_id ); 93 $dir = rtrim( $dir, DIRECTORY_SEPARATOR ); 94 $top_dir = $dir; 95 $stack = array($dir); 96 $index = 0; 97 98 while ( $index < count( $stack ) ) { 99 # Get indexed directory from stack 100 $dir = $stack[$index]; 101 102 $dh = @opendir( $dir ); 103 if ( $dh ) { 104 while ( ( $file = @readdir( $dh ) ) !== false ) { 105 if ( $file == '.' || $file == '..' ) 106 continue; 107 108 if ( @is_dir( $dir . DIRECTORY_SEPARATOR . $file ) ) 109 $stack[] = $dir . DIRECTORY_SEPARATOR . $file; 110 else if ( @is_file( $dir . DIRECTORY_SEPARATOR . $file ) ) 111 @unlink( $dir . DIRECTORY_SEPARATOR . $file ); 112 } 113 @closedir( $dh ); 114 } 115 $index++; 116 } 117 118 $stack = array_reverse( $stack ); // Last added dirs are deepest 119 foreach( (array) $stack as $dir ) { 120 if ( $dir != $top_dir) 121 @rmdir( $dir ); 122 } 123 124 clean_blog_cache( $blog ); 125 } 126 127 if ( $switch ) 128 restore_current_blog(); 129 } 130 131 // @todo Merge with wp_delete_user() ? 132 function wpmu_delete_user( $id ) { 133 global $wpdb; 134 135 $id = (int) $id; 136 $user = new WP_User( $id ); 137 138 do_action( 'wpmu_delete_user', $id ); 139 140 $blogs = get_blogs_of_user( $id ); 141 142 if ( ! empty( $blogs ) ) { 143 foreach ( $blogs as $blog ) { 144 switch_to_blog( $blog->userblog_id ); 145 remove_user_from_blog( $id, $blog->userblog_id ); 146 147 $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) ); 148 foreach ( (array) $post_ids as $post_id ) { 149 wp_delete_post( $post_id ); 150 } 151 152 // Clean links 153 $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) ); 154 155 if ( $link_ids ) { 156 foreach ( $link_ids as $link_id ) 157 wp_delete_link( $link_id ); 158 } 159 160 restore_current_blog(); 161 } 162 } 163 164 $meta = $wpdb->get_col( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d", $id ) ); 165 foreach ( $meta as $mid ) 166 delete_metadata_by_mid( 'user', $mid ); 167 168 $wpdb->delete( $wpdb->users, array( 'ID' => $id ) ); 169 170 clean_user_cache( $user ); 171 172 // allow for commit transaction 173 do_action( 'deleted_user', $id ); 174 175 return true; 176 } 177 178 function update_option_new_admin_email( $old_value, $value ) { 179 $email = get_option( 'admin_email' ); 180 if ( $value == get_option( 'admin_email' ) || !is_email( $value ) ) 181 return; 182 183 $hash = md5( $value. time() .mt_rand() ); 184 $new_admin_email = array( 185 'hash' => $hash, 186 'newemail' => $value 187 ); 188 update_option( 'adminhash', $new_admin_email ); 189 190 $content = apply_filters( 'new_admin_email_content', __( "Dear user, 191 192 You recently requested to have the administration email address on 193 your site changed. 194 If this is correct, please click on the following link to change it: 195 ###ADMIN_URL### 196 197 You can safely ignore and delete this email if you do not want to 198 take this action. 199 200 This email has been sent to ###EMAIL### 201 202 Regards, 203 All at ###SITENAME### 204 ###SITEURL### "), $new_admin_email ); 205 206 $content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'options.php?adminhash='.$hash ) ), $content ); 207 $content = str_replace( '###EMAIL###', $value, $content ); 208 $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content ); 209 $content = str_replace( '###SITEURL###', network_home_url(), $content ); 210 211 wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), get_option( 'blogname' ) ), $content ); 212 } 213 add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 ); 214 add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 ); 215 216 function send_confirmation_on_profile_email() { 217 global $errors, $wpdb; 218 $current_user = wp_get_current_user(); 219 if ( ! is_object($errors) ) 220 $errors = new WP_Error(); 221 222 if ( $current_user->ID != $_POST['user_id'] ) 223 return false; 224 225 if ( $current_user->user_email != $_POST['email'] ) { 226 if ( !is_email( $_POST['email'] ) ) { 227 $errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address isn’t correct." ), array( 'form-field' => 'email' ) ); 228 return; 229 } 230 231 if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM {$wpdb->users} WHERE user_email=%s", $_POST['email'] ) ) ) { 232 $errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address is already used." ), array( 'form-field' => 'email' ) ); 233 delete_option( $current_user->ID . '_new_email' ); 234 return; 235 } 236 237 $hash = md5( $_POST['email'] . time() . mt_rand() ); 238 $new_user_email = array( 239 'hash' => $hash, 240 'newemail' => $_POST['email'] 241 ); 242 update_option( $current_user->ID . '_new_email', $new_user_email ); 243 244 $content = apply_filters( 'new_user_email_content', __( "Dear user, 245 246 You recently requested to have the email address on your account changed. 247 If this is correct, please click on the following link to change it: 248 ###ADMIN_URL### 249 250 You can safely ignore and delete this email if you do not want to 251 take this action. 252 253 This email has been sent to ###EMAIL### 254 255 Regards, 256 All at ###SITENAME### 257 ###SITEURL###" ), $new_user_email ); 258 259 $content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail='.$hash ) ), $content ); 260 $content = str_replace( '###EMAIL###', $_POST['email'], $content); 261 $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content ); 262 $content = str_replace( '###SITEURL###', network_home_url(), $content ); 263 264 wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), get_option( 'blogname' ) ), $content ); 265 $_POST['email'] = $current_user->user_email; 266 } 267 } 268 add_action( 'personal_options_update', 'send_confirmation_on_profile_email' ); 269 270 function new_user_email_admin_notice() { 271 if ( strpos( $_SERVER['PHP_SELF'], 'profile.php' ) && isset( $_GET['updated'] ) && $email = get_option( get_current_user_id() . '_new_email' ) ) 272 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>"; 273 } 274 add_action( 'admin_notices', 'new_user_email_admin_notice' ); 275 276 /** 277 * Check whether a blog has used its allotted upload space. 278 * 279 * @since MU 280 * 281 * @param bool $echo Optional. If $echo is set and the quota is exceeded, a warning message is echoed. Default is true. 282 * @return int 283 */ 284 function upload_is_user_over_quota( $echo = true ) { 285 if ( get_site_option( 'upload_space_check_disabled' ) ) 286 return false; 287 288 $space_allowed = get_space_allowed(); 289 if ( empty( $space_allowed ) || !is_numeric( $space_allowed ) ) 290 $space_allowed = 10; // Default space allowed is 10 MB 291 292 $space_used = get_space_used(); 293 294 if ( ( $space_allowed - $space_used ) < 0 ) { 295 if ( $echo ) 296 _e( 'Sorry, you have used your space allocation. Please delete some files to upload more files.' ); 297 return true; 298 } else { 299 return false; 300 } 301 } 302 303 /** 304 * Displays the amount of disk space used by the current blog. Not used in core. 305 * 306 * @since MU 307 */ 308 function display_space_usage() { 309 $space_allowed = get_space_allowed(); 310 $space_used = get_space_used(); 311 312 $percent_used = ( $space_used / $space_allowed ) * 100; 313 314 if ( $space_allowed > 1000 ) { 315 $space = number_format( $space_allowed / 1024 ); 316 /* translators: Gigabytes */ 317 $space .= __( 'GB' ); 318 } else { 319 $space = number_format( $space_allowed ); 320 /* translators: Megabytes */ 321 $space .= __( 'MB' ); 322 } 323 ?> 324 <strong><?php printf( __( 'Used: %1$s%% of %2$s' ), number_format( $percent_used ), $space ); ?></strong> 325 <?php 326 } 327 328 /** 329 * Get the remaining upload space for this blog. 330 * 331 * @since MU 332 * @uses upload_is_user_over_quota() 333 * @uses get_space_allowed() 334 * @uses get_upload_space_available() 335 * 336 * @param int $size Current max size in bytes 337 * @return int Max size in bytes 338 */ 339 function fix_import_form_size( $size ) { 340 if ( upload_is_user_over_quota( false ) == true ) 341 return 0; 342 343 $available = get_upload_space_available(); 344 return min( $size, $available ); 345 } 346 347 // Edit blog upload space setting on Edit Blog page 348 function upload_space_setting( $id ) { 349 switch_to_blog( $id ); 350 $quota = get_option( 'blog_upload_space' ); 351 restore_current_blog(); 352 353 if ( !$quota ) 354 $quota = ''; 355 356 ?> 357 <tr> 358 <th><?php _e( 'Site Upload Space Quota '); ?></th> 359 <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> 360 </tr> 361 <?php 362 } 363 add_action( 'wpmueditblogaction', 'upload_space_setting' ); 364 365 function update_user_status( $id, $pref, $value, $deprecated = null ) { 366 global $wpdb; 367 368 if ( null !== $deprecated ) 369 _deprecated_argument( __FUNCTION__, '3.1' ); 370 371 $wpdb->update( $wpdb->users, array( $pref => $value ), array( 'ID' => $id ) ); 372 373 $user = new WP_User( $id ); 374 clean_user_cache( $user ); 375 376 if ( $pref == 'spam' ) { 377 if ( $value == 1 ) 378 do_action( 'make_spam_user', $id ); 379 else 380 do_action( 'make_ham_user', $id ); 381 } 382 383 return $value; 384 } 385 386 function refresh_user_details( $id ) { 387 $id = (int) $id; 388 389 if ( !$user = get_userdata( $id ) ) 390 return false; 391 392 clean_user_cache( $user ); 393 394 return $id; 395 } 396 397 function format_code_lang( $code = '' ) { 398 $code = strtolower( substr( $code, 0, 2 ) ); 399 $lang_codes = array( 400 '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', 401 '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', 402 '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', 403 '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', 404 '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', 405 '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', 406 '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', 407 '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', 408 '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', 409 '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', 410 've' => 'Venda', 'vi' => 'Vietnamese', 'vo' => 'Volapük', 'cy' => 'Welsh','wa' => 'Walloon','wo' => 'Wolof', 'xh' => 'Xhosa', 'yi' => 'Yiddish', 'yo' => 'Yoruba', 'za' => 'Zhuang; Chuang', 'zu' => 'Zulu' ); 411 $lang_codes = apply_filters( 'lang_codes', $lang_codes, $code ); 412 return strtr( $code, $lang_codes ); 413 } 414 415 function sync_category_tag_slugs( $term, $taxonomy ) { 416 if ( global_terms_enabled() && ( $taxonomy == 'category' || $taxonomy == 'post_tag' ) ) { 417 if ( is_object( $term ) ) { 418 $term->slug = sanitize_title( $term->name ); 419 } else { 420 $term['slug'] = sanitize_title( $term['name'] ); 421 } 422 } 423 return $term; 424 } 425 add_filter( 'get_term', 'sync_category_tag_slugs', 10, 2 ); 426 427 function _access_denied_splash() { 428 if ( ! is_user_logged_in() || is_network_admin() ) 429 return; 430 431 $blogs = get_blogs_of_user( get_current_user_id() ); 432 433 if ( wp_list_filter( $blogs, array( 'userblog_id' => get_current_blog_id() ) ) ) 434 return; 435 436 $blog_name = get_bloginfo( 'name' ); 437 438 if ( empty( $blogs ) ) 439 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 ) ); 440 441 $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>'; 442 $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>'; 443 444 $output .= '<h3>' . __('Your Sites') . '</h3>'; 445 $output .= '<table>'; 446 447 foreach ( $blogs as $blog ) { 448 $output .= "<tr>"; 449 $output .= "<td valign='top'>"; 450 $output .= "{$blog->blogname}"; 451 $output .= "</td>"; 452 $output .= "<td valign='top'>"; 453 $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>" ; 454 $output .= "</td>"; 455 $output .= "</tr>"; 456 } 457 $output .= '</table>'; 458 459 wp_die( $output ); 460 } 461 add_action( 'admin_page_access_denied', '_access_denied_splash', 99 ); 462 463 function check_import_new_users( $permission ) { 464 if ( !is_super_admin() ) 465 return false; 466 return true; 467 } 468 add_filter( 'import_allow_create_users', 'check_import_new_users' ); 469 // See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too. 470 471 function mu_dropdown_languages( $lang_files = array(), $current = '' ) { 472 $flag = false; 473 $output = array(); 474 475 foreach ( (array) $lang_files as $val ) { 476 $code_lang = basename( $val, '.mo' ); 477 478 if ( $code_lang == 'en_US' ) { // American English 479 $flag = true; 480 $ae = __( 'American English' ); 481 $output[$ae] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $ae . '</option>'; 482 } elseif ( $code_lang == 'en_GB' ) { // British English 483 $flag = true; 484 $be = __( 'British English' ); 485 $output[$be] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $be . '</option>'; 486 } else { 487 $translated = format_code_lang( $code_lang ); 488 $output[$translated] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . esc_html ( $translated ) . '</option>'; 489 } 490 491 } 492 493 if ( $flag === false ) // WordPress english 494 $output[] = '<option value=""' . selected( $current, '', false ) . '>' . __( 'English' ) . "</option>"; 495 496 // Order by name 497 uksort( $output, 'strnatcasecmp' ); 498 499 $output = apply_filters( 'mu_dropdown_languages', $output, $lang_files, $current ); 500 echo implode( "\n\t", $output ); 501 } 502 503 /* Warn the admin if SECRET SALT information is missing from wp-config.php */ 504 function secret_salt_warning() { 505 if ( !is_super_admin() ) 506 return; 507 $secret_keys = array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT' ); 508 $out = ''; 509 foreach( $secret_keys as $key ) { 510 if ( ! defined( $key ) ) 511 $out .= "define( '$key', '" . esc_html( wp_generate_password( 64, true, true ) ) . "' );<br />"; 512 } 513 if ( $out != '' ) { 514 $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.' ); 515 $msg .= '<br/>' . __( "Before the line <code>/* That's all, stop editing! Happy blogging. */</code> please add this code:" ); 516 $msg .= "<br/><br/><code>$out</code>"; 517 518 echo "<div class='update-nag'>$msg</div>"; 519 } 520 } 521 add_action( 'network_admin_notices', 'secret_salt_warning' ); 522 523 function site_admin_notice() { 524 global $wp_db_version; 525 if ( !is_super_admin() ) 526 return false; 527 if ( get_site_option( 'wpmu_upgrade_site' ) != $wp_db_version ) 528 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>"; 529 } 530 add_action( 'admin_notices', 'site_admin_notice' ); 531 add_action( 'network_admin_notices', 'site_admin_notice' ); 532 533 function avoid_blog_page_permalink_collision( $data, $postarr ) { 534 if ( is_subdomain_install() ) 535 return $data; 536 if ( $data['post_type'] != 'page' ) 537 return $data; 538 if ( !isset( $data['post_name'] ) || $data['post_name'] == '' ) 539 return $data; 540 if ( !is_main_site() ) 541 return $data; 542 543 $post_name = $data['post_name']; 544 $c = 0; 545 while( $c < 10 && get_id_from_blogname( $post_name ) ) { 546 $post_name .= mt_rand( 1, 10 ); 547 $c ++; 548 } 549 if ( $post_name != $data['post_name'] ) { 550 $data['post_name'] = $post_name; 551 } 552 return $data; 553 } 554 add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 ); 555 556 function choose_primary_blog() { 557 ?> 558 <table class="form-table"> 559 <tr> 560 <?php /* translators: My sites label */ ?> 561 <th scope="row"><?php _e( 'Primary Site' ); ?></th> 562 <td> 563 <?php 564 $all_blogs = get_blogs_of_user( get_current_user_id() ); 565 $primary_blog = get_user_meta( get_current_user_id(), 'primary_blog', true ); 566 if ( count( $all_blogs ) > 1 ) { 567 $found = false; 568 ?> 569 <select name="primary_blog"> 570 <?php foreach( (array) $all_blogs as $blog ) { 571 if ( $primary_blog == $blog->userblog_id ) 572 $found = true; 573 ?><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 574 } ?> 575 </select> 576 <?php 577 if ( !$found ) { 578 $blog = array_shift( $all_blogs ); 579 update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id ); 580 } 581 } elseif ( count( $all_blogs ) == 1 ) { 582 $blog = array_shift( $all_blogs ); 583 echo $blog->domain; 584 if ( $primary_blog != $blog->userblog_id ) // Set the primary blog again if it's out of sync with blog list. 585 update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id ); 586 } else { 587 echo "N/A"; 588 } 589 ?> 590 </td> 591 </tr> 592 <?php if ( in_array( get_site_option( 'registration' ), array( 'all', 'blog' ) ) ) : ?> 593 <tr> 594 <th scope="row" colspan="2" class="th-full"> 595 <a href="<?php echo apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ); ?>"><?php _e( 'Create a New Site' ); ?></a> 596 </th> 597 </tr> 598 <?php endif; ?> 599 </table> 600 <?php 601 } 602 603 /** 604 * Grants super admin privileges. 605 * 606 * @since 3.0.0 607 * @param int $user_id 608 */ 609 function grant_super_admin( $user_id ) { 610 global $super_admins; 611 612 // If global super_admins override is defined, there is nothing to do here. 613 if ( isset($super_admins) ) 614 return false; 615 616 do_action( 'grant_super_admin', $user_id ); 617 618 // Directly fetch site_admins instead of using get_super_admins() 619 $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); 620 621 $user = get_userdata( $user_id ); 622 if ( $user && ! in_array( $user->user_login, $super_admins ) ) { 623 $super_admins[] = $user->user_login; 624 update_site_option( 'site_admins' , $super_admins ); 625 do_action( 'granted_super_admin', $user_id ); 626 return true; 627 } 628 return false; 629 } 630 631 /** 632 * Revokes super admin privileges. 633 * 634 * @since 3.0.0 635 * @param int $user_id 636 */ 637 function revoke_super_admin( $user_id ) { 638 global $super_admins; 639 640 // If global super_admins override is defined, there is nothing to do here. 641 if ( isset($super_admins) ) 642 return false; 643 644 do_action( 'revoke_super_admin', $user_id ); 645 646 // Directly fetch site_admins instead of using get_super_admins() 647 $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); 648 649 $user = get_userdata( $user_id ); 650 if ( $user && $user->user_email != get_site_option( 'admin_email' ) ) { 651 if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) { 652 unset( $super_admins[$key] ); 653 update_site_option( 'site_admins', $super_admins ); 654 do_action( 'revoked_super_admin', $user_id ); 655 return true; 656 } 657 } 658 return false; 659 } 660 661 /** 662 * Whether or not we can edit this network from this page 663 * 664 * By default editing of network is restricted to the Network Admin for that site_id this allows for this to be overridden 665 * 666 * @since 3.1.0 667 * @param integer $site_id The network/site id to check. 668 */ 669 function can_edit_network( $site_id ) { 670 global $wpdb; 671 672 if ($site_id == $wpdb->siteid ) 673 $result = true; 674 else 675 $result = false; 676 677 return apply_filters( 'can_edit_network', $result, $site_id ); 678 } 679 680 /** 681 * Thickbox image paths for Network Admin. 682 * 683 * @since 3.1.0 684 * @access private 685 */ 686 function _thickbox_path_admin_subfolder() { 687 ?> 688 <script type="text/javascript"> 689 //<![CDATA[ 690 var tb_pathToImage = "../../wp-includes/js/thickbox/loadingAnimation.gif"; 691 //]]> 692 </script> 693 <?php 694 } 695 696 /** 697 * Whether or not we have a large network. 698 * 699 * The default criteria for a large network is either more than 10,000 users or more than 10,000 sites. 700 * Plugins can alter this criteria using the 'wp_is_large_network' filter. 701 * 702 * @since 3.3.0 703 * @param string $using 'sites or 'users'. Default is 'sites'. 704 * @return bool True if the network meets the criteria for large. False otherwise. 705 */ 706 function wp_is_large_network( $using = 'sites' ) { 707 if ( 'users' == $using ) { 708 $count = get_user_count(); 709 return apply_filters( 'wp_is_large_network', $count > 10000, 'users', $count ); 710 } 711 712 $count = get_blog_count(); 713 return apply_filters( 'wp_is_large_network', $count > 10000, 'sites', $count ); 714 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title