You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 13:45:17