Passed
Branch master (641bc5)
by Vinicius Morais
01:58
created

Api::executeCurl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace vinicinbgs\Autentique\Utils;
4
5
use CURLFile;
6
use CurlHandle;
7
use Exception;
8
9
use vinicinbgs\Autentique\exceptions\EmptyTokenException;
10
use vinicinbgs\Autentique\exceptions\EmptyQueryException;
11
use vinicinbgs\Autentique\exceptions\ContentTypeException;
12
use vinicinbgs\Autentique\exceptions\EmptyAutentiqueResponseException;
13
use vinicinbgs\Autentique\exceptions\EmptyAutentiqueUrlException;
14
use vinicinbgs\Autentique\exceptions\InvalidAutentiqueUrlException;
15
16
class Api
17
{
18
    const ACCEPT_CONTENTS = ["json", "form"];
19
20
    private $url;
21
22
    public function __construct(string $url)
23
    {
24
        $this->url = $this->setUrl($url);
25
    }
26
27
    /**
28
     * @param string $token
29
     * @param string $query
30
     * @param string $contentType json|form
31
     * @param string|null $pathFile
32
     * @return array
33
     */
34
    public function request(
35
        string $token,
36
        string $query,
37
        string $contentType,
38
        string $pathFile = null
39
    ): array {
40
        if (empty($token)) {
41
            throw new EmptyTokenException();
42
        }
43
44
        $this->validateParams($contentType, $query);
45
46
        $httpHeader = ["Authorization: Bearer {$token}"];
47
48
        $fields = '{"query":' . $query . "}";
49
50
        if ($contentType == "json") {
51
            $contentType = $this->requestJson();
52
        } else {
53
            $contentType = $this->requestFormData();
54
            $fields = [
55
                "operations" => $fields,
56
                "map" => '{"file": ["variables.file"]}',
57
                "file" => new CURLFile($pathFile),
58
            ];
59
        }
60
61
        array_push($httpHeader, $contentType);
62
63
        return $this->connect($httpHeader, $fields);
64
    }
65
66
    /**
67
     * @param array $httpHeader
68
     * @param string|array $fields
69
     * @return array $response
70
     */
71
    private function connect(array $httpHeader, $fields): array
72
    {
73
        $curl = curl_init();
74
75
        curl_setopt_array(
76
            /** @scrutinizer ignore-type */
77
            $curl,
78
            [
79
                CURLOPT_URL => $this->url,
80
                CURLOPT_RETURNTRANSFER => true,
81
                CURLOPT_ENCODING => "",
82
                CURLOPT_MAXREDIRS => 10,
83
                CURLOPT_TIMEOUT => 60,
84
                CURLOPT_FOLLOWLOCATION => true,
85
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
86
                CURLOPT_CUSTOMREQUEST => "POST",
87
                CURLOPT_POSTFIELDS => $fields,
88
                CURLOPT_HTTPHEADER => $httpHeader,
89
                CURLOPT_CAINFO => __DIR__ . "/../../ssl/ca-bundle.crt",
90
            ]
91
        );
92
93
        $response = $this->executeCurl($curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type resource; however, parameter $curl of vinicinbgs\Autentique\Utils\Api::executeCurl() does only seem to accept CurlHandle, 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

93
        $response = $this->executeCurl(/** @scrutinizer ignore-type */ $curl);
Loading history...
94
95
        $errorNo = $this->getErrorNo($curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type resource; however, parameter $curl of vinicinbgs\Autentique\Utils\Api::getErrorNo() does only seem to accept CurlHandle, 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

95
        $errorNo = $this->getErrorNo(/** @scrutinizer ignore-type */ $curl);
Loading history...
96
97
        if ($response == "[]") {
98
            throw new EmptyAutentiqueResponseException();
99
        }
100
101
        if ($errorNo) {
102
            throw new Exception(curl_error($curl));
103
        }
104
105
        curl_close(
106
            /** @scrutinizer ignore-type */
107
            $curl
108
        );
109
110
        return json_decode($response, true);
111
    }
112
113
    private function setUrl(string $url): string
114
    {
115
        if (empty($url)) {
116
            throw new EmptyAutentiqueUrlException();
117
        }
118
119
        return $url;
120
    }
121
122
    private function validateParams(string $contentType, string $query): void
123
    {
124
        if (!in_array($contentType, self::ACCEPT_CONTENTS)) {
125
            throw new ContentTypeException();
126
        }
127
128
        if (empty($query)) {
129
            throw new EmptyQueryException();
130
        }
131
132
        if (!filter_var($this->url, FILTER_VALIDATE_URL)) {
133
            throw new InvalidAutentiqueUrlException();
134
        }
135
    }
136
137
    private function requestJson(): string
138
    {
139
        return "Content-Type: application/json";
140
    }
141
142
    private function requestFormData(): string
143
    {
144
        return "Content-Type: multipart/form-data";
145
    }
146
147
    public function getErrorNo(CurlHandle $curl): int
148
    {
149
        return curl_errno(
150
            /** @scrutinizer ignore-type */
151
            $curl
152
        );
153
    }
154
155
    public function executeCurl(CurlHandle $curl): string
156
    {
157
        return curl_exec(
0 ignored issues
show
Bug Best Practice introduced by
The expression return curl_exec($curl) could return the type true which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
158
            /** @scrutinizer ignore-type */
159
            $curl
160
        );
161
    }
162
}
163