Make WordPress Core


Ignore:
Timestamp:
09/27/2017 09:43:59 PM (7 years ago)
Author:
flixos90
Message:

Multisite: Improve initializing available roles when switch sites.

Switching the available roles and the current user's capabilities no longer happens in switch_to_blog() and restore_current_blog(), instead it has been moved to a new function wp_switch_roles_and_user() which is hooked into the site switching process. This allows to improve performance by temporarily unhooking the function when roles and capabilities do not need to be switched.

This change ensures that switching available roles now works closer to switching user capabilities, particularly the changes in [41624]. A new WP_Roles::for_site( $site_id ) method has been introduced, and the WP_Roles::_init() method has been deprecated. It is furthermore possible to retrieve the site ID for which the available roles are currently initialized through a new WP_Roles::get_site_id().

Props johnjamesjacoby, flixos90.
Fixes #38645.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-roles.php

    r41162 r41625  
    6666
    6767    /**
     68     * The site ID the roles are initialized for.
     69     *
     70     * @since 4.9.0
     71     * @var int
     72     */
     73    protected $site_id = 0;
     74
     75    /**
    6876     * Constructor
    6977     *
    7078     * @since 2.0.0
    71      */
    72     public function __construct() {
    73         $this->_init();
     79     * @since 4.9.0 The $site_id argument was added.
     80     *
     81     * @global array $wp_user_roles Used to set the 'roles' property value.
     82     *
     83     * @param int $site_id Site ID to initialize roles for. Default is the current site.
     84     */
     85    public function __construct( $site_id = null ) {
     86        global $wp_user_roles;
     87
     88        $this->use_db = empty( $wp_user_roles );
     89
     90        $this->for_site( $site_id );
    7491    }
    7592
     
    98115     *
    99116     * @since 2.1.0
    100      *
    101      * @global array $wp_user_roles Used to set the 'roles' property value.
     117     * @deprecated 4.9.0 Use WP_Roles::for_site()
    102118     */
    103119    protected function _init() {
    104         global $wp_user_roles, $wpdb;
    105 
    106         $this->role_key = $wpdb->get_blog_prefix() . 'user_roles';
    107         if ( ! empty( $wp_user_roles ) ) {
    108             $this->roles = $wp_user_roles;
    109             $this->use_db = false;
    110         } else {
    111             $this->roles = get_option( $this->role_key );
    112         }
    113 
    114         if ( empty( $this->roles ) )
    115             return;
    116 
    117         $this->role_objects = array();
    118         $this->role_names =  array();
    119         foreach ( array_keys( $this->roles ) as $role ) {
    120             $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
    121             $this->role_names[$role] = $this->roles[$role]['name'];
    122         }
    123 
    124         /**
    125          * After the roles have been initialized, allow plugins to add their own roles.
    126          *
    127          * @since 4.7.0
    128          *
    129          * @param WP_Roles $this A reference to the WP_Roles object.
    130          */
    131         do_action( 'wp_roles_init', $this );
     120        _deprecated_function( __METHOD__, '4.9.0', 'WP_Roles::for_site()' );
     121
     122        $this->for_site();
    132123    }
    133124
     
    139130     *
    140131     * @since 3.5.0
    141      * @deprecated 4.7.0 Use new WP_Roles()
     132     * @deprecated 4.7.0 Use WP_Roles::for_site()
    142133     */
    143134    public function reinit() {
    144         _deprecated_function( __METHOD__, '4.7.0', 'new WP_Roles()' );
    145         $this->_init();
     135        _deprecated_function( __METHOD__, '4.7.0', 'WP_Roles::for_site()' );
     136
     137        $this->for_site();
    146138    }
    147139
     
    271263        return isset( $this->role_names[$role] );
    272264    }
     265
     266    /**
     267     * Initializes all of the available roles.
     268     *
     269     * @since 4.9.0
     270     */
     271    public function init_roles() {
     272        if ( empty( $this->roles ) ) {
     273            return;
     274        }
     275
     276        $this->role_objects = array();
     277        $this->role_names =  array();
     278        foreach ( array_keys( $this->roles ) as $role ) {
     279            $this->role_objects[ $role ] = new WP_Role( $role, $this->roles[ $role ]['capabilities'] );
     280            $this->role_names[ $role ] = $this->roles[ $role ]['name'];
     281        }
     282
     283        /**
     284         * After the roles have been initialized, allow plugins to add their own roles.
     285         *
     286         * @since 4.7.0
     287         *
     288         * @param WP_Roles $this A reference to the WP_Roles object.
     289         */
     290        do_action( 'wp_roles_init', $this );
     291    }
     292
     293    /**
     294     * Sets the site to operate on. Defaults to the current site.
     295     *
     296     * @since 4.9.0
     297     *
     298     * @global wpdb $wpdb WordPress database abstraction object.
     299     *
     300     * @param int $site_id Site ID to initialize roles for. Default is the current site.
     301     */
     302    public function for_site( $site_id = null ) {
     303        global $wpdb;
     304
     305        if ( ! empty( $site_id ) ) {
     306            $this->site_id = absint( $site_id );
     307        } else {
     308            $this->site_id = get_current_blog_id();
     309        }
     310
     311        $this->role_key = $wpdb->get_blog_prefix( $this->site_id ) . 'user_roles';
     312
     313        if ( ! empty( $this->roles ) && ! $this->use_db ) {
     314            return;
     315        }
     316
     317        $this->roles = $this->get_roles_data();
     318
     319        $this->init_roles();
     320    }
     321
     322    /**
     323     * Gets the ID of the site for which roles are currently initialized.
     324     *
     325     * @since 4.9.0
     326     *
     327     * @return int Site ID.
     328     */
     329    public function get_site_id() {
     330        return $this->site_id;
     331    }
     332
     333    /**
     334     * Gets the available roles data.
     335     *
     336     * @since 4.9.0
     337     *
     338     * @global array $wp_user_roles Used to set the 'roles' property value.
     339     *
     340     * @return array Roles array.
     341     */
     342    protected function get_roles_data() {
     343        global $wp_user_roles;
     344
     345        if ( ! empty( $wp_user_roles ) ) {
     346            return $wp_user_roles;
     347        }
     348
     349        if ( is_multisite() && $this->site_id != get_current_blog_id() ) {
     350            remove_action( 'switch_blog', 'wp_switch_roles_and_user', 1 );
     351
     352            $roles = get_blog_option( $this->site_id, $this->role_key, array() );
     353
     354            add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 );
     355
     356            return $roles;
     357        }
     358
     359        return get_option( $this->role_key, array() );
     360    }
    273361}
Note: See TracChangeset for help on using the changeset viewer.