如何将新用户角色限制为只能访问常规帖子,而不是自定义帖子类型?



我们正在尝试添加一个名为"post_editor"的新用户角色,该角色只能访问Wordpress的默认帖子,而不是我们命名为"content_blocks"和"幻灯片"的2种自定义帖子类型。

我们已经能够通过插件用户角色编辑器实现这一点,但我们试图不添加另一个插件。

这是我们尝试过的。 在每种情况下,它都会创建新的用户角色,但他们可以继续查看、编辑和发布"content_blocks"和"幻灯片"这两种自定义帖子类型。

我们如何防止此用户角色访问这 2 种自定义帖子类型?

// Attempt 1
add_action( 'admin_init', 'add_role_post_editor' );
function add_role_post_editor(){
global $wp_roles;
if( get_role( 'post_editor' ) == NULL){
$cap = array(
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'read' => true,  
'create_content_blocks' => false,
'delete_content_blocks' => false,
'edit_content_blocks' => false,
'edit_slides' => false,
'create_slides' => false,
'delete_slides' => false,
);
add_role( 'post_editor', 'Post Editor', $cap );
}
// Attempt 2
add_action( 'admin_init', 'add_role_post_editor' );
function add_role_post_editor(){
global $wp_roles;
if( get_role( 'post_editor' ) == NULL){
$cap = array(
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'read' => true
);
add_role( 'post_editor', 'Post Editor', $cap );
$role = get_role( 'post_editor' );
$role->remove_cap( 'create_content_blocks');
$role->remove_cap( 'delete_content_blocks' );
$role->remove_cap( 'edit_content_blocks' );
$role->remove_cap( 'edit_others_content_blocks' );
$role->remove_cap( 'edit_published_content_blocks' );
$role->remove_cap( 'publish_content_blocks');
$role->remove_cap( 'read_slides' );
$role->remove_cap( 'edit_slides' );
$role->remove_cap( 'edit_others_slides' );
}
}

问题是当我们注册自定义帖子类型时,我们还必须注册这些功能,否则我们无法在user_roles中添加或删除它们?

这可能会为你指明正确的方向。

首先,您应该修复如何更新用户的角色和功能。这些存储在数据库中,与在运行时简单地注册的自定义帖子类型非常不同。如果您正在使用自定义代码管理用户角色或上限,我建议不要使用插件来做同样的事情,因为这过去对我来说效果不佳。

有两种常规方法。

  1. 注册用户角色时,除了"读取"之外,不向用户提供任何功能,然后使用map_meta_cap仅向用户提供所需的内容。

  2. 在注册角色时为用户提供比他们需要的更多的功能,然后使用map_meta_cap尝试删除内容。

根据我的经验,#1 效果最好,但下面的代码更接近 #2。

此外,我认为"edit_posts"功能实际上为用户提供的不仅仅是听起来的。您需要阅读一些有关大写字母的文档以获取更多信息。

// update this to re-init caps which are stored in DB
$custom_user_role_version = "1.1";
if ( $custom_user_role_version !== get_option( "custom_user_role_version" ) ) {
update_option( "custom_user_role_version", $custom_user_role_version );
$r = 'post_editor';
remove_role( $r );
add_role( $r, [
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'read' => true,
// whether or not these do anything is dependant upon how the custom post type is registered
// and what we put inside of 'map_meta_cap'. Even though we say false here, it's possible
// that it does not do anything.
'create_content_blocks' => false,
'delete_content_blocks' => false,
'edit_content_blocks' => false,
'edit_slides' => false,
'create_slides' => false,
'delete_slides' => false,
]);
}

现在我们挂在"map_meta_cap"。此筛选器实际上只是具有相同名称的函数的最后一行。您应该阅读该函数以查看每个输入参数的选项。您必须进行一些研究和一些测试才能完成问题。阅读函数中的代码还可以让您深入了解register_post_type参数在元功能方面的工作原理。

function is_post_editor( $user ){
return $user instanceof WP_User && in_array( 'post_editor', $user->roles );
};
/**
* @see map_meta_cap
*/
add_filter( 'map_meta_cap', function( $caps, $cap = '', $user_id = null, $args = []  ){
// can return this to allow an action after authenticating the logged in user
//    $caps_to_allow = [
//        'exist'
//    ];
switch( $cap ) {
case 'edit_post':
if ( in_array( get_post_type( $args[0]), [ 'content_blocks', 'slides' ] ) ){
if ( is_post_editor( get_user_by( 'ID', $user_id ) ) ) {
// I think pushing 'do_not_allow' to $caps will also work.
return [
'do_not_allow'
];
}
}
break;
case 'read_post':
// you might need something here too.
break;
}
// the $caps that the user must have to perform the thing that requires $cap
return $caps;
});

最新更新