| 1 |
<?php |
| 2 |
/* |
| 3 |
Name: 用户角色 |
| 4 |
URI: https://mp.weixin.qq.com/s/NOOjbhtg6l4YhXGYZ9lBWg |
| 5 |
Description: 用户角色管理,以及用户额外权限设置。 |
| 6 |
Version: 1.0 |
| 7 |
*/ |
| 8 |
class WPJAM_Role{ |
| 9 |
public static function get_all(){ |
| 10 |
return $GLOBALS['wp_roles']->roles; |
| 11 |
} |
| 12 |
|
| 13 |
public static function get($role){ |
| 14 |
$data = self::get_all()[$role] ?? []; |
| 15 |
|
| 16 |
if($data){ |
| 17 |
$counts = count_users()['avail_roles']; |
| 18 |
|
| 19 |
$data['role'] = $role; |
| 20 |
$data['capabilities'] = array_keys($data['capabilities']); |
| 21 |
$data['cap_count'] = count($data['capabilities']); |
| 22 |
$data['user_count'] = isset($counts[$role]) ? '<a href="'.admin_url('users.php?role='.$role).'">'.$counts[$role].'</a>' : 0; |
| 23 |
} |
| 24 |
|
| 25 |
return $data; |
| 26 |
} |
| 27 |
|
| 28 |
public static function set($data, $role=''){ |
| 29 |
$data['capabilities'] = array_filter($data['capabilities']); |
| 30 |
$data['capabilities'] = array_fill_keys($data['capabilities'], 1); |
| 31 |
|
| 32 |
if($role){ |
| 33 |
remove_role($role); |
| 34 |
|
| 35 |
$label = '修改'; |
| 36 |
}else{ |
| 37 |
$role = $data['role']; |
| 38 |
$label = '新建'; |
| 39 |
} |
| 40 |
|
| 41 |
$result = add_role($role, $data['name'], $data['capabilities']); |
| 42 |
|
| 43 |
return is_null($result) ? new WP_Error('error', $label.'失败,可能重名或� |
| 44 |
� |
| 45 |
�他原因。') : $role; |
| 46 |
} |
| 47 |
|
| 48 |
public static function insert($data){ |
| 49 |
return self::set($data); |
| 50 |
} |
| 51 |
|
| 52 |
public static function update($role, $data){ |
| 53 |
return self::set($data, $role); |
| 54 |
} |
| 55 |
|
| 56 |
public static function delete($role){ |
| 57 |
$role == 'administrator' && wp_die('不能删除� |
| 58 |
级管理员角色。'); |
| 59 |
|
| 60 |
return remove_role($role); |
| 61 |
} |
| 62 |
|
| 63 |
public static function reset(){ |
| 64 |
require_once ABSPATH . 'wp-admin/includes/schema.php'; |
| 65 |
|
| 66 |
wpjam_map(self::get_all(), fn($v, $k)=> remove_role($k)); |
| 67 |
|
| 68 |
populate_roles(); |
| 69 |
} |
| 70 |
|
| 71 |
public static function query_items($args){ |
| 72 |
$counts = count_users()['avail_roles']; |
| 73 |
|
| 74 |
return array_values(wpjam_map(self::get_all(), fn($v, $k)=> array_merge($v, [ |
| 75 |
'role' => $k, |
| 76 |
'name' => translate_user_role($v['name']), |
| 77 |
'user_count' => isset($counts[$k]) ? '<a href="'.admin_url('users.php?role='.$k).'">'.$counts[$k].'</a>' : 0, |
| 78 |
'cap_count' => count($v['capabilities']), |
| 79 |
]))); |
| 80 |
} |
| 81 |
|
| 82 |
public static function map_meta_cap($user_id, $args){ |
| 83 |
if(isset($args[0]) && $args[0] === 'administrator' && (empty($args[1]) || $args[1] == 'delete')){ |
| 84 |
return ['do_not_allow']; |
| 85 |
} |
| 86 |
|
| 87 |
return is_multisite() ? ['manage_site'] : ['manage_options']; |
| 88 |
} |
| 89 |
|
| 90 |
public static function get_fields($action_key='', $id=0){ |
| 91 |
return [ |
| 92 |
'role' => ['title'=>'角色', 'type'=>'text', 'show_admin_column'=>true], |
| 93 |
'name' => ['title'=>'名称', 'type'=>'text', 'show_admin_column'=>true], |
| 94 |
'capabilities' => ['title'=>'权限', 'type'=>'mu-text'], |
| 95 |
'user_count' => ['title'=>'用户数', 'type'=>'view', 'show_admin_column'=>'only'], |
| 96 |
'cap_count' => ['title'=>'权限', 'type'=>'view', 'show_admin_column'=>'only'], |
| 97 |
]; |
| 98 |
} |
| 99 |
|
| 100 |
public static function get_actions(){ |
| 101 |
return [ |
| 102 |
'add' => ['title'=>'新建', 'last'=>true], |
| 103 |
'edit' => ['title'=>'编辑'], |
| 104 |
'delete' => ['title'=>'删除', 'direct'=>true, 'confirm'=>true, 'bulk'=>true], |
| 105 |
'reset' => ['title'=>'重置', 'direct'=>true, 'confirm'=>true, 'overall'=>true] |
| 106 |
]; |
| 107 |
} |
| 108 |
|
| 109 |
public static function get_additional($user, $output=''){ |
| 110 |
$user = is_object($user) ? $user : get_userdata($user); |
| 111 |
$caps = array_keys(wpjam_filter($user->caps, fn($v, $k)=> $v && !$GLOBALS['wp_roles']->is_role($k))); |
| 112 |
|
| 113 |
return $output == 'fields' ? wpjam_fields(['capabilities'=>['title'=>'权限', 'type'=>'mu-text', 'value'=>$caps]]) : $caps; |
| 114 |
} |
| 115 |
|
| 116 |
public static function set_additional($user, $caps){ |
| 117 |
$user = is_object($user) ? $user : get_userdata($user); |
| 118 |
$exists = self::get_additional($user); |
| 119 |
$caps = array_diff($caps, ['manage_sites', 'manage_options']); |
| 120 |
|
| 121 |
wpjam_map(array_diff($exists, $caps), fn($cap)=> $user->remove_cap($cap)); |
| 122 |
wpjam_map(array_diff($caps, $exists), fn($cap)=> $user->add_cap($cap)); |
| 123 |
} |
| 124 |
|
| 125 |
public static function builtin_page_load(){ |
| 126 |
current_user_can(is_multisite() ? 'manage_sites' : 'manage_options') && wpjam_hooks([ |
| 127 |
['additional_capabilities_display', false], |
| 128 |
['show_user_profile, edit_user_profile', fn($user)=> wpjam_echo('<h3>额外权限</h3>'.self::get_additional($user, 'fields'))], |
| 129 |
['personal_options_update, edit_user_profile_update', fn($v)=> add_action($v, fn($id)=> self::set_additional($id, $_POST['capabilities'] ?? []))] |
| 130 |
]); |
| 131 |
} |
| 132 |
} |
| 133 |
|
| 134 |
function wpjam_get_additional_capabilities($user){ |
| 135 |
return WPJAM_Role::get_additional($user); |
| 136 |
} |
| 137 |
|
| 138 |
function wpjam_set_additional_capabilities($user, $caps){ |
| 139 |
return WPJAM_Role::set_additional($user, $caps); |
| 140 |
} |
| 141 |
|
| 142 |
if(is_admin()){ |
| 143 |
wpjam_add_menu_page('roles', [ |
| 144 |
'plugin_page' => 'wpjam-user', |
| 145 |
'tab_slug' => 'roles', |
| 146 |
'title' => '角色管理', |
| 147 |
'order' => 8, |
| 148 |
'capability' => 'edit_roles', |
| 149 |
'model' => 'WPJAM_Role', |
| 150 |
'function' => 'list', |
| 151 |
'list_table' => ['singular'=>'role', 'plural'=>'roles', 'primary_key'=>'role'] |
| 152 |
]); |
| 153 |
|
| 154 |
wpjam_add_admin_load([ |
| 155 |
'base' => ['user-edit', 'profile'], |
| 156 |
'model' => 'WPJAM_Role' |
| 157 |
]); |
| 158 |
} |