WordPress.org

Make WordPress Core

Ticket #41332: 41332.diff

File 41332.diff, 9.2 KB (added by flixos90, 3 years ago)
  • src/wp-includes/capabilities.php

     
    859859
    860860        return $allcaps;
    861861}
     862
     863/**
     864 * Filters the user capabilities to grant attachment capabilities as necessary.
     865 *
     866 * The capabilities are granted based on the post capabilities a user has.
     867 *
     868 * @since 4.9.0
     869 *
     870 * @param array $allcaps An array of all the user's capabilities.
     871 * @return array Filtered array of the user's capabilities.
     872 */
     873function wp_maybe_grant_attachment_capabilities( $allcaps ) {
     874        $attachment_post_type = get_post_type_object( 'attachment' );
     875
     876        foreach ( get_object_vars( $attachment_post_type->cap ) as $post_cap => $attachment_cap ) {
     877                if ( '_posts' === substr( $post_cap, -6 ) && ! empty( $allcaps[ $post_cap ] ) ) {
     878                        $allcaps[ $attachment_cap ] = true;
     879                }
     880        }
     881
     882        return $allcaps;
     883}
  • src/wp-includes/default-filters.php

     
    514514
    515515// Capabilities
    516516add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 );
     517add_filter( 'user_has_cap', 'wp_maybe_grant_attachment_capabilities', 1 );
    517518
    518519unset( $filter, $action );
  • src/wp-includes/post.php

     
    7272                'show_ui' => true,
    7373                '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
    7474                '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    75                 'capability_type' => 'post',
     75                'capability_type' => 'attachment',
    7676                'capabilities' => array(
    7777                        'create_posts' => 'upload_files',
    7878                ),
     
    29642964 *     @type string $guid                  Global Unique ID for referencing the post. Default empty.
    29652965 *     @type array  $post_category         Array of category names, slugs, or IDs.
    29662966 *                                         Defaults to value of the 'default_category' option.
    2967  *     @type array  $tags_input            Array of tag names, slugs, or IDs. Default empty. 
     2967 *     @type array  $tags_input            Array of tag names, slugs, or IDs. Default empty.
    29682968 *     @type array  $tax_input             Array of taxonomy terms keyed by their taxonomy name. Default empty.
    29692969 *     @type array  $meta_input            Array of post meta values keyed by their post meta key. Default empty.
    29702970 * }
  • tests/phpunit/tests/user/capabilities.php

     
    215215
    216216        }
    217217
     218        final private function _getSingleSiteFakePrimitiveCaps() {
     219                return array(
     220                        'install_languages'            => array( 'administrator' ),
     221
     222                        'edit_others_attachments'      => array( 'administrator', 'editor' ),
     223                        'delete_others_attachments'    => array( 'administrator', 'editor' ),
     224                        'read_private_attachments'     => array( 'administrator', 'editor' ),
     225                        'edit_private_attachments'     => array( 'administrator', 'editor' ),
     226                        'delete_private_attachments'   => array( 'administrator', 'editor' ),
     227                        'publish_attachments'          => array( 'administrator', 'editor', 'author' ),
     228                        'edit_published_attachments'   => array( 'administrator', 'editor', 'author' ),
     229                        'delete_published_attachments' => array( 'administrator', 'editor', 'author' ),
     230                        'edit_attachments'             => array( 'administrator', 'editor', 'author', 'contributor' ),
     231                        'delete_attachments'           => array( 'administrator', 'editor', 'author', 'contributor' ),
     232                );
     233        }
     234
     235        final private function _getMultiSiteFakePrimitiveCaps() {
     236                return array(
     237                        'install_languages'            => array(),
     238
     239                        'edit_others_attachments'      => array( 'administrator', 'editor' ),
     240                        'delete_others_attachments'    => array( 'administrator', 'editor' ),
     241                        'read_private_attachments'     => array( 'administrator', 'editor' ),
     242                        'edit_private_attachments'     => array( 'administrator', 'editor' ),
     243                        'delete_private_attachments'   => array( 'administrator', 'editor' ),
     244                        'publish_attachments'          => array( 'administrator', 'editor', 'author' ),
     245                        'edit_published_attachments'   => array( 'administrator', 'editor', 'author' ),
     246                        'delete_published_attachments' => array( 'administrator', 'editor', 'author' ),
     247                        'edit_attachments'             => array( 'administrator', 'editor', 'author', 'contributor' ),
     248                        'delete_attachments'           => array( 'administrator', 'editor', 'author', 'contributor' ),
     249                );
     250        }
     251
    218252        final private function _getSingleSiteMetaCaps() {
    219253                return array(
    220254                        'create_sites'           => array(),
     
    282316        }
    283317
    284318        protected function getAllCapsAndRoles() {
    285                 return $this->getPrimitiveCapsAndRoles() + $this->getMetaCapsAndRoles();
     319                return $this->getPrimitiveCapsAndRoles() + $this->getFakePrimitiveCapsAndRoles() + $this->getMetaCapsAndRoles();
    286320        }
    287321
    288322        protected function getPrimitiveCapsAndRoles() {
     
    293327                }
    294328        }
    295329
     330        protected function getFakePrimitiveCapsAndRoles() {
     331                if ( is_multisite() ) {
     332                        return $this->_getMultiSiteFakePrimitiveCaps();
     333                } else {
     334                        return $this->_getSingleSiteFakePrimitiveCaps();
     335                }
     336        }
     337
    296338        protected function getMetaCapsAndRoles() {
    297339                if ( is_multisite() ) {
    298340                        return $this->_getMultiSiteMetaCaps();
     
    309351                sort( $multi_primitive );
    310352                $this->assertEquals( $single_primitive, $multi_primitive );
    311353
     354
     355                $single_fake_primitive = array_keys( $this->_getSingleSiteFakePrimitiveCaps() );
     356                $multi_fake_primitive  = array_keys( $this->_getMultiSiteFakePrimitiveCaps() );
     357                sort( $single_fake_primitive );
     358                sort( $multi_fake_primitive );
     359                $this->assertEquals( $single_fake_primitive, $multi_fake_primitive );
     360
    312361                $single_meta = array_keys( $this->_getSingleSiteMetaCaps() );
    313362                $multi_meta  = array_keys( $this->_getMultiSiteMetaCaps() );
    314363                sort( $single_meta );
     
    386435        }
    387436
    388437        /**
     438         * Test the tests. All fake primitive capabilities are checked twice against the user,
     439         * once with the 'user_has_cap' filters applied and once without. An administrator user
     440         * is used for the test. Note that super admin capabilities in multisite are skipped since
     441         * they cannot be tested with this method.
     442         *
     443         * @group capTestTests
     444         */
     445        public function testFakePrimitiveCapsTestsAreCorrect() {
     446                $user = self::$users['administrator'];
     447
     448                $caps = $this->getFakePrimitiveCapsAndRoles();
     449
     450                $filtered = array();
     451                foreach ( $caps as $cap => $roles ) {
     452                        if ( empty( $roles ) ) {
     453                                continue;
     454                        }
     455
     456                        if ( $user->has_cap( $cap ) ) {
     457                                $filtered[] = $cap;
     458                        }
     459                }
     460
     461                remove_all_filters( 'user_has_cap' );
     462
     463                $unfiltered = array();
     464                foreach ( $caps as $cap => $roles ) {
     465                        if ( empty( $roles ) ) {
     466                                continue;
     467                        }
     468
     469                        if ( ! $user->has_cap( $cap ) ) {
     470                                $unfiltered[] = $cap;
     471                        }
     472                }
     473
     474                $missing_fake_primitive_cap_checks = array_diff( $unfiltered, $filtered );
     475                $this->assertSame( array(), $missing_fake_primitive_cap_checks, 'These fake primitive capabilities are not correctly granted' );
     476
     477                $incorrect_fake_primitive_cap_checks = array_diff( $filtered, $unfiltered );
     478                $this->assertSame( array(), $incorrect_fake_primitive_cap_checks, 'These capabilities are not fake primitive' );
     479        }
     480
     481        /**
    389482         * Test the tests. All meta capabilities should have a condition in the `map_meta_cap()`
    390483         * function that handles the capability.
    391484         *
     
    898991                // user 1 has an extra capability
    899992                $user_1 = new WP_User($id_1);
    900993                $this->assertTrue($user_1->exists(), "Problem getting user $id_1");
    901                 $user_1->add_cap('publish_posts');
     994                $user_1->add_cap('edit_pages');
    902995
    903996                // re-fetch both users from the db
    904997                $user_1 = new WP_User($id_1);
     
    9111004                $this->assertEquals(array('contributor'), $user_2->roles);
    9121005
    9131006                // check the extra cap on both users
    914                 $this->assertTrue($user_1->has_cap('publish_posts'));
    915                 $this->assertFalse($user_2->has_cap('publish_posts'));
     1007                $this->assertTrue($user_1->has_cap('edit_pages'));
     1008                $this->assertFalse($user_2->has_cap('edit_pages'));
    9161009
    9171010                // make sure the other caps didn't get messed up
    9181011                $caps = $this->getAllCapsAndRoles();
    9191012                foreach ( $caps as $cap => $roles ) {
    920                         if ( in_array( 'contributor', $roles, true ) || 'publish_posts' === $cap ) {
     1013                        if ( in_array( 'contributor', $roles, true ) || 'edit_pages' === $cap ) {
    9211014                                $this->assertTrue( $user_1->has_cap( $cap ), "User should have the {$cap} capability" );
    9221015                        } else {
    9231016                                $this->assertFalse( $user_1->has_cap( $cap ), "User should not have the {$cap} capability" );
     
    11871280
    11881281                $cap = get_post_type_object( 'attachment' )->cap;
    11891282                $this->assertEquals( 'upload_files', $cap->create_posts );
    1190                 $this->assertEquals( 'edit_posts', $cap->edit_posts );
     1283                $this->assertEquals( 'edit_attachments', $cap->edit_posts );
    11911284
    11921285                $this->assertTrue( $author->has_cap( $cap->create_posts ) );
    11931286                $this->assertTrue( $author->has_cap( $cap->edit_posts ) );