Make WordPress Core


Ignore:
Timestamp:
09/19/2022 08:47:22 PM (4 years ago)
Author:
davidbaumwald
Message:

Role/Capability: Add a new update_role function.

Until now, changing a user's role involved deleting a user's role then re-adding. This change creates a new update_role function and associated method in WP_Roles to consolidate this process.

This commit also introduces new unit tests around update_role and adds additional "unhappy path" tests for roles and capabilities in general.

Props maksimkuzmin, peterwilsoncc, NomNom99, costdev, SergeyBiryukov.
Fixes #54572.

File:
1 edited

Legend:

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

    r54133 r54213  
    174174
    175175        /**
     176         * Updates an existing role. Creates a new role if it doesn't exist.
     177         *
     178         * Modifies the display name and/or capabilities for an existing role.
     179         * If the role does not exist then a new role is created.
     180         *
     181         * The capabilities are defined in the following format: `array( 'read' => true )`.
     182         * To explicitly deny the role a capability, set the value for that capability to false.
     183         *
     184         * @since 6.1.0
     185         *
     186         * @param string      $role         Role name.
     187         * @param string|null $display_name Optional. Role display name. If null, the display name
     188         *                                  is not modified. Default null.
     189         * @param bool[]|null $capabilities Optional. List of capabilities keyed by the capability name,
     190         *                                  e.g. `array( 'edit_posts' => true, 'delete_posts' => false )`.
     191         *                                  If null, don't alter capabilities for the existing role and make
     192         *                                  empty capabilities for the new one. Default null.
     193         * @return WP_Role|void WP_Role object, if the role is updated.
     194         */
     195        public function update_role( $role, $display_name = null, $capabilities = null ) {
     196                if ( ! is_string( $role ) || '' === trim( $role ) ) {
     197                        return;
     198                }
     199
     200                if ( null !== $display_name && ( ! is_string( $display_name ) || '' === trim( $display_name ) ) ) {
     201                        return;
     202                }
     203
     204                if ( null !== $capabilities && ! is_array( $capabilities ) ) {
     205                        return;
     206                }
     207
     208                if ( null === $display_name && null === $capabilities ) {
     209                        if ( isset( $this->role_objects[ $role ] ) ) {
     210                                return $this->role_objects[ $role ];
     211                        }
     212                        return;
     213                }
     214
     215                if ( null === $display_name ) {
     216                        if ( ! isset( $this->role_objects[ $role ] ) ) {
     217                                return;
     218                        }
     219
     220                        $display_name = $this->roles[ $role ]['name'];
     221                }
     222
     223                if ( null === $capabilities ) {
     224                        if ( isset( $this->role_objects[ $role ] ) ) {
     225                                $capabilities = $this->role_objects[ $role ]->capabilities;
     226                        } else {
     227                                $capabilities = array();
     228                        }
     229                }
     230
     231                if ( isset( $this->roles[ $role ] ) ) {
     232                        if ( null === $capabilities ) {
     233                                $capabilities = $this->role_objects[ $role ]->capabilities;
     234                        }
     235
     236                        unset( $this->role_objects[ $role ] );
     237                        unset( $this->role_names[ $role ] );
     238                        unset( $this->roles[ $role ] );
     239                }
     240
     241                // The roles database option will be updated in ::add_role().
     242                return $this->add_role( $role, $display_name, $capabilities );
     243        }
     244
     245        /**
    176246         * Removes a role by name.
    177247         *
Note: See TracChangeset for help on using the changeset viewer.