Files
CodePress/TODO.md
T
E.Noorlander 5357bc8915 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
2026-07-29 15:40:02 +02:00

8.0 KiB

CodePress TODO

Voltooid (recent)

Statistieken & GeoIP (v1.9.0)

  • GeoIP class 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 fseek voor 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's
  • Analytics class met aggregatie in admin/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, .mmdb pad, 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.log uitgebreid met landcode (9e veld), parser accepteert 7/8/9 velden

Beveiliging (v1.8.0)

  • BotGuard engine: AI-crawlers, zoekmachines, scrapers en lege user-agents herkennen en blokkeren
  • Admin pagina /admin/security met schakelaars, rate limiting en IP block/allowlist
  • Rate limiting per IP (HTTP 429 met Retry-After)
  • Dynamische /robots.txt en noai/noimageai meta-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/update met controle op Git-schrijfrechten
  • config.json en admin/config/admin.json uit 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 ![alt](url), 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-rename route/handler/template

Thema's

  • Thema's in subdirectory themes/naam/theme.json (ipv themes/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:40 in 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/false naar plugin config.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 Linuxstat() 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, $searchResults zouden 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. .bak bestanden)
  • 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