Making WordPress.org


Ignore:
Timestamp:
06/06/2018 12:08:53 AM (8 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.