Skip to content

Commit

Permalink
Cleaner API approach
Browse files Browse the repository at this point in the history
  • Loading branch information
steffen.brand committed Feb 23, 2017
1 parent d4217a7 commit 89ef727
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 57 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,31 @@ try {

CurrCurr does not provide its own SimpleCache implementation, however it does give you the possibility
to inject any [PSR-16 compliant implementation](https://packagist.org/providers/psr/simple-cache-implementation) into the EcbClient.
You just have to wrap it with a CacheConfig instance.

```php
$cc = new CurrCurr(
new EcbClient(
EcbClient::DEFAULT_EXCHANGE_RATES_URL,
new OpCache(sys_get_temp_dir() . '/cache'), // MANDATORY: your cache implementation goes here, this example uses odan/cache
EcbClient::CACHE_UNTIL_MIDNIGHT, // OPTIONAL: provide time to live in seconds
EcbClient::DEFAULT_CACHE_KEY // OPTIONAL: key to use for caching
new CacheConfig(
new OpCache(sys_get_temp_dir() . '/cache')
// Any PSR-16 compliant implementation
// This example uses odan/cache
)
)
);
```

You can provide your own key and time to live.

```php
new CacheConfig(
new OpCache(sys_get_temp_dir() . '/cache')
CacheConfig::CACHE_UNTIL_MIDNIGHT, // time to live in seconds
CacheConfig::DEFAULT_CACHE_KEY // key used for caching
);
```

### Mocking webservice response for Unit Testing your own project

CurrCurr allows you to inject your own implementation of the EcbClientInterface.
Expand Down
37 changes: 11 additions & 26 deletions src/Client/EcbClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use SteffenBrand\CurrCurr\Exception\ExchangeRatesRequestFailedException;
use SteffenBrand\CurrCurr\Mapper\ExchangeRatesMapper;
use SteffenBrand\CurrCurr\Mapper\MapperInterface;
use SteffenBrand\CurrCurr\Model\CacheConfig;
use SteffenBrand\CurrCurr\Model\ExchangeRate;

class EcbClient implements EcbClientInterface
Expand All @@ -19,19 +20,9 @@ class EcbClient implements EcbClientInterface
private $exchangeRatesUrl;

/**
* @var CacheInterface
* @var CacheConfig
*/
private $cache;

/**
* @var int
*/
private $cacheTimeInSeconds;

/**
* @var string
*/
private $cacheKey;
private $cacheConfig;

/**
* @var MapperInterface
Expand All @@ -45,21 +36,15 @@ class EcbClient implements EcbClientInterface

/**
* @param string $exchangeRatesUrl
* @param CacheInterface $cache
* @param int $cacheTimeInSeconds
* @param string $cacheKey
* @param CacheConfig $cacheConfig
* @param MapperInterface $mapper
*/
public function __construct(string $exchangeRatesUrl = self::DEFAULT_EXCHANGE_RATES_URL,
CacheInterface $cache = null,
int $cacheTimeInSeconds = self::CACHE_UNTIL_MIDNIGHT,
string $cacheKey = self::DEFAULT_CACHE_KEY,
CacheConfig $cacheConfig = null,
MapperInterface $mapper = null)
{
$this->exchangeRatesUrl = $exchangeRatesUrl;
$this->cache = $cache;
$this->cacheTimeInSeconds = $cacheTimeInSeconds;
$this->cacheKey = $cacheKey;
$this->cacheConfig = $cacheConfig;
if (null === $mapper) {
$mapper = new ExchangeRatesMapper();
}
Expand All @@ -74,7 +59,7 @@ public function __construct(string $exchangeRatesUrl = self::DEFAULT_EXCHANGE_RA
public function getExchangeRates(): array
{
try {
if (null !== $this->cache) {
if (null !== $this->cacheConfig && $this->cacheConfig->getCache() instanceof CacheInterface) {
$response = $this->performCachedRequest();
} else {
$response = $this->performRequest();
Expand All @@ -91,14 +76,14 @@ public function getExchangeRates(): array
*/
private function performCachedRequest()
{
$responseBody = $this->cache->get($this->cacheKey, null);
$responseBody = $this->cacheConfig->getCache()->get($this->cacheConfig->getCacheKey(), null);
if (null === $responseBody) {
$response = $this->performRequest();
if ($this->cacheTimeInSeconds === self::CACHE_UNTIL_MIDNIGHT) {
$this->cacheTimeInSeconds = strtotime('tomorrow') - time();
if ($this->cacheConfig->getCacheTimeInSeconds() === CacheConfig::CACHE_UNTIL_MIDNIGHT) {
$this->cacheConfig->setCacheTimeInSeconds(strtotime('tomorrow') - time());
}
$responseBody = $response->getBody()->getContents();
$this->cache->set($this->cacheKey, $responseBody, $this->cacheTimeInSeconds);
$this->cacheConfig->getCache()->set($this->cacheConfig->getCacheKey(), $responseBody, $this->cacheConfig->getCacheTimeInSeconds());
}

$response = new Response(200, [], $responseBody);
Expand Down
19 changes: 3 additions & 16 deletions src/Client/EcbClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Psr\SimpleCache\CacheInterface;
use SteffenBrand\CurrCurr\Mapper\MapperInterface;
use SteffenBrand\CurrCurr\Model\CacheConfig;
use SteffenBrand\CurrCurr\Model\ExchangeRate;

interface EcbClientInterface
Expand All @@ -14,27 +15,13 @@ interface EcbClientInterface
*/
const DEFAULT_EXCHANGE_RATES_URL = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';

/**
* @const int
*/
const CACHE_UNTIL_MIDNIGHT = -1;

/**
* @const string
*/
const DEFAULT_CACHE_KEY = 'curr-curr-cache';

/**
* @param string $exchangeRatesUrl
* @param CacheInterface $cache
* @param int $cacheTimeInSeconds
* @param string $cacheKey
* @param CacheConfig $cacheConfig
* @param MapperInterface $mapper
*/
public function __construct(string $exchangeRatesUrl = self::DEFAULT_EXCHANGE_RATES_URL,
CacheInterface $cache = null,
int $cacheTimeInSeconds = self::CACHE_UNTIL_MIDNIGHT,
string $cacheKey = self::DEFAULT_CACHE_KEY,
CacheConfig $cacheConfig = null,
MapperInterface $mapper = null);

/**
Expand Down
98 changes: 98 additions & 0 deletions src/Model/CacheConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace SteffenBrand\CurrCurr\Model;

use Psr\SimpleCache\CacheInterface;

class CacheConfig {

/**
* @const int
*/
const CACHE_UNTIL_MIDNIGHT = -1;

/**
* @const string
*/
const DEFAULT_CACHE_KEY = 'curr-curr-cache';

/**
* @var CacheInterface
*/
private $cache;

/**
* @var int
*/
private $cacheTimeInSeconds;

/**
* @var string
*/
private $cacheKey;

/**
* CacheConfig constructor.
*
* @param CacheInterface $cache PSR-16 compliant CacheInterface implementation
* @param int $cacheTimeInSeconds TTL in seconds
* @param string $cacheKey Key to use for caching
*/
public function __construct(CacheInterface $cache = null,
$cacheTimeInSeconds = self::CACHE_UNTIL_MIDNIGHT,
$cacheKey = self::DEFAULT_CACHE_KEY)
{
$this->cache = $cache;
$this->cacheTimeInSeconds = $cacheTimeInSeconds;
$this->cacheKey = $cacheKey;
}

/**
* @return CacheInterface
*/
public function getCache(): CacheInterface
{
return $this->cache;
}

/**
* @param CacheInterface $cache
*/
public function setCache(CacheInterface $cache)
{
$this->cache = $cache;
}

/**
* @return int
*/
public function getCacheTimeInSeconds(): int
{
return $this->cacheTimeInSeconds;
}

/**
* @param int $cacheTimeInSeconds
*/
public function setCacheTimeInSeconds(int $cacheTimeInSeconds)
{
$this->cacheTimeInSeconds = $cacheTimeInSeconds;
}

/**
* @return string
*/
public function getCacheKey(): string
{
return $this->cacheKey;
}

/**
* @param string $cacheKey
*/
public function setCacheKey(string $cacheKey)
{
$this->cacheKey = $cacheKey;
}

}
13 changes: 5 additions & 8 deletions src/Client/EcbClientMock.php → test/Client/EcbClientMock.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<?php

namespace SteffenBrand\CurrCurr\Client;
namespace SteffenBrand\CurrCurr\Test\Client;

use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\SimpleCache\CacheInterface;
use SteffenBrand\CurrCurr\Client\EcbClientInterface;
use SteffenBrand\CurrCurr\Exception\ExchangeRatesRequestFailedException;
use SteffenBrand\CurrCurr\Mapper\ExchangeRatesMapper;
use SteffenBrand\CurrCurr\Mapper\MapperInterface;
use SteffenBrand\CurrCurr\Model\CacheConfig;
use SteffenBrand\CurrCurr\Model\ExchangeRate;

class EcbClientMock implements EcbClientInterface
Expand Down Expand Up @@ -40,15 +41,11 @@ class EcbClientMock implements EcbClientInterface

/**
* @param string $expectedResponse
* @param CacheInterface $cache
* @param int $cacheTimeInSeconds
* @param string $cacheKey
* @param CacheConfig $cacheConfig
* @param MapperInterface $mapper
*/
public function __construct(string $expectedResponse = self::VALID_RESPONSE,
CacheInterface $cache = null,
int $cacheTimeInSeconds = self::CACHE_UNTIL_MIDNIGHT,
string $cacheKey = self::DEFAULT_CACHE_KEY,
CacheConfig $cacheConfig = null,
MapperInterface $mapper = null)
{
if (null === $mapper) {
Expand Down
2 changes: 1 addition & 1 deletion test/CurrCurrMockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use SteffenBrand\CurrCurr\CurrCurr;
use SteffenBrand\CurrCurr\Model\Currency;
use SteffenBrand\CurrCurr\Model\ExchangeRate;
use SteffenBrand\CurrCurr\Client\EcbClientMock;
use SteffenBrand\CurrCurr\Test\Client\EcbClientMock;

/**
* @runTestsInSeparateProcesses
Expand Down
9 changes: 6 additions & 3 deletions test/CurrCurrSimpleCacheIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PHPUnit_Framework_TestCase;
use SteffenBrand\CurrCurr\Client\EcbClient;
use SteffenBrand\CurrCurr\CurrCurr;
use SteffenBrand\CurrCurr\Model\CacheConfig;
use SteffenBrand\CurrCurr\Model\Currency;

/**
Expand Down Expand Up @@ -35,9 +36,11 @@ private function getInstance(string $cacheKey): CurrCurr
return new CurrCurr(
new EcbClient(
EcbClient::DEFAULT_EXCHANGE_RATES_URL,
new OpCache(sys_get_temp_dir() . '/cache'),
EcbClient::CACHE_UNTIL_MIDNIGHT,
$cacheKey
new CacheConfig(
new OpCache(sys_get_temp_dir() . '/cache'),
CacheConfig::CACHE_UNTIL_MIDNIGHT,
$cacheKey
)
)
);
}
Expand Down

0 comments on commit 89ef727

Please sign in to comment.