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