Passed
Push — master ( be88e3...87c6b6 )
by Fran
04:17
created

Service::setIsJson()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
namespace PSFS\base;
3
4
use PSFS\base\config\Config;
5
use PSFS\base\types\helpers\SecurityHelper;
6
use PSFS\base\types\helpers\ServiceHelper;
7
8
/**
9
 * Class Service
10
 * @package PSFS\base
11
 */
12
class Service extends Singleton
13
{
14
    const CTYPE_JSON = 'application/json';
15
    const CTYPE_MULTIPART = 'multipart/form-data';
16
    const CTYPE_FORM = 'application/x-www-form-urlencoded';
17
    const CTYPE_PLAIN = 'text/plain';
18
    const PSFS_TRACK_HEADER = 'X-PSFS-UID';
19
20
    /**
21
     * @var String Url de destino de la llamada
22
     */
23
    private $url;
24
    /**
25
     * @var array Parámetros de la llamada
26
     */
27
    private $params;
28
    /**
29
     * @var array Opciones llamada
30
     */
31
    private $options;
32
    /**
33
     * @var array Cabeceras de la llamada
34
     */
35
    private $headers;
36
    /**
37
     * @var string type
38
     */
39
    private $type;
40
    /**
41
     * @var resource $con
42
     */
43
    private $con;
44
    /**
45
     * @var string $result
46
     */
47
    private $result;
48
    /**
49
     * @var mixed
50
     */
51
    private $info = [];
52
53
    /**
54
     * @Injectable
55
     * @var \PSFS\base\Logger Log de las llamadas
56
     */
57
    protected $log;
58
    /**
59
     * @Injectable
60
     * @var \PSFS\base\Cache $cache
61
     */
62
    protected $cache;
63
    /**
64
     * @var bool
65
     */
66
    protected $isJson = true;
67
    /**
68
     * @var bool
69
     */
70
    protected $isMultipart = false;
71
72 1
    private function closeConnection() {
73 1
        if(null !== $this->con) {
74
            curl_close($this->con);
75
        }
76 1
    }
77
78
    public function __destruct()
79
    {
80
        $this->closeConnection();
81
    }
82
83
    /**
84
     * @return String
85
     */
86
    public function getUrl()
87
    {
88
        return $this->url;
89
    }
90
91
    /**
92
     * @param String $url
93
     */
94
    public function setUrl($url)
95
    {
96
        $this->url = $url;
97
        $this->initialize();
98
    }
99
100
    /**
101
     * @return string
102
     */
103
    public function getResult()
104
    {
105
        return $this->result;
106
    }
107
108
    /**
109
     * @param string $result
110
     */
111
    public function setResult($result)
112
    {
113
        $this->result = $result;
114
    }
115
116
    /**
117
     * @return array
118
     */
119
    public function getParams()
120
    {
121
        return $this->params;
122
    }
123
124
    /**
125
     * Add request param
126
     *
127
     * @param $key
128
     * @param null $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
129
     *
130
     * @return \PSFS\base\Service
131
     */
132
    public function addParam($key, $value = NULL)
133
    {
134
        $this->params[$key] = $value;
135
136
        return $this;
137
    }
138
139
    /**
140
     * @return array
141
     */
142
    public function getOptions()
143
    {
144
        return $this->options;
145
    }
146
147
    /**
148
     * Add request param
149
     *
150
     * @param $key
151
     * @param null $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
152
     *
153
     * @return \PSFS\base\Service
154
     */
155
    public function addOption($key, $value = NULL)
156
    {
157
        $this->options[$key] = $value;
158
159
        return $this;
160
    }
161
162
    /**
163
     * @param array $params
164
     */
165
    public function setParams($params)
166
    {
167
        $this->params = $params;
168
    }
169
170
    /**
171
     * @return array
172
     */
173
    public function getHeaders()
174
    {
175
        return $this->headers;
176
    }
177
178
    /**
179
     * @param array $headers
180
     */
181
    public function setHeaders($headers)
182
    {
183
        $this->headers = $headers;
184
    }
185
186
    /**
187
     * @param $header
188
     * @param null $content
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $content is correct as it would always require null to be passed?
Loading history...
189
     *
190
     * @return $this
191
     */
192
    public function addHeader($header, $content = NULL)
193
    {
194
        $this->headers[$header] = $content;
195
196
        return $this;
197
    }
198
199
    /**
200
     * @return string
201
     */
202
    public function getType()
203
    {
204
        return $this->type;
205
    }
206
207
    /**
208
     * @param string $type
209
     */
210
    public function setType($type)
211
    {
212
        $this->type = $type;
213
    }
214
215
    /**
216
     * @return Logger
217
     */
218
    public function getLog()
219
    {
220
        return $this->log;
221
    }
222
223
    /**
224
     * @param Logger $log
225
     */
226 1
    public function setLog($log)
227
    {
228 1
        $this->log = $log;
229 1
    }
230
231
    /**
232
     * @param bool $isJson
233
     */
234
    public function setIsJson($isJson = true) {
235
        $this->isJson = $isJson;
236
        if($isJson) {
237
            $this->setIsMultipart(false);
238
        }
239
    }
240
241
    /**
242
     * @return bool
243
     *
244
     */
245
    public function getIsJson() {
246
        return $this->isJson;
247
    }
248
249
    /**
250
     * @param bool $isMultipart
251
     */
252
    public function setIsMultipart($isMultipart = true) {
253
        $this->isMultipart = $isMultipart;
254
        if($isMultipart) {
255
            $this->setIsJson(false);
256
        }
257
    }
258
259
    /**
260
     * @return bool
261
     */
262
    public function getIsMultipart() {
263
        return $this->isMultipart;
264
    }
265
266
    /**
267
     * Método que limpia el contexto de la llamada
268
     */
269 1
    private function clearContext()
270
    {
271 1
        $this->url = NULL;
272 1
        $this->params = array();
273 1
        $this->headers = array();
274 1
        Logger::log('Context service for ' . static::class . ' cleared!');
275 1
        $this->closeConnection();
276 1
    }
277
278
    /**
279
     *
280
     */
281 1
    public function init()
282
    {
283 1
        parent::init();
284 1
        $this->clearContext();
285 1
    }
286
287
    /**
288
     * Initialize CURL
289
     */
290
    private function initialize()
291
    {
292
        $this->closeConnection();
293
        $this->params = [];
294
        $this->con = curl_init($this->url);
295
    }
296
297
    /**
298
     * Generate auth header
299
     * @param string $secret
300
     * @param string $module
301
     */
302
    protected function addRequestToken($secret, $module = 'PSFS')
303
    {
304
        $this->addHeader('X-PSFS-SEC-TOKEN', SecurityHelper::generateToken($secret, $module));
305
    }
306
307
    /**
308
     * @param $user
309
     * @param $pass
310
     */
311
    protected function addAuthHeader($user, $pass) {
312
        $this->addOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
313
        $this->addOption(CURLOPT_USERPWD, "$user:$pass");
314
    }
315
316
    protected function applyOptions() {
317
        if(count($this->options)) {
318
            curl_setopt_array($this->con, $this->options);
319
        }
320
    }
321
322
    protected function applyHeaders() {
323
        $headers = [];
324
        foreach($this->headers as $key => $value) {
325
            $headers[] = $key . ': ' . $value;
326
        }
327
        $headers[self::PSFS_TRACK_HEADER] = Logger::getUid();
328
        if(count($headers)) {
329
            curl_setopt($this->con, CURLOPT_HTTPHEADER, $headers);
330
        }
331
    }
332
333
    /**
334
     * @return int
335
     */
336
    private function parseServiceType() {
337
        if($this->getIsJson()) {
338
            return ServiceHelper::TYPE_JSON;
339
        }
340
        if($this->getIsMultipart()) {
341
            return ServiceHelper::TYPE_MULTIPART;
342
        }
343
        return ServiceHelper::TYPE_HTTP;
344
    }
345
346
    protected function setDefaults()
347
    {
348
        $serviceType = $this->parseServiceType();
349
        switch (strtoupper($this->type)) {
350
            case Request::VERB_GET:
351
            default:
352
                $this->addOption(CURLOPT_CUSTOMREQUEST, Request::VERB_GET);
353
                if(!empty($this->params)) {
354
                    $sep = false !== strpos($this->getUrl(), '?') ? '?' : '';
355
                    $this->url = $this->url . $sep . http_build_query($this->params);
356
                }
357
                break;
358
            case Request::VERB_POST:
359
                $this->addOption(CURLOPT_CUSTOMREQUEST, Request::VERB_POST);
360
                $this->addOption(CURLOPT_POSTFIELDS, ServiceHelper::parseRawData($serviceType, $this->getParams()));
361
                break;
362
            case Request::VERB_DELETE:
363
                $this->addOption(CURLOPT_CUSTOMREQUEST, Request::VERB_DELETE);
364
                break;
365
            case Request::VERB_PUT:
366
                $this->addOption(CURLOPT_CUSTOMREQUEST, Request::VERB_PUT);
367
                $this->addOption(CURLOPT_POSTFIELDS, ServiceHelper::parseRawData($serviceType, $this->getParams()));
368
                break;
369
            case Request::VERB_PATCH:
370
                $this->addOption(CURLOPT_CUSTOMREQUEST, Request::VERB_PATCH);
371
                $this->addOption(CURLOPT_POSTFIELDS, ServiceHelper::parseRawData($serviceType, $this->getParams()));
372
                break;
373
        }
374
375
        $this->addOption(CURLOPT_RETURNTRANSFER, true);
376
        $this->addOption(CURLOPT_FOLLOWLOCATION, true);
377
        $this->addOption(CURLOPT_SSL_VERIFYHOST, false);
378
        $this->addOption(CURLOPT_SSL_VERIFYPEER, false);
379
    }
380
381
    public function callSrv()
382
    {
383
        $this->setDefaults();
384
        $this->applyOptions();
385
        $this->applyHeaders();
386
        $verbose = null;
387
        if('debug' === Config::getParam('log.level')) {
388
            curl_setopt($this->con, CURLOPT_VERBOSE, true);
389
            $verbose = fopen('php://temp', 'wb+');
390
            curl_setopt($this->con, CURLOPT_STDERR, $verbose);
391
        }
392
        $result = curl_exec($this->con);
393
        $this->result = $this->isJson ? json_decode($result, true) : $result;
394
        if('debug' === Config::getParam('log.level')) {
395
            rewind($verbose);
0 ignored issues
show
Bug introduced by
It seems like $verbose can also be of type false; however, parameter $handle of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

395
            rewind(/** @scrutinizer ignore-type */ $verbose);
Loading history...
396
            $verboseLog = stream_get_contents($verbose);
0 ignored issues
show
Bug introduced by
It seems like $verbose can also be of type false; however, parameter $handle of stream_get_contents() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

396
            $verboseLog = stream_get_contents(/** @scrutinizer ignore-type */ $verbose);
Loading history...
397
            Logger::log($verboseLog, LOG_DEBUG, [
398
                'headers' => $this->getHeaders(),
399
                'options' => $this->getOptions(),
400
                'url' => $this->getUrl(),
401
            ]);
402
            $this->info['verbose'] = $verboseLog;
403
        }
404
        Logger::log($this->url . ' response: ', LOG_DEBUG, is_array($this->result) ? $this->result : [$this->result]);
405
        $this->info = array_merge($this->info, curl_getinfo($this->con));
406
    }
407
408
    /**
409
     * @return mixed
410
     */
411
    public function getCallInfo() {
412
        return $this->info;
413
    }
414
415
}
416