我的问题是,我希望客户端能够像贡献者,订阅者,编辑者和作者一样,创建新用户。管理员。客户端创建的新用户不应具有管理员角色。可以以某种方式隐藏此选项吗?
感谢
Vayu
#1 楼
实际上很简单。您需要过滤到map_meta_caps
,并停止编辑器创建/编辑管理员,并从“可编辑角色”数组中删除管理员角色。此类,作为插件或您主题的functions.php文件中的类,可以做到:class JPB_User_Caps {
// Add our filters
function __construct(){
add_filter( 'editable_roles', array($this, 'editable_roles'));
add_filter( 'map_meta_cap', array($this, 'map_meta_cap'), 10, 4);
}
// Remove 'Administrator' from the list of roles if the current user is not an admin
function editable_roles( $roles ){
if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
unset( $roles['administrator']);
}
return $roles;
}
// If someone is trying to edit or delete and admin and that user isn't an admin, don't allow it
function map_meta_cap( $caps, $cap, $user_id, $args ){
switch( $cap ){
case 'edit_user':
case 'remove_user':
case 'promote_user':
if( isset($args[0]) && $args[0] == $user_id )
break;
elseif( !isset($args[0]) )
$caps[] = 'do_not_allow';
$other = new WP_User( absint($args[0]) );
if( $other->has_cap( 'administrator' ) ){
if(!current_user_can('administrator')){
$caps[] = 'do_not_allow';
}
}
break;
case 'delete_user':
case 'delete_users':
if( !isset($args[0]) )
break;
$other = new WP_User( absint($args[0]) );
if( $other->has_cap( 'administrator' ) ){
if(!current_user_can('administrator')){
$caps[] = 'do_not_allow';
}
}
break;
default:
break;
}
return $caps;
}
}
$jpb_user_caps = new JPB_User_Caps();
EDIT
好,所以我选择了探究为什么它会导致用户删除失败。看起来delete_user的处理方式与edit_user略有不同;我已经修改了map_meta_cap方法来解决此问题。我已经在3.0.3上进行了测试,这将阻止除管理员之外的任何人实际删除,编辑或创建管理员。
EDIT 2
我更新了代码以反映@ bugnumber9的答案在下面。请给那个答案一个赞!
评论
有人可以验证此代码阻止他人删除管理员吗?我无法重现这种行为。它确实阻止了它们的编辑,但是“删除”悬停链接仍然出现,并且WP允许用户进行删除...
–体细胞
2010-12-15 12:47
@somatic-您发现了。感谢您指出了这一点。现在,此问题已解决。
– John P Bloch
2010-12-20 17:24
我也需要这样做,但是不确定将代码放在哪里!在functions.php中?如果没有,如何从functions.php工作呢?最好,直流
– v3nt
2011年7月27日在12:16
@daniel阅读了第一段。
– John P Bloch
2011年7月27日14:02
在3.4.1中表现出色,谢谢!确保为create_users,delete_users,add_users,remove_users,edit_users,list_users和promove_users添加功能
–乔恩·拉施(Jon Raasch)
2012年9月13日23:11
#2 楼
尽管已有大约7年的历史了,但是可以轻松地在谷歌上搜索此线程,并且仍然可以提供可行的解决方案。我的意思是@John P Bloch提供的代码。这就是说,在PHP 7下,它会产生一个非严重错误(已弃用PHP),如下所示:
不推荐使用PHP:与它们的类同名的方法将不会在以后的PHP版本中构造。 JPB_User_Caps在...
中已弃用构造函数。
为了解决此问题,只需替换此部分即可:
// Add our filters
function JPB_User_Caps(){
add_filter( 'editable_roles', array(&$this, 'editable_roles'));
add_filter( 'map_meta_cap', array(&$this, 'map_meta_cap'),10,4);
}
:
// Add our filters
function __construct() {
add_filter( 'editable_roles', array(&$this, 'editable_roles') );
add_filter( 'map_meta_cap', array(&$this, 'map_meta_cap'), 10, 4 );
}
这将解决问题。
评论
谢谢你,谢谢你,谢谢你。我感谢代码质量的奉献精神,并更新了我的答案,以便临时Google员工也可以获取备忘录。你摇滚!
– John P Bloch
17年7月18日在3:04
#3 楼
我正在寻找一个解决方案,其中编辑器可以只编辑菜单并创建/编辑用户而无需插件。所以我最终为有兴趣的人制作了它。// Customizes 'Editor' role to have the ability to modify menus, add new users
// and more.
class Custom_Admin {
// Add our filters
public function __construct(){
// Allow editor to edit theme options (ie Menu)
add_action('init', array($this, 'init'));
add_filter('editable_roles', array($this, 'editable_roles'));
add_filter('map_meta_cap', array($this, 'map_meta_cap'), 10, 4);
}
public function init() {
if ($this->is_client_admin()) {
// Disable access to the theme/widget pages if not admin
add_action('admin_head', array($this, 'modify_menus'));
add_action('load-themes.php', array($this, 'wp_die'));
add_action('load-widgets.php', array($this, 'wp_die'));
add_action('load-customize.php', array($this, 'wp_die'));
add_filter('user_has_cap', array($this, 'user_has_cap'));
}
}
public function wp_die() {
_default_wp_die_handler(__('You do not have sufficient permissions to access this page.'));
}
public function modify_menus()
{
remove_submenu_page( 'themes.php', 'themes.php' ); // hide the theme selection submenu
remove_submenu_page( 'themes.php', 'widgets.php' ); // hide the widgets submenu
// Appearance Menu
global $menu;
global $submenu;
if (isset($menu[60][0])) {
$menu[60][0] = "Menus"; // Rename Appearance to Menus
}
unset($submenu['themes.php'][6]); // Customize
}
// Remove 'Administrator' from the list of roles if the current user is not an admin
public function editable_roles( $roles ){
if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
unset( $roles['administrator']);
}
return $roles;
}
public function user_has_cap( $caps ){
$caps['list_users'] = true;
$caps['create_users'] = true;
$caps['edit_users'] = true;
$caps['promote_users'] = true;
$caps['delete_users'] = true;
$caps['remove_users'] = true;
$caps['edit_theme_options'] = true;
return $caps;
}
// If someone is trying to edit or delete and admin and that user isn't an admin, don't allow it
public function map_meta_cap( $caps, $cap, $user_id, $args ){
// $args[0] == other_user_id
foreach($caps as $key => $capability)
{
switch ($cap)
{
case 'edit_user':
case 'remove_user':
case 'promote_user':
if(isset($args[0]) && $args[0] == $user_id) {
break;
}
else if(!isset($args[0])) {
$caps[] = 'do_not_allow';
}
// Do not allow non-admin to edit admin
$other = new WP_User( absint($args[0]) );
if( $other->has_cap( 'administrator' ) ){
if(!current_user_can('administrator')){
$caps[] = 'do_not_allow';
}
}
break;
case 'delete_user':
case 'delete_users':
if( !isset($args[0])) {
break;
}
// Do not allow non-admin to delete admin
$other = new WP_User(absint($args[0]));
if( $other->has_cap( 'administrator' ) ){
if(!current_user_can('administrator')){
$caps[] = 'do_not_allow';
}
}
break;
break;
}
}
return $caps;
}
// If current user is called admin or administrative and is an editor
protected function is_client_admin() {
$current_user = wp_get_current_user();
$is_editor = isset($current_user->caps['editor']) ? $current_user->caps['editor'] : false;
return ($is_editor);
}
}
new Custom_Admin();
#4 楼
@John P Blochs解决方案仍然可以正常工作,但是我想我也将为“ map_meta_cap”添加一些小的过滤器。只是更短更清洁,至少对于我而言;) function my_map_meta_cap( $caps, $cap, $user_id, $args ) {
$check_caps = [
'edit_user',
'remove_user',
'promote_user',
'delete_user',
'delete_users'
];
if( !in_array( $cap, $check_caps ) || current_user_can('administrator') ) {
return $caps;
}
$other = get_user_by( 'id', $args[0] ?? false ); // PHP 7 check for variable in $args...
if( $other && $other->has_cap('administrator') ) {
$caps[] = 'do_not_allow';
}
return $caps;
}
add_filter('map_meta_cap', 'my_map_meta_cap', 10, 4 );
评论
请链接您正在使用的插件,我在查找您指的是插件时遇到了问题。