1 | <?php |
||
2 | |||
3 | namespace Daaner\NovaPoshta; |
||
4 | |||
5 | use Daaner\NovaPoshta\Contracts\NovaPoshtaInterface; |
||
6 | use Exception; |
||
7 | use Illuminate\Http\Client\Response as ClientResponse; |
||
8 | use Illuminate\Support\Facades\Http; |
||
9 | use Illuminate\Support\Facades\Log; |
||
10 | |||
11 | class NovaPoshta implements NovaPoshtaInterface |
||
12 | { |
||
13 | protected $api; |
||
14 | protected $url; |
||
15 | protected $dev; |
||
16 | |||
17 | protected $return; |
||
18 | |||
19 | protected $model; |
||
20 | protected $calledMethod; |
||
21 | protected $methodProperties; |
||
22 | |||
23 | /** |
||
24 | * NovaPoshta constructor main settings. |
||
25 | */ |
||
26 | public function __construct() |
||
27 | { |
||
28 | $this->dev = config('novaposhta.dev'); |
||
29 | $this->getApi(); |
||
30 | $this->url = config('novaposhta.base_uri').config('novaposhta.point'); |
||
31 | |||
32 | $this->return = [ |
||
33 | 'success' => false, |
||
34 | 'result' => null, |
||
35 | 'info' => [], |
||
36 | ]; |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * @return void |
||
41 | */ |
||
42 | public function getApi(): void |
||
43 | { |
||
44 | if (! $this->api) { |
||
45 | $this->api = config('novaposhta.api_key'); |
||
46 | } |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * Устанавливаем API токен отличный от значения в конфиге. |
||
51 | * |
||
52 | * @param string $api API токен |
||
53 | * @return $this |
||
54 | */ |
||
55 | public function setApi(string $api): self |
||
56 | { |
||
57 | $this->api = $api; |
||
58 | |||
59 | return $this; |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * @param bool $auth |
||
64 | * @return ClientResponse|string|array |
||
65 | */ |
||
66 | public function getData(bool $auth = true) |
||
67 | { |
||
68 | $url = $this->url.'/'.$this->model.'/'.$this->calledMethod; |
||
69 | |||
70 | $body = []; |
||
71 | $body['modelName'] = $this->model; |
||
72 | $body['calledMethod'] = $this->calledMethod; |
||
73 | $body['methodProperties'] = $this->methodProperties; |
||
74 | |||
75 | if ($auth) { |
||
76 | $body['apiKey'] = $this->api; |
||
77 | } |
||
78 | |||
79 | if ($this->dev) { |
||
80 | $this->development($auth); |
||
81 | } |
||
82 | |||
83 | try { |
||
84 | $response = Http::timeout(config('novaposhta.http_response_timeout', 3)) |
||
85 | ->retry( |
||
86 | config('novaposhta.http_retry_max_time', 2), |
||
87 | config('novaposhta.http_retry_delay', 500) |
||
88 | ) |
||
89 | ->withHeaders([ |
||
90 | 'Accept' => 'application/json', |
||
91 | 'Content-Type' => 'application/json', |
||
92 | ]) |
||
93 | ->post($url, $body); |
||
94 | } catch (Exception $e) { |
||
95 | if ($e->getCode() == 401) { |
||
96 | // Ошибка API ключа |
||
97 | $response = __('novaposhta::novaposhta.statusCode.20000200068'); |
||
98 | } else { |
||
99 | $response = $e->getMessage(); |
||
100 | } |
||
101 | } |
||
102 | |||
103 | return $response; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * @param string $model Модель Новой Почты |
||
108 | * @param string $calledMethod Метод модели |
||
109 | * @param array|null $methodProperties Тело запроса |
||
110 | * @param bool $auth Использовать ли аутентификацию токеном или нет |
||
111 | * @return array |
||
112 | */ |
||
113 | public function getResponse( |
||
114 | string $model, |
||
115 | string $calledMethod, |
||
116 | ?array $methodProperties, |
||
117 | bool $auth = true |
||
118 | ): array { |
||
119 | $this->model = $model; |
||
120 | $this->calledMethod = $calledMethod; |
||
121 | $this->methodProperties = $methodProperties; |
||
122 | |||
123 | $response = $this->getData($auth); |
||
124 | |||
125 | // Ошибка курла |
||
126 | if (! ($response instanceof ClientResponse)) { |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
127 | $this->return['info']['error'] = $response; |
||
128 | $this->return['info']['StatusCode'] = '20000100016'; // Сервис не доступен |
||
129 | $this->return['info']['StatusLocale'] = __('novaposhta::novaposhta.error_data'); |
||
130 | |||
131 | return $this->return; |
||
132 | } |
||
133 | |||
134 | // Ошибка запроса или 401 |
||
135 | if ($response->failed()) { |
||
136 | $this->return['info']['error'] = trans('novaposhta::novaposhta.error_data'); |
||
137 | |||
138 | return $this->return; |
||
139 | } |
||
140 | |||
141 | // если что-то не JSON (типа application/pdf) |
||
142 | if ($response->header('Content-Type') !== 'application/json') { |
||
143 | $this->return['success'] = $response->ok(); |
||
144 | |||
145 | $this->return['info']['file'] = true; |
||
146 | $this->return['info']['ContentType'] = $response->header('Content-Type'); |
||
147 | $this->return['info']['ContentDisposition'] = $response->header('Content-Disposition') ?? ''; |
||
148 | |||
149 | $this->return['result'] = $response->body(); |
||
150 | |||
151 | return $this->return; |
||
152 | } |
||
153 | |||
154 | $answer = $response->json(); |
||
155 | |||
156 | /** |
||
157 | * Development. |
||
158 | */ |
||
159 | if ($this->dev) { |
||
160 | $this->return['dev'] = $answer; |
||
161 | } |
||
162 | |||
163 | // TODO: Возможно, исправлено |
||
164 | if ($auth === false && isset($answer[0])) { |
||
165 | /** |
||
166 | * Костыль для Новой Почты. |
||
167 | * Спасибо Вам большое, что нормально не выдаете ответ :). |
||
168 | */ |
||
169 | $answer = $answer[0]; |
||
170 | } |
||
171 | |||
172 | if (isset($answer['success'])) { |
||
173 | $this->return['success'] = $answer['success']; |
||
174 | } |
||
175 | |||
176 | if (isset($answer['data'])) { |
||
177 | $this->return['result'] = $answer['data']; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * Формирование info. |
||
182 | */ |
||
183 | $this->return['info'] = $this->addInfo($answer); |
||
184 | |||
185 | return $this->return; |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Формирование информации. |
||
190 | * Ошибки, уведомления. |
||
191 | * |
||
192 | * @param mixed $answer Ответ от НП |
||
193 | */ |
||
194 | public function addInfo($answer): array |
||
195 | { |
||
196 | $info = []; |
||
197 | |||
198 | if (isset($answer['warnings']) && $answer['warnings']) { |
||
199 | $info['warnings'] = $answer['warnings']; |
||
200 | } |
||
201 | |||
202 | if (isset($answer['infoCodes']) && $answer['infoCodes']) { |
||
203 | $info['infoCodes'] = $answer['infoCodes']; |
||
204 | |||
205 | foreach ($answer['infoCodes'] as $err) { |
||
206 | $info['infoCodes'] = $err; |
||
207 | } |
||
208 | if (isset($answer['infoCodes'][0])) { |
||
209 | $info['StatusLocale'] = __('novaposhta::novaposhta.statusCode.'.$answer['infoCodes'][0]); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | if (isset($answer['errors']) && $answer['errors']) { |
||
214 | $info['errors'] = $answer['errors']; |
||
215 | if ($answer['errorCodes']) { |
||
216 | foreach ($answer['errorCodes'] as $err) { |
||
217 | $info['StatusCode'] = $err; |
||
218 | } |
||
219 | if (isset($answer['errorCodes'][0])) { |
||
220 | $info['StatusLocale'] = __('novaposhta::novaposhta.statusCode.'.$answer['errorCodes'][0]); |
||
221 | } |
||
222 | } |
||
223 | } |
||
224 | |||
225 | if (isset($answer['info']) && $answer['info']) { |
||
226 | $info['info'] = $answer['info']; |
||
227 | } |
||
228 | |||
229 | return $info; |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Логирование запроса. |
||
234 | * |
||
235 | * @param bool $auth Аутентификация |
||
236 | * @return void |
||
237 | */ |
||
238 | public function development(bool $auth): void |
||
239 | { |
||
240 | Log::debug('= = = = = = = = = = = = = = = = = = = ='); |
||
241 | Log::debug($this->model.' / '.$this->calledMethod.' // apiKey: '.(int) $auth); |
||
242 | Log::debug('--------------------'); |
||
243 | |||
244 | if (! empty($this->methodProperties)) { |
||
245 | try { |
||
246 | Log::notice(json_encode($this->methodProperties)); |
||
247 | } catch (Exception $e) { |
||
248 | Log::notice('method json_encode error'); |
||
249 | } |
||
250 | } |
||
251 | } |
||
252 | } |
||
253 |