# DataFirefly Live Counters — Guida completa

> DataFirefly Live Counters mostra sul tuo negozio PrestaShop un widget di contatori animati alimentato in parte automaticamente dal tuo database (clienti attivi, ordini spediti, prodotti, paesi serviti) e in parte…

- Pagina: <https://www.datafirefly.com/it/documentation/dflivecounters/>
- Lingua: it
- Aggiornato il: 2026-08-05
- Altre lingue: [fr](https://www.datafirefly.com/documentation/dflivecounters/index.md), [en](https://www.datafirefly.com/en/documentation/dflivecounters/index.md), [es](https://www.datafirefly.com/es/documentation/dflivecounters/index.md), [de](https://www.datafirefly.com/de/documentation/dflivecounters/index.md), [pl](https://www.datafirefly.com/pl/documentation/dflivecounters/index.md), [nl](https://www.datafirefly.com/nl/documentation/dflivecounters/index.md), [pt](https://www.datafirefly.com/pt/documentation/dflivecounters/index.md)
- Indice: <https://www.datafirefly.com/it/documentation/llms.txt>

DataFirefly Live Counters mostra sul tuo negozio PrestaShop un widget di contatori animati alimentato in parte automaticamente dal tuo database (clienti attivi, ordini spediti, prodotti, paesi serviti) e in parte da valori che inserisci tu (recensioni, soddisfazione, follower sui social…). Il widget si aggancia nativamente a diversi hook di visualizzazione (home, footer, carrello, colonne) o ovunque nel tuo tema tramite il tag Smarty `widget name="dflivecounters"`. Questa documentazione copre l'installazione, la configurazione dei 17 contatori disponibili, i 5 temi visivi, la strategia di cache, il collegamento delle API Facebook e Instagram, il refresh AJAX live e la risoluzione dei principali problemi.

## Installazione

1. Scarica l'archivio `dflivecounters.zip` dal tuo account DataFirefly.
2. Back-office di PrestaShop → **Moduli** → **Carica un modulo** → invia lo ZIP.
3. All'installazione, il modulo registra 7 hook di visualizzazione e inizializza una decina di variabili di configurazione. **Nessuna tabella SQL viene creata**: tutte le impostazioni risiedono in `ps_configuration`.
4. Il modulo carica il suo autoloader PSR-4 standalone — nessun `composer install` richiesto sul server.

Compatibile con PrestaShop 8.0 a 9.x, PHP 8.1+. Multi-negozio nativo, multilingua tramite Polylang Pro o il sistema multilingua nativo di PrestaShop. Compatibile con modalità demo.

## Aspetto del widget

Apri **Moduli → DataFirefly Live Counters → Configura**. La prima sezione raggruppa le impostazioni di aspetto globale.

### Tema visivo

Cinque temi pronti all'uso:

- **Minimal**: massima sobrietà, sfondo bianco, ideale per temi puliti.
- **Glassmorphism**: vetro smerigliato con `backdrop-blur`, sfondo leggermente tinto del colore primario. Molto di tendenza.
- **Gradient**: sfondo sfumato a larghezza piena dal colore primario a una tonalità più scura. Forte impatto visivo, testo bianco.
- **Card**: carte bianche elevate con ombra morbida e hover. Classico premium.
- **Flat**: sfondo leggermente tinto del colore primario, valori colorati in primario.

### Titolo e sottotitolo

Mostrati sopra la griglia dei contatori. Lasciali vuoti per nascondere l'intestazione (utile nel footer dove il contesto è già dato dall'ambiente).

### Colori

Tre colori principali guidano l'intero widget tramite variabili CSS (`--dflc-primary`, `--dflc-text`, `--dflc-bg`):

- **Colore primario**: icone di default, accento del tema Flat, sfumatura del tema Gradient.
- **Colore del testo**: titolo, sottotitolo, valori ed etichette.
- **Colore di sfondo**: sfondo della sezione (ignorato sui temi Glassmorphism e Gradient che applicano il proprio sfondo).

Ogni contatore può anche avere **il proprio colore di icona** (campo «Icon color» nella riga del contatore), il che ti permette ad esempio di mantenere le icone di Facebook e Instagram nei loro colori di brand mantenendo la coerenza del resto.

### Colonne

Due impostazioni indipendenti:

- **Colonne desktop**: da 1 a 6 (default 4).
- **Colonne mobile**: da 1 a 3 (default 2). Il breakpoint è 768 px.

### Durata dell'animazione CountUp

Durata in millisecondi durante la quale le cifre scorrono da 0 fino al loro valore obiettivo (default 2 000 ms). Viene applicata una curva ease-out cubic per una decelerazione morbida. Imposta `0` per disabilitare l'animazione e mostrare il valore finale immediatamente.

Sui dispositivi con `prefers-reduced-motion: reduce`, l'animazione viene disabilitata automaticamente, qualunque sia la durata configurata.

### Refresh AJAX live (opzionale)

Quando attivato, il widget interroga periodicamente un endpoint JSON per aggiornare i valori senza ricaricare la pagina. Due parametri:

- **Live refresh**: ON/OFF.
- **Intervallo**: in secondi, minimo 30 (default 60). Forzato a 30 se inserisci meno.

L'endpoint risponde con un header `Cache-Control: public, max-age=30` in modo che il tuo CDN possa assorbire il traffico. L'animazione di transizione da un valore al successivo parte dal valore attualmente mostrato, non da zero — visivamente più naturale.

### «Date from»

Data di riferimento usata da due contatori:

- **Ordini spediti**: conta solo gli ordini creati dopo questa data (filtro `WHERE date_add >= ?`).
- **Anni di esperienza**: calcola automaticamente il numero di anni trascorsi da questa data fino a oggi.

## Catalogo dei contatori

Sono disponibili 17 contatori, suddivisi in tre gruppi a seconda della modalità di calcolo.

### Contatori automatici (5)

Questi contatori leggono in tempo reale i dati del tuo PrestaShop. Nessun inserimento necessario.

- **Clienti**: clienti attivi (`active = 1 AND deleted = 0`), limitati allo shop context. TTL 15 min.
- **Ordini spediti**: ordini il cui storico stati contiene almeno uno degli stati selezionati (campo «Order states counted as shipped»). Se nessuno stato è selezionato, il modulo usa automaticamente il flag `shipped = 1` dalla tabella `ps_order_state`. TTL 15 min.
- **Ordini elaborati**: tutti gli ordini il cui stato corrente ha il flag `logable = 1` (il flag canonico di PrestaShop per gli ordini che contano nelle statistiche). Esclude quindi cancellazioni e rimborsi. TTL 15 min.
- **Prodotti**: prodotti attivi e visibili del catalogo, limitati allo shop context. TTL 30 min.
- **Paesi serviti**: numero di paesi distinti che hanno ricevuto almeno un ordine (`COUNT(DISTINCT id_country)` sulla tabella `ps_address` unita a `ps_orders`). TTL 1 h.

### Contatori ibridi (4)

Questi contatori tentano prima un calcolo automatico, poi ripiegano sul valore manuale che hai inserito come backup.

- **Anni di esperienza**: calcolato dalla «Date from»; valore manuale se preferisci fissare una cifra arrotondata (es.: «12» invece di «11»). TTL 24 h.
- **Articoli pubblicati**: auto-rilevamento delle tabelle dei principali moduli blog di PrestaShop (`smart_blog_post`, `prestablog_news`, `psblog_post`, `ph_simpleblog_post`) tramite `INFORMATION_SCHEMA`. Se non c'è corrispondenza, usa il valore manuale. TTL 24 h.
- **Follower Facebook**: chiamata alla Graph API di Facebook con un Page Access Token a lunga durata. Fallback manuale se non configurato o se l'API fallisce. TTL 1 h.
- **Follower Instagram**: chiamata alla Graph API di Instagram (account Business o Creator richiesto). Fallback manuale. TTL 1 h.

### Contatori manuali (8)

Questi contatori mostrano semplicemente il valore che inserisci. Ideali per metriche che PrestaShop non può calcolare o sulle quali vuoi avere il pieno controllo.

- **Recensioni clienti**: numero di recensioni (da Trustpilot, Avis Vérifiés, Google, ecc.).
- **Soddisfazione**: tasso di soddisfazione. Suggerimento: usa un suffisso «%» e un valore 0–100.
- **CO₂ risparmiato**: kg di emissioni evitate. Suggerimento: suffisso «kg».
- **Premi**: premi, certificazioni, riconoscimenti.
- **Ore di supporto**: suffisso «h».
- **Follower TikTok**: la TikTok Display API richiede un OAuth per utente impraticabile per un widget pubblico. Inserimento manuale.
- **Follower X (Twitter)**: la X API v2 è a pagamento. Inserimento manuale.
- **Follower LinkedIn**: LinkedIn Organization Followers richiede l'approvazione Marketing Developer Platform partner. Inserimento manuale.

## Configurazione per contatore

Ogni riga di contatore nell'admin propone le stesse impostazioni:

- **Attivato** (ON/OFF): solo i contatori attivati appaiono nel widget. L'ordine di visualizzazione segue quello dell'admin.
- **Etichetta personalizzata**: sostituisce l'etichetta di default. Lasciala vuota per usare l'etichetta nativa tradotta nella lingua del visitatore.
- **Valore (manuale)**: per i contatori manuali e il fallback degli ibridi.
- **Offset**: intero aggiunto al valore calcolato. Pratico per partire da una cifra più lusinghiera senza toccare il database. Per i contatori «Clienti» e «Ordini spediti» ad esempio, puoi aggiungere rispettivamente +500 e +2 000 se il tuo negozio è appena stato migrato. L'etichetta «Current live» accanto al campo Offset ti indica il valore grezzo calcolato da PrestaShop, senza offset.
- **Prefisso / Suffisso**: 4 e 6 caratteri rispettivamente. Prefisso e suffisso restano fissi anche durante l'animazione.
- **Decimali**: da 0 a 3. La formattazione usa `Intl.NumberFormat` con il locale del visitatore (separatori di migliaia e virgola decimale localizzati).
- **Colore icona**: sostituisce il colore primario solo per quell'icona.

Le etichette personalizzate sono memorizzate in configurazione **per negozio e per lingua** tramite il sistema nativo di PrestaShop. Puoi quindi avere «Clienti felici» in italiano e «Happy customers» in inglese — o anche un'etichetta diversa per negozio in multi-negozio.

## Stati ordine «spediti»

Il contatore «Ordini spediti» si basa di default sullo storico degli stati. L'impostazione **Order states counted as shipped** ti permette di scegliere con precisione quali stati contano. Su un'installazione PrestaShop standard, sono gli stati con ID 4 (Spedito) e 5 (Consegnato) ad essere pre-selezionati.

Se il tuo negozio usa stati personalizzati (es.: «Ritiro in negozio», «Click & Collect ritirato»), non dimenticare di aggiungerli alla selezione — altrimenti questi ordini non saranno contati.

Se nessuno stato è selezionato, il modulo ripiega su un fallback che interroga il flag `shipped = 1` nella tabella `ps_order_state`. Questo approccio è più permissivo e cattura la maggior parte delle configurazioni comuni.

## Configurare Facebook

1. Vai su [developers.facebook.com](https://developers.facebook.com/) e crea un'App di tipo «Business».
2. Nella sezione **Graph API Explorer**, seleziona la tua App e poi la tua Pagina Facebook.
3. Genera un **Page Access Token** con gli scope `pages_read_engagement` e `pages_show_list`.
4. Scambia questo token a breve durata (1 h) con un **token a lunga durata** (60 giorni) tramite l'endpoint `/oauth/access_token?grant_type=fb_exchange_token`.
5. Recupera il tuo **Page ID** nelle impostazioni della tua Pagina (sezione «Trasparenza della Pagina», o direttamente nel Graph API Explorer).
6. Compila i due campi nella configurazione di Live Counters e salva. Il contatore Facebook si aggiorna al salvataggio.

Il token a lunga durata scade dopo 60 giorni. Oltre, il contatore ripiega sul fallback manuale. Imposta un promemoria per rinnovare il token prima della scadenza.

## Configurare Instagram

1. Il tuo account Instagram deve essere in modalità **Business** o **Creator**. Gli account personali non sono supportati dalla Graph API.
2. Collega il tuo account Instagram a una Pagina Facebook (impostazioni della Pagina → Instagram).
3. Nel Graph API Explorer, interroga `/me/accounts` con il tuo Page Access Token per recuperare l'**Instagram User ID** associato (campo `instagram_business_account`).
4. Usa lo stesso token Facebook a lunga durata per l'API Instagram.
5. Compila l'IG User ID e il token nella configurazione di Live Counters.

## Strategia di cache

La cache funziona su due livelli per garantire un TTFB costante anche sotto traffico.

### Cache per contatore

Ogni contatore ha il suo TTL:

- 15 minuti: Clienti, Ordini spediti, Ordini elaborati.
- 30 minuti: Prodotti.
- 1 ora: Paesi serviti, Facebook, Instagram.
- 24 ore: Anni di esperienza, Articoli pubblicati e tutti i contatori manuali.

La cache utilizza prima lo strato `Cache` nativo di PrestaShop (memcached, APCu o Redis se configurati sul tuo server), poi un fallback filesystem in `var/cache/dflivecounters/`. Questo garantisce che i TTL siano rispettati anche se lo strato nativo è in modalità «no-cache».

### Cache del widget renderizzato

L'HTML completo del widget è esso stesso messo in cache per **60 secondi** per lingua e per hook (`dflc_widget_LANG_HASH`). Questo secondo strato assorbe la maggior parte del traffico anche quando i contatori interni sono già aggiornati.

### Purge automatica

- Salvare la configurazione purga automaticamente tutte le cache del modulo.
- Un pulsante **Purga cache** è disponibile nel pannello admin per invalidazione manuale.
- La disinstallazione del modulo purga la cache automaticamente.

Il pannello admin mostra le statistiche in diretta: numero di voci in cache, dimensione in KB, percorso della cartella. Utile per verificare che la cache filesystem sia attiva.

## Posizionare il widget nel tuo tema

Il modulo registra 7 hook all'installazione:

- `displayHome` — pagina iniziale
- `displayFooter` — piè di pagina
- `displayFooterBefore` — appena prima del footer (PS 8+)
- `displayLeftColumn` / `displayRightColumn` — colonne laterali
- `displayShoppingCartFooter` — pagina del carrello, sotto il riepilogo
- `actionFrontControllerSetMedia` — registra gli asset CSS/JS

Puoi aggiungere o rimuovere hook da **Design → Posizioni** nel back-office.

### Posizionamento libero via Smarty

Per posizionare il widget in un punto preciso del tuo tema (es.: sulla scheda prodotto, sotto il titolo di una categoria), usa il tag widget Smarty:

```
{widget name="dflivecounters"}
```

Il widget implementa l'interfaccia `WidgetInterface` nativa di PrestaShop, il che lo rende invocabile da qualsiasi template `.tpl` del tuo tema.

## Personalizzare il template del widget

Il template Smarty principale è `views/templates/hook/widget.tpl`. Per sovrascriverlo senza modificare il modulo (per preservare gli aggiornamenti), copialo nel tuo tema, nella cartella `themes/tuo-tema/modules/dflivecounters/views/templates/hook/widget.tpl`.

Variabili Smarty esposte:

- `{$dflc.counters}` — array di ogni contatore con le chiavi `key`, `label`, `value`, `icon`, `prefix`, `suffix`, `decimals`, `icon_color`
- `{$dflc.theme}` — slug del tema (`minimal`, `glassmorphism`, `gradient`, `card`, `flat`)
- `{$dflc.title}`, `{$dflc.subtitle}`
- `{$dflc.primary_color}`, `{$dflc.text_color}`, `{$dflc.bg_color}`
- `{$dflc.cols_desktop}`, `{$dflc.cols_mobile}`
- `{$dflc.hook}` — nome dell'hook di origine (utile per adattare il rendering in base al posizionamento)

## Endpoint AJAX

Il controller front `refresh` espone un URL JSON utilizzabile dal live refresh o da qualsiasi integrazione di terze parti:

```
index.php?fc=module&module=dflivecounters&controller=refresh
```

La risposta JSON contiene un booleano `success`, un `timestamp` Unix, e un oggetto `counters` dove ogni chiave è l'identificatore del contatore (customers, shipped_orders, facebook, instagram, ecc.) e ogni valore è il numero corrente. Il contenuto riflette i contatori attivati al momento della chiamata, con gli offset applicati. La risposta è servita con `Cache-Control: public, max-age=30`.

## Accessibilità

Il widget è progettato per rispettare le raccomandazioni WCAG 2.2 AA:

- Struttura semantica: `section`, `header`, `ul role="list"`, `li`.
- Tutte le icone SVG hanno `aria-hidden="true"` (decorative).
- Rispetto rigoroso di `prefers-reduced-motion: reduce`: animazione disabilitata, valore finale mostrato immediatamente.
- Contrasti: i colori di default rispettano un rapporto superiore a 4.5:1 sui temi Minimal e Card. Verifica i tuoi colori personalizzati con uno strumento come axe DevTools.
- Formato dei numeri: `font-variant-numeric: tabular-nums` per una larghezza di cifra costante (evita il «salto» visivo durante l'animazione).

## GDPR

Il widget è progettato per non richiedere alcun banner di consenso:

- Nessun cookie depositato lato visitatore.
- Nessuno script di terze parti caricato (nessun Facebook Pixel, nessun Google Tag Manager).
- Le chiamate API di Facebook e Instagram sono effettuate **lato server in PHP**, mai dal browser. Nessun dato del visitatore è trasmesso a Meta.
- Nessun dato personale raccolto o memorizzato dal modulo.

## Compatibilità e note tecniche

- PrestaShop 8.0 a 9.x, PHP 8.1+.
- Multi-negozio nativo: tutte le query SQL sono limitate a `Shop::getContextListShopID()`.
- Multilingua: Polylang Pro o sistema multilingua nativo di PrestaShop.
- Nessuna tabella SQL creata: configurazione memorizzata in `ps_configuration`.
- Autoloader PSR-4 standalone (nessun `composer install` sul server).
- WidgetInterface nativo di PrestaShop: utilizzabile tramite `{widget name="dflivecounters"}`.
- Peso degli asset: 3 KB JS, 2 KB CSS. Nessuna richiesta esterna di default.
- Conforme alle convenzioni AJAX di PrestaShop 9: `$this->module->l()` invece di `$this->l()`, controller front dedicato per il refresh, mai sovrascrive `ajaxRender`.

## FAQ e risoluzione dei problemi

**Il widget non appare sulla pagina iniziale.** Verifica che il modulo sia agganciato all'hook `displayHome` in **Design → Posizioni**. Verifica anche che almeno un contatore sia attivato: senza alcun contatore attivato, il widget non restituisce nulla (silenziosamente).

**Il contatore Facebook resta a zero.** Diverse cause possibili: Page ID errato, token scaduto (durata 60 giorni), scope mancante (`pages_read_engagement` è obbligatorio). Purga la cache del modulo e ricarica la configurazione: il valore restituito dalla Graph API apparirà accanto all'etichetta «Current live».

**Il contatore Ordini spediti è troppo basso.** Verifica la selezione «Order states counted as shipped»: solo gli stati selezionati vengono contati. Se vuoi includere stati personalizzati (es.: «Click & Collect ritirato»), aggiungili alla selezione.

**I numeri sembrano congelati e non riflettono il mio traffico reale.** È la cache che fa il suo lavoro. Il TTL di default va da 15 minuti (clienti, ordini) a 24 ore (contatori statici). Usa il pulsante **Purga cache** per invalidare manualmente. Per un refresh automatico, attiva la modalità **Live refresh**.

**L'animazione CountUp non si attiva.** Il widget usa IntersectionObserver e si attiva nel momento in cui entra nel viewport. Se il widget è già visibile al caricamento della pagina (es.: posizionato in alto), l'animazione parte immediatamente. Se resta congelata a zero: controlla la console JavaScript del tuo browser, un altro modulo potrebbe rompere il bundle JS.

**Il widget rovina il mio Lighthouse / Core Web Vitals.** Con un posizionamento a piè di pagina (footer) e la cache di 60 s sull'HTML renderizzato, l'impatto CLS / LCP è trascurabile. Se vedi un problema, verifica di non aver attivato il **Live refresh** con un intervallo troppo corto (l'AJAX si attiva mentre Lighthouse misura). Per un audit pulito, disattiva il live refresh.

**In multi-negozio, i contatori sono limitati per negozio?** Sì. Tutte le query SQL usano `Shop::getContextListShopID()`. In modalità «tutti i negozi», i contatori si sommano; in modalità «un negozio», contano solo quello. Le etichette personalizzate e il valore manuale sono anch'essi per-negozio-per-lingua.

**Come aggiungo un contatore personalizzato?** Crea una classe che estende `Df/LiveCounters/Counter/AbstractCounter` (o `ManualCounter` per un contatore 100% manuale), implementa `getKey()`, `getDefaultLabel()` e `getValue()`, poi aggiungi l'istanza all'array di istanze del `CounterRegistry`. Per non perdere il tuo codice al prossimo aggiornamento, crea un mini-modulo compagno che inietta il tuo contatore nel registry tramite un hook personalizzato — non esitare a contattarci per un esempio.
