root/trunk/wp-includes/wpmu-functions.php

Revision 1817, 73.5 kB (checked in by donncha, 1 day ago)

Move BLOGUPLOADDIR mod into it's own function and apply to upload_dir filter

  • Property svn:eol-style set to native
Line 
1 <?php
2 /*
3     Helper functions for WPMU
4 */
5 function load_muplugin_textdomain($domain, $path = false) {
6     $locale = get_locale();
7     if ( empty($locale) )
8         $locale = 'en_US';
9
10     if ( false === $path )
11         $path = WPMU_PLUGIN_DIR;
12
13     $mofile = WPMU_PLUGIN_DIR . "/$domain-$locale.mo";
14     load_textdomain($domain, $mofile);
15 }
16
17 function wpmu_update_blogs_date() {
18     global $wpdb;
19
20     $wpdb->update( $wpdb->blogs, array('last_updated' => current_time('mysql', true)), array('blog_id' => $wpdb->blogid) );
21     refresh_blog_details( $wpdb->blogid );
22
23     do_action( 'wpmu_blog_updated', $wpdb->blogid );
24 }
25
26 function get_blogaddress_by_id( $blog_id ) {
27     $bloginfo = get_blog_details( (int) $blog_id, false ); // only get bare details!
28     return clean_url("http://" . $bloginfo->domain . $bloginfo->path);
29 }
30
31 function get_blogaddress_by_name( $blogname ) {
32     global $current_site;
33
34     if( defined( "VHOST" ) && constant( "VHOST" ) == 'yes' ) {
35         if( $blogname == 'main' )
36             $blogname = 'www';
37         return clean_url( "http://" . $blogname . "." . $current_site->domain . $current_site->path );
38     } else {
39         return clean_url( "http://" . $current_site->domain . $current_site->path . $blogname . '/' );
40     }
41 }
42
43 function get_blogaddress_by_domain( $domain, $path ){
44     if( defined( "VHOST" ) && constant( "VHOST" ) == 'yes' ) {
45         $url = "http://".$domain.$path;
46     } else {
47         if( $domain != $_SERVER['HTTP_HOST'] ) {
48             $blogname = substr( $domain, 0, strpos( $domain, '.' ) );
49             if( $blogname != 'www.' ) {
50                 $url = 'http://' . substr( $domain, strpos( $domain, '.' ) + 1 ) . $path . $blogname . '/';
51             } else { // we're installing the main blog
52                 $url = 'http://' . substr( $domain, strpos( $domain, '.' ) + 1 ) . $path;
53             }
54         } else { // main blog
55             $url = 'http://' . $domain . $path;
56         }
57     }
58     return clean_url($url);
59 }
60
61 function get_sitestats() {
62     global $wpdb;
63
64     $stats['blogs'] = get_blog_count();
65
66     $count_ts = get_site_option( "get_user_count_ts" );
67     if( time() - $count_ts > 3600 ) {
68         $count = $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->users}" );
69         update_site_option( "user_count", $count );
70         update_site_option( "user_count_ts", time() );
71     } else {
72         $count = get_site_option( "user_count" );
73     }
74     $stats['users'] = $count;
75     return $stats;
76 }
77
78 function get_admin_users_for_domain( $sitedomain = '', $path = '' ) {
79     global $wpdb;
80     
81     if( $sitedomain == '' ) {
82         $site_id = $wpdb->siteid;
83     } else {
84         $site_id = $wpdb->get_var( $wpdb->prepare("SELECT id FROM $wpdb->site WHERE domain = %s AND path = %s", $sitedomain, $path) );
85     }
86
87     if( $site_id != false ) {
88         return $wpdb->get_results( $wpdb->prepare("SELECT u.ID, u.user_login, u.user_pass FROM $wpdb->users AS u, $wpdb->sitemeta AS sm WHERE sm.meta_key = 'admin_user_id' AND u.ID = sm.meta_value AND sm.site_id = %d", $site_id), ARRAY_A );
89     }
90     return false;
91 }
92
93 function get_user_details( $username ) {
94     global $wpdb;
95     return $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_login = %s", $username) );
96 }
97
98 function is_main_blog() {
99     global $current_blog, $current_site;
100     if( $current_blog->domain == $current_site->domain && $current_blog->path == $current_site->path )
101         return true;
102     return false;
103 }
104
105 function get_id_from_blogname( $name ) {
106     global $wpdb, $current_site;
107     $blog_id = wp_cache_get( "get_id_from_blogname_" . $name, 'blog-details' );
108     if( $blog_id )
109         return $blog_id;
110
111     if( constant( 'VHOST' ) == 'yes' ) {
112         $domain = $name . '.' . $current_site->domain;
113         $path = $current_site->path;
114     } else {
115         $domain = $current_site->domain;
116         $path = $current_site->path . $name . '/';
117     }
118     $blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domain, $path) );
119     wp_cache_set( 'get_id_from_blogname_' . $name, $blog_id, 'blog-details' );
120     return $blog_id;
121 }
122
123 function get_blog_details( $id, $getall = true ) {
124     global $wpdb;
125
126     if( !is_numeric( $id ) ) {
127         $id = get_id_from_blogname( $id );
128     }
129     $all = $getall == true ? '' : 'short';
130     $details = wp_cache_get( $id . $all, 'blog-details' );
131
132     if ( $details ) {
133         if ( $details == -1 )
134             return false;
135         elseif ( !is_object($details) ) // Clear old pre-serialized objects. Cache clients do better with that.
136             wp_cache_delete( $id . $all, 'blog-details' );
137         else
138             return $details;
139     }
140
141     $details = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->blogs WHERE blog_id = %d /* get_blog_details */", $id) );
142     if ( !$details ) {
143         wp_cache_set( $id . $all, -1, 'blog-details' );
144         return false;
145     }
146
147     if ( !$getall ) {
148         wp_cache_set( $id . $all, $details, 'blog-details' );
149         return $details;
150     }
151
152     $wpdb->suppress_errors();
153     switch_to_blog( $id );
154     $details->blogname   = get_option( 'blogname' );
155     $details->siteurl    = get_option( 'siteurl' );
156     $details->post_count = get_option( 'post_count' );
157     restore_current_blog();
158     $wpdb->suppress_errors( false );
159
160     $details = apply_filters('blog_details', $details);
161
162     wp_cache_set( $id . $all, $details, 'blog-details' );
163
164     $key = md5( $details->domain . $details->path );
165     wp_cache_set( $key, $details, 'blog-lookup' );
166
167     return $details;
168 }
169
170 function refresh_blog_details( $id ) {
171     $id = (int) $id;
172     $details = get_blog_details( $id, false );
173     
174     wp_cache_delete( $id , 'blog-details' );
175     wp_cache_delete( $id . 'short' , 'blog-details' );
176     wp_cache_delete( md5( $details->domain . $details->path )  , 'blog-lookup' );
177     wp_cache_delete( 'current_blog_' . $details->domain, 'site-options' );
178     wp_cache_delete( 'current_blog_' . $details->domain . $details->path, 'site-options' );
179 }
180
181 function get_current_user_id() {
182     global $current_user;
183     return $current_user->ID;
184 }
185
186 function is_site_admin( $user_login = false ) {
187     global $current_user;
188
189     if ( !$current_user && !$user_login )
190         return false;
191
192     if ( $user_login ) {
193         $user_login = sanitize_user( $user_login );
194     } elseif( isset( $current_user->user_login ) ) {
195         $user_login = $current_user->user_login;
196     } else {
197         return false;
198     }
199
200     $site_admins = get_site_option( 'site_admins', array('admin') );
201     if( is_array( $site_admins ) && in_array( $user_login, $site_admins ) )
202         return true;
203
204     return false;
205 }
206
207 /* get_blog_option() fetches the named option from a blog but it does not
208    execute the
209 /**
210  * Retrieve option value based on setting name and blog_id.
211  *
212  * If the option does not exist or does not have a value, then the return value
213  * will be false. This is useful to check whether you need to install an option
214  * and is commonly used during installation of plugin options and to test
215  * whether upgrading is required.
216  *
217  * There is a filter called 'blog_option_$option' with the $option being
218  * replaced with the option name. The filter takes two parameters. $value and
219  * $blog_id. It returns $value.
220  * The 'option_$option' filter in get_option() is not called.
221  *
222  * @since NA
223  * @package WordPress MU
224  * @subpackage Option
225  * @uses apply_filters() Calls 'blog_option_$optionname' with the option name value.
226  *
227  * @param int $blog_id is the id of the blog.
228  * @param string $setting Name of option to retrieve. Should already be SQL-escaped
229  * @param string $default (optional) Default value returned if option not found.
230  * @return mixed Value set for the option.
231  */
232 function get_blog_option( $blog_id, $setting, $default = false ) {
233     global $wpdb;
234
235     $key = $blog_id."-".$setting."-blog_option";
236     $value = wp_cache_get( $key, "site-options" );
237     if ( $value == null ) {
238         $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->base_prefix}{$blog_id}_options WHERE option_name = %s", $setting ) );
239         if ( is_object( $row ) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values
240             $value = $row->option_value;
241             if ( $value == false ) {
242                 wp_cache_set( $key, 'falsevalue', 'site-options' );
243             } else {
244                 wp_cache_set( $key, $value, 'site-options' );
245             }
246         } else { // option does not exist, so we must cache its non-existence
247             wp_cache_set( $key, 'noop', 'site-options' );
248             $value = $default;
249         }
250     } elseif( $value == 'noop' ) {
251         $value = $default;
252     } elseif( $value == 'falsevalue' ) {
253         $value = false;
254     }
255     // If home is not set use siteurl.
256     if ( 'home' == $setting && '' == $value )
257         return get_blog_option( $blog_id, 'siteurl' );
258
259     if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting )
260         $value = preg_replace( '|/+$|', '', $value );
261
262     if (! @unserialize( $value ) )
263         $value = stripslashes( $value );
264
265     return apply_filters( 'blog_option_' . $setting, maybe_unserialize( $value ), $blog_id );
266 }
267
268 function add_blog_option( $id, $key, $value ) {
269     $id = (int) $id;
270     
271     switch_to_blog($id);
272     add_option( $key, $value );
273     restore_current_blog();
274     wp_cache_set( $id."-".$key."-blog_option", $value, 'site-options' );
275 }
276
277 function delete_blog_option( $id, $key ) {
278     $id = (int) $id;
279     
280     switch_to_blog($id);
281     delete_option( $key );
282     restore_current_blog();
283     wp_cache_set( $id."-".$key."-blog_option", '', 'site-options' );
284 }
285
286 function update_blog_option( $id, $key, $value, $refresh = true ) {
287     $id = (int) $id;
288     
289     switch_to_blog($id);
290     update_option( $key, $value );
291     restore_current_blog();
292
293     if( $refresh == true )
294         refresh_blog_details( $id );
295     wp_cache_set( $id."-".$key."-blog_option", $value, 'site-options');
296 }
297
298 function switch_to_blog( $new_blog ) {
299     global $wpdb, $table_prefix, $blog_id, $switched, $switched_stack, $wp_roles, $current_user;
300
301     if ( empty($new_blog) )
302         return false;
303
304     if ( empty($switched_stack) )
305         $switched_stack = array();
306
307     $switched_stack[] = $blog_id;
308
309     if ( $blog_id == $new_blog )
310         return false;
311
312     $wpdb->set_blog_id($new_blog);
313     $table_prefix = $wpdb->prefix;
314     $prev_blog_id = $blog_id;
315     $blog_id = $new_blog;
316
317     if( is_object( $wp_roles ) ) {
318         $wpdb->suppress_errors();
319         $wp_roles->_init();
320         $wpdb->suppress_errors( false );
321     }
322
323     if ( is_object( $current_user ) )
324         $current_user->_init_caps();
325
326     wp_cache_init();
327     if ( function_exists('wp_cache_add_global_groups') ) {
328         wp_cache_add_global_groups(array ('users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss'));
329         wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
330     }
331
332     do_action('switch_blog', $blog_id, $prev_blog_id);
333     $switched = true;
334     return true;
335 }
336
337 function restore_current_blog() {
338     global $table_prefix, $wpdb, $blog_id, $switched, $switched_stack, $wp_roles, $current_user;
339
340     if ( !$switched )
341         return false;
342
343     $blog = array_pop($switched_stack);
344     if ( $blog_id == $blog )
345         return false;
346
347     $wpdb->set_blog_id($blog);
348     $prev_blog_id = $blog_id;
349     $blog_id = $blog;
350     $table_prefix = $wpdb->prefix;
351
352     if( is_object( $wp_roles ) ) {
353         $wpdb->suppress_errors();
354         $wp_roles->_init();
355         $wpdb->suppress_errors( false );
356     }
357
358     if ( is_object( $current_user ) )
359         $current_user->_init_caps();
360
361     wp_cache_init();
362     if ( function_exists('wp_cache_add_global_groups') ) {
363         wp_cache_add_global_groups(array ('users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss'));
364         wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
365     }
366
367     do_action('switch_blog', $blog_id, $prev_blog_id);
368
369     $switched = false;
370     return true;
371 }
372
373 function get_blogs_of_user( $id, $all = false ) {
374     global $wpdb;
375
376     $user = get_userdata( (int) $id );
377     if ( !$user )
378         return false;
379
380     $blogs = $match = array();
381     foreach ( (array) $user as $key => $value ) {
382         if ( false !== strpos( $key, '_capabilities') && 0 === strpos( $key, $wpdb->base_prefix ) && preg_match( '/' . $wpdb->base_prefix . '(\d+)_capabilities/', $key, $match ) ) {
383             $blog = get_blog_details( $match[1] );
384             if ( $blog && isset( $blog->domain ) && ( $all == true || $all == false && ( $blog->archived == 0 && $blog->spam == 0 && $blog->deleted == 0 ) ) ) {
385                 $blogs[$match[1]]->userblog_id = $match[1];
386                 $blogs[$match[1]]->blogname    = $blog->blogname;
387                 $blogs[$match[1]]->domain      = $blog->domain;
388                 $blogs[$match[1]]->path        = $blog->path;
389                 $blogs[$match[1]]->site_id     = $blog->site_id;
390                 $blogs[$match[1]]->siteurl     = $blog->siteurl;
391             }
392         }
393     }
394
395     return $blogs;
396 }
397
398 function get_active_blog_for_user( $user_id ) { // get an active blog for user - either primary blog or from blogs list
399     global $wpdb;
400     $primary_blog = get_usermeta( $user_id, "primary_blog" );
401     if( $primary_blog == false ) {
402         $details = false;
403     } else {
404         $details = get_blog_details( $primary_blog );
405     }
406
407     if( ( is_object( $details ) == false ) || ( is_object( $details ) && $details->archived == 1 || $details->spam == 1 || $details->deleted == 1 ) ) {
408         $blogs = get_blogs_of_user( $user_id, true ); // if a user's primary blog is shut down, check their other blogs.
409         $ret = false;
410         if( is_array( $blogs ) && count( $blogs ) > 0 ) {
411             foreach( (array) $blogs as $blog_id => $blog ) {
412                 if ( $blog->site_id != $wpdb->siteid )
413                     continue;
414                 $details = get_blog_details( $blog_id );
415                 if( is_object( $details ) && $details->archived == 0 && $details->spam == 0 && $details->deleted == 0 ) {
416                     $ret = $blog;
417                     $changed = false;
418                     if( !get_usermeta($user_id , 'primary_blog') ) {
419                         update_usermeta($user_id, 'primary_blog', $blog->userblog_id);
420                         $changed = true;
421                     }
422                     if( !get_usermeta($user_id , 'source_domain') ) {
423                         update_usermeta($user_id, 'source_domain', $blog->domain);
424                         $changed = true;
425                     }
426                     if( $changed )
427                         wp_cache_delete( $user_id, 'users' );
428                     break;
429                 }
430             }
431         } else {
432             $ret = "username only"; // user has no blogs.
433         }
434         return $ret;
435     } else {
436         return $details;
437     }
438 }
439
440 function is_user_member_of_blog( $user_id, $blog_id = 0 ) {
441     $user_id = (int) $user_id;
442     $blog_id = (int) $blog_id;
443     
444     if( $blog_id == 0 ) {
445         global $wpdb;
446         $blog_id = $wpdb->blogid;
447     }
448     
449     $blogs = get_blogs_of_user( $user_id );
450     if( is_array( $blogs ) ) {
451         return array_key_exists( $blog_id, $blogs );
452     } else {
453         return false;
454     }
455 }
456
457 function is_archived( $id ) {
458     return get_blog_status($id, 'archived');
459 }
460
461 function update_archived( $id, $archived ) {
462     update_blog_status($id, 'archived', $archived);
463     return $archived;
464 }
465
466 function update_blog_status( $id, $pref, $value, $refresh = 1 ) {
467     global $wpdb;
468
469     $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $id) );
470     if( $refresh == 1 )
471         refresh_blog_details($id);
472
473     if( $pref == 'spam' ) {
474         if( $value == 1 ) {
475             do_action( "make_spam_blog", $id );
476         } else {
477             do_action( "make_ham_blog", $id );
478         }
479     }
480
481     return $value;
482 }
483
484 function get_blog_status( $id, $pref ) {
485     global $wpdb;
486
487     $details = get_blog_details( $id, false );
488     if( $details ) {
489         return $details->$pref;
490     }
491     return $wpdb->get_var( $wpdb->prepare("SELECT $pref FROM {$wpdb->blogs} WHERE blog_id = %d", $id) );
492 }
493
494 function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
495     global $wpdb;
496     return $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND last_updated != '0000-00-00 00:00:00' ORDER BY last_updated DESC limit %d, %d", $wpdb->siteid, $start, $quantity ) , ARRAY_A );
497 }
498
499 function get_most_active_blogs( $num = 10, $display = true ) {
500     $most_active = get_site_option( "most_active" );
501     $update = false;
502     if( is_array( $most_active ) ) {
503         if( ( $most_active['time'] + 60 ) < time() ) { // cache for 60 seconds.
504             $update = true;
505         }
506     } else {
507         $update = true;
508     }
509
510     if( $update == true ) {
511         unset( $most_active );
512         $blogs = get_blog_list( 0, 'all', false ); // $blog_id -> $details
513         if( is_array( $blogs ) ) {
514             reset( $blogs );
515             foreach ( (array) $blogs as $key => $details ) {
516                 $most_active[ $details['blog_id'] ] = $details['postcount'];
517                 $blog_list[ $details['blog_id'] ] = $details; // array_slice() removes keys!!
518             }
519             arsort( $most_active );
520             reset( $most_active );
521             foreach ( (array) $most_active as $key => $details ) {
522                 $t[ $key ] = $blog_list[ $key ];
523             }
524             unset( $most_active );
525             $most_active = $t;
526         }
527         update_site_option( "most_active", $most_active );
528     }
529
530     if( $display == true ) {
531         if( is_array( $most_active ) ) {
532             reset( $most_active );
533             foreach ( (array) $most_active as $key => $details ) {
534                 $url = clean_url("http://" . $details['domain'] . $details['path']);
535                 echo "<li>" . $details['postcount'] . " <a href='$url'>$url</a></li>";
536             }
537         }
538     }
539     return array_slice( $most_active, 0, $num );
540 }
541
542 function get_blog_list( $start = 0, $num = 10, $deprecated = '' ) {
543     global $wpdb;
544
545     $blogs = get_site_option( "blog_list" );
546     $update = false;
547     if( is_array( $blogs ) ) {
548         if( ( $blogs['time'] + 60 ) < time() ) { // cache for 60 seconds.
549             $update = true;
550         }
551     } else {
552         $update = true;
553     }
554
555     if( $update == true ) {
556         unset( $blogs );
557         $blogs = $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid), ARRAY_A );
558
559         foreach ( (array) $blogs as $details ) {
560             $blog_list[ $details['blog_id'] ] = $details;
561             $blog_list[ $details['blog_id'] ]['postcount'] = $wpdb->get_var( "SELECT COUNT(ID) FROM " . $wpdb->base_prefix . $details['blog_id'] . "_posts WHERE post_status='publish' AND post_type='post'" );
562         }
563         unset( $blogs );
564         $blogs = $blog_list;
565         update_site_option( "blog_list", $blogs );
566     }
567
568     if( false == is_array( $blogs ) )
569         return array();
570
571     if( $num == 'all' ) {
572         return array_slice( $blogs, $start, count( $blogs ) );
573     } else {
574         return array_slice( $blogs, $start, $num );
575     }
576 }
577
578 function get_user_count() {
579     global $wpdb;
580
581     $count_ts = get_site_option( "user_count_ts" );
582     if( time() - $count_ts > 3600 ) {
583         $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'") );
584         update_site_option( "user_count", $count );
585         update_site_option( "user_count_ts", time() );
586     }
587
588     $count = get_site_option( "user_count" );
589
590     return $count;
591 }
592
593 function get_blog_count( $id = 0 ) {
594     global $wpdb;
595
596     if( $id == 0 )
597         $id = $wpdb->siteid;
598
599     $count_ts = get_site_option( "blog_count_ts" );
600     if( time() - $count_ts > 3600 ) {
601         $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $id) );
602         update_site_option( "blog_count", $count );
603         update_site_option( "blog_count_ts", time() );
604     }
605
606     $count = get_site_option( "blog_count" );
607
608     return $count;
609 }
610
611 function get_blog_post( $blog_id, $post_id ) {
612     global $wpdb;
613
614     $key = $blog_id."-".$post_id."-blog_post";
615     $post = wp_cache_get( $key, "site-options" );
616     if( $post == false ) {
617         $post = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}{$blog_id}_posts WHERE ID = %d", $post_id) );
618         wp_cache_add( $key, $post, "site-options", 120 );
619     }
620
621     return $post;
622
623 }
624
625 function add_user_to_blog( $blog_id, $user_id, $role ) {
626     switch_to_blog($blog_id);
627
628     $user = new WP_User($user_id);
629
630     if ( empty($user) )
631         return new WP_Error('user_does_not_exist', __('That user does not exist.'));
632
633     if ( !get_usermeta($user_id, 'primary_blog') ) {
634         update_usermeta($user_id, 'primary_blog', $blog_id);
635         $details = get_blog_details($blog_id);
636         update_usermeta($user_id, 'source_domain', $details->domain);
637     }
638
639     $user->set_role($role);
640
641     do_action('add_user_to_blog', $user_id, $role, $blog_id);
642     wp_cache_delete( $user_id, 'users' );
643     restore_current_blog();
644     return true;
645 }
646
647 function remove_user_from_blog($user_id, $blog_id = '', $reassign = '') {
648     global $wpdb;
649     switch_to_blog($blog_id);
650     $user_id = (int) $user_id;
651     do_action('remove_user_from_blog', $user_id, $blog_id);
652
653     // If being removed from the primary blog, set a new primary if the user is assigned
654     // to multiple blogs.
655     $primary_blog = get_usermeta($user_id, 'primary_blog');
656     if ( $primary_blog == $blog_id ) {
657         $new_id = '';
658         $new_domain = '';
659         $blogs = get_blogs_of_user($user_id);
660         foreach ( (array) $blogs as $blog ) {
661             if ( $blog->userblog_id == $blog_id )
662                 continue;
663             $new_id = $blog->userblog_id;
664             $new_domain = $blog->domain;
665             break;
666         }
667
668         update_usermeta($user_id, 'primary_blog', $new_id);
669         update_usermeta($user_id, 'source_domain', $new_domain);
670     }
671
672     // wp_revoke_user($user_id);
673     $user = new WP_User($user_id);
674     $user->remove_all_caps();
675
676     $blogs = get_blogs_of_user($user_id);
677     if ( count($blogs) == 0 ) {
678         update_usermeta($user_id, 'primary_blog', '');
679         update_usermeta($user_id, 'source_domain', '');
680     }
681
682     if( $reassign != '' ) {
683         $reassign = (int) $reassign;
684         $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_author = %d WHERE post_author = %d", $reassign, $user_id) );
685         $wpdb->query( $wpdb->prepare("UPDATE $wpdb->links SET link_owner = %d WHERE link_owner = %d", $reassign, $user_id) );
686     }
687
688     restore_current_blog();
689 }
690
691 function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) {
692     $domain       = addslashes( $domain );
693     $weblog_title = addslashes( $weblog_title );
694
695     if( empty($path) )
696         $path = '/';
697
698     // Check if the domain has been used already. We should return an error message.
699     if ( domain_exists($domain, $path, $site_id) )
700         return __('error: Blog URL already taken.');
701
702     // Need to backup wpdb table names, and create a new wp_blogs entry for new blog.
703     // Need to get blog_id from wp_blogs, and create new table names.
704     // Must restore table names at the end of function.
705
706     if ( ! $blog_id = insert_blog($domain, $path, $site_id) )
707         return __('error: problem creating blog entry');
708
709     switch_to_blog($blog_id);
710     install_blog($blog_id);
711     restore_current_blog();
712
713     return $blog_id;
714 }
715
716 function get_blog_permalink( $blog_id, $post_id ) {
717     $key = "{$blog_id}-{$post_id}-blog_permalink";
718     $link = wp_cache_get( $key, 'site-options' );
719     if( $link == false ) {
720         switch_to_blog( $blog_id );
721         $link = get_permalink( $post_id );
722         restore_current_blog();
723         wp_cache_add( $key, $link, "site-options", 30 );
724     }
725     return $link;
726 }
727
728 function get_blog_id_from_url( $domain, $path = '/' ) {
729     global $wpdb;
730
731     $domain = strtolower( $wpdb->escape( $domain ) );
732     $path = strtolower( $wpdb->escape( $path ) );
733     $id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' );
734
735     if( $id == -1 ) { // blog does not exist
736         return 0;
737     } elseif( $id ) {
738         return (int)$id;
739     }
740
741     $id = $wpdb->get_var( "SELECT blog_id FROM $wpdb->blogs WHERE domain = '$domain' and path = '$path' /* get_blog_id_from_url */" );
742
743     if ( !$id ) {
744         wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' );
745         return false;
746     }
747     wp_cache_set( md5( $domain . $path ), $id, 'blog-id-cache' );
748
749     return $id;
750 }
751
752 // wpmu admin functions
753
754 function wpmu_admin_do_redirect( $url = '' ) {
755     $ref = '';
756     if ( isset( $_GET['ref'] ) )
757         $ref = $_GET['ref'];
758     if ( isset( $_POST['ref'] ) )
759         $ref = $_POST['ref'];
760
761     if( $ref ) {
762         $ref = wpmu_admin_redirect_add_updated_param( $ref );
763         wp_redirect( $ref );
764         exit();
765     }
766     if( empty( $_SERVER['HTTP_REFERER'] ) == false ) {
767         wp_redirect( $_SERVER['HTTP_REFERER'] );
768         exit();
769     }
770
771     $url = wpmu_admin_redirect_add_updated_param( $url );
772     if( isset( $_GET['redirect'] ) ) {
773         if( substr( $_GET['redirect'], 0, 2 ) == 's_' ) {
774             $url .= "&action=blogs&s=". wp_specialchars( substr( $_GET['redirect'], 2 ) );
775         }
776     } elseif( isset( $_POST['redirect'] ) ) {
777         $url = wpmu_admin_redirect_add_updated_param( $_POST['redirect'] );
778     }
779     wp_redirect( $url );
780     exit();
781 }
782
783 function wpmu_admin_redirect_add_updated_param( $url = '' ) {
784     if( strpos( $url, 'updated=true' ) === false ) {
785         if( strpos( $url, '?' ) === false ) {
786             return $url . '?updated=true';
787         } else {
788             return $url . '&updated=true';
789         }
790     }
791     return $url;
792 }
793
794 function wpmu_admin_redirect_url() {
795     if( isset( $_GET['s'] ) ) {
796         return "s_".$_GET['s'];
797     }
798 }
799
800 function is_blog_user( $blog_id = 0 ) {
801     global $current_user, $wpdb;
802
803     if ( !$blog_id )
804         $blog_id = $wpdb->blogid;
805
806     $cap_key = $wpdb->base_prefix . $blog_id . '_capabilities';
807
808     if ( is_array($current_user->$cap_key) && in_array(1, $current_user->$cap_key) )
809         return true;
810
811     return false;
812 }
813
814 function validate_email( $email, $check_domain = true) {
815     if (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.'@'.
816         '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
817         '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $email))
818     {
819         if ($check_domain && function_exists('checkdnsrr')) {
820             list (, $domain)  = explode('@', $email);
821
822             if (checkdnsrr($domain.'.', 'MX') || checkdnsrr($domain.'.', 'A')) {
823                 return true;
824             }
825             return false;
826         }
827         return true;
828     }
829     return false;
830 }
831
832 function is_email_address_unsafe( $user_email ) {
833     $banned_names = get_site_option( "banned_email_domains" );
834     if ( is_array( $banned_names ) && empty( $banned_names ) == false ) {
835         $email_domain = strtolower( substr( $user_email, 1 + strpos( $user_email, '@' ) ) );
836         foreach( (array) $banned_names as $banned_domain ) {
837             if( $banned_domain == '' )
838                 continue;
839             if (
840                 strstr( $email_domain, $banned_domain ) ||
841                 (
842                     strstr( $banned_domain, '/' ) &&
843                     preg_match( $banned_domain, $email_domain )
844                 )
845             )
846             return true;
847         }
848     }
849     return false;
850 }
851
852 function wpmu_validate_user_signup($user_name, $user_email) {
853     global $wpdb;
854
855     $errors = new WP_Error();
856
857     $user_name = preg_replace( "/\s+/", '', sanitize_user( $user_name, true ) );
858     $user_email = sanitize_email( $user_email );
859
860     if ( empty( $user_name ) )
861            $errors->add('user_name', __("Please enter a username"));
862
863     $maybe = array();
864     preg_match( "/[a-z0-9]+/", $user_name, $maybe );
865
866     if( $user_name != $maybe[0] ) {
867         $errors->add('user_name', __("Only lowercase letters and numbers allowed"));
868     }
869
870     $illegal_names = get_site_option( "illegal_names" );
871     if( is_array( $illegal_names ) == false ) {
872         $illegal_names = array(  "www", "web", "root", "admin", "main", "invite", "administrator" );
873         add_site_option( "illegal_names", $illegal_names );
874     }
875     if( in_array( $user_name, $illegal_names ) == true ) {
876         $errors->add('user_name'__("That username is not allowed"));
877     }
878
879     if( is_email_address_unsafe( $user_email ) )
880         $errors->add('user_email'__("You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider."));
881
882     if( strlen( $user_name ) < 4 ) {
883         $errors->add('user_name'__("Username must be at least 4 characters"));
884     }
885
886     if ( strpos( " " . $user_name, "_" ) != false )
887         $errors->add('user_name', __("Sorry, usernames may not contain the character '_'!"));
888
889     // all numeric?
890     $match = array();
891     preg_match( '/[0-9]*/', $user_name, $match );
892     if ( $match[0] == $user_name )
893         $errors->add('user_name', __("Sorry, usernames must have letters too!"));
894
895     if ( !is_email( $user_email ) )
896         $errors->add('user_email', __("Please enter a correct email address"));
897
898     if ( !validate_email( $user_email ) )
899         $errors->add('user_email', __("Please check your email address."));
900
901     $limited_email_domains = get_site_option( 'limited_email_domains' );
902     if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) {
903         $emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
904         if( in_array( $emaildomain, $limited_email_domains ) == false ) {
905             $errors->add('user_email', __("Sorry, that email address is not allowed!"));
906         }
907     }
908
909     // Check if the username has been used already.
910     if ( username_exists($user_name) )
911         $errors->add('user_name', __("Sorry, that username already exists!"));
912
913     // Check if the email address has been used already.
914     if ( email_exists($user_email) )
915         $errors->add('user_email', __("Sorry, that email address is already used!"));
916
917     // Has someone already signed up for this username?
918     $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) );
919     if ( $signup != null ) {
920         $registered_at mysql2date('U', $signup->registered);
921         $now = current_time( 'timestamp', true );
922         $diff = $now - $registered_at;
923         // If registered more than two days ago, cancel registration and let this signup go through.
924         if ( $diff > 172800 ) {
925             $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE user_login = %s", $user_name) );
926         } else {
927             $errors->add('user_name', __("That username is currently reserved but may be available in a couple of days."));
928         }
929         if( $signup->active == 0 && $signup->user_email == $user_email )
930             $errors->add('user_email_used', __("username and email used"));
931     }
932
933     $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email) );
934     if ( $signup != null ) {
935         $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered);
936         // If registered more than two days ago, cancel registration and let this signup go through.
937         if ( $diff > 172800 ) {
938             $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE user_email = %s", $user_email) );
939         } else {
940             $errors->add('user_email', __("That email address has already been used. Please check your inbox for an activation email. It will become available in a couple of days if you do nothing."));
941         }
942     }
943
944     $result = array('user_name' => $user_name, 'user_email' => $user_email,    'errors' => $errors);
945
946     return apply_filters('wpmu_validate_user_signup', $result);
947 }
948
949 function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') {
950     global $wpdb, $domain, $base;
951
952     $blogname = preg_replace( "/\s+/", '', sanitize_user( $blogname, true ) );
953     $blog_title = strip_tags( $blog_title );
954     $blog_title = substr( $blog_title, 0, 50 );
955
956     $errors = new WP_Error();
957     $illegal_names = get_site_option( "illegal_names" );
958     if( $illegal_names == false ) {
959         $illegal_names = array( "www", "web", "root", "admin", "main", "invite", "administrator" );
960         add_site_option( "illegal_names", $illegal_names );
961     }
962
963     if ( empty( $blogname ) )
964         $errors->add('blogname', __("Please enter a blog name"));
965
966     $maybe = array();
967     preg_match( "/[a-z0-9]+/", $blogname, $maybe );
968     if( $blogname != $maybe[0] ) {
969         $errors->add('blogname', __("Only lowercase letters and numbers allowed"));
970     }
971     if( in_array( $blogname, $illegal_names ) == true ) {
972         $errors->add('blogname'__("That name is not allowed"));
973     }
974     if( strlen( $blogname ) < 4 && !is_site_admin() ) {
975         $errors->add('blogname'__("Blog name must be at least 4 characters"));
976     }
977
978     if ( strpos( " " . $blogname, "_" ) != false )
979         $errors->add('blogname', __("Sorry, blog names may not contain the character '_'!"));
980
981     // all numeric?
982     $match = array();
983     preg_match( '/[0-9]*/', $blogname, $match );
984     if ( $match[0] == $blogname )
985         $errors->add('blogname', __("Sorry, blog names must have letters too!"));
986
987     $blogname = apply_filters( "newblogname", $blogname );
988
989     $blog_title = stripslashes$blog_title );
990
991     if ( empty( $blog_title ) )
992         $errors->add('blog_title', __("Please enter a blog title"));
993
994     // Check if the domain/path has been used already.
995     if( constant( "VHOST" ) == 'yes' ) {
996         $mydomain = "$blogname.$domain";
997         $path = $base;
998     } else {
999         $mydomain = "$domain";
1000         $path = $base.$blogname.'/';
1001     }
1002     if ( domain_exists($mydomain, $path) )
1003         $errors->add('blogname', __("Sorry, that blog already exists!"));
1004
1005     if ( username_exists($blogname) ) {
1006         if  ( !is_object($user) && ( $user->user_login != $blogname ) )
1007             $errors->add('blogname', __("Sorry, that blog is reserved!"));
1008     }
1009
1010     // Has someone already signed up for this domain?
1011     $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); // TODO: Check email too?
1012     if ( ! empty($signup) ) {
1013         $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered);
1014         // If registered more than two days ago, cancel registration and let this signup go through.
1015         if ( $diff > 172800 ) {
1016             $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) );
1017         } else {
1018             $errors->add('blogname', __("That blog is currently reserved but may be available in a couple days."));
1019         }
1020     }
1021
1022     $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors);
1023     return apply_filters('wpmu_validate_blog_signup', $result);
1024 }
1025
1026 // Record signup information for future activation. wpmu_validate_signup() should be run
1027 // on the inputs before calling wpmu_signup().
1028 function wpmu_signup_blog($domain, $path, $title, $user, $user_email, $meta = '') {
1029     global $wpdb;
1030
1031     // Format data
1032     $key = substr( md5( time() . rand() . $domain ), 0, 16 );
1033     $meta = serialize($meta);
1034     $domain = $wpdb->escape($domain);
1035     $path = $wpdb->escape($path);
1036     $title = $wpdb->escape($title);
1037                     
1038     $wpdb->insert( $wpdb->signups, array(
1039         'domain' => $domain,
1040         'path' => $path,
1041         'title' => $title,
1042         'user_login' => $user,
1043         'user_email' => $user_email,
1044         'registered' => current_time('mysql', true),
1045         'activation_key' => $key,
1046         'meta' => $meta
1047     ) );
1048
1049     wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta);
1050 }
1051
1052 function wpmu_signup_user($user, $user_email, $meta = '') {
1053     global $wpdb;
1054
1055     // Format data
1056     $user = preg_replace( "/\s+/", '', sanitize_user( $user, true ) );
1057     $user_email = sanitize_email( $user_email );
1058     $key = substr( md5( time() . rand() . $user_email ), 0, 16 );
1059     $meta = serialize($meta);
1060                     
1061     $wpdb->insert( $wpdb->signups, array(
1062         'domain' => '',
1063         'path' => '',
1064         'title' => '',
1065         'user_login' => $user,
1066         'user_email' => $user_email,
1067         'registered' => current_time('mysql', true),
1068         'activation_key' => $key,
1069         'meta' => $meta
1070     ) );
1071
1072     wpmu_signup_user_notification($user, $user_email, $key, $meta);
1073 }
1074
1075 // Notify user of signup success.
1076 function wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta = '') {
1077     global $current_site;
1078
1079     if( !apply_filters('wpmu_signup_blog_notification', $domain, $path, $title, $user, $user_email, $key, $meta) )
1080         return false;
1081
1082     // Send email with activation link.
1083     if( constant( "VHOST" ) == 'no' ) {
1084         $activate_url = "http://" . $current_site->domain . $current_site->path . "wp-activate.php?key=$key";
1085     } else {
1086         $activate_url = "http://{$domain}{$path}wp-activate.php?key=$key";
1087     }
1088     $activate_url = clean_url($activate_url);
1089     $admin_email = get_site_option( "admin_email" );
1090     if( $admin_email == '' )
1091         $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
1092     $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
1093     $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
1094     $message = sprintf( __( apply_filters( 'wpmu_signup_blog_notification_email', "To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your blog here:\n\n%s" ) ), $activate_url, clean_url( "http://{$domain}{$path}" ) );
1095     // TODO: Don't hard code activation link.
1096     $subject = sprintf( __( apply_filters( 'wpmu_signup_blog_notification_subject', '[%s] Activate %s' ) ), $from_name, clean_url( 'http://' . $domain . $path ) );
1097     wp_mail($user_email, $subject, $message, $message_headers);
1098     return true;
1099 }
1100
1101 function wpmu_signup_user_notification($user, $user_email, $key, $meta = '') {
1102     global $current_site;
1103
1104     if( !apply_filters('wpmu_signup_user_notification', $user, $user_email, $key, $meta) )
1105         return false;
1106
1107     // Send email with activation link.
1108     $admin_email = get_site_option( "admin_email" );
1109     if( $admin_email == '' )
1110         $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
1111     $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
1112     $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
1113     $message = sprintf(__( apply_filters( 'wpmu_signup_user_notification_email', "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\n" ) ), clean_url("http://{$current_site->domain}{$current_site->path}wp-activate.php?key=$key") );
1114     // TODO: Don't hard code activation link.
1115     $subject = sprintf(__( apply_filters( 'wpmu_signup_user_notification_subject', 'Activate %s' )), $user);
1116     wp_mail($user_email, $subject, $message, $message_headers);
1117     return true;
1118 }
1119
1120 function wpmu_activate_signup($key) {
1121     global $wpdb;
1122
1123     $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) );
1124
1125     if ( empty($signup) )
1126         return new WP_Error('invalid_key', __('Invalid activation key.'));
1127
1128     if ( $signup->active )
1129         return new WP_Error('already_active', __('The blog is already active.'), $signup);
1130
1131     $meta = unserialize($signup->meta);
1132     $user_login = $wpdb->escape($signup->user_login);
1133     $user_email = $wpdb->escape($signup->user_email);
1134     wpmu_validate_user_signup($user_login, $user_email);
1135     $password = generate_random_password();
1136
1137     $user_id = username_exists($user_login);
1138
1139     if ( ! $user_id )
1140         $user_id = wpmu_create_user($user_login, $password, $user_email);
1141     else
1142         $user_already_exists = true;
1143
1144     if ( ! $user_id )
1145         return new WP_Error('create_user', __('Could not create user'), $signup);
1146
1147     $now = current_time('mysql', true);
1148
1149     if ( empty($signup->domain) ) {
1150         $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
1151         if ( isset($user_already_exists) )
1152             return new WP_Error('user_already_exists', __('That username is already activated.'), $signup);
1153         wpmu_welcome_user_notification($user_id, $password, $meta);
1154         if ( get_site_option( 'dashboard_blog' ) == false ) {
1155             add_user_to_blog( '1', $user_id, get_site_option( 'default_user_role', 'subscriber' ) );
1156         } else {
1157             add_user_to_blog( get_site_option( 'dashboard_blog' ), $user_id, get_site_option( 'default_user_role', 'subscriber' ) );
1158         }
1159         add_new_user_to_blog( $user_id, $user_email, $meta );
1160         do_action('wpmu_activate_user', $user_id, $password, $meta);
1161         return array('user_id' => $user_id, 'password' => $password, 'meta' => $meta);
1162     }
1163
1164     wpmu_validate_blog_signup($signup->domain, $signup->title);
1165     $blog_id = wpmu_create_blog($signup->domain, $signup->path, $signup->title, $user_id, $meta, $wpdb->siteid);
1166
1167     // TODO: What to do if we create a user but cannot create a blog?
1168     if ( is_wp_error($blog_id) ) {
1169         // If blog is taken, that means a previous attempt to activate this blog failed in between creating the blog and
1170         // setting the activation flag.  Let's just set the active flag and instruct the user to reset their password.
1171         if ( 'blog_taken' == $blog_id->get_error_code() ) {
1172             $blog_id->add_data($signup);
1173             $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
1174         }
1175
1176         return $blog_id;
1177     }
1178
1179     $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) );
1180
1181     wpmu_welcome_notification($blog_id, $user_id, $password, $signup->title, $meta);
1182
1183     do_action('wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta);
1184
1185     return array('blog_id' => $blog_id, 'user_id' => $user_id, 'password' => $password, 'title' => $signup->title, 'meta' => $meta);
1186 }
1187
1188 function generate_random_password( $len = 8 ) {
1189     $random_password = substr(md5(uniqid(microtime())), 0, intval( $len ) );
1190     $random_password = apply_filters('random_password', $random_password);
1191     return $random_password;
1192 }
1193
1194 function wpmu_create_user( $user_name, $password, $email) {
1195     $user_name = preg_replace( "/\s+/", '', sanitize_user( $user_name, true ) );
1196     if ( username_exists($user_name) )
1197         return false;
1198
1199     // Check if the email address has been used already.
1200     if ( email_exists($email) )
1201         return false;
1202
1203     $user_id = wp_create_user( $user_name, $password, $email );
1204     $user = new WP_User($user_id);
1205     
1206     // Newly created users have no roles or caps until they are added to a blog.
1207     update_user_option($user_id, 'capabilities', '');
1208     update_user_option($user_id, 'user_level', '');
1209
1210     do_action( 'wpmu_new_user', $user_id );
1211
1212     return $user_id;
1213 }
1214
1215 function wpmu_create_blog($domain, $path, $title, $user_id, $meta = '', $site_id = 1) {
1216     $domain = preg_replace( "/\s+/", '', sanitize_user( $domain, true ) );
1217     if( constant( 'VHOST' ) == 'yes' )
1218         $domain = str_replace( '@', '', $domain );
1219     $title = strip_tags( $title );
1220     $user_id = (int) $user_id;
1221
1222     if( empty($path) )
1223         $path = '/';
1224
1225     // Check if the domain has been used already. We should return an error message.
1226     if ( domain_exists($domain, $path, $site_id) )
1227         return new WP_Error('blog_taken', __('Blog already exists.'));
1228
1229     if ( !defined("WP_INSTALLING") )
1230         define( "WP_INSTALLING", true );
1231
1232     if ( ! $blog_id = insert_blog($domain, $path, $site_id) )
1233         return new WP_Error('insert_blog', __('Could not create blog.'));
1234
1235     switch_to_blog($blog_id);
1236
1237     install_blog($blog_id, $title);
1238
1239     install_blog_defaults($blog_id, $user_id);
1240
1241     add_user_to_blog($blog_id, $user_id, 'administrator');
1242
1243     if ( is_array($meta) ) foreach ($meta as $key => $value) {
1244         if( $key == 'public' || $key == 'archived' || $key == 'mature' || $key == 'spam' || $key == 'deleted' || $key == 'lang_id' ) {
1245             update_blog_status( $blog_id, $key, $value );
1246         } else {
1247             update_option( $key, $value );
1248         }
1249     }
1250
1251     add_option( 'WPLANG', get_site_option( 'WPLANG' ) );
1252
1253     update_option( 'blog_public', $meta['public'] );
1254
1255     if ( !is_site_admin() && get_usermeta( $user_id, 'primary_blog' ) == get_site_option( 'dashboard_blog', 1 ) )
1256         update_usermeta( $user_id, 'primary_blog', $blog_id );
1257
1258
1259     restore_current_blog();
1260
1261     do_action( 'wpmu_new_blog', $blog_id, $user_id );
1262
1263     return $blog_id;
1264 }
1265
1266 function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) {
1267     global $current_site;
1268     if( get_site_option( 'registrationnotification' ) != 'yes' )
1269         return false;
1270         
1271     $email = get_site_option( 'admin_email' );
1272     if( is_email($email) == false )
1273         return false;
1274     
1275     $options_site_url = clean_url("http://{$current_site->domain}{$current_site->path}wp-admin/wpmu-options.php");
1276
1277     switch_to_blog( $blog_id );
1278     $blogname = get_option( 'blogname' );
1279     $siteurl = get_option( 'siteurl' );
1280     restore_current_blog();
1281     
1282     $msg = sprintf( __( "New Blog: %1s
1283 URL: %2s
1284 Remote IP: %3s
1285
1286 Disable these notifications: %4s"), $blogname, $siteurl, $_SERVER['REMOTE_ADDR'], $options_site_url);
1287     $msg = apply_filters( 'newblog_notify_siteadmin', $msg );
1288     
1289     wp_mail( $email, sprintf( __( "New Blog Registration: %s" ), $siteurl ), $msg );
1290     return true;
1291 }
1292
1293 function newuser_notify_siteadmin( $user_id ) {
1294     global $current_site;
1295     if( get_site_option( 'registrationnotification' ) != 'yes' )
1296         return false;
1297         
1298     $email = get_site_option( 'admin_email' );
1299     if( is_email($email) == false )
1300         return false;
1301     $user = new WP_User($user_id);
1302
1303     $options_site_url = clean_url("http://{$current_site->domain}{$current_site->path}wp-admin/wpmu-options.php");
1304     $msg = sprintf(__("New User: %1s
1305 Remote IP: %2s
1306
1307 Disable these notifications: %3s"), $user->user_login, $_SERVER['REMOTE_ADDR'], $options_site_url);
1308     
1309     $msg = apply_filters( 'newuser_notify_siteadmin', $msg );
1310     wp_mail( $email, sprintf(__("New User Registration: %s"), $user->user_login), $msg );
1311     return true;
1312 }
1313
1314 function domain_exists($domain, $path, $site_id = 1) {
1315     global $wpdb;
1316     return $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) );
1317 }
1318
1319 function insert_blog($domain, $path, $site_id) {
1320     global $wpdb;
1321     
1322     $path = trailingslashit($path);
1323     $site_id = (int) $site_id;
1324     
1325     $wpdb->insert( $wpdb->blogs, array('site_id' => $site_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')) );
1326     if ( !$wpdb->insert_id )
1327         return false;
1328
1329     refresh_blog_details($wpdb->insert_id);
1330     return $wpdb->insert_id;
1331 }
1332
1333 // Install an empty blog.  wpdb should already be switched.
1334 function install_blog($blog_id, $blog_title = '') {
1335     global $wpdb, $table_prefix, $wp_roles;
1336     $wpdb->suppress_errors();
1337
1338     // Cast for security
1339     $blog_id = (int) $blog_id;
1340
1341     require_once( ABSPATH . 'wp-admin/includes/upgrade.php');
1342
1343     if ( $wpdb->get_results("SELECT ID FROM $wpdb->posts") )
1344         die(__('<h1>Already Installed</h1><p>You appear to have already installed WordPress. To reinstall please clear your old database tables first.</p>') . '</body></html>');
1345     $wpdb->suppress_errors( false);
1346
1347     $url = get_blogaddress_by_id($blog_id);
1348
1349     // Set everything up
1350     make_db_current_silent();
1351     populate_options();
1352     populate_roles();
1353     $wp_roles->_init();
1354
1355     // fix url.
1356     update_option('siteurl', $url);
1357     update_option('home', $url);
1358     update_option('fileupload_url', $url . "files" );
1359     update_option('upload_path', "wp-content/blogs.dir/" . $blog_id . "/files");
1360     update_option('blogname', $blog_title);
1361     update_option('admin_email', '');
1362     $wpdb->update( $wpdb->options, array('option_value' => ''), array('option_name' => 'admin_email') );
1363
1364     // Default category
1365     $wpdb->insert( $wpdb->terms, array('term_id' => 1, 'name' => __('Uncategorized'), 'slug' => sanitize_title(__('Uncategorized')), 'term_group' => 0) );
1366     $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => 1, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1) );
1367
1368     // Default link category
1369     $cat_name = __('Blogroll');
1370     $cat_slug = sanitize_title($cat_name);
1371     
1372     $blogroll_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) );
1373     if( $blogroll_id == null ) {
1374         $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) );
1375         $blogroll_id = $wpdb->insert_id;
1376     }
1377     $wpdb->insert( $wpdb->terms, array('term_id' => $blogroll_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) );
1378     $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $blogroll_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 2) );
1379     update_option('default_link_category', $blogroll_id);
1380
1381     // remove all perms
1382     $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key = %s", $table_prefix.'user_level') );
1383     $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key = %s", $table_prefix.'capabilities') );
1384
1385
1386     $wpdb->suppress_errors( false );
1387 }
1388
1389 function install_blog_defaults($blog_id, $user_id) {
1390     global $wpdb, $wp_rewrite, $current_site, $table_prefix;
1391
1392     $wpdb->suppress_errors();
1393
1394     // Cast for security
1395     $user_id = (int) $user_id;
1396     $blog_id = (int) $blog_id;
1397
1398     // Default links
1399     $wpdb->insert( $wpdb->links,  array('link_url' => 'http://wordpress.com/', 'link_name' => 'WordPress.com', 'link_category' => '1356', 'link_owner' => $user_id, 'link_rss' => 'http://wordpress.com/feed/') );
1400     $wpdb->insert( $wpdb->links,  array('link_url' => 'http://wordpress.org/', 'link_name' => 'WordPress.org', 'link_category' => '1356', 'link_owner' => $user_id, 'link_rss' => 'http://wordpress.org/development/feed/') );
1401     $wpdb->insert( $wpdb->term_relationships, array('object_id' => 1, 'term_taxonomy_id' => 2));
1402     $wpdb->insert( $wpdb->term_relationships, array('object_id' => 2, 'term_taxonomy_id' => 2));
1403
1404     // First post
1405     $now = date('Y-m-d H:i:s');
1406     $now_gmt = gmdate('Y-m-d H:i:s');
1407     $first_post = get_site_option( 'first_post' );
1408     if( $first_post == false ) {
1409         $first_post = stripslashes( __( 'Welcome to <a href="SITE_URL">SITE_NAME</a>. This is your first post. Edit or delete it, then start blogging!' ) );
1410     }
1411     $first_post = str_replace( "SITE_URL", clean_url("http://" . $current_site->domain . $current_site->path), $first_post );
1412     $first_post = str_replace( "SITE_NAME", $current_site->site_name, $first_post );
1413     $wpdb->insert( $wpdb->posts, array(
1414         'post_author' => $user_id,
1415         'post_date' => $now,
1416         'post_date_gmt' => $now_gmt,
1417         'post_content' => stripslashes( $first_post ),
1418         'post_excerpt' => '',
1419         'post_title' => __('Hello world!'),
1420         'post_name' => __('hello-world'),
1421         'post_modified' => $now,
1422         'post_modified_gmt' => $now_gmt,
1423         'comment_count' => 1
1424     ) );   
1425     $wpdb->insert( $wpdb->term_relationships, array('object_id' => 1, 'term_taxonomy_id' => 1));
1426     update_option( "post_count", 1 );
1427
1428     // First page
1429     $wpdb->insert( $wpdb->posts, array(
1430         'post_author' => $user_id,
1431         'post_date' => $now,
1432         'post_date_gmt' => $now_gmt,
1433         'post_content' => __('This is an example of a WordPress page, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many pages like this one or sub-pages as you like and manage all of your content inside of WordPress.'),
1434         'post_excerpt' => '',
1435         'post_title' => __('About'),
1436         'post_name' => __('about'),
1437         'post_modified' => $now,
1438         'post_modified_gmt' => $now_gmt,
1439         'post_status' => 'publish',
1440         'post_type' => 'page',
1441         'to_ping' => '',
1442         'pinged' => '',
1443         'post_content_filtered' => ''
1444     ) );
1445     
1446     // Flush rules to pick up the new page.
1447     $wp_rewrite->init();
1448     $wp_rewrite->flush_rules();
1449
1450     // Default comment
1451     $wpdb->insert( $wpdb->comments, array(
1452         'comment_post_ID' => '1',
1453         'comment_author' => __('Mr WordPress'),
1454         'comment_author_email' => '',
1455         'comment_author_url' => 'http://' . $current_site->domain . $current_site->path,
1456         'comment_author_IP' => '127.0.0.1',
1457         'comment_date' => $now,
1458         'comment_date_gmt' => $now_gmt,
1459         'comment_content' => __("Hi, this is a comment.<br />To delete a comment, just log in, and view the posts' comments, there you will have the option to edit or delete them.")
1460     ) );
1461     
1462     $user = new WP_User($user_id);
1463     $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') );
1464
1465     // Remove all perms except for the login user.
1466     $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') );
1467     $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') );
1468     
1469     // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id.
1470     if ( !is_site_admin( $user->user_login ) && $user_id != 1 )
1471         $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $wpdb->base_prefix.'1_capabilities') );
1472
1473     $wpdb->suppress_errors( false );
1474 }
1475
1476 function wpmu_welcome_notification($blog_id, $user_id, $password, $title, $meta = '') {
1477     global $current_site;
1478
1479     if( !apply_filters('wpmu_welcome_notification', $blog_id, $user_id, $password, $title, $meta) )
1480         return false;
1481
1482     $welcome_email = stripslashes( get_site_option( 'welcome_email' ) );
1483     if( $welcome_email == false )
1484         $welcome_email = stripslashes( __( "Dear User,
1485
1486 Your new SITE_NAME blog has been successfully set up at:
1487 BLOG_URL
1488
1489 You can log in to the administrator account with the following information:
1490 Username: USERNAME
1491 Password: PASSWORD
1492 Login Here: BLOG_URLwp-login.php
1493
1494 We hope you enjoy your new weblog.
1495 Thanks!
1496
1497 --The WordPress Team
1498 SITE_NAME" ) );
1499
1500     $url = get_blogaddress_by_id($blog_id);
1501     $user = new WP_User($user_id);
1502
1503     $welcome_email = str_replace( "SITE_NAME", $current_site->site_name, $welcome_email );
1504     $welcome_email = str_replace( "BLOG_URL", $url, $welcome_email );
1505     $welcome_email = str_replace( "USERNAME", $user->user_login, $welcome_email );
1506     $welcome_email = str_replace( "PASSWORD", $password, $welcome_email );
1507
1508     $welcome_email = apply_filters( "update_welcome_email", $welcome_email, $blog_id, $user_id, $password, $title, $meta);
1509     $admin_email = get_site_option( "admin_email" );
1510     if( $admin_email == '' )
1511         $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
1512     $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
1513     $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
1514     $message = $welcome_email;
1515     if( empty( $current_site->site_name ) )
1516         $current_site->site_name = "WordPress MU";
1517     $subject = apply_filters( 'update_welcome_subject', sprintf(__('New %1$s Blog: %2$s'), $current_site->site_name, stripslashes( $title ) ) );
1518     wp_mail($user->user_email, $subject, $message, $message_headers);
1519     return true;
1520 }
1521
1522 function wpmu_welcome_user_notification($user_id, $password, $meta = '') {
1523     global $current_site;
1524
1525     if( !apply_filters('wpmu_welcome_user_notification', $user_id, $password, $meta) )
1526         return false;
1527
1528     $welcome_email = __( "Dear User,
1529
1530 Your new account is setup.
1531
1532 You can log in with the following information:
1533 Username: USERNAME
1534 Password: PASSWORD
1535 LOGINLINK
1536
1537 Thanks!
1538
1539 --The WordPress Team
1540 SITE_NAME" );
1541
1542     $user = new WP_User($user_id);
1543
1544     $welcome_email = apply_filters( "update_welcome_user_email", $welcome_email, $user_id, $password, $meta);
1545     $welcome_email = str_replace( "SITE_NAME", $current_site->site_name, $welcome_email );
1546     $welcome_email = str_replace( "USERNAME", $user->user_login, $welcome_email );
1547     $welcome_email = str_replace( "PASSWORD", $password, $welcome_email );
1548     $welcome_email = str_replace( "LOGINLINK", site_url( 'wp-login.php' ), $welcome_email );
1549
1550     $admin_email = get_site_option( "admin_email" );
1551     if( $admin_email == '' )
1552         $admin_email = 'support@' . $_SERVER['SERVER_NAME'];
1553     $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) );
1554     $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
1555     $message = $welcome_email;
1556     if( empty( $current_site->site_name ) )
1557         $current_site->site_name = "WordPress MU";
1558     $subject = apply_filters( 'update_welcome_user_subject', sprintf(__('New %1$s User: %2$s'), $current_site->site_name, $user->user_login) );
1559     wp_mail($user->user_email, $subject, $message, $message_headers);
1560     return true;
1561 }
1562
1563 function get_current_site() {
1564     global $current_site;
1565     return $current_site;
1566 }
1567
1568 function get_user_id_from_string( $string ) {
1569     global $wpdb;
1570     if( is_email( $string ) ) {
1571         return $wpdb->get_var( $wpdb->prepare("SELECT ID FROM {$wpdb->users} WHERE user_email = %s", $string) );
1572     } elseif ( is_numeric( $string ) ) {
1573         return $string;
1574     }
1575     return $wpdb->get_var( $wpdb->prepare("SELECT ID FROM {$wpdb->users} WHERE user_login = %s", $string) );
1576 }
1577
1578 function get_most_recent_post_of_user( $user_id ) {
1579     global $wpdb;
1580
1581     $user_blogs = get_blogs_of_user( (int) $user_id );
1582     $most_recent_post = array();
1583
1584     // Walk through each blog and get the most recent post
1585     // published by $user_id
1586     foreach ( (array) $user_blogs as $blog ) {
1587         $recent_post = $wpdb->get_row( $wpdb->prepare("SELECT ID, post_date_gmt FROM {$wpdb->base_prefix}{$blog->userblog_id}_posts WHERE post_author = %d AND post_type = 'post' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1", $user_id ), ARRAY_A);
1588
1589         // Make sure we found a post
1590         if ( isset($recent_post['ID']) ) {
1591             $post_gmt_ts = strtotime($recent_post['post_date_gmt']);
1592
1593             // If this is the first post checked or if this post is
1594             // newer than the current recent post, make it the new
1595             // most recent post.
1596             if (
1597                 !isset($most_recent_post['post_gmt_ts'])
1598                 || ($post_gmt_ts > $most_recent_post['post_gmt_ts'])
1599             ) {
1600                 $most_recent_post = array(
1601                     'blog_id'        => $blog->userblog_id,
1602                     'post_id'        => $recent_post['ID'],
1603                     'post_date_gmt'    => $recent_post['post_date_gmt'],
1604                     'post_gmt_ts'    => $post_gmt_ts
1605                 );
1606             }
1607         }
1608     }
1609
1610     return $most_recent_post;
1611 }
1612
1613 /* Misc functions */
1614 function fix_upload_details( $uploads ) {
1615     $uploads['url'] = str_replace( UPLOADS, "files", $uploads['url'] );
1616     $uploads['baseurl'] = str_replace( UPLOADS, "files", $uploads['baseurl'] );
1617     return $uploads;
1618 }
1619
1620 function get_dirsize($directory) {
1621     $size = 0;
1622     if(substr($directory,-1) == '/') $directory = substr($directory,0,-1);
1623     if(!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) return false;
1624     if($handle = opendir($directory)) {
1625         while(($file = readdir($handle)) !== false) {
1626             $path = $directory.'/'.$file;
1627             if($file != '.' && $file != '..') {
1628                 if(is_file($path)) {
1629                     $size += filesize($path);
1630                 } elseif(is_dir($path)) {
1631                     $handlesize = get_dirsize($path);
1632                     if($handlesize >= 0) {
1633                         $size += $handlesize;
1634                     } else {
1635                         return false;
1636                     }
1637                 }
1638             }
1639         }
1640         closedir($handle);
1641     }
1642     return $size;
1643 }
1644
1645 function upload_is_user_over_quota( $echo = true ) {
1646     $spaceAllowed = get_space_allowed();
1647     if(empty($spaceAllowed) || !is_numeric($spaceAllowed))
1648         $spaceAllowed = 10;    // Default space allowed is 10 MB
1649     
1650     $dirName = BLOGUPLOADDIR;
1651     $size = get_dirsize($dirName) / 1024 / 1024;
1652     
1653     if( ($spaceAllowed-$size) < 0 ) {
1654         if( $echo )
1655             _e( "Sorry, you have used your space allocation. Please delete some files to upload more files." ); //No space left
1656         return true;
1657     } else {
1658         return false;
1659     }
1660 }
1661
1662 function check_upload_mimes($mimes) {
1663     $site_exts = explode( " ", get_site_option( "upload_filetypes" ) );
1664     foreach ( $site_exts as $ext ) {
1665         foreach ( $mimes as $ext_pattern => $mime ) {
1666             if( $ext != '' && strpos( $ext_pattern, $ext ) !== false ) {
1667                 $site_mimes[$ext_pattern] = $mime;
1668             }
1669         }
1670     }
1671     return $site_mimes;
1672 }
1673
1674 function update_posts_count( $deprecated = '' ) {
1675     global $wpdb;
1676     update_option( "post_count", (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ) );
1677 }
1678
1679 function wpmu_log_new_registrations( $blog_id, $user_id ) {
1680     global $wpdb;
1681     $user = new WP_User( (int) $user_id );
1682     $wpdb->insert( $wpdb->registration_log, array('email' => $user->user_email, 'IP' => preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] ), 'blog_id' => $blog_id, 'date_registered' => current_time('mysql')) );
1683 }
1684
1685 function fix_import_form_size( $size ) {
1686     if( upload_is_user_over_quota( false ) == true ) {
1687         return 0;
1688     }
1689     
1690     $spaceAllowed = 1024 * 1024 * get_space_allowed();
1691     $dirName = BLOGUPLOADDIR;
1692     $dirsize = get_dirsize($dirName) ;
1693     if( $size > $spaceAllowed - $dirsize ) {
1694         return $spaceAllowed - $dirsize; // remaining space
1695     } else {
1696         return $size; // default
1697     }
1698 }
1699
1700 if ( !function_exists('graceful_fail') ) :
1701 function graceful_fail( $message ) {
1702     $message = apply_filters('graceful_fail', $message);
1703     $message_template = apply_filters( 'graceful_fail_template',
1704 '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1705 <html xmlns="http://www.w3.org/1999/xhtml"><head profile="http://gmpg.org/xfn/11">
1706 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
1707 <title>Error!</title>
1708 <style type="text/css">
1709 img {
1710     border: 0;
1711 }
1712 body {
1713 line-height: 1.6em; font-family: Georgia, serif; width: 390px; margin: auto;
1714 text-align: center;
1715 }
1716 .message {
1717     font-size: 22px;
1718     width: 350px;
1719     margin: auto;
1720 }
1721 </style>
1722 </head>
1723 <body>
1724 <p class="message">%s</p>
1725 </body>
1726 </html>' );
1727     die( sprintf( $message_template, $message ) );
1728 }
1729 endif;
1730
1731 /* Delete blog */
1732 class delete_blog {
1733     function delete_blog() {
1734         $this->reallydeleteblog = false;
1735         add_action('admin_menu', array(&$this, 'admin_menu'));
1736         add_action('admin_footer', array(&$this, 'admin_footer'));
1737     }
1738
1739     function admin_footer() {
1740         global $wpdb, $current_blog, $current_site;
1741         if( $current_blog->domain . $current_blog->path == $current_site->domain . $current_site->path )
1742             return false;
1743
1744         if( $this->reallydeleteblog == true ) {
1745             wpmu_delete_blog( $wpdb->blogid );
1746         }
1747     }
1748
1749     function admin_menu() {
1750         global $current_blog, $current_site;
1751         if( $current_blog->domain . $current_blog->path != $current_site->domain . $current_site->path )
1752             add_submenu_page('options-general.php', __('Delete Blog'), __('Delete Blog'), 'manage_options', 'delete-blog', array(&$this, 'plugin_content'));
1753     }
1754
1755     function plugin_content() {
1756         global $current_blog, $current_site;
1757         $this->delete_blog_hash = get_settings('delete_blog_hash');
1758         echo '<div class="wrap"><h2>' . __('Delete Blog') . '</h2>';
1759         if( $_POST['action'] == "deleteblog" && $_POST['confirmdelete'] == '1' ) {
1760             $hash = substr( md5( $_SERVER['REQUEST_URI'] . time() ), 0, 6 );
1761             update_option( "delete_blog_hash", $hash );
1762             $url_delete = get_option( "siteurl" ) . "/wp-admin/options-general.php?page=delete-blog&h=" . $hash;
1763             $msg = __("Dear User,
1764 You recently clicked the 'Delete Blog' link on your blog and filled in a
1765 form on that page.
1766 If you really want to delete your blog, click the link below. You will not
1767 be asked to confirm again so only click this link if you are 100% certain:
1768 URL_DELETE
1769
1770 If you delete your blog, please consider opening a new blog here
1771 some time in the future! (But remember your current blog and username
1772 are gone forever.)
1773
1774 Thanks for using the site,
1775 Webmaster
1776 SITE_NAME
1777 ");
1778             $msg = str_replace( "URL_DELETE", $url_delete, $msg );
1779             $msg = str_replace( "SITE_NAME", $current_site->site_name, $msg );
1780             wp_mail( get_option( "admin_email" ), "[ " . get_option( "blogname" ) . " ] ".__("Delete My Blog"), $msg );
1781             ?>
1782             <p><?php _e('Thank you. Please check your email for a link to confirm your action. Your blog will not be deleted until this link is clicked.') ?></p>
1783             <?php
1784         } elseif( isset( $_GET['h'] ) && $_GET['h'] != '' && get_option('delete_blog_hash') != false ) {
1785             if( get_option('delete_blog_hash') == $_GET['h'] ) {
1786                 $this->reallydeleteblog = true;
1787                 echo "<p>" . sprintf(__('Thank you for using %s, your blog has been deleted. Happy trails to you until we meet again.'), $current_site->site_name) . "</p>";
1788             } else {
1789                 $this->reallydeleteblog = false;
1790                 echo "<p>" . __("I'm sorry, the link you clicked is stale. Please select another option.") . "</p>";
1791             }
1792         } else {
1793 ?>
1794             <p><?php printf(__('If you do not want to use your %s blog any more, you can delete it using the form below. When you click <strong>Delete My Blog</strong> you will be sent an email with a link in it. Click on this link to delete your blog.'), $current_site->site_name); ?></p>
1795             <p><?php _e('Remember, once deleted your blog cannot be restored.') ?></p>
1796             <form method='post'