Make WordPress Core

Changeset 59123


Ignore:
Timestamp:
09/30/2024 11:03:51 AM (18 months ago)
Author:
johnbillion
Message:

Role/Capability: Introduce the user_can_for_blog() function.

This complements the existing user capability checking functions and enables checking a capability of any user on any site on a Multisite network.

Props tmanoilov, rajinsharwar, n8finch, johnbillion

Fixes #45197

Location:
trunk
Files:
2 edited

Legend:

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

    r59122 r59123  
    10151015
    10161016/**
     1017 * Returns whether a particular user has the specified capability for a given site.
     1018 *
     1019 * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
     1020 * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
     1021 * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
     1022 *
     1023 * Example usage:
     1024 *
     1025 *     user_can_for_blog( $user->ID, $blog_id, 'edit_posts' );
     1026 *     user_can_for_blog( $user->ID, $blog_id, 'edit_post', $post->ID );
     1027 *     user_can_for_blog( $user->ID, $blog_id, 'edit_post_meta', $post->ID, $meta_key );
     1028 *
     1029 * @since 6.7.0
     1030 *
     1031 * @param int|WP_User $user       User ID or object.
     1032 * @param int         $blog_id    Site ID.
     1033 * @param string      $capability Capability name.
     1034 * @param mixed       ...$args    Optional further parameters, typically starting with an object ID.
     1035 * @return bool Whether the user has the given capability.
     1036 */
     1037function user_can_for_blog( $user, $blog_id, $capability, ...$args ) {
     1038    if ( ! is_object( $user ) ) {
     1039        $user = get_userdata( $user );
     1040    }
     1041
     1042    if ( empty( $user ) ) {
     1043        // User is logged out, create anonymous user object.
     1044        $user = new WP_User( 0 );
     1045        $user->init( new stdClass() );
     1046    }
     1047
     1048    // Check if the blog ID is valid.
     1049    if ( ! is_numeric( $blog_id ) || $blog_id <= 0 ) {
     1050        return false;
     1051    }
     1052
     1053    $switched = is_multisite() ? switch_to_blog( $blog_id ) : false;
     1054
     1055    $can = user_can( $user->ID, $capability, ...$args );
     1056
     1057    if ( $switched ) {
     1058        restore_current_blog();
     1059    }
     1060
     1061    return $can;
     1062}
     1063
     1064/**
    10171065 * Retrieves the global WP_Roles instance and instantiates it if necessary.
    10181066 *
  • trunk/tests/phpunit/tests/user/capabilities.php

    r59122 r59123  
    16541654    }
    16551655
     1656    /**
     1657     * @group can_for_blog
     1658     */
    16561659    public function test_current_user_can_for_blog() {
    16571660        global $wpdb;
     
    16631666        $this->assertTrue( current_user_can_for_blog( get_current_blog_id(), 'edit_posts' ) );
    16641667        $this->assertFalse( current_user_can_for_blog( get_current_blog_id(), 'foo_the_bar' ) );
     1668
    16651669        if ( ! is_multisite() ) {
    16661670            $this->assertTrue( current_user_can_for_blog( 12345, 'edit_posts' ) );
     1671            $this->assertFalse( current_user_can_for_blog( 12345, 'foo_the_bar' ) );
    16671672            return;
    16681673        }
     
    16731678
    16741679        $blog_id = self::factory()->blog->create( array( 'user_id' => $user->ID ) );
     1680
     1681        $this->assertNotWPError( $blog_id );
    16751682        $this->assertTrue( current_user_can_for_blog( $blog_id, 'edit_posts' ) );
    16761683        $this->assertFalse( current_user_can_for_blog( $blog_id, 'foo_the_bar' ) );
    16771684
     1685        $another_blog_id = self::factory()->blog->create( array( 'user_id' => self::$users['author']->ID ) );
     1686
     1687        $this->assertNotWPError( $another_blog_id );
     1688
     1689        // Verify the user doesn't have a capability
     1690        $this->assertFalse( current_user_can_for_blog( $another_blog_id, 'edit_posts' ) );
     1691
     1692        // Add the current user to the site
     1693        add_user_to_blog( $another_blog_id, $user->ID, 'author' );
     1694
     1695        // Verify they now have the capability
     1696        $this->assertTrue( current_user_can_for_blog( $another_blog_id, 'edit_posts' ) );
     1697
    16781698        wp_set_current_user( $old_uid );
     1699    }
     1700
     1701    /**
     1702     * @group can_for_blog
     1703     */
     1704    public function test_user_can_for_blog() {
     1705        $user = self::$users['editor'];
     1706
     1707        $this->assertTrue( user_can_for_blog( $user->ID, get_current_blog_id(), 'edit_posts' ) );
     1708        $this->assertFalse( user_can_for_blog( $user->ID, get_current_blog_id(), 'foo_the_bar' ) );
     1709
     1710        if ( ! is_multisite() ) {
     1711            $this->assertTrue( user_can_for_blog( $user->ID, 12345, 'edit_posts' ) );
     1712            $this->assertFalse( user_can_for_blog( $user->ID, 12345, 'foo_the_bar' ) );
     1713            return;
     1714        }
     1715
     1716        $blog_id = self::factory()->blog->create( array( 'user_id' => $user->ID ) );
     1717
     1718        $this->assertNotWPError( $blog_id );
     1719        $this->assertTrue( user_can_for_blog( $user->ID, $blog_id, 'edit_posts' ) );
     1720        $this->assertFalse( user_can_for_blog( $user->ID, $blog_id, 'foo_the_bar' ) );
     1721
     1722        $author = self::$users['author'];
     1723
     1724        // Verify another user doesn't have a capability
     1725        $this->assertFalse( is_user_member_of_blog( $author->ID, $blog_id ) );
     1726        $this->assertFalse( user_can_for_blog( $author->ID, $blog_id, 'edit_posts' ) );
     1727
     1728        // Add the author to the site
     1729        add_user_to_blog( $blog_id, $author->ID, 'author' );
     1730
     1731        // Verify they now have the capability
     1732        $this->assertTrue( is_user_member_of_blog( $author->ID, $blog_id ) );
     1733        $this->assertTrue( user_can_for_blog( $author->ID, $blog_id, 'edit_posts' ) );
     1734
     1735        // Verify the user doesn't have a capability for a non-existent site
     1736        $this->assertFalse( user_can_for_blog( $user->ID, -1, 'edit_posts' ) );
    16791737    }
    16801738
Note: See TracChangeset for help on using the changeset viewer.