businessdad icon

WooCommerce Currency Switcher - Advanced integration example

businessdad | PRO | 06/05/15 10:19:19 PM UTC | 0 ⭐ | 2167 👁️ | Never ⏰ | []
PHP |

6.91 KB

|

None

|

0 👍

/

0 👎

/**
 * Helper class to allow 3rd party plugins to implement multi-currency
 * capabilities. The class was designed to work with the Aelia Currency Switcher,
 * but it's generic enough to be adapted to other solutions.
 *
 * Need a consultation? Find us on Codeable: https://bit.ly/aelia_codeable
 * 
 * @author Aelia <[email protected]>
 * @link https://aelia.co
 * @link https://aelia.co/shop/currency-switcher-woocommerce/
 */
class Advanced_CurrencySwitcher_Integration  {
  // @var string Shop's base currency. Used for caching.
  protected static $_base_currency;
 
  /**
   * Returns shop's base currency. This method implements some simple caching,
   * to avoid calling get_option() too many times.
   *
   * @return string Shop's base currency.
   */
  protected static function shop_base_currency() {
    if(empty(self::$_base_currency)) {
      self::$_base_currency = get_option('woocommerce_currency');
    }
    return self::$_base_currency;
  }
 
  /**
   * Returns the list of the currencies enabled in the Aelia Currency Switcher.
   * If the Currency Switcher is not installed, or active, then the list will
   * only contain the shop base currency.
   *
   * @return array An array of currency codes.
   */
  public static function enabled_currencies() {
    return apply_filters('wc_aelia_cs_enabled_currencies', array(self::shop_base_currency()));
  }
 
  /**
   * Returns a product's base currency. A product's base currency is the point
   * of reference to calculate other prices, and it can differ from shop's base
   * currency.
   * For example, if a shop's base currency is USD, a product's base currency
   * can be EUR. In such case, product prices in other currencies can be
   * calculated automatically, as long as the EUR one is entered.
   *
   * @param int product_id A product ID.
   * @param string default_currency The default currency to use if the product
   * doesn't have a base currency.
   * @return string A currency code.
   */
  public static function get_product_base_currency($product_id, $default_currency = null) {
    if(empty($default_currency)) {
      $default_currency = self::shop_base_currency();
    }
    return apply_filters('wc_aelia_cs_product_base_currency', $default_currency, $product_id);
  }
 
  /**
   * Advanced integration with WooCommerce Currency Switcher, developed by Aelia
   * (https://aelia.co). This method can be used by any 3rd party plugin to
   * return prices in the active currency.
   *
   * @param double price The source price.
   * @param string to_currency The target currency. If empty, the active currency
   * is taken.
   * @param string from_currency The source currency. If empty, WooCommerce base
   * currency is taken.
   * @return double The price converted from source to destination currency.
   */
  public static function get_price_in_currency($price, $to_currency = null, $from_currency = null) {
    if(empty($from_currency)) {
      $from_currency = self::shop_base_currency();
    }
    if(empty($to_currency)) {
      $to_currency = get_woocommerce_currency();
    }
 
    return self::convert($price, $to_currency, $from_currency);
  }
 
  /**
   * Converts an amount from one currency to another, using exchange rates.
   *
   * @param float amount The amount to convert.
   * @param string to_currency The destination currency.
   * @param string from_currency The source currency.
   * @return float The amount converted to the target destination currency.
   */
  public static function convert($amount, $to_currency, $from_currency = null) {
    return apply_filters('wc_aelia_cs_convert', $amount, $from_currency, $to_currency);
  }
    
    /**
     * Returns a list of prices that should be a applied to a product for each currency.
     * This is a example of how the fixed-price logic could be implemented. The
     * actual implementation depends on the specifics of the product being proceseed,
     * on how the prices were stored, and so on.
     *
     * @param WC_Product product The product for which the prices should be retrieved.
     * @param string currency The currency for which the product prices will be retrieved.
     * @return array An array of prices.
     */
    protected function get_product_prices_for_currency($product, $currency) {
        // Load the custom prices in the specified currency         
        $prices = array(
            'my_custom_price' => get_post_meta($product->id, '_my_custom_price_' . $currency, true),
            'my_other_custom_price' => get_post_meta($product->id, 'my_other_custom_price_' . $currency, true),
        );
        return $prices;
    }
 
    /**
     * Performs a simple test conversion of an arbitrary value, using exchange
     * rates.
     */
  public function test() {
    $price = 123;
    // Just call the get_price_in_currency() method. This will use automatic conversion
    return self::get_price_in_currency($price);
  }
 
    /**
     * Alter the callbacks used by the Currency Switcher, replacing the callback
     * for a "my_custom_product" type with a custon one.
     *
     * @param callable convert_callback The original callback.
     * @param WC_Product product The callback being converted.
     * @return callable The callback that will convert the product's prices.
     */
    public function wc_aelia_currencyswitcher_product_convert_callback($convert_callback, $product) {
        if($product->product_type === 'my_custom_product') {
            $convert_callback = array($this, 'convert_my_custom_product');
        }
        
        return $convert_callback;
    }
    
    /**
     * Converts the prices of a custom product to the specified currency.
     *
     * @param WC_Product product A variable product.
     * @param string currency A currency code.
     * @return WC_Product The product with converted prices.
     */
    public function convert_my_custom_product($product, $currency) {
        /* Here you can implement your custom logic to convert the prices.
         *  The two lines below are just an example. Here you can do anything you
         *  want with the product, to ensure that its prices are converted correctly.
         */
 
        // Load the product prices that were entered manually for the specified currency
        $product_prices_for_currency = $this->get_product_prices_for_currency($product, $currency);
        
        // If prices were entered manually, then they will be used as they are. If not,
        // product's price in base currency will be converted using exchange rates
        $product->my_custom_price = isset($product_prices_for_currency['my_custom_price']) ? $product_prices_for_currency['my_custom_price'] : self::get_price_in_currency($product->my_custom_price);
        $product->my_other_custom_price = isset($product_prices_for_currency['my_other_custom_price']) ? $product_prices_for_currency['my_other_custom_price'] : self::get_price_in_currency($product->my_other_custom_price);
        
        return $product;
    }   
 
    public function __construct() {
        add_filter('wc_aelia_currencyswitcher_product_convert_callback', array($this, 'wc_aelia_currencyswitcher_product_convert_callback'), 10, 2);
    }
}

Comments