0 Day Analytics – Traffic Analytics Module Developer Documentation
Table of Contents
1. Overview & Architecture
The Traffic Analytics Module provides server-side website analytics for WordPress without external dependencies. It tracks visitors, pageviews, referrers, and technology metrics (browsers, OS, devices) while maintaining data privacy.
Key Capabilities
- Track unique visitors via cookie-based identification
- Record pageviews with full path and query parameter preservation
- Capture referrer data with domain grouping
- Detect device type, browser, and operating system from User-Agent
- Real-time visitor count (last 30 minutes)
- Two tracking methods: server-side (PHP) or client-side (JavaScript)
- High-performance file-based write buffer with batch aggregation
- Automatic data retention with configurable age limits
- SVG-based charts (no external chart library dependencies)
Architecture Overview
┌─────────────────────────────────────────────────────────────────────┐
│ Frontend Request │
└──────────────────────────────┬──────────────────────────────────────┘
│
┌─────────────────────┴─────────────────────┐
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ Server-side Track │ │ JS Beacon Track │
│ (template_redirect)│ │ (sendBeacon API) │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
└──────────────────┬──────────────────────┘
│
▼
┌─────────────────────┐
│ Traffic_Buffer │
│ (File-based JSONL) │
└──────────┬──────────┘
│
▼ (Cron: every minute)
┌─────────────────────┐
│ Traffic_Aggregator │
│ (Batch process) │
└──────────┬──────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Database Tables │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ site_stats │ │ page_stats │ │referrer_stats│ │ tech_stats │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Technology Stack
- PHP 7.4+ (strict types)
- WordPress Cron API for scheduled aggregation
- Custom database tables via entity classes
- SVG rendering for charts (no external dependencies)
- File-based write-ahead buffer for performance
2. File Map
advanced-analytics/
├── classes/
│ └── vendor/
│ ├── controllers/
│ │ ├── class-traffic-collector.php — Main tracking controller
│ │ ├── class-traffic-aggregator.php — Buffer processing & DB writes
│ │ └── class-traffic-buffer.php — File-based write buffer
│ ├── entities/
│ │ ├── class-traffic-site-stats-entity.php — Daily site totals
│ │ ├── class-traffic-page-stats-entity.php — Per-page stats
│ │ ├── class-traffic-paths-entity.php — URL path lookup
│ │ ├── class-traffic-referrer-stats-entity.php — Referrer stats
│ │ ├── class-traffic-referrer-urls-entity.php — Referrer URL lookup
│ │ ├── class-traffic-tech-stats-entity.php — Tech daily stats
│ │ └── class-traffic-tech-entity.php — Browser/OS/Device lookup
│ ├── lists/
│ │ └── views/
│ │ └── class-traffic-analytics-view.php — Dashboard rendering
│ └── settings/
│ └── settings-options/
│ └── traffic-analytics.php — Module settings fields
├── css/
│ └── admin/
│ └── traffic-dashboard.css — Dashboard styles
├── js/
│ └── admin/
│ └── traffic-dashboard.js — Dashboard interactions
└── [uploads]/
└── aadvana-traffic/
├── .htaccess — Deny access
├── index.php — Prevent directory listing
└── buffer-{timestamp}.jsonl — Active buffer file
3. Admin Screens
3.1 Traffic Dashboard
| URL | wp-admin/admin.php?page=advan_traffic_analytics |
|---|---|
| Menu Position | Sub-menu under “Error Logs” (position 6) |
| Capability | manage_options (or read if menu_admins_only is false) |
| Controller | Traffic_Analytics_View::render() |
UI Components
- Date preset buttons — Today, Yesterday, Last 7/28/90 Days, Last 12 Months
- Custom date range — Start and end date pickers
- Real-time indicator — Pulsing dot with visitor count
- Summary cards — Visitors, Pageviews, Pages/Visitor with % change
- SVG chart — Daily bar chart with tooltip interactivity
- Top Pages table — Expandable rows with query params
- Top Referrers table — Grouped by domain with favicons
- Tech panels — Devices, Browsers, Operating Systems
- Footer info — Current tracking method and buffer status
Screen layout:
┌──────────────────────────────────────────────────────────────────────┐
│ Traffic Analytics │
│──────────────────────────────────────────────────────────────────────│
│ [Today][Yesterday][7 Days][28 Days][90 Days][12 Mo] [Date Range] │
│ ● 12 visitors (30 min) │
│──────────────────────────────────────────────────────────────────────│
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Visitors │ │ Pageviews │ │ Pages/ │ │
│ │ 1,234 │ │ 5,678 │ │ Visitor │ │
│ │ +15.2% │ │ +8.3% │ │ 4.6 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│──────────────────────────────────────────────────────────────────────│
│ Visitors & Pageviews │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ ▁▂▃▅▇█▆▄▃▂▁▂▄▆█▇▅▃▂▁ (SVG Bar Chart) │ │
│ └────────────────────────────────────────────────────────────────┘ │
│──────────────────────────────────────────────────────────────────────│
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Top Pages │ │ Top Referrers │ │
│ ├─────────────────────┤ ├─────────────────────┤ │
│ │ /about/ 45 120 │ │ google.com 89 210 │ │
│ │ /contact/ 32 80 │ │ twitter.com 45 102 │ │
│ └─────────────────────┘ └─────────────────────┘ │
│──────────────────────────────────────────────────────────────────────│
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Devices │ │ Browsers │ │ OS │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│──────────────────────────────────────────────────────────────────────│
│ Tracking: Server-side (PHP) • Buffer: File-based (fast) │
└──────────────────────────────────────────────────────────────────────┘
3.2 Module Settings
| URL | wp-admin/admin.php?page=advan_logs_settings#aadvana-options-tab-traffic-analytics |
|---|---|
| Settings File | classes/vendor/settings/settings-options/traffic-analytics.php |
Available Settings
| Setting | ID | Type | Default | Description |
|---|---|---|---|---|
| Enable Traffic Analytics | traffic_analytics_module_enabled |
checkbox | false |
Master switch for the module. Disabled by default. |
| Tracking Method | traffic_tracking_method |
radio | server |
Choose server (PHP) or js (JavaScript) |
| Exclude Administrators | traffic_exclude_admins |
checkbox | false |
Exclude logged-in admins from tracking |
| Data Retention (days) | traffic_retention_days |
number | 90 |
Days to keep data (min: 30, max: 3650) |
4. Core Classes
4.1 ADVAN\Lists\Views\Traffic_Analytics_View
Renders the traffic analytics dashboard page. All methods are static.
Constants
<?php
public const MENU_SLUG = 'advan_traffic_analytics';
public const PAGE_SLUG = ADVAN_INNER_SLUG . '_page_advan_traffic_analytics';Public Methods
| Method | Return | Description |
|---|---|---|
menu_add() |
void | Registers the submenu page under Error Logs |
render() |
void | Main dashboard rendering method |
Private Methods
| Method | Return | Description |
|---|---|---|
get_date_range() |
array | Parses preset/custom date range from request |
get_previous_period($start, $end) |
array | Calculates comparison period dates |
render_summary_card($label, $current, $previous) |
void | Renders a metric card with % change |
render_chart($stats, $start, $end) |
void | Generates the SVG bar chart |
extract_query_params($url) |
array | Extracts query parameters for display |
page_group_has_params($urls) |
bool | Checks if page group has expandable URLs |
4.2 ADVAN\Controllers\Traffic_Collector
Main controller for traffic data collection. Handles both server-side and client-side tracking, bot detection, and visitor identification.
Constants
<?php
private const BOT_PATTERN = '/bot|crawl|spider|seo|lighthouse|facebookexternalhit|.../i';
private const EXCLUDED_PATHS_PATTERN = '/^\/(?:favicon\.ico|robots\.txt|wp-json\/|wp-admin|...)/';
private const COOKIE_NAME = 'aadvana_traffic_uid';
public const CRON_AGGREGATE_HOOK = ADVAN_PREFIX . 'traffic_aggregate'; // aadvana_traffic_aggregate
public const CRON_PRUNE_HOOK = ADVAN_PREFIX . 'traffic_prune'; // aadvana_traffic_prune
public const AJAX_ACTION = ADVAN_PREFIX . 'traffic_collect'; // aadvana_traffic_collectPublic Methods
| Method | Return | Description |
|---|---|---|
init() |
void | Initialises tracking hooks based on tracking method setting |
collect_server_side() |
void | Server-side tracking via template_redirect |
enqueue_tracking_script() |
void | Enqueues JS tracking script for client-side mode |
handle_ajax_collect() |
void | AJAX handler for JS beacon tracking |
add_cron_schedules($schedules) |
array | Registers “every_minute” cron schedule |
unschedule_cron() |
void | Removes cron events when module disabled |
run_prune() |
void | Cron callback to delete old data |
Bot Detection
The collector uses a regex pattern to detect common bots and crawlers:
<?php
private const BOT_PATTERN = '/bot|crawl|spider|seo|lighthouse|facebookexternalhit|
preview|slurp|mediapartners|googleother|bingpreview|msnbot|yandex|baidu|
duckduckgo|ia_archiver|semrush|ahrefs|majestic|pingdom|uptimerobot|jetmon|
wget|curl|python|java|go-http|node-fetch|headlesschrome|phantomjs/i';Excluded Paths
Certain paths are automatically excluded from tracking:
<?php
private const EXCLUDED_PATHS_PATTERN = '/^\/(?:
favicon\.ico|apple-touch-icon.*|robots\.txt|sitemap.*\.xml|
\.well-known\/|wp-json\/|wp-cron\.php|wp-login\.php|wp-admin|
xmlrpc\.php|wp-includes\/|wp-content\/(?:uploads|plugins|themes)\/
)/';4.3 ADVAN\Controllers\Traffic_Aggregator
Processes buffered traffic data and writes aggregated statistics to the database. Runs via cron every minute.
Constants
<?php
public const REALTIME_OPTION = ADVAN_PREFIX . 'traffic_realtime'; // aadvana_traffic_realtimePublic Methods
| Method | Return | Description |
|---|---|---|
run() |
int | Main aggregation cycle. Returns number of records processed |
get_realtime_count() |
int | Returns count of unique visitors in last 30 minutes |
Aggregation Process
- Claims the buffer file (renames to
.busyextension) - Reads records in chunks (5000 at a time) to limit memory usage
- Accumulates stats in memory arrays
- Writes to database tables using transactions (if available)
- Updates real-time visitor count option
- Deletes the processed buffer file
4.4 ADVAN\Controllers\Traffic_Buffer
Manages the file-based write-ahead buffer for high-performance traffic recording.
Constants
<?php
private const BUFFER_DIR = 'aadvana-traffic'; // Under wp-content/uploads/Public Methods
| Method | Return | Description |
|---|---|---|
get_buffer_dir() |
string | Returns full path to buffer directory |
ensure_buffer_dir() |
bool | Creates directory with protection files |
is_available() |
bool | Checks if file buffering is available |
get_buffer_file() |
string|false | Gets or creates the current buffer file |
write($data) |
bool | Appends a record to the buffer file |
claim_buffer() |
string|false | Atomically claims buffer for processing |
read_buffer_chunk($file, &$handle, $limit) |
array | Reads records in chunks |
cleanup_stale() |
void | Removes stale .busy files |
Buffer File Format
Records are stored as JSON Lines (one JSON object per line):
{"date":"2024-01-15","path":"/about/","referrer":"https://google.com/","is_new":1,"device_type":"desktop","browser":"Chrome","os":"Windows","ip_hash":"a1b2c3d4","timestamp":1705334400}
{"date":"2024-01-15","path":"/contact/","referrer":"","is_new":0,"device_type":"mobile","browser":"Safari","os":"iOS","ip_hash":"e5f6g7h8","timestamp":1705334401}5. Entity Classes
Entity classes extend Abstract_Entity and handle database table creation and queries. All entity classes are in the ADVAN\Entities namespace.
| Entity Class | Table Name | Purpose |
|---|---|---|
Traffic_Site_Stats_Entity |
aadvana_traffic_site_stats |
Daily site-wide totals (visitors, pageviews) |
Traffic_Page_Stats_Entity |
aadvana_traffic_page_stats |
Daily per-page statistics |
Traffic_Paths_Entity |
aadvana_traffic_paths |
URL path lookup table |
Traffic_Referrer_Stats_Entity |
aadvana_traffic_referrer_stats |
Daily referrer statistics |
Traffic_Referrer_Urls_Entity |
aadvana_traffic_referrer_urls |
Full referrer URL lookup table |
Traffic_Tech_Stats_Entity |
aadvana_traffic_tech_stats |
Daily tech breakdown (device/browser/OS) |
Traffic_Tech_Entity |
aadvana_traffic_tech |
Browser/OS/Device lookup table |
Key Entity Methods
<?php
// Traffic_Site_Stats_Entity
public static function get_stats( string $start, string $end ): array;
public static function get_totals( string $start, string $end ): array;
// Traffic_Page_Stats_Entity
public static function get_top_pages_grouped( string $start, string $end, int $limit ): array;
// Traffic_Referrer_Stats_Entity
public static function get_top_referrers_grouped( string $start, string $end, int $limit ): array;
// Traffic_Tech_Stats_Entity
public static function get_top_browsers( string $start, string $end, int $limit ): array;
public static function get_top_os( string $start, string $end, int $limit ): array;
public static function get_device_breakdown( string $start, string $end ): array;6. Data Model & Database Schema
The Traffic Analytics module uses 7 custom database tables, all prefixed with aadvana_traffic_.
Table: aadvana_traffic_site_stats
Stores daily site-wide aggregates.
CREATE TABLE aadvana_traffic_site_stats (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
date DATE NOT NULL,
visitors INT UNSIGNED DEFAULT 0,
pageviews INT UNSIGNED DEFAULT 0,
UNIQUE KEY unique_date (date),
KEY idx_date (date)
);Table: aadvana_traffic_paths
Lookup table for URL paths (normalised storage).
CREATE TABLE aadvana_traffic_paths (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
path VARCHAR(2048) NOT NULL,
path_hash CHAR(32) NOT NULL,
UNIQUE KEY unique_hash (path_hash),
KEY idx_path (path(191))
);Table: aadvana_traffic_page_stats
Daily statistics per page path.
CREATE TABLE aadvana_traffic_page_stats (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
date DATE NOT NULL,
path_id BIGINT UNSIGNED NOT NULL,
visitors INT UNSIGNED DEFAULT 0,
pageviews INT UNSIGNED DEFAULT 0,
UNIQUE KEY unique_date_path (date, path_id),
KEY idx_date (date),
KEY idx_path_id (path_id)
);Table: aadvana_traffic_referrer_urls
Lookup table for full referrer URLs.
CREATE TABLE aadvana_traffic_referrer_urls (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
url VARCHAR(2048) NOT NULL,
url_hash CHAR(32) NOT NULL,
domain VARCHAR(255) NOT NULL,
UNIQUE KEY unique_hash (url_hash),
KEY idx_domain (domain)
);Table: aadvana_traffic_referrer_stats
Daily statistics per referrer.
CREATE TABLE aadvana_traffic_referrer_stats (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
date DATE NOT NULL,
referrer_id BIGINT UNSIGNED NOT NULL,
visitors INT UNSIGNED DEFAULT 0,
pageviews INT UNSIGNED DEFAULT 0,
UNIQUE KEY unique_date_ref (date, referrer_id),
KEY idx_date (date),
KEY idx_referrer_id (referrer_id)
);Table: aadvana_traffic_tech
Lookup table for device/browser/OS combinations.
CREATE TABLE aadvana_traffic_tech (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
device_type VARCHAR(20) NOT NULL,
browser VARCHAR(100) NOT NULL,
os VARCHAR(100) NOT NULL,
UNIQUE KEY unique_tech (device_type, browser(50), os(50))
);Table: aadvana_traffic_tech_stats
Daily statistics per tech combination.
CREATE TABLE aadvana_traffic_tech_stats (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
date DATE NOT NULL,
tech_id BIGINT UNSIGNED NOT NULL,
visitors INT UNSIGNED DEFAULT 0,
pageviews INT UNSIGNED DEFAULT 0,
UNIQUE KEY unique_date_tech (date, tech_id),
KEY idx_date (date),
KEY idx_tech_id (tech_id)
);Options Storage
| Option Name | Purpose |
|---|---|
aadvana_traffic_realtime |
Stores real-time visitor data (IP hashes with timestamps) |
7. Runtime Execution Flow
Initialisation Flow
advanced-analytics.php
├─ Check if traffic_analytics_module_enabled setting is true
├─ If enabled:
│ └─ Traffic_Collector::init()
│ ├─ Check tracking method setting
│ ├─ If 'server':
│ │ └─ add_action('template_redirect', 'collect_server_side', 1)
│ ├─ If 'js':
│ │ └─ add_action('wp_enqueue_scripts', 'enqueue_tracking_script')
│ ├─ Register AJAX handlers (both methods)
│ ├─ add_filter('cron_schedules', 'add_cron_schedules')
│ ├─ Schedule cron events:
│ │ ├─ aadvana_traffic_aggregate (every_minute)
│ │ └─ aadvana_traffic_prune (weekly)
│ └─ add_action(CRON_AGGREGATE_HOOK, Traffic_Aggregator::run)
│
├─ plugins_loaded
│ └─ Settings::register_menus()
│ └─ If module enabled:
│ └─ Traffic_Analytics_View::menu_add()
Server-Side Tracking Flow
Frontend page request
├─ template_redirect fires (priority 1)
├─ Traffic_Collector::collect_server_side()
│ ├─ Check if admin request → skip
│ ├─ Check if REST/AJAX request → skip
│ ├─ Check excluded paths → skip
│ ├─ Check User-Agent for bots → skip
│ ├─ Check if admin excluded → skip (if setting enabled)
│ ├─ Get/set visitor cookie (aadvana_traffic_uid)
│ ├─ Determine if new visitor (cookie not present)
│ ├─ Parse User-Agent → device type, browser, OS
│ ├─ Build record array:
│ │ ├─ date, path, referrer
│ │ ├─ is_new, device_type, browser, os
│ │ └─ ip_hash, timestamp
│ └─ Traffic_Buffer::write($record)
│ ├─ If file buffer available:
│ │ └─ Append JSON line to buffer-{timestamp}.jsonl
│ └─ If not available:
│ └─ Direct database write (fallback)
Client-Side Tracking Flow
Frontend page load
├─ wp_enqueue_scripts fires
├─ Traffic_Collector::enqueue_tracking_script()
│ └─ Enqueue inline JS with sendBeacon()
│
Browser executes JS:
├─ navigator.sendBeacon() to admin-ajax.php
│ └─ action: aadvana_traffic_collect
│
Server receives AJAX:
├─ wp_ajax_nopriv_aadvana_traffic_collect
├─ Traffic_Collector::handle_ajax_collect()
│ ├─ Validate request
│ ├─ Same checks as server-side
│ └─ Traffic_Buffer::write($record)
Aggregation Flow (Cron)
WP Cron: aadvana_traffic_aggregate (every minute)
├─ Traffic_Aggregator::run()
│ ├─ Traffic_Buffer::cleanup_stale()
│ │ └─ Remove .busy files older than 5 minutes
│ ├─ Traffic_Buffer::claim_buffer()
│ │ └─ Rename buffer-{ts}.jsonl → buffer-{ts}.jsonl.busy
│ ├─ If no buffer to claim → return 0
│ ├─ Begin transaction (if MySQL supports it)
│ ├─ Loop: read_buffer_chunk() until empty
│ │ ├─ Parse JSON lines
│ │ ├─ Accumulate in memory:
│ │ │ ├─ site_stats[date] → visitors, pageviews
│ │ │ ├─ page_stats[date][path] → visitors, pageviews
│ │ │ ├─ referrer_stats[date][url] → visitors, pageviews
│ │ │ └─ tech_stats[date][key] → visitors, pageviews
│ │ └─ Track realtime visitors by ip_hash
│ ├─ Write accumulated data to DB tables (upsert)
│ ├─ Commit transaction
│ ├─ Update realtime option
│ └─ Delete processed buffer file
Data Pruning Flow (Cron)
WP Cron: aadvana_traffic_prune (weekly)
├─ Traffic_Collector::run_prune()
│ ├─ Get traffic_retention_days setting
│ ├─ Calculate cutoff date
│ └─ DELETE FROM each table WHERE date < cutoff
8. Hooks, Filters & Cron
WordPress Hooks Used
| Hook | Type | Priority | Callback | Description |
|---|---|---|---|---|
template_redirect |
Action | 1 | Traffic_Collector::collect_server_side() |
Server-side tracking entry point |
wp_enqueue_scripts |
Action | 10 | Traffic_Collector::enqueue_tracking_script() |
JS tracking script for client-side mode |
wp_ajax_aadvana_traffic_collect |
Action | 10 | Traffic_Collector::handle_ajax_collect() |
AJAX handler for logged-in users |
wp_ajax_nopriv_aadvana_traffic_collect |
Action | 10 | Traffic_Collector::handle_ajax_collect() |
AJAX handler for visitors |
cron_schedules |
Filter | 10 | Traffic_Collector::add_cron_schedules() |
Registers “every_minute” schedule |
Custom Cron Events
| Event | Schedule | Callback | Description |
|---|---|---|---|
aadvana_traffic_aggregate |
every_minute | Traffic_Aggregator::run() |
Processes buffer file and writes to DB |
aadvana_traffic_prune |
weekly | Traffic_Collector::run_prune() |
Deletes data older than retention period |
Menu Registration
| Hook | Type | Callback | Description |
|---|---|---|---|
admin_menu |
Action | Traffic_Analytics_View::menu_add() |
Adds Traffic Analytics submenu (via Settings::register_menus) |
9. Settings Reference
All settings are stored in the main plugin options array and accessed via Settings::get_option().
Option Keys
| Key | Type | Default | Description |
|---|---|---|---|
traffic_analytics_module_enabled |
bool | false |
Enable/disable module (disabled by default) |
traffic_tracking_method |
string | 'server' |
Tracking method: 'server' or 'js' |
traffic_exclude_admins |
bool | false |
Exclude logged-in administrators |
traffic_retention_days |
int | 90 |
Data retention period (30-3650 days) |
Accessing Settings
<?php
use ADVAN\Helpers\Settings;
// Check if module is enabled
if ( Settings::get_option( 'traffic_analytics_module_enabled' ) ) {
// Module is active
}
// Get tracking method
$method = Settings::get_option( 'traffic_tracking_method' ); // 'server' or 'js'
// Get retention days
$days = Settings::get_option( 'traffic_retention_days' ); // Default: 9010. Tracking Mechanisms
Visitor Identification
Visitors are identified using a cookie-based system:
<?php
// Cookie name: aadvana_traffic_uid
// Value: Random hash (e.g., "a1b2c3d4e5f6...")
// Lifetime: 1 year (365 days)
// Set on first page visit
$cookie_name = 'aadvana_traffic_uid';
$is_new_visitor = ! isset( $_COOKIE[ $cookie_name ] );
if ( $is_new_visitor ) {
$uid = wp_generate_password( 32, false, false );
setcookie( $cookie_name, $uid, time() + YEAR_IN_SECONDS, '/', '', is_ssl(), true );
}Server-Side Tracking
Hooks into template_redirect at priority 1 (runs very early):
<?php
// Runs on every frontend page load
add_action( 'template_redirect', array( __CLASS__, 'collect_server_side' ), 1 );Client-Side Tracking (JavaScript)
<script>
(function() {
if (navigator.sendBeacon) {
var data = new FormData();
data.append('action', 'aadvana_traffic_collect');
data.append('path', window.location.pathname + window.location.search);
data.append('referrer', document.referrer);
navigator.sendBeacon('<!--?php echo admin_url('admin-ajax.php'); ?-->', data);
}
})();
</script>User-Agent Parsing
Device type, browser, and OS are extracted from the User-Agent header:
<?php
// Device type detection
if ( preg_match( '/Mobile|Android.*Mobile|iPhone|iPod/i', $ua ) ) {
$device_type = 'mobile';
} elseif ( preg_match( '/Tablet|iPad|Android(?!.*Mobile)/i', $ua ) ) {
$device_type = 'tablet';
} else {
$device_type = 'desktop';
}
// Browser detection patterns:
// Chrome, Firefox, Safari, Edge, Opera, IE, etc.
// OS detection patterns:
// Windows, macOS, iOS, Android, Linux, etc.11. File Buffer System
The file buffer system provides high-performance traffic recording by deferring database writes.
Buffer Location
wp-content/uploads/aadvana-traffic/
├── .htaccess # Deny all access
├── index.php # Prevent directory listing
└── buffer-{ts}.jsonl # Active buffer file
Buffer File Naming
buffer-1705334400.jsonl # Active buffer (timestamp = creation time)
buffer-1705334400.jsonl.busy # Being processed by aggregator
Atomic Claims
The aggregator claims a buffer file atomically using rename():
<?php
// Only one process can successfully claim the buffer
$busy_file = $buffer_file . '.busy';
if ( @rename( $buffer_file, $busy_file ) ) {
// This process owns the buffer
// Process records...
@unlink( $busy_file );
}Fallback Mode
If the buffer directory is not writable, the collector falls back to direct database writes:
<?php
if ( Traffic_Buffer::is_available() ) {
Traffic_Buffer::write( $record );
} else {
// Direct DB insert (slower, but functional)
Traffic_Site_Stats_Entity::increment( $date );
// ... other tables ...
}Stale File Cleanup
The aggregator cleans up .busy files older than 5 minutes (in case of process crashes):
<?php
public static function cleanup_stale(): void {
$stale_threshold = 5 * MINUTE_IN_SECONDS;
$busy_files = glob( self::get_buffer_dir() . '/*.busy' );
foreach ( $busy_files as $file ) {
if ( time() - filemtime( $file ) > $stale_threshold ) {
// Rename back to normal file so it can be processed
$original = str_replace( '.busy', '', $file );
@rename( $file, $original );
}
}
}12. Code Examples
Check if Module is Enabled
<?php
use ADVAN\Helpers\Settings;
if ( Settings::get_option( 'traffic_analytics_module_enabled' ) ) {
// Traffic Analytics is active
}Get Traffic Stats for a Date Range
<?php
use ADVAN\Entities\Traffic_Site_Stats_Entity;
// Get daily stats array
$stats = Traffic_Site_Stats_Entity::get_stats( '2024-01-01', '2024-01-31' );
// Returns: [ ['date' => '2024-01-01', 'visitors' => 100, 'pageviews' => 250], ... ]
// Get totals for the period
$totals = Traffic_Site_Stats_Entity::get_totals( '2024-01-01', '2024-01-31' );
// Returns: ['visitors' => 3000, 'pageviews' => 8500]Get Top Pages
<?php
use ADVAN\Entities\Traffic_Page_Stats_Entity;
$top_pages = Traffic_Page_Stats_Entity::get_top_pages_grouped( '2024-01-01', '2024-01-31', 10 );
// Returns: [
// [
// 'base_path' => '/about/',
// 'visitors' => 500,
// 'pageviews' => 1200,
// 'urls' => [
// ['path' => '/about/', 'visitors' => 400, 'pageviews' => 1000],
// ['path' => '/about/?ref=twitter', 'visitors' => 100, 'pageviews' => 200],
// ]
// ],
// ...
// ]Get Top Referrers
<?php
use ADVAN\Entities\Traffic_Referrer_Stats_Entity;
$top_referrers = Traffic_Referrer_Stats_Entity::get_top_referrers_grouped( '2024-01-01', '2024-01-31', 10 );
// Returns: [
// [
// 'domain' => 'google.com',
// 'visitors' => 800,
// 'pageviews' => 1500,
// 'urls' => [
// ['url' => 'https://google.com/search?q=...', 'visitors' => 500, 'pageviews' => 900],
// ...
// ]
// ],
// ...
// ]Get Tech Breakdown
<?php
use ADVAN\Entities\Traffic_Tech_Stats_Entity;
// Top browsers
$browsers = Traffic_Tech_Stats_Entity::get_top_browsers( '2024-01-01', '2024-01-31', 10 );
// Returns: [ ['name' => 'Chrome', 'visitors' => 600, 'pageviews' => 1400], ... ]
// Top operating systems
$os_list = Traffic_Tech_Stats_Entity::get_top_os( '2024-01-01', '2024-01-31', 10 );
// Returns: [ ['name' => 'Windows', 'visitors' => 500, 'pageviews' => 1200], ... ]
// Device breakdown
$devices = Traffic_Tech_Stats_Entity::get_device_breakdown( '2024-01-01', '2024-01-31' );
// Returns: [
// ['name' => 'desktop', 'visitors' => 700, 'pageviews' => 1800],
// ['name' => 'mobile', 'visitors' => 250, 'pageviews' => 500],
// ['name' => 'tablet', 'visitors' => 50, 'pageviews' => 100],
// ]Get Real-Time Visitor Count
<?php
use ADVAN\Controllers\Traffic_Aggregator;
$realtime_count = Traffic_Aggregator::get_realtime_count();
// Returns: int (number of unique visitors in last 30 minutes)Check Buffer Availability
<?php
use ADVAN\Controllers\Traffic_Buffer;
if ( Traffic_Buffer::is_available() ) {
echo 'File-based buffering is active';
} else {
echo 'Falling back to direct database writes';
}Manually Trigger Aggregation
<?php
use ADVAN\Controllers\Traffic_Aggregator;
// Useful for testing or immediate processing
$records_processed = Traffic_Aggregator::run();
echo "Processed {$records_processed} records";Need User Guide documentation?
See Traffic Analytics Module User Guide for more details about configuration, practical usage and information.
Comments (0)
Join the conversation. to leave a comment.