Track and analyse every visitor. Visualise traffic. Detect threats.
A WordPress plugin that enriches visitor IP addresses with real-time geolocation, ISP data, and risk intelligence β powered by the IpQuery API via guibranco/ipquery-php.
π Documentation Β· π Report a Bug Β· β¨ Request a Feature
| Feature | Description | |
|---|---|---|
| πΊοΈ | World heatmap | Interactive Leaflet.js map with a heat layer weighted by visit count |
| π | Country & city charts | Horizontal bar chart of top countries; dedicated top-cities table with country flags |
| π‘οΈ | Risk intelligence | Per-IP flags for VPN, proxy, Tor, datacenter, and mobile connections |
| π’ | Risk scoring | Numeric risk score (0β100) per IP with colour-coded indicators |
| π | Visitors table | Searchable, sortable, filterable table with full enrichment data for every IP |
| π | Manual lookup | Instantly enrich any IP address on demand from the admin panel |
| β‘ | Non-blocking | API calls run at shutdown β visitor page load is never delayed |
| ποΈ | Smart caching | WordPress transients cache each IP for 1 hour; only one API call per IP per hour |
| π§Ή | Auto-retention | Configurable data retention with daily WP-Cron cleanup |
| π | Privacy controls | Exclude IPs, skip logged-in users or admins, disable tracking at any time |
The plugin adds an IpQuery entry to the WordPress admin sidebar with three sub-pages.
Dashboard β a live overview built from four widgets:
- Stat cards β total visits, unique IPs, VPN/proxy/Tor count, and overall risk rate
- Visitor heatmap β world map with gradient heat layer (blue β yellow β red)
- Top countries β bar chart (Chart.js) and a flag-annotated data table
- Top cities β table with city name, country flag, visit count, and traffic share
- Risk breakdown β doughnut chart and individual cards for each risk type
Visitors β full paginated table of every tracked IP with search, type filters, per-row delete, manual lookup form, and bulk purge.
Settings β all tracking options, data retention, excluded IPs list, and a system status panel.
Visitor browser request
β
βΌ WordPress bootstrap
β
[ init ] IpQuery_Tracker registered
β
[ wp ] maybe_track()
β ββ skip: AJAX / REST / Cron
β ββ skip: logged-in / admin (configurable)
β ββ resolve IP (Cloudflare β X-Real-IP β X-Forwarded-For β REMOTE_ADDR)
β ββ skip: private ranges, excluded IPs
β ββ transient hit β bump visit_count only
β ββ transient miss β register shutdown callback
β
Page rendered & sent to browser βββββ no latency added
β
[ shutdown ] lookup_and_store()
β
βΌ
IpQueryClient::getIpData($ip) β guibranco/ipquery-php
β
βΌ
GET https://api.ipquery.io/{ip}?format=json
β
βΌ
IpQueryResponse { location, isp, risk }
β
βΌ
IpQuery_DB::upsert() β wp_ipquery_visitors
β
βΌ
set_transient( "ipq_{md5}", 1, HOUR_IN_SECONDS )
| Requirement | Minimum |
|---|---|
| WordPress | 6.0 |
| PHP | 8.2 |
| PHP extension | cURL |
| Database | MySQL 5.7+ / MariaDB 10.3+ |
No Composer or external package manager needed β guibranco/ipquery-php is bundled inside
includes/vendor/.
- Download the latest
.zipfrom the Releases page. - In your WordPress admin go to Plugins β Add New Plugin β Upload Plugin.
- Upload the
.zipand click Install Now, then Activate.
git clone https://github.com/guibranco/ipquery-wordpress.gitCopy the ipquery-wordpress/ folder into wp-content/plugins/, then activate it from Plugins in the WordPress admin.
The plugin automatically:
- Creates the
wp_ipquery_visitorsdatabase table - Writes default settings to
wp_options - Schedules a daily WP-Cron event for data retention cleanup
Navigate to IpQuery β Settings to configure:
| Setting | Default | Description |
|---|---|---|
| Enable Tracking | β On | Master switch β disable to pause all tracking |
| Track Logged-in Users | β Off | Whether authenticated visitors are tracked |
| Track Administrators | β Off | Whether manage_options users are tracked |
| Look Up Private IPs | β Off | Send private/LAN IPs to the API (useful for local dev) |
| Excluded IPs | (empty) | Newline-separated list of IPs to never track |
| Data Retention | 90 days | Records older than this are auto-deleted by cron |
Full documentation: guilherme.stracini.com.br/ipquery-wordpress/configuration
A single table wp_ipquery_visitors is created on activation:
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT
ip VARCHAR(45) UNIQUE NOT NULL
country VARCHAR(100)
country_code VARCHAR(10)
city VARCHAR(100)
state VARCHAR(100)
zipcode VARCHAR(20)
latitude DECIMAL(10,7)
longitude DECIMAL(10,7)
timezone VARCHAR(100)
asn VARCHAR(50)
org VARCHAR(255)
isp VARCHAR(255)
is_mobile TINYINT(1)
is_vpn TINYINT(1)
is_tor TINYINT(1)
is_proxy TINYINT(1)
is_datacenter TINYINT(1)
risk_score SMALLINT(3)
first_seen DATETIME
last_seen DATETIME
visit_count BIGINT UNSIGNEDipquery-wordpress/
βββ ipquery-wordpress.php # Plugin bootstrap & constants
βββ includes/
β βββ vendor/ # Bundled guibranco/ipquery-php
β β βββ IpQueryClient.php
β β βββ IpQueryException.php
β β βββ IIpQueryClient.php
β β βββ Response/
β β βββ IpQueryResponse.php
β β βββ Isp.php
β β βββ Location.php
β β βββ Risk.php
β βββ class-ipquery-db.php # Table install, upsert, and query helpers
β βββ class-ipquery-tracker.php # Visitor capture, IP resolution, caching
β βββ class-ipquery-admin.php # Admin menus, AJAX, action handlers
βββ admin/views/
β βββ dashboard.php # Heatmap, charts, stat cards, tables
β βββ visitors.php # Searchable/sortable visitor log
β βββ settings.php # Settings form & system status
βββ assets/
β βββ css/admin.css
β βββ js/ipquery-maps.js # Leaflet heatmap
β βββ js/ipquery-charts.js # Chart.js bar & doughnut charts
βββ docs/ # Jekyll / Just the Docs site
β βββ _config.yml
β βββ index.md
β βββ installation.md
β βββ configuration.md
β βββ dashboard.md
β βββ visitors.md
β βββ tracking.md
β βββ api.md
β βββ privacy.md
βββ .github/workflows/
βββ docs.yml # GitHub Pages deployment
| Dependency | Role |
|---|---|
| guibranco/ipquery-php | PHP client library for the IpQuery API β bundled inside the plugin |
| IpQuery API | Free IP intelligence service providing geolocation, ISP, and risk data |
| Leaflet.js | Interactive world map rendering |
| Leaflet.heat | Heatmap layer for Leaflet |
| Chart.js | Bar and doughnut charts |
| OpenStreetMap | Map tile provider |
| Flag CDN | Country flag images |
Full documentation is available at guilherme.stracini.com.br/ipquery-wordpress.
| Page | Description |
|---|---|
| Installation | System requirements and install steps |
| Configuration | All settings explained |
| Dashboard | Widget reference |
| Visitors | Visitor table, filters, and lookup |
| How Tracking Works | Technical flow and caching |
| IpQuery API | API fields and PHP library reference |
| Privacy & GDPR | Data collected, controls, and policy guidance |
Contributions, issues, and feature requests are welcome.
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Commit your changes:
git commit -m "feat: add my feature" - Push to the branch:
git push origin feat/my-feature - Open a Pull Request
Please follow the WordPress Coding Standards for PHP files.
Distributed under the MIT License. See LICENSE for full text.
Made with β€οΈ by Guilherme Branco Stracini Β· Built on guibranco/ipquery-php