Внутренний курс валют в магазине на WooCommerce + Автообновление с cbr.ru

Бывает такой юзкейс: цена на товар должна заполняться в евро, долларах или юанях (да хоть в биткоинах :)), а выводиться на фронтенде только в рублях, по актуальному курсу. Обычно такое случается, когда закуп идет напрямую у производителя, а курс национальной валюты нестабилен.

На этой картинке все прекрасно

Я искал решение, но большинство WordPress плагинов не совсем подходило для этой задачи — в основном, это были switcher’ы (переключатели) курсов, различные выпадающие списки, кнопки и пр. Главная проблема, что указывать цену в валюте нужно было только в одном месте, при добавлении/редактировании товара, а во всех других местах были только рубли: при просмотре списка товаров, что на самом сайте, что в админке, в карточке, при оформлении заказа, в списках заказов, т. е. везде. А эти плагины меняли курс, в лучшем случае, только на всей пользовательской части сайта + переключатель для этой задачи не нужен.

Самым подходящим нашелся плагин Currency per Product for WooCommerce.
Но он требовал некоторых доработок. Эти доработки я оформил в виде плагина-дополнения для этого плагина 🙂

По сути доработаны 2 вещи: автообновление курса с сайта Центрального банка Российской Федерации и автовыбор валюты по умолчанию на странице редактирования товара.
В премиум версии плагина Currency per Product есть автообновление курса, но нет ЦБ РФ в списке источников, да и зачем платить, когда можно сделать все самому)

Плагин очень прост, я разберу его код по частям, возможно какие-то фрагменты кода окажутся полезными не только в рамках этой задачи.

Ну давай разберем по частям, тобою написанное

Я не стал делать страницу с опциями плагина, а просто вынес конфиг в константы:

define('CPP_EXCHANGE_RATE_OPTION', 'alg_wc_cpp_exchange_rate_1'); // Это WP option куда Currency per Product for WooCommerce сохраняет курсы валют
define('CPP_CBR_VALUTE_ID', 'R01239'); // ID валюты в XML-фиде с cbr.ru
define('CPP_DEFAULT_VAL', 'EUR'); // Валюта в которой задается цена товара

Функция получения курса валют из XML-фида cbr.ru
И обновление опции alg_wc_cpp_exchange_rate_1

function cppcbr_update_currency() {
    $doc = new \DOMDocument();
    $doc->load('http://www.cbr.ru/scripts/XML_daily.asp');
    $xpath = new \DOMXPath($doc);
    $curs = (float) str_replace(',', '.', $xpath->query('/ValCurs/Valute[@ID="' . CPP_CBR_VALUTE_ID . '"]/Value')->item(0)->textContent);
    if (!$curs)
        return false;
    $curs = 1 / $curs;
    return update_option(CPP_EXCHANGE_RATE_OPTION, $curs);
}

Назначаем эту функцию обработчиком хука WP Cron задания cppcbr_schedule

add_action('cppcbr_schedule', 'cppcbr_update_currency');

Само задание крон cppcbr_schedule добавляем при активации плагина:

function cppcbr_activation() {
    if (!wp_next_scheduled('cppcbr_hourly_event')) {
        wp_schedule_event(time(), 'hourly', 'cppcbr_schedule');
    }
}

register_activation_hook(__FILE__, 'cppcbr_activation');

Ну и не забудем удалить его при дезактивации:

function cppcbr_deactivation() {
    wp_clear_scheduled_hook('cppcbr_schedule');
}

register_deactivation_hook(__FILE__, 'cppcbr_deactivation');

Автовыбор валюты по умолчанию на странице редактирования товара:

function cppcbr_woocommerce_currency($woocommerce_currency) {
    if (!is_admin())
        return $woocommerce_currency;
    global $pagenow;
    if ($pagenow == 'post-new.php') {
        return CPP_DEFAULT_VAL;
    }
    return $woocommerce_currency;
}

add_filter('woocommerce_currency', 'cppcbr_woocommerce_currency');

Скачать бесплатно без смс плагин Autoupdate from cbr.ru for Currency per Product.

Скриншот страницы настроек Currency per Product для кейса описанного в посте (Указываем в евро, выводим в RUR).