WordPress.org

Make WordPress Core

Changeset 39082


Ignore:
Timestamp:
11/02/2016 12:30:29 AM (4 years ago)
Author:
pento
Message:

Roles/Capabilities: Add a new wp_roles_init filter.

Historically, it's been difficult to extend user roles, but reasonable to work around by waiting until after init has fired, to add custom roles and capabilities. With the addition of Locale Switching, Core now potentially loads roles before init has fired, leaving a window where custom roles and capabilities are not handled.

The new filter allows plugins to add their own custom roles whenever they're initialised (on page load, or when switching sites, for example), so that they can always be obeyed.

WP_Roles has also been tidied up a little bit, to remove duplicate code.

Props johnjamesjacoby, pento.
Fixes #23016.

Location:
trunk
Files:
4 edited

Legend:

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

    r38768 r39082  
    128128            $this->role_names[$role] = $this->roles[$role]['name'];
    129129        }
     130
     131        /**
     132         * After the roles have been initialized, allow plugins to add their own roles.
     133         *
     134         * @since 4.7.0
     135         *
     136         * @param WP_Roles A reference to the WP_Roles object.
     137         */
     138        do_action( 'wp_roles_init', $this );
    130139    }
    131140
     
    137146     *
    138147     * @since 3.5.0
     148     * @deprecated 4.7.0 Use new WP_Roles()
    139149     * @access public
    140150     */
    141151    public function reinit() {
    142         global $wpdb;
    143 
    144         // There is no need to reinit if using the wp_user_roles global.
    145         if ( ! $this->use_db ) {
    146             return;
    147         }
    148 
    149         // Duplicated from _init() to avoid an extra function call.
    150         $this->role_key = $wpdb->get_blog_prefix() . 'user_roles';
    151         $this->roles = get_option( $this->role_key );
    152         if ( empty( $this->roles ) )
    153             return;
    154 
    155         $this->role_objects = array();
    156         $this->role_names =  array();
    157         foreach ( array_keys( $this->roles ) as $role ) {
    158             $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
    159             $this->role_names[$role] = $this->roles[$role]['name'];
    160         }
     152        __deprecated_function( __METHOD__, '4.7.0', 'new WP_Roles()' );
     153        $this->_init();
    161154    }
    162155
  • trunk/src/wp-includes/ms-blogs.php

    r38943 r39082  
    767767 */
    768768function switch_to_blog( $new_blog, $deprecated = null ) {
    769     global $wpdb;
     769    global $wpdb, $wp_roles;
    770770
    771771    $blog_id = get_current_blog_id();
     
    823823
    824824    if ( did_action( 'init' ) ) {
    825         wp_roles()->reinit();
     825        $wp_roles = new WP_Roles();
    826826        $current_user = wp_get_current_user();
    827827        $current_user->for_blog( $new_blog );
     
    851851 */
    852852function restore_current_blog() {
    853     global $wpdb;
     853    global $wpdb, $wp_roles;
    854854
    855855    if ( empty( $GLOBALS['_wp_switched_stack'] ) ) {
     
    897897
    898898    if ( did_action( 'init' ) ) {
    899         wp_roles()->reinit();
     899        $wp_roles = new WP_Roles();
    900900        $current_user = wp_get_current_user();
    901901        $current_user->for_blog( $blog );
  • trunk/tests/phpunit/tests/user/capabilities.php

    r39035 r39082  
    4242        unset($GLOBALS['wp_user_roles']);
    4343        global $wp_roles;
    44         if ( is_object( $wp_roles ) )
    45             $wp_roles->_init();
     44        $wp_roles = new WP_Roles();
    4645    }
    4746
     
    16271626    }
    16281627
     1628    protected $_role_test_wp_roles_role;
     1629    /**
     1630     * @ticket 23016
     1631     */
     1632    public function test_wp_roles_init_action() {
     1633        $this->_role_test_wp_roles_init = array(
     1634            'role' => 'test_wp_roles_init',
     1635            'info' => array(
     1636                'name' => 'Test WP Roles Init',
     1637                'capabilities' => array( 'testing_magic' => true ),
     1638            ),
     1639        );
     1640        add_action( 'wp_roles_init', array( $this, '_hook_wp_roles_init' ), 10, 1 );
     1641
     1642        $wp_roles = new WP_Roles();
     1643
     1644        remove_action( 'wp_roles_init', array( $this, '_hook_wp_roles_init' ) );
     1645
     1646        $expected = new WP_Role( $this->_role_test_wp_roles_init['role'], $this->_role_test_wp_roles_init['info']['capabilities'] );
     1647
     1648        $role = $wp_roles->get_role( $this->_role_test_wp_roles_init['role'] );
     1649
     1650        $this->assertEquals( $expected, $role );
     1651        $this->assertContains( $this->_role_test_wp_roles_init['info']['name'], $wp_roles->role_names );
     1652    }
     1653
     1654    public function _hook_wp_roles_init( $wp_roles ) {
     1655        $wp_roles->add_role( $this->_role_test_wp_roles_init['role'], $this->_role_test_wp_roles_init['info']['name'], $this->_role_test_wp_roles_init['info']['capabilities'] );
     1656    }
    16291657}
  • trunk/tests/phpunit/tests/user/multisite.php

    r38903 r39082  
    397397        $this->assertWPError( $result );
    398398    }
     399
     400    /**
     401     * @ticket 23016
     402     */
     403    public function test_wp_roles_global_is_reset() {
     404        global $wp_roles;
     405        $role = 'test_global_is_reset';
     406        $role_name = 'Test Global Is Reset';
     407        $blog_id = self::factory()->blog->create();
     408
     409        $wp_roles->add_role( $role, $role_name, array() );
     410
     411        $this->assertNotEmpty( $wp_roles->get_role( $role ) );
     412
     413        switch_to_blog( $blog_id );
     414
     415        $this->assertEmpty( $wp_roles->get_role( $role ) );
     416
     417        $wp_roles->add_role( $role, $role_name, array() );
     418
     419        $this->assertNotEmpty( $wp_roles->get_role( $role ) );
     420
     421        restore_current_blog();
     422
     423        $this->assertNotEmpty( $wp_roles->get_role( $role ) );
     424
     425        $wp_roles->remove_role( $role );
     426    }
    399427}
    400428
Note: See TracChangeset for help on using the changeset viewer.