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

WordPress pre_get_posts多$query->set失效:作者与自定义字段筛选问题

解决WordPress自定义角色文章可见性的OR条件查询问题

你遇到的问题根源是:直接同时设置author和meta条件时,WordPress会生成AND逻辑的SQL查询——要求文章必须同时满足「作者是当前用户」和「parbandeh_masool=2」,这就导致只有同时符合两个条件的文章才会被显示,自然出现无文章的情况。

要实现「自己的文章 + parbandeh_masool=2的文章」的OR逻辑,有两种可靠的解决方法:


方法1:合并文章ID数组(简单易维护)

通过分别获取两类文章的ID,合并后设置查询仅包含这些ID,逻辑直观,适合大多数场景:

add_action('pre_get_posts', 'restrict_invoicer_post_visibility');
function restrict_invoicer_post_visibility($query) {
    // 仅针对后台文章列表的主查询,且当前用户是invoicer角色
    if (!is_admin() || !$query->is_main_query() || $query->get('post_type') !== 'post' || !current_user_can('invoicer')) {
        return;
    }

    $current_user_id = get_current_user_id();

    // 获取当前用户的所有文章ID(包含草稿、待审等状态)
    $user_post_ids = get_posts([
        'author' => $current_user_id,
        'post_type' => 'post',
        'post_status' => ['publish', 'draft', 'pending', 'future'],
        'fields' => 'ids',
        'numberposts' => -1
    ]);

    // 获取所有parbandeh_masool值为2的文章ID
    $masool_post_ids = get_posts([
        'meta_key' => 'parbandeh_masool',
        'meta_value' => 2,
        'post_type' => 'post',
        'post_status' => ['publish', 'draft', 'pending', 'future'],
        'fields' => 'ids',
        'numberposts' => -1
    ]);

    // 合并并去重ID数组
    $allowed_post_ids = array_unique(array_merge($user_post_ids, $masool_post_ids));

    // 处理空数组情况,避免显示所有文章
    if (empty($allowed_post_ids)) {
        $allowed_post_ids = [0];
    }

    // 设置查询仅包含允许的文章ID
    $query->set('post__in', $allowed_post_ids);
}

方法2:直接修改SQL查询条件(性能更优)

通过钩子修改SQL的WHERE子句和JOIN语句,直接实现OR逻辑,适合文章数量较多的场景:

add_action('pre_get_posts', 'setup_invoicer_post_query');
function setup_invoicer_post_query($query) {
    if (is_admin() && $query->is_main_query() && $query->get('post_type') === 'post' && current_user_can('invoicer')) {
        // 添加WHERE和JOIN钩子
        add_filter('posts_where', 'add_invoicer_or_conditions');
        add_filter('posts_join', 'add_postmeta_table_join');
    }
}

function add_invoicer_or_conditions($where) {
    global $wpdb, $current_user;
    $user_id = $current_user->ID;

    // 移除默认的author强制条件(如果存在)
    $where = preg_replace("/\s*AND?\s*\({$wpdb->posts}\.post_author\s*=\s*'{$user_id}'\)/i", "", $where);
    $where = preg_replace("/^WHERE\s*\({$wpdb->posts}\.post_author\s*=\s*'{$user_id}'\)/i", "WHERE", $where);

    // 添加OR逻辑条件:作者是当前用户 或者 parbandeh_masool=2
    $where .= " AND ({$wpdb->posts}.post_author = '{$user_id}' OR ({$wpdb->postmeta}.meta_key = 'parbandeh_masool' AND {$wpdb->postmeta}.meta_value = '2'))";

    return $where;
}

function add_postmeta_table_join($join) {
    global $wpdb;
    // 确保仅连接一次postmeta表
    if (strpos($join, $wpdb->postmeta) === false) {
        $join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
    }
    return $join;
}

注意事项

  • 替换invoicer为你的实际自定义角色标识
  • 方法1中post_status的取值需和后台文章列表默认显示的状态一致,确保不会遗漏草稿、待审等状态的文章
  • 方法2需注意SQL语句的兼容性,避免和其他查询条件冲突

内容的提问来源于stack exchange,提问作者Ahmad Karimi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:43:18