Issues (3)

src/utils/Api.php (1 issue)

1
<?php
2
3
namespace vinicinbgs\Autentique\Utils;
4
5
use CURLFile;
6
use Exception;
7
use vinicinbgs\Autentique\exceptions\ContentTypeException;
8
use vinicinbgs\Autentique\exceptions\EmptyAutentiqueResponseException;
9
use vinicinbgs\Autentique\exceptions\EmptyAutentiqueUrlException;
10
use vinicinbgs\Autentique\exceptions\EmptyQueryException;
11
use vinicinbgs\Autentique\exceptions\EmptyTokenException;
12
use vinicinbgs\Autentique\exceptions\InvalidAutentiqueUrlException;
13
14
class Api
15
{
16
    const ACCEPT_CONTENTS = ["json", "form"];
17
18
    private $url;
19
20
    private $timeout = 60;
21
22
    /**
23
     * @param string $url Autentique API URL
24
     * @param int $timeout=60 seconds to timeout request
25
     */
26
    public function __construct(string $url, int $timeout = 60)
27
    {
28
        $this->url     = $this->setUrl($url);
29
        $this->timeout = $timeout;
30
    }
31
32
    /**
33
     * @param string $token
34
     * @param string $query
35
     * @param string $contentType json|form
36
     * @param string|null $pathFile
37
     * @return array
38
     */
39
    public function request(
40
        string $token,
41
        string $query,
42
        string $contentType,
43
        string $pathFile = null
44
    ): array {
45
        if (empty($token)) {
46
            throw new EmptyTokenException();
47
        }
48
49
        $this->validateParams($contentType, $query);
50
51
        $httpHeader = ["Authorization: Bearer {$token}"];
52
53
        $fields = '{"query":' . $query . "}";
54
55
        if ($contentType == "json") {
56
            $contentType = $this->requestJson();
57
        } else {
58
            $contentType = $this->requestFormData();
59
            $fields      = [
60
                "operations" => $fields,
61
                "map"        => '{"file": ["variables.file"]}',
62
                "file"       => new CURLFile($pathFile),
63
            ];
64
        }
65
66
        array_push($httpHeader, $contentType);
67
68
        return $this->connect($httpHeader, $fields);
69
    }
70
71
    /**
72
     * @param array $httpHeader
73
     * @param string|array $fields
74
     * @return array $response
75
     */
76
    private function connect(array $httpHeader, $fields): array
77
    {
78
        $curl = curl_init();
79
80
        curl_setopt_array(
81
            /** @scrutinizer ignore-type */
82
            $curl,
83
            [
84
                CURLOPT_URL            => $this->url,
85
                CURLOPT_RETURNTRANSFER => true,
86
                CURLOPT_ENCODING       => "",
87
                CURLOPT_MAXREDIRS      => 10,
88
                CURLOPT_CONNECTTIMEOUT => $this->timeout,
89
                CURLOPT_TIMEOUT        => $this->timeout,
90
                CURLOPT_FOLLOWLOCATION => true,
91
                CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
92
                CURLOPT_CUSTOMREQUEST  => "POST",
93
                CURLOPT_POSTFIELDS     => $fields,
94
                CURLOPT_HTTPHEADER     => $httpHeader,
95
                CURLOPT_CAINFO         => __DIR__ . "/../../ssl/ca-bundle.crt",
96
            ]
97
        );
98
99
        $response = $this->executeCurl($curl);
100
101
        $errorNo = $this->getErrorNo($curl);
102
103
        if ($response == "[]") {
104
            throw new EmptyAutentiqueResponseException();
105
        }
106
107
        if ($errorNo) {
108
            throw new Exception(curl_error($curl));
109
        }
110
111
        curl_close(
112
            /** @scrutinizer ignore-type */
113
            $curl
114
        );
115
116
        return json_decode($response, true);
117
    }
118
119
    private function setUrl(string $url): string
120
    {
121
        if (empty($url)) {
122
            throw new EmptyAutentiqueUrlException();
123
        }
124
125
        return $url;
126
    }
127
128
    private function validateParams(string $contentType, string $query): void
129
    {
130
        if (!in_array($contentType, self::ACCEPT_CONTENTS)) {
131
            throw new ContentTypeException();
132
        }
133
134
        if (empty($query)) {
135
            throw new EmptyQueryException();
136
        }
137
138
        if (!filter_var($this->url, FILTER_VALIDATE_URL)) {
139
            throw new InvalidAutentiqueUrlException();
140
        }
141
    }
142
143
    private function requestJson(): string
144
    {
145
        return "Content-Type: application/json";
146
    }
147
148
    private function requestFormData(): string
149
    {
150
        return "Content-Type: multipart/form-data";
151
    }
152
153
    public function getErrorNo($curl): int
154
    {
155
        return curl_errno(
156
            /** @scrutinizer ignore-type */
157
            $curl
158
        );
159
    }
160
161
    public function executeCurl($curl): string
162
    {
163
        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...
164
            /** @scrutinizer ignore-type */
165
            $curl
166
        );
167
    }
168
169
    /**
170
     * Get the value of url
171
     * @return string
172
     *
173
     * @codeCoverageIgnore
174
     */
175
    public function getUrl(): string
176
    {
177
        return $this->url;
178
    }
179
}
180