home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / ms-blogs.php < prev    next >
Encoding:
PHP Script  |  2017-10-18  |  38.3 KB  |  1,332 lines

  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 (3.0.0)
  9.  */
  10.  
  11. /**
  12.  * Update the last_updated field for the current site.
  13.  *
  14.  * @since MU (3.0.0)
  15.  */
  16. function wpmu_update_blogs_date() {
  17.     $site_id = get_current_blog_id();
  18.  
  19.     update_blog_details( $site_id, array( 'last_updated' => current_time( 'mysql', true ) ) );
  20.     /**
  21.      * Fires after the blog details are updated.
  22.      *
  23.      * @since MU (3.0.0)
  24.      *
  25.      * @param int $blog_id Site ID.
  26.      */
  27.     do_action( 'wpmu_blog_updated', $site_id );
  28. }
  29.  
  30. /**
  31.  * Get a full blog URL, given a blog id.
  32.  *
  33.  * @since MU (3.0.0)
  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_site( (int) $blog_id );
  40.  
  41.     if ( empty( $bloginfo ) ) {
  42.         return '';
  43.     }
  44.  
  45.     $scheme = parse_url( $bloginfo->home, PHP_URL_SCHEME );
  46.     $scheme = empty( $scheme ) ? 'http' : $scheme;
  47.  
  48.     return esc_url( $scheme . '://' . $bloginfo->domain . $bloginfo->path );
  49. }
  50.  
  51. /**
  52.  * Get a full blog URL, given a blog name.
  53.  *
  54.  * @since MU (3.0.0)
  55.  *
  56.  * @param string $blogname The (subdomain or directory) name
  57.  * @return string
  58.  */
  59. function get_blogaddress_by_name( $blogname ) {
  60.     if ( is_subdomain_install() ) {
  61.         if ( $blogname == 'main' )
  62.             $blogname = 'www';
  63.         $url = rtrim( network_home_url(), '/' );
  64.         if ( !empty( $blogname ) )
  65.             $url = preg_replace( '|^([^\.]+://)|', "\${1}" . $blogname . '.', $url );
  66.     } else {
  67.         $url = network_home_url( $blogname );
  68.     }
  69.     return esc_url( $url . '/' );
  70. }
  71.  
  72. /**
  73.  * Retrieves a sites ID given its (subdomain or directory) slug.
  74.  *
  75.  * @since MU (3.0.0)
  76.  * @since 4.7.0 Converted to use get_sites().
  77.  *
  78.  * @param string $slug A site's slug.
  79.  * @return int|null The site ID, or null if no site is found for the given slug.
  80.  */
  81. function get_id_from_blogname( $slug ) {
  82.     $current_network = get_network();
  83.     $slug = trim( $slug, '/' );
  84.  
  85.     if ( is_subdomain_install() ) {
  86.         $domain = $slug . '.' . preg_replace( '|^www\.|', '', $current_network->domain );
  87.         $path = $current_network->path;
  88.     } else {
  89.         $domain = $current_network->domain;
  90.         $path = $current_network->path . $slug . '/';
  91.     }
  92.  
  93.     $site_ids = get_sites( array(
  94.         'number' => 1,
  95.         'fields' => 'ids',
  96.         'domain' => $domain,
  97.         'path' => $path,
  98.     ) );
  99.  
  100.     if ( empty( $site_ids ) ) {
  101.         return null;
  102.     }
  103.  
  104.     return array_shift( $site_ids );
  105. }
  106.  
  107. /**
  108.  * Retrieve the details for a blog from the blogs table and blog options.
  109.  *
  110.  * @since MU (3.0.0)
  111.  *
  112.  * @global wpdb $wpdb WordPress database abstraction object.
  113.  *
  114.  * @param int|string|array $fields  Optional. A blog ID, a blog slug, or an array of fields to query against.
  115.  *                                  If not specified the current blog ID is used.
  116.  * @param bool             $get_all Whether to retrieve all details or only the details in the blogs table.
  117.  *                                  Default is true.
  118.  * @return WP_Site|false Blog details on success. False on failure.
  119.  */
  120. function get_blog_details( $fields = null, $get_all = true ) {
  121.     global $wpdb;
  122.  
  123.     if ( is_array($fields ) ) {
  124.         if ( isset($fields['blog_id']) ) {
  125.             $blog_id = $fields['blog_id'];
  126.         } elseif ( isset($fields['domain']) && isset($fields['path']) ) {
  127.             $key = md5( $fields['domain'] . $fields['path'] );
  128.             $blog = wp_cache_get($key, 'blog-lookup');
  129.             if ( false !== $blog )
  130.                 return $blog;
  131.             if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) {
  132.                 $nowww = substr( $fields['domain'], 4 );
  133.                 $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'] ) );
  134.             } else {
  135.                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $fields['domain'], $fields['path'] ) );
  136.             }
  137.             if ( $blog ) {
  138.                 wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details');
  139.                 $blog_id = $blog->blog_id;
  140.             } else {
  141.                 return false;
  142.             }
  143.         } elseif ( isset($fields['domain']) && is_subdomain_install() ) {
  144.             $key = md5( $fields['domain'] );
  145.             $blog = wp_cache_get($key, 'blog-lookup');
  146.             if ( false !== $blog )
  147.                 return $blog;
  148.             if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) {
  149.                 $nowww = substr( $fields['domain'], 4 );
  150.                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'] ) );
  151.             } else {
  152.                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $fields['domain'] ) );
  153.             }
  154.             if ( $blog ) {
  155.                 wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details');
  156.                 $blog_id = $blog->blog_id;
  157.             } else {
  158.                 return false;
  159.             }
  160.         } else {
  161.             return false;
  162.         }
  163.     } else {
  164.         if ( ! $fields )
  165.             $blog_id = get_current_blog_id();
  166.         elseif ( ! is_numeric( $fields ) )
  167.             $blog_id = get_id_from_blogname( $fields );
  168.         else
  169.             $blog_id = $fields;
  170.     }
  171.  
  172.     $blog_id = (int) $blog_id;
  173.  
  174.     $all = $get_all == true ? '' : 'short';
  175.     $details = wp_cache_get( $blog_id . $all, 'blog-details' );
  176.  
  177.     if ( $details ) {
  178.         if ( ! is_object( $details ) ) {
  179.             if ( $details == -1 ) {
  180.                 return false;
  181.             } else {
  182.                 // Clear old pre-serialized objects. Cache clients do better with that.
  183.                 wp_cache_delete( $blog_id . $all, 'blog-details' );
  184.                 unset($details);
  185.             }
  186.         } else {
  187.             return $details;
  188.         }
  189.     }
  190.  
  191.     // Try the other cache.
  192.     if ( $get_all ) {
  193.         $details = wp_cache_get( $blog_id . 'short', 'blog-details' );
  194.     } else {
  195.         $details = wp_cache_get( $blog_id, 'blog-details' );
  196.         // If short was requested and full cache is set, we can return.
  197.         if ( $details ) {
  198.             if ( ! is_object( $details ) ) {
  199.                 if ( $details == -1 ) {
  200.                     return false;
  201.                 } else {
  202.                     // Clear old pre-serialized objects. Cache clients do better with that.
  203.                     wp_cache_delete( $blog_id, 'blog-details' );
  204.                     unset($details);
  205.                 }
  206.             } else {
  207.                 return $details;
  208.             }
  209.         }
  210.     }
  211.  
  212.     if ( empty($details) ) {
  213.         $details = WP_Site::get_instance( $blog_id );
  214.         if ( ! $details ) {
  215.             // Set the full cache.
  216.             wp_cache_set( $blog_id, -1, 'blog-details' );
  217.             return false;
  218.         }
  219.     }
  220.  
  221.     if ( ! $details instanceof WP_Site ) {
  222.         $details = new WP_Site( $details );
  223.     }
  224.  
  225.     if ( ! $get_all ) {
  226.         wp_cache_set( $blog_id . $all, $details, 'blog-details' );
  227.         return $details;
  228.     }
  229.  
  230.     switch_to_blog( $blog_id );
  231.     $details->blogname   = get_option( 'blogname' );
  232.     $details->siteurl    = get_option( 'siteurl' );
  233.     $details->post_count = get_option( 'post_count' );
  234.     $details->home       = get_option( 'home' );
  235.     restore_current_blog();
  236.  
  237.     /**
  238.      * Filters a blog's details.
  239.      *
  240.      * @since MU (3.0.0)
  241.      * @deprecated 4.7.0 Use site_details
  242.      *
  243.      * @param object $details The blog details.
  244.      */
  245.     $details = apply_filters_deprecated( 'blog_details', array( $details ), '4.7.0', 'site_details' );
  246.  
  247.     wp_cache_set( $blog_id . $all, $details, 'blog-details' );
  248.  
  249.     $key = md5( $details->domain . $details->path );
  250.     wp_cache_set( $key, $details, 'blog-lookup' );
  251.  
  252.     return $details;
  253. }
  254.  
  255. /**
  256.  * Clear the blog details cache.
  257.  *
  258.  * @since MU (3.0.0)
  259.  *
  260.  * @param int $blog_id Optional. Blog ID. Defaults to current blog.
  261.  */
  262. function refresh_blog_details( $blog_id = 0 ) {
  263.     $blog_id = (int) $blog_id;
  264.     if ( ! $blog_id ) {
  265.         $blog_id = get_current_blog_id();
  266.     }
  267.  
  268.     clean_blog_cache( $blog_id );
  269. }
  270.  
  271. /**
  272.  * Update the details for a blog. Updates the blogs table for a given blog id.
  273.  *
  274.  * @since MU (3.0.0)
  275.  *
  276.  * @global wpdb $wpdb WordPress database abstraction object.
  277.  *
  278.  * @param int   $blog_id Blog ID
  279.  * @param array $details Array of details keyed by blogs table field names.
  280.  * @return bool True if update succeeds, false otherwise.
  281.  */
  282. function update_blog_details( $blog_id, $details = array() ) {
  283.     global $wpdb;
  284.  
  285.     if ( empty($details) )
  286.         return false;
  287.  
  288.     if ( is_object($details) )
  289.         $details = get_object_vars($details);
  290.  
  291.     $current_details = get_site( $blog_id );
  292.     if ( empty($current_details) )
  293.         return false;
  294.  
  295.     $current_details = get_object_vars($current_details);
  296.  
  297.     $details = array_merge($current_details, $details);
  298.     $details['last_updated'] = current_time('mysql', true);
  299.  
  300.     $update_details = array();
  301.     $fields = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id');
  302.     foreach ( array_intersect( array_keys( $details ), $fields ) as $field ) {
  303.         if ( 'path' === $field ) {
  304.             $details[ $field ] = trailingslashit( '/' . trim( $details[ $field ], '/' ) );
  305.         }
  306.  
  307.         $update_details[ $field ] = $details[ $field ];
  308.     }
  309.  
  310.     $result = $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) );
  311.  
  312.     if ( false === $result )
  313.         return false;
  314.  
  315.     // If spam status changed, issue actions.
  316.     if ( $details['spam'] != $current_details['spam'] ) {
  317.         if ( $details['spam'] == 1 ) {
  318.             /**
  319.              * Fires when the 'spam' status is added to a blog.
  320.              *
  321.              * @since MU (3.0.0)
  322.              *
  323.              * @param int $blog_id Blog ID.
  324.              */
  325.             do_action( 'make_spam_blog', $blog_id );
  326.         } else {
  327.             /**
  328.              * Fires when the 'spam' status is removed from a blog.
  329.              *
  330.              * @since MU (3.0.0)
  331.              *
  332.              * @param int $blog_id Blog ID.
  333.              */
  334.             do_action( 'make_ham_blog', $blog_id );
  335.         }
  336.     }
  337.  
  338.     // If mature status changed, issue actions.
  339.     if ( $details['mature'] != $current_details['mature'] ) {
  340.         if ( $details['mature'] == 1 ) {
  341.             /**
  342.              * Fires when the 'mature' status is added to a blog.
  343.              *
  344.              * @since 3.1.0
  345.              *
  346.              * @param int $blog_id Blog ID.
  347.              */
  348.             do_action( 'mature_blog', $blog_id );
  349.         } else {
  350.             /**
  351.              * Fires when the 'mature' status is removed from a blog.
  352.              *
  353.              * @since 3.1.0
  354.              *
  355.              * @param int $blog_id Blog ID.
  356.              */
  357.             do_action( 'unmature_blog', $blog_id );
  358.         }
  359.     }
  360.  
  361.     // If archived status changed, issue actions.
  362.     if ( $details['archived'] != $current_details['archived'] ) {
  363.         if ( $details['archived'] == 1 ) {
  364.             /**
  365.              * Fires when the 'archived' status is added to a blog.
  366.              *
  367.              * @since MU (3.0.0)
  368.              *
  369.              * @param int $blog_id Blog ID.
  370.              */
  371.             do_action( 'archive_blog', $blog_id );
  372.         } else {
  373.             /**
  374.              * Fires when the 'archived' status is removed from a blog.
  375.              *
  376.              * @since MU (3.0.0)
  377.              *
  378.              * @param int $blog_id Blog ID.
  379.              */
  380.             do_action( 'unarchive_blog', $blog_id );
  381.         }
  382.     }
  383.  
  384.     // If deleted status changed, issue actions.
  385.     if ( $details['deleted'] != $current_details['deleted'] ) {
  386.         if ( $details['deleted'] == 1 ) {
  387.             /**
  388.              * Fires when the 'deleted' status is added to a blog.
  389.              *
  390.              * @since 3.5.0
  391.              *
  392.              * @param int $blog_id Blog ID.
  393.              */
  394.             do_action( 'make_delete_blog', $blog_id );
  395.         } else {
  396.             /**
  397.              * Fires when the 'deleted' status is removed from a blog.
  398.              *
  399.              * @since 3.5.0
  400.              *
  401.              * @param int $blog_id Blog ID.
  402.              */
  403.             do_action( 'make_undelete_blog', $blog_id );
  404.         }
  405.     }
  406.  
  407.     if ( isset( $details['public'] ) ) {
  408.         switch_to_blog( $blog_id );
  409.         update_option( 'blog_public', $details['public'] );
  410.         restore_current_blog();
  411.     }
  412.  
  413.     clean_blog_cache( $blog_id );
  414.  
  415.     return true;
  416. }
  417.  
  418. /**
  419.  * Clean the blog cache
  420.  *
  421.  * @since 3.5.0
  422.  *
  423.  * @global bool $_wp_suspend_cache_invalidation
  424.  *
  425.  * @param WP_Site|int $blog The site object or ID to be cleared from cache.
  426.  */
  427. function clean_blog_cache( $blog ) {
  428.     global $_wp_suspend_cache_invalidation;
  429.  
  430.     if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
  431.         return;
  432.     }
  433.  
  434.     if ( empty( $blog ) ) {
  435.         return;
  436.     }
  437.  
  438.     $blog_id = $blog;
  439.     $blog = get_site( $blog_id );
  440.     if ( ! $blog ) {
  441.         if ( ! is_numeric( $blog_id ) ) {
  442.             return;
  443.         }
  444.  
  445.         // Make sure a WP_Site object exists even when the site has been deleted.
  446.         $blog = new WP_Site( (object) array(
  447.             'blog_id' => $blog_id,
  448.             'domain'  => null,
  449.             'path'    => null,
  450.         ) );
  451.     }
  452.  
  453.     $blog_id = $blog->blog_id;
  454.     $domain_path_key = md5( $blog->domain . $blog->path );
  455.  
  456.     wp_cache_delete( $blog_id, 'sites' );
  457.     wp_cache_delete( $blog_id, 'site-details' );
  458.     wp_cache_delete( $blog_id, 'blog-details' );
  459.     wp_cache_delete( $blog_id . 'short' , 'blog-details' );
  460.     wp_cache_delete( $domain_path_key, 'blog-lookup' );
  461.     wp_cache_delete( $domain_path_key, 'blog-id-cache' );
  462.     wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
  463.     wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
  464.  
  465.     /**
  466.      * Fires immediately after a site has been removed from the object cache.
  467.      *
  468.      * @since 4.6.0
  469.      *
  470.      * @param int     $id              Blog ID.
  471.      * @param WP_Site $blog            Site object.
  472.      * @param string  $domain_path_key md5 hash of domain and path.
  473.      */
  474.     do_action( 'clean_site_cache', $blog_id, $blog, $domain_path_key );
  475.  
  476.     wp_cache_set( 'last_changed', microtime(), 'sites' );
  477.  
  478.     /**
  479.      * Fires after the blog details cache is cleared.
  480.      *
  481.      * @since 3.4.0
  482.      * @deprecated 4.9.0 Use clean_site_cache
  483.      *
  484.      * @param int $blog_id Blog ID.
  485.      */
  486.     do_action_deprecated( 'refresh_blog_details', array( $blog_id ), '4.9.0', 'clean_site_cache' );
  487. }
  488.  
  489. /**
  490.  * Cleans the site details cache for a site.
  491.  *
  492.  * @since 4.7.4
  493.  *
  494.  * @param int $site_id Optional. Site ID. Default is the current site ID.
  495.  */
  496. function clean_site_details_cache( $site_id = 0 ) {
  497.     $site_id = (int) $site_id;
  498.     if ( ! $site_id ) {
  499.         $site_id = get_current_blog_id();
  500.     }
  501.  
  502.     wp_cache_delete( $site_id, 'site-details' );
  503.     wp_cache_delete( $site_id, 'blog-details' );
  504. }
  505.  
  506. /**
  507.  * Retrieves site data given a site ID or site object.
  508.  *
  509.  * Site data will be cached and returned after being passed through a filter.
  510.  * If the provided site is empty, the current site global will be used.
  511.  *
  512.  * @since 4.6.0
  513.  *
  514.  * @param WP_Site|int|null $site Optional. Site to retrieve. Default is the current site.
  515.  * @return WP_Site|null The site object or null if not found.
  516.  */
  517. function get_site( $site = null ) {
  518.     if ( empty( $site ) ) {
  519.         $site = get_current_blog_id();
  520.     }
  521.  
  522.     if ( $site instanceof WP_Site ) {
  523.         $_site = $site;
  524.     } elseif ( is_object( $site ) ) {
  525.         $_site = new WP_Site( $site );
  526.     } else {
  527.         $_site = WP_Site::get_instance( $site );
  528.     }
  529.  
  530.     if ( ! $_site ) {
  531.         return null;
  532.     }
  533.  
  534.     /**
  535.      * Fires after a site is retrieved.
  536.      *
  537.      * @since 4.6.0
  538.      *
  539.      * @param WP_Site $_site Site data.
  540.      */
  541.     $_site = apply_filters( 'get_site', $_site );
  542.  
  543.     return $_site;
  544. }
  545.  
  546. /**
  547.  * Adds any sites from the given ids to the cache that do not already exist in cache.
  548.  *
  549.  * @since 4.6.0
  550.  * @access private
  551.  *
  552.  * @see update_site_cache()
  553.  * @global wpdb $wpdb WordPress database abstraction object.
  554.  *
  555.  * @param array $ids ID list.
  556.  */
  557. function _prime_site_caches( $ids ) {
  558.     global $wpdb;
  559.  
  560.     $non_cached_ids = _get_non_cached_ids( $ids, 'sites' );
  561.     if ( ! empty( $non_cached_ids ) ) {
  562.         $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
  563.  
  564.         update_site_cache( $fresh_sites );
  565.     }
  566. }
  567.  
  568. /**
  569.  * Updates sites in cache.
  570.  *
  571.  * @since 4.6.0
  572.  *
  573.  * @param array $sites Array of site objects.
  574.  */
  575. function update_site_cache( $sites ) {
  576.     if ( ! $sites ) {
  577.         return;
  578.     }
  579.  
  580.     foreach ( $sites as $site ) {
  581.         wp_cache_add( $site->blog_id, $site, 'sites' );
  582.         wp_cache_add( $site->blog_id . 'short', $site, 'blog-details' );
  583.     }
  584. }
  585.  
  586. /**
  587.  * Retrieves a list of sites matching requested arguments.
  588.  *
  589.  * @since 4.6.0
  590.  * @since 4.8.0 Introduced the 'lang_id', 'lang__in', and 'lang__not_in' parameters.
  591.  *
  592.  * @see WP_Site_Query::parse_query()
  593.  *
  594.  * @param string|array $args {
  595.  *     Optional. Array or query string of site query parameters. Default empty.
  596.  *
  597.  *     @type array        $site__in          Array of site IDs to include. Default empty.
  598.  *     @type array        $site__not_in      Array of site IDs to exclude. Default empty.
  599.  *     @type bool         $count             Whether to return a site count (true) or array of site objects.
  600.  *                                           Default false.
  601.  *     @type array        $date_query        Date query clauses to limit sites by. See WP_Date_Query.
  602.  *                                           Default null.
  603.  *     @type string       $fields            Site fields to return. Accepts 'ids' (returns an array of site IDs)
  604.  *                                           or empty (returns an array of complete site objects). Default empty.
  605.  *     @type int          $ID                A site ID to only return that site. Default empty.
  606.  *     @type int          $number            Maximum number of sites to retrieve. Default 100.
  607.  *     @type int          $offset            Number of sites to offset the query. Used to build LIMIT clause.
  608.  *                                           Default 0.
  609.  *     @type bool         $no_found_rows     Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
  610.  *     @type string|array $orderby           Site status or array of statuses. Accepts 'id', 'domain', 'path',
  611.  *                                           'network_id', 'last_updated', 'registered', 'domain_length',
  612.  *                                           'path_length', 'site__in' and 'network__in'. Also accepts false,
  613.  *                                           an empty array, or 'none' to disable `ORDER BY` clause.
  614.  *                                           Default 'id'.
  615.  *     @type string       $order             How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
  616.  *     @type int          $network_id        Limit results to those affiliated with a given network ID. If 0,
  617.  *                                           include all networks. Default 0.
  618.  *     @type array        $network__in       Array of network IDs to include affiliated sites for. Default empty.
  619.  *     @type array        $network__not_in   Array of network IDs to exclude affiliated sites for. Default empty.
  620.  *     @type string       $domain            Limit results to those affiliated with a given domain. Default empty.
  621.  *     @type array        $domain__in        Array of domains to include affiliated sites for. Default empty.
  622.  *     @type array        $domain__not_in    Array of domains to exclude affiliated sites for. Default empty.
  623.  *     @type string       $path              Limit results to those affiliated with a given path. Default empty.
  624.  *     @type array        $path__in          Array of paths to include affiliated sites for. Default empty.
  625.  *     @type array        $path__not_in      Array of paths to exclude affiliated sites for. Default empty.
  626.  *     @type int          $public            Limit results to public sites. Accepts '1' or '0'. Default empty.
  627.  *     @type int          $archived          Limit results to archived sites. Accepts '1' or '0'. Default empty.
  628.  *     @type int          $mature            Limit results to mature sites. Accepts '1' or '0'. Default empty.
  629.  *     @type int          $spam              Limit results to spam sites. Accepts '1' or '0'. Default empty.
  630.  *     @type int          $deleted           Limit results to deleted sites. Accepts '1' or '0'. Default empty.
  631.  *     @type int          $lang_id           Limit results to a language ID. Default empty.
  632.  *     @type array        $lang__in          Array of language IDs to include affiliated sites for. Default empty.
  633.  *     @type array        $lang__not_in      Array of language IDs to exclude affiliated sites for. Default empty.
  634.  *     @type string       $search            Search term(s) to retrieve matching sites for. Default empty.
  635.  *     @type array        $search_columns    Array of column names to be searched. Accepts 'domain' and 'path'.
  636.  *                                           Default empty array.
  637.  *     @type bool         $update_site_cache Whether to prime the cache for found sites. Default true.
  638.  * }
  639.  * @return array|int List of WP_Site objects, a list of site ids when 'fields' is set to 'ids',
  640.  *                   or the number of sites when 'count' is passed as a query var.
  641.  */
  642. function get_sites( $args = array() ) {
  643.     $query = new WP_Site_Query();
  644.  
  645.     return $query->query( $args );
  646. }
  647.  
  648. /**
  649.  * Retrieve option value for a given blog id based on name of option.
  650.  *
  651.  * If the option does not exist or does not have a value, then the return value
  652.  * will be false. This is useful to check whether you need to install an option
  653.  * and is commonly used during installation of plugin options and to test
  654.  * whether upgrading is required.
  655.  *
  656.  * If the option was serialized then it will be unserialized when it is returned.
  657.  *
  658.  * @since MU (3.0.0)
  659.  *
  660.  * @param int    $id      A blog ID. Can be null to refer to the current blog.
  661.  * @param string $option  Name of option to retrieve. Expected to not be SQL-escaped.
  662.  * @param mixed  $default Optional. Default value to return if the option does not exist.
  663.  * @return mixed Value set for the option.
  664.  */
  665. function get_blog_option( $id, $option, $default = false ) {
  666.     $id = (int) $id;
  667.  
  668.     if ( empty( $id ) )
  669.         $id = get_current_blog_id();
  670.  
  671.     if ( get_current_blog_id() == $id )
  672.         return get_option( $option, $default );
  673.  
  674.     switch_to_blog( $id );
  675.     $value = get_option( $option, $default );
  676.     restore_current_blog();
  677.  
  678.     /**
  679.      * Filters a blog option value.
  680.      *
  681.      * The dynamic portion of the hook name, `$option`, refers to the blog option name.
  682.      *
  683.      * @since 3.5.0
  684.      *
  685.      * @param string  $value The option value.
  686.      * @param int     $id    Blog ID.
  687.      */
  688.     return apply_filters( "blog_option_{$option}", $value, $id );
  689. }
  690.  
  691. /**
  692.  * Add a new option for a given blog id.
  693.  *
  694.  * You do not need to serialize values. If the value needs to be serialized, then
  695.  * it will be serialized before it is inserted into the database. Remember,
  696.  * resources can not be serialized or added as an option.
  697.  *
  698.  * You can create options without values and then update the values later.
  699.  * Existing options will not be updated and checks are performed to ensure that you
  700.  * aren't adding a protected WordPress option. Care should be taken to not name
  701.  * options the same as the ones which are protected.
  702.  *
  703.  * @since MU (3.0.0)
  704.  *
  705.  * @param int    $id     A blog ID. Can be null to refer to the current blog.
  706.  * @param string $option Name of option to add. Expected to not be SQL-escaped.
  707.  * @param mixed  $value  Optional. Option value, can be anything. Expected to not be SQL-escaped.
  708.  * @return bool False if option was not added and true if option was added.
  709.  */
  710. function add_blog_option( $id, $option, $value ) {
  711.     $id = (int) $id;
  712.  
  713.     if ( empty( $id ) )
  714.         $id = get_current_blog_id();
  715.  
  716.     if ( get_current_blog_id() == $id )
  717.         return add_option( $option, $value );
  718.  
  719.     switch_to_blog( $id );
  720.     $return = add_option( $option, $value );
  721.     restore_current_blog();
  722.  
  723.     return $return;
  724. }
  725.  
  726. /**
  727.  * Removes option by name for a given blog id. Prevents removal of protected WordPress options.
  728.  *
  729.  * @since MU (3.0.0)
  730.  *
  731.  * @param int    $id     A blog ID. Can be null to refer to the current blog.
  732.  * @param string $option Name of option to remove. Expected to not be SQL-escaped.
  733.  * @return bool True, if option is successfully deleted. False on failure.
  734.  */
  735. function delete_blog_option( $id, $option ) {
  736.     $id = (int) $id;
  737.  
  738.     if ( empty( $id ) )
  739.         $id = get_current_blog_id();
  740.  
  741.     if ( get_current_blog_id() == $id )
  742.         return delete_option( $option );
  743.  
  744.     switch_to_blog( $id );
  745.     $return = delete_option( $option );
  746.     restore_current_blog();
  747.  
  748.     return $return;
  749. }
  750.  
  751. /**
  752.  * Update an option for a particular blog.
  753.  *
  754.  * @since MU (3.0.0)
  755.  *
  756.  * @param int    $id         The blog id.
  757.  * @param string $option     The option key.
  758.  * @param mixed  $value      The option value.
  759.  * @param mixed  $deprecated Not used.
  760.  * @return bool True on success, false on failure.
  761.  */
  762. function update_blog_option( $id, $option, $value, $deprecated = null ) {
  763.     $id = (int) $id;
  764.  
  765.     if ( null !== $deprecated  )
  766.         _deprecated_argument( __FUNCTION__, '3.1.0' );
  767.  
  768.     if ( get_current_blog_id() == $id )
  769.         return update_option( $option, $value );
  770.  
  771.     switch_to_blog( $id );
  772.     $return = update_option( $option, $value );
  773.     restore_current_blog();
  774.  
  775.     return $return;
  776. }
  777.  
  778. /**
  779.  * Switch the current blog.
  780.  *
  781.  * This function is useful if you need to pull posts, or other information,
  782.  * from other blogs. You can switch back afterwards using restore_current_blog().
  783.  *
  784.  * Things that aren't switched:
  785.  *  - plugins. See #14941
  786.  *
  787.  * @see restore_current_blog()
  788.  * @since MU (3.0.0)
  789.  *
  790.  * @global wpdb            $wpdb
  791.  * @global int             $blog_id
  792.  * @global array           $_wp_switched_stack
  793.  * @global bool            $switched
  794.  * @global string          $table_prefix
  795.  * @global WP_Object_Cache $wp_object_cache
  796.  *
  797.  * @param int  $new_blog   The id of the blog you want to switch to. Default: current blog
  798.  * @param bool $deprecated Deprecated argument
  799.  * @return true Always returns True.
  800.  */
  801. function switch_to_blog( $new_blog, $deprecated = null ) {
  802.     global $wpdb;
  803.  
  804.     $blog_id = get_current_blog_id();
  805.     if ( empty( $new_blog ) ) {
  806.         $new_blog = $blog_id;
  807.     }
  808.  
  809.     $GLOBALS['_wp_switched_stack'][] = $blog_id;
  810.  
  811.     /*
  812.      * If we're switching to the same blog id that we're on,
  813.      * set the right vars, do the associated actions, but skip
  814.      * the extra unnecessary work
  815.      */
  816.     if ( $new_blog == $blog_id ) {
  817.         /**
  818.          * Fires when the blog is switched.
  819.          *
  820.          * @since MU (3.0.0)
  821.          *
  822.          * @param int $new_blog New blog ID.
  823.          * @param int $new_blog Blog ID.
  824.          */
  825.         do_action( 'switch_blog', $new_blog, $new_blog );
  826.         $GLOBALS['switched'] = true;
  827.         return true;
  828.     }
  829.  
  830.     $wpdb->set_blog_id( $new_blog );
  831.     $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
  832.     $prev_blog_id = $blog_id;
  833.     $GLOBALS['blog_id'] = $new_blog;
  834.  
  835.     if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
  836.         wp_cache_switch_to_blog( $new_blog );
  837.     } else {
  838.         global $wp_object_cache;
  839.  
  840.         if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
  841.             $global_groups = $wp_object_cache->global_groups;
  842.         } else {
  843.             $global_groups = false;
  844.         }
  845.         wp_cache_init();
  846.  
  847.         if ( function_exists( 'wp_cache_add_global_groups' ) ) {
  848.             if ( is_array( $global_groups ) ) {
  849.                 wp_cache_add_global_groups( $global_groups );
  850.             } else {
  851.                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
  852.             }
  853.             wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
  854.         }
  855.     }
  856.  
  857.     /** This filter is documented in wp-includes/ms-blogs.php */
  858.     do_action( 'switch_blog', $new_blog, $prev_blog_id );
  859.     $GLOBALS['switched'] = true;
  860.  
  861.     return true;
  862. }
  863.  
  864. /**
  865.  * Restore the current blog, after calling switch_to_blog()
  866.  *
  867.  * @see switch_to_blog()
  868.  * @since MU (3.0.0)
  869.  *
  870.  * @global wpdb            $wpdb
  871.  * @global array           $_wp_switched_stack
  872.  * @global int             $blog_id
  873.  * @global bool            $switched
  874.  * @global string          $table_prefix
  875.  * @global WP_Object_Cache $wp_object_cache
  876.  *
  877.  * @return bool True on success, false if we're already on the current blog
  878.  */
  879. function restore_current_blog() {
  880.     global $wpdb;
  881.  
  882.     if ( empty( $GLOBALS['_wp_switched_stack'] ) ) {
  883.         return false;
  884.     }
  885.  
  886.     $blog = array_pop( $GLOBALS['_wp_switched_stack'] );
  887.     $blog_id = get_current_blog_id();
  888.  
  889.     if ( $blog_id == $blog ) {
  890.         /** This filter is documented in wp-includes/ms-blogs.php */
  891.         do_action( 'switch_blog', $blog, $blog );
  892.         // If we still have items in the switched stack, consider ourselves still 'switched'
  893.         $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
  894.         return true;
  895.     }
  896.  
  897.     $wpdb->set_blog_id( $blog );
  898.     $prev_blog_id = $blog_id;
  899.     $GLOBALS['blog_id'] = $blog;
  900.     $GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
  901.  
  902.     if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
  903.         wp_cache_switch_to_blog( $blog );
  904.     } else {
  905.         global $wp_object_cache;
  906.  
  907.         if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
  908.             $global_groups = $wp_object_cache->global_groups;
  909.         } else {
  910.             $global_groups = false;
  911.         }
  912.  
  913.         wp_cache_init();
  914.  
  915.         if ( function_exists( 'wp_cache_add_global_groups' ) ) {
  916.             if ( is_array( $global_groups ) ) {
  917.                 wp_cache_add_global_groups( $global_groups );
  918.             } else {
  919.                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
  920.             }
  921.             wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
  922.         }
  923.     }
  924.  
  925.     /** This filter is documented in wp-includes/ms-blogs.php */
  926.     do_action( 'switch_blog', $blog, $prev_blog_id );
  927.  
  928.     // If we still have items in the switched stack, consider ourselves still 'switched'
  929.     $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
  930.  
  931.     return true;
  932. }
  933.  
  934. /**
  935.  * Switches the initialized roles and current user capabilities to another site.
  936.  *
  937.  * @since 4.9.0
  938.  *
  939.  * @param int $new_site_id New site ID.
  940.  * @param int $old_site_id Old site ID.
  941.  */
  942. function wp_switch_roles_and_user( $new_site_id, $old_site_id ) {
  943.     if ( $new_site_id == $old_site_id ) {
  944.         return;
  945.     }
  946.  
  947.     if ( ! did_action( 'init' ) ) {
  948.         return;
  949.     }
  950.  
  951.     wp_roles()->for_site( $new_site_id );
  952.     wp_get_current_user()->for_site( $new_site_id );
  953. }
  954.  
  955. /**
  956.  * Determines if switch_to_blog() is in effect
  957.  *
  958.  * @since 3.5.0
  959.  *
  960.  * @global array $_wp_switched_stack
  961.  *
  962.  * @return bool True if switched, false otherwise.
  963.  */
  964. function ms_is_switched() {
  965.     return ! empty( $GLOBALS['_wp_switched_stack'] );
  966. }
  967.  
  968. /**
  969.  * Check if a particular blog is archived.
  970.  *
  971.  * @since MU (3.0.0)
  972.  *
  973.  * @param int $id The blog id
  974.  * @return string Whether the blog is archived or not
  975.  */
  976. function is_archived( $id ) {
  977.     return get_blog_status($id, 'archived');
  978. }
  979.  
  980. /**
  981.  * Update the 'archived' status of a particular blog.
  982.  *
  983.  * @since MU (3.0.0)
  984.  *
  985.  * @param int    $id       The blog id
  986.  * @param string $archived The new status
  987.  * @return string $archived
  988.  */
  989. function update_archived( $id, $archived ) {
  990.     update_blog_status($id, 'archived', $archived);
  991.     return $archived;
  992. }
  993.  
  994. /**
  995.  * Update a blog details field.
  996.  *
  997.  * @since MU (3.0.0)
  998.  *
  999.  * @global wpdb $wpdb WordPress database abstraction object.
  1000.  *
  1001.  * @param int    $blog_id BLog ID
  1002.  * @param string $pref    A field name
  1003.  * @param string $value   Value for $pref
  1004.  * @param null   $deprecated
  1005.  * @return string|false $value
  1006.  */
  1007. function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
  1008.     global $wpdb;
  1009.  
  1010.     if ( null !== $deprecated  )
  1011.         _deprecated_argument( __FUNCTION__, '3.1.0' );
  1012.  
  1013.     if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) )
  1014.         return $value;
  1015.  
  1016.     $result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) );
  1017.  
  1018.     if ( false === $result )
  1019.         return false;
  1020.  
  1021.     clean_blog_cache( $blog_id );
  1022.  
  1023.     if ( 'spam' == $pref ) {
  1024.         if ( $value == 1 ) {
  1025.             /** This filter is documented in wp-includes/ms-blogs.php */
  1026.             do_action( 'make_spam_blog', $blog_id );
  1027.         } else {
  1028.             /** This filter is documented in wp-includes/ms-blogs.php */
  1029.             do_action( 'make_ham_blog', $blog_id );
  1030.         }
  1031.     } elseif ( 'mature' == $pref ) {
  1032.         if ( $value == 1 ) {
  1033.             /** This filter is documented in wp-includes/ms-blogs.php */
  1034.             do_action( 'mature_blog', $blog_id );
  1035.         } else {
  1036.             /** This filter is documented in wp-includes/ms-blogs.php */
  1037.             do_action( 'unmature_blog', $blog_id );
  1038.         }
  1039.     } elseif ( 'archived' == $pref ) {
  1040.         if ( $value == 1 ) {
  1041.             /** This filter is documented in wp-includes/ms-blogs.php */
  1042.             do_action( 'archive_blog', $blog_id );
  1043.         } else {
  1044.             /** This filter is documented in wp-includes/ms-blogs.php */
  1045.             do_action( 'unarchive_blog', $blog_id );
  1046.         }
  1047.     } elseif ( 'deleted' == $pref ) {
  1048.         if ( $value == 1 ) {
  1049.             /** This filter is documented in wp-includes/ms-blogs.php */
  1050.             do_action( 'make_delete_blog', $blog_id );
  1051.         } else {
  1052.             /** This filter is documented in wp-includes/ms-blogs.php */
  1053.             do_action( 'make_undelete_blog', $blog_id );
  1054.         }
  1055.     } elseif ( 'public' == $pref ) {
  1056.         /**
  1057.          * Fires after the current blog's 'public' setting is updated.
  1058.          *
  1059.          * @since MU (3.0.0)
  1060.          *
  1061.          * @param int    $blog_id Blog ID.
  1062.          * @param string $value   The value of blog status.
  1063.           */
  1064.         do_action( 'update_blog_public', $blog_id, $value ); // Moved here from update_blog_public().
  1065.     }
  1066.  
  1067.     return $value;
  1068. }
  1069.  
  1070. /**
  1071.  * Get a blog details field.
  1072.  *
  1073.  * @since MU (3.0.0)
  1074.  *
  1075.  * @global wpdb $wpdb WordPress database abstraction object.
  1076.  *
  1077.  * @param int    $id   The blog id
  1078.  * @param string $pref A field name
  1079.  * @return bool|string|null $value
  1080.  */
  1081. function get_blog_status( $id, $pref ) {
  1082.     global $wpdb;
  1083.  
  1084.     $details = get_site( $id );
  1085.     if ( $details )
  1086.         return $details->$pref;
  1087.  
  1088.     return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) );
  1089. }
  1090.  
  1091. /**
  1092.  * Get a list of most recently updated blogs.
  1093.  *
  1094.  * @since MU (3.0.0)
  1095.  *
  1096.  * @global wpdb $wpdb WordPress database abstraction object.
  1097.  *
  1098.  * @param mixed $deprecated Not used
  1099.  * @param int   $start      The offset
  1100.  * @param int   $quantity   The maximum number of blogs to retrieve. Default is 40.
  1101.  * @return array The list of blogs
  1102.  */
  1103. function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
  1104.     global $wpdb;
  1105.  
  1106.     if ( ! empty( $deprecated ) )
  1107.         _deprecated_argument( __FUNCTION__, 'MU' ); // never used
  1108.  
  1109.     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", get_current_network_id(), $start, $quantity ), ARRAY_A );
  1110. }
  1111.  
  1112. /**
  1113.  * Retrieves a list of networks.
  1114.  *
  1115.  * @since 4.6.0
  1116.  *
  1117.  * @param string|array $args Optional. Array or string of arguments. See WP_Network_Query::parse_query()
  1118.  *                           for information on accepted arguments. Default empty array.
  1119.  * @return array|int List of WP_Network objects, a list of network ids when 'fields' is set to 'ids',
  1120.  *                   or the number of networks when 'count' is passed as a query var.
  1121.  */
  1122. function get_networks( $args = array() ) {
  1123.     $query = new WP_Network_Query();
  1124.  
  1125.     return $query->query( $args );
  1126. }
  1127.  
  1128. /**
  1129.  * Retrieves network data given a network ID or network object.
  1130.  *
  1131.  * Network data will be cached and returned after being passed through a filter.
  1132.  * If the provided network is empty, the current network global will be used.
  1133.  *
  1134.  * @since 4.6.0
  1135.  *
  1136.  * @global WP_Network $current_site
  1137.  *
  1138.  * @param WP_Network|int|null $network Optional. Network to retrieve. Default is the current network.
  1139.  * @return WP_Network|null The network object or null if not found.
  1140.  */
  1141. function get_network( $network = null ) {
  1142.     global $current_site;
  1143.     if ( empty( $network ) && isset( $current_site ) ) {
  1144.         $network = $current_site;
  1145.     }
  1146.  
  1147.     if ( $network instanceof WP_Network ) {
  1148.         $_network = $network;
  1149.     } elseif ( is_object( $network ) ) {
  1150.         $_network = new WP_Network( $network );
  1151.     } else {
  1152.         $_network = WP_Network::get_instance( $network );
  1153.     }
  1154.  
  1155.     if ( ! $_network ) {
  1156.         return null;
  1157.     }
  1158.  
  1159.     /**
  1160.      * Fires after a network is retrieved.
  1161.      *
  1162.      * @since 4.6.0
  1163.      *
  1164.      * @param WP_Network $_network Network data.
  1165.      */
  1166.     $_network = apply_filters( 'get_network', $_network );
  1167.  
  1168.     return $_network;
  1169. }
  1170.  
  1171. /**
  1172.  * Removes a network from the object cache.
  1173.  *
  1174.  * @since 4.6.0
  1175.  *
  1176.  * @global bool $_wp_suspend_cache_invalidation
  1177.  *
  1178.  * @param int|array $ids Network ID or an array of network IDs to remove from cache.
  1179.  */
  1180. function clean_network_cache( $ids ) {
  1181.     global $_wp_suspend_cache_invalidation;
  1182.  
  1183.     if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
  1184.         return;
  1185.     }
  1186.  
  1187.     foreach ( (array) $ids as $id ) {
  1188.         wp_cache_delete( $id, 'networks' );
  1189.  
  1190.         /**
  1191.          * Fires immediately after a network has been removed from the object cache.
  1192.          *
  1193.          * @since 4.6.0
  1194.          *
  1195.          * @param int $id Network ID.
  1196.          */
  1197.         do_action( 'clean_network_cache', $id );
  1198.     }
  1199.  
  1200.     wp_cache_set( 'last_changed', microtime(), 'networks' );
  1201. }
  1202.  
  1203. /**
  1204.  * Updates the network cache of given networks.
  1205.  *
  1206.  * Will add the networks in $networks to the cache. If network ID already exists
  1207.  * in the network cache then it will not be updated. The network is added to the
  1208.  * cache using the network group with the key using the ID of the networks.
  1209.  *
  1210.  * @since 4.6.0
  1211.  *
  1212.  * @param array $networks Array of network row objects.
  1213.  */
  1214. function update_network_cache( $networks ) {
  1215.     foreach ( (array) $networks as $network ) {
  1216.         wp_cache_add( $network->id, $network, 'networks' );
  1217.     }
  1218. }
  1219.  
  1220. /**
  1221.  * Adds any networks from the given IDs to the cache that do not already exist in cache.
  1222.  *
  1223.  * @since 4.6.0
  1224.  * @access private
  1225.  *
  1226.  * @see update_network_cache()
  1227.  * @global wpdb $wpdb WordPress database abstraction object.
  1228.  *
  1229.  * @param array $network_ids Array of network IDs.
  1230.  */
  1231. function _prime_network_caches( $network_ids ) {
  1232.     global $wpdb;
  1233.  
  1234.     $non_cached_ids = _get_non_cached_ids( $network_ids, 'networks' );
  1235.     if ( !empty( $non_cached_ids ) ) {
  1236.         $fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
  1237.  
  1238.         update_network_cache( $fresh_networks );
  1239.     }
  1240. }
  1241.  
  1242. /**
  1243.  * Handler for updating the site's last updated date when a post is published or
  1244.  * an already published post is changed.
  1245.  *
  1246.  * @since 3.3.0
  1247.  *
  1248.  * @param string $new_status The new post status
  1249.  * @param string $old_status The old post status
  1250.  * @param object $post       Post object
  1251.  */
  1252. function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
  1253.     $post_type_obj = get_post_type_object( $post->post_type );
  1254.     if ( ! $post_type_obj || ! $post_type_obj->public ) {
  1255.         return;
  1256.     }
  1257.  
  1258.     if ( 'publish' != $new_status && 'publish' != $old_status ) {
  1259.         return;
  1260.     }
  1261.  
  1262.     // Post was freshly published, published post was saved, or published post was unpublished.
  1263.  
  1264.     wpmu_update_blogs_date();
  1265. }
  1266.  
  1267. /**
  1268.  * Handler for updating the current site's last updated date when a published
  1269.  * post is deleted.
  1270.  *
  1271.  * @since 3.4.0
  1272.  *
  1273.  * @param int $post_id Post ID
  1274.  */
  1275. function _update_blog_date_on_post_delete( $post_id ) {
  1276.     $post = get_post( $post_id );
  1277.  
  1278.     $post_type_obj = get_post_type_object( $post->post_type );
  1279.     if ( ! $post_type_obj || ! $post_type_obj->public ) {
  1280.         return;
  1281.     }
  1282.  
  1283.     if ( 'publish' != $post->post_status ) {
  1284.         return;
  1285.     }
  1286.  
  1287.     wpmu_update_blogs_date();
  1288. }
  1289.  
  1290. /**
  1291.  * Handler for updating the current site's posts count when a post is deleted.
  1292.  *
  1293.  * @since 4.0.0
  1294.  *
  1295.  * @param int $post_id Post ID.
  1296.  */
  1297. function _update_posts_count_on_delete( $post_id ) {
  1298.     $post = get_post( $post_id );
  1299.  
  1300.     if ( ! $post || 'publish' !== $post->post_status || 'post' !== $post->post_type ) {
  1301.         return;
  1302.     }
  1303.  
  1304.     update_posts_count();
  1305. }
  1306.  
  1307. /**
  1308.  * Handler for updating the current site's posts count when a post status changes.
  1309.  *
  1310.  * @since 4.0.0
  1311.  * @since 4.9.0 Added the `$post` parameter.
  1312.  *
  1313.  * @param string  $new_status The status the post is changing to.
  1314.  * @param string  $old_status The status the post is changing from.
  1315.  * @param WP_Post $post       Post object
  1316.  */
  1317. function _update_posts_count_on_transition_post_status( $new_status, $old_status, $post = null ) {
  1318.     if ( $new_status === $old_status ) {
  1319.         return;
  1320.     }
  1321.  
  1322.     if ( 'post' !== get_post_type( $post ) ) {
  1323.         return;
  1324.     }
  1325.  
  1326.     if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
  1327.         return;
  1328.     }
  1329.  
  1330.     update_posts_count();
  1331. }
  1332.