yf_payment_api__currency class

Fileplugins/payment/classes/yf_payment_api__currency.class.php
Use_class('payment_api__currency')

Public properties

A site sets them in its config with $PROJECT_CONF['payment_api__currency']['NAME'] = ...;

PropertyDefaultDescription
$api null
$base 'UAH'
$cache []
$index []
$main 'UNT'
$main_shadow 'USD'
$payment_api null
$provider
['nbu' => ['id' => 1, 'code' => 'nbu', 'short' => 'NBU', 'full' => 'National Bank of Ukraine', 'base' => 'UAH', 'method' => [...]], 'p24' => ['id' => 101, 'code' => 'p24', 'short' => 'Privat24', 'full' => 'PrivatBank', 'base' => 'UAH', 'method' => [...]], 'cashex' => ['id' => 201, 'code' => 'cashex', 'short' => 'CashExchange', 'full' => 'CashExchange.com.ua', 'base' => 'UAH', 'method' => [...]]]
array (
  'nbu' => 
  array (
    'id' => 1,
    'code' => 'nbu',
    'short' => 'NBU',
    'full' => 'National Bank of Ukraine',
    'base' => 'UAH',
    'method' => 
    array (
      'json' => true,
      'xml' => true,
      'html' => true,
    ),
  ),
  'p24' => 
  array (
    'id' => 101,
    'code' => 'p24',
    'short' => 'Privat24',
    'full' => 'PrivatBank',
    'base' => 'UAH',
    'method' => 
    array (
      'json' => true,
    ),
  ),
  'cashex' => 
  array (
    'id' => 201,
    'code' => 'cashex',
    'short' => 'CashExchange',
    'full' => 'CashExchange.com.ua',
    'base' => 'UAH',
    'method' => 
    array (
      'xml' => true,
      'json' => true,
    ),
  ),
)
$provider_allow ['nbu' => true]
$provider_default 'nbu'
$rate ['buy' => 3.5, 'sell' => -2.5]
$user_id null

Public methods 18

conversion

public function conversion($options = null)
    public function conversion($options = null)
    {
        $_amount = $_currency_id = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        if ( ! ($_amount ?? null)) {
            return  null;
        }
        $result = $this->rate($options);
        if ($result === null) {
            return  null;
        }
        $result *= $_amount;
        $payment_api = $this->payment_api;
        $to = ($_to ?? null) ?: $_currency_id;
        list($currency_id, $currency) = $payment_api->get_currency__by_id([
                'currency_id' => $to,
            ]);
        if (@ ! $currency_id) {
            return  $result;
        }
        $result = $payment_api->_number_float($result, $currency['minor_units']);
        return  $result;
    }

correction

public function correction($options = null)
    public function correction($options = null)
    {
        $_currency_rate = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        if (empty($_currency_rate)) {
            return  null;
        }
        // currency
        empty($_main) && $_main = $this->main;
        // correction
        $k_buy = 1 + $this->rate['buy'] / 100;
        $k_sell = 1 + $this->rate['sell'] / 100;
        $result = $_currency_rate;
        foreach ($result as $index => &$item) {
            if ($item['from'] == $_main) {
                // buy
                $value = &$item['from_value'];
                $value = $value * $k_buy;
            } elseif ($item['to'] == $_main) {
                // sell
                $value = &$item['to_value'];
                $value = $value * $k_sell;
            }
        }
        return  $result;
    }

load

public function load($options = null)
    public function load($options = null)
    {
        $_provider = $_method = $_date = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        @$provider = &$this->provider[strtolower((string) $_provider)];
        if ( ! $provider) {
            $result = [
                'status' => false,
                'status_message' => 'Loading exchange rates: provider not found',
            ];
            return  $result;
        }
        $provider_id = $provider['id'];
        // method
        $method_id = null;
        @$method = &$provider['method'];
        if (($_method ?? null)) {
            if ( ! ($method[$_method] ?? null)) {
                $result = [
                    'status' => false,
                    'status_message' => 'Loading exchange rates: method not found',
                ];
                return  $result;
            }
            $method_id = $_method;
        } else {
            if (is_array($method)) {
                foreach ($method as $id => $active) {
                    if ($active) {
                        $method_id = $id;
                        break;
                    }
                }
            }
        }
        // date
        $date = 0;
        if (($_date ?? null)) {
            if ( ! is_numeric($_date)) {
                $date = @strtotime($_date);
                if (is_int($date)) {
                    $options['date'] = $date;
                }
            }
        }
        // cache
        @$result = $this->cache[__FUNCTION__][$provider_id][$method_id][$date];
        if ( ! ($_is_force_load ?? null) && $result) {
            return  $result;
        }
        // load
        $code = &$provider['code'];
        $load = __FUNCTION__ . '__' . $code;
        $method_id && $load .= '_' . $method_id;
        $status = method_exists($this, $load);
        if ( ! $status) {
            $result = [
                'status' => false,
                'status_message' => 'Loading exchange rates: handler not found',
            ];
            return  $result;
        }
        $result = $this->{ $load }($options);
        // cache
        $this->cache[__FUNCTION__][$provider_id][$method_id][$date] = $result;
        return  $result;
    }
public function load__cashex_json($options = null)
    public function load__cashex_json($options = null)
    {
        $_request_options = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $api = $this->api;
        $payment_api = $this->payment_api;
        // prepare request options
        $url = 'http://api.cashex.com.ua/api/v1/exchange';
        $request_options = [
            'is_redirect' => true,
        ];
        ($_request_options ?? null) && $request_options = array_replace_recursive(
            $request_options,
            $_request_options
        );
        $result = $api->_request($url, null, $request_options);
        list($status, $response) = $result;
        if (empty($status)) {
            return  null;
        }
        // prepare
        $count = count($response);
        if ($count < 1) {
            return  null;
        }
        $data = [];
        $currencies = $payment_api->currencies;
        foreach ($response as $i => $item) {
            $currency_id = $item['Currency'];
            if (empty($currencies[$currency_id])) {
                continue;
            }
            $from_value = 100;
            $to_value_buy = $item['Buy'] * $from_value;
            $to_value_sale = $item['Sale'] * $from_value;
            $data[] = [
                'from' => $currency_id,
                'to' => 'UAH',
                'from_value' => $from_value,
                'to_value' => $to_value_sale,
            ];
            $data[] = [
                'from' => 'UAH',
                'to' => $currency_id,
                'from_value' => $to_value_buy,
                'to_value' => $from_value,
            ];
        }
        return  $data;
    }
public function load__cashex_xml($options = null)
    public function load__cashex_xml($options = null)
    {
        $_request_options = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $api = $this->api;
        $payment_api = $this->payment_api;
        // prepare request options
        $url = 'http://api.cashex.com.ua/XmlApi.ashx';
        $request_options = [
            'is_redirect' => true,
            'is_response_raw' => true,
        ];
        ($_request_options ?? null) && $request_options = array_replace_recursive(
            $request_options,
            $_request_options
        );
        $result = $api->_request($url, null, $request_options);
        list($status, $response) = $result;
        if (empty($status)) {
            return  $result;
        }
        require_php_lib('sf_dom_crawler');
        $crawler = new \Symfony\Component\DomCrawler\Crawler($response);
        $table = $crawler->filter('element');
        $count = $table->count();
        if ($count < 1) {
            return  null;
        }
        $currencies = $payment_api->currencies;
        $data = [];
        $table->each(function ($node, $i) use (&$currencies, &$data) {
            $currency_id = $node->filter('currency')->text();
            if (empty($currencies[$currency_id])) {
                return;
            }
            $buy = $node->filter('buy')->text();
            $sale = $node->filter('sale')->text();
            $data[] = [
                'from' => $currency_id,
                'to' => 'UAH',
                'from_value' => 1,
                'to_value' => $buy,
            ];
            $data[] = [
                'from' => 'UAH',
                'to' => $currency_id,
                'from_value' => $sale,
                'to_value' => 1,
            ];
        });
        return  $data;
    }

load__nbu

public function load__nbu($options = null)
    public function load__nbu($options = null)
    {
        $_date = $_request_options = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $api = $this->api;
        $payment_api = $this->payment_api;
        // base url
        $url = 'http://bank.gov.ua/NBUStatService/v1/statdirectory/exchange';
        $uri = [];
        // method
        switch (($_method ?? null)) {
            case 'xml':  $uri[] = 'xml';
                break;
            default:
            case 'json': $uri[] = 'json';
                break;
        }
        // date
        if (($_date ?? null)) {
            $tpl = 'Ymd';
            $uri[] = 'date=' . date($tpl, $_date);
        }
        // url
        $uri = implode('&', $uri);
        $uri && $url .= '?' . $uri;
        // prepare request options
        $request_options = [
            'is_redirect' => true,
        ];
        ($_request_options ?? null) && $request_options = array_replace_recursive(
            $request_options,
            $_request_options
        );
        $result = $api->_request($url, null, $request_options);
        @list($status, $response) = $result;
        if (empty($status)) {
            return  null;
        }
        // prepare
        $count = count($response);
        if ($count < 1) {
            return  null;
        }
        $data = [];
        $currencies = $payment_api->currencies;
        foreach ($response as $i => $item) {
            if (($_method ?? null) == 'xml') {
                $item = (array) $item;
            }
            $currency_id = $item['cc'];
            if (empty($currencies[$currency_id])) {
                continue;
            }
            $from_value = 100;
            $to_value = $item['rate'] * $from_value;
            $data[] = [
                'from' => $currency_id,
                'to' => 'UAH',
                'from_value' => $from_value,
                'to_value' => $to_value,
            ];
        }
        return  $data;
    }
public function load__nbu_html($options = null)
    public function load__nbu_html($options = null)
    {
        $_date = $_request_options = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $api = $this->api;
        $payment_api = $this->payment_api;
        // prepare request options
        $url = 'http://www.bank.gov.ua/control/uk/curmetal/detail/currency?period=daily';
        // date
        if (($_date ?? null)) {
            $tpl = 'd.m.Y';
            $url = 'http://www.bank.gov.ua/control/uk/curmetal/currency/search?formType=searchFormDate&time_step=daily&date=' . date($tpl, $_date);
        }
        // request
        $request_options = [
            'is_response_raw' => true,
        ];
        ($_request_options ?? null) && $request_options = array_replace_recursive(
            $request_options,
            $_request_options
        );
        $result = $api->_request($url, null, $request_options);
        list($status, $response) = $result;
        if (empty($status)) {
            return  $result;
        }
        require_php_lib('sf_dom_crawler');
        $crawler = new \Symfony\Component\DomCrawler\Crawler($response);
        $table = $crawler->filter('.content > table')->eq(3);
        $count = $table->count();
        if ($count < 1) {
            return  null;
        }
        $table_data = [];
        $table->filter('tr')->each(function ($node, $i) use (&$table_data) {
            $table_data[] = $node->filter('td')->extract(['_text']);
        });
        $count = count($table_data);
        if ($count < 1) {
            return  null;
        }
        $data = [];
        $currencies = $payment_api->currencies;
        foreach ($table_data as $i => $item) {
            $currency_id = $item[1];
            if (empty($currencies[$currency_id])) {
                continue;
            }
            $from_value = $item[2];
            $to_value = $item[4];
            $data[] = [
                'from' => $currency_id,
                'to' => 'UAH',
                'from_value' => $from_value,
                'to_value' => $to_value,
            ];
        }
        return  $data;
    }
public function load__nbu_json($options = null)
    public function load__nbu_json($options = null)
    {
        $result = $this->load__nbu($options);
        return  $result;
    }

load__nbu_xml

public function load__nbu_xml($options = null)
    public function load__nbu_xml($options = null)
    {
        $result = $this->load__nbu($options);
        return  $result;
    }
public function load__p24_json($options = null)
    public function load__p24_json($options = null)
    {
        $_request_options = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $api = $this->api;
        $payment_api = $this->payment_api;
        // prepare request options
        $url = 'https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=3';
        $request_options = [
            'is_response_json' => true,
        ];
        ($_request_options ?? null) && $request_options = array_replace_recursive(
            $request_options,
            $_request_options
        );
        $result = $api->_request($url, null, $request_options);
        list($status, $response) = $result;
        if (empty($status)) {
            return  null;
        }
        // prepare
        $count = count($response);
        if ($count < 1) {
            return  null;
        }
        $data = [];
        $currencies = $payment_api->currencies;
        foreach ($response as $i => $item) {
            $currency_id = $item['ccy'];
            if (empty($currencies[$currency_id])) {
                continue;
            }
            $from_value = 100;
            $to_value_buy = $item['buy'] * $from_value;
            $to_value_sale = $item['sale'] * $from_value;
            $data[] = [
                'from' => $currency_id,
                'to' => 'UAH',
                'from_value' => $from_value,
                'to_value' => $to_value_sale,
            ];
            $data[] = [
                'from' => 'UAH',
                'to' => $currency_id,
                'from_value' => $to_value_buy,
                'to_value' => $from_value,
            ];
        }
        return  $data;
    }

load_rate

public function load_rate($options = null)
    public function load_rate($options = null)
    {
        $_provider = $_currency_id = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $result = null;
        if ( ! ($_from ?? null) && ! ($_currency_id ?? null)) {
            return  $result;
        }
        // provider
        $provider = $this->provider($options);
        if ( ! $provider) {
            return  $result;
        }
        ! $_provider && $_provider = $provider['code'];
        // currency base, main
        ! ($_main ?? null) && $_main = $this->main;
        $base = $provider['base'];
        $from = ($_from ?? null) ?: $_currency_id;
        $to = ($_to ?? null) ?: $base;
        // request
        $o = [
            'provider' => $_provider,
            'method' => ($_method ?? null),
            'date' => ($_date ?? null),
            'is_force' => ($_is_force ?? null),
        ];
        // request
        $data = $this->load($o);
        if ( ! $data) {
            return  $result;
        }
        // processing
        if ($from == $base) {
            $data = $this->reverse(['provider' => $_provider, 'currency_rate' => $data]);
        }
        if (($from != $base && $to != $base) || ($from == $_main || $to == $_main)) {
            $data = $this->prepare(['provider' => $_provider, 'currency_rate' => $data]);
        }
        if ($from == $_main || $to == $_main) {
            $data = $this->correction(['provider' => $_provider, 'currency_rate' => $data]);
        }
        foreach ((array) $data as $idx => $item) {
            if ($item['from'] == $from && $item['to'] == $to) {
                $result = $item['to_value'] / $item['from_value'];
                break;
            }
        }
        return  $result;
    }

prepare

public function prepare($options = null)
    public function prepare($options = null)
    {
        $_provider = $_currency_rate = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        if (empty($_currency_rate)) {
            return  null;
        }
        // base
        if ( ! ($_base ?? null) && ($_provider ?? null)) {
            $_base = $this->provider[$_provider]['base'];
        }
        // currency
        empty($_base) && $_base = $this->base;
        empty($_main) && $_main = $this->main;
        empty($_main_shadow) && $_main_shadow = $this->main_shadow;
        // create index
        $index = [];
        $currencies = [];
        foreach ($_currency_rate as $i => &$item) {
            $from = $item['from'];
            $to = $item['to'];
            $name = $from . '-' . $to;
            // relations
            $index[$name] = &$item;
            // available
            $currencies[$from] = $from;
            $currencies[$to] = $to;
        }
        // find main relations
        $main_relations = $currencies;
        unset($main_relations[$_base]);
        foreach ($main_relations as $id1) {
            foreach ($main_relations as $id2) {
                if ($id1 == $id2) {
                    continue;
                }
                if (
                    ! empty($index[$id1 . '-' . $_base])
                    && ! empty($index[$id2 . '-' . $_base])
                ) {
                    $from_value = $index[$id1 . '-' . $_base]['from_value'] / $index[$id2 . '-' . $_base]['from_value'];
                    $to_value = $index[$id1 . '-' . $_base]['to_value'] / $index[$id2 . '-' . $_base]['to_value'];
                    $_currency_rate[] = [
                        'from' => $id1,
                        'to' => $id2,
                        'from_value' => $from_value,
                        'to_value' => $to_value,
                    ];
                }
            }
        }
        // find main shadow
        $result = $_currency_rate;
        foreach ($_currency_rate as $i => &$item) {
            $from = $item['from'];
            $to = $item['to'];
            // add base
            $base_id = null;
            $_main_shadow == $from && $base_id = 'from';
            $_main_shadow == $to && $base_id = 'to';
            if ( ! empty($base_id)) {
                $base_item = $item;
                $base_item[$base_id] = $_main;
                $result[] = $base_item;
            }
        }
        return  $result;
    }

provider

public function provider($options = null)
    public function provider($options = null)
    {
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $result = null;
        $provider = &$this->provider;
        $index = &$this->index;
        // default
        $_provider = strtolower(($_provider ?? null) ?: $this->provider_default);
        // provider_id
        if (($_provider_id ?? null)) {
            $_provider_id = (int) $_provider_id;
            if ( ! is_array($index['provider']['id'][$_provider_id])) {
                return  $result;
            }
            $result = $index['provider']['id'][$_provider_id];
        }
        // allow
        if ( ! ($_is_force ?? null) && ! @$this->provider_allow[$_provider]) {
            return  $result;
        }
        ! $result && $result = $provider[$_provider];
        return  $result;
    }

rate

public function rate($options = null)
    public function rate($options = null)
    {
        $_currency_id = $_provider = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $result = null;
        $_type = ($_type ?? null) == 'sell' ? 'sell' : 'buy';
        if ( ! ($_from ?? null) && ! ($_currency_id ?? null)) {
            return  $result;
        }
        // provider
        $provider = $this->provider($options);
        if ( ! $provider) {
            return  $result;
        }
        // currency base
        $from = ($_from ?? null) ?: $_currency_id;
        $to = ($_to ?? null) ?: $provider['base'];
        $o = [
            'type' => $_type,
            'currency_id' => $from,
            'provider' => $_provider,
        ];
        $rates = $this->rates($o);
        $r = &$rates[$to];
        if ( ! ($r ?? null)) {
            return  $result;
        }
        $result = $r['rate'] / $r['value'];
        return  $result;
    }

rates

public function rates($options = null)
    public function rates($options = null)
    {
        $_currency_id = $_is_force = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        // var
        $_type = ($_type ?? null) == 'sell' ? 'sell' : 'buy';
        if ( ! ($_type ?? null) || ! ($_currency_id ?? null)) {
            return  null;
        }
        $payment_api = $this->payment_api;
        // provider
        $provider_item = $this->provider($options);
        if ( ! $provider_item) {
            return  null;
        }
        $provider = $provider_item['code'];
        $provider_id = $provider_item['id'];
        // cache
        $currency_rate = $this->cache[__FUNCTION__][$provider_id][$_type][$_currency_id];
        if ( ! empty($_is_force) || ! $currency_rate) {
            list($currency_id, $currency) = $payment_api->get_currency__by_id(['currency_id' => $_currency_id]);
            if (($_type ?? null) == 'buy') {
                $target = 'to';
                $source = 'from';
            } else {
                $target = 'from';
                $source = 'to';
            }
            $key_value = $target . '_value';
            $key_rate = $source . '_value';
            $sql = db()->table('payment_currency_rate')
                ->select('*', 'max( datetime ) as latest')
                ->where('provider_id', '=', $provider_id)
                ->where($target, '=', $_currency_id)
                ->group_by($source)
                ->sql();
            $result = db()->table('payment_currency_rate as l')
                ->select('l.*')
                ->inner_join("( $sql ) as r", 'l.datetime = r.latest AND l.from = r.from AND l.to = r.to', true)
                ->where('l.provider_id', '=', $provider_id)
                ->where("l.$target", '=', $_currency_id)
                ->order_by('datetime', 'DESC')
                ->get_all();
            if (empty($result)) {
                $currency_id_default = &$payment_api->currency_id_default;
                foreach ($payment_api->currencies as $key => $item) {
                    if ($currency_id_default == $key) {
                        continue;
                    }
                    $currency_rate[$key] = [
                        'value' => 1.0,
                        'rate' => 1.0,
                    ];
                }
            } else {
                foreach ($result as $id => $item) {
                    $key = $item[$source];
                    $value = $item[$key_value];
                    $rate = $item[$key_rate];
                    $currency_rate[$key] = [
                        'value' => (float) $value,
                        'rate' => (float) $rate,
                    ];
                }
            }
        }
        // get from db
        return  $currency_rate;
    }

reverse

public function reverse($options = null)
    public function reverse($options = null)
    {
        $_currency_rate = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        if (empty($_currency_rate)) {
            return  null;
        }
        // reverse
        $result = $_currency_rate;
        foreach ($_currency_rate as $i => $item) {
            $from = $item['from'];
            $to = $item['to'];
            $result[] = [
                'from' => $item['to'],
                'to' => $item['from'],
                'from_value' => $item['to_value'],
                'to_value' => $item['from_value'],
            ];
        }
        return  $result;
    }

update

public function update($options = null)
    public function update($options = null)
    {
        $_provider = $_currency_rate = null;
        // import options
        is_array($options) && extract($options, EXTR_PREFIX_ALL | EXTR_REFS, '');
        if ( ! ($_provider ?? null) || ! ($_currency_rate ?? null)) {
            return  null;
        }
        $provider_id = @$this->provider[$_provider]['id'];
        if ( ! ($provider_id ?? null)) {
            return  null;
        }
        // var
        $payment_api = $this->payment_api;
        $sql_datetime = $payment_api->sql_datetime();
        // add datetime, value
        $decimals = 6;
        foreach ($_currency_rate as $index => &$item) {
            ! ($item['provider_id'] ?? null) && $item['provider_id'] = $provider_id;
            $item['datetime'] = &$sql_datetime;
            $value = &$item['from_value'];
            $value = $payment_api->_number_mysql($value, $decimals);
            $value = &$item['to_value'];
            $value = $payment_api->_number_mysql($value, $decimals);
        }
        if ( ! ($_currency_rate ?? null)) {
            return  null;
        }
        // store
        $result = db()->table('payment_currency_rate')->insert(
            $_currency_rate
            // , array( 'sql' => true, )
        );
        return  $result;
    }

Methods starting with _ hooks and helpers; not routable as page actions

_init

public function _init()
    public function _init()
    {
        $this->api = _class('api');
        $this->payment_api = _class('payment_api');
        // index
        $index = &$this->index;
        $provider = &$this->provider;
        foreach ($provider as $key => &$item) {
            $id = $item['id'];
            $index['provider']['id'][$id] = &$item;
        }
    }