From 88172cc6d3bb9fc11f01f3e01d9bf55926a43704 Mon Sep 17 00:00:00 2001 From: oligirling Date: Thu, 19 Feb 2026 08:31:05 +0000 Subject: [PATCH 1/2] Upgrade SDK to API v2, add OHLC endpoint, remove limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump API version from v1 to v2 (/api/v2/) - Add ohlc() endpoint with setCurrency() and setInterval() methods - Remove setLimit() — not supported in API v2 - Replace getCommonBaseAndLimit() with getCommonBase() - Update tests: remove limit tests, add ohlc/currency/interval tests - Update README with endpoint descriptions and OHLC docs - Add CHANGELOG entry for v3.0.0 Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 13 +++++ README.md | 80 +++++++++++++++++++++---- src/CurrencyApi.php | 120 ++++++++++++++++++++++++++------------ tests/CurrencyApiTest.php | 105 +++++++++++++++++++++------------ 4 files changed, 234 insertions(+), 84 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85d6104..d8e7903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. +## [3.0.0] - 2026-02-19 + +### Added +- New `ohlc()` endpoint for OHLC (Open, High, Low, Close) candlestick data (requires paid plan). +- New `setCurrency()` method to set the quote currency for the OHLC endpoint. +- New `setInterval()` method to set the candle interval for the OHLC endpoint (`5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d`). + +### Changed +- Upgraded to API v2 (`/api/v2/`). + +### Removed +- `setLimit()` method and `limit` parameter — API v2 no longer supports filtering currencies by a limit. All supported currencies are always returned (with `null` for unavailable ones). + ## [2.0.0] - 2026-02-13 ### Changed diff --git a/README.md b/README.md index 760dae7..46302c7 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ -# CurrencyApi PHP wrapper +# CurrencyApi PHP wrapper -[![Latest Stable Version](https://poser.pugx.org/houseofapis/currencyapi/v/stable)](https://packagist.org/packages/houseofapis/currencyapi) [![License](https://poser.pugx.org/houseofapis/currencyapi/license)](https://packagist.org/packages/houseofapis/currencyapi) [![Build Status](https://travis-ci.org/houseofapis/currencyapi-php.svg?branch=master)](https://travis-ci.org/houseofapis/currencyapi-php) [![Coverage Status](https://coveralls.io/repos/github/houseofapis/currencyapi-php/badge.svg?branch=master)](https://coveralls.io/github/houseofapis/currencyapi-php?branch=master) +[![Latest Stable Version](https://poser.pugx.org/houseofapis/currencyapi/v/stable)](https://packagist.org/packages/houseofapis/currencyapi) [![License](https://poser.pugx.org/houseofapis/currencyapi/license)](https://packagist.org/packages/houseofapis/currencyapi) [![Build Status](https://travis-ci.org/houseofapis/currencyapi-php.svg?branch=master)](https://travis-ci.org/houseofapis/currencyapi-php) [![Coverage Status](https://coveralls.io/repos/github/houseofapis/currencyapi-php/badge.svg?branch=master)](https://coveralls.io/github/houseofapis/currencyapi-php?branch=master) -CurrencyApi.net provides live currency rates via a REST API. A live currency feed for over 152 currencies, including physical (USD, GBP, EUR + more) and cryptos (Bitcoin, Litecoin, Ethereum + more). A JSON and XML currency api updated every 60 seconds. +CurrencyApi.net provides live currency rates via a REST API. A live currency feed for over 163 currencies, including physical (USD, GBP, EUR + more) and cryptos (Bitcoin, Litecoin, Ethereum + more). A JSON and XML currency api updated every 60 seconds. Features: - Live exchange rates (updated every 60 seconds). -- 152 currencies world currencies. +- 163+ world currencies. - Popular cryptocurrencies included; Bitcoin, Litecoin etc. - Convert currencies on the fly with the convert endpoint. - Historical currency rates back to year 2000. +- OHLC (candlestick) data for technical analysis. - Easy to follow documentation Signup for a free or paid account here. @@ -61,6 +62,8 @@ $currencyApi = new \CurrencyApi\CurrencyApi('API_KEY'); ### Live rates: +Returns the latest exchange rates for all supported currencies. + ```php $result = $currencyApi->rates(); ``` @@ -70,7 +73,6 @@ Example with all available methods: $result = $currencyApi ->setBase('USD') ->setOutput('JSON') - ->setLimit('BTC,EUR,GBP') ->rates(); ``` **Available methods for rates endpoint** @@ -79,12 +81,13 @@ $result = $currencyApi | --- | --- | | `setBase()` | The base currency you wish you receive the currency conversions for. This will output all currency conversions for that currency. **Default: USD**. | | `setOutput()` | Response output in either JSON or XML. **Default: JSON**. | -| `setLimit()` | Limit which currency conversions are returned using the limit param. Comma separated (no space) values. **Optional** |
### List of available currencies: +Returns a list of all currencies supported by the API. + ```php $result = $currencyApi->currencies(); ``` @@ -106,6 +109,8 @@ $result = $currencyApi ### Convert: +Converts an amount from one currency to another using the latest rates. + ```php $result = $currencyApi ->setAmount(100) @@ -127,6 +132,8 @@ $result = $currencyApi ### Historical: +Returns exchange rates for all currencies on a specific date. + ```php $result = $currencyApi->setDate('2019-01-01')->historical(); ``` @@ -137,7 +144,6 @@ Example with all available methods: $result = $currencyApi ->setDate('2019-01-01') ->setBase('GBP') - ->setLimit('USD') ->setOutput('JSON') ->historical(); ``` @@ -149,14 +155,15 @@ $result = $currencyApi | `setDate()` | The historical date you wish to receive the currency conversions for. This should be formatted as YYYY-MM-DD. **Required**. | | `setBase()` | The base currency you wish you receive the currency conversions for. This will output all currency conversions for that currency. **Default: USD**. | | `setOutput()` | Response output in either JSON or XML. **Default: JSON**. | -| `setLimit()` | Limit which currency conversions are returned using the limit param. Comma separated (no space) values. **Optional** |
### Timeframe: +Returns exchange rates for all currencies across a date range, with one entry per day. + ```php -$result = $currencyApi->setStartDate('2019-01-01')->setEndDate('2019-01-05')->historical(); +$result = $currencyApi->setStartDate('2019-01-01')->setEndDate('2019-01-05')->timeframe(); ``` Example with all available methods: @@ -166,7 +173,6 @@ $result = $currencyApi ->setStartDate('2019-01-01') ->setEndDate('2019-01-05') ->setBase('GBP') - ->setLimit('USD,BTC') ->setOutput('XML') ->timeframe(); ``` @@ -179,5 +185,57 @@ $result = $currencyApi | `setEndDate()` | The historical date you wish to receive the currency conversions until. This should be formatted as YYYY-MM-DD. **Required**. | | `setBase()` | The base currency you wish you receive the currency conversions for. This will output all currency conversions for that currency. **Default: USD**. | | `setOutput()` | Response output in either JSON or XML. **Default: JSON**. | -| `setLimit()` | Limit which currency conversions are returned using the limit param. Comma separated (no space) values. **Optional** | +
+ +### OHLC (Open, High, Low, Close): + +Returns candlestick data for a currency pair on a given date, useful for charting and technical analysis. + +```php +$result = $currencyApi + ->setCurrency('EUR') + ->setDate('2023-12-25') + ->ohlc(); +``` + +Example with all available methods: + +```php +$result = $currencyApi + ->setCurrency('EUR') + ->setDate('2023-12-25') + ->setBase('GBP') + ->setInterval('1h') + ->ohlc(); +``` + +**Available methods for OHLC endpoint** + +| Methods | Description | +| --- | --- | +| `setCurrency()` | The currency to retrieve OHLC data for. Three letter ISO 4217 currency code. **Required**. | +| `setDate()` | The date to retrieve OHLC data for. This should be formatted as YYYY-MM-DD. **Required**. | +| `setBase()` | The base currency for the rates. **Default: USD**. | +| `setInterval()` | The interval for the OHLC candles. One of: `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d`. **Default: 1d**. | + +**Example response:** + +```json +{ + "valid": true, + "base": "USD", + "quote": "EUR", + "date": "2023-12-25", + "interval": "1d", + "ohlc": [ + { + "start": "2023-12-25T00:00:00Z", + "open": 0.9123, + "high": 0.9187, + "low": 0.9098, + "close": 0.9154 + } + ] +} +``` diff --git a/src/CurrencyApi.php b/src/CurrencyApi.php index c476ebd..7e1ad3d 100644 --- a/src/CurrencyApi.php +++ b/src/CurrencyApi.php @@ -19,7 +19,7 @@ class CurrencyApi /** * Version of the API */ - const API_VERSION = 'v1'; + const API_VERSION = 'v2'; /** * Default base currency @@ -53,15 +53,6 @@ class CurrencyApi */ protected $output = self::DEFAULT_OUTPUT; - /** - * Limit which currency conversions are returned - * Comma separated values - * eg: 'USD,GBP,BTC' - * - * @var string - */ - protected $limit = ''; - /** * The value of the currency you want to convert from. * This should be a number and can contain a decimal place. @@ -110,6 +101,22 @@ class CurrencyApi */ protected $end_date = ''; + /** + * The currency to retrieve OHLC data for. + * This will be a three letter ISO 4217 currency code. + * + * @var string + */ + protected $currency = ''; + + /** + * The interval for OHLC data. + * One of: 5m, 15m, 30m, 1h, 4h, 12h, 1d + * + * @var string + */ + protected $interval = ''; + /** * CurrencyApi constructor. * @param string $key @@ -145,19 +152,6 @@ public function setOutput(string $output) : CurrencyApi return $this; } - /** - * Sets the limit of currencies returned - * See limit property for description ^ - * - * @param string $limit - * @return CurrencyApi - */ - public function setLimit(string $limit) : CurrencyApi - { - $this->limit = str_replace(' ', '', strtoupper($limit)); - return $this; - } - /** * Sets the amount to convert * See amount property for description ^ @@ -236,6 +230,33 @@ public function setEndDate(string $end_date) : CurrencyApi return $this; } + /** + * Sets the currency for the OHLC endpoint + * See currency property for description ^ + * + * @param string $currency + * @return CurrencyApi + */ + public function setCurrency(string $currency) : CurrencyApi + { + $this->currency = strtoupper($currency); + return $this; + } + + /** + * Sets the interval for the OHLC endpoint + * See interval property for description ^ + * One of: 5m, 15m, 30m, 1h, 4h, 12h, 1d + * + * @param string $interval + * @return CurrencyApi + */ + public function setInterval(string $interval) : CurrencyApi + { + $this->interval = $interval; + return $this; + } + /** * Get the live rates * @@ -245,7 +266,7 @@ public function setEndDate(string $end_date) : CurrencyApi */ public function rates() : array { - return $this->get($this->buildUrl('rates', $this->getCommonBaseAndLimit())); + return $this->get($this->buildUrl('rates', $this->getCommonBase())); } /** @@ -296,6 +317,18 @@ public function timeframe() : array return $this->get($this->buildUrl('timeframe', $this->getTimeFrameParams())); } + /** + * Get OHLC (Open, High, Low, Close) data for a currency pair + * + * @return array + * @throws BadRequestException + * @throws ConnectException + */ + public function ohlc() : array + { + return $this->get($this->buildUrl('ohlc', $this->getOhlcParams())); + } + /** * Prepares parameters for the convert endpoint * @@ -317,7 +350,7 @@ protected function getConvertParams() : array */ protected function getHistoricalParams() : array { - return array_merge(['date' => $this->date], $this->getCommonBaseAndLimit()); + return array_merge(['date' => $this->date], $this->getCommonBase()); } /** @@ -330,25 +363,40 @@ protected function getTimeFrameParams() : array return array_merge([ 'start_date' => $this->start_date, 'end_date' => $this->end_date - ], $this->getCommonBaseAndLimit()); + ], $this->getCommonBase()); } /** - * Adds commonly used base and limit parameters if they are set + * Prepares parameters for the OHLC endpoint * * @return array */ - protected function getCommonBaseAndLimit() : array + protected function getOhlcParams() : array { - $queryParams = []; - - if($this->base !== self::DEFAULT_BASE) { - $queryParams['base'] = $this->base; + $params = [ + 'currency' => $this->currency, + 'date' => $this->date, + ]; + if ($this->base !== self::DEFAULT_BASE) { + $params['base'] = $this->base; + } + if (!empty($this->interval)) { + $params['interval'] = $this->interval; } - if(!empty($this->limit)) { - $queryParams['limit'] = $this->limit; + return $params; + } + + /** + * Adds the base parameter if it differs from the default + * + * @return array + */ + protected function getCommonBase() : array + { + if ($this->base !== self::DEFAULT_BASE) { + return ['base' => $this->base]; } - return $queryParams; + return []; } /** @@ -387,7 +435,7 @@ protected function buildUrl(string $endpoint, array $urlParams = []) : string * Example of what's returned: * [ * [valid] => true - * [timestamp] => 1583182512 + * [updated] => 1583182512 * [base] => GBP * [rates] => [ * [AED] => 4.68987 diff --git a/tests/CurrencyApiTest.php b/tests/CurrencyApiTest.php index 312d465..4c53f0e 100644 --- a/tests/CurrencyApiTest.php +++ b/tests/CurrencyApiTest.php @@ -42,39 +42,27 @@ public function invokeMethod(&$object, $methodName, array $parameters = array()) return $method->invokeArgs($object, $parameters); } - public function getProtectedProperty($object, $property) + public function getProtectedProperty($object, $property) { $reflection = new \ReflectionClass($object); $reflection_property = $reflection->getProperty($property); return $reflection_property->getValue($object); - } + } - public function testGetCommonBaseAndLimitDefaultBaseWithLimit() + public function testGetCommonBaseDefaultBase() { - $base = 'USD'; - $limit = 'USD,EUR'; - $this->currencyApi->setBase($base); - $this->currencyApi->setLimit($limit); - - $invokedMethod = $this->invokeMethod($this->currencyApi, 'getCommonBaseAndLimit'); - + $this->currencyApi->setBase('USD'); + $invokedMethod = $this->invokeMethod($this->currencyApi, 'getCommonBase'); $this->assertArrayNotHasKey('base', $invokedMethod); - $this->assertArrayHasKey('limit', $invokedMethod); - $this->assertContains($limit, $invokedMethod); + $this->assertEmpty($invokedMethod); } - public function testGetCommonBaseAndLimitNotDefaultBaseWithoutLimit() + public function testGetCommonBaseNotDefaultBase() { - $base = 'GBP'; - $limit = ''; - $this->currencyApi->setBase($base); - $this->currencyApi->setLimit($limit); - - $invokedMethod = $this->invokeMethod($this->currencyApi, 'getCommonBaseAndLimit'); - + $this->currencyApi->setBase('GBP'); + $invokedMethod = $this->invokeMethod($this->currencyApi, 'getCommonBase'); $this->assertArrayHasKey('base', $invokedMethod); $this->assertContains('GBP', $invokedMethod); - $this->assertArrayNotHasKey('limit', $invokedMethod); } public function testGetSharedParamsNotDefault() @@ -144,6 +132,20 @@ public function testSetEndDate() $this->assertEquals($date, $this->getProtectedProperty($this->currencyApi, 'end_date')); } + public function testSetCurrency() + { + $currency = 'eur'; + $this->assertEquals($this->currencyApi, $this->currencyApi->setCurrency($currency)); + $this->assertEquals('EUR', $this->getProtectedProperty($this->currencyApi, 'currency')); + } + + public function testSetInterval() + { + $interval = '1h'; + $this->assertEquals($this->currencyApi, $this->currencyApi->setInterval($interval)); + $this->assertEquals($interval, $this->getProtectedProperty($this->currencyApi, 'interval')); + } + public function testGetConvertParams() { $amount = 100; @@ -182,22 +184,50 @@ public function testGetTimeFrameParams() ], $invokedMethod); } + public function testGetOhlcParams() + { + $currency = 'EUR'; + $date = '2023-12-25'; + $this->currencyApi->setCurrency($currency); + $this->currencyApi->setDate($date); + $invokedMethod = $this->invokeMethod($this->currencyApi, 'getOhlcParams'); + $this->assertEquals([ + 'currency' => $currency, + 'date' => $date, + ], $invokedMethod); + } + + public function testGetOhlcParamsWithBaseAndInterval() + { + $currency = 'EUR'; + $date = '2023-12-25'; + $base = 'GBP'; + $interval = '1h'; + $this->currencyApi->setCurrency($currency); + $this->currencyApi->setDate($date); + $this->currencyApi->setBase($base); + $this->currencyApi->setInterval($interval); + $invokedMethod = $this->invokeMethod($this->currencyApi, 'getOhlcParams'); + $this->assertEquals([ + 'currency' => $currency, + 'date' => $date, + 'base' => $base, + 'interval' => $interval, + ], $invokedMethod); + } + public function testBuildUrl() { $endpoint = 'rates'; $urlParams = []; $invokedMethod = $this->invokeMethod($this->currencyApi, 'buildUrl', [$endpoint, $urlParams]); - $this->assertEquals('https://currencyapi.net/api/v1/rates?key=123', $invokedMethod); - - $urlParams = ['limit' => 'GBP,EUR']; - $invokedMethod = $this->invokeMethod($this->currencyApi, 'buildUrl', [$endpoint, $urlParams]); - $this->assertEquals('https://currencyapi.net/api/v1/rates?limit=GBP%2CEUR&key=123', $invokedMethod); + $this->assertEquals('https://currencyapi.net/api/v2/rates?key=123', $invokedMethod); - $urlParams = ['limit' => 'GBP,EUR', 'base' => 'BTC']; + $urlParams = ['base' => 'BTC']; $this->currencyApi->setOutput('xMl'); $invokedMethod = $this->invokeMethod($this->currencyApi, 'buildUrl', [$endpoint, $urlParams]); - $this->assertEquals('https://currencyapi.net/api/v1/rates?limit=GBP%2CEUR&base=BTC&key=123&output=XML', $invokedMethod); + $this->assertEquals('https://currencyapi.net/api/v2/rates?base=BTC&key=123&output=XML', $invokedMethod); } public function testGetCurlError() @@ -262,10 +292,10 @@ public function testGetBadRequestExceptionXml() public function testGet() { - $expectedResponse = '{"valid": true, "timestamp": 1584738889, "base": "USD", "rates": {"AED": 3.67338, "AFN": 76.154}}'; + $expectedResponse = '{"valid": true, "updated": 1584738889, "base": "USD", "rates": {"AED": 3.67338, "AFN": 76.154}}'; $expectedResult = [ 'valid' => true, - 'timestamp' => 1584738889, + 'updated' => 1584738889, 'base' => 'USD', 'rates' => ['AED' => 3.67338, 'AFN' => 76.154] ]; @@ -277,20 +307,21 @@ public function testGet() public function testEndpointMethods() { - $expectedResponse = '{"valid": true, "timestamp": 1584738889, "base": "USD", "rates": {"AED": 3.67338, "AFN": 76.154}}'; + $expectedResponse = '{"valid": true, "updated": 1584738889, "base": "USD", "rates": {"AED": 3.67338, "AFN": 76.154}}'; $expectedResult = [ 'valid' => true, - 'timestamp' => 1584738889, + 'updated' => 1584738889, 'base' => 'USD', 'rates' => ['AED' => 3.67338, 'AFN' => 76.154] ]; $curl_exec = $this->getFunctionMock("HouseOfApis\CurrencyApi", "curl_exec"); $curl_exec->expects($this->any())->willReturn($expectedResponse); - $this->assertEquals($expectedResult,$this->currencyApi->rates()); - $this->assertEquals($expectedResult,$this->currencyApi->currencies()); - $this->assertEquals($expectedResult,$this->currencyApi->convert()); - $this->assertEquals($expectedResult,$this->currencyApi->historical()); - $this->assertEquals($expectedResult,$this->currencyApi->timeframe()); + $this->assertEquals($expectedResult, $this->currencyApi->rates()); + $this->assertEquals($expectedResult, $this->currencyApi->currencies()); + $this->assertEquals($expectedResult, $this->currencyApi->convert()); + $this->assertEquals($expectedResult, $this->currencyApi->historical()); + $this->assertEquals($expectedResult, $this->currencyApi->timeframe()); + $this->assertEquals($expectedResult, $this->currencyApi->ohlc()); } } From babb749c704fa31916ddb799725aec78014ec09a Mon Sep 17 00:00:00 2001 From: oligirling Date: Sat, 21 Feb 2026 09:28:11 +0000 Subject: [PATCH 2/2] Add v1 deprecation notice to README API v1 will be retired on 31st July 2026, redirecting to v2. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 46302c7..fadd529 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Features: Signup for a free or paid account here. +> **Note:** API v1 is deprecated and will be retired on **31st July 2026**, at which point all v1 traffic will be redirected to v2. This SDK (v3.0.0+) targets API v2. If you are on an older version of this SDK, please upgrade. + ## This package is a: PHP wrapper for CurrencyApi.net endpoints.