如何为WordPress用户表按Newsletter列表筛选并排序自定义列
实现WordPress用户列表的邮件列表筛选与自定义列排序
一、修复筛选器表单的小问题
你现有代码里的$user_id未定义,会导致报错,先删除这行无用代码:
// 移除该行,$user_id在此处未定义且当前函数无需获取单个订阅者 $subscriber = $newsletter->get_user(get_userdata($user_id)->user_email);
二、实现特定邮件列表的用户筛选
由于订阅数据存在wp_newsletter表,需要通过pre_user_query钩子修改WP_User_Query的SQL语句,关联该表完成筛选:
1. 添加筛选逻辑钩子
add_action('pre_user_query', 'filter_users_by_newsletter_list'); function filter_users_by_newsletter_list($query) { global $pagenow; // 仅在用户列表页面生效,且存在合法筛选参数时执行 if ($pagenow !== 'users.php' || empty($_GET['group'])) { return; } $list_key = sanitize_text_field($_GET['group']); // 验证参数格式,防止SQL注入 if (!preg_match('/^list_[0-9]+$/', $list_key)) { return; } global $wpdb; // 关联wp_newsletter表,筛选对应列表订阅状态为1的用户 $query->query_from .= " INNER JOIN {$wpdb->prefix}newsletter n ON {$wpdb->users}.user_email = n.email"; $query->query_where .= $wpdb->prepare(" AND n.$list_key = %d", 1); // 兼容原有搜索条件 if (!empty($query->query_vars['search'])) { $search_clause = $wpdb->prepare("({$wpdb->users}.user_login LIKE %s OR {$wpdb->users}.user_email LIKE %s OR {$wpdb->users}.user_nicename LIKE %s)", '%' . $wpdb->esc_like($query->query_vars['search']) . '%', '%' . $wpdb->esc_like($query->query_vars['search']) . '%', '%' . $wpdb->esc_like($query->query_vars['search']) . '%' ); $query->query_where = str_replace('WHERE 1=1', "WHERE 1=1 AND $search_clause", $query->query_where); } }
2. 保留筛选状态的URL参数
修改筛选表单,添加隐藏字段保留现有GET参数(如搜索关键词、分页参数),避免筛选后分页/排序丢失条件:
// 在<form>标签内添加以下代码 <?php foreach ($_GET as $key => $value) { if ($key !== 'group' && $key !== 'submit') { echo '<input type="hidden" name="' . esc_attr($key) . '" value="' . esc_attr($value) . '">'; } } ?>
三、实现自定义列的字母排序
假设你的自定义列键名为newsletter_lists,按以下步骤实现排序:
1. 标记自定义列为可排序
add_filter('manage_users_sortable_columns', 'make_newsletter_list_column_sortable'); function make_newsletter_list_column_sortable($columns) { // 替换为你实际的自定义列键名 $columns['newsletter_lists'] = 'newsletter_list_name'; return $columns; }
2. 处理排序逻辑
在之前的filter_users_by_newsletter_list函数中添加排序处理,通过CASE语句将订阅状态转化为列表名称,再进行排序:
// 在filter_users_by_newsletter_list函数内,筛选逻辑之后添加以下代码 // 处理排序:如果排序键为自定义的newsletter_list_name if ($query->query_vars['orderby'] === 'newsletter_list_name') { global $wpdb; // 若未关联newsletter表,先执行关联 if (strpos($query->query_from, "{$wpdb->prefix}newsletter") === false) { $query->query_from .= " LEFT JOIN {$wpdb->prefix}newsletter n ON {$wpdb->users}.user_email = n.email"; } $lists = get_option("newsletter_subscription_lists"); // 构建CASE语句,将list_x的1/0映射为对应列表名称 $case_sql = "CASE "; foreach ($lists as $key => $label) { if (preg_match('/^list_[0-9]+$/', $key)) { $case_sql .= $wpdb->prepare("WHEN n.$key = 1 THEN %s ", $label); } } $case_sql .= "ELSE '' END"; $order = esc_sql($query->query_vars['order']); // 设置排序规则,兼容多列表用户的排序 $query->query_orderby = " ORDER BY $case_sql $order, {$wpdb->users}.user_login $order"; }
四、完整代码整合
将所有代码添加到主题functions.php或自定义插件中:
// 渲染筛选器表单 add_action( 'manage_users_extra_tablenav', 'render_custom_filter_options' ); function render_custom_filter_options() { $newsletter = Newsletter::instance(); $lists = get_option("newsletter_subscription_lists"); // 过滤有效列表 $pattern = "/list_[0-9]+$/"; foreach ($lists as $key => $entry) { if(!preg_match($pattern,$key) || empty($entry)) { unset($lists[$key]); } } ?> <form method="GET" class="alignleft actions"> <?php // 保留现有GET参数 foreach ($_GET as $key => $value) { if ($key !== 'group' && $key !== 'submit') { echo '<input type="hidden" name="' . esc_attr($key) . '" value="' . esc_attr($value) . '">'; } } ?> <select name="group"> <option value="">Gruppen filtern</option> <?php foreach ( $lists as $value => $label ): ?> <option value="<?php echo esc_attr( $value ); ?>" <?php selected($_GET["group"], $value); ?>><?php echo esc_html( $label ); ?></option> <?php endforeach; ?> </select> <input type="submit" class="button" value="Filter"> </form> <?php } // 处理筛选和排序逻辑 add_action('pre_user_query', 'filter_users_by_newsletter_list'); function filter_users_by_newsletter_list($query) { global $pagenow; if ($pagenow !== 'users.php') { return; } global $wpdb; $has_join = strpos($query->query_from, "{$wpdb->prefix}newsletter") !== false; // 处理筛选 if (!empty($_GET['group'])) { $list_key = sanitize_text_field($_GET['group']); if (!preg_match('/^list_[0-9]+$/', $list_key)) { return; } if (!$has_join) { $query->query_from .= " INNER JOIN {$wpdb->prefix}newsletter n ON {$wpdb->users}.user_email = n.email"; $has_join = true; } $query->query_where .= $wpdb->prepare(" AND n.$list_key = %d", 1); // 兼容搜索条件 if (!empty($query->query_vars['search'])) { $search_clause = $wpdb->prepare("({$wpdb->users}.user_login LIKE %s OR {$wpdb->users}.user_email LIKE %s OR {$wpdb->users}.user_nicename LIKE %s)", '%' . $wpdb->esc_like($query->query_vars['search']) . '%', '%' . $wpdb->esc_like($query->query_vars['search']) . '%', '%' . $wpdb->esc_like($query->query_vars['search']) . '%' ); $query->query_where = str_replace('WHERE 1=1', "WHERE 1=1 AND $search_clause", $query->query_where); } } // 处理排序 if ($query->query_vars['orderby'] === 'newsletter_list_name') { if (!$has_join) { $query->query_from .= " LEFT JOIN {$wpdb->prefix}newsletter n ON {$wpdb->users}.user_email = n.email"; } $lists = get_option("newsletter_subscription_lists"); $case_sql = "CASE "; foreach ($lists as $key => $label) { if (preg_match('/^list_[0-9]+$/', $key)) { $case_sql .= $wpdb->prepare("WHEN n.$key = 1 THEN %s ", $label); } } $case_sql .= "ELSE '' END"; $order = esc_sql($query->query_vars['order']); $query->query_orderby = " ORDER BY $case_sql $order, {$wpdb->users}.user_login $order"; } } // 标记自定义列为可排序 add_filter('manage_users_sortable_columns', 'make_newsletter_list_column_sortable'); function make_newsletter_list_column_sortable($columns) { // 替换为你实际的自定义列键名 $columns['newsletter_lists'] = 'newsletter_list_name'; return $columns; }
注意事项
- 将代码中的
newsletter_lists替换为你实际添加的自定义列键名。 - 代码已通过
$wpdb->prepare、sanitize_text_field等方法做了SQL注入防护,可安全使用。 - 若用户属于多个邮件列表,排序逻辑会取第一个匹配的列表名称,可根据需求调整CASE语句实现多列表名称拼接排序。
内容的提问来源于stack exchange,提问作者rnsrv
相关产品推荐
相关产品推荐

