diff --git a/wp-includes/class-wp-user.php b/wp-includes/class-wp-user.php index 8fd5e5cd21..27f49b2e86 100644 --- a/wp-includes/class-wp-user.php +++ b/wp-includes/class-wp-user.php @@ -37,6 +37,9 @@ * @property string $rich_editing * @property string $syntax_highlighting * @property string $use_ssl + * @property array $caps + * @property string[] $roles + * @property array $allcaps */ #[AllowDynamicProperties] class WP_User { @@ -60,10 +63,10 @@ class WP_User { * Capabilities that the individual user has been granted outside of those inherited from their role. * * @since 2.0.0 - * @var bool[] Array of key/value pairs where keys represent a capability name - * and boolean values represent whether the user has that capability. + * @var array|null Array of key/value pairs where keys represent a capability name + * and boolean values represent whether the user has that capability. */ - public $caps = array(); + protected $caps = null; /** * User metadata option name. @@ -79,16 +82,16 @@ class WP_User { * @since 2.0.0 * @var string[] */ - public $roles = array(); + protected $roles = array(); /** * All capabilities the user has, including individual and role based. * * @since 2.0.0 - * @var bool[] Array of key/value pairs where keys represent a capability name - * and boolean values represent whether the user has that capability. + * @var array Array of key/value pairs where keys represent a capability name + * and boolean values represent whether the user has that capability. */ - public $allcaps = array(); + protected $allcaps = array(); /** * The filter context applied to user data fields. @@ -288,6 +291,10 @@ class WP_User { $key = 'ID'; } + if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) { + return true; + } + if ( isset( $this->data->$key ) ) { return true; } @@ -321,6 +328,11 @@ class WP_User { return $this->ID; } + if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) { + $this->load_capability_data(); + return $this->$key; + } + if ( isset( $this->data->$key ) ) { $value = $this->data->$key; } else { @@ -363,6 +375,13 @@ class WP_User { return; } + // Ensure capability data is loaded before setting related properties. + if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) { + $this->load_capability_data(); + $this->$key = $value; + return; + } + $this->data->$key = $value; } @@ -386,6 +405,10 @@ class WP_User { ); } + if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) { + $this->$key = null; + } + if ( isset( $this->data->$key ) ) { unset( $this->data->$key ); } @@ -515,6 +538,11 @@ class WP_User { $wp_roles = wp_roles(); + // Edge case: In case someone calls this method before lazy initialization, we need to initialize on demand. + if ( ! isset( $this->caps ) ) { + $this->caps = $this->get_caps_data(); + } + // Filter out caps that are not role names and assign to $this->roles. if ( is_array( $this->caps ) ) { $this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) ); @@ -548,6 +576,7 @@ class WP_User { if ( empty( $role ) ) { return; } + $this->load_capability_data(); if ( in_array( $role, $this->roles, true ) ) { return; @@ -577,6 +606,7 @@ class WP_User { * @param string $role Role name. */ public function remove_role( $role ) { + $this->load_capability_data(); if ( ! in_array( $role, $this->roles, true ) ) { return; } @@ -609,6 +639,7 @@ class WP_User { * @param string $role Role name. */ public function set_role( $role ) { + $this->load_capability_data(); if ( 1 === count( $this->roles ) && current( $this->roles ) === $role ) { return; } @@ -710,6 +741,7 @@ class WP_User { * @param bool $grant Whether to grant capability to user. */ public function add_cap( $cap, $grant = true ) { + $this->load_capability_data(); $this->caps[ $cap ] = $grant; update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); @@ -724,6 +756,7 @@ class WP_User { * @param string $cap Capability name. */ public function remove_cap( $cap ) { + $this->load_capability_data(); if ( ! isset( $this->caps[ $cap ] ) ) { return; } @@ -742,10 +775,10 @@ class WP_User { */ public function remove_all_caps() { global $wpdb; - $this->caps = array(); + $this->caps = null; delete_user_meta( $this->ID, $this->cap_key ); delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); - $this->get_role_caps(); + $this->load_capability_data(); } /** @@ -776,6 +809,8 @@ class WP_User { * the given capability for that object. */ public function has_cap( $cap, ...$args ) { + $this->load_capability_data(); + if ( is_numeric( $cap ) ) { _deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) ); $cap = $this->translate_level_to_cap( $cap ); @@ -877,10 +912,7 @@ class WP_User { } $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities'; - - $this->caps = $this->get_caps_data(); - - $this->get_role_caps(); + $this->caps = null; } /** @@ -911,4 +943,17 @@ class WP_User { return $caps; } + + /** + * Loads capability data if it has not been loaded yet. + * + * @since 6.9.0 + */ + private function load_capability_data() { + if ( isset( $this->caps ) ) { + return; + } + $this->caps = $this->get_caps_data(); + $this->get_role_caps(); + } } diff --git a/wp-includes/version.php b/wp-includes/version.php index ca6e84f93a..3e72d732b0 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.9-alpha-60914'; +$wp_version = '6.9-alpha-60915'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.