diff --git a/src/wp-includes/admin-bar.php b/src/wp-includes/admin-bar.php index de33f54d54..70dcecea73 100644 --- a/src/wp-includes/admin-bar.php +++ b/src/wp-includes/admin-bar.php @@ -179,11 +179,18 @@ function wp_admin_bar_sidebar_toggle( $wp_admin_bar ) { function wp_admin_bar_my_account_item( $wp_admin_bar ) { $user_id = get_current_user_id(); $current_user = wp_get_current_user(); - $profile_url = get_edit_profile_url( $user_id ); if ( ! $user_id ) return; + if ( current_user_can( 'read' ) ) { + $profile_url = get_edit_profile_url( $user_id ); + } elseif ( is_multisite() ) { + $profile_url = get_dashboard_url( $user_id, 'profile.php' ); + } else { + $profile_url = false; + } + $avatar = get_avatar( $user_id, 26 ); $howdy = sprintf( __('Howdy, %1$s'), $current_user->display_name ); $class = empty( $avatar ) ? '' : 'with-avatar'; @@ -209,11 +216,18 @@ function wp_admin_bar_my_account_item( $wp_admin_bar ) { function wp_admin_bar_my_account_menu( $wp_admin_bar ) { $user_id = get_current_user_id(); $current_user = wp_get_current_user(); - $profile_url = get_edit_profile_url( $user_id ); if ( ! $user_id ) return; + if ( current_user_can( 'read' ) ) { + $profile_url = get_edit_profile_url( $user_id ); + } elseif ( is_multisite() ) { + $profile_url = get_dashboard_url( $user_id, 'profile.php' ); + } else { + $profile_url = false; + } + $wp_admin_bar->add_group( array( 'parent' => 'my-account', 'id' => 'user-actions', @@ -234,12 +248,16 @@ function wp_admin_bar_my_account_menu( $wp_admin_bar ) { 'tabindex' => -1, ), ) ); - $wp_admin_bar->add_menu( array( - 'parent' => 'user-actions', - 'id' => 'edit-profile', - 'title' => __( 'Edit My Profile' ), - 'href' => $profile_url, - ) ); + + if ( false !== $profile_url ) { + $wp_admin_bar->add_menu( array( + 'parent' => 'user-actions', + 'id' => 'edit-profile', + 'title' => __( 'Edit My Profile' ), + 'href' => $profile_url, + ) ); + } + $wp_admin_bar->add_menu( array( 'parent' => 'user-actions', 'id' => 'logout', @@ -281,7 +299,7 @@ function wp_admin_bar_site_menu( $wp_admin_bar ) { $wp_admin_bar->add_menu( array( 'id' => 'site-name', 'title' => $title, - 'href' => is_admin() ? home_url( '/' ) : admin_url(), + 'href' => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(), ) ); // Create submenu items. @@ -304,7 +322,7 @@ function wp_admin_bar_site_menu( $wp_admin_bar ) { ) ); } - } else { + } else if ( current_user_can( 'read' ) ) { // We're on the front end, link to the Dashboard. $wp_admin_bar->add_menu( array( 'parent' => 'site-name', diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index b1a1c046d0..c5652d528b 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -27,6 +27,11 @@ html:lang(he-il) .rtl #wpadminbar * { font-family: Arial, sans-serif; } +#wpadminbar .ab-empty-item { + cursor: default; +} + +#wpadminbar .ab-empty-item, #wpadminbar a.ab-item, #wpadminbar > #wp-toolbar span.ab-label, #wpadminbar > #wp-toolbar span.noticon { @@ -451,6 +456,7 @@ html:lang(he-il) .rtl #wpadminbar * { font-size: 11px; } +#wpadminbar #wp-admin-bar-my-account.with-avatar > .ab-empty-item img, #wpadminbar #wp-admin-bar-my-account.with-avatar > a img { width: auto; height: 16px; @@ -464,6 +470,7 @@ html:lang(he-il) .rtl #wpadminbar * { display: inline; } +#wpadminbar.ie8 #wp-admin-bar-my-account.with-avatar > .ab-empty-item img, #wpadminbar.ie8 #wp-admin-bar-my-account.with-avatar > a img { width: auto; } diff --git a/tests/phpunit/tests/adminbar.php b/tests/phpunit/tests/adminbar.php index 533f7caad1..709deecdf9 100644 --- a/tests/phpunit/tests/adminbar.php +++ b/tests/phpunit/tests/adminbar.php @@ -15,7 +15,6 @@ class Tests_AdminBar extends WP_UnitTestCase { function setUp() { parent::setUp(); $this->current_user = get_current_user_id(); - wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) ); } function tearDown() { @@ -27,6 +26,8 @@ class Tests_AdminBar extends WP_UnitTestCase { * @ticket 21117 */ function test_content_post_type() { + wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) ); + register_post_type( 'content', array( 'show_in_admin_bar' => true ) ); $admin_bar = new WP_Admin_Bar; @@ -44,6 +45,8 @@ class Tests_AdminBar extends WP_UnitTestCase { * @ticket 21117 */ function test_merging_existing_meta_values() { + wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) ); + $admin_bar = new WP_Admin_Bar; $admin_bar->add_node( array( @@ -61,4 +64,194 @@ class Tests_AdminBar extends WP_UnitTestCase { $node = $admin_bar->get_node( 'test-node' ); $this->assertEquals( array( 'class' => 'test-class', 'some-meta' => 'value' ), $node->meta ); } -} \ No newline at end of file + + /** + * @ticket 25162 + */ + public function test_admin_bar_contains_correct_links_for_users_with_no_role() { + if ( is_multisite() ) { + $this->markTestSkipped( 'Test does not run in multisite' ); + } + + $nobody = $this->factory->user->create( array( 'role' => '' ) ); + $this->assertFalse( user_can( $nobody, 'read' ) ); + + wp_set_current_user( $nobody ); + + $wp_admin_bar = $this->get_standard_admin_bar(); + + $node_site_name = $wp_admin_bar->get_node( 'site-name' ); + $node_my_account = $wp_admin_bar->get_node( 'my-account' ); + $node_user_info = $wp_admin_bar->get_node( 'user-info' ); + $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' ); + + // Site menu points to the home page instead of the admin URL + $this->assertEquals( home_url( '/' ), $node_site_name->href ); + + // No profile links as the user doesn't have any permissions on the site + $this->assertFalse( $node_my_account->href ); + $this->assertFalse( $node_user_info->href ); + $this->assertNull( $node_edit_profile ); + + } + + /** + * @ticket 25162 + */ + public function test_admin_bar_contains_correct_links_for_users_with_role() { + if ( is_multisite() ) { + $this->markTestSkipped( 'Test does not run in multisite' ); + } + + $editor = $this->factory->user->create( array( 'role' => 'editor' ) ); + $this->assertTrue( user_can( $editor, 'read' ) ); + + wp_set_current_user( $editor ); + + $wp_admin_bar = $this->get_standard_admin_bar(); + + $node_site_name = $wp_admin_bar->get_node( 'site-name' ); + $node_my_account = $wp_admin_bar->get_node( 'my-account' ); + $node_user_info = $wp_admin_bar->get_node( 'user-info' ); + $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' ); + + // Site menu points to the admin URL + $this->assertEquals( admin_url( '/' ), $node_site_name->href ); + + $profile_url = admin_url( 'profile.php' ); + + // Profile URLs point to profile.php + $this->assertEquals( $profile_url, $node_my_account->href ); + $this->assertEquals( $profile_url, $node_user_info->href ); + $this->assertEquals( $profile_url, $node_edit_profile->href ); + + } + + /** + * @ticket 25162 + * @group multisite + */ + public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_blog() { + if ( ! is_multisite() ) { + $this->markTestSkipped( 'Test only runs in multisite' ); + } + + $admin = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $editor = $this->factory->user->create( array( 'role' => 'editor' ) ); + + $this->assertTrue( user_can( $admin, 'read' ) ); + $this->assertTrue( user_can( $editor, 'read' ) ); + + $new_blog_id = $this->factory->blog->create( array( + 'user_id' => $admin, + ) ); + + $this->assertTrue( is_user_member_of_blog( $admin, $new_blog_id ) ); + $this->assertFalse( is_user_member_of_blog( $editor, $new_blog_id ) ); + + wp_set_current_user( $editor ); + + switch_to_blog( $new_blog_id ); + + $wp_admin_bar = $this->get_standard_admin_bar(); + + $node_site_name = $wp_admin_bar->get_node( 'site-name' ); + $node_my_account = $wp_admin_bar->get_node( 'my-account' ); + $node_user_info = $wp_admin_bar->get_node( 'user-info' ); + $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' ); + + // get primary blog + $primary = get_active_blog_for_user( $editor ); + $this->assertInternalType( 'object', $primary ); + + // No Site menu as the user isn't a member of this blog + $this->assertNull( $node_site_name ); + + $primary_profile_url = get_admin_url( $primary->blog_id, 'profile.php' ); + + // Ensure the user's primary blog is not the same as the main site + $this->assertNotEquals( $primary_profile_url, admin_url( 'profile.php' ) ); + + // Profile URLs should go to the user's primary blog + $this->assertEquals( $primary_profile_url, $node_my_account->href ); + $this->assertEquals( $primary_profile_url, $node_user_info->href ); + $this->assertEquals( $primary_profile_url, $node_edit_profile->href ); + + restore_current_blog(); + + } + + /** + * @ticket 25162 + * @group multisite + */ + public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_network() { + if ( ! is_multisite() ) { + $this->markTestSkipped( 'Test only runs in multisite' ); + } + + $admin = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $nobody = $this->factory->user->create( array( 'role' => '' ) ); + + $this->assertTrue( user_can( $admin, 'read' ) ); + $this->assertFalse( user_can( $nobody, 'read' ) ); + + $new_blog_id = $this->factory->blog->create( array( + 'user_id' => $admin, + ) ); + + $this->assertTrue( is_user_member_of_blog( $admin, $new_blog_id ) ); + $this->assertFalse( is_user_member_of_blog( $nobody, $new_blog_id ) ); + $this->assertTrue( is_user_member_of_blog( $nobody, get_current_blog_id() ) ); + + // Remove `$nobody` from the current blog, so they're not a member of any blog + $removed = remove_user_from_blog( $nobody, get_current_blog_id() ); + + $this->assertTrue( $removed ); + $this->assertFalse( is_user_member_of_blog( $nobody, get_current_blog_id() ) ); + + wp_set_current_user( $nobody ); + + switch_to_blog( $new_blog_id ); + + $wp_admin_bar = $this->get_standard_admin_bar(); + + $node_site_name = $wp_admin_bar->get_node( 'site-name' ); + $node_my_account = $wp_admin_bar->get_node( 'my-account' ); + $node_user_info = $wp_admin_bar->get_node( 'user-info' ); + $node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' ); + + // get primary blog + $primary = get_active_blog_for_user( $nobody ); + $this->assertNull( $primary ); + + // No Site menu as the user isn't a member of this site + $this->assertNull( $node_site_name ); + + $user_profile_url = user_admin_url( 'profile.php' ); + + $this->assertNotEquals( $user_profile_url, admin_url( 'profile.php' ) ); + + // Profile URLs should go to the user's primary blog + $this->assertEquals( $user_profile_url, $node_my_account->href ); + $this->assertEquals( $user_profile_url, $node_user_info->href ); + $this->assertEquals( $user_profile_url, $node_edit_profile->href ); + + restore_current_blog(); + + } + + protected function get_standard_admin_bar() { + global $wp_admin_bar; + + _wp_admin_bar_init(); + + $this->assertTrue( is_admin_bar_showing() ); + $this->assertInstanceOf( 'WP_Admin_Bar', $wp_admin_bar ); + + do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) ); + + return $wp_admin_bar; + } + +}