WPCS
Перемикач валют для сайтів WordPress без WooCommerce: ціни, записані у вмісті, конвертуються у валюту відвідувача.
- Перший реліз
- Активні встановлення
- 900+
- Рейтинг
- Читати відгуки
Про мене
WPCS переносить перемикання валют із WOOCS на звичайні сайти WordPress: туроператори, оголошення про нерухомість, прайси послуг. Ціни записуються в одній базовій валюті через шорткод [wpcs_price] або поле post meta й показуються у валюті, яку вибрав відвідувач, або в тій, що призначена його країні.
Без WooCommerce плагін не має звичної інфраструктури: ні фільтрів цін, ні обробника сесій, ні сервісу геолокації. Він мусить сам зберігати вибір відвідувача, отримувати курси валют із зовнішніх джерел, які змінюються або зникають, і працювати за повносторінкових кешів, що віддають усім один HTML.
Відповідь — єдиний конвеєр цін (курс, точність, роздільники, шаблон символу), підключуване сховище для кожного відвідувача, постачальники курсів, які повертають курс або помилку замість нуля, і режим кешу, в якому ціни виводяться як позначені span-и й перемальовуються для кожного відвідувача одним AJAX-викликом.
Преміум-збірка й безкоштовна збірка на wordpress.org мають одну кодову базу; безкоштовна збірка обмежена двома валютами.
WPCS · перемикач валют
що розв'язано
Конвертація та форматування цін
shipped · 2016Що це даєВідвідувачі бачать ціни у своїй валюті з правильним символом і десятковими знаками. Власники можуть додавати маржу до курсів або задавати фіксовані ціни для кожної валюти.
- Проблема
- Ціни в записах записано в одній базовій валюті. Кожен відвідувач має бачити їх, конвертованими за правильним курсом, з правильними точністю, роздільниками й положенням символу — без цінових функцій WooCommerce.
- Рішення
Усі ціни проходять через один конвеєр: помножити на курс, відформатувати з точністю й роздільниками для кожної валюти, а потім обгорнути в шаблон символу та позначений span, що зберігає базову суму.
- Стек
Вміст містить ціни лише в базовій валюті[wpcs_price] конвертує буквальне значення або мета-поле запису за поточним курсом
Шорткод приймає value або meta_value з необов'язковим post_id; post_id без meta_value читає мета-ключ wpcs_price. price() множить на курс лише тоді, коли поточна валюта відрізняється від базової, а потім передає число у format_price_numeric() і фільтр wpcs_price.
price_html() обгортає результат у span з унікальним id і data-amount, що містить базове значення, яке режим кешу сторінок згодом використовує для перемальовування.
Деякі ціни не повинні слідувати за курсом валютtype="fixed" приймає суми для кожної валюти на кшталт 'USD:15,EUR:20'
Для фіксованих цін шорткод розбирає список у карту й показує суму для поточної валюти або 'none', якщо її немає. Список цін у всіх валютах використовує ту саму карту замість конвертації.
Валюти відрізняються копійками, десятковими знаками й роздільникамиТочність зі списку валют без копійок і десяткових знаків для кожної валюти; роздільники для кожної валюти
JPY і TWD завжди показуються без копійок; будь-яку валюту можна додати до цього списку через hide_cents. Налаштування містять десяткові знаки для кожної валюти та роздільники десяткової частини й тисяч для кожної валюти. Вибір роздільника — це індекс у двох паралельних масивах, де індекс 0 означає глобальне налаштування, тож наявні сайти зберігають своє форматування.
Сайтам потрібна маржа поверх ринкового курсу'Interest' для кожної валюти додається до курсу під час читання; сторінка налаштувань бачить сирий курс
Interest — це фіксована сума, що зберігається поруч із курсом. get_currencies() додає її до курсу скрізь, крім сторінки налаштувань плагіна, тож адміністратор редагує чистий курс, а фронтенд конвертує з коригованим. Після цього для власних правил виконується фільтр wpcs_currency_data_manipulation.
Показати одну ціну в усіх валютах і конвертувати між будь-якими двомаВідформатована ціна розбирається назад до базової, потім конвертується вперед; крос-курс to/from
Список інформації про ціну прибирає роздільник тисяч із уже відформатованого рядка, нормалізує роздільник десяткової частини, конвертує назад у базову через back_convert() (1/rate), а потім уперед у кожну іншу валюту. Точка [wpcs_converter] використовує rate[to] / rate[from], обидва відносно бази, і відкидає копійки для валют без копійок.
Іноді ціна має показуватися в одній валюті для всіх відвідувачівfix_currency підміняє поточну валюту на час однієї конвертованої ціни, а потім відновлює її
Для конвертованої ціни шорткод запам'ятовує валюту відвідувача, перемикається на запитану, якщо вона налаштована, відображає ціну й перемикається назад, тож решта сторінки зберігає вибір відвідувача.
Джерела курсів валют та оновлення
shipped · 2016Що це даєКурси валют оновлюються самі з кількох джерел, а невдале оновлення ніколи не перетворює ціну на нуль.
- Проблема
- Безкоштовні API курсів змінюються, закриваються або починають вимагати ключі; національні банки публікують курси лише відносно власної валюти; а невдале отримання не повинно замінювати робочий курс нулем.
- Рішення
Кожне джерело — це постачальник, що повертає курс відносно базової валюти сайту або -1 з повідомленням про помилку; WP-Cron оновлює курси й зберігає лише значення, більші за нуль.
- Стек
API курсів з'являються, змінюються й закриваютьсяПостачальники визначаються за назвою; невідомі назви йдуть у фільтр для власних джерел
Журнал змін фіксує цю плинність: Yahoo вилучено в 1.1.1 (2017), Google вилучено в 1.1.2 (2018), обидва повернуто в 1.1.3 (2018), джерела, що перестали працювати, знову вилучено в 1.1.3 і 1.1.4, власні агрегатори через хук — у 1.1.5 (2020). Кожне джерело — це клас з getApiUrl() і parseResponse() на спільній базі RateProvider.
get_rate_provider() зіставляє значення опції з назвою класу; якщо класу немає, wpcs_add_aggregator_processor дозволяє сайту підключити власне джерело, а wpcs_announce_aggregator додає його до списку в налаштуваннях. У списку налаштувань 14 джерел.
Центральні банки котирують кожну валюту відносно власноїКрос-курси обчислюються як rate[to] / rate[base], коли база сайту відрізняється
ECB публікує відносно EUR, Національний банк України — відносно UAH, Magyar Nemzeti Bank — відносно HUF. Кожен постачальник обробляє три випадки: база — валюта банку, ціль — валюта банку, жодна з них. Джерело MNB — це SOAP-сервіс з комами як десятковими роздільниками та котируваннями за одиницю (наприклад, 100 JPY), які нормалізуються перед діленням.
Невдале отримання не повинно задавати курс, що дорівнює нулюПостачальники повертають -1 з помилкою; cron зберігає лише курси, більші за нуль
get_rate() повертає текст помилки постачальника замість числа, коли курс від'ємний. rate_auto_update() приводить результати до float і замінює курс лише тоді, коли нове значення більше за нуль, тож зламане джерело ніколи не запише нуль чи текст помилки як курс.
Курси мають оновлюватися без того, щоб адміністратор відкривав налаштуванняПодія WP-Cron з доданими розкладами 'week' і 'month'
Налаштування пропонують щогодини, двічі на день, щодня, щотижня або щомісяця. Плагін реєструє два додаткові інтервали через cron_schedules і при завантаженні планує подію з вибраним інтервалом, якщо вона ще не запланована.
Зміна базової валюти робить недійсними всі збережені курсиsave_etalon() позначає нову базу й заново отримує кожен курс відносно неї
Обробник AJAX зберігає новий прапорець is_etalon, задає нову валюту за замовчуванням у пам'яті, запитує курс для кожної іншої валюти через активного постачальника й повертає курси у форму налаштувань.
Налаштування багатьох валют вручну повільне й схильне до помилокВбудована таблиця зі 118 валют; масове додавання отримує курс і прапор (UI преміуму)
WPCS_World_Currencies зберігає символ, опис, десяткові знаки й код прапора для кожної валюти. add_currencies_ajax() додає вибрані, отримує курс для кожної, реєструє невідомі символи як власні знаки та завантажує прапор у медіатеку, а якщо завантаження не вдається, використовує віддалений URL прапора. Діалог масового додавання показується лише в преміум-збірці.
Валюта відвідувача та кешування сторінок
shipped · 2016Що це даєКожен відвідувач зберігає вибрану валюту навіть на закешованих сторінках, тож сайт може лишатися швидким, не показуючи чужу валюту.
- Проблема
- Вибрана валюта належить одному відвідувачеві, але повносторінкові кеші віддають усім один HTML, а сховище з ключем за IP змішує відвідувачів за одним проксі чи NAT.
- Рішення
Підключуване сховище для кожного відвідувача та режим кешу, в якому браузер просить admin-ajax перемалювати всі span-и цін закешованої сторінки для валюти відвідувача.
- Стек
Закешований HTML показує валюту того, хто прогрів кешРежим кешу: JS збирає всі span-и .wpcs_price і перемальовує їх одним запитом
Кожен span ціни має унікальний id і базову суму. З увімкненою опцією кешу front.js надсилає пари id/сума на wpcs_get_prices_html, який визначає валюту відвідувача на сервері й повертає карту id → новий HTML плюс поточну валюту; віджети перемикача після цього синхронізуються з нею. Цей режим присутній у коді 2016 року.
Поки віджети перемикача встановлюються на повернену валюту, прапорець не дає їхнім подіям change запустити ще одне перемикання валюти.
Хостинги відрізняються тим, яке сховище для кожного відвідувача працюєСтратегія сховища вибирається в налаштуваннях: сесія, transient за ключем IP або cookie
WPCS_STORAGE будує бекенд за назвою з абстрактного класу Storage. SessionStorage::create() повертає false, коли session_start() не вдається, і тоді обгортка переходить на сховище transient. Кожне значення санітизується при записі.
Відвідувачі за одним IP не повинні ділити одну вибрану валютуСховище cookie: випадковий UUID у cookie, значення в transients
Журнал змін називає причину: transients з ключем за IP змішують користувачів, що мають одну адресу. CookieStorage ключує transients за UUID із cookie. Якщо заголовки вже надіслано, коли створюється ID, він виводить скрипт у футері, який надсилає ID на AJAX-точку з перевіркою nonce, а та встановлює cookie з чистої відповіді.
?currency= у посиланнях розколює кеші й потрапляє в поширювані URLНеобов'язковий режим: задавати валюту через AJAX і перезавантажувати, без GET-параметра
У режимі за замовчуванням wpcs_redirect() перебудовує поточний URL, зберігаючи інші GET-параметри та #якір. У режимі 'No GET data in link' він надсилає валюту на wpcs_set_currency_ajax і перезавантажує сторінку. GET-параметри, виведені у скрипт сторінки, спершу рекурсивно санітизуються.
Вітальна або гео-валюта має застосовуватися один раз і не перевизначати вибірПрапорець першого візиту в сховищі; логіка валюти за замовчуванням виконується, лише поки він 0
У першому запиті вітальна валюта зберігається й прапорець встановлюється; гео-правила також виконуються лише для першого унікального візиту. Якщо збережену валюту пізніше видалено зі списку, get_currencies() повертається до базової.
Вибір валюти за Geo-IP
shipped · 2017Що це даєНові відвідувачі автоматично бачать валюту своєї країни за правилами, які задає власник, без оплати сервісу визначення місцезнаходження.
- Проблема
- Без WooCommerce немає сервісу геолокації, тому плагін мусить зіставляти IP відвідувача з країною на будь-якому хостингу, за проксі й CDN, без платного API.
- Рішення
Вбудована база країн MaxMind за інтерфейсом резолвера, з необов'язковою базою GeoIP2, яку завантажує власник сайту, та правилами адмінки, що зіставляють країни з валютами.
- Стек
Визначення країни на сайті без WooCommerceВбудований MaxMind GeoIP.dat з його PHP-читачем
WC_Geolocation від WooCommerce недоступний на простому сайті WordPress, тож плагін постачає власну базу країн. lib/GeoIP.dat і geoip.inc обгорнуті в OpenIpCountryResolver з кешем за IP у межах запиту.
Справжній IP клієнта прихований за проксі та CDNЧитати X-Real-IP, потім перший хоп X-Forwarded-For, потім REMOTE_ADDR
З вбудованою базою заголовок Cloudflare HTTP_CF_IPCOUNTRY використовується напряму, а пошук у базі пропускається. Запит, чий REMOTE_ADDR дорівнює 127.0.0.1 або ::1, розв'язується як 8.8.8.8 до читання заголовків проксі.
Застарілі дані про країни менш точніОпція GeoIP2: GeoLite2 .mmdb завантажується й розпаковується в адмінці
З ліцензійним ключем MaxMind адміністратор завантажує архів GeoLite2-Country; обробник розпаковує .tar.gz через PharData, знаходить файл .mmdb, копіює його в uploads/currency-switcher і видаляє тимчасові файли і при успіху, і при помилці. Без ключа плагін лишається на вбудованій базі. Пошук іде через пакет Composer geoip2.
Зіставити країни з валютами, з перевизначенням на рівні кодуПравила валюта => країни; фільтр wpcs_geo_position перевизначає країну
init_geo_currency() визначає країну, пропускає її через wpcs_geo_position, зберігає для відвідувача й застосовує перше підхоже правило лише під час першого візиту. [wpcs_check_country] виводить виявлену країну для налагодження правила.
Захист публічного вводу
shipped · 2021Що це даєАнонімні відвідувачі не можуть зловжити перемикачем валют, щоб вставити вміст або змінити налаштування, тож ціни й сторінки лишаються такими, як їх задав власник.
- Проблема
- Перемикач працює на кожній сторінці фронтенду, відкриває AJAX-точки анонімним відвідувачам і приймає атрибути шорткодів від авторів, тож зовнішній ввід потрапляє в HTML, сховище й налаштування.
- Рішення
Перевіряти коди валют з URL і форми перемикача за налаштованим списком, обмежувати й перевіряти за шаблоном масиви запиту, екранувати атрибути та кодувати JSON для контексту HTML.
- Стек
Публічна точка цін приймає масив від анонімних відвідувачівМаксимум 500 елементів, перевірка id за шаблоном, перевірки на скаляри, вивід JSON_HEX_*
wpcs_get_prices_html доступна анонімним відвідувачам. Вона обрізає ввід до 500 записів, приймає лише id, що відповідають набору символів uniqid(), який використовує price_html(), пропускає нескалярні ціни й кодує відповідь із JSON_HEX_TAG, AMP, APOS і QUOT, бо admin-ajax віддає її як text/html.
Значення шорткодів потрапляють в атрибути даних HTMLАтрибути data-* будуються з esc_attr() для ключа й значення
price_html() записує значення, що надходять з атрибутів [wpcs_price], як-от базова сума або сирий список 'USD:15,EUR:20' фіксованої ціни, в атрибути data-* span-а ціни. Ключі й значення екрануються та беруться в лапки, тож значення атрибута не може вставити розмітку.
Точка курсів будує рядок шорткоду зі вводу запитуСписок виключень перетинається з відомими кодами, валюта перевіряється, точність через intval
wpcs_rates_current_currency передає ввід відвідувача в do_shortcode(). Виживають лише коди валют, що є в конфігурації, результат проходить esc_attr, а точність приводиться до int, тож додатковий синтаксис шорткодів вставити не можна.
Валюта з URL чи форми перемикача може бути будь-яким рядкомЗначення з URL і форми приймаються лише якщо це налаштовані коди; збережені значення санітизуються
Поле форми перемикача валют і параметр ?currency= перевіряються через array_key_exists() за налаштованим списком до потрапляння в сховище, а WPCS_STORAGE::set_val() санітизує кожне значення.
Символи у вигляді HTML-сутностей ламалися при круговому проходженні форми налаштуваньСимволи надсилаються як хеші md5 і зіставляються назад зі списком відомих символів
Символи на кшталт руб. зберігаються як сутності. Select надсилає md5(symbol), а обробник збереження зіставляє хеш назад з оригінальною сутністю зі списку відомих, тож сутність не кодується двічі й не береться із сирого вводу. Збереження захищене check_admin_referer(), а position перевіряється за фіксованим списком.
Цифри
wordpress.org- Активні встановлення 900+ лічильник wordpress.org.
- Відгуки 13 Середня оцінка: 4.1 з 5.
- Років підтримки 10 З 26 травня 2016 р., останнє оновлення 21 вересня 2026 р..