文章目录[隐藏]
WordPress柔性用户权限分级管理插件开发教程
一、引言:为什么需要柔性权限管理
在当今网络传媒环境中,WordPress已成为众多媒体机构的首选内容管理系统。随着站点规模的扩大和团队协作的复杂化,传统的固定用户角色系统往往无法满足实际需求。编辑可能需要临时审核权限,记者可能需要特定栏目的发布权限,而实习生可能只需要基础的投稿功能。
柔性用户权限分级管理正是为了解决这些问题而诞生的。与WordPress默认的固定角色系统不同,柔性权限管理允许管理员根据实际需求,动态创建、调整和分配权限组合,实现真正的精细化权限控制。
二、插件基础架构设计
2.1 创建插件主文件
<?php
/**
* Plugin Name: 柔性用户权限管理器
* Plugin URI: https://yourdomain.com/
* Description: 为WordPress站点提供灵活的用户权限分级管理功能
* Version: 1.0.0
* Author: 网络传媒技术团队
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('FLEX_PERMISSIONS_VERSION', '1.0.0');
define('FLEX_PERMISSIONS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FLEX_PERMISSIONS_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class Flex_Permissions_Manager {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 管理界面
add_action('admin_menu', array($this, 'add_admin_menu'));
// 用户权限检查
add_filter('user_has_cap', array($this, 'check_flex_permissions'), 10, 4);
// 加载文本域
add_action('plugins_loaded', array($this, 'load_textdomain'));
}
public function activate() {
// 创建必要的数据库表
$this->create_tables();
// 添加默认权限组
$this->add_default_permission_groups();
// 设置版本号
update_option('flex_permissions_version', FLEX_PERMISSIONS_VERSION);
}
public function deactivate() {
// 清理临时数据
// 注意:不删除用户权限数据,以便重新激活时恢复
}
public function load_textdomain() {
load_plugin_textdomain('flex-permissions', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
// 其他方法将在后续章节实现
}
// 启动插件
Flex_Permissions_Manager::get_instance();
?>
2.2 创建数据库表结构
/**
* 创建权限管理所需的数据库表
*/
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_prefix = $wpdb->prefix . 'flex_perm_';
// 权限组表
$permission_groups_table = $table_prefix . 'groups';
$sql_groups = "CREATE TABLE IF NOT EXISTS $permission_groups_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
group_name varchar(100) NOT NULL,
group_slug varchar(100) NOT NULL,
description text,
is_default tinyint(1) DEFAULT 0,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY group_slug (group_slug)
) $charset_collate;";
// 权限规则表
$permission_rules_table = $table_prefix . 'rules';
$sql_rules = "CREATE TABLE IF NOT EXISTS $permission_rules_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
group_id mediumint(9) NOT NULL,
capability varchar(100) NOT NULL,
post_type varchar(50) DEFAULT '',
taxonomy varchar(50) DEFAULT '',
allowed tinyint(1) DEFAULT 1,
conditions text,
priority smallint(5) DEFAULT 10,
PRIMARY KEY (id),
KEY group_id (group_id),
KEY capability (capability)
) $charset_collate;";
// 用户-权限组关联表
$user_groups_table = $table_prefix . 'user_groups';
$sql_user_groups = "CREATE TABLE IF NOT EXISTS $user_groups_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
group_id mediumint(9) NOT NULL,
expires_at datetime DEFAULT NULL,
assigned_by bigint(20),
assigned_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY user_group (user_id, group_id),
KEY user_id (user_id),
KEY group_id (group_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_groups);
dbDelta($sql_rules);
dbDelta($sql_user_groups);
}
三、权限组管理功能实现
3.1 权限组CRUD操作
/**
* 添加默认权限组
*/
private function add_default_permission_groups() {
$default_groups = array(
array(
'name' => '高级编辑',
'slug' => 'senior-editor',
'description' => '拥有所有栏目的编辑和审核权限',
'is_default' => 0
),
array(
'name' => '栏目编辑',
'slug' => 'column-editor',
'description' => '拥有指定栏目的编辑权限',
'is_default' => 0
),
array(
'name' => '特约记者',
'slug' => 'special-reporter',
'description' => '可以投稿和编辑自己的文章',
'is_default' => 0
),
array(
'name' => '实习编辑',
'slug' => 'intern-editor',
'description' => '基础投稿权限,需要审核',
'is_default' => 1
)
);
foreach ($default_groups as $group) {
$this->add_permission_group($group);
}
}
/**
* 添加权限组到数据库
* @param array $group_data 权限组数据
* @return int|false 成功返回组ID,失败返回false
*/
public function add_permission_group($group_data) {
global $wpdb;
$table_name = $wpdb->prefix . 'flex_perm_groups';
$defaults = array(
'group_name' => '',
'group_slug' => '',
'description' => '',
'is_default' => 0
);
$data = wp_parse_args($group_data, $defaults);
// 验证必要字段
if (empty($data['group_name']) || empty($data['group_slug'])) {
return false;
}
// 确保slug唯一
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $table_name WHERE group_slug = %s",
$data['group_slug']
));
if ($existing) {
return false;
}
$result = $wpdb->insert($table_name, $data);
if ($result) {
return $wpdb->insert_id;
}
return false;
}
/**
* 获取所有权限组
* @param array $args 查询参数
* @return array 权限组列表
*/
public function get_permission_groups($args = array()) {
global $wpdb;
$table_name = $wpdb->prefix . 'flex_perm_groups';
$defaults = array(
'include_default' => true,
'orderby' => 'group_name',
'order' => 'ASC',
'limit' => 0,
'offset' => 0
);
$args = wp_parse_args($args, $defaults);
$where = array('1=1');
$params = array();
if (!$args['include_default']) {
$where[] = 'is_default = %d';
$params[] = 0;
}
$where_clause = implode(' AND ', $where);
$query = "SELECT * FROM $table_name WHERE $where_clause";
if (!empty($args['orderby'])) {
$query .= " ORDER BY " . esc_sql($args['orderby']) . " " . esc_sql($args['order']);
}
if ($args['limit'] > 0) {
$query .= " LIMIT %d";
$params[] = $args['limit'];
if ($args['offset'] > 0) {
$query .= " OFFSET %d";
$params[] = $args['offset'];
}
}
if (!empty($params)) {
$query = $wpdb->prepare($query, $params);
}
return $wpdb->get_results($query);
}
3.2 权限规则管理
/**
* 为权限组添加权限规则
* @param int $group_id 权限组ID
* @param string $capability 权限标识
* @param array $args 额外参数
* @return int|false 成功返回规则ID,失败返回false
*/
public function add_permission_rule($group_id, $capability, $args = array()) {
global $wpdb;
$table_name = $wpdb->prefix . 'flex_perm_rules';
$defaults = array(
'post_type' => '',
'taxonomy' => '',
'allowed' => 1,
'conditions' => '',
'priority' => 10
);
$data = wp_parse_args($args, $defaults);
$data['group_id'] = $group_id;
$data['capability'] = $capability;
// 序列化条件数组
if (is_array($data['conditions'])) {
$data['conditions'] = maybe_serialize($data['conditions']);
}
$result = $wpdb->insert($table_name, $data);
if ($result) {
return $wpdb->insert_id;
}
return false;
}
/**
* 获取权限组的规则
* @param int $group_id 权限组ID
* @return array 权限规则列表
*/
public function get_group_rules($group_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'flex_perm_rules';
$rules = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $table_name WHERE group_id = %d ORDER BY priority ASC, capability ASC",
$group_id
));
// 反序列化条件
foreach ($rules as &$rule) {
if (!empty($rule->conditions)) {
$rule->conditions = maybe_unserialize($rule->conditions);
}
}
return $rules;
}
四、用户权限分配与检查
4.1 用户-权限组关联管理
/**
* 为用户分配权限组
* @param int $user_id 用户ID
* @param int $group_id 权限组ID
* @param array $args 额外参数
* @return bool 是否成功
*/
public function assign_group_to_user($user_id, $group_id, $args = array()) {
global $wpdb;
$table_name = $wpdb->prefix . 'flex_perm_user_groups';
$defaults = array(
'expires_at' => null,
'assigned_by' => get_current_user_id()
);
$data = wp_parse_args($args, $defaults);
$data['user_id'] = $user_id;
$data['group_id'] = $group_id;
// 检查是否已存在
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $table_name WHERE user_id = %d AND group_id = %d",
$user_id, $group_id
));
if ($existing) {
// 更新现有记录
$result = $wpdb->update(
$table_name,
array('expires_at' => $data['expires_at']),
array('id' => $existing)
);
} else {
// 插入新记录
$result = $wpdb->insert($table_name, $data);
}
// 清除用户权限缓存
$this->clear_user_permissions_cache($user_id);
return (bool)$result;
}
/**
* 获取用户的权限组
* @param int $user_id 用户ID
* @param bool $include_expired 是否包含已过期的
* @return array 用户权限组列表
*/
public function get_user_groups($user_id, $include_expired = false) {
global $wpdb;
$groups_table = $wpdb->prefix . 'flex_perm_groups';
$user_groups_table = $wpdb->prefix . 'flex_perm_user_groups';
$query = "SELECT g.*, ug.expires_at, ug.assigned_at
FROM $groups_table g
INNER JOIN $user_groups_table ug ON g.id = ug.group_id
WHERE ug.user_id = %d";
$params = array($user_id);
if (!$include_expired) {
$query .= " AND (ug.expires_at IS NULL OR ug.expires_at >= %s)";
$params[] = current_time('mysql');
}
$query .= " ORDER BY g.group_name ASC";
return $wpdb->get_results($wpdb->prepare($query, $params));
}
4.2 核心权限检查逻辑
/**
* 检查用户权限的核心方法
* @param array $allcaps 用户所有权限
* @param array $caps 需要的权限
* @param array $args 额外参数
* @param WP_User $user 用户对象
* @return array 更新后的权限数组
*/
public function check_flex_permissions($allcaps, $caps, $args, $user) {
// 如果是超级管理员,直接返回所有权限
if (is_super_admin($user->ID)) {
return $allcaps;
}
// 获取用户的所有权限组
$user_groups = $this->get_user_groups($user->ID);
if (empty($user_groups)) {
return $allcaps;
}
// 收集所有权限组的规则
$group_rules = array();
foreach ($user_groups as $group) {
$rules = $this->get_group_rules($group->id);
$group_rules = array_merge($group_rules, $rules);
}
// 按优先级排序
usort($group_rules, function($a, $b) {
return $a->priority - $b->priority;
});
// 应用权限规则
foreach ($group_rules as $rule) {
// 检查权限是否匹配
if (in_array($rule->capability, $caps)) {
// 检查条件
if ($this->check_rule_conditions($rule, $args)) {
$allcaps[$rule->capability] = (bool)$rule->allowed;
}
}
}
return $allcaps;
}
/**
* 检查规则条件
* @param object $rule 权限规则
* @param array $args 检查参数
* @return bool 是否满足条件
*/
private function check_rule_conditions($rule, $args) {
if (empty($rule->conditions)) {
return true;
}
$conditions = $rule->conditions;
// 检查文章类型条件
if (!empty($conditions['post_type']) && !empty($args[2])) {
$post = get_post($args[2]);
if ($post && $post->post_type !== $conditions['post_type']) {
return false;
}
}
// 检查分类法条件
if (!empty($conditions['taxonomy']) && !empty($args[2])) {
$post = get_post($args[2]);
if ($post) {
$terms = wp_get_post_terms($post->ID, $conditions['taxonomy']);
if (empty($terms)) {
return false;
}
}
}
// 检查时间条件
if (!empty($conditions['time_restriction'])) {
$current_hour = (int)current_time('H');
if ($current_hour < $conditions['time_restriction']['start'] ||
$current_hour > $conditions['time_restriction']['end']) {
return false;
}
}
return true;
}
五、管理界面实现
5.1 添加管理菜单
/**
* 添加管理菜单
*/
public function add_admin_menu() {
// 主菜单
add_menu_page(
__('柔性权限管理', 'flex-permissions'),
__('权限管理', 'flex-permissions'),
'manage_options',
'flex-permissions',
array($this, 'render_admin_page'),
'dashicons-groups',
30
);
// 子菜单
add_submenu_page(
'flex-permissions',
__('权限组管理', 'flex-permissions'),
__('权限组', 'flex-permissions'),
'manage_options',
'flex-permissions-groups',
array($this, 'render_groups_page')
);
add_submenu_page(
'flex-permissions',
flex-permissions'),
__('用户分配', 'flex-permissions'),
'manage_options',
'flex-permissions-users',
array($this, 'render_users_page')
);
add_submenu_page(
'flex-permissions',
__('权限规则', 'flex-permissions'),
__('规则设置', 'flex-permissions'),
'manage_options',
'flex-permissions-rules',
array($this, 'render_rules_page')
);
add_submenu_page(
'flex-permissions',
__('系统设置', 'flex-permissions'),
__('设置', 'flex-permissions'),
'manage_options',
'flex-permissions-settings',
array($this, 'render_settings_page')
);
}
/**
- 渲染权限组管理页面
*/
public function render_groups_page() {
// 检查权限
if (!current_user_can('manage_options')) {
wp_die(__('您没有权限访问此页面。', 'flex-permissions'));
}
// 处理表单提交
$this->handle_group_form_submit();
// 获取所有权限组
$groups = $this->get_permission_groups();
?>
<div class="wrap">
<h1 class="wp-heading-inline"><?php _e('权限组管理', 'flex-permissions'); ?></h1>
<a href="#" class="page-title-action" id="add-new-group"><?php _e('添加新权限组', 'flex-permissions'); ?></a>
<hr class="wp-header-end">
<!-- 添加/编辑权限组表单 -->
<div id="group-form-container" style="display: none;">
<h2><?php _e('权限组信息', 'flex-permissions'); ?></h2>
<form method="post" action="">
<?php wp_nonce_field('flex_permissions_group_action', 'flex_permissions_nonce'); ?>
<input type="hidden" name="action" value="save_group">
<input type="hidden" name="group_id" id="group_id" value="0">
<table class="form-table">
<tr>
<th scope="row">
<label for="group_name"><?php _e('组名称', 'flex-permissions'); ?></label>
</th>
<td>
<input type="text" name="group_name" id="group_name" class="regular-text" required>
<p class="description"><?php _e('权限组的显示名称', 'flex-permissions'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="group_slug"><?php _e('组标识', 'flex-permissions'); ?></label>
</th>
<td>
<input type="text" name="group_slug" id="group_slug" class="regular-text" required>
<p class="description"><?php _e('唯一的英文标识符,只能包含小写字母、数字和连字符', 'flex-permissions'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="description"><?php _e('描述', 'flex-permissions'); ?></label>
</th>
<td>
<textarea name="description" id="description" rows="3" class="large-text"></textarea>
<p class="description"><?php _e('权限组的详细描述', 'flex-permissions'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="is_default"><?php _e('默认组', 'flex-permissions'); ?></label>
</th>
<td>
<input type="checkbox" name="is_default" id="is_default" value="1">
<label for="is_default"><?php _e('设为新用户的默认权限组', 'flex-permissions'); ?></p>
</td>
</tr>
</table>
<p class="submit">
<button type="submit" class="button button-primary"><?php _e('保存权限组', 'flex-permissions'); ?></button>
<button type="button" class="button" id="cancel-group-form"><?php _e('取消', 'flex-permissions'); ?></button>
</p>
</form>
</div>
<!-- 权限组列表 -->
<h2><?php _e('现有权限组', 'flex-permissions'); ?></h2>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th scope="col" class="manage-column column-primary"><?php _e('组名称', 'flex-permissions'); ?></th>
<th scope="col"><?php _e('标识', 'flex-permissions'); ?></th>
<th scope="col"><?php _e('描述', 'flex-permissions'); ?></th>
<th scope="col"><?php _e('默认', 'flex-permissions'); ?></th>
<th scope="col"><?php _e('用户数', 'flex-permissions'); ?></th>
<th scope="col"><?php _e('操作', 'flex-permissions'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($groups)): ?>
<tr>
<td colspan="6"><?php _e('暂无权限组', 'flex-permissions'); ?></td>
</tr>
<?php else: ?>
<?php foreach ($groups as $group): ?>
<?php $user_count = $this->get_group_user_count($group->id); ?>
<tr>
<td class="column-primary">
<strong><?php echo esc_html($group->group_name); ?></strong>
<div class="row-actions">
<span class="edit">
<a href="#" class="edit-group" data-group-id="<?php echo $group->id; ?>"><?php _e('编辑', 'flex-permissions'); ?></a> |
</span>
<span class="rules">
<a href="<?php echo admin_url('admin.php?page=flex-permissions-rules&group_id=' . $group->id); ?>"><?php _e('规则', 'flex-permissions'); ?></a> |
</span>
<span class="delete">
<a href="#" class="delete-group" data-group-id="<?php echo $group->id; ?>" data-group-name="<?php echo esc_attr($group->group_name); ?>"><?php _e('删除', 'flex-permissions'); ?></a>
</span>
</div>
</td>
<td><?php echo esc_html($group->group_slug); ?></td>
<td><?php echo esc_html($group->description); ?></td>
<td><?php echo $group->is_default ? __('是', 'flex-permissions') : __('否', 'flex-permissions'); ?></td>
<td><?php echo $user_count; ?></td>
<td>
<a href="<?php echo admin_url('admin.php?page=flex-permissions-users&group_id=' . $group->id); ?>" class="button button-small"><?php _e('分配用户', 'flex-permissions'); ?></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// 显示添加表单
$('#add-new-group').on('click', function(e) {
e.preventDefault();
$('#group-form-container').slideDown();
$('#group_id').val('0');
$('#group_name').val('');
$('#group_slug').val('');
$('#description').val('');
$('#is_default').prop('checked', false);
});
// 取消表单
$('#cancel-group-form').on('click', function() {
$('#group-form-container').slideUp();
});
// 编辑权限组
$('.edit-group').on('click', function(e) {
e.preventDefault();
var groupId = $(this).data('group-id');
// 这里应该通过AJAX获取权限组数据
// 为简化示例,我们假设数据已加载
$('#group-form-container').slideDown();
// 实际开发中需要通过AJAX加载数据
});
// 删除权限组
$('.delete-group').on('click', function(e) {
e.preventDefault();
var groupId = $(this).data('group-id');
var groupName = $(this).data('group-name');
if (confirm('确定要删除权限组 "' + groupName + '" 吗?')) {
// 发送删除请求
$.post(ajaxurl, {
action: 'delete_flex_permissions_group',
group_id: groupId,
nonce: '<?php echo wp_create_nonce('flex_permissions_ajax'); ?>'
}, function(response) {
if (response.success) {
location.reload();
} else {
alert(response.data);
}
});
}
});
});
</script>
<?php
}
/**
- 处理权限组表单提交
*/
private function handle_group_form_submit() {
if (!isset($_POST['flex_permissions_nonce']) ||
!wp_verify_nonce($_POST['flex_permissions_nonce'], 'flex_permissions_group_action')) {
return;
}
if ($_POST['action'] !== 'save_group') {
return;
}
$group_data = array(
'group_name' => sanitize_text_field($_POST['group_name']),
'group_slug' => sanitize_title($_POST['group_slug']),
'description' => sanitize_textarea_field($_POST['description']),
'is_default' => isset($_POST['is_default']) ? 1 : 0
);
$group_id = isset($_POST['group_id']) ? intval($_POST['group_id']) : 0;
if ($group_id > 0) {
// 更新现有权限组
$this->update_permission_group($group_id, $group_data);
$message = __('权限组更新成功!', 'flex-permissions');
} else {
// 添加新权限组
$this->add_permission_group($group_data);
$message = __('权限组添加成功!', 'flex-permissions');
}
// 显示成功消息
add_action('admin_notices', function() use ($message) {
?>
<div class="notice notice-success is-dismissible">
<p><?php echo $message; ?></p>
</div>
<?php
});
}
### 5.2 用户分配界面
/**
- 渲染用户分配页面
*/
public function render_users_page() {
if (!current_user_can('manage_options')) {
wp_die(__('您没有权限访问此页面。', 'flex-permissions'));
}
$group_id = isset($_GET['group_id']) ? intval($_GET['group_id']) : 0;
$current_group = $group_id ? $this->get_permission_group($group_id) : null;
?>
<div class="wrap">
<h1><?php _e('用户权限分配', 'flex-permissions'); ?></h1>
<!-- 选择权限组 -->
<div class="card">
<h2 class="title"><?php _e('选择权限组', 'flex-permissions'); ?></h2>
<form method="get" action="">
<input type="hidden" name="page" value="flex-permissions-users">
<select name="group_id" id="select-group">
<option value="0"><?php _e('-- 选择权限组 --', 'flex-permissions'); ?></option>
<?php
$groups = $this->get_permission_groups();
foreach ($groups as $group) {
$selected = $group->id == $group_id ? 'selected' : '';
echo '<option value="' . $group->id . '" ' . $selected . '>' . esc_html($group->group_name) . '</option>';
}
?>
</select>
<button type="submit" class="button"><?php _e('选择', 'flex-permissions'); ?></button>
</form>
</div>
<?php if ($current_group): ?>
<div class="card">
<h2><?php echo sprintf(__('为 "%s" 分配用户', 'flex-permissions'), esc_html($current_group->group_name)); ?></h2>
<!-- 添加用户到权限组 -->
<h3><?php _e('添加用户', 'flex-permissions'); ?></h3>
<form method="post" action="" class="add-user-form">
<?php wp_nonce_field('flex_permissions_user_action', 'flex_permissions_user_nonce'); ?>
<input type="hidden" name="action" value="add_user_to_group">
<input type="hidden" name="group_id" value="<?php echo $group_id; ?>">
<table class="form-table">
<tr>
<th scope="row">
<label for="user_search"><?php _e('搜索用户', 'flex-permissions'); ?></label>
</th>
<td>
<input type="text" name="user_search" id="user_search" class="regular-text" placeholder="<?php _e('输入用户名或邮箱', 'flex-permissions'); ?>">
<div id="user-search-results" style="display: none;"></div>
</td>
</tr>
<tr>
<th scope="row">
<label for="expires_at"><?php _e('过期时间', 'flex-permissions'); ?></label>
</th>
<td>
<input type="datetime-local" name="expires_at" id="expires_at">
<p class="description"><?php _e('留空表示永不过期', 'flex-permissions'); ?></p>
</td>
</tr>
</table>
<p class="submit">
<button type="submit" class="button button-primary"><?php _e('添加用户', 'flex-permissions'); ?></button>
</p>
</form>
<!-- 当前组内用户列表 -->
<h3><?php _e('已分配用户', 'flex-permissions'); ?></h3>
<?php
$users = $this->get_group_users($group_id);
if (empty($users)):
?>
<p><?php _e('暂无用户分配到此权限组。', 'flex-permissions'); ?></p>
<?php else: ?>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th><?php _e('用户名', 'flex-permissions'); ?></th>
<th><?php _e('姓名', 'flex-permissions'); ?></th>
<th><?php _e('邮箱', 'flex-permissions'); ?></th>
<th><?php _e('分配时间', 'flex-permissions'); ?></th>
<th><?php _e('过期时间', 'flex-permissions'); ?></th>
<th><?php _e('操作', 'flex-permissions'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?php echo esc_html($user->user_login); ?></td>
<td><?php echo esc_html($user->display_name); ?></td>
<td><?php echo esc_html($user->user_email); ?></td>
<td><?php echo date_i18n(get_option('date_format'), strtotime($user->assigned_at)); ?></td>
<td>
<?php if ($user->expires_at): ?>
<?php echo date_i18n(get_option('date_format'), strtotime($user->expires_at)); ?>
<?php if (strtotime($user->expires_at) < current_time('timestamp')): ?>
<span class="dashicons dashicons-warning" style="color: #dc3232;" title="<?php _e('已过期', 'flex-permissions'); ?>"></span>
<?php endif; ?>
<?php else: ?>
<?php _e('永不过期', 'flex-permissions'); ?>
<?php endif; ?>
</td>
<td>
<form method="post" action="" style="display: inline;">
<?php wp_nonce_field('flex_permissions_user_action', 'flex_permissions_user_nonce'); ?>
<input type="hidden" name="action" value="remove_user_from_group">
<input type="hidden" name="group_id" value="<?php echo $group_id; ?>">
<input type="hidden" name="user_id" value="<?php echo $user->ID; ?>">
<button type="submit" class="button button-small button-link-delete"><?php _e('移除', 'flex-permissions'); ?></button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// 用户搜索功能
$('#user_search').on('keyup', function() {
var searchTerm = $(this).val();
if (searchTerm.length < 2) {
$('#user-search-results').hide().empty();
return;
}
$.post(ajaxurl, {
action: 'search_flex_permissions_users',
search: searchTerm,
group_id: <?php echo $group_id; ?>,
nonce: '<?php echo wp_create_nonce('flex_permissions_ajax'); ?>'
}, function(response) {
if (response.success && response.data.length > 0) {
var html = '<ul>';
$.each(response.data, function(index, user) {
html += '<li><a href="#" class="select-user" data-user-id="' + user.id + '" data-user-name="' + user.name + '">' + user.name + ' (' + user.email + ')</a></li>';
});
html += '</ul>';
$('#user-search-results').html(html).show();
} else {
$('#user-search-results').hide().empty();
}
});
});
// 选择用户
$(document).on('click', '.select-user', function
