WordPress.org

Make WordPress Core

Ticket #14122: 14122.diff

File 14122.diff, 13.9 KB (added by nacin, 8 years ago)

Entirely untested. Probably missing some components.

  • wp-includes/post.php

     
    2020                '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
    2121                '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    2222                'capability_type' => 'post',
     23                'map_meta_cap' => true,
    2324                'hierarchical' => false,
    2425                'rewrite' => false,
    2526                'query_var' => false,
     
    3132                '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
    3233                '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    3334                'capability_type' => 'page',
     35                'map_meta_cap' => true,
    3436                'hierarchical' => true,
    3537                'rewrite' => false,
    3638                'query_var' => false,
     
    836838 * - menu_position - The position in the menu order the post type should appear. Defaults to the bottom.
    837839 * - menu_icon - The url to the icon to be used for this menu. Defaults to use the posts icon.
    838840 * - capability_type - The post type to use for checking read, edit, and delete capabilities. Defaults to "post".
    839  * - capabilities - Array of capabilities for this post type. You can see accepted values in {@link get_post_type_capabilities()}. By default the capability_type is used to construct capabilities.
     841 * - capabilities - Array of capabilities for this post type. You can see accepted values in {@link get_post_type_capabilities()}. By default the capability_type is used as a base to construct capabilities.
     842 * - map_meta_cap - Whether to use the internal default meta capability handling. Defaults to false.
    840843 * - hierarchical - Whether the post type is hierarchical. Defaults to false.
    841844 * - supports - An alias for calling add_post_type_support() directly. See add_post_type_support() for Documentation. Defaults to none.
    842845 * - register_meta_box_cb - Provide a callback function that will be called when setting up the meta boxes for the edit form.  Do remove_meta_box() and add_meta_box() calls in the callback.
     
    866869        // Args prefixed with an underscore are reserved for internal use.
    867870        $defaults = array(
    868871                'labels' => array(), 'description' => '', 'publicly_queryable' => null, 'exclude_from_search' => null,
    869                 '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'capabilities' => array(), 'hierarchical' => false,
     872                'capability_type' => 'post', 'capabilities' => array(), 'map_meta_cap' => false,
     873                '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'hierarchical' => false,
    870874                'public' => false, 'rewrite' => true, 'query_var' => true, 'supports' => array(), 'register_meta_box_cb' => null,
    871875                'taxonomies' => array(), 'show_ui' => null, 'menu_position' => null, 'menu_icon' => null,
    872876                'permalink_epmask' => EP_PERMALINK, 'can_export' => true, 'show_in_nav_menus' => null, 'show_in_menu' => null,
     
    978982 * - read_private_posts - The capability that controls reading private posts. Defaults to "read_private . $capability_type . s" (read_private_posts).
    979983 * - delete_post - The meta capability that controls deleting a particular object of this post type. Defaults to "delete_ . $capability_type" (delete_post).
    980984 *
     985 * @see map_meta_cap()
    981986 * @since 3.0.0
     987 *
    982988 * @param object $args
    983989 * @return object object with all the capabilities as member variables
    984990 */
    985991function get_post_type_capabilities( $args ) {
    986         $defaults = array(
     992        global $_post_type_meta_capabilities;
     993
     994        $default_capabilities = array(
     995                // Meta capabilities are generally mapped to primitive capabilities depending on the context
     996                // (which would be the post being edited/deleted/read), instead of granted to users or roles:
    987997                'edit_post'          => 'edit_'         . $args->capability_type,
     998                'read_post'          => 'read_'         . $args->capability_type,
     999                'delete_post'        => 'delete_'       . $args->capability_type,
     1000                // Primitive capabilities that are used outside of map_meta_cap():
    9881001                'edit_posts'         => 'edit_'         . $args->capability_type . 's',
    9891002                'edit_others_posts'  => 'edit_others_'  . $args->capability_type . 's',
    9901003                'publish_posts'      => 'publish_'      . $args->capability_type . 's',
    991                 'read_post'          => 'read_'         . $args->capability_type,
    9921004                'read_private_posts' => 'read_private_' . $args->capability_type . 's',
    993                 'delete_post'        => 'delete_'       . $args->capability_type,
    9941005        );
    995         $labels = array_merge( $defaults, $args->capabilities );
    996         return (object) $labels;
     1006        // Primitive capabilities that are used within map_meta_cap():
     1007        if ( $args->map_meta_cap ) {
     1008                $default_capabilities_for_mapping = array(
     1009                        'read'                   => 'read',
     1010                        'delete_posts'           => 'delete_'           . $args->capability_type . 's',
     1011                        'delete_private_posts'   => 'delete_private_'   . $args->capability_type . 's',
     1012                        'delete_published_posts' => 'delete_published_' . $args->capability_type . 's',
     1013                        'delete_others_posts'    => 'delete_others_'    . $args->capability_type . 's',
     1014                        'edit_private_posts'     => 'edit_private_'     . $args->capability_type . 's',
     1015                        'edit_published_posts'   => 'edit_published_'   . $args->capability_type . 's',
     1016                );
     1017                $default_capabilities = array_merge( $default_capabilities, $default_capabilities_for_mapping );
     1018        }
     1019        $capabilities = array_merge( $default_capabilities, $args->capabilities );
     1020        if ( $args->map_meta_cap )
     1021                _post_type_meta_capabilities( $capabilities );
     1022        return (object) $capabilities;
    9971023}
    9981024
    9991025/**
     1026 * Stores or returns a list of post type meta caps for map_meta_cap().
     1027 *
     1028 * @since 3.1.0
     1029 * @access private
     1030 */
     1031function _post_type_meta_capabilities( $capabilities = null ) {
     1032        static $meta_caps = array();
     1033        if ( null === $capabilities )
     1034                return $meta_caps;
     1035        foreach ( $capabilities as $core => $custom ) {
     1036                if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ) ) )
     1037                        $meta_caps[ $custom ] = $core;
     1038        }
     1039}
     1040
     1041/**
    10001042 * Builds an object with all post type labels out of a post type object
    10011043 *
    10021044 * Accepted keys of the label array in the post type object:
  • wp-includes/capabilities.php

     
    817817                        $caps[] = 'edit_users'; // Explicit due to primitive fall through
    818818                break;
    819819        case 'delete_post':
     820        case 'delete_page':
    820821                $author_data = get_userdata( $user_id );
    821822                //echo "post ID: {$args[0]}<br />";
    822823                $post = get_post( $args[0] );
    823824                $post_type = get_post_type_object( $post->post_type );
    824                 if ( $post_type && 'post' != $post_type->capability_type ) {
     825                if ( 'delete_post' == $cap && $post_type && 'post' != $post_type->capability_type && ! $post_type->map_meta_cap ) {
    825826                        $args = array_merge( array( $post_type->cap->delete_post, $user_id ), $args );
    826827                        return call_user_func_array( 'map_meta_cap', $args );
    827828                }
     
    837838                if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) {
    838839                        // If the post is published...
    839840                        if ( 'publish' == $post->post_status ) {
    840                                 $caps[] = 'delete_published_posts';
     841                                $caps[] = $post_type->cap->delete_published_posts;
    841842                        } elseif ( 'trash' == $post->post_status ) {
    842843                                if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) )
    843                                         $caps[] = 'delete_published_posts';
     844                                        $caps[] = $post_type->cap->delete_published_posts;
    844845                        } else {
    845846                                // If the post is draft...
    846                                 $caps[] = 'delete_posts';
     847                                $caps[] = $post_type->cap->delete_posts;
    847848                        }
    848849                } else {
    849850                        // The user is trying to edit someone else's post.
    850                         $caps[] = 'delete_others_posts';
     851                        $caps[] = $post_type->cap->delete_others_posts;
    851852                        // The post is published, extra cap required.
    852853                        if ( 'publish' == $post->post_status )
    853                                 $caps[] = 'delete_published_posts';
     854                                $caps[] = $post_type->cap->delete_published_posts;
    854855                        elseif ( 'private' == $post->post_status )
    855                                 $caps[] = 'delete_private_posts';
     856                                $caps[] = $post_type->cap->delete_private_posts;
    856857                }
    857858                break;
    858         case 'delete_page':
    859                 $author_data = get_userdata( $user_id );
    860                 //echo "post ID: {$args[0]}<br />";
    861                 $page = get_page( $args[0] );
    862                 $page_author_data = get_userdata( $page->post_author );
    863                 //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
    864                 // If the user is the author...
    865 
    866                 if ('' != $page->post_author) {
    867                         $page_author_data = get_userdata( $page->post_author );
    868                 } else {
    869                         //No author set yet so default to current user for cap checks
    870                         $page_author_data = $author_data;
    871                 }
    872 
    873                 if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID ) {
    874                         // If the page is published...
    875                         if ( $page->post_status == 'publish' ) {
    876                                 $caps[] = 'delete_published_pages';
    877                         } elseif ( 'trash' == $page->post_status ) {
    878                                 if ('publish' == get_post_meta($page->ID, '_wp_trash_meta_status', true) )
    879                                         $caps[] = 'delete_published_pages';
    880                         } else {
    881                                 // If the page is draft...
    882                                 $caps[] = 'delete_pages';
    883                         }
    884                 } else {
    885                         // The user is trying to edit someone else's page.
    886                         $caps[] = 'delete_others_pages';
    887                         // The page is published, extra cap required.
    888                         if ( $page->post_status == 'publish' )
    889                                 $caps[] = 'delete_published_pages';
    890                         elseif ( $page->post_status == 'private' )
    891                                 $caps[] = 'delete_private_pages';
    892                 }
    893                 break;
    894859                // edit_post breaks down to edit_posts, edit_published_posts, or
    895860                // edit_others_posts
    896861        case 'edit_post':
     862        case 'edit_page':
    897863                $author_data = get_userdata( $user_id );
    898864                //echo "post ID: {$args[0]}<br />";
    899865                $post = get_post( $args[0] );
    900866
    901867                $post_type = get_post_type_object( $post->post_type );
    902                 if ( $post_type && 'post' != $post_type->capability_type ) {
     868                if ( 'edit_post' == $cap && $post_type && 'post' != $post_type->capability_type && ! $post_type->map_meta_cap ) {
    903869                        $args = array_merge( array( $post_type->cap->edit_post, $user_id ), $args );
    904870                        return call_user_func_array( 'map_meta_cap', $args );
    905871                }
     
    909875                if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) {
    910876                        // If the post is published...
    911877                        if ( 'publish' == $post->post_status ) {
    912                                 $caps[] = 'edit_published_posts';
     878                                $caps[] = $post_type->cap->edit_published_posts;
    913879                        } elseif ( 'trash' == $post->post_status ) {
    914880                                if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) )
    915                                         $caps[] = 'edit_published_posts';
     881                                        $caps[] = $post_type->cap->edit_published_posts;
    916882                        } else {
    917883                                // If the post is draft...
    918                                 $caps[] = 'edit_posts';
     884                                $caps[] = $post_type->cap->edit_posts;
    919885                        }
    920886                } else {
    921887                        // The user is trying to edit someone else's post.
    922                         $caps[] = 'edit_others_posts';
     888                        $caps[] = $post_type->cap->edit_others_posts;
    923889                        // The post is published, extra cap required.
    924890                        if ( 'publish' == $post->post_status )
    925                                 $caps[] = 'edit_published_posts';
     891                                $caps[] = $post_type->cap->edit_published_posts;
    926892                        elseif ( 'private' == $post->post_status )
    927                                 $caps[] = 'edit_private_posts';
     893                                $caps[] = $post_type->cap->edit_private_posts;
    928894                }
    929895                break;
    930         case 'edit_page':
    931                 $author_data = get_userdata( $user_id );
    932                 //echo "post ID: {$args[0]}<br />";
    933                 $page = get_page( $args[0] );
    934                 $page_author_data = get_userdata( $page->post_author );
    935                 //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
    936                 // If the user is the author...
    937                 if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID ) {
    938                         // If the page is published...
    939                         if ( 'publish' == $page->post_status ) {
    940                                 $caps[] = 'edit_published_pages';
    941                         } elseif ( 'trash' == $page->post_status ) {
    942                                 if ('publish' == get_post_meta($page->ID, '_wp_trash_meta_status', true) )
    943                                         $caps[] = 'edit_published_pages';
    944                         } else {
    945                                 // If the page is draft...
    946                                 $caps[] = 'edit_pages';
    947                         }
    948                 } else {
    949                         // The user is trying to edit someone else's page.
    950                         $caps[] = 'edit_others_pages';
    951                         // The page is published, extra cap required.
    952                         if ( 'publish' == $page->post_status )
    953                                 $caps[] = 'edit_published_pages';
    954                         elseif ( 'private' == $page->post_status )
    955                                 $caps[] = 'edit_private_pages';
    956                 }
    957                 break;
    958896        case 'read_post':
     897        case 'read_page':
    959898                $post = get_post( $args[0] );
    960899                $post_type = get_post_type_object( $post->post_type );
    961                 if ( $post_type && 'post' != $post_type->capability_type ) {
     900                if ( 'read_post' == $cap && $post_type && 'post' != $post_type->capability_type && ! $post_type->map_meta_cap ) {
    962901                        $args = array_merge( array( $post_type->cap->read_post, $user_id ), $args );
    963902                        return call_user_func_array( 'map_meta_cap', $args );
    964903                }
    965904
    966905                if ( 'private' != $post->post_status ) {
    967                         $caps[] = 'read';
     906                        $caps[] = $post_type->cap->read;
    968907                        break;
    969908                }
    970909
    971910                $author_data = get_userdata( $user_id );
    972911                $post_author_data = get_userdata( $post->post_author );
    973912                if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID )
    974                         $caps[] = 'read';
     913                        $caps[] = $post_type->cap->read;
    975914                else
    976                         $caps[] = 'read_private_posts';
     915                        $caps[] = $post_type->cap->read_private_posts;
    977916                break;
    978         case 'read_page':
    979                 $page = get_page( $args[0] );
    980 
    981                 if ( 'private' != $page->post_status ) {
    982                         $caps[] = 'read';
    983                         break;
    984                 }
    985 
    986                 $author_data = get_userdata( $user_id );
    987                 $page_author_data = get_userdata( $page->post_author );
    988                 if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID )
    989                         $caps[] = 'read';
    990                 else
    991                         $caps[] = 'read_private_pages';
    992                 break;
    993917        case 'edit_comment':
    994918                $comment = get_comment( $args[0] );
    995919                $post = get_post( $comment->comment_post_ID );
     
    1050974                        $caps[] = $cap;
    1051975                break;
    1052976        default:
     977                // Handle meta capabilities for custom post types.
     978                $post_type_meta_caps = _post_type_meta_capabilities();
     979                if ( isset( $post_type_meta_caps[ $cap ] ) ) {
     980                        $args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
     981                        return call_user_func_array( 'map_meta_cap', $args );
     982                }
     983
    1053984                // If no meta caps match, return the original cap.
    1054985                $caps[] = $cap;
    1055986        }