繁体   English   中英

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

[英]How to limit a new user role to access only regular posts, not custom post types?

我们正在尝试添加一个名为“post_editor”的新用户角色,它只能访问 Wordpress 的默认帖子,而不是我们命名为“content_blocks”和“slides”的 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;
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM