Passed
Push — main ( dd7998...bae415 )
by Dylan
03:01
created

Curl::setURL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Lifeboat\Utils;
4
5
use Lifeboat\CurlResponse;
6
use Lifeboat\Exceptions\InvalidArgumentException;
7
use Lifeboat\Utils\URL;
8
use LogicException;
9
10
/**
11
 * Class Curl
12
 * @package Lifeboat
13
 */
14
class Curl {
15
16
    const ALLOWED_METHODS   = ['GET', 'POST', 'DELETE', 'PUT'];
17
    const USER_AGENT        = 'LifeboatSDK/curl-service';
18
19
    private static $_cache = [];
20
21
    private $_method    = 'GET';
22
    private $_url       = '';
23
    private $_data      = [];
24
    private $_isfile    = false;
25
    private $_headers   = [
26
        'Content-Type'      => 'application/x-www-form-urlencoded',
27
        'X-Requested-By'    => self::USER_AGENT
28
    ];
29
    private $_enable_cache = false;
30
31
    /**
32
     * Curl constructor.
33
     *
34
     * @param string $url
35
     * @param array $data
36
     * @param array $headers
37
     *
38
     * @throws LogicException
39
     */
40
    public function __construct(string $url = null, array $data = [], array $headers = [])
41
    {
42
        if (!is_null($url)) $this->setURL($url);
43
        foreach ($data as $name => $value)      $this->addDataParam($name, $value);
44
        foreach ($headers as $name => $value)   $this->addHeader($name, $value);
45
    }
46
47
    /**
48
     * @param string $url
49
     * @return Curl
50
     */
51
    public function setURL(string $url): Curl
52
    {
53
        $this->_url = $url;
54
        return $this;
55
    }
56
57
    /**
58
     * @return string
59
     */
60
    public function getURL(): string
61
    {
62
        return $this->_url;
63
    }
64
65
    /**
66
     * @param string $method
67
     * @return $this
68
     * @throws InvalidArgumentException If $method specified is invalid
69
     */
70
    public function setMethod(string $method = 'GET'): Curl
71
    {
72
        if (!in_array($method, self::ALLOWED_METHODS)) {
73
            throw new InvalidArgumentException("HTTP Method '{$method}' is not allowed");
74
        }
75
76
        $this->_method = $method;
77
        return $this;
78
    }
79
80
    /**
81
     * @return string
82
     */
83
    public function getMethod(): string
84
    {
85
        return $this->_method;
86
    }
87
88
    /**
89
     * @param string $name
90
     * @param mixed $value
91
     * @return $this
92
     */
93
    public function addDataParam(string $name, $value): Curl
94
    {
95
        $this->_data[$name] = $value;
96
        return $this;
97
    }
98
99
    public function removeDataParam(string $name): Curl
100
    {
101
        if (array_key_exists($name, $this->_data)) unset($this->_data[$name]);
102
        return $this;
103
    }
104
105
    /**
106
     * @return array
107
     */
108
    public function getDataParams(): array
109
    {
110
        return $this->_data;
111
    }
112
113
    /**
114
     * @param string $name
115
     * @param string $value
116
     * @return Curl
117
     */
118
    public function addHeader(string $name, string $value): Curl
119
    {
120
        $this->_headers[$name] = $value;
121
        return $this;
122
    }
123
124
    /**
125
     * @param string $name
126
     * @return Curl
127
     */
128
    public function removeHeader(string $name): Curl
129
    {
130
        if (array_key_exists($name, $this->_headers)) unset($this->_headers[$name]);
131
        return $this;
132
    }
133
134
    /**
135
     * @return array
136
     */
137
    public function getHeaders(): array
138
    {
139
        return $this->_headers;
140
    }
141
142
    public function setIsFileUpload(bool $is_file): Curl
143
    {
144
        $this->addHeader('Content-Type', 'multipart/form-data');
145
        $this->_isfile = $is_file;
146
        return $this;
147
    }
148
149
    public function isFileUpload(): bool
150
    {
151
        return $this->_isfile;
152
    }
153
154
    /**
155
     * @param bool $switch
156
     * @return $this
157
     */
158
    public function cacheRequests(bool $switch): Curl
159
    {
160
        $this->_enable_cache = $switch;
161
        return $this;
162
    }
163
164
    /**
165
     * @return CurlResponse
166
     */
167
    public function curl(): CurlResponse
168
    {
169
        $post_data      = null;
170
        $send_headers   = [];
171
        $request_uri    = $this->getURL();
172
173
        //  Headers
174
        foreach ($this->getHeaders() as $k => $v) $send_headers[] = "{$k}: {$v}";
175
176
        // Request Data
177
        switch ($this->getMethod()) {
178
            case 'GET':
179
            case 'DELETE':
180
                foreach ($this->getDataParams() as $name => $value) $request_uri = URL::setGetVar($name, $value, $request_uri);
181
                break;
182
183
            case 'POST':
184
                $post_data = ($this->isFileUpload()) ? $this->getDataParams() : http_build_query($this->getDataParams());
185
                break;
186
            case 'PUT':
187
                $post_data = http_build_query($this->getDataParams());
188
                break;
189
        }
190
191
        if ($this->_enable_cache && $this->getMethod() === 'GET') {
192
            $cache_key = urlencode($request_uri) . implode(',', $send_headers);
193
            if (array_key_exists($cache_key, self::$_cache)) {
194
                return self::$_cache[$cache_key];
195
            }
196
        }
197
198
        $ch = curl_init();
199
        curl_setopt($ch, CURLOPT_URL, $request_uri);
200
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
201
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->getMethod());
202
        curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT);
203
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
204
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
205
        curl_setopt($ch, CURLOPT_ENCODING, '');
206
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
207
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
208
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
209
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
210
211
        if (!empty($send_headers))  curl_setopt($ch, CURLOPT_HTTPHEADER, $send_headers);
212
        if (!is_null($post_data))   {
213
            curl_setopt($ch, CURLOPT_POST, 1);
214
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
215
        }
216
217
        $result     = curl_exec($ch);
218
        $http_code  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
219
220
        $response = new CurlResponse($http_code, $result);
221
        if ($this->_enable_cache && isset($cache_key)) self::$_cache[$cache_key] = $response;
222
223
        return $response;
224
    }
225
226
    /**
227
     * @see Curl::curl()
228
     *
229
     * @return CurlResponse
230
     */
231
    public function curl_json(): CurlResponse
232
    {
233
        $this->addHeader('Accept', 'application/json');
234
        return $this->curl();
235
    }
236
}
237