PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.9.2
ووسلام – همگام سازی ووکامرس و باسلام v1.9.2
1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 1.8.6 All 53 releases
sync-basalam / includes / Services / Api / ApiResponseHandler.php

ApiResponseHandler.php in ووسلام – همگام سازی ووکامرس و باسلام 1.9.2, at includes/Services/Api/ApiResponseHandler.php

152 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SyncBasalam\Services\Api;
4
5 use SyncBasalam\Admin\Settings\SettingsConfig;
6 use SyncBasalam\Admin\Settings\SettingsManager;
7 use SyncBasalam\Jobs\Exceptions\RetryableException;
8 use SyncBasalam\Jobs\Exceptions\NonRetryableException;
9
10 defined('ABSPATH') || exit;
11
12 class ApiResponseHandler
13 {
14 public function handle($response, $url = ''): array
15 {
16 if (is_wp_error($response)) {
17 return $this->handleWpError($response, $url);
18 }
19
20 $body = wp_remote_retrieve_body($response);
21
22 $statusCodeRaw = wp_remote_retrieve_response_code($response);
23 $statusCode = is_numeric($statusCodeRaw) ? (int) $statusCodeRaw : 0;
24
25 return $this->handleHttpStatusCode($statusCode, $body, $url);
26 }
27
28
29 private function handleWpError(\WP_Error $response, string $url = ''): array
30 {
31 $errorMessage = $response->get_error_message();
32 $category = RequestStatusTracker::recordWpError($response, $url);
33 $reason = RequestStatusTracker::describeCategoryFa($category);
34
35 if ($category === 'blocked_http') {
36 throw new BlockedHttpRequestException(esc_html($reason . ' | جزئیات فنی: ' . $errorMessage));
37 }
38
39 if ($category === 'timeout') {
40 throw RetryableException::apiTimeout(esc_html($reason . ' | جزئیات فنی: ' . $errorMessage));
41 }
42
43 if (in_array($category, ['dns_error', 'ssl_error', 'connection_error', 'network_error'], true)) {
44 throw RetryableException::networkError(esc_html($reason . ' | جزئیات فنی: ' . $errorMessage));
45 }
46
47 throw RetryableException::temporary(esc_html($reason . ' | جزئیات فنی: ' . $errorMessage));
48 }
49
50 private function handleHttpStatusCode(int $statusCode, $body, $url): array
51 {
52 RequestStatusTracker::recordHttpStatus($statusCode, $url);
53
54 if ($statusCode === 0) {
55 throw new BlockedHttpRequestException(esc_html(RequestStatusTracker::describeHttpStatusFa(0)));
56 }
57
58 if (in_array($statusCode, [200, 201, 202], true)) {
59 return $this->successResponse($body, $statusCode);
60 }
61
62 if (in_array($statusCode, [408, 504], true)) {
63 throw RetryableException::apiTimeout(esc_html(RequestStatusTracker::describeHttpStatusFa($statusCode)));
64 }
65
66 if ($statusCode === 429) {
67 throw RetryableException::rateLimit(esc_html(RequestStatusTracker::describeHttpStatusFa(429)));
68 }
69
70 if (in_array($statusCode, [500, 502, 503], true)) {
71 throw RetryableException::serverError(esc_html(RequestStatusTracker::describeHttpStatusFa($statusCode)));
72 }
73
74 if ($statusCode === 401) {
75 if ($this->isBasalamDomain($url)) {
76 SettingsManager::updateSettings([
77 SettingsConfig::TOKEN => null,
78 SettingsConfig::REFRESH_TOKEN => null,
79 ]);
80 }
81 throw NonRetryableException::unauthorized(esc_html(RequestStatusTracker::describeHttpStatusFa(401)));
82 }
83
84 $clientErrors = [
85 400 => 'درخواست نا�
86 عتبر',
87 403 => 'دسترسی غیر�
88 جاز',
89 404 => '�
90 نبع �
91 ورد نظر یافت نشد',
92 422 => 'خطا در پردازش داده‌ها',
93 ];
94
95 if (isset($clientErrors[$statusCode])) {
96 $bodyMessage = $this->extractErrorMessageFromBody($body);
97 $base = $bodyMessage ?: $clientErrors[$statusCode];
98 $reason = RequestStatusTracker::describeHttpStatusFa($statusCode);
99 throw NonRetryableException::permanent(esc_html($base . $reason));
100 }
101
102 // Unknown error - treat as retryable
103 throw RetryableException::temporary(esc_html(RequestStatusTracker::describeHttpStatusFa($statusCode)));
104 }
105
106 private function extractErrorMessageFromBody($body): ?string
107 {
108 if (empty($body)) return null;
109
110 if (is_string($body)) {
111 $decoded = json_decode($body, true);
112 if (is_array($decoded)) {
113 $body = $decoded;
114 }
115 }
116
117 if (is_array($body)) {
118 if (!empty($body['errors'][0]['message'])) return $body['errors'][0]['message'];
119 if (isset($body['messages'][0]['message'])) return $body['messages'][0]['message'];
120 if (isset($body['message'])) return $body['message'];
121 if (isset($body['error'])) return $body['error'];
122 }
123
124 return null;
125 }
126
127 private function isBasalamDomain(string $url): bool
128 {
129 $host = parse_url($url, PHP_URL_HOST);
130
131 if (!is_string($host) || $host === '') return false;
132
133
134 return $host === 'basalam.com' || substr(strtolower($host), -strlen('.basalam.com')) === '.basalam.com';
135 }
136
137 private function successResponse($body, int $statusCode): array
138 {
139 return [
140 'body' => $body,
141 'status_code' => $statusCode,
142 'success' => true
143 ];
144 }
145
146 public function handleTimeout(string $url): array
147 {
148 RequestStatusTracker::recordCategory('timeout', ['url' => $url]);
149 throw RetryableException::apiTimeout(esc_html(RequestStatusTracker::describeCategoryFa('timeout')));
150 }
151 }
152