1919
2020class FetchCurrenciesService {
2121 private static $ EXCHANGE_URL = 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/{base}.json ' ;
22+ private static $ SYMBOLS_FILE = __DIR__ . '/symbols.json ' ;
23+
2224 private IAppConfig $ config ;
25+
2326 private CurrencyMapper $ currencyMapper ;
27+
2428 private CospendProjectMapper $ projectMapper ;
29+
2530 private LoggerInterface $ logger ;
2631
32+ /* @var array<string, array<symbol: string, name: string, symbol_native: string, decimal_digits: int, rounding: int, code: string, name_plural: string>> */
33+ private array $ symbols ;
34+
2735 public function __construct (
2836 IAppConfig $ config ,
2937 CurrencyMapper $ currencyMapper ,
@@ -34,6 +42,7 @@ public function __construct(
3442 $ this ->currencyMapper = $ currencyMapper ;
3543 $ this ->projectMapper = $ projectMapper ;
3644 $ this ->logger = $ logger ;
45+ $ this ->loadSymbols ();
3746 }
3847
3948 public function fetchCurrencyRates (): void {
@@ -68,8 +77,13 @@ public function fetchCurrencyRates(): void {
6877
6978 foreach ($ currencies as $ currency ) {
7079 $ cur = $ this ->getCurrencyName ($ currency ->getName ());
80+ if ($ cur === null ) {
81+ $ this ->logger ->error ('Currency not found: ' . $ currency ->getName ());
82+ continue ;
83+ }
7184 $ lcur = strtolower ($ cur );
72- $ newRate = floatval (number_format (1 / $ json [$ lbase ][$ lcur ], 2 ));
85+ $ baseRate = $ json [$ lbase ][$ lcur ];
86+ $ newRate = floatval (number_format (1 / $ baseRate , 2 ));
7387 $ currency ->setExchangeRate ($ newRate );
7488 $ this ->logger ->info ('Setting exchange rate for currency ' . $ cur . ' to ' . $ newRate );
7589 $ this ->currencyMapper ->update ($ currency );
@@ -80,17 +94,35 @@ public function fetchCurrencyRates(): void {
8094 $ this ->config ->setValueString ('autocurrency ' , 'last_update ' , $ lastUpdate );
8195 }
8296
83- private function getCurrencyName (string $ name ): string {
84- // find 3-letter currency code for the base currency
85- preg_match ('/([A-Z]{3})/ ' , $ name , $ matches );
97+ /** Match the currency name from the known currencies. **/
98+ private function getCurrencyName (string $ name ): ?string {
99+ foreach ($ this ->symbols as $ cur => $ currency ) {
100+ // e.g. usd
101+ $ id = strtolower ($ cur );
102+ if (strtolower ($ name ) === $ id ) {
103+ return $ id ;
104+ }
86105
87- $ this ->logger ->info ('Matches: ' . json_encode ($ matches ));
106+ // e.g. $
107+ $ symbol = $ currency ['symbol ' ];
108+ if (str_contains ($ name , $ symbol )) {
109+ return $ id ;
110+ }
88111
89- if (count ($ matches ) === 2 ) {
90- $ name = $ matches [1 ];
112+ // e.g. $ USD
113+ preg_match ('/\b ' . $ id . '\b/ ' , strtolower ($ name ), $ matches );
114+ if (count ($ matches ) > 0 ) {
115+ return $ id ;
116+ }
91117 }
92118
93- return $ name ;
119+ return null ;
120+ }
121+
122+ /** Load symbols from the symbols.json file */
123+ private function loadSymbols (): void {
124+ $ this ->symbols = json_decode (file_get_contents (FetchCurrenciesService::$ SYMBOLS_FILE ), true );
125+ $ this ->logger ->info ('Loaded symbols: ' . json_encode ($ this ->symbols ));
94126 }
95127
96128 /**
0 commit comments