WordPress 5.3 enhances the function of “website”

Article directory [hide]

  • Changes to the database
    • Save database version and update date in multi-site metadata
    • Delete the blog_versions table
  • Changes to WP_MS_Sites_List_Table
    • Site status view
    • Additional table navigation
    • Website display status
  • Other changes
    • Return short-circuited multisite class
    • Improved site and network lookup performance through ID

Changes to the database

The introduction of site metadata in WordPress 5.1 opens up many new possibilities for multiple sites.

Save database version and update date in multi-site metadata

In [46193], the database version and update date are stored in the blogmetatable.

If your multi-site setup requires access to the database version from the global context, instead of using switch_to_blogcalls to loop around each site get_option( 'db_version' ), you can try the following function.

function get_site_versions() {
    global $wpdb;
    $query = $wpdb->prepare( "SELECT blog_id, meta_value FROM $wpdb->blogmeta WHERE meta_key = 'db_version' ORDER BY blog_id DESC");
    return $wpdb->get_results( $query );
}

Delete the blog_versions table

Currently, there is a blog_versions table named in the multisite . This table stores the database version as a number and update date. It was introduced in #11644, but has never been used in core.

Since the database version and update date are now stored in the blogmetatable, the blog_versionstable is redundant.

Changes to WP_MS_Sites_List_Table

WordPress 5.3 adds some enhancements to the WP_MS_Sites_List_Table class, allowing plugin authors to use site metadata to provide a richer experience for multisite administrators on the “Manage Network Sites” interface.

Those who use and/or customize the “All Articles” interface will be very familiar with these enhancements.

Site status view

Now, the “Web Sites” interface will display a list of containing a site count by status (such as “Public”, “Trash”, etc.), similar to the article status links on the “All Articles” screen.

Status can also be views_sites-networkfiltered using filters.

For example, suppose there is a multi-site where the main site acts as a of local restaurants, and each site is for a single restaurant, and restaurant owners can purchase “subscriptions” so they can display more about their restaurant listings Info: Basic subscription will allow them to add photos of restaurants, premium subscription will allow them to add menus.

You can then store the subscription levels in a blogmetatable, and you can add “status” for different subscription levels, as shown below:

add_filter( 'views_sites-network', 'myplugin_add_site_status_views' );
function myplugin_add_site_status_views( $view_links ) {
    $statuses = array(
        'free'      => _n_noop(
            'Free <span class="count">(%s)</span>',
            'Free <span class="count">(%s)</span>',
            'myplugin'
        ),
        'basic'   => _n_noop(
            'Basic <span class="count">(%s)</span>',
            'Basic <span class="count">(%s)</span>',
            'myplugin'
        ),
        'advanced'   => _n_noop(
            'Advanced <span class="count">(%s)</span>',
            'Advanced <span class="count">(%s)</span>',
            'myplugin'
        ),
    );
 
    // get the count of sites with each of our custom statuses.
    $args = array(
        'meta_query' => array(
            array(
                'key'     => 'myplugin-status',
                'compare' => '=',
            ),
        ),
        'count' => true,
    );
    $counts = array();
    foreach ( array_keys( $statuses ) as $status ) {
        $args['meta_query'][0]['value'] = $status;
        $counts[ $status ] = get_sites( $args );
    }
 
    $requested_status = isset( $_GET['status'] ) ? wp_unslash( trim( $_GET['status'] ) ) : '';
 
    foreach ( $statuses as $status => $label_count ) {
        $current_link_attributes = $requested_status === $status ?
            ' class="current" aria-current="page"' :
            '';
        if ( (int) $counts[ $status ] > 0 ) {
            $label = sprintf( translate_nooped_plural( $label_count, $counts[ $status ] ), number_format_i18n( $counts[ $status ] ) );
 
            $view_links[ $status ] = sprintf(
                '<a href="%1$s"%2$s>%3$s</a>',
                esc_url( add_query_arg( 'status', $status, 'sites.php' ) ),
                $current_link_attributes,
                $label
            );
        }
    }
 
    return $view_links;
}

When a user clicks on a custom status link, the existing ms_sites_list_table_query_args can be used to limit the rows in the list to sites with that specific custom status, as shown below:

add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_custom_status' );
function myplugin_sites_with_custom_status( $args ) {
    $status = ! empty( $_GET['status' ] ) ? wp_unslash( $_GET['status' ] ) : '';
 
    if ( empty( $status ) || ! in_array( $_GET['status'], array( 'free', 'basic', 'advanced' ) ) ) {
        return $args;
    }
 
    $meta_query = array(
        'key'   => 'myplugin-status',
        'value' => $status,
    );
 
    if ( isset( $args['meta_query'] ) ) {
        // add our meta query to the existing one(s).
        $args['meta_query'] = array(
            'relation' => 'AND',
            $meta_query,
            array( $args['meta_query'] ),
        );
    }
    else {
        // add our meta query.
        $args['meta_query'] = array(
            $meta_query,
        );
    }
 
    return $args;
}

Additional table navigation

Displayed in the ”  all articles” on the interface of the article can be filtered by date and classification. The plug-in can also add custom filter conditions through the restrict_manage_posts filter.

Continuing the restaurant guide example above, assume that the food provided by each restaurant is also stored in the blogmetatable. Then, we can allow the network administrator to filter the site according to the type of food by adding a drop-down list of various foods:

Such a drop-down list can now be restrict_manage_sitesadded to the “Web Site” interface through a new action hook (introduced in Trac#45954), as shown below:

add_action( 'restrict_manage_sites', 'myplugin_add_cuisines_dropdown' );
function myplugin_add_cuisines_dropdown( $which ) {
    if ( 'top' !== $which ) {
        return;
    }
 
    echo '<select name="cuisine">';
    printf( '<option value="">%s</option>', __( 'All cuisines', 'myplugin' ) );
 
    $cuisines = array(
        'French'  => __( 'French', 'myplugin' ),
        'Indian'  => __( 'Indian', 'myplugin' ),
        'Mexican' => __( 'Mexican', 'myplugin' ),
    );
     
    $requested_cuisine = isset( $_GET['cuisine'] ) ? wp_unslash( $_GET['cuisine'] ) : '';
     
    foreach ( $cuisines as $cuisine => $label ) {
        $selected = selected( $cuisine, $requested_cuisine, false );
        printf( '<option%s>%s</option>', $selected, $label );
    }
 
    echo '</select>';
 
    return;
}

When the user selects a food type and clicks the ”  filter” button, the rows in the list can be limited to sites that provide the food using the existing ms_sites_list_table_query_args filter, as shown below:

add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_cuisine' );
function myplugin_sites_with_cuisine( $args ) {
    if ( empty( $_GET['cuisine' ] ) ) {
        return $args;
    }
 
    $meta_query = array(
        'key'   => 'myplugin-cuisine',
        'value' => wp_unslash( $_GET['cuisine' ] ),
    );
 
    if ( isset( $args['meta_query'] ) ) {
        // add our meta query to the existing one(s).
        $args['meta_query'] = array(
            'relation' => 'AND',
            $meta_query,
            array( $args['meta_query'] ),
        );
    }
    else {
        // add our meta query.
        $args['meta_query'] = array(
            $meta_query,
        );
    }
 
    return $args;
}

Website display status

Like other lists, each row in the “Sites” list now has a display status. By default, all website statuses (except “Public”) for each website are included as display status. In addition, the main site of the network also has a “main” display status.

When the user selects a specific site status view, that status will not be in the display status (just like the “All Articles” screen).

The plug-in can also use display_site_statesfilters to modify the display status.

To continue our restaurant guide example, we can add a custom status and the food provided by each restaurant as the display status. This can be achieved in the following ways:

add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_cuisine' );
function myplugin_sites_with_cuisine( $args ) {
    if ( empty( $_GET['cuisine' ] ) ) {
        return $args;
    }
 
    $meta_query = array(
        'key'   => 'myplugin-cuisine',
        'value' => wp_unslash( $_GET['cuisine' ] ),
    );
 
    if ( isset( $args['meta_query'] ) ) {
        // add our meta query to the existing one(s).
        $args['meta_query'] = array(
            'relation' => 'AND',
            $meta_query,
            array( $args['meta_query'] ),
        );
    }
    else {
        // add our meta query.
        $args['meta_query'] = array(
            $meta_query,
        );
    }
 
    return $args;
}

Other changes

Return short-circuited multisite class

The fix is ​​in the original patch [44983], introducing a pre-query filter in the multisite class. This error makes the short-circuit behavior different from other short-circuit behaviors, and it continues to execute. Now, after passing networks_pre_queryand sites_pre_queryrunning the filter, the code will exit immediately. This allows developers to fully hotline network and site queries to load from another source (for example, a different cache or elastic search).

Improved site and network lookup performance through ID

In earlier versions of WordPress, when running the code get_site( 12345 ) , without the site ID, the results will not be cached. This means that all subsequent lookups will still cause the database query to be triggered, which is unnecessary. In [45910], non-existent site will be stored as -1not falsefor subsequent database lookups.