我试图阻止某些用户在管理界面(“后端”)和实际网站(“前端”)上访问某些帖子,页面,类别和附件。
我已经使用template_redirect
动作解决了前端,检查是否允许wp_get_current_user()
查看global $post
,如果不是,则触发404。
我还使用pre_get_posts
过滤器解决了大多数帖子列表。甚至管理员内部的列表(不幸的是,并非所有列表)。
但是,在管理员内部,用户仍然可以简单地通过输入诸如/wp-admin/post.php?post=SOME_ID&action=edit
之类的正确URL来编辑他实际上不应该访问的任何帖子,附件,类别或页面。
我尝试使用map_meta_cap
过滤器修复此问题,虽然它似乎适用于帖子和页面(查看正常的编辑屏幕时为附件),但我无法使其用于附件“弹出式窗口”(当您单击列表中的附件并获得带有此类URL的弹出式窗口:/wp-admin/upload.php?item=SOME_ID
)或类别(/wp-admin/term.php?taxonomy=category&tag_ID=SOME_ID&post_type=post
)。
首先,我什至不确定要为附件和类别过滤的功能,但是我一直在尝试使用upload_files
和manage_categories
,但无法知道哪个帖子/术语正在编辑:
add_filter('map_meta_cap', function ($caps, $cap, $user_id, $args) {
# NOTE: $args[0] contains the post->ID
if (in_array($cap, ['edit_post', 'delete_post', 'edit_page', 'delete_page']) and !can_current_user_access_post($args[0])) {
return ['do_not_allow'];
}
elseif (in_array($cap, ['upload_files'])) {
# NOTE: $args is false, not sure how to check if user can access current attachment
}
elseif (in_array($cap, ['manage_categories'])) {
# NOTE: $args is false, not sure how to check if user can access current term
}
return $caps;
}, 10, 4);
我也很好奇为什么不能简单地将read_post
和read_page
添加到要检查的大写以防止读取访问? (这将允许我删除我的template_redirect
代码)。
此外,如果我可以使此map_meta_cap
代码在任何地方都可以正常工作(即使对于read
也可以),则可以删除pre_get_posts
过滤器,这会很好。
我以前从未使用过map_meta_cap
,坦率地说,我对它的工作原理有些困惑。
编辑:我现在也使用edit_term
功能解决了类别编辑屏幕。
答案 0 :(得分:0)
好吧,事实证明read_post
和read_page
实际上并没有阻止任何人阅读帖子或页面。不知道那到底在做什么。因此,仍然需要我的template_redirect
来阻止前端访问。
第二,使用pre_get_posts
过滤器隐藏附件实际上也可以解决附件弹出问题,因为如果附件列表中未打印附件,则弹出窗口不起作用(抛出JS错误)尝试访问弹出窗口时在控制台上)-我猜是因为弹出代码打印在同一列表中。
即使这可能是一个错误,并且可能并不完全安全,但它适用于我的用例。不过,对于附件弹出窗口,我也希望使用map_meta_cap
解决方案。