getSettings(SettingsConfig::TOKEN); $this->defaultHeaders = [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'user-agent' => 'Wp-Basalam', 'referer' => get_site_url(), ]; if (!empty($token)) $this->defaultHeaders['Authorization'] = 'Bearer ' . $token; $this->validator = new ApiRequestValidator(); $this->responseHandler = new ApiResponseHandler(); $this->circuitBreaker = new CircuitBreaker(); } public function run(string $url, $data, array $headers = []): array { $url = Endpoints::resolve($url); $validationResult = $this->validator->validate($url, $data, $headers); if (!$validationResult['valid']) { Logger::error("خطا در اعتبارسنجی ریکوئست: " . $validationResult['message']); return [ 'body' => null, 'status_code' => 400, 'error' => $validationResult['message'] ]; } // Check circuit breaker — throws CircuitBreakerOpenException when OPEN. $this->circuitBreaker->isAllowed(); $preparedRequest = $this->prepareRequest($url, $data, $headers); if (isset($preparedRequest['error'])) { Logger::error("خطای امنیتی: " . $preparedRequest['error']); return ['body' => null, 'status_code' => 401, 'error' => $preparedRequest['error']]; } try { $response = $this->executeRequest($preparedRequest); $result = $this->responseHandler->handle($response, $url); $this->circuitBreaker->recordSuccess(); return $result; } catch (\Throwable $e) { if ($this->shouldRecordFailure($e, $url)) { $this->circuitBreaker->recordFailure(); } throw $e; } } protected function prepareRequest(string $url, $data, array $headers): array { $headers = array_merge($this->defaultHeaders, $headers); return [ 'url' => $url, 'data' => json_encode($data), 'headers' => $headers, ]; } abstract protected function executeRequest(array $request); protected function shouldRecordFailure(\Throwable $exception, string $url): bool { if (!$this->isBasalamDomain($url)) return false; if ($exception instanceof BlockedHttpRequestException) return false; return $exception instanceof RetryableException; } protected function isBasalamDomain(string $url): bool { $host = parse_url($url, PHP_URL_HOST); if (!is_string($host) || $host === '') return false; $host = strtolower($host); return $host === 'basalam.com' || substr($host, -strlen('.basalam.com')) === '.basalam.com'; } }