CodePress CMS v1.9.0: visitor statistics with SVG world map and GeoIP

- Add GeoIP class with provider chain: local DB-IP Lite, MaxMind .mmdb, external API
- Add built-in pure-PHP MMDBReader so .mmdb works without Composer
- Add cli/geoip-update.php to download DB-IP Lite and build a compact binary index
- Add cli/generate-world-map.php to generate the world map SVG from Natural Earth TopoJSON
- Add Analytics class aggregating stats in admin/storage/stats.json with LOCK_EX
- Add admin statistics page with choropleth world map, country list, top pages,
  daily chart, referrers and a period filter
- Add GeoIP and privacy settings with database update and stats reset buttons
- Add optional IP anonymization and configurable retention period
- Add country field to requests.log (parser accepts 7, 8 or 9 fields)
- Add country column to request log and KPI cards to the dashboard
- Ignore GeoIP binaries and stats.json in Git
- Update TODO.md, guides and version to 1.9.0
This commit is contained in:
2026-07-29 15:40:02 +02:00
parent 8c6b38c2c5
commit 06785e9922
20 changed files with 1804 additions and 11 deletions
+5
View File
@@ -68,6 +68,7 @@
<tr>
<th>Tijd</th>
<th>IP</th>
<th>Land</th>
<th>Pagina</th>
<th>Type / Gebruiker</th>
<th>Status</th>
@@ -81,6 +82,10 @@
<tr class="<?= str_starts_with($log['status'] ?? 'ok', 'blocked') ? 'table-danger' : '' ?>">
<td class="text-nowrap small text-muted"><?= htmlspecialchars($log['time']) ?></td>
<td><code class="small"><?= htmlspecialchars($log['ip']) ?></code></td>
<td class="text-nowrap small" title="<?= htmlspecialchars(GeoIP::getCountryName($log['country'] ?: null)) ?>">
<?= GeoIP::getCountryFlagEmoji($log['country'] ?: null) ?>
<span class="text-muted"><?= htmlspecialchars($log['country'] ?: '—') ?></span>
</td>
<td><?= htmlspecialchars($log['page']) ?></td>
<td>
<span class="badge bg-<?= $log['visitor_info']['badge'] ?>">