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