added zarbox link alternate
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user