WordPress.org

Making WordPress.org


Ignore:
Timestamp:
06/06/2018 12:08:53 AM (2 years ago)
Author:
coreymckrill
Message:

WordCamp Utilities: Add oxr as current exchange rate source

Fixer has a new API that does not meet our needs with the free plan.
Open Exchange Rates has a very similar API that seems to do everything we need.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/utilities/class-currency-xrt-client.php

    r6633 r7271  
    88 *
    99 * Get historical exchange rates for the major currencies. Designed to be able to use different API sources for
    10  * the exchange rate data. Initially built using the Fixer API (fixer.io). "XRT" = "exchange rate".
     10 * the exchange rate data. Initially built using the Fixer API (fixer.io). Now includes Open Exchange Rates.
     11 * "XRT" = "exchange rate".
    1112 */
    1213class Currency_XRT_Client {
     
    3233
    3334    /**
     35     * @var string The key for accessing the source's API.
     36     */
     37    protected $api_key = '';
     38
     39    /**
    3440     * @var array Cache of exchange rates by date for reuse.
    3541     */
     
    4046     *
    4147     * @param string $base_currency Optional. Currency symbol for the base currency. Default 'USD'.
    42      * @param string $source        Optional. Identifier for the exchange rates source. Default 'fixer'.
    43      */
    44     public function __construct( $base_currency = 'USD', $source = 'fixer' ) {
     48     * @param string $source        Optional. Identifier for the exchange rates source. Default 'oxr'.
     49     */
     50    public function __construct( $base_currency = 'USD', $source = 'oxr' ) {
    4551        $this->error = new \WP_Error();
    4652
     
    4854        $this->source        = $source;
    4955        $this->api_base      = $this->get_api_base( $this->source );
     56        $this->api_key       = $this->get_api_key( $this->source );
    5057    }
    5158
     
    6269        switch ( $source ) {
    6370            case 'fixer' :
    64             default :
    65                 $base_url = 'https://api.fixer.io/';
     71                $base_url = 'https://data.fixer.io/api/';
     72                break;
     73            case 'oxr' :
     74                $base_url = 'https://openexchangerates.org/api/';
    6675                break;
    6776        }
    6877
    6978        return trailingslashit( $base_url );
     79    }
     80
     81    /**
     82     * Get the API key based on the given source.
     83     *
     84     * @param string $source
     85     *
     86     * @return string The API key.
     87     */
     88    protected function get_api_key( $source ) {
     89        $key = '';
     90
     91        switch ( $source ) {
     92            case 'fixer' :
     93                if ( defined( 'WORDCAMP_FIXER_API_KEY' ) ) {
     94                    $key = WORDCAMP_FIXER_API_KEY;
     95                }
     96                break;
     97            case 'oxr' :
     98                if ( defined( 'WORDCAMP_OXR_API_KEY' ) ) {
     99                    $key = WORDCAMP_OXR_API_KEY;
     100                }
     101                break;
     102        }
     103
     104        return $key;
    70105    }
    71106
     
    79114    public function get_rates( $date ) {
    80115        $rates = array();
    81         $cache_key = 'wc_currency_rates_' . strtotime( $date );
     116        $cache_key = 'wc_currency_rates_' . $this->source . '_' . strtotime( $date );
    82117
    83118        try {
     
    97132        switch ( $this->source ) {
    98133            case 'fixer' :
     134                $rates = $this->send_fixer_request( $date );
     135                break;
     136            case 'oxr' :
     137                $rates = $this->send_oxr_request( $date );
     138                break;
    99139            default :
    100                 $rates = $this->send_fixer_request( $date );
     140                $rates = new \WP_Error(
     141                    'invalid_xrt_source',
     142                    sprintf(
     143                        '%s is not a valid currency exchange rate source.',
     144                        esc_html( $this->source )
     145                    )
     146                );
    101147                break;
    102148        }
     
    178224        $data = array();
    179225
    180         $request_url = add_query_arg( array(
    181             'base' => $this->base_currency,
    182         ), $this->api_base . $date->format( 'Y-m-d' ) );
     226        $api_endpoint = $date->format( 'Y-m-d' );
     227        $now = new \DateTime();
     228
     229        if ( $date->format( 'Y-m-d' ) === $now->format( 'Y-m-d' ) || $date > $now ) {
     230            $api_endpoint = 'latest';
     231        }
     232
     233        $request_url = add_query_arg(
     234            array(
     235                'access_key' => $this->api_key,
     236                'base'       => $this->base_currency,
     237            ),
     238            esc_url( $this->api_base . $api_endpoint )
     239        );
    183240
    184241        $response      = wcorg_redundant_remote_get( $request_url );
     
    192249                $this->error->add(
    193250                    'request_error',
    194                     $response_body['error']
     251                    sprintf(
     252                        '%s: %s',
     253                        $response_body['error']['code'],
     254                        $response_body['error']['info']
     255                    )
    195256                );
    196257            } else {
     
    201262            }
    202263        } else {
    203             $this->error->add(
    204                 'http_response_code',
    205                 $response_code . ': ' . print_r( $response_body, true )
    206             );
     264            if ( isset( $response_body['error'] ) ) {
     265                $this->error->add(
     266                    'request_error',
     267                    sprintf(
     268                        '%s: %s',
     269                        $response_body['error']['code'],
     270                        $response_body['error']['info']
     271                    )
     272                );
     273            } else {
     274                $this->error->add(
     275                    'http_response_code',
     276                    $response_code . ': ' . print_r( $response_body, true )
     277                );
     278            }
    207279        }
    208280
     
    213285        return $data;
    214286    }
     287
     288    /**
     289     * Send a request to the Open Exchange Rates API and return the results.
     290     *
     291     * @param \DateTime $date The date to retrieve rates for.
     292     *
     293     * @return array|\WP_Error An array of rates, or an error.
     294     */
     295    protected function send_oxr_request( \DateTime $date ) {
     296        $data = array();
     297
     298        $api_endpoint = 'historical/' . $date->format( 'Y-m-d' );
     299        $now = new \DateTime();
     300
     301        if ( $date->format( 'Y-m-d' ) === $now->format( 'Y-m-d' ) || $date > $now ) {
     302            $api_endpoint = 'latest';
     303        }
     304
     305        $request_url = add_query_arg(
     306            array(
     307                'app_id' => $this->api_key,
     308                'base'   => $this->base_currency,
     309            ),
     310            esc_url( sprintf( '%s%s.json', $this->api_base, $api_endpoint ) )
     311        );
     312
     313        $response      = wcorg_redundant_remote_get( $request_url );
     314        $response_code = wp_remote_retrieve_response_code( $response );
     315        $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
     316
     317        if ( 200 === $response_code ) {
     318            if ( isset( $response_body['rates'] ) ) {
     319                $data = $response_body['rates'];
     320            } else {
     321                $this->error->add(
     322                    'unexpected_response_data',
     323                    'The API response did not provide the expected data.'
     324                );
     325            }
     326        } else {
     327            if ( isset( $response_body['error'], $response_body['message'], $response_body['description'] ) ) {
     328                $this->error->add(
     329                    esc_html( $response_body['message'] ),
     330                    esc_html( $response_body['description'] )
     331                );
     332            } else {
     333                $this->error->add(
     334                    'http_response_code',
     335                    $response_code . ': ' . print_r( $response_body, true )
     336                );
     337            }
     338        }
     339
     340        if ( ! empty( $this->error->get_error_messages() ) ) {
     341            return $this->error;
     342        }
     343
     344        return $data;
     345    }
    215346}
Note: See TracChangeset for help on using the changeset viewer.