Skip to:
Content

BuddyPress.org

Changeset 12740


Ignore:
Timestamp:
10/04/2020 04:44:28 PM (6 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.