WordPress 4.2
[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 Full URL of the blog if found. Empty string if not.
37  */
38 function get_blogaddress_by_id( $blog_id ) {
39         $bloginfo = get_blog_details( (int) $blog_id, false ); // only get bare details!
40         return ( $bloginfo ) ? 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|false Blog details on success. False on failure.
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 Optional. Blog ID. Defaults to current blog.
239  */
240 function refresh_blog_details( $blog_id = 0 ) {
241         $blog_id = (int) $blog_id;
242         if ( ! $blog_id ) {
243                 $blog_id = get_current_blog_id();
244         }
245
246         $details = get_blog_details( $blog_id, false );
247         if ( ! $details ) {
248                 // Make sure clean_blog_cache() gets the blog ID
249                 // when the blog has been previously cached as
250                 // non-existent.
251                 $details = (object) array(
252                         'blog_id' => $blog_id,
253                         'domain' => null,
254                         'path' => null
255                 );
256         }
257
258         clean_blog_cache( $details );
259
260         /**
261          * Fires after the blog details cache is cleared.
262          *
263          * @since 3.4.0
264          *
265          * @param int $blog_id Blog ID.
266          */
267         do_action( 'refresh_blog_details', $blog_id );
268 }
269
270 /**
271  * Update the details for a blog. Updates the blogs table for a given blog id.
272  *
273  * @since MU
274  *
275  * @param int $blog_id Blog ID
276  * @param array $details Array of details keyed by blogs table field names.
277  * @return bool True if update succeeds, false otherwise.
278  */
279 function update_blog_details( $blog_id, $details = array() ) {
280         global $wpdb;
281
282         if ( empty($details) )
283                 return false;
284
285         if ( is_object($details) )
286                 $details = get_object_vars($details);
287
288         $current_details = get_blog_details($blog_id, false);
289         if ( empty($current_details) )
290                 return false;
291
292         $current_details = get_object_vars($current_details);
293
294         $details = array_merge($current_details, $details);
295         $details['last_updated'] = current_time('mysql', true);
296
297         $update_details = array();
298         $fields = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id');
299         foreach ( array_intersect( array_keys( $details ), $fields ) as $field ) {
300                 if ( 'path' === $field ) {
301                         $details[ $field ] = trailingslashit( '/' . trim( $details[ $field ], '/' ) );
302                 }
303
304                 $update_details[ $field ] = $details[ $field ];
305         }
306
307         $result = $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) );
308
309         if ( false === $result )
310                 return false;
311
312         // If spam status changed, issue actions.
313         if ( $details['spam'] != $current_details['spam'] ) {
314                 if ( $details['spam'] == 1 ) {
315                         /**
316                          * Fires when the blog status is changed to 'spam'.
317                          *
318                          * @since MU
319                          *
320                          * @param int $blog_id Blog ID.
321                          */
322                         do_action( 'make_spam_blog', $blog_id );
323                 } else {
324                         /**
325                          * Fires when the blog status is changed to 'ham'.
326                          *
327                          * @since MU
328                          *
329                          * @param int $blog_id Blog ID.
330                          */
331                         do_action( 'make_ham_blog', $blog_id );
332                 }
333         }
334
335         // If mature status changed, issue actions.
336         if ( $details['mature'] != $current_details['mature'] ) {
337                 if ( $details['mature'] == 1 ) {
338                         /**
339                          * Fires when the blog status is changed to 'mature'.
340                          *
341                          * @since 3.1.0
342                          *
343                          * @param int $blog_id Blog ID.
344                          */
345                         do_action( 'mature_blog', $blog_id );
346                 } else {
347                         /**
348                          * Fires when the blog status is changed to 'unmature'.
349                          *
350                          * @since 3.1.0
351                          *
352                          * @param int $blog_id Blog ID.
353                          */
354                         do_action( 'unmature_blog', $blog_id );
355                 }
356         }
357
358         // If archived status changed, issue actions.
359         if ( $details['archived'] != $current_details['archived'] ) {
360                 if ( $details['archived'] == 1 ) {
361                         /**
362                          * Fires when the blog status is changed to 'archived'.
363                          *
364                          * @since MU
365                          *
366                          * @param int $blog_id Blog ID.
367                          */
368                         do_action( 'archive_blog', $blog_id );
369                 } else {
370                         /**
371                          * Fires when the blog status is changed to 'unarchived'.
372                          *
373                          * @since MU
374                          *
375                          * @param int $blog_id Blog ID.
376                          */
377                         do_action( 'unarchive_blog', $blog_id );
378                 }
379         }
380
381         // If deleted status changed, issue actions.
382         if ( $details['deleted'] != $current_details['deleted'] ) {
383                 if ( $details['deleted'] == 1 ) {
384                         /**
385                          * Fires when the blog status is changed to 'deleted'.
386                          *
387                          * @since 3.5.0
388                          *
389                          * @param int $blog_id Blog ID.
390                          */
391                         do_action( 'make_delete_blog', $blog_id );
392                 } else {
393                         /**
394                          * Fires when the blog status is changed to 'undeleted'.
395                          *
396                          * @since 3.5.0
397                          *
398                          * @param int $blog_id Blog ID.
399                          */
400                         do_action( 'make_undelete_blog', $blog_id );
401                 }
402         }
403
404         if ( isset( $details['public'] ) ) {
405                 switch_to_blog( $blog_id );
406                 update_option( 'blog_public', $details['public'] );
407                 restore_current_blog();
408         }
409
410         refresh_blog_details($blog_id);
411
412         return true;
413 }
414
415 /**
416  * Clean the blog cache
417  *
418  * @since 3.5.0
419  *
420  * @param stdClass $blog The blog details as returned from get_blog_details()
421  */
422 function clean_blog_cache( $blog ) {
423         $blog_id = $blog->blog_id;
424         $domain_path_key = md5( $blog->domain . $blog->path );
425
426         wp_cache_delete( $blog_id , 'blog-details' );
427         wp_cache_delete( $blog_id . 'short' , 'blog-details' );
428         wp_cache_delete(  $domain_path_key, 'blog-lookup' );
429         wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
430         wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
431         wp_cache_delete( 'get_id_from_blogname_' . trim( $blog->path, '/' ), 'blog-details' );
432         wp_cache_delete( $domain_path_key, 'blog-id-cache' );
433 }
434
435 /**
436  * Retrieve option value for a given blog id based on name of option.
437  *
438  * If the option does not exist or does not have a value, then the return value
439  * will be false. This is useful to check whether you need to install an option
440  * and is commonly used during installation of plugin options and to test
441  * whether upgrading is required.
442  *
443  * If the option was serialized then it will be unserialized when it is returned.
444  *
445  * @since MU
446  *
447  * @param int $id A blog ID. Can be null to refer to the current blog.
448  * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
449  * @param mixed $default Optional. Default value to return if the option does not exist.
450  * @return mixed Value set for the option.
451  */
452 function get_blog_option( $id, $option, $default = false ) {
453         $id = (int) $id;
454
455         if ( empty( $id ) )
456                 $id = get_current_blog_id();
457
458         if ( get_current_blog_id() == $id )
459                 return get_option( $option, $default );
460
461         switch_to_blog( $id );
462         $value = get_option( $option, $default );
463         restore_current_blog();
464
465         /**
466          * Filter a blog option value.
467          *
468          * The dynamic portion of the hook name, `$option`, refers to the blog option name.
469          *
470          * @since 3.5.0
471          *
472          * @param string  $value The option value.
473          * @param int     $id    Blog ID.
474          */
475         return apply_filters( "blog_option_{$option}", $value, $id );
476 }
477
478 /**
479  * Add a new option for a given blog id.
480  *
481  * You do not need to serialize values. If the value needs to be serialized, then
482  * it will be serialized before it is inserted into the database. Remember,
483  * resources can not be serialized or added as an option.
484  *
485  * You can create options without values and then update the values later.
486  * Existing options will not be updated and checks are performed to ensure that you
487  * aren't adding a protected WordPress option. Care should be taken to not name
488  * options the same as the ones which are protected.
489  *
490  * @since MU
491  *
492  * @param int $id A blog ID. Can be null to refer to the current blog.
493  * @param string $option Name of option to add. Expected to not be SQL-escaped.
494  * @param mixed $value Optional. Option value, can be anything. Expected to not be SQL-escaped.
495  * @return bool False if option was not added and true if option was added.
496  */
497 function add_blog_option( $id, $option, $value ) {
498         $id = (int) $id;
499
500         if ( empty( $id ) )
501                 $id = get_current_blog_id();
502
503         if ( get_current_blog_id() == $id )
504                 return add_option( $option, $value );
505
506         switch_to_blog( $id );
507         $return = add_option( $option, $value );
508         restore_current_blog();
509
510         return $return;
511 }
512
513 /**
514  * Removes option by name for a given blog id. Prevents removal of protected WordPress options.
515  *
516  * @since MU
517  *
518  * @param int $id A blog ID. Can be null to refer to the current blog.
519  * @param string $option Name of option to remove. Expected to not be SQL-escaped.
520  * @return bool True, if option is successfully deleted. False on failure.
521  */
522 function delete_blog_option( $id, $option ) {
523         $id = (int) $id;
524
525         if ( empty( $id ) )
526                 $id = get_current_blog_id();
527
528         if ( get_current_blog_id() == $id )
529                 return delete_option( $option );
530
531         switch_to_blog( $id );
532         $return = delete_option( $option );
533         restore_current_blog();
534
535         return $return;
536 }
537
538 /**
539  * Update an option for a particular blog.
540  *
541  * @since MU
542  *
543  * @param int $id The blog id
544  * @param string $option The option key
545  * @param mixed $value The option value
546  * @return bool True on success, false on failure.
547  */
548 function update_blog_option( $id, $option, $value, $deprecated = null ) {
549         $id = (int) $id;
550
551         if ( null !== $deprecated  )
552                 _deprecated_argument( __FUNCTION__, '3.1' );
553
554         if ( get_current_blog_id() == $id )
555                 return update_option( $option, $value );
556
557         switch_to_blog( $id );
558         $return = update_option( $option, $value );
559         restore_current_blog();
560
561         refresh_blog_details( $id );
562
563         return $return;
564 }
565
566 /**
567  * Switch the current blog.
568  *
569  * This function is useful if you need to pull posts, or other information,
570  * from other blogs. You can switch back afterwards using restore_current_blog().
571  *
572  * Things that aren't switched:
573  *  - autoloaded options. See #14992
574  *  - plugins. See #14941
575  *
576  * @see restore_current_blog()
577  * @since MU
578  *
579  * @param int $new_blog The id of the blog you want to switch to. Default: current blog
580  * @param bool $deprecated Deprecated argument
581  * @return bool Always returns True.
582  */
583 function switch_to_blog( $new_blog, $deprecated = null ) {
584         global $wpdb, $wp_roles;
585
586         if ( empty( $new_blog ) )
587                 $new_blog = $GLOBALS['blog_id'];
588
589         $GLOBALS['_wp_switched_stack'][] = $GLOBALS['blog_id'];
590
591         /*
592          * If we're switching to the same blog id that we're on,
593          * set the right vars, do the associated actions, but skip
594          * the extra unnecessary work
595          */
596         if ( $new_blog == $GLOBALS['blog_id'] ) {
597                 /**
598                  * Fires when the blog is switched.
599                  *
600                  * @since MU
601                  *
602                  * @param int $new_blog New blog ID.
603                  * @param int $new_blog Blog ID.
604                  */
605                 do_action( 'switch_blog', $new_blog, $new_blog );
606                 $GLOBALS['switched'] = true;
607                 return true;
608         }
609
610         $wpdb->set_blog_id( $new_blog );
611         $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
612         $prev_blog_id = $GLOBALS['blog_id'];
613         $GLOBALS['blog_id'] = $new_blog;
614
615         if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
616                 wp_cache_switch_to_blog( $new_blog );
617         } else {
618                 global $wp_object_cache;
619
620                 if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
621                         $global_groups = $wp_object_cache->global_groups;
622                 else
623                         $global_groups = false;
624
625                 wp_cache_init();
626
627                 if ( function_exists( 'wp_cache_add_global_groups' ) ) {
628                         if ( is_array( $global_groups ) ) {
629                                 wp_cache_add_global_groups( $global_groups );
630                         } else {
631                                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ) );
632                         }
633                         wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
634                 }
635         }
636
637         if ( did_action( 'init' ) ) {
638                 $wp_roles->reinit();
639                 $current_user = wp_get_current_user();
640                 $current_user->for_blog( $new_blog );
641         }
642
643         /** This filter is documented in wp-includes/ms-blogs.php */
644         do_action( 'switch_blog', $new_blog, $prev_blog_id );
645         $GLOBALS['switched'] = true;
646
647         return true;
648 }
649
650 /**
651  * Restore the current blog, after calling switch_to_blog()
652  *
653  * @see switch_to_blog()
654  * @since MU
655  *
656  * @return bool True on success, false if we're already on the current blog
657  */
658 function restore_current_blog() {
659         global $wpdb, $wp_roles;
660
661         if ( empty( $GLOBALS['_wp_switched_stack'] ) )
662                 return false;
663
664         $blog = array_pop( $GLOBALS['_wp_switched_stack'] );
665
666         if ( $GLOBALS['blog_id'] == $blog ) {
667                 /** This filter is documented in wp-includes/ms-blogs.php */
668                 do_action( 'switch_blog', $blog, $blog );
669                 // If we still have items in the switched stack, consider ourselves still 'switched'
670                 $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
671                 return true;
672         }
673
674         $wpdb->set_blog_id( $blog );
675         $prev_blog_id = $GLOBALS['blog_id'];
676         $GLOBALS['blog_id'] = $blog;
677         $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
678
679         if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
680                 wp_cache_switch_to_blog( $blog );
681         } else {
682                 global $wp_object_cache;
683
684                 if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
685                         $global_groups = $wp_object_cache->global_groups;
686                 else
687                         $global_groups = false;
688
689                 wp_cache_init();
690
691                 if ( function_exists( 'wp_cache_add_global_groups' ) ) {
692                         if ( is_array( $global_groups ) ) {
693                                 wp_cache_add_global_groups( $global_groups );
694                         } else {
695                                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ) );
696                         }
697                         wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
698                 }
699         }
700
701         if ( did_action( 'init' ) ) {
702                 $wp_roles->reinit();
703                 $current_user = wp_get_current_user();
704                 $current_user->for_blog( $blog );
705         }
706
707         /** This filter is documented in wp-includes/ms-blogs.php */
708         do_action( 'switch_blog', $blog, $prev_blog_id );
709
710         // If we still have items in the switched stack, consider ourselves still 'switched'
711         $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
712
713         return true;
714 }
715
716 /**
717  * Determines if switch_to_blog() is in effect
718  *
719  * @since 3.5.0
720  *
721  * @return bool True if switched, false otherwise.
722  */
723 function ms_is_switched() {
724         return ! empty( $GLOBALS['_wp_switched_stack'] );
725 }
726
727 /**
728  * Check if a particular blog is archived.
729  *
730  * @since MU
731  *
732  * @param int $id The blog id
733  * @return string Whether the blog is archived or not
734  */
735 function is_archived( $id ) {
736         return get_blog_status($id, 'archived');
737 }
738
739 /**
740  * Update the 'archived' status of a particular blog.
741  *
742  * @since MU
743  *
744  * @param int $id The blog id
745  * @param string $archived The new status
746  * @return string $archived
747  */
748 function update_archived( $id, $archived ) {
749         update_blog_status($id, 'archived', $archived);
750         return $archived;
751 }
752
753 /**
754  * Update a blog details field.
755  *
756  * @since MU
757  *
758  * @param int $blog_id BLog ID
759  * @param string $pref A field name
760  * @param string $value Value for $pref
761  * @return string $value
762  */
763 function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
764         global $wpdb;
765
766         if ( null !== $deprecated  )
767                 _deprecated_argument( __FUNCTION__, '3.1' );
768
769         if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) )
770                 return $value;
771
772         $result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) );
773
774         if ( false === $result )
775                 return false;
776
777         refresh_blog_details( $blog_id );
778
779         if ( 'spam' == $pref ) {
780                 if ( $value == 1 ) {
781                         /** This filter is documented in wp-includes/ms-blogs.php */
782                         do_action( 'make_spam_blog', $blog_id );
783                 } else {
784                         /** This filter is documented in wp-includes/ms-blogs.php */
785                         do_action( 'make_ham_blog', $blog_id );
786                 }
787         } elseif ( 'mature' == $pref ) {
788                 if ( $value == 1 ) {
789                         /** This filter is documented in wp-includes/ms-blogs.php */
790                         do_action( 'mature_blog', $blog_id );
791                 } else {
792                         /** This filter is documented in wp-includes/ms-blogs.php */
793                         do_action( 'unmature_blog', $blog_id );
794                 }
795         } elseif ( 'archived' == $pref ) {
796                 if ( $value == 1 ) {
797                         /** This filter is documented in wp-includes/ms-blogs.php */
798                         do_action( 'archive_blog', $blog_id );
799                 } else {
800                         /** This filter is documented in wp-includes/ms-blogs.php */
801                         do_action( 'unarchive_blog', $blog_id );
802                 }
803         } elseif ( 'deleted' == $pref ) {
804                 if ( $value == 1 ) {
805                         /** This filter is documented in wp-includes/ms-blogs.php */
806                         do_action( 'make_delete_blog', $blog_id );
807                 } else {
808                         /** This filter is documented in wp-includes/ms-blogs.php */
809                         do_action( 'make_undelete_blog', $blog_id );
810                 }
811         } elseif ( 'public' == $pref ) {
812                 /**
813                  * Fires after the current blog's 'public' setting is updated.
814                  *
815                  * @since MU
816                  *
817                  * @param int    $blog_id Blog ID.
818                  * @param string $value   The value of blog status.
819                  */
820                 do_action( 'update_blog_public', $blog_id, $value ); // Moved here from update_blog_public().
821         }
822
823         return $value;
824 }
825
826 /**
827  * Get a blog details field.
828  *
829  * @since MU
830  *
831  * @param int $id The blog id
832  * @param string $pref A field name
833  * @return bool $value
834  */
835 function get_blog_status( $id, $pref ) {
836         global $wpdb;
837
838         $details = get_blog_details( $id, false );
839         if ( $details )
840                 return $details->$pref;
841
842         return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) );
843 }
844
845 /**
846  * Get a list of most recently updated blogs.
847  *
848  * @since MU
849  *
850  * @param mixed $deprecated Not used
851  * @param int $start The offset
852  * @param int $quantity The maximum number of blogs to retrieve. Default is 40.
853  * @return array The list of blogs
854  */
855 function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
856         global $wpdb;
857
858         if ( ! empty( $deprecated ) )
859                 _deprecated_argument( __FUNCTION__, 'MU' ); // never used
860
861         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 );
862 }
863
864 /**
865  * Handler for updating the blog date when a post is published or an already published post is changed.
866  *
867  * @since 3.3.0
868  *
869  * @param string $new_status The new post status
870  * @param string $old_status The old post status
871  * @param object $post Post object
872  */
873 function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
874         $post_type_obj = get_post_type_object( $post->post_type );
875         if ( ! $post_type_obj || ! $post_type_obj->public ) {
876                 return;
877         }
878
879         if ( 'publish' != $new_status && 'publish' != $old_status ) {
880                 return;
881         }
882
883         // Post was freshly published, published post was saved, or published post was unpublished.
884
885         wpmu_update_blogs_date();
886 }
887
888 /**
889  * Handler for updating the blog date when a published post is deleted.
890  *
891  * @since 3.4.0
892  *
893  * @param int $post_id Post ID
894  */
895 function _update_blog_date_on_post_delete( $post_id ) {
896         $post = get_post( $post_id );
897
898         $post_type_obj = get_post_type_object( $post->post_type );
899         if ( ! $post_type_obj || ! $post_type_obj->public ) {
900                 return;
901         }
902
903         if ( 'publish' != $post->post_status ) {
904                 return;
905         }
906
907         wpmu_update_blogs_date();
908 }
909
910 /**
911  * Handler for updating the blog posts count date when a post is deleted.
912  *
913  * @since 4.0.0
914  *
915  * @param int $post_id Post ID.
916  */
917 function _update_posts_count_on_delete( $post_id ) {
918         $post = get_post( $post_id );
919
920         if ( ! $post || 'publish' !== $post->post_status ) {
921                 return;
922         }
923
924         update_posts_count();
925 }
926
927 /**
928  * Handler for updating the blog posts count date when a post status changes.
929  *
930  * @since 4.0.0
931  *
932  * @param string $new_status The status the post is changing to.
933  * @param string $old_status The status the post is changing from.
934  */
935 function _update_posts_count_on_transition_post_status( $new_status, $old_status ) {
936         if ( $new_status === $old_status ) {
937                 return;
938         }
939
940         if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
941                 return;
942         }
943
944         update_posts_count();
945 }
946