Мультивалютность в Drupal 7 (Ubercart 3)

В один прекрасный день передо мной стала задача сделать мультивалютность на сайте, уже работающем на ubercart 3. Переместить все товары в Commerce, на котором данная функция решается элементарно не было возможности да и особово желания. Было решено искать в интеренте готовое решение, но оно не увенчалось успехом. Но вот случайно наткнуля песочницу одного проекта, который решил мои проблемы. Пришлось немного покопаться в коде и кое-где подправить, и Эврика! Все заработало. 
Ниже приведу пример самого рабочего модуля. Конечно, можно сделать и оптимальней, но данный вариант рабочий и хорошо себя показывает на большом рабочем проекте с посещяемостью свыше 2000 человек. 

Модуль расчитан на то, что главной валютой будут выставлены доллары USD, а цены по умолчанию будут в гривнах UAH.

Я назвал модуль uc_currency.

Содержание файла uc_currency:

name = uc_currency
description = allow user to setting multiple rate to ubercart
core = 7.x

dependencies[] = uc_store
dependencies[] = currency_api

 

Содержимое файла uc_currency.admin.inc :
 

<?php

/**
 * @file
 * Ubercart currency admin configuration page
 */

/**
 * Tmplements hook_form().
 */
function uc_currency_settings_form($form, $form_state) {


  $default_currency_code = variable_get('uc_currency_base', 'none');

  $currencies_arr = unserialize(variable_get('uc_currency_convert'));

  $form['currency_base'] = array(
    '#type' => 'textfield',
    '#title' => 'Base Currency ',
    '#description' => 'Enter here your three character <a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes">ISO 4217</a> currency code. (separate with comma for multiple currencies)',
    '#value' => variable_get('uc_currency_base', UC_CURRENCY_DEFAULT_CURRENCY),
  );

  $form['currencies_convert'] = array(
    '#type' => 'textfield',
    '#title' => 'Allowed Currencies',
    '#description' => 'Enter here your three character <a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes">ISO 4217</a> currency code. (separate with comma for multiple currencies)',
    '#value' => implode(', ', (array) $currencies_arr),
    '#attributes' => array('onchange' => 'this.form.submit();'),
  );

  $options = array(
    UC_CURRENCY_RATE_AUTO => 'Automatic Rate Conversion (Rate From <a href="http://finance.yahoo.com/currency-converter/#from=USD;to=EUR;amt=1">Yahoo Finance</a>)',
    UC_CURRENCY_RATE_MANUAL => 'Manual Rate',
  );

  $form['currencies_converter_type'] = array(
    '#type' => 'radios',
    '#title' => 'Choose convertion type',
    '#default_value' => variable_get('uc_currency_converter_type', UC_CURRENCY_RATE_AUTO),
    '#options' => $options,
    '#attributes' => array('onchange' => 'this.form.submit();'),
  );

  if (variable_get('uc_currency_converter_type') == UC_CURRENCY_RATE_MANUAL) {

    $form['allowed_code_values'] = array(
      '#type' => 'fieldset',
      '#title' => 'Manual Rate Values',
    );

    $currencies_rate = unserialize(variable_get('uc_currency_rates', array()));

    if (!empty($currencies_arr)) {
      foreach ($currencies_arr as $item) {
        $value = isset($currencies_rate[$item]) ? $currencies_rate[$item] : '';
        $form['allowed_code_values'][$item] = array(
          '#type' => 'textfield',
          '#title' => check_plain($item) . ' rate to ' . check_plain($default_currency_code) . ':',
          '#size' => '10',
          '#value' => isset($currencies_rate[$item])?$currencies_rate[$item]:'',
        );
      }
    }
  }


  $options = array(
    UC_CURRENCY_SELECT => 'Select List',
    UC_CURRENCY_RADIOS => 'Radio Buttons',
  );

  $form['currencies_form_type'] = array(
    '#type' => 'radios',
    '#title' => 'Choose switcher type',
    '#default_value' => variable_get('uc_currency_form_type', UC_CURRENCY_SELECT),
    '#options' => $options,
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Save',
  );

  return $form;
}

/**
 * Implements uc_currency_settings_form().
 */
function uc_currency_settings_form_submit(&$form, $form_state) {

  $input = $form_state['input'];

  $convert_currencies_tmp = explode(',', $input['currencies_convert']);

  if (is_array($convert_currencies_tmp)) {
    foreach ($convert_currencies_tmp as $item) {
      $convert_currencies[trim($item)] = trim($item);
    }
  }
  else {
    $convert_currencies[$convert_currencies_tmp] = $convert_currencies_tmp;
  }
  $currencies_rate = array();
  
  if($input['currencies_converter_type']==2){
    foreach ($convert_currencies as $item) {
      if(isset($input[$item])){
      $currencies_rate[$item] = $input[$item];
      }
    }
  }
  variable_set('uc_currency_convert', serialize($convert_currencies));

  variable_set('uc_currency_rates', serialize($currencies_rate));

  variable_set('uc_currency_form_type', $input['currencies_form_type']);


  variable_set('uc_currency_base', $input['currency_base']);
  variable_set('uc_currency_code', $input['currency_base']);
  variable_set('uc_currency_sign', currency_api_get_symbol($input['currency_base']));

  variable_set('uc_currency_converter_type', $input['currencies_converter_type']);

  drupal_set_message(t('Currency configurations saved'), 'status');
}

И наконец содержимое uc_currency.module :
 

<?php

/**
 * @file
 * Add multiple currency configurations features to ubercart
 */

/**
 * switcher select list
 */
define('UC_CURRENCY_SELECT', '1');

/**
 * switcher radio button
 */
define('UC_CURRENCY_RADIOS', '2');


/**
 * switcher select list
 */
define('UC_CURRENCY_RATE_AUTO', '1');

/**
 * switcher radio button
 */
define('UC_CURRENCY_RATE_MANUAL', '2');

/**
 * switcher radio button
 */
define('UC_CURRENCY_DEFAULT_CURRENCY', 'UAH');

/**
 * Implements hook_menu().
 */
function uc_currency_menu() {
  $items = array();

  $items['admin/store/settings/currency'] = array(
    'title' => 'Currency',
    'description' => 'Change currency configurations',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('uc_currency_settings_form'),
    'access arguments' => array('administer currency'),
    'file' => 'uc_currency.admin.inc',
  );

  return $items;
}

/**
 * Implements hook_permission().
 */
function uc_currency_permission() {
  return array(
    'administer currency' => array(
      'title' => t('Administer Currency'),
      'description' => t('Allow administratior to administer currency configurations'),
    ),
  );
}

/**
 * Implements hook_block_info().
 */
function uc_currency_block_info() {

  $blocks['uc_currency_block'] = array(
    'info' => t('Currency Switcher'),
    'cache' => DRUPAL_NO_CACHE,
    'status' => FALSE,
    'region' => -1,
  );

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function uc_currency_block_view($delta = '') {

  switch ($delta) {
    case 'uc_currency_block':
      $product_count = count(uc_cart_get_contents());
      $block['subject'] = '';
      $block['content'] = drupal_get_form('uc_currency_switcher_form');
      break;
  }
  return $block;
}

/**
 * Implements theme_registry_alter().
 */
function uc_currency_theme_registry_alter(&$theme_registry) {
  unset($theme_registry['uc_price']['includes']);

  $module_path = drupal_get_path('module', 'uc_currency');
  $theme_registry['uc_price'] = array(
    'file' => 'uc_currency.module',
    'type' => 'module',
    'theme path' => $module_path,
    'function' => 'theme_uc_price_multiple_currency',
    'variables' => array('price' => NULL, 'suffixes' => NULL),
  );
}

/**
 * Implements hook_uc_cart_alter().
 */
function uc_currency_uc_cart_alter(&$items) {
  $default_currency_code = UAH;
  $code = isset($_SESSION['currency_switcher']) ? $_SESSION['currency_switcher'] : $default_currency_code;

  foreach ($items as $key => $item) {
    $items[$key]->order->currency = $code;
  }
}

/**
 * Overrided callback function of theme_uc_price.
 * @see uc_currency_theme_registry_alter
 *
 * @param array $variables
 *   associative array containing:
 *   - price = ubercart item price (base price)
 *   - suffixes = Price suffixes
 *
 * @ingroup themeable
 */
function theme_uc_price_multiple_currency($variables) {

  $default_currency_code = UAH;
  $code = isset($_SESSION['currency_switcher']) ? $_SESSION['currency_switcher'] : $default_currency_code;

  $symbol = currency_api_get_symbol($code);

  if (variable_get('uc_currency_converter_type') == UC_CURRENCY_RATE_MANUAL) {
    $price = uc_currency_manual_convertion($code, $variables['price']);
  }
  else {
    $price = currency_api_convert($default_currency_code, $code, $variables['price']);
  }


  $output = '<span class="uc-price">' . uc_currency_format($price['value'], $symbol) . '</span>';

  if (!empty($variables['suffixes'])) {
    $output .= '<span class="price-suffixes">' . implode(' ', $variables['suffixes']) . '</span>';
  }
  return $output;
}

/**
 * Implements hook_form_submit().
 */
function uc_currency_switcher_form($form, $form_state) {
  $form = array();

  drupal_add_js('
    jQuery(document).ready(function($){
      $("#edit-currency-switcher").change(function(){
        $("#edit-currency-switcher-submit").click();
      });
    });    
  ', array('type' => 'inline'));

  $default_currency_code = variable_get('uc_currency_code', UC_CURRENCY_DEFAULT_CURRENCY);


  $currencies_arr[$default_currency_code] = $default_currency_code;

  $currency_convert = unserialize(variable_get('uc_currency_convert', ''));
  if (!empty($currency_convert)) {
    $currencies_arr = array_merge($currencies_arr, $currency_convert);
  }

  $form['currency_switcher'] = array(
    '#type' => 'select',
    '#options' => $currencies_arr,
    '#default_value' => isset($_SESSION['currency_switcher']) ? $_SESSION['currency_switcher'] : UAH,
  );

  $form['currency_switcher_submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#attributes' => array('style' => 'display:none;'),
  );

  return $form;
}

/**
 * Implements uc_currency_switcher_form_submit().
 */
function uc_currency_switcher_form_submit(&$form, $form_state) {

  $input = $form_state['input'];

  // Store currencies code to session.
  $_SESSION['currency_switcher'] = $input['currency_switcher'];
}

/**
 * Manually Convert the currency
 *
 * @param string $to
 *   Currency code target
 *
 * @param number $value
 *   value of price
 *
 * @return ArrayIterator
 *   array price
 */
function uc_currency_manual_convertion($to, $value) {

  if ($to == variable_get('uc_currency_base')) {
    $result['code'] = $to;
    $result['value'] = 1 * $value;
  }
  else {
    $currencies_rate = unserialize(variable_get('uc_currency_rates'));

    $result['value'] = $currencies_rate[$to] * $value;
    $result['code'] = $to;
  }
  return $result;
}

К сожалению, ссылку на песочницу уже не смогу найти. 
Также вы можете скачать готовый модуль