# DataFirefly Live Counters: kompletny przewodnik

> DataFirefly Live Counters wyświetla w Twoim sklepie PrestaShop widget animowanych liczników, zasilany częściowo automatycznie z Twojej bazy (aktywni klienci, wysłane zamówienia, produkty, obsługiwane kraje), a częściowo wartościami, które wpisujesz ręcznie…

- Strona: <https://www.datafirefly.com/pl/documentation/dflivecounters/>
- Język: pl
- Zaktualizowano: 2026-08-01
- Inne języki: [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), [it](https://www.datafirefly.com/it/documentation/dflivecounters/index.md), [nl](https://www.datafirefly.com/nl/documentation/dflivecounters/index.md), [pt](https://www.datafirefly.com/pt/documentation/dflivecounters/index.md)
- Indeks: <https://www.datafirefly.com/pl/documentation/llms.txt>

DataFirefly Live Counters wyświetla w Twoim sklepie PrestaShop widget animowanych liczników, zasilany częściowo automatycznie z Twojej bazy (aktywni klienci, wysłane zamówienia, produkty, obsługiwane kraje), a częściowo wartościami, które wpisujesz ręcznie (opinie, satysfakcja, obserwujący w mediach społecznościowych i inne). Widget umieszcza się natywnie na kilku hookach (strona główna, stopka, koszyk, kolumny) albo w dowolnym miejscu motywu znacznikiem Smarty `widget name="dflivecounters"`. Ta dokumentacja obejmuje instalację, konfigurację 17 dostępnych liczników, 5 motywów wizualnych, strategię cache, podpięcie API Facebooka i Instagrama, live refresh AJAX oraz rozwiązywanie najczęstszych problemów.

## Instalacja

1. Pobierz archiwum `dflivecounters.zip` ze swojego konta DataFirefly.
2. Zaplecze PrestaShop > **Moduły** > **Wgraj moduł** > wyślij plik ZIP.
3. Podczas instalacji moduł rejestruje 7 hooków wyświetlania i inicjalizuje kilkanaście zmiennych konfiguracyjnych. **Żadna tabela SQL nie jest tworzona**: wszystkie ustawienia trafiają do `ps_configuration`.
4. Moduł ładuje własny samodzielny autoloader PSR-4, na serwerze nie jest potrzebne `composer install`.

Zgodny z PrestaShop 8.0 do 9.x, PHP 8.1+. Natywny multisklep, wielojęzyczność przez Polylang Pro lub natywny system PrestaShop. Zgodny z trybem demo.

## Wygląd widgetu

Otwórz **Moduły > DataFirefly Live Counters > Konfiguruj**. Pierwsza sekcja zbiera ustawienia wyglądu globalnego.

### Motyw wizualny

Pięć gotowych motywów:

- **Minimal**: maksymalna prostota, białe tło, idealny dla motywów minimalistycznych.
- **Glassmorphism**: matowe szkło z `backdrop-blur`, tło lekko zabarwione kolorem głównym. Bardzo modny.
- **Gradient**: pełnoszerokościowe tło gradientowe od koloru głównego do ciemnego odcienia. Mocny efekt wizualny, biały tekst.
- **Card**: białe uniesione karty z miękkim cieniem i efektem hover. Klasyczny premium.
- **Flat**: tło lekko zabarwione kolorem głównym, wartości w kolorze głównym.

### Tytuł i podtytuł

Wyświetlane nad siatką liczników. Zostaw puste, aby ukryć nagłówek (przydatne w stopce, gdzie kontekst wynika już z otoczenia).

### Kolory

Trzy główne kolory sterują całym widgetem przez zmienne CSS (`--dflc-primary`, `--dflc-text`, `--dflc-bg`):

- **Kolor główny**: domyślne ikony, akcent motywu Flat, gradient motywu Gradient.
- **Kolor tekstu**: tytuł, podtytuł, wartości i etykiety.
- **Kolor tła**: tło sekcji (ignorowany w motywach Glassmorphism i Gradient, które stosują własne tło).

Każdy licznik może mieć też **własny kolor ikony** (pole „Icon color" w wierszu licznika), co pozwala na przykład zachować ikony Facebooka i Instagrama w barwach marki, nie tracąc spójności reszty.

### Kolumny

Dwa niezależne ustawienia:

- **Kolumny na desktopie**: od 1 do 6 (domyślnie 4).
- **Kolumny na mobile**: od 1 do 3 (domyślnie 2). Breakpoint wynosi 768 px.

### Czas trwania animacji CountUp

Czas w milisekundach, przez który liczby przewijają się od 0 do wartości docelowej (domyślnie 2 000 ms). Stosowana jest krzywa ease-out cubic dla łagodnego wyhamowania. Ustaw `0`, aby wyłączyć animację i od razu pokazać wartość końcową.

Na urządzeniach z ustawieniem `prefers-reduced-motion: reduce` animacja jest wyłączana automatycznie, niezależnie od skonfigurowanego czasu.

### Live refresh AJAX (opcjonalny)

Po włączeniu widget okresowo odpytuje endpoint JSON, aby zaktualizować wartości bez przeładowania strony. Dwa parametry:

- **Live refresh**: włączony lub wyłączony.
- **Interwał**: w sekundach, minimum 30 (domyślnie 60). Przy niższej wartości ustawienie jest wymuszane na 30.

Endpoint odpowiada z nagłówkiem `Cache-Control: public, max-age=30`, dzięki czemu Twój CDN może przejąć ruch. Animacja przejścia z jednej wartości na drugą startuje od poprzednio wyświetlanej liczby, a nie od zera, więc efekt wizualny jest bardziej naturalny.

### „Date from"

Data referencyjna używana przez dwa liczniki:

- **Wysłane zamówienia**: liczy wyłącznie zamówienia utworzone po tej dacie (filtr `WHERE date_add >= ?`).
- **Lata doświadczenia**: automatycznie wylicza liczbę lat od tej daty do dziś.

## Katalog liczników

Dostępnych jest 17 liczników, podzielonych na trzy grupy według sposobu wyliczania.

### Liczniki automatyczne (5)

Te liczniki czytają dane Twojego PrestaShopa w czasie rzeczywistym. Nie wymagają żadnego wpisywania.

- **Klienci**: aktywni klienci (`active = 1 AND deleted = 0`), ograniczeni do kontekstu sklepu. TTL 15 min.
- **Wysłane zamówienia**: zamówienia, których historia statusów zawiera co najmniej jeden z wybranych stanów (pole „Order states counted as shipped"). Jeśli nie wybrano żadnego stanu, moduł automatycznie korzysta z flagi `shipped = 1` w tabeli `ps_order_state`. TTL 15 min.
- **Zrealizowane zamówienia**: wszystkie zamówienia, których bieżący stan ma flagę `logable = 1` (kanoniczna flaga PrestaShop dla zamówień liczonych w statystykach). Wyklucza więc anulowania i zwroty. TTL 15 min.
- **Produkty**: aktywne i widoczne produkty katalogu, ograniczone do kontekstu sklepu. TTL 30 min.
- **Obsługiwane kraje**: liczba różnych krajów, które otrzymały co najmniej jedno zamówienie (`COUNT(DISTINCT id_country)` na tabeli `ps_address` złączonej z `ps_orders`). TTL 1 h.

### Liczniki hybrydowe (4)

Te liczniki najpierw próbują wyliczenia automatycznego, a następnie przechodzą na wartość ręczną wpisaną przez Ciebie jako backup.

- **Lata doświadczenia**: wyliczane od daty „Date from"; wartość ręczna, jeśli wolisz podać zaokrągloną liczbę (na przykład 12 zamiast 11). TTL 24 h.
- **Opublikowane artykuły**: automatyczne wykrywanie tabel głównych modułów blogowych PrestaShop (`smart_blog_post`, `prestablog_news`, `psblog_post`, `ph_simpleblog_post`) przez `INFORMATION_SCHEMA`. Przy braku dopasowania użyj wartości ręcznej. TTL 24 h.
- **Obserwujący na Facebooku**: wywołanie Graph API Facebooka z długoterminowym Page Access Tokenem. Ręczny fallback, gdy brak konfiguracji lub gdy API zawiedzie. TTL 1 h.
- **Obserwujący na Instagramie**: wywołanie Graph API Instagrama (wymagane konto Business lub Creator). Ręczny fallback. TTL 1 h.

### Liczniki ręczne (8)

Te liczniki po prostu wyświetlają wpisaną przez Ciebie wartość. Idealne dla metryk, których PrestaShop nie potrafi wyliczyć albo które chcesz w pełni kontrolować.

- **Opinie klientów**: liczba opinii (z Trustpilota, Avis Vérifiés, Google i innych).
- **Satysfakcja**: współczynnik satysfakcji. Wskazówka: użyj sufiksu „%" i wartości od 0 do 100.
- **Zaoszczędzone CO₂**: kilogramy uniknionych emisji. Wskazówka: sufiks „kg".
- **Nagrody**: wyróżnienia, certyfikaty, tytuły.
- **Godziny wsparcia**: sufiks „h".
- **Obserwujący na TikToku**: TikTok Display API wymaga OAuth per użytkownik, co jest niepraktyczne dla publicznego widgetu. Wpis ręczny.
- **Obserwujący na X (Twitterze)**: API X v2 jest płatne. Wpis ręczny.
- **Obserwujący na LinkedInie**: LinkedIn Organization Followers wymaga zatwierdzenia w Marketing Developer Platform. Wpis ręczny.

## Konfiguracja pojedynczego licznika

Każdy wiersz licznika w adminie oferuje te same ustawienia:

- **Włączony**: tylko włączone liczniki pojawiają się w widgecie. Kolejność wyświetlania odpowiada kolejności w adminie.
- **Własna etykieta**: zastępuje etykietę domyślną. Zostaw puste, aby użyć natywnej etykiety przetłumaczonej na język odwiedzającego.
- **Wartość (ręczna)**: dla liczników ręcznych i jako fallback dla hybrydowych.
- **Offset**: liczba całkowita dodawana do wyliczonej wartości. Praktyczne, aby startować od korzystnej liczby bez dotykania bazy danych. Dla liczników „Klienci" i „Wysłane zamówienia" możesz na przykład dodać odpowiednio +500 i +2 000, jeśli sklep został dopiero co zmigrowany. Etykieta „Current live" obok pola Offset pokazuje surową wartość wyliczoną przez PrestaShop, bez offsetu.
- **Prefiks i sufiks**: odpowiednio 4 i 6 znaków. Prefiks i sufiks pozostają nieruchome także w trakcie animacji.
- **Miejsca dziesiętne**: od 0 do 3. Formatowanie korzysta z `Intl.NumberFormat` z lokalizacją odwiedzającego (zlokalizowane separatory tysięcy i przecinek dziesiętny).
- **Kolor ikony**: zastępuje kolor główny wyłącznie dla tej ikony.

Własne etykiety są zapisywane w konfiguracji **per sklep i per język** przez natywny system PrestaShop. Możesz więc mieć „Zadowoleni klienci" po polsku i „Happy customers" po angielsku, a nawet inną etykietę dla każdego sklepu w trybie multisklep.

## Stany zamówień liczone jako wysłane

Licznik „Wysłane zamówienia" domyślnie opiera się na historii statusów. Ustawienie **Order states counted as shipped** pozwala precyzyjnie wskazać stany, które się liczą. Na standardowej instalacji PrestaShop wstępnie skonfigurowane są stany o ID 4 (Wysłano) i 5 (Dostarczono).

Jeśli Twój sklep używa własnych statusów (na przykład „Odbiór osobisty", „Click & Collect odebrane"), pamiętaj, aby dodać je do wyboru, w przeciwnym razie te zamówienia nie zostaną policzone.

Jeśli nie wybrano żadnego stanu, moduł przechodzi na fallback odpytujący flagę `shipped = 1` w tabeli `ps_order_state`. To podejście jest bardziej liberalne i obejmuje większość typowych konfiguracji.

## Konfiguracja Facebooka

1. Wejdź na [developers.facebook.com](https://developers.facebook.com/) i utwórz aplikację typu „Business".
2. W sekcji **Graph API Explorer** wybierz swoją aplikację, a następnie swoją Stronę na Facebooku.
3. Wygeneruj **Page Access Token** z zakresami `pages_read_engagement` i `pages_show_list`.
4. Wymień ten krótkotrwały token (1 h) na **token długoterminowy** (60 dni) przez endpoint `/oauth/access_token?grant_type=fb_exchange_token`.
5. Odczytaj swój **Page ID** w ustawieniach Strony (sekcja „Przejrzystość strony" albo bezpośrednio w Graph API Explorer).
6. Wypełnij oba pola w konfiguracji Live Counters i zapisz. Licznik Facebooka aktualizuje się przy zapisie.

Token długoterminowy wygasa po 60 dniach. Po tym czasie licznik przechodzi na ręczny fallback. Ustaw sobie przypomnienie, aby odnowić token przed wygaśnięciem.

## Konfiguracja Instagrama

1. Twoje konto na Instagramie musi być w trybie **Business** lub **Creator**. Konta osobiste nie są obsługiwane przez Graph API.
2. Powiąż konto na Instagramie ze Stroną na Facebooku (ustawienia Strony > Instagram).
3. W Graph API Explorer odpytaj `/me/accounts` swoim Page Access Tokenem, aby odczytać powiązany **Instagram User ID** (pole `instagram_business_account`).
4. Do API Instagrama użyj tego samego długoterminowego tokenu Facebooka.
5. Wpisz IG User ID i token w konfiguracji Live Counters.

## Strategia cache

Cache działa na dwóch poziomach, aby zapewnić stały TTFB nawet pod obciążeniem.

### Cache pojedynczego licznika

Każdy licznik ma własny TTL:

- 15 minut: Klienci, Wysłane zamówienia, Zrealizowane zamówienia.
- 30 minut: Produkty.
- 1 godzina: Obsługiwane kraje, Facebook, Instagram.
- 24 godziny: Lata doświadczenia, Opublikowane artykuły i wszystkie liczniki ręczne.

Cache korzysta najpierw z natywnej warstwy `Cache` PrestaShopa (memcached, APCu albo Redis, jeśli są skonfigurowane na Twoim serwerze), a następnie z fallbacku filesystem w `var/cache/dflivecounters/`. Gwarantuje to respektowanie TTL nawet wtedy, gdy warstwa natywna działa w trybie bez cache.

### Cache wyrenderowanego widgetu

Kompletny HTML widgetu jest dodatkowo buforowany przez **60 sekund** per język i per hook (`dflc_widget_LANG_HASH`). Ta druga warstwa przejmuje większość ruchu nawet wtedy, gdy wewnętrzne liczniki są już aktualne.

### Automatyczne czyszczenie

- Zapis konfiguracji automatycznie czyści wszystkie cache modułu.
- Przycisk **Wyczyść cache** w panelu administracyjnym umożliwia ręczne unieważnienie.
- Odinstalowanie modułu automatycznie czyści cache.

Panel administracyjny pokazuje statystyki na żywo: liczbę wpisów w cache, rozmiar w KB, ścieżkę katalogu. Przydatne do sprawdzenia, czy cache filesystem faktycznie działa.

## Umieszczenie widgetu w motywie

Moduł rejestruje przy instalacji 7 hooków:

- `displayHome`: strona główna
- `displayFooter`: stopka
- `displayFooterBefore`: tuż przed stopką (PS 8+)
- `displayLeftColumn` i `displayRightColumn`: kolumny boczne
- `displayShoppingCartFooter`: strona koszyka, pod podsumowaniem
- `actionFrontControllerSetMedia`: rejestruje zasoby CSS i JS

Hooki możesz dodawać i usuwać w **Wygląd > Pozycje** w zapleczu.

### Dowolne umieszczenie przez Smarty

Aby umieścić widget w konkretnym miejscu motywu (na przykład na karcie produktu, pod tytułem kategorii), użyj znacznika widget Smarty:

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

Widget implementuje natywny interfejs `WidgetInterface` PrestaShopa, dzięki czemu można go wywołać z dowolnego szablonu `.tpl` Twojego motywu.

## Personalizacja szablonu widgetu

Głównym szablonem Smarty jest `views/templates/hook/widget.tpl`. Aby go nadpisać bez modyfikowania modułu (i tym samym zachować aktualizacje), skopiuj go do swojego motywu, do katalogu `themes/twoj-motyw/modules/dflivecounters/views/templates/hook/widget.tpl`.

Udostępniane zmienne Smarty:

- `{$dflc.counters}`: tablica każdego licznika z kluczami `key`, `label`, `value`, `icon`, `prefix`, `suffix`, `decimals`, `icon_color`
- `{$dflc.theme}`: slug motywu (`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}`: nazwa hooka źródłowego (przydatna do dostosowania renderowania w zależności od miejsca)

## Endpoint AJAX

Kontroler frontowy `refresh` udostępnia adres JSON używany przez live refresh lub przez dowolną integrację zewnętrzną:

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

Odpowiedź JSON zawiera wartość logiczną `success`, uniksowy `timestamp` oraz obiekt `counters`, w którym każdy klucz to identyfikator licznika (customers, shipped_orders, facebook, instagram i inne), a każda wartość to bieżąca liczba. Treść odzwierciedla liczniki włączone w momencie wywołania, z zastosowanymi offsetami. Odpowiedź jest serwowana z nagłówkiem `Cache-Control: public, max-age=30`.

## Dostępność

Widget został zaprojektowany zgodnie z zaleceniami WCAG 2.2 AA:

- Struktura semantyczna: `section`, `header`, `ul role="list"`, `li`.
- Wszystkie ikony SVG mają `aria-hidden="true"` (są dekoracyjne).
- Ścisłe respektowanie `prefers-reduced-motion: reduce`: animacja wyłączona, wartość końcowa pokazana natychmiast.
- Kontrasty: kolory domyślne utrzymują współczynnik powyżej 4.5:1 w motywach Minimal i Card. Sprawdź swoje własne kolory narzędziem takim jak axe DevTools.
- Format liczb: `font-variant-numeric: tabular-nums` dla stałej szerokości cyfry (eliminuje wizualne „skakanie" w trakcie animacji).

## RODO

Widget został zaprojektowany tak, aby nie wymagał żadnej wzmianki o zgodzie:

- Żadne cookie nie jest zapisywane po stronie odwiedzającego.
- Żaden skrypt zewnętrzny nie jest ładowany (brak Facebook Pixel, brak Google Tag Manager).
- Wywołania API Facebooka i Instagrama są wykonywane **po stronie serwera w PHP**, nigdy z przeglądarki. Żadne dane odwiedzającego nie trafiają do Meta.
- Moduł nie zbiera ani nie przechowuje żadnych danych osobowych.

## Zgodność i uwagi techniczne

- PrestaShop 8.0 do 9.x, PHP 8.1+.
- Natywny multisklep: wszystkie zapytania SQL są ograniczone do `Shop::getContextListShopID()`.
- Wielojęzyczność: Polylang Pro lub natywny system wielojęzyczny PrestaShopa.
- Żadna tabela SQL nie jest tworzona: konfiguracja zapisywana w `ps_configuration`.
- Samodzielny autoloader PSR-4 (bez `composer install` na serwerze).
- Natywny WidgetInterface PrestaShopa: użyteczny przez `{widget name="dflivecounters"}`.
- Waga zasobów: 3 KB JS, 2 KB CSS. Domyślnie żadnych żądań zewnętrznych.
- Zgodność z konwencjami AJAX PrestaShop 9: `$this->module->l()` zamiast `$this->l()`, dedykowany kontroler frontowy do odświeżania, żadnego nadpisywania `ajaxRender`.

## FAQ i rozwiązywanie problemów

**Widget nie wyświetla się na stronie głównej.** Sprawdź, czy moduł jest podpięty do hooka `displayHome` w **Wygląd > Pozycje**. Sprawdź też, czy włączony jest co najmniej jeden licznik: bez włączonego licznika widget nie zwraca nic (po cichu).

**Licznik Facebooka pozostaje na zerze.** Możliwych przyczyn jest kilka: nieprawidłowy Page ID, wygasły token (czas życia 60 dni), brakujący zakres (`pages_read_engagement` jest wymagany). Wyczyść cache modułu i przeładuj konfigurację: wartość zwrócona przez Graph API pojawi się obok etykiety „Current live".

**Licznik wysłanych zamówień jest zbyt niski.** Sprawdź wybór „Order states counted as shipped": liczone są wyłącznie zaznaczone stany. Jeśli chcesz uwzględnić własne statusy (na przykład „Click & Collect odebrane"), dodaj je do wyboru.

**Liczby wydają się zamrożone i nie odzwierciedlają rzeczywistego ruchu.** To działanie cache. Domyślny TTL waha się od 15 minut (klienci, zamówienia) do 24 godzin (liczniki statyczne). Użyj przycisku **Wyczyść cache**, aby unieważnić go ręcznie. Aby odświeżać automatycznie, włącz tryb **Live refresh**.

**Animacja CountUp się nie uruchamia.** Widget korzysta z IntersectionObserver i uruchamia się w momencie wejścia w viewport. Jeśli widget jest widoczny już przy ładowaniu strony (na przykład umieszczony na samej górze), animacja startuje natychmiast. Jeśli pozostaje zamrożona na zerze, sprawdź konsolę JavaScript przeglądarki: inny moduł mógł zepsuć bundle JS.

**Widget psuje mój wynik Lighthouse i Core Web Vitals.** Przy umieszczeniu na dole strony (stopka) i 60-sekundowym cache na wyrenderowanym HTML wpływ na CLS i LCP jest znikomy. Jeśli zauważysz problem, sprawdź, czy nie włączyłeś **Live refresh** ze zbyt krótkim interwałem (AJAX odpala się w trakcie pomiaru Lighthouse). Do czystego audytu wyłącz live refresh.

**Czy w trybie multisklep liczniki są ograniczone do sklepu?** Tak. Wszystkie zapytania SQL używają `Shop::getContextListShopID()`. W trybie „wszystkie sklepy" liczniki sumują dane, w trybie pojedynczego sklepu liczą tylko jego. Etykiety i wartość ręczna również są per sklep i per język.

**Jak dodać własny licznik?** Utwórz klasę rozszerzającą `Df/LiveCounters/Counter/AbstractCounter` (albo `ManualCounter` dla licznika w pełni ręcznego), zaimplementuj `getKey()`, `getDefaultLabel()` i `getValue()`, a następnie dodaj instancję do tablicy instancji w `CounterRegistry`. Aby nie stracić swojego kodu przy najbliższej aktualizacji, utwórz mały moduł towarzyszący, który wstrzykuje Twój licznik do rejestru przez własny hook. Napisz do nas, chętnie podeślemy przykład.
