From 439f96624fd8daf52a434a473b481d7dd864cd96 Mon Sep 17 00:00:00 2001 From: "yaswanth.kumar" Date: Wed, 8 Apr 2026 11:27:12 +0530 Subject: [PATCH] Fix view_stats capability check for multi-role users The view_stats meta-cap mapping only checked the first role in the user's roles array via array_shift(). Users with multiple roles (e.g. customer + administrator) could be denied stats access if their first role wasn't in the stats roles allowlist. Use array_intersect() to check all user roles against the allowed stats roles instead of only the first. Fixes #47258 --- .../stats/changelog/fix-stats-view-multi-role | 4 ++++ projects/packages/stats/src/class-main.php | 7 +++---- .../packages/stats/tests/php/Main_Test.php | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 projects/packages/stats/changelog/fix-stats-view-multi-role diff --git a/projects/packages/stats/changelog/fix-stats-view-multi-role b/projects/packages/stats/changelog/fix-stats-view-multi-role new file mode 100644 index 000000000000..b2d44cc70f8e --- /dev/null +++ b/projects/packages/stats/changelog/fix-stats-view-multi-role @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fix view_stats capability check for users with multiple roles by checking all roles instead of only the first. diff --git a/projects/packages/stats/src/class-main.php b/projects/packages/stats/src/class-main.php index 9f4eebe6b581..1d592e2f4313 100644 --- a/projects/packages/stats/src/class-main.php +++ b/projects/packages/stats/src/class-main.php @@ -127,12 +127,11 @@ public static function map_meta_caps( $caps, $cap, $user_id ) { $user = new WP_User( $user_id ); // WordPress 6.9 introduced lazy-loading of some WP_User properties, including `roles`. // It also made said properties protected, so we can't modify keys directly. - $user_roles = $user->roles; - $user_role = array_shift( $user_roles ); // Work with the copy + $user_roles = (array) $user->roles; $stats_roles = Options::get_option( 'roles' ); - // Is the users role in the available stats roles? - if ( is_array( $stats_roles ) && in_array( $user_role, $stats_roles, true ) ) { + // Is any of the user's roles in the available stats roles? + if ( is_array( $stats_roles ) && ! empty( array_intersect( $user_roles, $stats_roles ) ) ) { $caps = array( 'read' ); } } diff --git a/projects/packages/stats/tests/php/Main_Test.php b/projects/packages/stats/tests/php/Main_Test.php index 90a7cdcb1226..3709e3d5e181 100644 --- a/projects/packages/stats/tests/php/Main_Test.php +++ b/projects/packages/stats/tests/php/Main_Test.php @@ -178,6 +178,25 @@ public function test_view_stats_meta_mapping() { $this->assertTrue( user_can( $dummy_user_id, 'view_stats' ) ); } + /** + * Test Main::map_meta_caps with multi-role user where admin is not the first role. + */ + public function test_view_stats_meta_mapping_multi_role() { + $dummy_user_id = wp_insert_user( + array( + 'user_login' => 'dummy_multirole', + 'user_pass' => 'password', + 'role' => 'subscriber', + ) + ); + + // Add administrator as a second role. + $user = new \WP_User( $dummy_user_id ); + $user->add_role( 'administrator' ); + + $this->assertTrue( user_can( $dummy_user_id, 'view_stats' ) ); + } + /** * Test Main::should_track */