ydassdsa
This commit is contained in:
@@ -197,7 +197,8 @@ final class FxRatesService
|
||||
public function refreshLatestRates(?array $currencies = null, ?string $baseCurrency = null, string $triggerSource = 'manual'): array
|
||||
{
|
||||
$requestedBase = $this->normalizeCurrency($baseCurrency ?: $this->defaultBaseCurrency());
|
||||
$payload = $this->fetchLatestPayload($requestedBase, null);
|
||||
$requestedCurrencies = $this->normalizeRequestedCurrencies($currencies, $requestedBase);
|
||||
$payload = $this->fetchLatestPayload($requestedBase, $requestedCurrencies);
|
||||
$base = $this->normalizeCurrency((string) ($payload['base'] ?? $requestedBase));
|
||||
if ($base === '') {
|
||||
$base = $requestedBase !== '' ? $requestedBase : 'USD';
|
||||
@@ -227,11 +228,16 @@ final class FxRatesService
|
||||
public function ensureFreshLatestRates(float $maxAgeHours = 24.0, ?string $baseCurrency = null, ?array $currencies = null, string $triggerSource = 'manual'): array
|
||||
{
|
||||
$base = $this->normalizeCurrency($baseCurrency ?: $this->defaultBaseCurrency());
|
||||
$requestedCurrencies = $this->normalizeRequestedCurrencies($currencies, $base);
|
||||
$latest = $this->repository->getLatestFetch($base);
|
||||
$maxAgeSeconds = (int) round(max(1.0, $maxAgeHours) * 3600);
|
||||
$fetchedAt = is_array($latest) ? strtotime((string) ($latest['fetched_at'] ?? '')) : false;
|
||||
$fetchedAt = is_array($latest) ? $this->parseStoredUtcTimestamp((string) ($latest['fetched_at'] ?? '')) : null;
|
||||
|
||||
if ($fetchedAt !== false && (time() - $fetchedAt) <= $maxAgeSeconds) {
|
||||
if (
|
||||
$fetchedAt !== null
|
||||
&& (time() - $fetchedAt) <= $maxAgeSeconds
|
||||
&& $this->latestFetchCoversCurrencies($latest, $requestedCurrencies)
|
||||
) {
|
||||
return [
|
||||
'base' => $base,
|
||||
'rate_date' => $latest['rate_date'] ?? null,
|
||||
@@ -243,7 +249,7 @@ final class FxRatesService
|
||||
];
|
||||
}
|
||||
|
||||
$result = $this->refreshLatestRates($currencies, $base, $triggerSource);
|
||||
$result = $this->refreshLatestRates($requestedCurrencies, $base, $triggerSource);
|
||||
$result['reused'] = false;
|
||||
return $result;
|
||||
}
|
||||
@@ -855,6 +861,38 @@ final class FxRatesService
|
||||
return strtoupper(trim((string) $currency));
|
||||
}
|
||||
|
||||
private function normalizeRequestedCurrencies(?array $currencies, string $baseCurrency): ?array
|
||||
{
|
||||
if (!is_array($currencies)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$base = $this->normalizeCurrency($baseCurrency);
|
||||
$normalized = array_values(array_unique(array_filter(array_map(
|
||||
fn (mixed $currency): string => $this->normalizeCurrency((string) $currency),
|
||||
$currencies
|
||||
), fn (string $currency): bool => $currency !== '' && $currency !== $base)));
|
||||
|
||||
return $normalized === [] ? null : $normalized;
|
||||
}
|
||||
|
||||
private function latestFetchCoversCurrencies(?array $latestFetch, ?array $currencies): bool
|
||||
{
|
||||
if (!is_array($latestFetch) || !is_numeric($latestFetch['id'] ?? null) || !is_array($currencies) || $currencies === []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$snapshot = $this->repository->getSnapshotByFetchId((int) $latestFetch['id'], $currencies);
|
||||
$rates = is_array($snapshot['rates'] ?? null) ? $snapshot['rates'] : [];
|
||||
foreach ($currencies as $currency) {
|
||||
if (!array_key_exists($currency, $rates)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function normalizeTimestamp(?string $value): ?string
|
||||
{
|
||||
$value = trim((string) $value);
|
||||
@@ -863,13 +901,31 @@ final class FxRatesService
|
||||
}
|
||||
|
||||
try {
|
||||
$date = new DateTimeImmutable($value);
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}(?::\d{2})?)?$/', $value) === 1) {
|
||||
$date = new DateTimeImmutable(str_replace(' ', 'T', $value), new DateTimeZone('UTC'));
|
||||
} else {
|
||||
$date = new DateTimeImmutable($value);
|
||||
}
|
||||
return $date->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s');
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function parseStoredUtcTimestamp(string $value): ?int
|
||||
{
|
||||
$normalized = $this->normalizeTimestamp($value);
|
||||
if ($normalized === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (new DateTimeImmutable($normalized, new DateTimeZone('UTC')))->getTimestamp();
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function normalizeRateDate(mixed $value): string
|
||||
{
|
||||
if (is_string($value) && trim($value) !== '') {
|
||||
|
||||
Reference in New Issue
Block a user