- 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
8.0 KiB
8.0 KiB
CodePress TODO
✅ Voltooid (recent)
Statistieken & GeoIP (v1.9.0)
GeoIPclass met providerketen: lokaal (DB-IP Lite) → MaxMind.mmdb→ externe API, met automatische fallback- Eigen pure-PHP MMDB-lezer (
MMDBReader), geen Composer-afhankelijkheid nodig cli/geoip-update.php— downloadt DB-IP Lite en bouwt compacte binaire index (354k IPv4 + 342k IPv6 records)- Binary search lookup via
fseekvoor IPv4 (10 bytes/record) en IPv6 (34 bytes/record) - Placeholder-landcodes (
ZZ/XX) tellen als onbekend cli/generate-world-map.php— genereert SVG-wereldkaart uit Natural Earth TopoJSON (publiek domein) met ISO alpha-2 id'sAnalyticsclass met aggregatie inadmin/storage/stats.json(LOCK_EX), overleeft het wissen van logs- Admin pagina
/admin/statistics: KPI's, choropleth wereldkaart met tooltips, landenlijst met vlaggen, top pagina's, dagelijkse grafiek, referrers - Periodefilter 7 / 30 / 90 dagen / alles
- GeoIP- en privacy-instellingen in admin (provider,
.mmdbpad, API URL/sleutel, bewaartermijn) - Knop "GeoIP database bijwerken" en "Statistieken wissen" in admin
- IP-anonimisering als schakelaar (
RequestLogger::anonymizeIp()), standaard uit - Landkolom met vlag in requests log + KPI-kaarten op dashboard
requests.loguitgebreid met landcode (9e veld), parser accepteert 7/8/9 velden
Beveiliging (v1.8.0)
BotGuardengine: AI-crawlers, zoekmachines, scrapers en lege user-agents herkennen en blokkeren- Admin pagina
/admin/securitymet schakelaars, rate limiting en IP block/allowlist - Rate limiting per IP (HTTP 429 met
Retry-After) - Dynamische
/robots.txtennoai/noimageaimeta-tags - Statuskolom met badges in requests log
- Echte bezoeker-IP achter HAProxy/PFSense (
RequestLogger::getClientIp(), 2-pass publiek IP filter) - HAProxy/PFSense handleiding (
docs/haproxy-bot-blocking.md) - Eén-klik systeemupdate via
/admin/updatemet controle op Git-schrijfrechten config.jsonenadmin/config/admin.jsonuit Git, automatisch aangemaakt indien afwezig- ARIAComponents.php parse error — opgelost op regels 67, 137 en 262 (
'UTF-8)→'UTF-8'))
Media & Editor
- Media browser modal met upload, thumbnail grid, en size-prompt
- Media knop in editor toolbar voor alle modes (md/html/php)
- Recursieve scan van
content/voor media bestanden (ipv alleen-assets/) /-media/URL prefix voor media bestanden (consistente routing, geen special cases)/-assets/blijft werken voor backward compatibility- Size prompt voor afbeeldingen: Markdown
, HTML/PHP<img>met width/height - Editor change detectie:
editor.on('change', ...)werkt nu correct - "Terug" knop verandert naar rode "Annuleren" bij ongewijzigde wijzigingen (content-edit + content-new)
- Upload knop disabled tot bestand geselecteerd
- "Aanmaken" knop disabled tot bestandsnaam ingevuld
- Editor mode switching in content-new werkt via
switchMode()(mode + toolbar + data-ext)
Content Management
- Inline rename veld in content-edit pagina (geen aparte rename knop)
- Bestanden en mappen verplaatsen (content-move)
- Breadcrumb toont geen
.meer (dirname check op PHP niveau) - Verwijderde aparte
content-file-renameroute/handler/template
Thema's
- Thema's in subdirectory
themes/naam/theme.json(ipvthemes/naam.json) - Thema CRUD in admin (aanmaken, activeren, bewerken, verwijderen)
- File upload voor thema achtergrond afbeeldingen
Security & Code Quality (docs/TODO.md)
- Path traversal fix (
realpath()+ prefix-check) - JWT secret fallback verwijderd
executePhpFile()pad-restrictie- IP spoofing fix in MQTTTracker
- Debug uitgezet in admin config
- Cookie security (Secure/HttpOnly/SameSite)
- Dead code verwijderd
htmlspecialchars()op bestandspad gecorrigeerd- Ongebruikte methode
scanForPageNames()verwijderd - Breadcrumb titels geescaped
- Taalparameter in zoekresultaat-URLs
- Operator precedence bug in MQTTTracker
- Hardcoded strings vervangen
- HTML lang attribuut dynamisch gemaakt
- console.log verwijderd
- Sidebar toggle aria attributes
🔴 Nog openstaand
Kritiek
- Plugin auto-loading — Elke map in
plugins/wordt blind geladen zonder allowlist of validatie (PluginManager.php:40in docs/TODO.md)
Hoog
- autoLinkPageTitles() — Regex kan geneste
<a>tags produceren (CodePressCMS.php) - MQTT wachtwoord — Credentials in plain text JSON (
MQTTTracker.php) - Markdown editor — WYSIWYG/split-view Markdown editor integreren in content-edit (bijv. EasyMDE, SimpleMDE, of Toast UI Editor). Live preview, toolbar met opmaakknoppen, drag & drop afbeeldingen
- Plugin activeren/deactiveren — Toggle knop per plugin in admin Plugins pagina. Schrijft
enabled: true/falsenaar pluginconfig.json - Plugin API — Uitgebreide API voor plugins zodat ze kunnen inhaken op CMS events (hooks/filters):
onPageLoad,onBeforeRender,onAfterRender,onSearch,onMenuBuild
Medium
- Taalwisselaar verliest pagina — Wisselen van taal navigeert altijd naar homepage (
header.mustache) - ctime is geen creatietijd op Linux —
stat()ctime is inode-wijzigingstijd (CodePressCMS.php) - getGuidePage() dupliceert markdown parsing — Zelfde CommonMark setup als
parseMarkdown() - HTMLBlock ontbrekende
</div>— Niet-gesloten tags bij null-check - formatDisplayName() redundante logica — Dubbele checks en overtollige str_replace
- Plugin configuratie editor — Per-plugin config.json bewerken vanuit admin panel
- Admin activity log — Logboek van alle admin acties (wie deed wat wanneer) met viewer in dashboard
- Wachtwoord wijzigen eigen account — Apart formulier voor ingelogde gebruiker om eigen wachtwoord te wijzigen (met huidig wachtwoord verificatie)
- Admin thema — Admin sidebar kleur overnemen van site thema config (
header_color) - Map aanmaken/verwijderen — Directory management in admin Content pagina
- Bestand uploaden — Uploaden naar andere mappen dan
-assets/via admin Content pagina - Content preview — Live preview van Markdown/HTML content naast de editor
Laag
- Geen type hints — Ontbrekende type declarations op properties en methoden
- Public properties —
$config,$currentLanguage,$searchResultszouden private moeten zijn - Inline CSS — ~250 regels statische CSS in template i.p.v. extern bestand
- style.css is Bootstrap — Bestandsnaam is misleidend, Bootstrap wordt mogelijk dubbel geladen
- Geen error handling op
file_get_contents()— Meerdere calls zonder return-check - Logger slikt fouten —
@file_put_contents()met error suppression - Logger tail() leest heel bestand — Geheugenprobleem bij grote logbestanden
- Externe links missen
rel="noreferrer" - Zoekformulier mist aria-label
- mobile.css override Bootstrap utilities met
!important - Content versioning — Simpele file-based backup bij elke save (bijv.
.bakbestanden) - Zoeken in admin — Zoekfunctie binnen de admin content browser
- Drag & drop — Bestanden herordenen/verplaatsen via drag & drop
- Keyboard shortcuts — Ctrl+S om op te slaan in editor, Ctrl+N voor nieuw bestand
- Dark mode — Admin panel dark mode toggle
- Responsive admin — Admin sidebar inklapbaar op mobiel (nu is het gestacked)
- stats.json bij hoog verkeer — Nu één schrijfactie met LOCK_EX per request. Bij veel verkeer eventueel opsplitsen naar dagbestanden of APCu
- Steden op de kaart — Nu alleen landniveau; met een City-database ook stippen per stad plotten
- Statistieken exporteren — CSV/JSON export van bezoekersstatistieken
- Automatische GeoIP-update — Maandelijkse cron/schedule i.p.v. handmatig op de knop drukken