PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.3
ووسلام – همگام سازی ووکامرس و باسلام v1.10.3
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 / TicketServiceManager.php

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

217 lines 6.7 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;
4
5 use SyncBasalam\Admin\Settings\SettingsConfig;
6 use SyncBasalam\Services\Hamsalam\FetchHamsalamToken;
7 use SyncBasalam\Services\Hamsalam\FetchHamsalamBusinessId;
8
9 use SyncBasalam\Services\Ticket\FetchAllTickets;
10 use SyncBasalam\Services\Ticket\FetchTicket;
11 use SyncBasalam\Services\Ticket\FetchTicketSubjects;
12 use SyncBasalam\Services\Ticket\CreateTicket;
13 use SyncBasalam\Services\Ticket\CreateTicketItem;
14 use SyncBasalam\Services\Ticket\UploadTicketMedia;
15
16 use SyncBasalam\Jobs\Exceptions\RetryableException;
17 use SyncBasalam\Jobs\Exceptions\NonRetryableException;
18
19 class TicketServiceManager
20 {
21 private $hamsalamToken;
22 private $hamsalamBusinessId;
23 private $tokenFetcher;
24 private $businessIdFetcher;
25
26 private const MAX_RETRY_ATTEMPTS = 2;
27
28 public static function isUnauthorized($response): bool
29 {
30 return is_array($response) && isset($response['status_code']) && intval($response['status_code']) === 401;
31 }
32
33 public static function ticketStatuses(): array
34 {
35 return [
36 'pending_response' => 'در انتظار پاسخ',
37 'under_review' => 'در حال بررسی',
38 'closed' => 'بسته شده',
39 'answered' => 'پاسخ داده شده',
40 ];
41 }
42
43 public static function resolveTicketStatus(array $ticket): string
44 {
45 $status = $ticket['data']['status'] ?? $ticket['status'] ?? '';
46
47 if (is_array($status)) {
48 $status = $status['slug'] ?? $status['name'] ?? '';
49 }
50
51 return strtolower(trim((string) $status));
52 }
53
54 public static function isTicketClosed(array $ticket): bool
55 {
56 return in_array(self::resolveTicketStatus($ticket), ['closed', 'بسته شده'], true);
57 }
58
59 public function __construct()
60 {
61 $settings = (array) syncBasalamSettings()->getSettings();
62
63 $this->hamsalamToken = $settings[SettingsConfig::HAMSALAM_TOKEN] ?? null;
64 $this->hamsalamBusinessId = $settings[SettingsConfig::HAMSALAM_BUSINESS_ID] ?? null;
65 $this->tokenFetcher = new FetchHamsalamToken();
66 $this->businessIdFetcher = new FetchHamsalamBusinessId();
67 }
68
69 private function executeWithRetry(callable $callback, array $callbackArgs = []): array
70 {
71 $attempt = 0;
72
73 while ($attempt < self::MAX_RETRY_ATTEMPTS) {
74 $attempt++;
75
76 try {
77 $token = $this->getHamsalamToken();
78 if (!$this->hasValue($token)) return $this->buildErrorResponse('توکن ه�
79 سلا�
80 در دسترس نیست.', 401);
81
82 $data = call_user_func_array($callback, array_merge([$token], $callbackArgs));
83 } catch (RetryableException $e) {
84 return $this->buildErrorResponse($e->getMessage(), $e->getCode() ?: 400);
85 } catch (NonRetryableException $e) {
86 return $this->buildErrorResponse($e->getMessage(), $e->getCode() ?: 400);
87 } catch (\Exception $e) {
88 return $this->buildErrorResponse($e->getMessage(), 500);
89 }
90
91 if (!is_array($data) || !isset($data['status_code'])) {
92 return $this->buildErrorResponse('پاسخ دریافتی از سرویس نا�
93 عتبر است.', 500);
94 }
95
96 if (!self::isUnauthorized($data)) return $data;
97
98 if ($attempt >= self::MAX_RETRY_ATTEMPTS) return $data;
99
100 $this->refreshHamsalamToken();
101 }
102
103 return $this->buildErrorResponse('خطای ناشناخته در پردازش درخواست.', 500);
104 }
105
106 private function buildErrorResponse(string $message, int $statusCode = 500): array
107 {
108 return [
109 'status_code' => $statusCode,
110 'error' => true,
111 'message' => $message,
112 ];
113 }
114
115 private function getHamsalamToken()
116 {
117 if ($this->hasValue($this->hamsalamToken)) return $this->hamsalamToken;
118
119 $this->hamsalamToken = $this->tokenFetcher->fetch();
120 return $this->hamsalamToken;
121 }
122
123 private function refreshHamsalamToken(): void
124 {
125 $this->hamsalamToken = $this->tokenFetcher->fetch();
126 }
127
128 private function getHamsalamBusinessId()
129 {
130 if ($this->hasValue($this->hamsalamBusinessId)) return $this->hamsalamBusinessId;
131
132 $this->hamsalamBusinessId = $this->businessIdFetcher->fetch();
133 return $this->hamsalamBusinessId;
134 }
135
136 private function hasValue($value): bool
137 {
138 return !($value === null || $value === '');
139 }
140
141 private function isValidTicketPayload($title, $subject, $content): bool
142 {
143 if (!isset($title, $subject, $content)) return false;
144
145 $title = trim((string) $title);
146 $content = trim((string) $content);
147
148 return mb_strlen($title) >= 3
149 && mb_strlen($title) <= 255
150 && mb_strlen($content) >= 10;
151 }
152
153 public function CheckHamsalamAccess($page = 1): array
154 {
155 return $this->fetchAllTickets($page);
156 }
157
158 public function fetchTicketSubjects(): array
159 {
160 $service = new FetchTicketSubjects();
161 return $this->executeWithRetry([$service, 'execute']);
162 }
163
164 public function fetchAllTickets($page = 1): array
165 {
166 $service = new FetchAllTickets();
167 $page = max(1, intval($page));
168
169 return $this->executeWithRetry([$service, 'execute'], [$page]);
170 }
171
172 public function fetchTicket($ticket_id): array
173 {
174 $service = new FetchTicket($ticket_id);
175 return $this->executeWithRetry([$service, 'execute']);
176 }
177
178 public function uploadTicketMedia($filePath): array
179 {
180 $service = new UploadTicketMedia();
181 return $this->executeWithRetry([$service, 'execute'], [$filePath]);
182 }
183
184 public function createTicket($title, $subject, $content, $fileIds = []): array
185 {
186 if (!$this->isValidTicketPayload($title, $subject, $content)) {
187 return $this->buildErrorResponse('اطلاعات وارد شده �
188 عتبر نیست', 400);
189 }
190
191 $service = new CreateTicket();
192
193 $data = [
194 'title' => $title,
195 'subject' => $subject,
196 'content' => $content,
197 'file_ids' => is_array($fileIds) ? $fileIds : [],
198 'business_id' => $this->getHamsalamBusinessId(),
199 ];
200
201 return $this->executeWithRetry([$service, 'execute'], [$data]);
202 }
203
204 public function createTicketItem($ticket_id, $content, $fileIds = []): array
205 {
206 $service = new CreateTicketItem($ticket_id);
207
208 $data = [
209 'type' => 'content',
210 'content' => $content,
211 'file_ids' => is_array($fileIds) ? $fileIds : [],
212 ];
213
214 return $this->executeWithRetry([$service, 'execute'], [$data]);
215 }
216 }
217