Passed
Push — master ( a99763...fbfe14 )
by Andrey
03:27
created

NovaPoshta::addInfo()   C

Complexity

Conditions 14
Paths 48

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 14
eloc 19
nc 48
nop 1
dl 0
loc 36
rs 6.2666
c 2
b 1
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
65
     */
66
    public function getData(bool $auth = true)
67
    {
68
69
        $url = $this->url.'/'.$this->model.'/'.$this->calledMethod;
70
71
        $body = [];
72
        $body['modelName'] = $this->model;
73
        $body['calledMethod'] = $this->calledMethod;
74
        $body['methodProperties'] = $this->methodProperties;
75
76
        if ($auth) {
77
            $body['apiKey'] = $this->api;
78
        }
79
80
        if ($this->dev) {
81
            $this->development($auth);
82
        }
83
84
        try {
85
            $response = Http::timeout(config('novaposhta.http_response_timeout', 3))
86
                ->retry(
87
                    config('novaposhta.http_retry_max_time', 2),
88
                    config('novaposhta.http_retry_delay', 500)
89
                )
90
                ->withHeaders([
91
                    'Accept' => 'application/json',
92
                    'Content-Type' => 'application/json',
93
                ])
94
                ->post($url, $body);
95
        } catch (Exception $e) {
96
            if ($e->getCode() == 401) {
97
                // Ошибка API ключа
98
                $response = __('novaposhta::novaposhta.statusCode.20000200068');
99
            } else {
100
                $response = $e->getMessage();
101
            }
102
        }
103
104
        return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response also could return the type array which is incompatible with the documented return type Illuminate\Http\Client\Response|string.
Loading history...
105
    }
106
107
108
109
    /**
110
     * @param  string  $model  Модель Новой Почты
111
     * @param  string  $calledMethod  Метод модели
112
     * @param  array|null  $methodProperties  Тело запроса
113
     * @param  bool  $auth  Использовать ли аутентификацию токеном или нет
114
     * @return array
115
     */
116
    public function getResponse(
117
        string $model,
118
        string $calledMethod,
119
        ?array $methodProperties,
120
        bool $auth = true
121
    ): array
122
    {
123
124
        $this->model = $model;
125
        $this->calledMethod = $calledMethod;
126
        $this->methodProperties = $methodProperties;
127
128
        $response = $this->getData($auth);
129
130
        // Ошибка курла
131
        if (!($response instanceof ClientResponse)) {
0 ignored issues
show
introduced by
$response is always a sub-type of Illuminate\Http\Client\Response.
Loading history...
132
            $this->return['info']['error'] = $response;
133
            $this->return['info']['StatusCode'] = '20000100016'; // Сервис не доступен
134
            $this->return['info']['StatusLocale'] = __('novaposhta::novaposhta.error_data');
135
136
            return $this->return;
137
        }
138
139
        // Ошибка запроса или 401
140
        if ($response->failed()) {
141
            $this->return['info']['error'] = trans('novaposhta::novaposhta.error_data');
142
143
            return $this->return;
144
        }
145
146
        // если что-то не JSON (типа application/pdf)
147
        if ($response->header('Content-Type') !== 'application/json') {
148
            $this->return['success'] = $response->ok();
149
150
            $this->return['info']['file'] = true;
151
            $this->return['info']['ContentType'] = $response->header('Content-Type');
152
            $this->return['info']['ContentDisposition'] = $response->header('Content-Disposition') ?? '';
153
154
            $this->return['result'] = $response->body();
155
156
            return $this->return;
157
        }
158
159
        $answer = $response->json();
160
161
        /**
162
         * Development.
163
         */
164
        if ($this->dev) {
165
            $this->return['dev'] = $answer;
166
        }
167
168
        // TODO: Возможно, исправлено
169
        if ($auth === false && isset($answer[0])) {
170
            /**
171
             * Костыль для Новой Почты.
172
             * Спасибо Вам большое, что нормально не выдаете ответ :).
173
             */
174
            $answer = $answer[0];
175
        }
176
177
        if (isset($answer['success'])) {
178
            $this->return['success'] = $answer['success'];
179
        }
180
181
        if (isset($answer['data'])) {
182
            $this->return['result'] = $answer['data'];
183
        }
184
185
        /**
186
         * Формирование info.
187
         */
188
        $this->return['info'] = $this->addInfo($answer);
189
190
        return $this->return;
191
    }
192
193
    /**
194
     * Формирование информации.
195
     * Ошибки, уведомления.
196
     *
197
     * @param  mixed  $answer  Ответ от НП
198
     */
199
    public function addInfo($answer): array
200
    {
201
        $info = [];
202
203
        if (isset($answer['warnings']) && $answer['warnings']) {
204
            $info['warnings'] = $answer['warnings'];
205
        }
206
207
        if (isset($answer['infoCodes']) && $answer['infoCodes']) {
208
            $info['infoCodes'] = $answer['infoCodes'];
209
210
            foreach ($answer['infoCodes'] as $err) {
211
                $info['infoCodes'] = $err;
212
            }
213
            if (isset($answer['infoCodes'][0])) {
214
                $info['StatusLocale'] = __('novaposhta::novaposhta.statusCode.'.$answer['infoCodes'][0]);
215
            }
216
        }
217
218
        if (isset($answer['errors']) && $answer['errors']) {
219
            $info['errors'] = $answer['errors'];
220
            if ($answer['errorCodes']) {
221
                foreach ($answer['errorCodes'] as $err) {
222
                    $info['StatusCode'] = $err;
223
                }
224
                if (isset($answer['errorCodes'][0])) {
225
                    $info['StatusLocale'] = __('novaposhta::novaposhta.statusCode.'.$answer['errorCodes'][0]);
226
                }
227
            }
228
        }
229
230
        if (isset($answer['info']) && $answer['info']) {
231
            $info['info'] = $answer['info'];
232
        }
233
234
        return $info;
235
    }
236
237
    /**
238
     * Логирование запроса.
239
     *
240
     * @param  bool  $auth  Аутентификация
241
     * @return void
242
     */
243
    public function development(bool $auth): void {
244
        Log::debug('= = = = = = = = = = = = = = = = = = = =');
245
        Log::debug($this->model.' / '.$this->calledMethod.' // apiKey: '.(int) $auth);
246
        Log::debug('--------------------');
247
248
        if (! empty($this->methodProperties)) {
249
            try {
250
                Log::notice(json_encode($this->methodProperties));
251
            } catch (Exception $e) {
252
                Log::notice('method json_encode error');
253
            }
254
        }
255
    }
256
}
257