WordPress 5.3 增强“网络站点”的功能

对数据库的更改

WordPress 5.1 中站点元数据的引入为多站点开辟了许多新的可能性。

多站点元数据中保存数据库版本和更新日期

[46193]中,数据库版本和更新日期都保存在blogmeta表中。

如果您的多站点设置要求从全局上下文访问数据库版本,而不是使用switch_to_blog调用在每个站点周围循环get_option( 'db_version' ),那您可以尝试以下函数。

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 );
}

删除blog_versions表

目前,多站点中有一个名为blog_versions的数据表。这个表将数据库版本存储为数字和更新日期。它是在#11644中引入的,但一直都没有在WP核心中使用过。

由于现在将数据库版本和更新日期都保存在blogmeta表中,所以blog_versions表就多余了。

对WP_MS_Sites_List_Table的更改

WordPress 5.3WP_MS_Sites_List_Table类中添加了一些增强功能,使插件作者可以利用站点元数据在“ 管理网络站点”界面上为多站点管理员提供更丰富的体验。

使用和/或自定义“所有文章”界面的人员将非常熟悉这些增强功能。

站点状态视图

现在,“网络站点”界面将显示一个链接列表,其中包含按状态(例如“公共”,“垃圾”等)的站点计数,类似于“所有文章”屏幕上的文章状态链接。

状态链接也可以使用views_sites-network过滤器进行过滤。

例如,假设有一个多站点,其中主站点充当本地餐馆的目录,而每个站点都是针对单个餐馆的,而餐馆所有者可以购买“订阅”,从而使他们可以显示有关其餐馆清单的更多信息:基本订阅将允许他们添加餐厅的照片,高级订阅将允许他们添加菜单。

然后可以将订阅级别存储在blogmeta表中,并可以为不同的订阅级别添加“状态”链接,如下所示:

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;
}

当用户单击一个自定义状态链接时,可以使用现有的ms_sites_list_table_query_args将列表中的行限制为具有该特定自定义状态的网站,如下所示:

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;
}

额外的表格导航

显示在“ 所有文章”界面上的文章可以按日期和分类进行过滤。插件还可以通过 restrict_manage_posts过滤器 添加自定义过滤条件。

继续上面的餐厅指南示例,假设每个餐厅提供的食物也存储在blogmeta表中。然后,我们可以允许网络管理员通过添加各种美食的下拉列表,根据食物的类型来过滤站点:

这样的下拉列表现在可以通过新的restrict_manage_sites动作钩子(在Trac#45954中引入)添加到“网络站点”界面上,如下所示:

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;
}

当用户选择一种食物类型并单击“ 过滤器”按钮时,列表中的行可以仅限于使用现有ms_sites_list_table_query_args过滤器提供该美食的站点, 如下所示:

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;
}

网站显示状态

与其他列表一样,“站点”列表中的每一行现在都有显示状态。默认情况下,每个网站的所有网站状态(“公共”除外)都作为显示状态包括在内。此外,网络的主站点也具有“主要”显示状态。

当用户选择了特定的站点状态视图时,该状态将不在显示状态中(就像“所有文章”屏幕一样)。

插件还可以使用display_site_states过滤器修改显示状态 。

为了进一步延续我们的餐厅指南示例,我们可以添加自定义状态以及每个餐厅提供的美食作为显示状态。这可以通过以下方式实现:

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;
}

其他变更

返回短路的多站点类

修复在 [44983]原始补丁,在多站点类中引入了预查询过滤器。此错误使短路行为与其他短路行为有所不同,并且仍在继续执行。现在,通过networks_pre_querysites_pre_query运行过滤后,该代码将立即退出。这使开发人员可以完全热线连接网络和站点查询,以从另一个来源(例如,不同的缓存或弹性搜索)进行加载。

通过ID改进了站点和网络查找的性能

在早期版本的WordPress中,当运行代码get_site( 12345 ) 时,如果没有该站点的ID,是不会缓存结果的。这意味着随后的所有查找仍将导致数据库查询被触发,这是不必要的。在[45910]中,不存在的站点数据将存储为-1而不是false,以便后续的数据库查找。

倡萌

一个文科IT宅男,喜欢折腾WordPress和被它折腾 ^_^

2 条评论

发表评论