WordPress:自定义帖子类型的功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8198038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 18:49:38  来源:igfitidea点击:

WordPress: Capabilities for custom post types

wordpresswordpress-plugincustom-post-typecapability

提问by emersonthis

I'm writing a plugin which creates a custom post_type. I'd also like the plugin to create a custom role which can only add/edit/delete the new post_type. I've tried several plugins (Role Scoper, Advanced Access manager) and they allow me to redefine or create new roles, but they don't allow me to assign capabilities specific to the new post_type. For example, I want to allow the ability to add/edit my new post_type but NOT normal posts/pages.

我正在编写一个创建自定义 post_type 的插件。我还希望该插件创建一个只能添加/编辑/删除新 post_type 的自定义角色。我已经尝试了几个插件(角色范围、高级访问管理器),它们允许我重新定义或创建新角色,但它们不允许我分配特定于新 post_type 的功能。例如,我想允许添加/编辑我的新 post_type 但不是普通的帖子/页面。

From what I've read, I can add new roles with the add_role()function. One of the parameters of this function is an array of "capabilities" which appear to be defined here. I think what I need is to be able to add my capabilities that are specific to MY post_type. Is this possible?

根据我的阅读,我可以使用add_role()函数添加新角色。此函数的参数之一是一个“功能”数组,它似乎在此处定义。我认为我需要的是能够添加特定于 MY post_type 的功能。这可能吗?

回答by Johannes Pille

Capabilities for Custom Post Types

自定义帖子类型的功能

The function register_post_type()takes a $capabilitiesarray as one of its (optional) arguments.

该函数register_post_type()$capabilities数组作为其(可选)参数之一。

It could look like so:

它可能看起来像这样:

$capabilities = array(
    'publish_posts' => 'publish_ypts',
    'edit_posts' => 'edit_ypts',
    'edit_others_posts' => 'edit_others_ypts',
    'delete_posts' => 'delete_ypts',
    'delete_others_posts' => 'delete_others_ypts',
    'read_private_posts' => 'read_private_ypts',
    'edit_post' => 'edit_ypt',
    'delete_post' => 'delete_ypt',
    'read_post' => 'read_ypt'
);

where "ypt" stands for "your post type".

其中“ypt”代表“您的帖子类型”。

Thereafter you could add a new role to your WordPress that has these exact capabilities (and possibly some more of the standard WordPress capabilities):

此后,您可以向您的 WordPress 添加一个新角色,该角色具有以下确切功能(可能还有更多标准 WordPress 功能):

add_role(
    'ypt_author',
    'Author of your post type',
    array(
        'publish_ypts' => true,
        'edit_ypts' => true,
        'edit_others_ypts' => true,
        'delete_ypts' => true,
        'delete_others_ypts' => true,
        'read_private_ypts' => true,
        'edit_ypt' => true,
        'delete_ypt' => true,
        'read_ypt' => true,
        // more standard capabilities here
    )
);

The latter can be done using plugins though, check out the Membersplugin by Justin Tadlock, for instance.

后者可以使用插件来完成,例如,查看Justin Tadlock的Members插件。

Thorough Example

彻底的例子

To give you a more concrete example:

给你一个更具体的例子:

/* REGISTER POST TYPE */

add_action('init', 'ypt_register');

function ypt_register()
{

    $labels = array(
        'name' => _x('YPTs', 'post type general name'),
        'singular_name' => _x('YPT', 'post type singular name'),
        'add_new' => _x('Add New YPT', 'Team item'),
        'add_new_item' => __('Add a new post of type YPT'),
        'edit_item' => __('Edit YPT'),
        'new_item' => __('New YPT'),
        'view_item' => __('View YPT'),
        'search_items' => __('Search YPTs'),
        'not_found' =>  __('No YPTs found'),
        'not_found_in_trash' => __('No YPTs currently trashed'),
        'parent_item_colon' => ''
    );

    $capabilities = array(
        // this is where the first code block from above goes
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'ypt',
        'capabilities' => $capabilities,
        'hierarchical' => false,
        'menu_position' => null,
        'supports' => array( 'title', 'author', 'thumbnail' )
    ); 

    register_post_type( 'ypt' , $args );

    flush_rewrite_rules( false );
}


/* MAP META CAPABILITIES */

add_filter( 'map_meta_cap', 'ypt_map_meta_cap', 10, 4 );

function ypt_map_meta_cap( $caps, $cap, $user_id, $args )
{

    if ( 'edit_ypt' == $cap || 'delete_ypt' == $cap || 'read_ypt' == $cap ) {
        $post = get_post( $args[0] );
        $post_type = get_post_type_object( $post->post_type );
        $caps = array();
    }

    if ( 'edit_ypt' == $cap ) {
        if ( $user_id == $post->post_author )
            $caps[] = $post_type->cap->edit_posts;
        else
            $caps[] = $post_type->cap->edit_others_posts;
    }

    elseif ( 'delete_ypt' == $cap ) {
        if ( $user_id == $post->post_author )
            $caps[] = $post_type->cap->delete_posts;
        else
            $caps[] = $post_type->cap->delete_others_posts;
    }

    elseif ( 'read_ypt' == $cap ) {
        if ( 'private' != $post->post_status )
            $caps[] = 'read';
        elseif ( $user_id == $post->post_author )
            $caps[] = 'read';
        else
            $caps[] = $post_type->cap->read_private_posts;
    }

    return $caps;
}

回答by kaiser

Nowadays (WP 3.5+), it's much easier. Just set the map_meta_capargument to TRUEand choose a string(typically the post type name) for the capability_typeargument when registering the post type.

如今(WP 3.5+),这要容易得多。在注册帖子类型时,只需将map_meta_cap参数设置为TRUE并选择一个string(通常是帖子类型名称)作为capability_type参数。

A simple var_dump( $GLOBALS['wp_post_types']['new_custom_post_type'] ) );will show you something like the following.

一个简单的var_dump( $GLOBALS['wp_post_types']['new_custom_post_type'] ) );将向您展示如下内容。

[cap] => stdClass Object
(
    [edit_post]      => "edit_{$capability_type}"
    [read_post]      => "read_{$capability_type}"
    [delete_post]        => "delete_{$capability_type}"
    [edit_posts]         => "edit_{$capability_type}s"
    [edit_others_posts]  => "edit_others_{$capability_type}s"
    [publish_posts]      => "publish_{$capability_type}s"
    [read_private_posts]     => "read_private_{$capability_type}s"
        [delete_posts]           => "delete_{$capability_type}s"
        [delete_private_posts]   => "delete_private_{$capability_type}s"
        [delete_published_posts] => "delete_published_{$capability_type}s"
        [delete_others_posts]    => "delete_others_{$capability_type}s"
        [edit_private_posts]     => "edit_private_{$capability_type}s"
        [edit_published_posts]   => "edit_published_{$capability_type}s"
)

The moreintended array part are the seven other primitive capabilitiesthat are not checked by core, but mapped by map_meta_caps()during post type registration.

旨在阵列部分是第7个其他原语功能不是由核心检查,但由映射map_meta_caps()后类型注册期间。