Skip to content

[Bug] "Users Currently Online" widget shows the same user multiple times #191

@parhumm

Description

@parhumm

Problem Description

The "Users Currently Online" widget (slim_p1_18) displays the same logged-in user multiple times — once for each page they've visited within the last 5 minutes. A user who visited 4 pages in the current session appears 4 times in the widget instead of once.

There is also a secondary bug in get_top() at wp-slimstat-db.php:1173: the expression empty($_column['use_date_filters']) evaluates to true when use_date_filters => false is passed (since empty(false) === true in PHP), silently ignoring the false value and applying the global date range filter on top of the custom 5-minute WHERE clause. This means the widget may return zero results when the user is viewing a historical date range in the dashboard.

Impact

  • Dashboard widget "Users Currently Online" is factually incorrect — it shows pageview counts instead of unique user counts.
  • Multiple identical usernames inflate the apparent count (e.g., 1 user → 4 entries, showing "1–4 of 4" in pagination).
  • Widget becomes unusable in high-traffic periods. Staff monitoring live activity get a misleading picture of who is actually online.

Steps to Reproduce

  1. Log in to WordPress as any user (e.g., shahab)
  2. Visit at least 2 different pages on the frontend within a 5-minute window
  3. Navigate to the SlimStat dashboard and open the "Users Currently Online" widget
  4. Observe: the same username appears once per page visited, not once per user

Expected Behavior

Each unique logged-in user should appear exactly once in the widget, regardless of how many pages they visited within the 5-minute window. The widget should function as a unique-user count, not a pageview list.

Actual Behavior

The same username is repeated for every pageview. A single user who visited 4 pages within 5 minutes appears 4 times. The pagination reads "Showing 1–4 of 4" for a single user.

Root Cause Analysis

Bug 1 (primary): wrong data source in slim_p1_18

admin/view/wp-slimstat-reports.php:254–268 uses get_recent() with type => 'recent'. get_recent() returns one row per matching row in slim_stats — no aggregation, no GROUP BY. For "Users Currently Online," the correct function is get_top() which issues GROUP BY {column} ... COUNT(*) AS counthits, deduplicating per username.

Bug 2 (secondary): empty(false) in get_top() ignores use_date_filters = false

admin/view/wp-slimstat-db.php:1173:

// Buggy: empty(false) === true in PHP → use_date_filters=false silently becomes true
$_use_date_filters = empty($_column['use_date_filters']) ? true : $_column['use_date_filters'];

// Fixed:
$_use_date_filters = isset($_column['use_date_filters']) ? (bool)$_column['use_date_filters'] : true;

When slim_p1_18 is switched to get_top() with use_date_filters => false, this secondary bug causes the global date range filter to be AND-ed with the custom 5-minute WHERE clause, potentially hiding currently-online users when a historical date range is selected in the dashboard.

Proposed Fix

File 1: admin/view/wp-slimstat-db.php:1173

// Before (buggy):
$_use_date_filters = empty($_column['use_date_filters']) ? true : $_column['use_date_filters'];

// After (fixed):
$_use_date_filters = isset($_column['use_date_filters']) ? (bool)$_column['use_date_filters'] : true;

File 2: admin/view/wp-slimstat-reports.php:254–268

// Before (buggy — uses get_recent, no dedup):
'callback_args' => [
    'type'             => 'recent',
    'columns'          => 'username',
    'where'            => '(dt_out > ' . (date_i18n('U') - 300) . ') OR (dt > ' . (date_i18n('U') - 300) . ')',
    'use_date_filters' => false,
    'raw'              => ['wp_slimstat_db', 'get_recent'],
],

// After (fixed — get_top with GROUP BY username):
'callback_args' => [
    'type'             => 'top',
    'columns'          => 'username',
    'where'            => '((dt_out > ' . (date_i18n('U') - 300) . ') OR (dt > ' . (date_i18n('U') - 300) . ')) AND username IS NOT NULL AND username <> ""',
    'use_date_filters' => false,
    'raw'              => ['wp_slimstat_db', 'get_top'],
],

Code References

File Lines Description
admin/view/wp-slimstat-reports.php 254–268 slim_p1_18 "Users Currently Online" — bug location (uses get_recent, no dedup)
admin/view/wp-slimstat-db.php 1173 empty(false) bug in get_top()use_date_filters=false silently ignored
admin/view/wp-slimstat-db.php 1054–1084 get_recent() — returns all rows, no aggregation
admin/view/wp-slimstat-db.php 1157–1226 get_top() — correct function with GROUP BY and counthits

Environment

Field Value
Tech Stack WordPress (PHP)
Runtime PHP 8.5.0, WP-CLI 2.12.0
OS Darwin 25.1.0 arm64
Branch development
Plugin Version wp-slimstat 5.4.3

Reported via: qa-issue-report skill (jaan.to plugin)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions