FacetWP AJAX Filter Ignoring User Role – How to Restrict Posts Properly

Introduction:

FacetWP is a powerful tool for creating dynamic, AJAX-powered content filters on WordPress sites. However, you might encounter a common issue: user-based post restrictions disappear when filters are applied through AJAX, causing all posts to appear regardless of your initial constraints. This issue can significantly impact sites that rely heavily on user roles or custom user-based content visibility.

In this post, we’ll discuss why this happens and provide a practical solution to ensure your user-based restrictions remain intact even after AJAX filtering.

Understanding the Problem:

Initially, your FacetWP templates correctly limit displayed posts based on user roles or assigned terms. However, when a filter is activated, FacetWP triggers an AJAX call without user authentication context, causing get_current_user_id() to return zero. This results in FacetWP disregarding your original user-based query, loading all available posts instead.

The Solution:

To address this, we need to access user authentication details directly from WordPress cookies, ensuring we maintain the user context during AJAX requests. Specifically, we can leverage the LOGGED_IN_COOKIE provided by WordPress.

Here’s a concise approach:

$user_id = get_current_user_id();

if (empty($user_id)) {
    if (isset($_COOKIE[LOGGED_IN_COOKIE])) {
        list($username) = explode('|', $_COOKIE[LOGGED_IN_COOKIE]);
        $user = get_user_by('login', $username);
        $user_id = $user ? $user->ID : 0;
    }
}

By extracting the username from LOGGED_IN_COOKIE, we retrieve the correct user object and, consequently, the user ID. This allows us to reapply the appropriate user-specific restrictions to our query arguments.

Practical Example:

Imagine you have a user role called "special_manager," and each manager has specific dealers assigned. Your goal is to show only posts associated with those dealers. Here’s how you can implement this using facetwp_query_args:

function webeng_filter_facetwp_social_images_query($query_args, $class) {
    $user_id = get_current_user_id();
    $user = get_userdata($user_id);

    if (empty($user_id)) {
        if (isset($_COOKIE[LOGGED_IN_COOKIE])) {
            $parts = explode('|', $_COOKIE[LOGGED_IN_COOKIE]);
            $username = $parts[0];
            $user = get_user_by('login', $username);
            $user_id = $user ? $user->ID : 0;
        }
    }

    $roles = $user ? $user->roles : array();

    if (in_array("special_manager", $roles)) {
        $dealers = get_field("dealers", "user_" . $user_id);

        if (!empty($dealers) && is_array($dealers)) {
            $slugs = array_map(function($dealer) {
                return $dealer->slug;
            }, $dealers);

            $query_args['tax_query'][] = [
                'taxonomy' => 'dealer',
                'field' => 'slug',
                'terms' => $slugs,
                'operator' => 'IN'
            ];
        } else {
            $query_args['post__in'] = array(0);
        }
    }

    return $query_args;
}
add_filter('facetwp_query_args', 'webeng_filter_facetwp_social_images_query', 10, 2);

Conclusion:

By retrieving user data directly from the authentication cookie, your FacetWP AJAX filters will consistently respect user-specific restrictions, maintaining both security and relevance in your site’s content display. With this solution, your FacetWP setup remains robust, dynamic, and fully user-aware.