Make WordPress Core

Changeset 52823


Ignore:
Timestamp:
03/06/2022 04:09:06 PM (2 years ago)
Author:
SergeyBiryukov
Message:

Users: Bring some consistency to user role hooks.

This standardizes the actions that one needs to hook to for tracking user role changes:

  • add_user_role is only fired when the user has actually gained a new role.
  • remove_user_role is only fired when the role was actually removed.

Both actions are now fired in WP_User::set_role() as appropriate.

Props dd32, SergeyBiryukov.
Fixes #54164.

Location:
trunk
Files:
2 edited

Legend:

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

    r51851 r52823  
    543543        }
    544544
     545        if ( in_array( $role, $this->roles, true ) ) {
     546            return;
     547        }
     548
    545549        $this->caps[ $role ] = true;
    546550        update_user_meta( $this->ID, $this->cap_key, $this->caps );
     
    570574            return;
    571575        }
     576
    572577        unset( $this->caps[ $role ] );
    573578        update_user_meta( $this->ID, $this->cap_key, $this->caps );
     
    607612
    608613        $old_roles = $this->roles;
     614
    609615        if ( ! empty( $role ) ) {
    610616            $this->caps[ $role ] = true;
    611617            $this->roles         = array( $role => true );
    612618        } else {
    613             $this->roles = false;
    614         }
     619            $this->roles = array();
     620        }
     621
    615622        update_user_meta( $this->ID, $this->cap_key, $this->caps );
    616623        $this->get_role_caps();
    617624        $this->update_user_level_from_caps();
     625
     626        foreach ( $old_roles as $old_role ) {
     627            if ( ! $old_role || $old_role === $role ) {
     628                continue;
     629            }
     630
     631            /** This action is documented in wp-includes/class-wp-user.php */
     632            do_action( 'remove_user_role', $this->ID, $old_role );
     633        }
     634
     635        if ( $role && ! in_array( $role, $old_roles, true ) ) {
     636            /** This action is documented in wp-includes/class-wp-user.php */
     637            do_action( 'add_user_role', $this->ID, $role );
     638        }
    618639
    619640        /**
  • trunk/tests/phpunit/tests/user/capabilities.php

    r52010 r52823  
    16241624        $caps = $user->caps;
    16251625        $this->assertNotEmpty( $user->caps );
     1626
    16261627        $user->set_role( 'administrator' );
    16271628        $this->assertNotEmpty( $user->caps );
    16281629        $this->assertSame( $caps, $user->caps );
     1630    }
     1631
     1632    /**
     1633     * @ticket 54164
     1634     */
     1635    public function test_set_role_fires_remove_user_role_and_add_user_role_hooks() {
     1636        $user = self::$users['administrator'];
     1637
     1638        $remove_user_role = new MockAction();
     1639        $add_user_role    = new MockAction();
     1640        add_action( 'remove_user_role', array( $remove_user_role, 'action' ) );
     1641        add_action( 'add_user_role', array( $add_user_role, 'action' ) );
     1642
     1643        $user->set_role( 'editor' );
     1644        $this->assertSame( 1, $remove_user_role->get_call_count() );
     1645        $this->assertSame( 1, $add_user_role->get_call_count() );
    16291646    }
    16301647
Note: See TracChangeset for help on using the changeset viewer.