added zarbox link alternate

This commit is contained in:
2026-07-12 22:13:46 +03:30
parent 300c909b9e
commit 82691cdf2c
2 changed files with 105 additions and 25 deletions
+104 -24
View File
@@ -46,17 +46,99 @@ class ZaarboxPriceService
public function apiUrl(): string
{
$url = trim((string) $this->config->getString(
'zaarbox_api_url',
(string) config('price_providers.zaarbox_api_url', 'https://price.zaarbox.ir/api/free')
$candidates = $this->feedUrlCandidates();
return $candidates[0] ?? 'https://price.zaarbox.ir/api/free';
}
/**
* آدرس‌های فید `/api/free` به ترتیب failover — از کلید zaarbox_api_url.
* مقدار می‌تواند تک‌URL (legacy) یا JSON آرایه/لیست جداشده با کاما/خط جدید باشد (تا ۵ مورد).
* هر مورد به مسیر /api/free نرمال می‌شود.
*
* @return array<int, string>
*/
public function feedUrlCandidates(): array
{
$raw = trim((string) $this->config->getString('zaarbox_api_url', ''));
$urls = [];
if ($raw !== '') {
$decoded = json_decode($raw, true);
if (is_array($decoded)) {
foreach ($decoded as $item) {
$value = is_array($item) ? ($item['url'] ?? '') : $item;
$urls[] = trim((string) $value);
}
} else {
foreach (preg_split('/[\r\n,]+/', $raw) ?: [] as $item) {
$urls[] = trim((string) $item);
}
}
}
$candidates = array_values(array_filter(
array_map(fn (string $u) => $this->normalizeFeedUrl($u), $urls),
fn (string $u) => $u !== ''
));
return $url !== '' ? $url : 'https://price.zaarbox.ir/api/free';
$candidates = array_values(array_unique($candidates));
if ($candidates === []) {
$fallback = trim((string) config('price_providers.zaarbox_api_url', 'https://price.zaarbox.ir/api/free'));
$candidates[] = $this->normalizeFeedUrl($fallback !== '' ? $fallback : 'https://price.zaarbox.ir/api/free');
}
return array_slice($candidates, 0, 5);
}
/** نرمال‌سازی به آدرس فید — اگر مسیر /api/free نداشت اضافه می‌شود */
private function normalizeFeedUrl(string $url): string
{
$url = rtrim(trim($url), '/');
if ($url === '') {
return '';
}
if (preg_match('~/api/free$~i', $url)) {
return $url;
}
return $url . '/api/free';
}
/**
* دریافت فید با failover — اولین سروری که آرایهٔ معتبر برگرداند.
*
* @return array<int, array<string, mixed>>|null
*/
private function fetchFeedWithFailover(): ?array
{
foreach ($this->feedUrlCandidates() as $url) {
try {
$prices = Http::withoutVerifying()
->timeout(12)
->get($url)
->json();
if (is_array($prices) && $prices !== []) {
return $prices;
}
} catch (\Throwable $e) {
Log::warning('Partner feed url failed, trying next', [
'url' => $url,
'message' => $e->getMessage(),
]);
}
}
return null;
}
public function hasApiUrlConfigured(): bool
{
return trim($this->config->getString('zaarbox_api_url', '')) !== '';
return $this->feedUrlCandidates() !== [];
}
/** کلید یا id ردیف انس در JSON تابلو (settings: zaarbox_ounce_key) */
@@ -305,10 +387,19 @@ class ZaarboxPriceService
return [
'price' => round((float) $rawPrice, 2),
'label' => trim((string) ($ounce['name'] ?? 'اونس طلا')) ?: 'اونس طلا',
'label' => self::formatOunceDisplayLabel((string) ($ounce['name'] ?? '')),
];
}
private static function formatOunceDisplayLabel(string $name): string
{
$label = trim($name);
$label = preg_replace('/\s+tala\.ir\s*$/iu', '', $label) ?? $label;
$label = trim($label);
return $label !== '' ? $label : 'اونس طلا';
}
/**
* @param array<string, mixed> $payload
* @return array<string, mixed>
@@ -332,10 +423,7 @@ class ZaarboxPriceService
}
try {
$prices = Http::withoutVerifying()
->timeout(20)
->get($this->apiUrl())
->json();
$prices = $this->fetchFeedWithFailover();
if (!is_array($prices)) {
return $empty;
@@ -364,18 +452,7 @@ class ZaarboxPriceService
/** @return array<int, array<string, mixed>>|null */
public function fetchPriceList(): ?array
{
try {
$prices = Http::withoutVerifying()
->timeout(20)
->get($this->apiUrl())
->json();
return is_array($prices) ? $prices : null;
} catch (\Throwable $e) {
Log::warning('Zaarbox price list fetch failed', ['message' => $e->getMessage()]);
return null;
}
return $this->fetchFeedWithFailover();
}
/**
@@ -457,8 +534,11 @@ class ZaarboxPriceService
}
try {
$url = $apiUrl ?: $this->apiUrl();
$prices = Http::withoutVerifying()->timeout(20)->get($url)->json();
if ($apiUrl !== null && trim($apiUrl) !== '') {
$prices = Http::withoutVerifying()->timeout(12)->get($apiUrl)->json();
} else {
$prices = $this->fetchFeedWithFailover();
}
if (!is_array($prices)) {
return $empty;
}