Appearance
Permissions & Licensing Filters
Capabilities
wpsr_admin_permission
wpsr_admin_permission — The capability required to manage WP Social Ninja
When it runs: Applied when the plugin checks whether the current user may access admin features. Defaults to manage_options.
Parameters:
$cap(string): the required capability (default'manage_options').
Source: app/Services/Helper.php
Usage:
php
add_filter('wpsr_admin_permission', function ($cap) {
return 'edit_others_posts'; // let editors manage WP Social Ninja
});Permission-model filters — readable_permissions, plugin_permissions, user_permissions
When they run: in Services/PermissionManager.php when resolving who can access which features. Use these instead of editing policy classes.
| Filter | Value |
|---|---|
wpsocialreviews/readable_permissions | $permissions |
wpsocialreviews/plugin_permissions | $permissions |
wpsocialreviews/user_permissions | $permissions |
Source: app/Services/PermissionManager.php
wpsocialreviews/settings_platform_capabilities 4.4.0
wpsocialreviews/settings_platform_capabilities — Which capability owns a settings platform
When it runs: Applied in SettingsController::platformCapabilities() when a settings request names a platform. SettingsPolicy gates the whole settings group on any one settings capability, which is wider than any single screen — this map narrows it, so holding one screen's capability reaches only that screen's platforms.
Return the modified platform => [capabilities] array. A platform absent from the map is refused with a 403 Invalid platform., so a hook name is never built from an unrecognised identifier — add your platform here when you register it.
Parameters:
$map(array): platform slug mapped to an array of capability slugs. Core fills feed platforms withwpsn_feeds_platforms_settings, review platforms (including the ones stored inwpsr_available_valid_platforms) withwpsn_reviews_platforms_settings, and adds the aggregate keyreviews.
Source: app/Http/Controllers/SettingsController.php
Usage:
php
add_filter('wpsocialreviews/settings_platform_capabilities', function ($map) {
$map['myplatform'] = ['wpsn_reviews_platforms_settings'];
return $map;
});Visitor request budgets 4.4.0
The public reviews feed endpoint charges each caller against two windows — a short one that allows normal use and a long one that stops a caller who keeps going. Both must pass. Searched and unsearched requests are counted separately, so load-more clicks do not spend the search budget.
WARNING
This is a budget guard, not a security control. Read-then-write is not atomic, so it undercounts under concurrency. Do not rely on it to bound abuse.
Window and limit filters — visitor_search_rate_*, visitor_search_hourly_*
When they run: in Helper::allowVisitorFeedRequest(), once per public feed request. Every value receives $wpsr_is_search as a second argument. Returning 0 for a window or a limit drops that budget entirely.
| Filter | Default | Args |
|---|---|---|
wpsocialreviews/visitor_search_rate_window | 60 | $window, $is_search |
wpsocialreviews/visitor_search_rate_limit | 30 searching, 120 otherwise | $limit, $is_search |
wpsocialreviews/visitor_search_hourly_window | HOUR_IN_SECONDS | $window, $is_search |
wpsocialreviews/visitor_search_hourly_limit | 200 searching, 1200 otherwise | $limit, $is_search |
Counts are stored in transients (wpsr_rl_*), so a site with a persistent object cache never touches the database for this.
Source: app/Services/Platforms/Reviews/Helper.php
Usage:
php
add_filter('wpsocialreviews/visitor_search_rate_limit', function ($limit, $wpsr_is_search) {
if (!$wpsr_is_search) {
return $limit;
}
return 10; // tighter budget for searches only
}, 10, 2);wpsocialreviews/visitor_rate_client_ip_header — Trust a proxy's client-IP header
When it runs: Applied first in Helper::visitorFeedRateKey(). The limiter keys on REMOTE_ADDR, which behind a CDN is the proxy's address — so every visitor shares one bucket. Return a $_SERVER key to read the real client from instead. Default is '' (use REMOTE_ADDR).
Parameters:
$header(string): the$_SERVERkey to read,''by default.
Source: app/Services/Platforms/Reviews/Helper.php
Usage:
php
add_filter('wpsocialreviews/visitor_rate_client_ip_header', function ($header) {
return 'HTTP_CF_CONNECTING_IP';
});DANGER
Forwarded-for headers are client-set unless a proxy overwrites them. Only name a header on an install where a proxy actually rewrites it — otherwise any visitor can mint a fresh budget per request. Core validates the value with FILTER_VALIDATE_IP and falls back to REMOTE_ADDR when it does not parse, but it cannot tell a spoofed valid address from a real one.
X-Forwarded-For is a chain (client, proxy1, proxy2); core takes the first entry.
wpsocialreviews/visitor_search_rate_key — The final bucket identity
When it runs: Applied last in Helper::visitorFeedRateKey(), on the fully-derived key. Return the string to bucket by; returning '' disables the limiter for that caller.
By the time the filter runs, core has already bucketed the address by network (an IPv6 /64 is one allocation, so the full address would mean 2^64 budgets; an IPv4 address is kept whole) and appended |u{user_id} for logged-in visitors, so one office behind a single address does not share a limit.
Parameters:
$key(string): the derived bucket key.
Source: app/Services/Platforms/Reviews/Helper.php
Usage:
php
add_filter('wpsocialreviews/visitor_search_rate_key', function ($key) {
if (is_user_logged_in() && current_user_can('edit_posts')) {
return ''; // no budget for editors
}
return $key;
});Licensing
License filters — wpsr_get_license, wpsr_activate_license, wpsr_deactivate_license
When they run: Core exposes these as unfulfilled filters (they default to false); Pro's PluginManager fulfills them. Only relevant if you are building on the licensing flow.
| Filter | Args |
|---|---|
wpsr_get_license | false, $request |
wpsr_activate_license | false, $request |
wpsr_deactivate_license | false, $request |
Source: app/Http/Controllers/SettingsController.php, app/Services/CLI/Commands.php

