WPCS
Un sélecteur de devises pour les sites WordPress sans WooCommerce : les prix écrits dans le contenu sont convertis dans la devise du visiteur.
- Première version
- Installations actives
- 900+
- Note
- Lire les avis
À propos
WPCS apporte le changement de devise de WOOCS aux sites WordPress ordinaires : voyagistes, annonces immobilières, listes de tarifs de services. Les prix sont écrits dans une devise de base via le shortcode [wpcs_price] ou un champ post meta, et affichés dans la devise choisie par le visiteur ou celle attribuée à son pays.
Sans WooCommerce, l'extension n'a aucune de l'infrastructure habituelle : pas de filtres de prix, pas de gestionnaire de sessions, pas de service de géolocalisation. Elle doit conserver elle-même le choix du visiteur, récupérer des taux de change auprès de sources externes qui changent ou disparaissent, et continuer à fonctionner derrière des caches de pages complètes qui servent le même HTML à tout le monde.
La réponse est un pipeline de prix unique (taux, précision, séparateurs, modèle de symbole), un stockage par visiteur interchangeable, des fournisseurs de taux qui renvoient un taux ou une erreur plutôt qu'un zéro, et un mode cache dans lequel les prix sont émis sous forme de spans balisés et rendus à nouveau pour chaque visiteur par un seul appel AJAX.
La version premium et la version gratuite de wordpress.org partagent une seule base de code ; la version gratuite est limitée à deux devises.
WPCS · sélecteur de devises
ce qui a été résolu
Conversion et formatage des prix
shipped · 2016Ce que cela apporteLes visiteurs voient les prix dans leur devise avec le bon symbole et les bonnes décimales. Les propriétaires peuvent ajouter une marge aux taux ou fixer des prix par devise.
- Problème
- Les prix des articles sont écrits dans une seule devise de base. Chaque visiteur doit les voir convertis avec le bon taux, la bonne précision, les bons séparateurs et la bonne position du symbole, sans les fonctions de prix de WooCommerce.
- Solution
Tous les prix passent par un pipeline unique : multiplication par le taux, formatage avec la précision et les séparateurs de chaque devise, puis enveloppe dans un modèle de symbole et un span balisé qui conserve le montant de base.
- Stack
Le contenu ne contient que des prix dans la devise de base[wpcs_price] convertit une valeur littérale ou un champ post meta avec le taux courant
Le shortcode accepte value, ou meta_value avec un post_id facultatif ; post_id sans meta_value lit la clé meta wpcs_price. price() ne multiplie par le taux que si la devise courante diffère de la devise de base, puis transmet le nombre à format_price_numeric() et au filtre wpcs_price.
price_html() enveloppe le résultat dans un span avec un ID unique et data-amount contenant la valeur de base, que le mode cache de page utilise plus tard pour le rendre à nouveau.
Certains prix ne doivent pas suivre le taux de changetype="fixed" accepte des montants par devise comme 'USD:15,EUR:20'
Pour les prix fixes, le shortcode analyse la liste en une table et affiche le montant de la devise courante, ou 'none' s'il est absent. La liste des prix dans toutes les devises utilise la même table au lieu de convertir.
Les devises diffèrent par les centimes, les décimales et les séparateursPrécision issue d'une liste de devises sans centimes et de décimales par devise ; séparateurs par devise
JPY et TWD sont toujours affichés sans centimes ; n'importe quelle devise peut être ajoutée à cette liste avec hide_cents. Les réglages comprennent les décimales par devise ainsi que les séparateurs décimal et des milliers par devise. Le choix du séparateur est un index dans deux tableaux parallèles, où l'index 0 signifie le réglage global, de sorte que les sites existants gardent leur formatage.
Les sites veulent une marge au-dessus du taux du marché« Intérêt » par devise ajouté au taux à la lecture ; la page de réglages voit le taux brut
L'intérêt est un montant fixe stocké à côté du taux. get_currencies() l'ajoute au taux partout sauf sur la page de réglages de l'extension, si bien que l'administrateur modifie le taux brut tandis que le front office convertit avec le taux ajusté. Un filtre wpcs_currency_data_manipulation s'exécute ensuite pour les règles personnalisées.
Afficher un prix dans toutes les devises, et convertir entre deux devises quelconquesPrix formaté ré-analysé en base, puis converti vers l'avant ; taux croisé de/vers
La liste d'informations de prix retire le séparateur des milliers de la chaîne déjà formatée, normalise le séparateur décimal, reconvertit en base avec back_convert() (1/rate) puis convertit vers chacune des autres devises. Le point d'accès [wpcs_converter] utilise rate[to] / rate[from], tous deux relatifs à la base, et supprime les centimes pour les devises sans centimes.
Un prix doit parfois s'afficher dans une seule devise pour tous les visiteursfix_currency remplace la devise courante pour un prix converti, puis la restaure
Pour un prix converti, le shortcode mémorise la devise du visiteur, bascule sur la devise demandée si elle est configurée, effectue le rendu, puis rebascule pour que le reste de la page garde le choix du visiteur.
Sources et mises à jour des taux de change
shipped · 2016Ce que cela apporteLes taux de change se mettent à jour d'eux-mêmes à partir de plusieurs sources, et une mise à jour échouée ne transforme jamais un prix en zéro.
- Problème
- Les API de taux gratuites changent, ferment ou se mettent à exiger des clés ; les banques nationales ne publient des taux que par rapport à leur propre devise ; et une récupération échouée ne doit pas remplacer un taux valide par zéro.
- Solution
Chaque source est un fournisseur qui renvoie un taux relatif à la devise de base du site ou -1 avec un message d'erreur ; WP-Cron rafraîchit les taux et n'enregistre que les valeurs supérieures à zéro.
- Stack
Les API de taux apparaissent, changent et fermentFournisseurs résolus par leur nom ; les noms inconnus vont à un filtre pour les sources personnalisées
Le changelog garde la trace de ces mouvements : Yahoo retiré en 1.1.1 (2017), Google retiré en 1.1.2 (2018), les deux rajoutés en 1.1.3 (2018), sources qui ont cessé de fonctionner retirées à nouveau en 1.1.3 et 1.1.4, agrégateurs personnalisés via un hook en 1.1.5 (2020). Chaque source est une classe avec getApiUrl() et parseResponse() sur une base commune RateProvider.
get_rate_provider() associe la valeur de l'option à un nom de classe ; si aucune classe n'existe, wpcs_add_aggregator_processor permet à un site de brancher sa propre source, et wpcs_announce_aggregator l'ajoute à la liste des réglages. La liste des réglages compte 14 sources.
Les banques centrales cotent chaque devise par rapport à la leurTaux croisés calculés comme rate[to] / rate[base] lorsque la base du site diffère
La BCE publie par rapport à l'EUR, la Banque nationale d'Ukraine par rapport à l'UAH, la Magyar Nemzeti Bank par rapport au HUF. Chaque fournisseur gère trois cas : la base est la devise de la banque, la cible est la devise de la banque, aucune des deux. La source MNB est un service SOAP avec des décimales à virgule et des cotations par unités (par exemple 100 JPY), normalisées avant la division.
Une récupération échouée ne doit pas fixer un taux de zéroLes fournisseurs renvoient -1 avec une erreur ; le cron n'enregistre que les taux supérieurs à zéro
get_rate() renvoie le texte d'erreur du fournisseur au lieu d'un nombre lorsque le taux est négatif. rate_auto_update() convertit les résultats en float et ne remplace un taux que lorsque la nouvelle valeur est supérieure à zéro, si bien qu'une source défaillante n'écrit jamais zéro ni un texte d'erreur comme taux.
Les taux doivent se rafraîchir sans qu'un administrateur ouvre les réglagesÉvénement WP-Cron avec des planifications « week » et « month » ajoutées
Les réglages proposent toutes les heures, deux fois par jour, tous les jours, toutes les semaines ou tous les mois. L'extension enregistre les deux intervalles supplémentaires via cron_schedules et planifie l'événement avec l'intervalle sélectionné au chargement lorsqu'il n'est pas encore planifié.
Changer la devise de base invalide tous les taux stockéssave_etalon() marque la nouvelle base et récupère à nouveau chaque taux par rapport à elle
Le gestionnaire AJAX enregistre le nouvel indicateur is_etalon, définit en mémoire la nouvelle devise par défaut, demande un taux pour chaque autre devise via le fournisseur actif et renvoie les taux au formulaire de réglages.
Configurer de nombreuses devises à la main est lent et sujet aux erreursTable intégrée de 118 devises ; l'ajout en masse récupère le taux et le drapeau (interface premium)
WPCS_World_Currencies contient le symbole, la description, les décimales et le code du drapeau de chaque devise. add_currencies_ajax() ajoute celles qui sont sélectionnées, récupère un taux pour chacune, enregistre les symboles inconnus comme signes personnalisés et télécharge le drapeau dans la médiathèque, avec repli sur une URL de drapeau distante si le téléchargement échoue. La boîte de dialogue d'ajout en masse n'est affichée que dans la version premium.
Devise du visiteur et cache des pages
shipped · 2016Ce que cela apporteChaque visiteur garde la devise qu'il a choisie, même sur des pages en cache, si bien que le site peut rester rapide sans montrer la devise de quelqu'un d'autre.
- Problème
- La devise choisie appartient à un seul visiteur, mais les caches de pages complètes servent le même HTML à tout le monde, et un stockage indexé par IP mélange les visiteurs derrière un même proxy ou NAT.
- Solution
Stockage par visiteur interchangeable, et mode cache dans lequel le navigateur demande à admin-ajax de rendre à nouveau tous les spans de prix d'une page en cache pour la devise du visiteur.
- Stack
Le HTML en cache montre la devise de celui qui a réchauffé le cacheMode cache : le JS collecte tous les spans .wpcs_price et les rend à nouveau en une seule requête
Chaque span de prix porte un ID unique et le montant de base. Avec l'option cache activée, front.js envoie les paires id/montant à wpcs_get_prices_html, qui résout la devise du visiteur côté serveur et renvoie une table d'ID vers le nouveau HTML ainsi que la devise courante ; les widgets de sélection sont ensuite synchronisés avec elle. Ce mode est présent dans le code de 2016.
Pendant que les widgets de sélection sont réglés sur la devise renvoyée, un indicateur empêche leurs événements de changement de lancer un autre changement de devise.
Les hébergeurs diffèrent par le type de stockage par visiteur qui fonctionneStratégie de stockage choisie dans les réglages : session, transient indexé par IP ou cookie
WPCS_STORAGE construit le backend par son nom à partir d'une classe abstraite Storage. SessionStorage::create() renvoie false lorsque session_start() échoue, et l'enveloppe se rabat alors sur le stockage par transient. Chaque valeur est assainie à l'écriture.
Des visiteurs derrière une même IP ne doivent pas partager la même devise choisieStockage par cookie : UUID aléatoire dans un cookie, valeurs dans des transients
Le changelog en donne la raison : les transients indexés par IP mélangent les utilisateurs qui partagent une adresse. CookieStorage indexe les transients par un cookie UUID. Si les en-têtes sont déjà envoyés quand l'ID est créé, il affiche un script de pied de page qui envoie l'ID à un point d'accès AJAX protégé par nonce, lequel définit le cookie à partir d'une réponse propre.
?currency= dans les liens divise les caches et fuit dans les URL partagéesMode facultatif : définir la devise en AJAX et recharger, sans paramètre GET
Dans le mode par défaut, wpcs_redirect() reconstruit l'URL courante en gardant les autres paramètres GET et l'ancre #. Dans le mode « No GET data in link », elle envoie la devise à wpcs_set_currency_ajax et recharge. Les paramètres GET repris dans le script de la page sont d'abord assainis de façon récursive.
La devise de bienvenue ou géographique doit s'appliquer une fois, sans écraser un choixIndicateur de première visite dans le stockage ; la logique de la devise par défaut ne s'exécute que tant qu'il vaut 0
À la première requête, la devise de bienvenue est stockée et l'indicateur est posé ; les règles géographiques ne s'exécutent aussi que pour une première visite unique. Si une devise stockée est retirée plus tard de la liste, get_currencies() se rabat sur la devise de base.
Sélection de la devise par géolocalisation IP
shipped · 2017Ce que cela apporteLes nouveaux visiteurs voient automatiquement la devise de leur pays, selon les règles définies par le propriétaire, sans payer de service de localisation.
- Problème
- Sans WooCommerce, il n'y a pas de service de géolocalisation ; l'extension doit donc associer l'IP d'un visiteur à un pays sur n'importe quel hébergeur, derrière des proxys et des CDN, sans API payante.
- Solution
Une base de pays MaxMind intégrée derrière une interface de résolveur, avec une base GeoIP2 facultative téléchargée par le propriétaire du site, et des règles d'administration qui associent des pays à des devises.
- Stack
Détection du pays sur un site sans WooCommerceMaxMind GeoIP.dat intégré avec son lecteur PHP
WC_Geolocation de WooCommerce n'est pas disponible sur un WordPress ordinaire ; l'extension embarque donc sa propre base de pays. lib/GeoIP.dat et geoip.inc sont enveloppés dans OpenIpCountryResolver avec un cache par requête indexé par IP.
La vraie IP du client est cachée derrière des proxys et des CDNLire X-Real-IP, puis le premier saut de X-Forwarded-For, puis REMOTE_ADDR
Avec la base intégrée, un en-tête Cloudflare HTTP_CF_IPCOUNTRY est utilisé directement et la recherche dans la base est ignorée. Une requête dont REMOTE_ADDR est 127.0.0.1 ou ::1 est résolue comme 8.8.8.8 avant la lecture des en-têtes de proxy.
Les données de pays historiques sont moins précisesOption GeoIP2 : .mmdb GeoLite2 téléchargé et décompressé dans l'administration
Avec une clé de licence MaxMind, l'administrateur télécharge l'archive GeoLite2-Country ; le gestionnaire décompresse le .tar.gz avec PharData, trouve le fichier .mmdb, le copie dans uploads/currency-switcher et supprime les fichiers temporaires en cas de succès comme d'erreur. Sans clé, l'extension reste sur la base intégrée. Les recherches passent par le paquet Composer geoip2.
Associer des pays à des devises, avec une surcharge au niveau du codeRègles devise => pays ; le filtre wpcs_geo_position remplace le pays
init_geo_currency() résout le pays, le fait passer par wpcs_geo_position, le stocke pour le visiteur et applique la première règle correspondante lors d'une première visite seulement. [wpcs_check_country] affiche le pays détecté pour déboguer une règle.
Durcissement des entrées publiques
shipped · 2021Ce que cela apporteLes visiteurs anonymes ne peuvent pas détourner le sélecteur de devises pour injecter du contenu ou modifier les réglages, si bien que les prix et les pages restent tels que le propriétaire les a définis.
- Problème
- Le sélecteur s'exécute sur chaque page publique, expose des points d'accès AJAX à des visiteurs anonymes et prend des attributs de shortcode venant des auteurs, si bien que des entrées extérieures atteignent le HTML, le stockage et les réglages.
- Solution
Vérifier les codes de devise de l'URL et du formulaire de sélection par rapport à la liste configurée, plafonner et contrôler par motif les tableaux de la requête, échapper les attributs, et encoder le JSON pour un contexte HTML.
- Stack
Le point d'accès public des prix reçoit un tableau de visiteurs anonymes500 éléments au maximum, contrôle du motif des ID, contrôles de scalaires, sortie JSON_HEX_*
wpcs_get_prices_html est accessible aux visiteurs anonymes. Il découpe l'entrée à 500 éléments, n'accepte que les ID qui correspondent au jeu de caractères de uniqid() utilisé par price_html(), ignore les prix non scalaires, et encode la réponse avec JSON_HEX_TAG, AMP, APOS et QUOT car admin-ajax la sert en text/html.
Des valeurs de shortcode se retrouvent dans des attributs data HTMLAttributs data-* construits avec esc_attr() sur la clé et la valeur
price_html() écrit dans des attributs data-* du span de prix des valeurs issues des attributs de [wpcs_price], comme le montant de base ou la liste brute 'USD:15,EUR:20' d'un prix fixe. Les clés et les valeurs sont échappées et entre guillemets, de sorte qu'une valeur d'attribut ne peut pas injecter de balisage.
Le point d'accès des taux construit une chaîne de shortcode à partir de la requêteListe d'exclusion croisée avec les codes connus, devise validée, precision passée par intval
wpcs_rates_current_currency transmet une entrée de visiteur à do_shortcode(). Seuls survivent les codes de devise présents dans la configuration, le résultat passe par esc_attr, et la précision est convertie en entier, de sorte qu'aucune syntaxe de shortcode supplémentaire ne peut être injectée.
Une devise venant de l'URL ou du formulaire de sélection peut être n'importe quelle chaîneValeurs de l'URL et du formulaire acceptées seulement si ce sont des codes configurés ; valeurs stockées assainies
Le champ du formulaire de sélection de devise et le paramètre ?currency= sont vérifiés avec array_key_exists() par rapport à la liste configurée avant d'atteindre le stockage, et WPCS_STORAGE::set_val() assainit chaque valeur.
Les symboles en entités HTML se cassaient lors des allers-retours du formulaire de réglagesSymboles envoyés sous forme de hachages md5 et associés à la liste de symboles connus
Des symboles tels que руб. sont stockés comme entités. Le select envoie md5(symbole), et le gestionnaire d'enregistrement associe le hachage à l'entité d'origine de la liste connue, si bien que l'entité n'est ni encodée deux fois ni prise dans une entrée brute. L'enregistrement est protégé par check_admin_referer(), et la position est vérifiée par rapport à une liste fixe.
Chiffres
wordpress.org- Installations actives 900+ compteur de wordpress.org.
- Avis 13 Moyenne de 4.1 sur 5.
- Années de maintenance 10 Depuis 26 mai 2016, dernière mise à jour 21 septembre 2026.