WordPress 多站点是一个很棒的工具,但它有其局限性和警告,特别是当你处理非常大的网络时。在薇晓朵网站,我们使用此代码段来阻止 “我的网站” 菜单查询用户所属的网络上的每个网站。
这对于小型网络或只是少数博客/网站的用户来说并不是那么糟糕,但如果你有超级管理员,他们是大多数(如果不是全部)网站的成员,那么你肯定会想要这个片段。
/** * Loading all sites menu for large multisite * is inefficient and bad news */ function large_network_remove_wp_admin_bar_my_sites_menu() { remove_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 ); } add_action( 'add_admin_bar_menus', 'large_network_remove_wp_admin_bar_my_sites_menu' ); /** * Let's replace that menu with one that has * links to the network dashboard instead. */ function large_network_replacement_my_sites_menu( $wp_admin_bar ) { if ( ! current_user_can( 'manage_network' ) ) { // bail.. no network menu for you! return; } $wp_admin_bar->add_menu( array( 'id' => 'prefix-my-sites', 'title' => __( 'My Sites' ), 'href' => admin_url( 'my-sites.php' ), )); $wp_admin_bar->add_menu( array( 'id' => 'prefix-network-admin', 'parent' => 'prefix-my-sites', 'title' => __( 'Network Dashboard' ), 'href' => network_admin_url(), )); $wp_admin_bar->add_menu( array( 'id' => 'prefix-network-sites', 'parent' => 'prefix-my-sites', 'title' => __( 'Network Sites' ), 'href' => network_admin_url( 'sites.php' ), )); $wp_admin_bar->add_menu( array( 'id' => 'prefix-network-users', 'parent' => 'prefix-my-sites', 'title' => __( 'Network Users' ), 'href' => network_admin_url( 'users.php' ), )); } add_action( 'admin_bar_menu', 'large_network_replacement_my_sites_menu', 20 );
更新:当 WordPress 用户登录并且是许多站点的成员(例如数千个)时,仍然存在一些性能问题。我在 WordPress trac 上创建了一张新票,希望它有一些动力,但在那之前我提供了一个有用的片段,它有助于解决超级管理员成为数千个网站 “成员” 的问题。
/** * Remove all site capability keys when retrieving user meta * This prevents `get_blog_details` lookups for all the sites * a super admin is a member or admin * * @link https://core.trac.wordpress.org/ticket/31746#comment:1 get_blogs_of_user() can be very slow when a user is a member of thousands of sites */ function large_network_skip_get_blogs_of_user_with_many_sites( $null, $object_id, $meta_key ) { global $wpdb; // Don't proceed if fetching a specific meta key, or the current user is not a super admin if ( $meta_key || ! is_super_admin() ) { return $null; } // Ok, then fetch all the user meta (remove this filter to do so) remove_filter( 'get_user_metadata', __FUNCTION__, 10, 4 ); $keys = get_user_meta( $object_id ); add_filter( 'get_user_metadata', __FUNCTION__, 10, 4 ); // And loop through them foreach ( $keys as $key => $value ) { // Ignore non-capability meta keys if ( 'capabilities' !== substr( $key, -12 ) ) { continue; } // Ignore meta keys w/o the base_prefix if ( $wpdb->base_prefix && 0 !== strpos( $key, $wpdb->base_prefix ) ) { continue; } // Attempt to get the blog id from the string $blog_id = str_replace( array( $wpdb->base_prefix, '_capabilities' ), '', $key ); // If it's not numeric, ignore this too if ( ! is_numeric( $blog_id ) ) { continue; } // Ok, let's black-list this capability meta from being sent back unset( $keys[ $key ] ); } return $keys; } add_filter( 'get_user_metadata', 'large_network_skip_get_blogs_of_user_with_many_sites', 10, 3 );