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