cyxc
This commit is contained in:
@@ -151,14 +151,6 @@ final class Router
|
||||
$this->respond(['data' => $this->probeFxRates(Http::input())], 200);
|
||||
}
|
||||
|
||||
if ($resource === 'currencies-refresh' && $method === 'POST') {
|
||||
$this->respond(['data' => $this->refreshCurrencies()], 201);
|
||||
}
|
||||
|
||||
if ($resource === 'currencies-probe' && $method === 'POST') {
|
||||
$this->respond(['data' => $this->probeCurrencies()], 200);
|
||||
}
|
||||
|
||||
if ($resource === 'fx-history' && $method === 'GET') {
|
||||
$this->respond(['data' => $this->fxHistory()]);
|
||||
}
|
||||
@@ -297,18 +289,6 @@ final class Router
|
||||
Http::json(['data' => $this->purchaseMiner($projectKey, (int) $matches[1], Http::input())], 201);
|
||||
}
|
||||
|
||||
if ($resource === 'currencies' && $method === 'GET') {
|
||||
Http::json(['data' => $this->currencies()]);
|
||||
}
|
||||
|
||||
if ($resource === 'currency-aliases' && $method === 'GET') {
|
||||
Http::json(['data' => $this->currencyAliases()]);
|
||||
}
|
||||
|
||||
if ($resource === 'currency-aliases' && $method === 'POST') {
|
||||
Http::json(['data' => $this->saveCurrencyAlias(Http::input())], 201);
|
||||
}
|
||||
|
||||
throw new ApiException('Ressource nicht gefunden.', 404, ['resource' => $resource, 'method' => $method]);
|
||||
} catch (ApiException $exception) {
|
||||
$this->debug->add('router.handle.api_exception', [
|
||||
@@ -513,8 +493,6 @@ final class Router
|
||||
$backup = [
|
||||
'project' => $this->repository()->getProject($projectKey),
|
||||
'settings' => $this->safeRead(fn () => $this->repository()->getSettings($projectKey)),
|
||||
'currencies' => $this->safeRead(fn () => $this->repository()->listCurrencies(), []),
|
||||
'currency_aliases' => $this->safeRead(fn () => $this->repository()->listCurrencyAliases(), []),
|
||||
'cost_plans' => $this->safeRead(fn () => $this->repository()->listCostPlans($projectKey), []),
|
||||
'measurements' => $this->safeRead(fn () => $this->repository()->listAllMeasurements($projectKey), []),
|
||||
'measurement_rates' => $this->safeRead(fn () => $this->repository()->listMeasurementRates($projectKey), []),
|
||||
@@ -538,23 +516,6 @@ final class Router
|
||||
$projectName = is_array($backup['project']) ? ($backup['project']['project_name'] ?? null) : null;
|
||||
$this->repository()->ensureProject($projectKey, is_string($projectName) ? $projectName : null);
|
||||
|
||||
foreach ($backup['currencies'] as $currency) {
|
||||
$this->repository()->saveCurrency([
|
||||
'code' => $currency['code'],
|
||||
'name' => $currency['name'],
|
||||
'symbol' => $currency['symbol'] ?? null,
|
||||
'is_active' => !empty($currency['is_active']) ? 1 : 0,
|
||||
'is_crypto' => !empty($currency['is_crypto']) ? 1 : 0,
|
||||
'sort_order' => (int) ($currency['sort_order'] ?? 0),
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($backup['currency_aliases'] as $alias) {
|
||||
if (!empty($alias['alias_code']) && !empty($alias['currency_code'])) {
|
||||
$this->repository()->saveCurrencyAlias((string) $alias['alias_code'], (string) $alias['currency_code']);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($backup['settings'])) {
|
||||
$this->repository()->saveSettings($projectKey, [
|
||||
'baseline_measured_at' => $backup['settings']['baseline_measured_at'],
|
||||
@@ -750,7 +711,6 @@ final class Router
|
||||
'targets' => count($backup['targets']),
|
||||
'dashboards' => count($backup['dashboards']),
|
||||
'miner_offers' => count($backup['miner_offers']),
|
||||
'currency_aliases' => count($backup['currency_aliases']),
|
||||
'fx_rates' => $restoredFxRates,
|
||||
],
|
||||
]);
|
||||
@@ -795,20 +755,6 @@ final class Router
|
||||
return $this->fx()->probeLatestRates($base);
|
||||
}
|
||||
|
||||
private function refreshCurrencies(): array
|
||||
{
|
||||
$result = $this->fx()->refreshCurrencyCatalog();
|
||||
$synced = $this->syncLocalCurrencyCatalogFromFxRates(true);
|
||||
return $result + [
|
||||
'local_catalog_synced' => count($synced),
|
||||
];
|
||||
}
|
||||
|
||||
private function probeCurrencies(): array
|
||||
{
|
||||
return $this->fx()->probeCurrencyCatalog();
|
||||
}
|
||||
|
||||
private function fxHistory(): array
|
||||
{
|
||||
if (!modules()->isEnabled('fx-rates') || !modules()->hasFunction('fx-rates', 'recent_fetches')) {
|
||||
@@ -1293,7 +1239,7 @@ final class Router
|
||||
|
||||
private function bootstrapMeasurements(string $projectKey, array $settings, string $view): array
|
||||
{
|
||||
if (in_array($view, ['settings', 'currencies', 'dashboards'], true)) {
|
||||
if (in_array($view, ['settings', 'dashboards'], true)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -1373,7 +1319,7 @@ final class Router
|
||||
private function normalizeBootstrapView(string $view): string
|
||||
{
|
||||
$normalized = trim(strtolower($view));
|
||||
return in_array($normalized, ['overview', 'measurements', 'dashboards', 'currencies', 'mining', 'settings'], true)
|
||||
return in_array($normalized, ['overview', 'measurements', 'dashboards', 'mining', 'settings'], true)
|
||||
? $normalized
|
||||
: 'overview';
|
||||
}
|
||||
@@ -1475,22 +1421,12 @@ final class Router
|
||||
return;
|
||||
}
|
||||
|
||||
$knownCodes = array_map(
|
||||
static fn (array $currency): string => strtoupper((string) ($currency['code'] ?? '')),
|
||||
$this->currencies()
|
||||
);
|
||||
|
||||
if (in_array($priceCurrency, $knownCodes, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$matched = $this->currencyCatalogEntry($priceCurrency);
|
||||
$this->repository()->ensureCurrencyCode($priceCurrency, $matched['name'] ?? $priceCurrency);
|
||||
|
||||
try {
|
||||
$this->refreshCurrencies();
|
||||
} catch (\Throwable) {
|
||||
// Measurement save must not fail because the external currency sync is unavailable.
|
||||
if ($this->currencyCatalogEntry($priceCurrency) === null) {
|
||||
throw new ApiException(
|
||||
'Waehrung ist im fx-rates Katalog nicht vorhanden.',
|
||||
422,
|
||||
['currency' => $priceCurrency]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1580,25 +1516,7 @@ final class Router
|
||||
|
||||
private function currencies(): array
|
||||
{
|
||||
$catalog = $this->syncLocalCurrencyCatalogFromFxRates();
|
||||
return $catalog !== [] ? $catalog : $this->repository()->listCurrencies();
|
||||
}
|
||||
|
||||
private function currencyAliases(): array
|
||||
{
|
||||
return $this->repository()->listCurrencyAliases();
|
||||
}
|
||||
|
||||
private function saveCurrencyAlias(array $input): array
|
||||
{
|
||||
$aliasCode = strtoupper(trim((string) ($input['alias_code'] ?? '')));
|
||||
$currencyCode = $this->requiredCurrency($input['currency_code'] ?? null, 'currency_code');
|
||||
|
||||
if (!preg_match('/^[A-Z0-9]{3,10}$/', $aliasCode)) {
|
||||
throw new ApiException('Feld alias_code muss ein gueltiger Waehrungscode sein.', 422);
|
||||
}
|
||||
|
||||
return $this->repository()->saveCurrencyAlias($aliasCode, $currencyCode);
|
||||
return $this->currencyCatalog();
|
||||
}
|
||||
|
||||
private function minerOffers(string $projectKey): array
|
||||
@@ -1945,24 +1863,18 @@ final class Router
|
||||
throw new ApiException("Feld {$field} muss ein gueltiger Waehrungscode sein.", 422);
|
||||
}
|
||||
|
||||
$resolved = $this->repository()->resolveCurrencyCode($currency);
|
||||
if ($resolved !== null && !empty($resolved['code'])) {
|
||||
return (string) $resolved['code'];
|
||||
}
|
||||
|
||||
$catalogEntry = $this->currencyCatalogEntry($currency);
|
||||
if (is_array($catalogEntry)) {
|
||||
$this->repository()->ensureCurrencyCode($currency, (string) ($catalogEntry['name'] ?? $currency));
|
||||
return $currency;
|
||||
}
|
||||
|
||||
throw new ApiException(
|
||||
"Feld {$field} verweist auf keinen vorhandenen Waehrungsrecord.",
|
||||
"Feld {$field} verweist auf keinen vorhandenen fx-rates Waehrungscode.",
|
||||
422,
|
||||
[
|
||||
'field' => $field,
|
||||
'missing_currency' => $currency,
|
||||
'hint' => 'Synchronisiere zuerst den Waehrungskatalog aus fx-rates oder hinterlege einen Alias auf einen bestehenden Waehrungsrecord.',
|
||||
'hint' => 'Synchronisiere zuerst den Waehrungskatalog im Modul fx-rates.',
|
||||
'available_currencies' => array_slice(array_map(
|
||||
static fn (array $item): string => (string) ($item['code'] ?? ''),
|
||||
$this->currencies()
|
||||
@@ -1981,10 +1893,15 @@ final class Router
|
||||
|
||||
private function assertCurrencyType(string $code, bool $expectedCrypto, string $field): void
|
||||
{
|
||||
$this->ensureLocalCurrencyRecord($code);
|
||||
$resolved = $this->repository()->resolveCurrencyCode($code);
|
||||
$currency = is_array($resolved) ? ($resolved['currency'] ?? null) : null;
|
||||
$isCrypto = !empty($currency['is_crypto']);
|
||||
if ($this->currencyCatalogEntry($code) === null) {
|
||||
throw new ApiException(
|
||||
"Feld {$field} verweist auf keinen vorhandenen fx-rates Waehrungscode.",
|
||||
422,
|
||||
['field' => $field, 'currency' => $code]
|
||||
);
|
||||
}
|
||||
|
||||
$isCrypto = $this->isCryptoCurrencyCode($code);
|
||||
if ($isCrypto !== $expectedCrypto) {
|
||||
throw new ApiException(
|
||||
$expectedCrypto
|
||||
@@ -2248,22 +2165,6 @@ final class Router
|
||||
return null;
|
||||
}
|
||||
|
||||
private function syncLocalCurrencyCatalogFromFxRates(bool $forceRefresh = false): array
|
||||
{
|
||||
if ($forceRefresh) {
|
||||
$this->fxRatesSettingsCache = null;
|
||||
$this->currencyCatalogCache = null;
|
||||
}
|
||||
|
||||
$catalog = $this->currencyCatalog();
|
||||
if ($catalog === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$this->repository()->saveCurrencies($catalog);
|
||||
return $this->repository()->listCurrencies();
|
||||
}
|
||||
|
||||
private function syncFxRatesPreferredCurrencies(array $preferredCurrencies): void
|
||||
{
|
||||
if (!modules()->isEnabled('fx-rates') || !modules()->hasFunction('fx-rates', 'save_runtime_settings')) {
|
||||
@@ -2274,22 +2175,7 @@ final class Router
|
||||
'preferred_currencies' => $preferredCurrencies,
|
||||
]);
|
||||
$this->fxRatesSettingsCache = null;
|
||||
}
|
||||
|
||||
private function ensureLocalCurrencyRecord(string $code): void
|
||||
{
|
||||
$resolved = $this->repository()->resolveCurrencyCode($code);
|
||||
if ($resolved !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$catalogEntry = $this->currencyCatalogEntry($code);
|
||||
if ($catalogEntry !== null) {
|
||||
$this->repository()->saveCurrency($catalogEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->repository()->ensureCurrencyCode($code, $code);
|
||||
$this->currencyCatalogCache = null;
|
||||
}
|
||||
|
||||
private function isCryptoCurrencyCode(string $code): bool
|
||||
|
||||
Reference in New Issue
Block a user