Skip to:
Content

BuddyPress.org

Changeset 12740


Ignore:
Timestamp:
10/04/2020 04:44:28 PM (5 years ago)
Author:
imath
Message:

Core: improve the way BuddyPress adds the bp_moderate cap to Admins

This capability is dynamically added to the users having the manage_options one on regular configurations of WordPress (non multisite).

The private function _bp_enforce_bp_moderate_cap_for_admins() has been deprecated and we are now using the private function _bp_roles_init() to do this capability mapping.

This need for improvement has been revealed by an issue about the incapacity for Admins to edit BP Emails if they weren't their authors.

Props shanebp, boonebgorges, johnjamesjacoby

Fixes #8355

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/bp-core-caps.php

    r11107 r12740  
    346346
    347347/**
     348 * Adds the `bp_moderate` cap to Roles having the `manage_options` cap when
     349 * BuddyPress is not active on the network.
     350 *
     351 * @since 7.0.0
     352 *
     353 * @access private
     354 *
     355 * @param WP_Roles $wp_roles The WordPress roles object.
     356 */
     357function _bp_roles_init( WP_Roles $wp_roles ) {
     358    $roles_list = array();
     359    $caps_list  = wp_list_pluck( $wp_roles->role_objects, 'capabilities' );
     360
     361    // Look for roles having the `manage_options` capability set to true.
     362    $filtered_list = wp_list_filter( $caps_list, array( 'manage_options' => true ) );
     363
     364    if ( $filtered_list ) {
     365        $roles_list = array_keys( $filtered_list );
     366
     367        // Loop into roles list to add the `bp_moderate` capability.
     368        foreach ( $roles_list as $role ) {
     369            if ( isset( $wp_roles->roles[ $role ] ) ) {
     370                $wp_roles->roles[ $role ]['capabilities']['bp_moderate'] = true;
     371            }
     372
     373            if ( isset( $wp_roles->role_objects[ $role ] ) ) {
     374                $wp_roles->role_objects[ $role ]->capabilities['bp_moderate'] = true;
     375            }
     376        }
     377    }
     378
     379    // Make sure to remove the `bp_moderate` capability from roles when BuddyPress is network activated.
     380    if ( bp_is_network_activated() ) {
     381        foreach ( $roles_list as $role ) {
     382            unset( $wp_roles->roles[ $role ]['capabilities']['bp_moderate'], $wp_roles->role_objects[ $role ]->capabilities['bp_moderate'] );
     383        }
     384    }
     385}
     386add_action( 'wp_roles_init', '_bp_roles_init', 10, 1 );
     387
     388/** Deprecated ****************************************************************/
     389
     390/**
    348391 * Temporary implementation of 'bp_moderate' cap.
    349392 *
     
    364407 *
    365408 * @since 1.6.0
     409 * @deprecated 7.0.0
    366410 *
    367411 * @access private
     
    376420 */
    377421function _bp_enforce_bp_moderate_cap_for_admins( $caps = array(), $cap = '', $user_id = 0, $args = array() ) {
     422    _deprecated_function( __FUNCTION__, '7.0.0' );
    378423
    379424    // Bail if not checking the 'bp_moderate' cap.
     
    395440    return array( 'manage_options' );
    396441}
    397 add_filter( 'map_meta_cap', '_bp_enforce_bp_moderate_cap_for_admins', 10, 4 );
    398 
    399 /** Deprecated ****************************************************************/
    400442
    401443/**
  • trunk/tests/phpunit/testcases/core/caps.php

    r12606 r12740  
    66 */
    77class BP_Tests_Core_Caps extends BP_UnitTestCase {
     8    protected $reset_user_id;
     9    protected $blog_id;
     10
     11    public function setUp() {
     12        parent::setUp();
     13
     14        $this->reset_user_id = get_current_user_id();
     15
     16        if ( is_multisite() ) {
     17            $this->blog_id = self::factory()->blog->create();
     18        }
     19    }
     20
     21    public function tearDown() {
     22        parent::tearDown();
     23
     24        $this->set_current_user( $this->reset_user_id );
     25    }
     26
    827    public function test_bp_current_user_can_should_interpret_integer_second_param_as_a_blog_id() {
    928        if ( ! is_multisite() ) {
     
    5978        return $caps;
    6079    }
     80
     81    /**
     82     * @group bp_moderate
     83     */
     84    public function test_administrator_can_bp_moderate() {
     85        $u = self::factory()->user->create(
     86            array(
     87                'role' => 'administrator',
     88            )
     89        );
     90
     91        $this->set_current_user( $u );
     92
     93        $this->assertTrue( bp_current_user_can( 'bp_moderate' ), 'Administrator can `bp_moderate` on default WordPress config' );
     94    }
     95
     96    /**
     97     * @group bp_moderate
     98     */
     99    public function test_role_with_manage_options_cap_can_bp_moderate() {
     100        add_role( 'random_role', 'Random Role', array( 'manage_options' => true ) );
     101
     102        // Reset roles.
     103        wp_roles()->init_roles();
     104
     105        $u = self::factory()->user->create(
     106            array(
     107                'role' => 'random_role',
     108            )
     109        );
     110
     111        $this->set_current_user( $u );
     112
     113        $this->assertTrue( bp_current_user_can( 'bp_moderate' ), 'Users having a `manage_options` cap into their role can `bp_moderate`' );
     114
     115        remove_role( 'random_role' );
     116    }
     117
     118    /**
     119     * @group bp_moderate
     120     */
     121    public function test_administrator_can_bp_moderate_emails() {
     122        $u1 = self::factory()->user->create(
     123            array(
     124                'role' => 'administrator',
     125            )
     126        );
     127        $u2 = self::factory()->user->create(
     128            array(
     129                'role' => 'administrator',
     130            )
     131        );
     132
     133        $this->set_current_user( $u1 );
     134
     135        $email = self::factory()->post->create(
     136            array(
     137                'post_type'   => 'bp-email',
     138            )
     139        );
     140
     141        $this->assertTrue( current_user_can( 'edit_post', $email ), 'Administrator should be able to edit emails they created' );
     142
     143        $this->set_current_user( $u2 );
     144
     145        $this->assertTrue( current_user_can( 'edit_post', $email ), 'Administrator should be able to edit emails others created when BuddyPress is not network activated' );
     146    }
     147
     148    /**
     149     * @group bp_moderate
     150     */
     151    public function test_administrator_can_bp_moderate_network_activated() {
     152        if ( ! is_multisite() ) {
     153            $this->markTestSkipped( __METHOD__ . ' requires multisite.' );
     154        }
     155
     156        $u1 = self::factory()->user->create(
     157            array(
     158                'role' => 'administrator',
     159            )
     160        );
     161        grant_super_admin( $u1 );
     162
     163        $u2 = self::factory()->user->create(
     164            array(
     165                'role' => 'administrator',
     166            )
     167        );
     168
     169        add_filter( 'bp_is_network_activated', '__return_true' );
     170
     171        // Swith & restore to reset the roles.
     172        switch_to_blog( $this->blog_id );
     173
     174        $this->set_current_user( $u1 );
     175        $this->assertTrue( bp_current_user_can( 'bp_moderate' ), 'Only Super Admins can `bp_moderate` when BuddyPress is network activated' );
     176
     177        $this->set_current_user( $u2 );
     178
     179        $this->assertFalse( bp_current_user_can( 'bp_moderate' ), 'Regular Admins cannot `bp_moderate` when BuddyPress is network activated' );
     180
     181        grant_super_admin( $u2 );
     182        $this->assertTrue( bp_current_user_can( 'bp_moderate' ), 'Only Super Admins can `bp_moderate` when BuddyPress is network activated' );
     183
     184        restore_current_blog();
     185
     186        remove_filter( 'bp_is_network_activated', '__return_true' );
     187    }
     188
     189    /**
     190     * @group bp_moderate
     191     */
     192    public function test_administrator_can_bp_moderate_emails_network_activated() {
     193        if ( ! is_multisite() ) {
     194            $this->markTestSkipped( __METHOD__ . ' requires multisite.' );
     195        }
     196
     197        $u1 = self::factory()->user->create(
     198            array(
     199                'role' => 'administrator',
     200            )
     201        );
     202        grant_super_admin( $u1 );
     203
     204        $u2 = self::factory()->user->create(
     205            array(
     206                'role' => 'administrator',
     207            )
     208        );
     209
     210        $email = self::factory()->post->create(
     211            array(
     212                'post_type'   => 'bp-email',
     213            )
     214        );
     215
     216        add_filter( 'bp_is_network_activated', '__return_true' );
     217
     218        // Swith & restore to reset the roles.
     219        switch_to_blog( $this->blog_id );
     220        restore_current_blog();
     221
     222        $this->set_current_user( $u1 );
     223        $this->assertTrue( current_user_can( 'edit_post', $email ), 'Super Admins should be able to edit emails they created' );
     224
     225        $this->set_current_user( $u2 );
     226        $this->assertFalse( current_user_can( 'edit_post', $email ), 'Administrator should not be able to edit emails others created when BuddyPress is network activated' );
     227
     228        grant_super_admin( $u2 );
     229        $this->assertTrue( current_user_can( 'edit_post', $email ), 'Super Admins should be able to edit emails others created' );
     230
     231        remove_filter( 'bp_is_network_activated', '__return_true' );
     232    }
    61233}
Note: See TracChangeset for help on using the changeset viewer.