S.I.
S.I.

Reputation: 3375

Multiple currency request in class

I have a class which pull info for one currency currently USD/EUR. I want to add more like AUD/EUR, CAD/EUR etc ,... and then via dropdown menu user will can choose what to see. So far this is the class

class API
{
    public static function getUSDRate() {
        $urldata = get_curl_content('https://example.com/');
        $rates = json_decode($urldata, TRUE);        
        if (!$rates) {
            return '-';
        }

        $usdRate = @$rates['USD']['sell'];
        if (!$usdRate) {        
            return '-';
        }        
        return $usdRate;
    }

    public static function convertUSDToEUR($usdPrice) {
        $usdRate = self::getUSDRate();
        if ($usdRate === '-') {
            return '-';
    }

    $usdRate = doubleval($usdRate);
    return round($usdPrice / $usdRate, 8);
 }

So I want to add for example this

 $audRate = @$rates['AUD']['sell'];
 if (!$audRate) {        
      return '-';
 }        
 return $audRate;

 public static function convertAUDToEUR($audPrice) {
     $audRate = self::getAUDRate();
     if ($audRate === '-') {
         return '-';
 }

 $audRate = doubleval($audRate);
 return round($audPrice / $audRate, 8);

Do I need to write for each addition currency this? Or there is more 'intelligent' way? Or I must create class for each currency?

Upvotes: 0

Views: 148

Answers (2)

user5124226
user5124226

Reputation:

If you are getting all currencies from your service I can suggest something like:

    <?php
    class API
    {
        // caching rates service results
        protected $ratesCache;

        // requesting rates service 
        // (we can force API request again by passing true)
        public function getRates($cacheClear = false) {
            // if we don't need to clear the cache and we already 
            // did request to rate service
            if ($cacheClear != true && !empty($this->ratesCache)) {
                // returning cached result
                return $this->ratesCache;
            }

            // request to rate service
            $urldata = get_curl_content('https://example.com/');
            $rates = json_decode($urldata, TRUE);        
            if (empty($rates)) {
                return '-';
            }

            // caching result
            $this->ratesCache = $rates;

            return $this->ratesCache;
        }

        // return the list of available rates
        public function getRatesList() {
            $rates = $this->getRates();
            // you can add here foreach to check which rates has 'sell' value
            // so you list only possible to convert currencies
            return array_keys($rates);
        }

        // convert currencies value to EUR
        public function convertToEUR($currency, $price) {
            $rates = $this->getRates();
            if (empty($rates[$currency]['sell'])) {
                return '-';
            }

            $rate = doubleval($rates[$currency]);
            return round($price / $rate, 8);
        }
     }

and the usage will be like:

<?php
$rateConvertor = new Api();
$availableRates = $rateConvertor->getRates();
// using foreach you can build <select> with currencies
// ...
// user select currency, set price (or you get it from somewhere else)
$amount = $rateConvertor->convertToEUR($currency, $price);

Upvotes: 1

trincot
trincot

Reputation: 350705

Here is an idea for a class that supports conversion from any currency. You must provide the currency upon creating an instance of the class, and then you can use that object's methods to do the conversion.

Like in your code, the exchange rates are read in a static variable, and only when not already done before:

class CurrencyRate {
    public static $rates;
    private $conversionRate;
    private $currency;
    private $amount;

    function __construct($currFrom = "EUR") {
        // Currency to be provided when creating instance. EUR is default.
        if (empty(static::$rates)) {
            // Only request rates when not already loaded
            $urldata = get_curl_content('https://example.com/');
            self::$rates = json_decode($urldata, TRUE);
            // Add dummy rate for converting EUR to EUR
            self::$rates['EUR'] = ['sell' => '1'];
        }
        $this->currency = $currFrom;
        // Get exchange rate to EUR for this currency
        if (isset(self::$rates[$currFrom]['sell'])) {
            $this->conversionRate = doubleval(self::$rates[$currFrom]['sell']);
        } else {
            $this->conversionRate = 0; // not found
        }
    }

    public function currency() {
        return $this->currency;
    }

    public function rate() {
        return $this->conversionRate;
    }

    public function amount($newAmount = null) {
        // If argument is provided then this is a setter, otherwise a getter
        if (isset($newAmount)) {
            $this->amount = $newAmount;
            return $this; // allow "chaining"
        }
        return $this->amount;
    }

    public function euro() {
        // Convert object's amount to EUR 
        if ($this->conversionRate == 0) return "-"; // cannot convert
        return round($this->amount / $this->conversionRate, 8);
    }
}

Example use:

// define the currency of your object. 
// You could pass 'AUD' or any other supported currency
$usd = new CurrencyRate('USD');

// set amount  in that currency
$usd->amount(12.34);

// get amount in that currency (is the same)
echo "amount: " . $usd->amount() . " USD<br>";

// get rate from that currency to EUR
echo "rate: " . $usd->rate() . "<br>";

// get amount in EUR
echo "Converted: " . $usd->euro() . " EUR<br>";

Upvotes: 1

Related Questions