WordPress: возможности для пользовательских типов записей - PullRequest
12 голосов
/ 20 ноября 2011

Я пишу плагин, который создает пользовательский тип post_type.Я также хотел бы, чтобы плагин создавал пользовательскую роль, которая может только добавлять / редактировать / удалять новый post_type.Я пробовал несколько плагинов (Role Scoper, Advanced Access Manager), и они позволяют мне переопределять или создавать новые роли, но они не позволяют мне назначать возможности, специфичные для нового post_type.Например, я хочу разрешить возможность добавлять / редактировать мой новый post_type, но НЕ обычные записи / страницы.

Из того, что я прочитал, я могу добавлять новые роли с помощью add_role () функция.Одним из параметров этой функции является массив «возможностей», которые, по-видимому, определены как здесь .Я думаю, что мне нужно, чтобы иметь возможность добавлять свои возможности, которые являются специфическими для моего post_type.Это возможно?

Ответы [ 2 ]

24 голосов
/ 20 ноября 2011

Возможности для пользовательских типов сообщений

Функция register_post_type() принимает массив $capabilities в качестве одного из (необязательных) аргументов.

Это может выглядеть так:

$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'
);

где «ypt» означает «тип вашего сообщения».

После этого вы можете добавить новую роль в ваш 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
    )
);

Последнее может быть сделано с помощью плагинов, хотя, посмотрите, например, плагин Members от Джастина Тэдлока.

Тщательный пример

Чтобы дать вам более конкретный пример:

/* 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;
}
17 голосов
/ 20 мая 2013

В наше время (WP 3.5+) это намного проще. Просто установите аргумент map_meta_cap на TRUE и выберите string (обычно это имя типа записи) для аргумента capability_type при регистрации типа записи.

Простой 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"
)

Предполагаемая часть массива more - это семь других примитивных возможностей , которые не проверяются ядром, но отображаются map_meta_caps() при регистрации типа сообщения.

...