Wordpress 3.5
[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' ) );
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&#8217;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 }