Hooks and filters
The plugin exposes an extension surface focused on the capture pipeline, the notification flow, the bot filter, and the admin panel structure.
Actions
Section titled “Actions”bp_profile_views_after_insert
Section titled “bp_profile_views_after_insert”Fired immediately after a view row is inserted into {prefix}bp_profile_views.
do_action( 'bp_profile_views_after_insert', $insert_id, $user_id, $viewer_id );| Param | Type | Description |
|---|---|---|
$insert_id |
int |
The $wpdb->insert_id of the new row. |
$user_id |
int |
Profile owner (the person whose profile was viewed). |
$viewer_id |
int |
Visitor. 0 for logged-out visitors. |
The plugin’s own bp_profile_views_notification() callback is hooked here at priority 10. Add your own listener to forward view events to an analytics endpoint, queue a job, or trigger custom logic:
add_action( 'bp_profile_views_after_insert', function ( $row_id, $user_id, $viewer_id ) { // Example: push to an external stats service. my_stats_track( 'profile_view', $user_id, $viewer_id ); }, 20, 3);Filters
Section titled “Filters”bpv_notification_views_interval_day
Section titled “bpv_notification_views_interval_day”Controls the dedupe window for the “notify on view” feature. The plugin passes a MySQL INTERVAL expression string and interpolates it directly into a NOW() - INTERVAL {value} clause. Return a valid MySQL interval unit string.
$notify_day = apply_filters( 'bpv_notification_views_interval_day', $notify_day );| Param | Type | Default | Description |
|---|---|---|---|
$notify_day |
string |
'1 DAY' |
MySQL interval expression passed to NOW() - INTERVAL. |
This filter only runs when allow_user_notification is 'yes' in General settings. If notifications are disabled, this filter is never called.
// One notification per week per viewer/profile pair.add_filter( 'bpv_notification_views_interval_day', function () { return '7 DAY';} );
// Once per month.add_filter( 'bpv_notification_views_interval_day', function () { return '1 MONTH';} );
// Conditional: longer window on a quieter site.add_filter( 'bpv_notification_views_interval_day', function ( $interval ) { return get_option( 'site_low_activity' ) === 'yes' ? '14 DAY' : $interval;} );bp_profile_views_is_bot
Section titled “bp_profile_views_is_bot”Short-circuits the built-in user-agent bot detector. Return true to treat the current request as a bot (skip recording the view), false to force-count it regardless of UA, or null to fall through to the built-in UA pattern matching.
$override = apply_filters( 'bp_profile_views_is_bot', null );| Param | Type | Default | Description |
|---|---|---|---|
$override |
bool|null |
null |
true = bot, false = human, null = use UA patterns. |
// Plug in a third-party bot-detection service.add_filter( 'bp_profile_views_is_bot', function ( $override ) { if ( is_bool( $override ) ) { return $override; // Already decided. } return my_bot_detection_service()->is_bot();} );
// Force-count a known monitoring UA that the built-in list would block.add_filter( 'bp_profile_views_is_bot', function ( $override ) { $ua = isset( $_SERVER['HTTP_USER_AGENT'] ) ? (string) $_SERVER['HTTP_USER_AGENT'] : ''; if ( false !== strpos( $ua, 'MyStatusCheckBot/1.0' ) ) { return false; } return $override;} );bp_profile_views_bot_user_agents
Section titled “bp_profile_views_bot_user_agents”Filters the list of lowercase UA substrings used by the built-in bot detector. Incoming user-agent strings are matched against each pattern with strpos(). Any match marks the request as a bot and prevents a view from being recorded.
$patterns = apply_filters( 'bp_profile_views_bot_user_agents', $patterns );| Param | Type | Description |
|---|---|---|
$patterns |
string[] |
Lowercase substrings. Default list includes 'bot', 'crawler', 'spider', 'ahrefs', 'semrushbot', 'curl', and ~20 others. |
// Add an in-house crawler to the blocklist.add_filter( 'bp_profile_views_bot_user_agents', function ( $patterns ) { $patterns[] = 'mycrawler'; return $patterns;} );
// Remove a pattern that causes false positives on your stack.add_filter( 'bp_profile_views_bot_user_agents', function ( $patterns ) { return array_values( array_filter( $patterns, fn( $p ) => $p !== 'monitoring' ) );} );bp_profile_views_filter_by
Section titled “bp_profile_views_filter_by”Sets the default chart period when no filter_by query-string parameter is present on the Views sub-tab. Applied in both the Legacy and Nouveau template partials.
$filter_by = apply_filters( 'bp_profile_views_filter_by', 'all' );| Param | Type | Default | Description |
|---|---|---|---|
$filter_by |
string |
'all' |
Chart period. Accepted values: 'all', '7', '30', '365'. The numeric values represent a day count; 'all' shows the complete history. |
The template renders four <select> options whose value attributes are exactly these strings. The PHP query uses strtotime('-' . ($filter_by - 1) . ' days'), so any non-numeric value other than 'all' will produce garbled arithmetic and return no rows.
// Default to the last 30 days instead of all-time.add_filter( 'bp_profile_views_filter_by', function () { return '30';} );
// Default to the last 7 days.add_filter( 'bp_profile_views_filter_by', function () { return '7';} );bpv_admin_tabs
Section titled “bpv_admin_tabs”Filters the admin sidebar tab array before rendering. Use this to add, remove, or reorder tabs in the plugin settings panel (1.5.0 and later).
$tabs = apply_filters( 'bpv_admin_tabs', $tabs );| Param | Type | Description |
|---|---|---|
$tabs |
array |
Keyed by tab slug. Each entry is ['label' => string, 'icon' => string, 'group' => string]. Groups: 'main', 'settings', 'account', 'resources'. |
Default tabs by group:
| Slug | Label | Group |
|---|---|---|
overview |
Overview | main |
members |
Members Views | main |
discover |
Discover | main |
general |
General | settings |
display |
Display | settings |
license |
License | account |
help |
Help & Docs | account |
The sidebar also renders a Resources group containing an outbound Documentation link. That is not a tab and is not in this array — see bpv_admin_help_links below.
// Add a custom tab.add_filter( 'bpv_admin_tabs', function ( $tabs ) { $tabs['my-custom-tab'] = array( 'label' => __( 'My Settings', 'my-plugin' ), 'icon' => 'dashicons-admin-tools', 'group' => 'settings', ); return $tabs;} );
// Remove the License tab for managed/agency installs.add_filter( 'bpv_admin_tabs', function ( $tabs ) { unset( $tabs['license'] ); return $tabs;} );bpv_admin_help_links
Section titled “bpv_admin_help_links”Filters the URLs used on the Help & Docs admin tab and the sidebar Resources → Documentation link (1.5.3 and later). Both read the same map via Bpv_Admin::get_help_links(), so one filter re-points every documentation link at once. Re-point them for white-label installs or an internal help desk without forking.
$bpv_help_links = apply_filters( 'bpv_admin_help_links', $bpv_help_links );| Key | Default |
|---|---|
docs |
Documentation home |
getting |
Getting-started guide |
product |
Product page |
support |
Support / ticket URL |
contact |
Contact URL |
add_filter( 'bpv_admin_help_links', function ( $links ) { $links['support'] = 'https://help.example.com/'; return $links;} );bpv_discover_products
Section titled “bpv_discover_products”Filters the product list shown on the Discover admin tab (1.5.3 and later). Each entry is an array with name, logo (a filename in assets/images/ecosystem/), desc, and url. Return an empty array to blank the tab on white-label installs, or unset discover via bpv_admin_tabs to drop the tab entirely.
$bpv_ecosystem = apply_filters( 'bpv_discover_products', $bpv_ecosystem );add_filter( 'bpv_discover_products', function ( $products ) { return array_values( array_filter( $products, function ( $product ) { return 'Jetonomy' !== $product['name']; } ) );} );bpv_install_catalog
Section titled “bpv_install_catalog”Filters the one-click install catalog behind the Discover tab (1.5.3 and later). Keyed by plugin slug; each entry carries label, item_id (EDD product id), key (free distribution licence), basename, detect (callable), store_url, and optionally license_option.
Only slugs present in this catalog can be installed - the AJAX handler resolves the requested slug against it and returns 404 for anything else, so a request can never name its own package URL.
$catalog = apply_filters( 'bpv_install_catalog', $catalog );add_filter( 'bpv_install_catalog', function ( $catalog ) { unset( $catalog['wb-gamification'] ); return $catalog;} );BuddyPress notification component
Section titled “BuddyPress notification component”The plugin registers its own component for the BP Notifications system. Useful if you query the wp_bp_notifications table directly or build custom notification handlers:
| Field | Value |
|---|---|
| Component name | bp_profile_view_notifications |
| Component action | bp_profile_view_notifications_action |
| Format text | "{display_name} viewed your profile." |
| Notification link | Visitor’s profile URL, nonce-signed for mark-as-read |
The mark-as-read nonce is mark-as-read-notification-{current_user_id}-{viewer_id}. When a profile owner clicks a notification and lands on the viewer’s profile page, the plugin verifies this nonce and marks all matching notifications for that pair as read.
Dedupe is enforced in PHP before any notification is created: the plugin queries wp_bp_notifications for any existing row matching (user_id, secondary_item_id, component_name) within the configured interval. If one is found, no new notification is created.
If the BuddyPress Notifications component is not active, views are still recorded but the notification flow is silently inert.
Programmatic opt-out
Section titled “Programmatic opt-out”To opt a user out of being tracked from code, set the visitor_setting user meta to 'no':
update_user_meta( $user_id, 'visitor_setting', 'no' );The next time that user visits a profile their visit is not recorded. Existing rows are unaffected. To re-enable tracking set the meta back to 'yes'.
Where to next
Section titled “Where to next”- REST and AJAX — AJAX endpoints.
- Database schema — the underlying table.
- Theme overrides — partial overrides for the Views tab and recent-visitors strip.
- Uninstall —
BPV_KEEP_DATA_ON_UNINSTALL.

