Skip to content

DB Site Analytics

v3.0.3

DB Site Analytics

Tracciamento visite server-side: nessun cookie, nessun servizio esterno, solo visite reali. I dati restano nel tuo database.

Versione 3.3.0  ·  Davide Bertolino  ·  WordPress 5.8+  ·  PHP 7.4+  ·  GPL v2

Ho realizzato questo plugin per davidebertolino.it con un obiettivo preciso: misurare le visite al sito senza installare un singolo servizio di terze parti. Google Analytics profila gli utenti. Matomo è potente ma complesso. Plausible è a pagamento. Nessuno di questi era quello che cercavo per un sito personale di una scuola o di un piccolo professionista.

DB Site Analytics traccia le visite completamente lato server, usando l’hook template_redirect di WordPress. Nessuno script viene aggiunto alle pagine per contare le visite, gli ad-blocker non possono bloccarlo, le performance non vengono toccate. I dati finiscono nel database WordPress del sito — e solo lì. Niente cookie, niente dati a terzi: in genere non serve il banner di consenso.

⚠️ Google Analytics non è conforme al GDPR per i siti europei. Il Garante italiano, insieme alle autorità di Francia, Austria e altri paesi UE, ha stabilito che il trasferimento di dati personali (incluso l’indirizzo IP) verso server negli USA viola il GDPR perché non garantisce un livello di protezione adeguato. Per le scuole e le pubbliche amministrazioni italiane, usare Google Analytics senza le dovute cautele espone a sanzioni. DB Site Analytics non trasferisce nessun dato fuori dal tuo server — il problema non si pone.

✨ Novità della versione 3.3.0

La 3.3.0 è un aggiornamento dedicato all’accuratezza. Un contatore server-side vede ogni richiesta che arriva a WordPress, non solo le persone: nelle statistiche finivano scanner che cercavano /.env o /up.php, bot che martellavano la ricerca interna e perfino il sito stesso tra i primi referrer. Ora le statistiche contano solo visite reali.

  • Solo pagine reali — esclusi 404, richieste HEAD, prefetch del browser, favicon e anteprime
  • Filtro bot rivisto — richieste senza User-Agent, browser headless, librerie HTTP e crawler SEO
  • Referrer puliti — raggruppati per dominio, la navigazione interna non conta più come provenienza
  • Fuso orario del sito — giorni, grafico e filtri seguono l’ora italiana, anche al cambio dell’ora legale
  • Staff escluso — le tue visite mentre lavori al sito non vengono più contate
  • Ricerche interne e condivisioni sui social in report separati
  • Bonifica storico — esclude dalle statistiche il rumore registrato in passato, senza cancellare nulla

Dopo l’aggiornamento visite e referral caleranno: è normale, quei numeri non misuravano visite vere. Il dettaglio completo è nel changelog.


Cosa fa

↗️ Dashboard e statistiche

La dashboard admin mostra tutto quello che serve per capire come viene usato il sito, senza diventare un cruscotto da data scientist.

  • Grafico visite giornaliere (pageview + visitatori unici) con filtro date libero
  • KPI: oggi, ultimi 7 giorni, periodo selezionato — calcolati sui giorni del fuso orario del sito
  • Confronto periodo corrente vs periodo precedente con variazione percentuale
  • Top 10 pagine con pageview e visitatori unici
  • Top 10 referrer raggruppati per dominio — da dove arriva davvero il traffico
  • Breakdown dispositivi (desktop / mobile / tablet), browser, sistema operativo e paese
  • Widget nel pannello principale di WordPress con riepilogo rapido

⛔ Solo visite reali

Un contatore lato server riceve anche tutto ciò che non è una persona. Dalla versione 3.3.0 il plugin scarta le richieste che non corrispondono a una pagina visitata da un essere umano:

  • Pagine inesistenti (404) — gli scanner che cercano .env, wp-login.php o file PHP vulnerabili non finiscono più tra le pagine
  • Bot e crawler — motori di ricerca, tool SEO, browser headless, librerie come curl o python-requests e richieste senza User-Agent
  • Richieste tecniche — HEAD dei link checker, prefetch e prerender del browser, favicon, anteprime ed embed
  • Staff del sito — chi può modificare contenuti (amministratori, editor, autori) non viene contato mentre lavora

La lista dei pattern bot è estendibile con il filtro dbsa_bot_patterns.

⚖️ Privacy by design

Il plugin è progettato per ridurre al minimo i dati personali. Non viene salvato nessun indirizzo IP, non vengono installati cookie, non viene inviato nulla a server di terze parti. Per contare i visitatori unici senza identificarli, viene usato un hash giornaliero:

visitor_hash = SHA256(IP + User-Agent + salt_giornaliero)

Il salt cambia a mezzanotte, nel fuso orario del sito, e quello del giorno precedente viene eliminato: da quel momento l’hash non è più ricollegabile a nessun visitatore. Durante la giornata è un dato pseudonimo, non anonimo; dopo la rotazione non esiste più modo di risalire alla persona.

  • Nessun indirizzo IP salvato — viene usato solo in memoria, per l’hash e l’eventuale geolocalizzazione
  • Nessun cookie e nulla memorizzato sul dispositivo del visitatore
  • Nessuna comunicazione con servizi esterni durante il tracciamento
  • Referrer esterni salvati senza query string, dove a volte finiscono email o parametri personali
  • Esclusione configurabile per staff, ruoli utente, percorsi URL e utenti loggati
  • Pulizia automatica dei dati con retention configurabile (30 / 60 / 90 / 180 / 365 giorni)

In genere non serve il banner di consenso, perché non si usano cookie né altri strumenti sul dispositivo del visitatore. Il trattamento va comunque descritto nell’informativa privacy del sito.

✈️ Geolocalizzazione per paese (opzionale)

Attivando il GeoIP, la dashboard mostra da quali paesi arrivano le visite. Il plugin scarica il database gratuito DB-IP Country Lite (~10 MB) direttamente sul tuo server e lo aggiorna ogni mese: il lookup avviene in locale, senza chiamate a servizi esterni durante il tracciamento.

  • Nel database viene salvato solo il codice del paese (es. IT), mai l’indirizzo IP
  • Lettore MMDB scritto in PHP puro, senza dipendenze Composer
  • Aggiornamento automatico mensile e pulsante di aggiornamento manuale nelle impostazioni
  • Attribuzione: IP Geolocation by DB-IP (licenza CC BY 4.0)

⬇️ Download tracking (opzionale)

Vuoi sapere quante volte viene scaricato un PDF o un file ZIP? Abilita il tracking dei download dalle impostazioni. Il plugin aggiunge un piccolo script (~1KB) nel frontend che intercetta i click sui link a file con estensioni configurabili.

  • Intercetta click su link a PDF, ZIP, DOCX, XLSX e qualsiasi estensione configurabile, anche con link relativi
  • Usa navigator.sendBeacon — non blocca la navigazione
  • Compatibile con la cache di pagina, con limite di richieste per IP contro gli abusi
  • Pagina dedicata con top file scaricati, visitatori unici e pagina di provenienza
  • Export CSV con BOM UTF-8 (compatibile con Excel italiano)

⚡ Tracking eventi (opzionale)

Due tipi di evento tracciabili, entrambi opzionali e attivabili separatamente dalle impostazioni.

  • Outbound link — registra i click su link che portano fuori dal sito, con URL di destinazione e conteggio
  • Scroll depth — misura fino a che punto i visitatori leggono le pagine (soglie: 25%, 50%, 75%, 100%)
  • Script frontend ~1.5KB con throttling via requestAnimationFrame
  • Export CSV eventi

✳️ Ricerche interne e condivisioni

Due report che non richiedono nessuno script: il plugin li ricava direttamente dalle richieste che arrivano al server. Sono attivi di default e disattivabili dalle impostazioni.

  • Ricerche interne — cosa cercano i visitatori nel sito. Le ricerche non finiscono più tra le pagine; quelle vuote o più lunghe di 100 caratteri vengono scartate e ogni IP può registrarne al massimo 10 al minuto
  • Anteprime di condivisione — quando un link viene incollato su Facebook, WhatsApp, Telegram, X, LinkedIn, Slack o Discord, la piattaforma scarica la pagina per generare l’anteprima. Queste richieste sono escluse dalle visite ma contate a parte: una stima di quante volte una pagina viene condivisa

I termini cercati possono contenere dati personali: se attivi il report, citalo nell’informativa privacy.

♻️ Bonifica storico

Le correzioni sull’accuratezza valgono dal momento dell’aggiornamento. Per ripulire anche i dati registrati in passato, in Analytics → Impostazioni c’è la sezione Bonifica storico:

  • Per ogni categoria (percorsi da scanner, pagine senza titolo, ricerche registrate come pagine) mostra quante righe sono coinvolte e gli URL più frequenti, così verifichi prima di agire
  • Le righe non vengono cancellate: vengono marcate ed escluse dalle statistiche
  • Un clic su Ripristina riporta tutto com’era

Un backup del database prima di procedere resta comunque una buona idea.

✏️ Shortcode contatore visite

Vuoi mostrare il numero di visite direttamente in una pagina o in un post? Usa lo shortcode [dbsa_views].

ShortcodeRisultato
[dbsa_views]Visite alla pagina corrente, ultimi 30 giorni
[dbsa_views period="7"]Ultimi 7 giorni
[dbsa_views page_id="123"]Visite a una pagina specifica
[dbsa_views type="visitors"]Visitatori unici invece di pageview
[dbsa_views format="compact"]“1.234 visite” — numero + etichetta
[dbsa_views format="number"]Solo il numero

⚙️ REST API

Il plugin espone una REST API autenticata per integrare le statistiche in applicazioni esterne, dashboard personalizzate o script. Richiede il capability manage_options. Le date sono giorni nel fuso orario del sito.

GET /wp-json/dbsa/v1/stats?from=2026-09-01&to=2026-09-30
GET /wp-json/dbsa/v1/stats/pages?limit=10
GET /wp-json/dbsa/v1/stats/referrers
GET /wp-json/dbsa/v1/stats/devices
GET /wp-json/dbsa/v1/stats/daily
GET /wp-json/dbsa/v1/stats/downloads
GET /wp-json/dbsa/v1/stats/events

/stats/devices include il breakdown per paese; /stats/events restituisce link esterni, scroll depth, ricerche interne e anteprime di condivisione.

↪️ Export CSV

Tutti i dati sono esportabili in CSV direttamente dalla dashboard, filtrati per intervallo di date. I file usano il separatore ; e il BOM UTF-8 per la compatibilità con Excel italiano.

  • Export pageview: data/ora nel fuso del sito, URL, titolo, referrer, dominio di provenienza, dispositivo, browser, OS
  • Export download: data/ora, nome file, URL, pagina di provenienza
  • Export eventi: data/ora, tipo evento (link esterni, scroll, ricerche, condivisioni), dato, pagina

⏩ Aggiornamenti automatici

Il plugin si aggiorna direttamente dal pannello Plugin di WordPress, come quelli del repository ufficiale. Quando esce una nuova versione, ricevi la notifica e aggiorni con un clic. Niente download manuali, niente ZIP da ricaricare.

⚠️ Cache di pagina. Il conteggio delle pageview avviene in PHP: se usi una cache di pagina completa (WP Super Cache, LiteSpeed Cache, Cloudflare APO…), le pagine servite dalla cache non vengono contate. Download ed eventi, tracciati via JavaScript, non hanno questo limite.


Quanto costa?

FunzionalitàCosto
Tracciamento pageview server-sideGratis
Filtro bot, 404 e richieste non umaneGratis
Dashboard con grafico e KPIGratis
Confronto periodi con variazione %Gratis
Breakdown dispositivi, browser, OSGratis
Geolocalizzazione per paeseGratis
Download trackingGratis
Tracking eventi (outbound + scroll)Gratis
Ricerche interne e anteprime di condivisioneGratis
Bonifica storicoGratis
Shortcode [dbsa_views]Gratis
REST APIGratis
Export CSV (pageview, download, eventi)Gratis
Widget dashboard WordPressGratis
Aggiornamenti automatici da WordPressGratis
Versione “Pro” con funzionalità aggiuntiveNon esiste

Installazione

  1. Scarica lo ZIP dalla pagina GitHub Releases
  2. Vai su Plugin → Aggiungi nuovo → Carica plugin
  3. Carica lo ZIP e clicca Installa, poi Attiva
  4. Il plugin appare come Analytics nel menu laterale dell’admin

Primo utilizzo

Il tracciamento delle pageview è attivo immediatamente dopo l’attivazione, insieme ai report di ricerche interne e condivisioni. Non è richiesta nessuna configurazione iniziale e le visite dello staff sono escluse di default. Per abilitare download, eventi e geolocalizzazione, vai su Analytics → Impostazioni.

Se aggiorni da una versione precedente, dai un’occhiata alla sezione Bonifica storico per ripulire anche i dati passati.


Note tecniche

Per chi vuole capire cosa gira sotto il cofano.

Struttura database

Il plugin crea tre tabelle con prefisso {prefix}dbsa_:

  • dbsa_pageviews — ogni visita registrata, con dominio di provenienza normalizzato (referrer_host), paese e flag is_bot usato dalla bonifica; index su created_at, page_url e visitor_hash, created_at
  • dbsa_downloads — click su file scaricabili
  • dbsa_events — eventi (outbound, scroll, ricerche, condivisioni), con index su event_type, created_at

Le tabelle vengono create con dbDelta() all’attivazione e aggiornate automaticamente quando cambia lo schema. Le migrazioni pesanti, come il ricalcolo del dominio di provenienza sullo storico, girano in background a blocchi tramite WP-Cron. Le date sono salvate in UTC e convertite nel fuso orario del sito solo in lettura. La pulizia dei dati scaduti avviene ogni notte, rispettando la retention configurata.

Struttura del plugin

db-site-analytics/
├── db-site-analytics.php     # Entry point: singleton, hook attivazione
├── uninstall.php             # Rimozione completa di tabelle e opzioni
├── inc/
│   ├── class-db.php          # Tabelle, query, migrazioni, bonifica storico
│   ├── class-tracker.php     # Pageview, filtro bot e 404, ricerche, condivisioni
│   ├── class-visitor.php     # Hash giornaliero, salt, IP, rate limiting
│   ├── class-geoip.php       # Download e lookup database DB-IP
│   ├── class-mmdb-reader.php # Lettore MMDB in PHP puro
│   ├── class-downloader.php  # Download tracking (JS + AJAX handler)
│   ├── class-events.php      # Tracking eventi (JS + AJAX handler)
│   ├── class-shortcodes.php  # Shortcode [dbsa_views]
│   ├── class-rest-api.php    # REST API /wp-json/dbsa/v1/
│   ├── class-exporter.php    # CSV export
│   ├── class-admin.php       # Dashboard, menu, impostazioni, widget WP
│   └── class-updater.php     # GitHub auto-updater
├── templates/admin/
│   ├── dashboard.php
│   ├── downloads.php
│   ├── events.php
│   ├── settings.php
│   └── widget.php
└── assets/
    ├── css/
    │   ├── db-admin-ui.css   # Design system admin condiviso
    │   ├── admin.css         # Stili plugin-specifici admin
    │   └── frontend.css      # Stili shortcode frontend
    └── js/
        ├── admin.js          # Grafici della dashboard
        ├── downloader.js     # Frontend download tracker (~1KB)
        ├── events.js         # Frontend events tracker (~1.5KB)
        └── vendor/
            └── chart.umd.min.js  # Chart.js 4.4.0 (MIT), incluso nel plugin

Changelog

3.3.0

  • Accuratezza: esclusi dal conteggio i 404 (scanner che cercano .env, up.php, wp-login…), le richieste HEAD, il prefetch/prerender del browser, favicon, anteprime ed embed
  • Accuratezza: filtro bot rivisto (richieste senza User-Agent, HeadlessChrome, okhttp, Bytespider, PetalBot…) ed estendibile con il filtro dbsa_bot_patterns
  • Accuratezza: referrer normalizzati per dominio (senza www); la navigazione interna non conta più come referral. Nuova colonna referrer_host, storico ricalcolato in background
  • Accuratezza: giorni, grafico e filtri seguono il fuso orario del sito (prima UTC), con gestione dell’ora legale; il salt dei visitatori ruota a mezzanotte locale e non più due volte al giorno
  • Nuovo: “Escludi lo staff del sito” — le visite di chi può modificare contenuti non vengono registrate (l’opzione “Escludi gli amministratori” non era applicata)
  • Nuovo: ricerche interne tracciate come evento separato, con un massimo di 10 ricerche al minuto per IP
  • Nuovo: conteggio delle anteprime di condivisione (Facebook, WhatsApp, Telegram, X, LinkedIn…)
  • Nuovo: “Bonifica storico” nelle impostazioni — esclude il rumore registrato in passato, senza cancellare dati e con ripristino
  • Nuovo: campi searches e share_previews nell’endpoint REST /stats/events
  • Privacy: referrer esterni salvati senza query string; eliminate le copie dei salt dei giorni passati; testi privacy corretti
  • Performance: Chart.js incluso nel plugin (nessuna richiesta a CDN), CSS dello shortcode caricato solo dove serve, query duplicata rimossa dalla dashboard
  • Fix: shortcode [dbsa_views] senza attributi in errore fatale su WordPress ≤ 6.4
  • Fix: iPhone e iPad rilevati come macOS
  • Fix: download con link relativi e link esterni //dominio non tracciati
  • Fix: con i permalink semplici tutte le visite risultavano sulla homepage
  • Fix: date non valide accettate nei filtri della dashboard e dell’export
  • Fix: l’auto-updater riattivava il plugin anche se era disattivato
  • API: in /stats/referrers il campo referrer contiene ora il dominio normalizzato
  • Export CSV: date nel fuso orario del sito e nuova colonna Host Referrer

3.2.0

  • Nuovo: geolocalizzazione per paese (GeoIP) self-contained — database gratuito DB-IP Country Lite scaricato localmente, nessuna registrazione, nessun servizio esterno a runtime
  • Nuovo: lettore MMDB in PHP puro, zero dipendenze Composer, supporto record 24/28/32 bit e IPv4/IPv6
  • Nuovo: card “Paesi” nella dashboard e campo countries nell’endpoint REST /stats/devices
  • Nuovo: endpoint REST /stats/downloads e /stats/events — la REST API copre ora tutte le metriche (7 endpoint)
  • Nuovo: sezione GeoIP nelle impostazioni con stato del database e aggiornamento manuale; aggiornamento automatico mensile via cron
  • Privacy: l’IP è usato solo in memoria per il lookup; nel database viene registrato esclusivamente il codice paese
  • Qualità: CI su GitHub Actions (PHPCS con WordPress Coding Standards, lint PHP 7.4/8.3) e release automatica dello ZIP

3.1.0

  • Fix critico: rimosso il nonce dagli endpoint di tracking download/eventi — con il page caching il nonce in cache scadeva e il tracking falliva silenziosamente
  • Sicurezza: limite di richieste per IP sugli endpoint pubblici (20 download/min, 30 eventi/min) e validazione stretta degli eventi
  • Sicurezza: nuova impostazione “dietro proxy/CDN” — di default l’IP è letto solo da REMOTE_ADDR; gli header X-Forwarded-For/CF-Connecting-IP vengono usati solo se l’opzione è attiva
  • Performance: cache per shortcode, dashboard, widget e AJAX; eliminato SHOW TABLES a ogni pageview
  • Fix: rotazione del salt atomica, retention in UTC con cancellazione a blocchi da 5000 righe, cron programmato a mezzanotte

3.0.3

  • Fix: errore fatale nella dashboard su PHP 7.4 — $wpdb restituisce stringhe, aggiunti cast espliciti prima di operazioni aritmetiche su browser, OS e scroll depth

3.0.2

  • Fix compatibilità PHP 7.4: rimossi i return type union (int|false) introdotti in PHP 8.0

3.0.1

  • Fix: hook enqueue corretti per tutte le sottopagine admin
  • Fix: impostazioni di default complete all’attivazione
  • Fix: dashboard AJAX restituisce ora tutti i dati aggiornati
  • Aggiunto: CSS frontend per lo shortcode [dbsa_views]

3.0.0

  • REST API: 5 endpoint autenticati (/stats, /stats/pages, /stats/referrers, /stats/devices, /stats/daily)
  • Shortcode [dbsa_views] con parametri page_id, period, type, format
  • Tracking eventi: outbound link click e scroll depth (25% / 50% / 75% / 100%)
  • Nuova pagina admin “Eventi” con tabella outbound e barre scroll depth
  • Export CSV eventi
  • Tabella database dbsa_events

2.0.0

  • Confronto periodo corrente vs periodo precedente con variazione percentuale
  • Breakdown browser e OS nella dashboard (bar chart inline)
  • Download tracking: intercetta click su file scaricabili con JS ~1KB
  • Nuova pagina admin “Download” con top file e pagina di provenienza
  • Export CSV pageview e download con BOM UTF-8

1.0.0

  • Prima release: tracciamento pageview server-side
  • Dashboard con grafico, KPI, top pagine, top referrer, breakdown dispositivi
  • Filtro bot automatico, esclusione ruoli e percorsi
  • Visitor hash giornaliero
  • Pulizia dati automatica via WP-Cron con retention configurabile
  • Widget nel pannello principale di WordPress
  • GitHub auto-updater

Licenza

GPL v2 or later. Sei libero di utilizzare, modificare e distribuire il plugin. Il codice sorgente è disponibile su GitHub.

Autore

Davide Bertolino — davidebertolino.it — info@davidebertolino.it

✅ Nessuna registrazione. Nessun reminder. Nessun trucco.

Scarica, installa, usa. Niente account, niente popup, niente “passa a Pro”, niente telemetria. Niente Google. Il codice è tuo, la licenza è GPL v2, le funzionalità sono tutte incluse. Fine.

Hai suggerimenti o hai trovato un bug? Contattami!

Other Plugins

v1.3.0

DB Privacy Hub

Open Source — GPL v2 DB Privacy Hub Hub privacy unificato per l’ecosistema plugin DB. Genera la Privacy Policy che…

v1.3.0

DB SEO Manager

Open Source — GPL v2 DB SEO Manager SEO completa per WordPress, costruita prima di tutto per il GDPR. Niente…

v1.3.0

DB Event Manager

Open Source — GPL v2 DB Event Manager Gestione eventi con iscrizione, QR code personale, check-in da telefono e survey…