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