PS PrestaShop Iniciante

DataFirefly Live Counters: guia completo

Instalar, configurar e explorar os 17 contadores animados de prova social para PrestaShop 8 e 9: clientes, encomendas expedidas, seguidores Facebook e Instagram, 5 temas visuais, cache multicamada e atualização AJAX em direto.

Atualizado Versão do módulo 1.0.1

O DataFirefly Live Counters mostra na sua loja PrestaShop um widget de contadores animados alimentado em parte automaticamente pela sua base de dados (clientes ativos, encomendas expedidas, produtos, países servidos) e em parte por valores que introduz (avaliações, satisfação, seguidores nas redes sociais…). O widget posiciona-se nativamente em vários hooks (página inicial, rodapé, carrinho, colunas) ou em qualquer sítio do seu tema através da tag Smarty widget name="dflivecounters". Esta documentação cobre a instalação, a configuração dos 17 contadores disponíveis, os 5 temas visuais, a estratégia de cache, a ligação às APIs do Facebook e do Instagram, a atualização AJAX em direto e a resolução dos principais problemas.

Instalação

  1. Transfira o arquivo dflivecounters.zip a partir da sua conta DataFirefly.
  2. Back-office PrestaShop → MódulosCarregar um módulo → envie o ZIP.
  3. Na instalação, o módulo regista 7 hooks de apresentação e inicializa uma dezena de variáveis de configuração. Não é criada nenhuma tabela SQL: todas as definições são guardadas em ps_configuration.
  4. O módulo carrega o seu autoloader PSR-4 autónomo: não é necessário nenhum composer install no servidor.

Compatível com PrestaShop 8.0 a 9.x, PHP 8.1+. Multiloja nativo, multilingue através do sistema nativo do PrestaShop. Compatível com o modo de demonstração.

Aspeto do widget

Abra Módulos → DataFirefly Live Counters → Configurar. A primeira secção reúne as definições de aspeto global.

Tema visual

Cinco temas prontos a usar:

  • Minimal: sobriedade máxima, fundo branco, ideal para temas minimalistas.
  • Glassmorphism: vidro fosco com backdrop-blur, fundo ligeiramente tingido com a cor primária. Muito atual.
  • Gradient: fundo em gradiente de largura total, da cor primária para um tom escuro. Forte impacto visual, texto branco.
  • Card: cartões brancos elevados com sombra suave e hover. Clássico premium.
  • Flat: fundo ligeiramente tingido com a cor primária, valores coloridos na cor primária.

Título e subtítulo

Apresentados acima da grelha de contadores. Deixe vazios para ocultar o cabeçalho (útil no rodapé, onde o contexto já é dado pelo ambiente).

Cores

Três cores principais comandam todo o widget através de variáveis CSS (--dflc-primary, --dflc-text, --dflc-bg):

  • Cor principal: ícones por defeito, destaque do tema Flat, gradiente do tema Gradient.
  • Cor do texto: título, subtítulo, valores e etiquetas.
  • Cor de fundo: fundo da secção (ignorada nos temas Glassmorphism e Gradient, que aplicam o seu próprio fundo).

Cada contador pode também ter a sua própria cor de ícone (campo «Icon color» na linha do contador), o que permite por exemplo manter os ícones do Facebook e do Instagram nas cores da marca respetiva, conservando a coerência do resto.

Colunas

Duas definições independentes:

  • Colunas desktop: 1 a 6 (por defeito 4).
  • Colunas mobile: 1 a 3 (por defeito 2). O breakpoint é 768 px.

Duração da animação CountUp

Duração em milissegundos durante a qual os números correm de 0 até ao valor alvo (por defeito 2 000 ms). É aplicada uma curva de ease-out cúbica para uma desaceleração suave. Coloque 0 para desativar a animação e mostrar o valor final de imediato.

Nos dispositivos com prefers-reduced-motion: reduce, a animação é automaticamente desativada, qualquer que seja a duração configurada.

Atualização AJAX em direto (opcional)

Quando ativada, o widget consulta periodicamente um endpoint JSON para atualizar os valores sem recarregar a página. Dois parâmetros:

  • Live refresh: ON/OFF.
  • Intervalo: em segundos, mínimo 30 (por defeito 60). Definição forçada a 30 se introduzir menos.

O endpoint responde com um Cache-Control: public, max-age=30 que permite ao seu CDN absorver o tráfego. A animação de transição de um valor para outro arranca a partir do valor anteriormente apresentado, não a partir de zero: o efeito visual é mais natural.

«Date from»

Data de referência usada por dois contadores:

  • Encomendas expedidas: contabiliza apenas as encomendas criadas depois desta data (filtro WHERE date_add >= ?).
  • Anos de experiência: calcula automaticamente o número de anos decorridos desde essa data até hoje.

Catálogo dos contadores

Estão disponíveis 17 contadores, distribuídos por três grupos consoante o modo de cálculo.

Contadores automáticos (5)

Estes contadores leem em tempo real os dados do seu PrestaShop. Nenhuma introdução necessária.

  • Clientes: clientes ativos (active = 1 AND deleted = 0), delimitados ao contexto da loja. TTL 15 min.
  • Encomendas expedidas: encomendas com pelo menos um histórico de estado entre os estados selecionados (campo «Order states counted as shipped»). Se nenhum estado estiver selecionado, o módulo usa automaticamente o flag shipped = 1 da tabela ps_order_state. TTL 15 min.
  • Encomendas tratadas: todas as encomendas cujo estado atual tem o flag logable = 1 (o flag canónico do PrestaShop para as encomendas que contam nas estatísticas). Exclui portanto anulações e reembolsos. TTL 15 min.
  • Produtos: produtos ativos e visíveis do catálogo, delimitados ao contexto da loja. TTL 30 min.
  • Países servidos: número de países distintos que receberam pelo menos uma encomenda (COUNT(DISTINCT id_country) na tabela ps_address em join com ps_orders). TTL 1 h.

Contadores híbridos (4)

Estes contadores tentam primeiro um cálculo automático e recorrem depois ao valor manual que introduziu como reserva.

  • Anos de experiência: calculado a partir da data «Date from»; valor manual se preferir fixar um número arredondado (ex.: «12» em vez de «11»). TTL 24 h.
  • Artigos publicados: deteção automática das tabelas dos principais módulos de blogue PrestaShop (smart_blog_post, prestablog_news, psblog_post, ph_simpleblog_post) através de INFORMATION_SCHEMA. Se não houver correspondência, use o valor manual. TTL 24 h.
  • Seguidores Facebook: chamada à Graph API do Facebook com um Page Access Token de longa duração. Reserva manual se não estiver configurado ou se a API falhar. TTL 1 h.
  • Seguidores Instagram: chamada à Graph API do Instagram (conta Business ou Creator obrigatória). Reserva manual. TTL 1 h.

Contadores manuais (8)

Estes contadores mostram simplesmente o valor que introduz. Ideais para as métricas que o PrestaShop não consegue calcular ou que quer controlar totalmente.

  • Avaliações de clientes: número de avaliações (Trustpilot, Google, plataformas de avaliações certificadas, etc.).
  • Satisfação: taxa de satisfação. Dica: use um sufixo «%» e um valor 0–100.
  • CO₂ poupado: kg de emissões evitadas. Dica: sufixo «kg».
  • Prémios: prémios, certificações, distinções.
  • Horas de suporte: sufixo «h».
  • Seguidores TikTok: a Display API do TikTok exige um OAuth por utilizador, impraticável para um widget público. Introdução manual.
  • Seguidores X (Twitter): a API X v2 é paga. Introdução manual.
  • Seguidores LinkedIn: o LinkedIn Organization Followers exige aprovação na Marketing Developer Platform. Introdução manual.

Configuração por contador

Cada linha de contador na administração propõe as mesmas definições:

  • Ativo (ON/OFF): só os contadores ativos aparecem no widget. A ordem de apresentação segue a da administração.
  • Etiqueta personalizada: substitui a etiqueta por defeito. Deixe vazio para usar a etiqueta nativa traduzida no idioma do visitante.
  • Valor (manual): para os contadores manuais e a reserva dos híbridos.
  • Offset: inteiro adicionado ao valor calculado. Prático para partir de um número mais favorável sem tocar na base de dados. Nos contadores «Clientes» e «Encomendas expedidas», por exemplo, pode adicionar respetivamente +500 e +2 000 se a sua loja acabou de ser migrada. A etiqueta «Current live» ao lado do campo Offset indica o valor bruto calculado pelo PrestaShop, sem offset.
  • Prefixo / Sufixo: 4 e 6 caracteres respetivamente. O prefixo e o sufixo permanecem fixos mesmo durante a animação.
  • Casas decimais: 0 a 3. A formatação usa Intl.NumberFormat com a localidade do visitante (separadores de milhares e vírgula decimal localizados).
  • Cor do ícone: substitui a cor primária apenas para esse ícone.

As etiquetas personalizadas são guardadas na configuração por loja e por idioma através do sistema nativo do PrestaShop. Pode assim ter «Clientes satisfeitos» em português e «Happy customers» em inglês, ou mesmo uma etiqueta diferente por loja em multiloja.

Estados de encomenda «expedidos»

O contador «Encomendas expedidas» baseia-se por defeito no histórico dos estados. A definição Order states counted as shipped permite escolher com precisão os estados que contam. Numa instalação PrestaShop padrão, são os estados ID 4 (Expedida) e 5 (Entregue) que estão pré-configurados.

Se a sua loja usa estados personalizados (ex.: «Entrega em mão», «Click & Collect levantado»), lembre-se de os adicionar à seleção, caso contrário essas encomendas não serão contabilizadas.

Se nenhum estado estiver selecionado, o módulo recorre a uma reserva que consulta o flag shipped = 1 da tabela ps_order_state. Esta abordagem é mais permissiva e abrange a maioria das configurações correntes.

Configurar o Facebook

  1. Aceda a developers.facebook.com e crie uma App de tipo «Business».
  2. Na secção Graph API Explorer, selecione a sua App e depois a sua Página Facebook.
  3. Gere um Page Access Token com os scopes pages_read_engagement e pages_show_list.
  4. Troque esse token curto (1 h) por um token de longa duração (60 dias) através do endpoint /oauth/access_token?grant_type=fb_exchange_token.
  5. Obtenha o seu Page ID nas definições da sua Página (secção «Transparência da Página» ou diretamente no Graph API Explorer).
  6. Preencha os dois campos na configuração do Live Counters e guarde. O contador Facebook é atualizado ao guardar.

O token de longa duração expira ao fim de 60 dias. Depois disso, o contador recorre à reserva manual. Crie um lembrete para renovar o token antes da expiração.

Configurar o Instagram

  1. A sua conta Instagram tem de estar em modo Business ou Creator. As contas pessoais não são suportadas pela Graph API.
  2. Associe a sua conta Instagram a uma Página Facebook (definições da Página → Instagram).
  3. No Graph API Explorer, consulte /me/accounts com o seu Page Access Token para obter o Instagram User ID associado (campo instagram_business_account).
  4. Use o mesmo token Facebook de longa duração para a API do Instagram.
  5. Preencha o IG User ID e o token na configuração do Live Counters.

Estratégia de cache

A cache funciona a dois níveis para garantir um TTFB constante mesmo sob tráfego.

Cache por contador

Cada contador tem o seu próprio TTL:

  • 15 minutos: Clientes, Encomendas expedidas, Encomendas tratadas.
  • 30 minutos: Produtos.
  • 1 hora: Países servidos, Facebook, Instagram.
  • 24 horas: Anos de experiência, Artigos publicados e todos os contadores manuais.

A cache usa primeiro a camada Cache nativa do PrestaShop (memcached, APCu ou Redis, se configurados no seu servidor), e depois uma reserva em sistema de ficheiros em var/cache/dflivecounters/. Isso garante que os TTL são respeitados mesmo que a camada nativa esteja em modo «no-cache».

Cache do widget renderizado

O HTML completo do widget é ele próprio colocado em cache durante 60 segundos por idioma e por hook (dflc_widget_LANG_HASH). Esta segunda camada absorve a maioria do tráfego mesmo quando os contadores internos já estão atualizados.

Limpeza automática

  • Guardar a configuração limpa automaticamente todas as caches do módulo.
  • Um botão Limpar a cache está disponível no painel de administração para invalidação manual.
  • A desinstalação do módulo limpa a cache automaticamente.

O painel de administração mostra as estatísticas em direto: número de entradas em cache, tamanho em KB, caminho da pasta. Útil para verificar que a cache em sistema de ficheiros está ativa.

Posicionar o widget no seu tema

O módulo regista 7 hooks na instalação:

  • displayHome: página inicial
  • displayFooter: rodapé
  • displayFooterBefore: imediatamente antes do rodapé (PS 8+)
  • displayLeftColumn / displayRightColumn: colunas laterais
  • displayShoppingCartFooter: página do carrinho, por baixo do resumo
  • actionFrontControllerSetMedia: regista os recursos CSS/JS

Pode adicionar ou remover hooks em Design → Posições no back-office.

Posicionamento livre através do Smarty

Para posicionar o widget num sítio preciso do seu tema (ex.: na página de produto, por baixo do título de uma categoria), use a tag widget Smarty:

{widget name="dflivecounters"}

O widget implementa a interface WidgetInterface nativa do PrestaShop, o que o torna chamável a partir de qualquer template .tpl do seu tema.

Personalizar o template do widget

O template Smarty principal é views/templates/hook/widget.tpl. Para o substituir sem modificar o módulo (de forma a preservar as atualizações), copie-o para o seu tema, na pasta themes/o-seu-tema/modules/dflivecounters/views/templates/hook/widget.tpl.

Variáveis Smarty expostas:

  • {$dflc.counters}: array de cada contador com as chaves key, label, value, icon, prefix, suffix, decimals, icon_color
  • {$dflc.theme}: slug do 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 do hook de origem (útil para adaptar a renderização consoante o posicionamento)

Endpoint AJAX

O controlador front-office refresh expõe um URL JSON utilizável pela atualização em direto ou por qualquer integração de terceiros:

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

A resposta JSON contém um booleano success, um timestamp Unix e um objeto counters em que cada chave é o identificador do contador (customers, shipped_orders, facebook, instagram, etc.) e cada valor é o número atual. O conteúdo reflete os contadores ativos no momento da chamada, com os offsets aplicados. A resposta é servida com Cache-Control: public, max-age=30.

Acessibilidade

O widget é concebido para respeitar as recomendações WCAG 2.2 AA:

  • Estrutura semântica: section, header, ul role="list", li.
  • Todos os ícones SVG têm aria-hidden="true" (decorativos).
  • Respeito estrito de prefers-reduced-motion: reduce: animação desativada, valor final apresentado de imediato.
  • Contrastes: as cores por defeito respeitam um rácio superior a 4.5:1 nos temas Minimal e Card. Verifique as suas cores personalizadas com uma ferramenta como o axe DevTools.
  • Formato dos números: font-variant-numeric: tabular-nums para uma largura de dígito constante (evita o «salto» visual durante a animação).

RGPD

O widget é concebido para não exigir nenhuma menção de consentimento:

  • Nenhum cookie colocado do lado do visitante.
  • Nenhum script de terceiros carregado (sem Facebook Pixel, sem Google Tag Manager).
  • As chamadas às APIs do Facebook e do Instagram são feitas do lado do servidor em PHP, nunca a partir do navegador. Nenhum dado do visitante é transmitido à Meta.
  • Nenhum dado pessoal recolhido ou guardado pelo módulo.

Compatibilidade e notas técnicas

  • PrestaShop 8.0 a 9.x, PHP 8.1+.
  • Multiloja nativo: todas as consultas SQL são delimitadas ao Shop::getContextListShopID().
  • Multilingue: sistema multilingue nativo do PrestaShop.
  • Nenhuma tabela SQL criada: configuração guardada em ps_configuration.
  • Autoloader PSR-4 autónomo (sem composer install no servidor).
  • WidgetInterface nativa do PrestaShop: utilizável através de {widget name="dflivecounters"}.
  • Peso dos recursos: 3 KB JS, 2 KB CSS. Nenhum pedido externo por defeito.
  • Conforme às convenções AJAX do PrestaShop 9: $this->module->l() em vez de $this->l(), controlador front-office dedicado para a atualização, nunca uma substituição de ajaxRender.

FAQ e resolução de problemas

O widget não aparece na página inicial. Verifique que o módulo está ligado ao hook displayHome em Design → Posições. Verifique também que pelo menos um contador está ativo: sem contador ativo, o widget não devolve nada (silenciosamente).

O contador Facebook fica a zero. Várias causas possíveis: Page ID incorreto, token expirado (validade de 60 dias), scope em falta (pages_read_engagement é obrigatório). Limpe a cache do módulo e recarregue a configuração: o valor devolvido pela Graph API aparecerá ao lado da etiqueta «Current live».

O contador Encomendas expedidas está demasiado baixo. Verifique a seleção «Order states counted as shipped»: só os estados selecionados são contados. Se quiser incluir estados personalizados (ex.: «Click & Collect levantado»), adicione-os à seleção.

Os números parecem congelados e não refletem o meu tráfego real. É a cache a fazer o seu trabalho. O TTL por defeito vai de 15 minutos (clientes, encomendas) a 24 horas (contadores estáticos). Use o botão Limpar a cache para invalidar manualmente. Para uma atualização automática, ative o modo Live refresh.

A animação CountUp não arranca. O widget usa IntersectionObserver e dispara no momento em que entra no viewport. Se o widget já estiver visível no carregamento da página (ex.: colocado mesmo no topo), a animação arranca de imediato. Se ficar congelada a zero: verifique a consola JavaScript do seu navegador, outro módulo pode estar a quebrar o bundle JS.

O widget prejudica o meu Lighthouse / Core Web Vitals. Com um posicionamento no fundo da página (rodapé) e a cache de 60 s no HTML renderizado, o impacto CLS / LCP é negligenciável. Se constatar um problema, verifique que não ativou o Live refresh com um intervalo demasiado curto (o AJAX dispara enquanto o Lighthouse mede). Para uma auditoria limpa, desative a atualização em direto.

Em multiloja, os contadores são delimitados por loja? Sim. Todas as consultas SQL usam Shop::getContextListShopID(). Em modo «todas as lojas», os contadores acumulam; em modo «uma loja», contam apenas essa. As etiquetas e o valor manual são igualmente por loja e por idioma.

Como adicionar um novo contador personalizado? Crie uma classe que estenda Df/LiveCounters/Counter/AbstractCounter (ou ManualCounter para um contador 100% manual), implemente getKey(), getDefaultLabel() e getValue(), e adicione depois a instância ao array de instâncias do CounterRegistry. Para não perder o seu código na próxima atualização, crie um mini-módulo complementar que injete o seu contador no registry através de um hook personalizado. Contacte-nos para obter um exemplo.

Esta página foi útil?

Ainda com dúvidas? Contacte o suporte