Idioma

Entrar em contacto

Plugin para WordPress · desde 2016

WPCS

Um seletor de moeda para sites WordPress sem WooCommerce: os preços escritos no conteúdo são convertidos para a moeda do visitante.

Primeira versão
Instalações ativas
900+
Classificação
4.1 / 5 (13)Ler avaliações
  • PHP
  • Shortcodes do WordPress
  • Transients
  • Cookies / sessões PHP
  • WP-Cron
  • wp_remote_get
  • SimpleXML / SoapClient
  • MaxMind GeoIP (legacy .dat) e GeoIP2 (.mmdb)
  • PharData
  • admin-ajax
  • jQuery
Ver em wordpress.org wordpress.org

Sobre

O WPCS leva a troca de moeda do WOOCS a sites WordPress comuns: operadores turísticos, anúncios imobiliários, listas de preços de serviços. Os preços são escritos numa moeda base através do shortcode [wpcs_price] ou de um campo post meta e mostrados na moeda que o visitante escolheu ou na que está atribuída ao seu país.

Sem o WooCommerce, o plugin não tem nenhuma da infraestrutura habitual: sem filtros de preços, sem gestor de sessões, sem serviço de geolocalização. Tem de guardar a escolha do visitante por si próprio, obter taxas de câmbio de fontes externas que mudam ou desaparecem, e continuar a funcionar atrás de caches de página inteira que servem o mesmo HTML a todos.

A resposta é um único circuito de preços (taxa, precisão, separadores, template de símbolo), armazenamento por visitante intercambiável, fornecedores de taxas que devolvem uma taxa ou um erro em vez de um zero, e um modo de cache em que os preços são emitidos como spans marcados e voltam a ser apresentados para cada visitante através de uma única chamada AJAX.

A build premium e a build gratuita no wordpress.org partilham a mesma base de código; a build gratuita está limitada a duas moedas.

WPCS · seletor de moeda

o que foi resolvido

ATIVOdesde 2016

Conversão e formatação de preços

shipped · 2016

O que ofereceOs visitantes veem os preços na sua moeda, com o símbolo e os decimais certos. Os proprietários podem acrescentar uma margem às taxas ou definir preços fixos por moeda.

Problema
Os preços nos posts são escritos numa moeda base. Cada visitante tem de os ver convertidos com a taxa, a precisão, os separadores e a posição do símbolo certos, sem as funções de preços do WooCommerce.
Solução

Todos os preços passam por um único circuito: multiplicar pela taxa, formatar com precisão e separadores por moeda, e depois envolver num template de símbolo e num span marcado que guarda o montante base.

Stack
  • PHP
  • Shortcodes
  • number_format
Tarefas · 6
O conteúdo guarda preços apenas na moeda base[wpcs_price] converte um valor literal ou um campo post meta pela taxa atual

O shortcode aceita value, ou meta_value com um post_id opcional; post_id sem meta_value lê a chave meta wpcs_price. price() multiplica pela taxa apenas quando a moeda atual difere da base, e depois passa o número para format_price_numeric() e para o filtro wpcs_price.

price_html() envolve o resultado num span com um ID único e data-amount com o valor base, que o modo de cache de páginas usa mais tarde para o voltar a apresentar.

Alguns preços não devem seguir a taxa de câmbiotype="fixed" aceita montantes por moeda como 'USD:15,EUR:20'

Para preços fixos, o shortcode converte a lista num mapa e mostra o montante da moeda atual, ou 'none' se faltar. A lista de preço em todas as moedas usa o mesmo mapa em vez de converter.

As moedas diferem em cêntimos, decimais e separadoresPrecisão a partir de uma lista de moedas sem cêntimos e de decimais por moeda; separadores por moeda

JPY e TWD são sempre mostrados sem cêntimos; qualquer moeda pode ser acrescentada a essa lista com hide_cents. As definições incluem decimais por moeda e separadores decimal e de milhares por moeda. A escolha do separador é um índice em dois arrays paralelos, em que o índice 0 significa a definição global, de modo que os sites existentes mantêm a sua formatação.

Os sites querem uma margem sobre a taxa de mercado'Interest' por moeda somado à taxa na leitura; a página de definições vê a taxa em bruto

O interest é um montante fixo guardado junto à taxa. get_currencies() soma-o à taxa em todo o lado, exceto na página de definições do plugin, de modo que o administrador edita a taxa limpa enquanto o front end converte com a ajustada. Um filtro wpcs_currency_data_manipulation corre depois disso para regras personalizadas.

Mostrar um preço em todas as moedas e converter entre quaisquer duasPreço formatado convertido de volta para a base e depois convertido para a frente; taxa cruzada para/de

A lista de informação de preço retira o separador de milhares da string já formatada, normaliza o separador decimal, converte de volta para a base com back_convert() (1/taxa) e depois para cada uma das outras moedas. O endpoint [wpcs_converter] usa rate[to] / rate[from], ambas relativas à base, e elimina os cêntimos nas moedas sem cêntimos.

Por vezes um preço tem de aparecer numa só moeda para todos os visitantesfix_currency troca a moeda atual por um preço convertido e depois restaura-a

Para um preço convertido, o shortcode memoriza a moeda do visitante, passa para a moeda pedida se estiver configurada, apresenta e volta atrás, de modo que o resto da página mantém a escolha do visitante.

Fontes e atualizações de taxas de câmbio

shipped · 2016

O que ofereceAs taxas de câmbio atualizam-se sozinhas a partir de várias fontes, e uma atualização falhada nunca transforma um preço em zero.

Problema
As APIs gratuitas de taxas mudam, fecham ou passam a exigir chaves; os bancos nacionais publicam taxas apenas em relação à sua própria moeda; e uma obtenção falhada não deve substituir uma taxa válida por zero.
Solução

Cada fonte é um fornecedor que devolve uma taxa relativa à moeda base do site ou -1 com uma mensagem de erro; o WP-Cron atualiza as taxas e só guarda valores acima de zero.

Stack
  • PHP
  • wp_remote_get
  • SimpleXML
  • SoapClient
  • WP-Cron
Tarefas · 6
As APIs de taxas surgem, mudam e fechamFornecedores resolvidos por nome; nomes desconhecidos vão para um filtro de fontes personalizadas

O changelog regista a instabilidade: Yahoo removido na 1.1.1 (2017), Google removido na 1.1.2 (2018), ambos repostos na 1.1.3 (2018), fontes que deixaram de funcionar removidas de novo na 1.1.3 e na 1.1.4, agregadores personalizados através de um hook na 1.1.5 (2020). Cada fonte é uma classe com getApiUrl() e parseResponse() sobre uma base partilhada RateProvider.

get_rate_provider() faz corresponder o valor da opção a um nome de classe; se não existir classe, wpcs_add_aggregator_processor permite a um site ligar a sua própria fonte, e wpcs_announce_aggregator acrescenta-a à lista das definições. A lista das definições tem 14 fontes.

Os bancos centrais cotam todas as moedas em relação à suaTaxas cruzadas calculadas como rate[to] / rate[base] quando a base do site é diferente

O BCE publica em relação ao EUR, o Banco Nacional da Ucrânia em relação à UAH, o Magyar Nemzeti Bank em relação ao HUF. Cada fornecedor trata três casos: a base é a moeda do banco, o destino é a moeda do banco, nenhum dos dois. A fonte MNB é um serviço SOAP com decimais em vírgula e cotações por unidade (por exemplo 100 JPY), normalizadas antes da divisão.

Uma obtenção falhada não deve definir uma taxa de zeroOs fornecedores devolvem -1 com um erro; o cron só guarda taxas superiores a zero

get_rate() devolve o texto de erro do fornecedor em vez de um número quando a taxa é negativa. rate_auto_update() converte os resultados para float e só substitui uma taxa quando o novo valor é superior a zero, pelo que uma fonte avariada nunca grava zero nem um texto de erro como taxa.

As taxas têm de ser atualizadas sem que um administrador abra as definiçõesEvento do WP-Cron com agendamentos 'week' e 'month' acrescentados

As definições oferecem de hora a hora, duas vezes por dia, diário, semanal ou mensal. O plugin regista os dois intervalos adicionais através de cron_schedules e agenda o evento com o intervalo selecionado no carregamento, quando ainda não está agendado.

Mudar a moeda base invalida todas as taxas guardadassave_etalon() marca a nova base e volta a obter todas as taxas em relação a ela

O handler AJAX guarda o novo indicador is_etalon, define a nova moeda predefinida em memória, pede uma taxa para cada uma das outras moedas através do fornecedor ativo e devolve as taxas ao formulário de definições.

Configurar muitas moedas à mão é lento e propenso a errosTabela incorporada de 118 moedas; a adição em massa obtém taxa e bandeira (interface premium)

WPCS_World_Currencies guarda símbolo, descrição, decimais e código de bandeira por moeda. add_currencies_ajax() adiciona as selecionadas, obtém uma taxa para cada uma, regista símbolos desconhecidos como sinais personalizados e descarrega a bandeira para a biblioteca de multimédia, recorrendo a um URL remoto de bandeira se a transferência falhar. A caixa de diálogo de adição em massa só é mostrada na build premium.

Moeda do visitante e cache de páginas

shipped · 2016

O que ofereceCada visitante mantém a moeda que escolheu mesmo em páginas em cache, pelo que o site pode continuar rápido sem mostrar a moeda de outra pessoa.

Problema
A moeda escolhida pertence a um visitante, mas as caches de página inteira servem o mesmo HTML a todos, e o armazenamento indexado por IP mistura visitantes atrás de um proxy ou NAT.
Solução

Armazenamento por visitante intercambiável, e um modo de cache em que o navegador pede ao admin-ajax para voltar a apresentar todos os spans de preços de uma página em cache na moeda do visitante.

Stack
  • Transients
  • Cookies
  • Sessões PHP
  • admin-ajax
  • jQuery
Tarefas · 5
O HTML em cache mostra a moeda de quem aqueceu a cacheModo de cache: o JS recolhe todos os spans .wpcs_price e volta a apresentá-los num único pedido

Cada span de preço leva um ID único e o montante base. Com a opção de cache ativa, front.js envia os pares id/montante para wpcs_get_prices_html, que resolve a moeda do visitante no servidor e devolve um mapa de id para novo HTML mais a moeda atual; os widgets do seletor são depois sincronizados com ela. O modo existe no código de 2016.

Enquanto os widgets do seletor estão a ser definidos para a moeda devolvida, um indicador impede que os seus eventos de mudança iniciem outra troca de moeda.

Os alojamentos diferem no tipo de armazenamento por visitante que funcionaEstratégia de armazenamento escolhida nas definições: sessão, transient indexado por IP ou cookie

WPCS_STORAGE constrói o backend pelo nome a partir de uma classe abstrata Storage. SessionStorage::create() devolve false quando session_start() falha, e o wrapper recorre então ao armazenamento em transient. Cada valor é sanitizado na escrita.

Visitantes atrás de um IP não devem partilhar uma moeda escolhidaArmazenamento por cookie: UUID aleatório num cookie, valores em transients

O changelog indica o motivo: os transients indexados por IP misturam utilizadores que partilham um endereço. CookieStorage indexa os transients por um cookie UUID. Se os cabeçalhos já tiverem sido enviados quando o ID é criado, imprime um script no rodapé que envia o ID para um endpoint AJAX verificado por nonce, o qual define o cookie a partir de uma resposta limpa.

?currency= nos links divide as caches e passa para URLs partilhadosModo opcional: definir a moeda por AJAX e recarregar, sem parâmetro GET

No modo predefinido, wpcs_redirect() reconstrói o URL atual mantendo os outros parâmetros GET e a âncora #. No modo 'No GET data in link', envia a moeda para wpcs_set_currency_ajax e recarrega. Os parâmetros GET repetidos no script da página são primeiro sanitizados recursivamente.

A moeda de boas-vindas ou geográfica deve aplicar-se uma vez, sem substituir uma escolhaIndicador de primeira visita no armazenamento; a lógica da moeda predefinida só corre enquanto for 0

No primeiro pedido, a moeda de boas-vindas é guardada e o indicador é definido; as regras geográficas também só correm numa primeira visita única. Se uma moeda guardada for removida da lista mais tarde, get_currencies() recorre à base.

Seleção de moeda por Geo-IP

shipped · 2017

O que ofereceOs novos visitantes veem automaticamente a moeda do seu país, com base em regras definidas pelo proprietário, sem pagar por um serviço de localização.

Problema
Sem o WooCommerce não há serviço de geolocalização, pelo que o plugin tem de mapear o IP de um visitante para um país em qualquer alojamento, atrás de proxies e CDNs, sem uma API paga.
Solução

Uma base de dados de países MaxMind incluída, atrás de uma interface de resolução, com uma base de dados GeoIP2 opcional descarregada pelo proprietário do site, e regras de administração que mapeiam países para moedas.

Stack
  • MaxMind GeoIP legacy
  • GeoIP2 / GeoLite2
  • PharData
  • Composer
Tarefas · 4
Deteção de país num site sem WooCommerceMaxMind GeoIP.dat incluído, com o seu leitor PHP

O WC_Geolocation do WooCommerce não está disponível num site WordPress simples, pelo que o plugin traz a sua própria base de dados de países. lib/GeoIP.dat e geoip.inc são envolvidos em OpenIpCountryResolver com uma cache por IP em cada pedido.

O IP real do cliente está escondido atrás de proxies e CDNsLer X-Real-IP, depois o primeiro salto de X-Forwarded-For e depois REMOTE_ADDR

Com a base de dados incluída, um cabeçalho HTTP_CF_IPCOUNTRY da Cloudflare é usado diretamente e a consulta à base de dados é ignorada. Um pedido cujo REMOTE_ADDR seja 127.0.0.1 ou ::1 é resolvido como 8.8.8.8 antes de os cabeçalhos de proxy serem lidos.

Os dados de países legados são menos precisosOpção GeoIP2: GeoLite2 .mmdb descarregado e descompactado na administração

Com uma chave de licença MaxMind, o administrador descarrega o arquivo GeoLite2-Country; o handler descompacta o .tar.gz com PharData, encontra o ficheiro .mmdb, copia-o para uploads/currency-switcher e remove os ficheiros temporários em caso de êxito e de erro. Sem chave, o plugin mantém-se na base de dados incluída. As consultas passam pelo pacote Composer geoip2.

Mapear países para moedas, com uma substituição ao nível do códigoRegras moeda => países; o filtro wpcs_geo_position substitui o país

init_geo_currency() resolve o país, passa-o por wpcs_geo_position, guarda-o para o visitante e aplica a primeira regra correspondente apenas numa primeira visita. [wpcs_check_country] imprime o país detetado para depurar uma regra.

Reforço da segurança da entrada pública

shipped · 2021

O que ofereceOs visitantes anónimos não podem usar o seletor de moeda para injetar conteúdo ou alterar definições, pelo que os preços e as páginas se mantêm como o proprietário os definiu.

Problema
O seletor corre em todas as páginas do front end, expõe endpoints AJAX a visitantes anónimos e aceita atributos de shortcode dos autores, pelo que entradas externas chegam ao HTML, ao armazenamento e às definições.
Solução

Verificar os códigos de moeda do URL e do formulário do seletor em relação à lista configurada, limitar e verificar por padrão os arrays do pedido, escapar atributos e codificar JSON para um contexto HTML.

Stack
  • PHP
  • esc_attr
  • sanitize_text_field
  • Nonces
Tarefas · 5
O endpoint público de preços aceita um array de visitantes anónimosMáximo de 500 itens, verificação de padrão do id, verificações de escalares, saída JSON_HEX_*

wpcs_get_prices_html está disponível para visitantes anónimos. Corta a entrada para 500 registos, aceita apenas ids que correspondam ao conjunto de caracteres de uniqid() usado por price_html(), ignora preços não escalares e codifica a resposta com JSON_HEX_TAG, AMP, APOS e QUOT porque o admin-ajax a serve como text/html.

Os valores dos shortcodes acabam em atributos data do HTMLAtributos data-* construídos com esc_attr() na chave e no valor

price_html() escreve valores que vêm dos atributos de [wpcs_price], como o montante base ou a lista em bruto 'USD:15,EUR:20' de um preço fixo, em atributos data-* do span de preço. As chaves e os valores são escapados e colocados entre aspas, pelo que um valor de atributo não pode injetar marcação.

O endpoint de taxas constrói uma string de shortcode a partir da entrada do pedidoLista de exclusão intersetada com os códigos conhecidos, moeda validada, precisão com intval

wpcs_rates_current_currency passa entrada do visitante para do_shortcode(). Só sobrevivem os códigos de moeda que existem na configuração, o resultado passa por esc_attr, e a precisão é convertida para int, pelo que não pode ser injetada sintaxe de shortcode adicional.

Uma moeda vinda do URL ou do formulário do seletor pode ser qualquer stringValores do URL e do formulário aceites apenas se forem códigos configurados; valores guardados sanitizados

O campo do formulário do seletor de moeda e o parâmetro ?currency= são verificados com array_key_exists() em relação à lista configurada antes de chegarem ao armazenamento, e WPCS_STORAGE::set_val() sanitiza todos os valores.

Os símbolos com entidades HTML quebravam nos envios de ida e volta do formulário de definiçõesSímbolos enviados como hashes md5 e mapeados de volta para a lista de símbolos conhecidos

Símbolos como руб. são guardados como entidades. O select envia md5(símbolo), e o handler de gravação mapeia o hash de volta para a entidade original da lista conhecida, de modo que a entidade não é codificada duas vezes nem tomada da entrada em bruto. A gravação é protegida por check_admin_referer(), e a posição é verificada em relação a uma lista fixa.

Números

wordpress.org
  • Instalações ativas 900+ contador do wordpress.org.
  • Avaliações 13 Média de 4.1 em 5.
  • Anos de suporte 10 Desde 26 de maio de 2016, última atualização em 21 de setembro de 2026.