Commit bba9dff6 authored by Thorsten Buss's avatar Thorsten Buss

add CurrencyUpdater

parent 595e2648
......@@ -204,8 +204,25 @@ Examples:
```
### Use the CurrencyUpdater
Download and parse a CurrencyFile and save it with a Closure
Examples:
```php
$updater = new \Bnet\Money\Updater\CurrencyUpdater();
$updater->update_currency_table(function($item) use($db) {
$db->save($item);
});
```
## Changelog
**0.1.4
- add CurrencyUpdater to download and parse a file and save the data with a Closure
**0.1.3
- add TaxedMoney for use MoneyObject with Tax
**0.1.2
......
<?php
/**
* User: thorsten
* Date: 22.07.16
* Time: 21:48
*/
namespace Bnet\Money\Updater;
use Bnet\Money\Updater\Exception\CurrencyUpdaterException;
class CurrencyUpdater {
const DEFAULT_CURRENCY_FILE = 'https://raw.github.com/RubyMoney/money/master/config/currency_iso.json';
protected $file;
/**
* CurrencyUpdater constructor.
* @param null $file
*/
public function __construct($file=null) {
$this->file = $file ?: self::DEFAULT_CURRENCY_FILE;
}
/**
* Update the currencyTable from a file/url with a specific parser
* @param \Closure $itemParser
* @param \Closure $fileParser
* @return bool
*/
public function update_currency_table($itemSaver, \Closure $itemParser = null, \Closure $fileParser = null) {
$file = $this->file;
$fileParser = @$fileParser ?: function ($file) {
return json_decode(file_get_contents($file), true);
};
$err = array();
$arr = $fileParser($file);
foreach ($arr as $item) {
try {
if (is_callable($itemParser))
$itemParser($item, $itemSaver);
else
$this->parseItem($item, $itemSaver);
} catch (CurrencyUpdaterException $e) {
if ($e->getPrevious())
$err[$item['iso_code']] = get_class($e->getPrevious()) . '::' . $e->getPrevious()->getMessage();
else
$err[$item['iso_code']] = get_class($e) . '::' . $e->getMessage();
}
}
// return errorList or true if no errors
return $err ?: true;
}
/**
* Read Currency Item and parse it with the $parser
* parse an item with the given parser and return the result of the $parser
* @param array $raw_item
* @param \Closure $saver
* @return mixed
* @throws CurrencyUpdaterException
*/
protected function parseItem($raw_item, \Closure $saver) {
/* $raw_item
"eur": {
"priority": 2,
"iso_code": "EUR",
"name": "Euro",
"symbol": "€",
"alternate_symbols": [],
"subunit": "Cent",
"subunit_to_unit": 100,
"symbol_first": true,
"html_entity": "&#x20AC;",
"decimal_mark": ",",
"thousands_separator": ".",
"iso_numeric": "978",
"smallest_denomination": 1
},
*/
$item = [
'code' => strtoupper($raw_item['iso_code']),
'iso' => $raw_item['iso_numeric'],
'name' => $raw_item['name'],
'symbol_left' => '',
'symbol_right' => '',
'decimal_mark' => $raw_item['decimal_mark'],
'thousands_separator' => $raw_item['thousands_separator'],
'unit_factor' => $raw_item['subunit_to_unit']
];
if ($raw_item['symbol_first']) {
$item['symbol_left'] = $raw_item['symbol'];
} else {
$item['symbol_right'] = $raw_item['symbol'];
}
// calculate the decimal places
$item['decimal_place'] = strlen(preg_replace('/1/', '', $raw_item['subunit_to_unit']));
try {
$ret = $saver($item);
} catch (\Exception $e) {
if ($e instanceof CurrencyUpdaterException)
throw new CurrencyUpdaterException("", 0, $e);
}
return $ret;
}
}
\ No newline at end of file
<?php
/**
* User: thorsten
* Date: 22.07.16
* Time: 21:54
*/
namespace Bnet\Money\Updater\Exception;
class CurrencyUpdaterException extends \Exception {
}
\ No newline at end of file
<?php
/**
* User: thorsten
* Date: 22.07.16
* Time: 23:00
*/
namespace Tests\Bnet\Money\Updater;
class CurrencyUpdaterTest extends \PHPUnit_Framework_TestCase {
public function testCurrencyUpdaterDefaultJsonParser() {
$tmpFile = '/tmp/currencyFile.json';
$data = '{
"eur": {
"priority": 2,
"iso_code": "EUR",
"name": "Euro",
"symbol": "€",
"alternate_symbols": [
],
"subunit": "Cent",
"subunit_to_unit": 100,
"symbol_first": true,
"html_entity": "7",
"decimal_mark": ",",
"thousands_separator": ".",
"iso_numeric": "978",
"smallest_denomination": 1
}
}';
file_put_contents($tmpFile, $data);
$updater = new \Bnet\Money\Updater\CurrencyUpdater($tmpFile);
$a = null;
$updater->update_currency_table(function($item) use(&$a) {
$a = $item;
});
$this->assertEquals('EUR', $a['code'], 'code');
$this->assertEquals('978', $a['iso'], 'iso');
$this->assertEquals('Euro', $a['name'], 'name');
$this->assertEquals("€", $a['symbol_left'], 'symbol_left');
$this->assertEquals("", $a['symbol_right'], 'symbol_right');
$this->assertEquals(2, $a['decimal_place'], 'decimal_place');
$this->assertEquals(',', $a['decimal_mark'], 'decimal_mark');
$this->assertEquals('.', $a['thousands_separator'], 'thousands_separator');
$this->assertEquals(100, $a['unit_factor'], 'unit_factor');
@unlink($tmpFile);
}
public function testCurrencyUpdaterCustomParser() {
$tmpFile = '/tmp/currencyFile';
$data = 'T1:Test2';
file_put_contents($tmpFile, $data);
$updater = new \Bnet\Money\Updater\CurrencyUpdater($tmpFile);
$a = null;
$updater->update_currency_table(function($item) use(&$a) {
$a = $item;
}, function($item, $saver) {
return $saver($item);
}, function($file) {
return [explode(':', file_get_contents($file))];
});
$this->assertEquals('T1', $a[0], 'first');
$this->assertEquals('Test2', $a[1], 'second');
@unlink($tmpFile);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment