Make WordPress Core


Ignore:
Timestamp:
03/16/2018 02:14:04 AM (7 years ago)
Author:
flixos90
Message:

Multisite: Introduce metadata for sites.

A new global multisite table wp_blogmeta is added to the database schema, and a set of *_site_meta() API functions are introduced.

The implementation fails gracefully when the new table is not yet available, which may happen especially shortly after the core update, before the network has been upgraded to the new database schema. The presence of the table is detected once and stored as a global setting on the main network.

Core does not yet use site metadata, but there are several use-cases to be implemented or explored in the near future, and it allows plugins to extend sites with arbitrary data, which will come in particularly handy with the upcoming REST API endpoint for sites.

Props spacedmonkey, johnjamesjacoby, jeremyfelt, flixos90.
Fixes #37923.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ms-blogs.php

    r42678 r42836  
    475475    wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
    476476    wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
     477    wp_cache_delete( $blog_id, 'blog_meta' );
    477478
    478479    /**
     
    561562 *
    562563 * @since 4.6.0
     564 * @since 5.0.0 Introduced the `$update_meta_cache` parameter.
    563565 * @access private
    564566 *
     
    566568 * @global wpdb $wpdb WordPress database abstraction object.
    567569 *
    568  * @param array $ids ID list.
    569  */
    570 function _prime_site_caches( $ids ) {
     570 * @param array $ids               ID list.
     571 * @param bool  $update_meta_cache Optional. Whether to update the meta cache. Default true.
     572 */
     573function _prime_site_caches( $ids, $update_meta_cache = true ) {
    571574    global $wpdb;
    572575
     
    575578        $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ',', array_map( 'intval', $non_cached_ids ) ) ) );
    576579
    577         update_site_cache( $fresh_sites );
     580        update_site_cache( $fresh_sites, $update_meta_cache );
    578581    }
    579582}
     
    583586 *
    584587 * @since 4.6.0
    585  *
    586  * @param array $sites Array of site objects.
    587  */
    588 function update_site_cache( $sites ) {
     588 * @since 5.0.0 Introduced the `$update_meta_cache` parameter.
     589 *
     590 * @param array $sites             Array of site objects.
     591 * @param bool  $update_meta_cache Whether to update site meta cache. Default true.
     592 */
     593function update_site_cache( $sites, $update_meta_cache = true ) {
    589594    if ( ! $sites ) {
    590595        return;
    591596    }
    592 
     597    $site_ids = array();
    593598    foreach ( $sites as $site ) {
     599        $site_ids[] = $site->blog_id;
    594600        wp_cache_add( $site->blog_id, $site, 'sites' );
    595601        wp_cache_add( $site->blog_id . 'short', $site, 'blog-details' );
    596602    }
     603
     604    if ( $update_meta_cache ) {
     605        update_sitemeta_cache( $site_ids );
     606    }
     607}
     608
     609/**
     610 * Updates metadata cache for list of site IDs.
     611 *
     612 * Performs SQL query to retrieve all metadata for the sites matching `$site_ids` and stores them in the cache.
     613 * Subsequent calls to `get_site_meta()` will not need to query the database.
     614 *
     615 * @since 5.0.0
     616 *
     617 * @param array $site_ids List of site IDs.
     618 * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
     619 */
     620function update_sitemeta_cache( $site_ids ) {
     621    if ( ! is_site_meta_supported() ) {
     622        return false;
     623    }
     624
     625    return update_meta_cache( 'blog', $site_ids );
    597626}
    598627
     
    798827
    799828/**
     829 * Adds metadata to a site.
     830 *
     831 * @since 5.0.0
     832 *
     833 * @param int    $site_id    Site ID.
     834 * @param string $meta_key   Metadata name.
     835 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
     836 * @param bool   $unique     Optional. Whether the same key should not be added.
     837 *                           Default false.
     838 * @return int|false Meta ID on success, false on failure.
     839 */
     840function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) {
     841    // Bail if site meta table is not installed.
     842    if ( ! is_site_meta_supported() ) {
     843        /* translators: %s: database table name */
     844        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.0.0' );
     845        return false;
     846    }
     847
     848    $added = add_metadata( 'blog', $site_id, $meta_key, $meta_value, $unique );
     849
     850    // Bust site query cache.
     851    if ( $added ) {
     852        wp_cache_set( 'last_changed', microtime(), 'sites' );
     853    }
     854
     855    return $added;
     856}
     857
     858/**
     859 * Removes metadata matching criteria from a site.
     860 *
     861 * You can match based on the key, or key and value. Removing based on key and
     862 * value, will keep from removing duplicate metadata with the same key. It also
     863 * allows removing all metadata matching key, if needed.
     864 *
     865 * @since 5.0.0
     866 *
     867 * @param int    $site_id    Site ID.
     868 * @param string $meta_key   Metadata name.
     869 * @param mixed  $meta_value Optional. Metadata value. Must be serializable if
     870 *                           non-scalar. Default empty.
     871 * @return bool True on success, false on failure.
     872 */
     873function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) {
     874    // Bail if site meta table is not installed.
     875    if ( ! is_site_meta_supported() ) {
     876        /* translators: %s: database table name */
     877        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.0.0' );
     878        return false;
     879    }
     880
     881    $deleted = delete_metadata( 'blog', $site_id, $meta_key, $meta_value );
     882
     883    // Bust site query cache.
     884    if ( $deleted ) {
     885        wp_cache_set( 'last_changed', microtime(), 'sites' );
     886    }
     887
     888    return $deleted;
     889}
     890
     891/**
     892 * Retrieves metadata for a site.
     893 *
     894 * @since 5.0.0
     895 *
     896 * @param int    $site_id Site ID.
     897 * @param string $key     Optional. The meta key to retrieve. By default, returns
     898 *                        data for all keys. Default empty.
     899 * @param bool   $single  Optional. Whether to return a single value. Default false.
     900 * @return mixed Will be an array if $single is false. Will be value of meta data
     901 *               field if $single is true.
     902 */
     903function get_site_meta( $site_id, $key = '', $single = false ) {
     904    // Bail if site meta table is not installed.
     905    if ( ! is_site_meta_supported() ) {
     906        /* translators: %s: database table name */
     907        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.0.0' );
     908        return false;
     909    }
     910
     911    return get_metadata( 'blog', $site_id, $key, $single );
     912}
     913
     914/**
     915 * Updates metadata for a site.
     916 *
     917 * Use the $prev_value parameter to differentiate between meta fields with the
     918 * same key and site ID.
     919 *
     920 * If the meta field for the site does not exist, it will be added.
     921 *
     922 * @since 5.0.0
     923 *
     924 * @param int    $site_id    Site ID.
     925 * @param string $meta_key   Metadata key.
     926 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
     927 * @param mixed  $prev_value Optional. Previous value to check before removing.
     928 *                           Default empty.
     929 * @return int|bool Meta ID if the key didn't exist, true on successful update,
     930 *                  false on failure.
     931 */
     932function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' ) {
     933    // Bail if site meta table is not installed.
     934    if ( ! is_site_meta_supported() ) {
     935        /* translators: %s: database table name */
     936        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.0.0' );
     937        return false;
     938    }
     939
     940    $updated = update_metadata( 'blog', $site_id, $meta_key, $meta_value, $prev_value );
     941
     942    // Bust site query cache.
     943    if ( $updated ) {
     944        wp_cache_set( 'last_changed', microtime(), 'sites' );
     945    }
     946
     947    return $updated;
     948}
     949
     950/**
     951 * Deletes everything from site meta matching meta key.
     952 *
     953 * @since 5.0.0
     954 *
     955 * @param string $meta_key Metadata key to search for when deleting.
     956 * @return bool Whether the site meta key was deleted from the database.
     957 */
     958function delete_site_meta_by_key( $meta_key ) {
     959    // Bail if site meta table is not installed.
     960    if ( ! is_site_meta_supported() ) {
     961        /* translators: %s: database table name */
     962        _doing_it_wrong( __FUNCTION__, sprintf( __( 'The %s table is not installed. Please run the network database upgrade.' ), $GLOBALS['wpdb']->blogmeta ), '5.0.0' );
     963        return false;
     964    }
     965
     966    $deleted = delete_metadata( 'blog', null, $meta_key, '', true );
     967
     968    // Bust site query cache.
     969    if ( $deleted ) {
     970        wp_cache_set( 'last_changed', microtime(), 'sites' );
     971    }
     972
     973    return $deleted;
     974}
     975
     976/**
    800977 * Switch the current blog.
    801978 *
     
    8701047                wp_cache_add_global_groups( $global_groups );
    8711048            } else {
    872                 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' ) );
     1049                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', 'blog_meta' ) );
    8731050            }
    8741051            wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
     
    9381115                wp_cache_add_global_groups( $global_groups );
    9391116            } else {
    940                 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' ) );
     1117                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', 'blog_meta' ) );
    9411118            }
    9421119            wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
Note: See TracChangeset for help on using the changeset viewer.