WordPress 3.8
[autoinstalls/wordpress.git] / wp-includes / ms-blogs.php
1 <?php
2
3 /**
4  * Site/blog functions that work with the blogs table and related data.
5  *
6  * @package WordPress
7  * @subpackage Multisite
8  * @since MU
9  */
10
11 /**
12  * Update the last_updated field for the current blog.
13  *
14  * @since MU
15  */
16 function wpmu_update_blogs_date() {
17         global $wpdb;
18
19         update_blog_details( $wpdb->blogid, array('last_updated' => current_time('mysql', true)) );
20         /**
21          * Fires after the blog details are updated.
22          *
23          * @since MU
24          *
25          * @param int $blog_id Blog ID.
26          */
27         do_action( 'wpmu_blog_updated', $wpdb->blogid );
28 }
29
30 /**
31  * Get a full blog URL, given a blog id.
32  *
33  * @since MU
34  *
35  * @param int $blog_id Blog ID
36  * @return string
37  */
38 function get_blogaddress_by_id( $blog_id ) {
39         $bloginfo = get_blog_details( (int) $blog_id, false ); // only get bare details!
40         return esc_url( 'http://' . $bloginfo->domain . $bloginfo->path );
41 }
42
43 /**
44  * Get a full blog URL, given a blog name.
45  *
46  * @since MU
47  *
48  * @param string $blogname The (subdomain or directory) name
49  * @return string
50  */
51 function get_blogaddress_by_name( $blogname ) {
52         if ( is_subdomain_install() ) {
53                 if ( $blogname == 'main' )
54                         $blogname = 'www';
55                 $url = rtrim( network_home_url(), '/' );
56                 if ( !empty( $blogname ) )
57                         $url = preg_replace( '|^([^\.]+://)|', "\${1}" . $blogname . '.', $url );
58         } else {
59                 $url = network_home_url( $blogname );
60         }
61         return esc_url( $url . '/' );
62 }
63
64 /**
65  * Given a blog's (subdomain or directory) slug, retrieve its id.
66  *
67  * @since MU
68  *
69  * @param string $slug
70  * @return int A blog id
71  */
72 function get_id_from_blogname( $slug ) {
73         global $wpdb;
74
75         $current_site = get_current_site();
76         $slug = trim( $slug, '/' );
77
78         $blog_id = wp_cache_get( 'get_id_from_blogname_' . $slug, 'blog-details' );
79         if ( $blog_id )
80                 return $blog_id;
81
82         if ( is_subdomain_install() ) {
83                 $domain = $slug . '.' . $current_site->domain;
84                 $path = $current_site->path;
85         } else {
86                 $domain = $current_site->domain;
87                 $path = $current_site->path . $slug . '/';
88         }
89
90         $blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domain, $path) );
91         wp_cache_set( 'get_id_from_blogname_' . $slug, $blog_id, 'blog-details' );
92         return $blog_id;
93 }
94
95 /**
96  * Retrieve the details for a blog from the blogs table and blog options.
97  *
98  * @since MU
99  *
100  * @param int|string|array $fields A blog ID, a blog slug, or an array of fields to query against. Optional. If not specified the current blog ID is used.
101  * @param bool $get_all Whether to retrieve all details or only the details in the blogs table. Default is true.
102  * @return object Blog details.
103  */
104 function get_blog_details( $fields = null, $get_all = true ) {
105         global $wpdb;
106
107         if ( is_array($fields ) ) {
108                 if ( isset($fields['blog_id']) ) {
109                         $blog_id = $fields['blog_id'];
110                 } elseif ( isset($fields['domain']) && isset($fields['path']) ) {
111                         $key = md5( $fields['domain'] . $fields['path'] );
112                         $blog = wp_cache_get($key, 'blog-lookup');
113                         if ( false !== $blog )
114                                 return $blog;
115                         if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) {
116                                 $nowww = substr( $fields['domain'], 4 );
117                                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) AND path = %s ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'], $fields['path'] ) );
118                         } else {
119                                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $fields['domain'], $fields['path'] ) );
120                         }
121                         if ( $blog ) {
122                                 wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details');
123                                 $blog_id = $blog->blog_id;
124                         } else {
125                                 return false;
126                         }
127                 } elseif ( isset($fields['domain']) && is_subdomain_install() ) {
128                         $key = md5( $fields['domain'] );
129                         $blog = wp_cache_get($key, 'blog-lookup');
130                         if ( false !== $blog )
131                                 return $blog;
132                         if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) {
133                                 $nowww = substr( $fields['domain'], 4 );
134                                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'] ) );
135                         } else {
136                                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $fields['domain'] ) );
137                         }
138                         if ( $blog ) {
139                                 wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details');
140                                 $blog_id = $blog->blog_id;
141                         } else {
142                                 return false;
143                         }
144                 } else {
145                         return false;
146                 }
147         } else {
148                 if ( ! $fields )
149                         $blog_id = get_current_blog_id();
150                 elseif ( ! is_numeric( $fields ) )
151                         $blog_id = get_id_from_blogname( $fields );
152                 else
153                         $blog_id = $fields;
154         }
155
156         $blog_id = (int) $blog_id;
157
158         $all = $get_all == true ? '' : 'short';
159         $details = wp_cache_get( $blog_id . $all, 'blog-details' );
160
161         if ( $details ) {
162                 if ( ! is_object( $details ) ) {
163                         if ( $details == -1 ) {
164                                 return false;
165                         } else {
166                                 // Clear old pre-serialized objects. Cache clients do better with that.
167                                 wp_cache_delete( $blog_id . $all, 'blog-details' );
168                                 unset($details);
169                         }
170                 } else {
171                         return $details;
172                 }
173         }
174
175         // Try the other cache.
176         if ( $get_all ) {
177                 $details = wp_cache_get( $blog_id . 'short', 'blog-details' );
178         } else {
179                 $details = wp_cache_get( $blog_id, 'blog-details' );
180                 // If short was requested and full cache is set, we can return.
181                 if ( $details ) {
182                         if ( ! is_object( $details ) ) {
183                                 if ( $details == -1 ) {
184                                         return false;
185                                 } else {
186                                         // Clear old pre-serialized objects. Cache clients do better with that.
187                                         wp_cache_delete( $blog_id, 'blog-details' );
188                                         unset($details);
189                                 }
190                         } else {
191                                 return $details;
192                         }
193                 }
194         }
195
196         if ( empty($details) ) {
197                 $details = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE blog_id = %d /* get_blog_details */", $blog_id ) );
198                 if ( ! $details ) {
199                         // Set the full cache.
200                         wp_cache_set( $blog_id, -1, 'blog-details' );
201                         return false;
202                 }
203         }
204
205         if ( ! $get_all ) {
206                 wp_cache_set( $blog_id . $all, $details, 'blog-details' );
207                 return $details;
208         }
209
210         switch_to_blog( $blog_id );
211         $details->blogname              = get_option( 'blogname' );
212         $details->siteurl               = get_option( 'siteurl' );
213         $details->post_count    = get_option( 'post_count' );
214         restore_current_blog();
215
216         /**
217          * Filter a blog's details.
218          *
219          * @since MU
220          *
221          * @param object $details The blog details.
222          */
223         $details = apply_filters( 'blog_details', $details );
224
225         wp_cache_set( $blog_id . $all, $details, 'blog-details' );
226
227         $key = md5( $details->domain . $details->path );
228         wp_cache_set( $key, $details, 'blog-lookup' );
229
230         return $details;
231 }
232
233 /**
234  * Clear the blog details cache.
235  *
236  * @since MU
237  *
238  * @param int $blog_id Blog ID
239  */
240 function refresh_blog_details( $blog_id ) {
241         $blog_id = (int) $blog_id;
242         $details = get_blog_details( $blog_id, false );
243         if ( ! $details ) {
244                 // Make sure clean_blog_cache() gets the blog ID
245                 // when the blog has been previously cached as
246                 // non-existent.
247                 $details = (object) array(
248                         'blog_id' => $blog_id,
249                         'domain' => null,
250                         'path' => null
251                 );
252         }
253
254         clean_blog_cache( $details );
255
256         /**
257          * Fires after the blog details cache is cleared.
258          *
259          * @since 3.4.0
260          *
261          * @param int $blog_id Blog ID.
262          */
263         do_action( 'refresh_blog_details', $blog_id );
264 }
265
266 /**
267  * Update the details for a blog. Updates the blogs table for a given blog id.
268  *
269  * @since MU
270  *
271  * @param int $blog_id Blog ID
272  * @param array $details Array of details keyed by blogs table field names.
273  * @return bool True if update succeeds, false otherwise.
274  */
275 function update_blog_details( $blog_id, $details = array() ) {
276         global $wpdb;
277
278         if ( empty($details) )
279                 return false;
280
281         if ( is_object($details) )
282                 $details = get_object_vars($details);
283
284         $current_details = get_blog_details($blog_id, false);
285         if ( empty($current_details) )
286                 return false;
287
288         $current_details = get_object_vars($current_details);
289
290         $details = array_merge($current_details, $details);
291         $details['last_updated'] = current_time('mysql', true);
292
293         $update_details = array();
294         $fields = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id');
295         foreach ( array_intersect( array_keys( $details ), $fields ) as $field )
296                 $update_details[$field] = $details[$field];
297
298         $result = $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) );
299
300         if ( false === $result )
301                 return false;
302
303         // If spam status changed, issue actions.
304         if ( $details['spam'] != $current_details['spam'] ) {
305                 if ( $details['spam'] == 1 ) {
306                         /**
307                          * Fires when the blog status is changed to 'spam'.
308                          *
309                          * @since MU
310                          *
311                          * @param int $blog_id Blog ID.
312                          */
313                         do_action( 'make_spam_blog', $blog_id );
314                 } else {
315                         /**
316                          * Fires when the blog status is changed to 'ham'.
317                          *
318                          * @since MU
319                          *
320                          * @param int $blog_id Blog ID.
321                          */
322                         do_action( 'make_ham_blog', $blog_id );
323                 }
324         }
325
326         // If mature status changed, issue actions.
327         if ( $details['mature'] != $current_details['mature'] ) {
328                 if ( $details['mature'] == 1 ) {
329                         /**
330                          * Fires when the blog status is changed to 'mature'.
331                          *
332                          * @since 3.1.0
333                          *
334                          * @param int $blog_id Blog ID.
335                          */
336                         do_action( 'mature_blog', $blog_id );
337                 } else {
338                         /**
339                          * Fires when the blog status is changed to 'unmature'.
340                          *
341                          * @since 3.1.0
342                          *
343                          * @param int $blog_id Blog ID.
344                          */
345                         do_action( 'unmature_blog', $blog_id );
346                 }
347         }
348
349         // If archived status changed, issue actions.
350         if ( $details['archived'] != $current_details['archived'] ) {
351                 if ( $details['archived'] == 1 ) {
352                         /**
353                          * Fires when the blog status is changed to 'archived'.
354                          *
355                          * @since MU
356                          *
357                          * @param int $blog_id Blog ID.
358                          */
359                         do_action( 'archive_blog', $blog_id );
360                 } else {
361                         /**
362                          * Fires when the blog status is changed to 'unarchived'.
363                          *
364                          * @since MU
365                          *
366                          * @param int $blog_id Blog ID.
367                          */
368                         do_action( 'unarchive_blog', $blog_id );
369                 }
370         }
371
372         // If deleted status changed, issue actions.
373         if ( $details['deleted'] != $current_details['deleted'] ) {
374                 if ( $details['deleted'] == 1 ) {
375                         /**
376                          * Fires when the blog status is changed to 'deleted'.
377                          *
378                          * @since 3.5.0
379                          *
380                          * @param int $blog_id Blog ID.
381                          */
382                         do_action( 'make_delete_blog', $blog_id );
383                 } else {
384                         /**
385                          * Fires when the blog status is changed to 'undeleted'.
386                          *
387                          * @since 3.5.0
388                          *
389                          * @param int $blog_id Blog ID.
390                          */
391                         do_action( 'make_undelete_blog', $blog_id );
392                 }
393         }
394
395         if ( isset( $details['public'] ) ) {
396                 switch_to_blog( $blog_id );
397                 update_option( 'blog_public', $details['public'] );
398                 restore_current_blog();
399         }
400
401         refresh_blog_details($blog_id);
402
403         return true;
404 }
405
406 /**
407  * Clean the blog cache
408  *
409  * @since 3.5.0
410  *
411  * @param stdClass $blog The blog details as returned from get_blog_details()
412  */
413 function clean_blog_cache( $blog ) {
414         $blog_id = $blog->blog_id;
415         $domain_path_key = md5( $blog->domain . $blog->path );
416
417         wp_cache_delete( $blog_id , 'blog-details' );
418         wp_cache_delete( $blog_id . 'short' , 'blog-details' );
419         wp_cache_delete(  $domain_path_key, 'blog-lookup' );
420         wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
421         wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
422         wp_cache_delete( 'get_id_from_blogname_' . trim( $blog->path, '/' ), 'blog-details' );
423         wp_cache_delete( $domain_path_key, 'blog-id-cache' );
424 }
425
426 /**
427  * Retrieve option value for a given blog id based on name of option.
428  *
429  * If the option does not exist or does not have a value, then the return value
430  * will be false. This is useful to check whether you need to install an option
431  * and is commonly used during installation of plugin options and to test
432  * whether upgrading is required.
433  *
434  * If the option was serialized then it will be unserialized when it is returned.
435  *
436  * @since MU
437  *
438  * @param int $id A blog ID. Can be null to refer to the current blog.
439  * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
440  * @param mixed $default Optional. Default value to return if the option does not exist.
441  * @return mixed Value set for the option.
442  */
443 function get_blog_option( $id, $option, $default = false ) {
444         $id = (int) $id;
445
446         if ( empty( $id ) )
447                 $id = get_current_blog_id();
448
449         if ( get_current_blog_id() == $id )
450                 return get_option( $option, $default );
451
452         switch_to_blog( $id );
453         $value = get_option( $option, $default );
454         restore_current_blog();
455
456         /**
457          * Filter a blog option value.
458          *
459          * The dynamic portion of the hook name, $option, refers to the blog option name.
460          *
461          * @since 3.5.0
462          *
463          * @param string  $value The option value.
464          * @param int     $id    Blog ID.
465          */
466         return apply_filters( "blog_option_{$option}", $value, $id );
467 }
468
469 /**
470  * Add a new option for a given blog id.
471  *
472  * You do not need to serialize values. If the value needs to be serialized, then
473  * it will be serialized before it is inserted into the database. Remember,
474  * resources can not be serialized or added as an option.
475  *
476  * You can create options without values and then update the values later.
477  * Existing options will not be updated and checks are performed to ensure that you
478  * aren't adding a protected WordPress option. Care should be taken to not name
479  * options the same as the ones which are protected.
480  *
481  * @since MU
482  *
483  * @param int $id A blog ID. Can be null to refer to the current blog.
484  * @param string $option Name of option to add. Expected to not be SQL-escaped.
485  * @param mixed $value Optional. Option value, can be anything. Expected to not be SQL-escaped.
486  * @return bool False if option was not added and true if option was added.
487  */
488 function add_blog_option( $id, $option, $value ) {
489         $id = (int) $id;
490
491         if ( empty( $id ) )
492                 $id = get_current_blog_id();
493
494         if ( get_current_blog_id() == $id )
495                 return add_option( $option, $value );
496
497         switch_to_blog( $id );
498         $return = add_option( $option, $value );
499         restore_current_blog();
500
501         return $return;
502 }
503
504 /**
505  * Removes option by name for a given blog id. Prevents removal of protected WordPress options.
506  *
507  * @since MU
508  *
509  * @param int $id A blog ID. Can be null to refer to the current blog.
510  * @param string $option Name of option to remove. Expected to not be SQL-escaped.
511  * @return bool True, if option is successfully deleted. False on failure.
512  */
513 function delete_blog_option( $id, $option ) {
514         $id = (int) $id;
515
516         if ( empty( $id ) )
517                 $id = get_current_blog_id();
518
519         if ( get_current_blog_id() == $id )
520                 return delete_option( $option );
521
522         switch_to_blog( $id );
523         $return = delete_option( $option );
524         restore_current_blog();
525
526         return $return;
527 }
528
529 /**
530  * Update an option for a particular blog.
531  *
532  * @since MU
533  *
534  * @param int $id The blog id
535  * @param string $option The option key
536  * @param mixed $value The option value
537  * @return bool True on success, false on failure.
538  */
539 function update_blog_option( $id, $option, $value, $deprecated = null ) {
540         $id = (int) $id;
541
542         if ( null !== $deprecated  )
543                 _deprecated_argument( __FUNCTION__, '3.1' );
544
545         if ( get_current_blog_id() == $id )
546                 return update_option( $option, $value );
547
548         switch_to_blog( $id );
549         $return = update_option( $option, $value );
550         restore_current_blog();
551
552         refresh_blog_details( $id );
553
554         return $return;
555 }
556
557 /**
558  * Switch the current blog.
559  *
560  * This function is useful if you need to pull posts, or other information,
561  * from other blogs. You can switch back afterwards using restore_current_blog().
562  *
563  * Things that aren't switched:
564  *  - autoloaded options. See #14992
565  *  - plugins. See #14941
566  *
567  * @see restore_current_blog()
568  * @since MU
569  *
570  * @param int $new_blog The id of the blog you want to switch to. Default: current blog
571  * @param bool $deprecated Deprecated argument
572  * @return bool True on success, false if the validation failed
573  */
574 function switch_to_blog( $new_blog, $deprecated = null ) {
575         global $wpdb, $wp_roles;
576
577         if ( empty( $new_blog ) )
578                 $new_blog = $GLOBALS['blog_id'];
579
580         $GLOBALS['_wp_switched_stack'][] = $GLOBALS['blog_id'];
581
582         /*
583          * If we're switching to the same blog id that we're on,
584          * set the right vars, do the associated actions, but skip
585          * the extra unnecessary work
586          */
587         if ( $new_blog == $GLOBALS['blog_id'] ) {
588                 /**
589                  * Fires when the blog is switched.
590                  *
591                  * @since MU
592                  *
593                  * @param int $new_blog New blog ID.
594                  * @param int $new_blog Blog ID.
595                  */
596                 do_action( 'switch_blog', $new_blog, $new_blog );
597                 $GLOBALS['switched'] = true;
598                 return true;
599         }
600
601         $wpdb->set_blog_id( $new_blog );
602         $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
603         $prev_blog_id = $GLOBALS['blog_id'];
604         $GLOBALS['blog_id'] = $new_blog;
605
606         if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
607                 wp_cache_switch_to_blog( $new_blog );
608         } else {
609                 global $wp_object_cache;
610
611                 if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
612                         $global_groups = $wp_object_cache->global_groups;
613                 else
614                         $global_groups = false;
615
616                 wp_cache_init();
617
618                 if ( function_exists( 'wp_cache_add_global_groups' ) ) {
619                         if ( is_array( $global_groups ) )
620                                 wp_cache_add_global_groups( $global_groups );
621                         else
622                                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', ' blog-id-cache' ) );
623                         wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
624                 }
625         }
626
627         if ( did_action( 'init' ) ) {
628                 $wp_roles->reinit();
629                 $current_user = wp_get_current_user();
630                 $current_user->for_blog( $new_blog );
631         }
632
633         /** This filter is documented in wp-includes/ms-blogs.php */
634         do_action( 'switch_blog', $new_blog, $prev_blog_id );
635         $GLOBALS['switched'] = true;
636
637         return true;
638 }
639
640 /**
641  * Restore the current blog, after calling switch_to_blog()
642  *
643  * @see switch_to_blog()
644  * @since MU
645  *
646  * @return bool True on success, false if we're already on the current blog
647  */
648 function restore_current_blog() {
649         global $wpdb, $wp_roles;
650
651         if ( empty( $GLOBALS['_wp_switched_stack'] ) )
652                 return false;
653
654         $blog = array_pop( $GLOBALS['_wp_switched_stack'] );
655
656         if ( $GLOBALS['blog_id'] == $blog ) {
657                 /** This filter is documented in wp-includes/ms-blogs.php */
658                 do_action( 'switch_blog', $blog, $blog );
659                 // If we still have items in the switched stack, consider ourselves still 'switched'
660                 $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
661                 return true;
662         }
663
664         $wpdb->set_blog_id( $blog );
665         $prev_blog_id = $GLOBALS['blog_id'];
666         $GLOBALS['blog_id'] = $blog;
667         $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
668
669         if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
670                 wp_cache_switch_to_blog( $blog );
671         } else {
672                 global $wp_object_cache;
673
674                 if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
675                         $global_groups = $wp_object_cache->global_groups;
676                 else
677                         $global_groups = false;
678
679                 wp_cache_init();
680
681                 if ( function_exists( 'wp_cache_add_global_groups' ) ) {
682                         if ( is_array( $global_groups ) )
683                                 wp_cache_add_global_groups( $global_groups );
684                         else
685                                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', ' blog-id-cache' ) );
686                         wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
687                 }
688         }
689
690         if ( did_action( 'init' ) ) {
691                 $wp_roles->reinit();
692                 $current_user = wp_get_current_user();
693                 $current_user->for_blog( $blog );
694         }
695
696         /** This filter is documented in wp-includes/ms-blogs.php */
697         do_action( 'switch_blog', $blog, $prev_blog_id );
698
699         // If we still have items in the switched stack, consider ourselves still 'switched'
700         $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
701
702         return true;
703 }
704
705 /**
706  * Determines if switch_to_blog() is in effect
707  *
708  * @since 3.5.0
709  *
710  * @return bool True if switched, false otherwise.
711  */
712 function ms_is_switched() {
713         return ! empty( $GLOBALS['_wp_switched_stack'] );
714 }
715
716 /**
717  * Check if a particular blog is archived.
718  *
719  * @since MU
720  *
721  * @param int $id The blog id
722  * @return string Whether the blog is archived or not
723  */
724 function is_archived( $id ) {
725         return get_blog_status($id, 'archived');
726 }
727
728 /**
729  * Update the 'archived' status of a particular blog.
730  *
731  * @since MU
732  *
733  * @param int $id The blog id
734  * @param string $archived The new status
735  * @return string $archived
736  */
737 function update_archived( $id, $archived ) {
738         update_blog_status($id, 'archived', $archived);
739         return $archived;
740 }
741
742 /**
743  * Update a blog details field.
744  *
745  * @since MU
746  *
747  * @param int $blog_id BLog ID
748  * @param string $pref A field name
749  * @param string $value Value for $pref
750  * @return string $value
751  */
752 function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
753         global $wpdb;
754
755         if ( null !== $deprecated  )
756                 _deprecated_argument( __FUNCTION__, '3.1' );
757
758         if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) )
759                 return $value;
760
761         $result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) );
762
763         if ( false === $result )
764                 return false;
765
766         refresh_blog_details( $blog_id );
767
768         if ( 'spam' == $pref ) {
769                 if ( $value == 1 ) {
770                         /** This filter is documented in wp-includes/ms-blogs.php */
771                         do_action( 'make_spam_blog', $blog_id );
772                 } else {
773                         /** This filter is documented in wp-includes/ms-blogs.php */
774                         do_action( 'make_ham_blog', $blog_id );
775                 }
776         } elseif ( 'mature' == $pref ) {
777                 if ( $value == 1 ) {
778                         /** This filter is documented in wp-includes/ms-blogs.php */
779                         do_action( 'mature_blog', $blog_id );
780                 } else {
781                         /** This filter is documented in wp-includes/ms-blogs.php */
782                         do_action( 'unmature_blog', $blog_id );
783                 }
784         } elseif ( 'archived' == $pref ) {
785                 if ( $value == 1 ) {
786                         /** This filter is documented in wp-includes/ms-blogs.php */
787                         do_action( 'archive_blog', $blog_id );
788                 } else {
789                         /** This filter is documented in wp-includes/ms-blogs.php */
790                         do_action( 'unarchive_blog', $blog_id );
791                 }
792         } elseif ( 'deleted' == $pref ) {
793                 if ( $value == 1 ) {
794                         /** This filter is documented in wp-includes/ms-blogs.php */
795                         do_action( 'make_delete_blog', $blog_id );
796                 } else {
797                         /** This filter is documented in wp-includes/ms-blogs.php */
798                         do_action( 'make_undelete_blog', $blog_id );
799                 }
800         } elseif ( 'public' == $pref ) {
801                 /**
802                  * Fires after the current blog's 'public' setting is updated.
803                  *
804                  * @since MU
805                  *
806                  * @param int    $blog_id Blog ID.
807                  * @param string $value   The value of blog status.
808                  */
809                 do_action( 'update_blog_public', $blog_id, $value ); // Moved here from update_blog_public().
810         }
811
812         return $value;
813 }
814
815 /**
816  * Get a blog details field.
817  *
818  * @since MU
819  *
820  * @param int $id The blog id
821  * @param string $pref A field name
822  * @return bool $value
823  */
824 function get_blog_status( $id, $pref ) {
825         global $wpdb;
826
827         $details = get_blog_details( $id, false );
828         if ( $details )
829                 return $details->$pref;
830
831         return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) );
832 }
833
834 /**
835  * Get a list of most recently updated blogs.
836  *
837  * @since MU
838  *
839  * @param mixed $deprecated Not used
840  * @param int $start The offset
841  * @param int $quantity The maximum number of blogs to retrieve. Default is 40.
842  * @return array The list of blogs
843  */
844 function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
845         global $wpdb;
846
847         if ( ! empty( $deprecated ) )
848                 _deprecated_argument( __FUNCTION__, 'MU' ); // never used
849
850         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 );
851 }
852
853 /**
854  * Handler for updating the blog date when a post is published or an already published post is changed.
855  *
856  * @since 3.3.0
857  *
858  * @param string $new_status The new post status
859  * @param string $old_status The old post status
860  * @param object $post Post object
861  */
862 function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
863         $post_type_obj = get_post_type_object( $post->post_type );
864         if ( ! $post_type_obj->public )
865                 return;
866
867         if ( 'publish' != $new_status && 'publish' != $old_status )
868                 return;
869
870         // Post was freshly published, published post was saved, or published post was unpublished.
871
872         wpmu_update_blogs_date();
873 }
874
875 /**
876  * Handler for updating the blog date when a published post is deleted.
877  *
878  * @since 3.4.0
879  *
880  * @param int $post_id Post ID
881  */
882 function _update_blog_date_on_post_delete( $post_id ) {
883         $post = get_post( $post_id );
884
885         $post_type_obj = get_post_type_object( $post->post_type );
886         if ( ! $post_type_obj->public )
887                 return;
888
889         if ( 'publish' != $post->post_status )
890                 return;
891
892         wpmu_update_blogs_date();
893 }
894