Curl::make()   B
last analyzed

Complexity

Conditions 6
Paths 12

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 8.439
c 0
b 0
f 0
cc 6
eloc 19
nc 12
nop 4
1
<?php
2
/**
3
 * This file is part of the jyggen/curl library
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright Copyright (c) Jonas Stendahl <[email protected]>
9
 * @license http://opensource.org/licenses/MIT MIT
10
 * @link https://jyggen.com/projects/jyggen-curl Documentation
11
 * @link https://packagist.org/packages/jyggen/curl Packagist
12
 * @link https://github.com/jyggen/curl GitHub
13
 */
14
15
namespace Jyggen\Curl;
16
17
use Jyggen\Curl\Dispatcher;
18
use Jyggen\Curl\DispatcherInterface;
19
use Jyggen\Curl\Exception\InvalidArgumentException;
20
use Jyggen\Curl\Request;
21
use Jyggen\Curl\RequestInterface;
22
23
/**
24
 * Provides static helpers for simplified cURL usage.
25
 */
26
class Curl
27
{
28
    /**
29
     * The data to send with each request.
30
     *
31
     * @var array
32
     */
33
    protected $data;
34
35
    /**
36
     * The request dispatcher to use.
37
     *
38
     * @var DispatcherInterface
39
     */
40
    protected $dispatcher;
41
42
    /**
43
     * Which HTTP verb to use.
44
     *
45
     * @var string
46
     */
47
    protected $verb;
48
49
    /**
50
     * The requests that should be sent.
51
     *
52
     * @var array
53
     */
54
    protected $requests;
55
56
    /**
57
     * Make one or multiple DELETE requests.
58
     *
59
     * @param mixed $urls
60
     * @param mixed $data
61
     * @param callable $callback
62
     * @return array
63
     */
64
    public static function delete($urls, $data = null, callable $callback = null)
65
    {
66
        return static::make('delete', $urls, $data, $callback);
67
    }
68
69
    /**
70
     * Make one or multiple GET requests.
71
     *
72
     * @param mixed $urls
73
     * @param mixed $data
74
     * @param callable $callback
75
     * @return array
76
     */
77
    public static function get($urls, $data = null, callable $callback = null)
78
    {
79
        return static::make('get', $urls, $data, $callback);
80
    }
81
82
    /**
83
     * Make one or multiple POST requests.
84
     *
85
     * @param mixed $urls
86
     * @param mixed $data
87
     * @param callable $callback
88
     * @return array
89
     */
90
    public static function post($urls, $data = null, callable $callback = null)
91
    {
92
        return static::make('post', $urls, $data, $callback);
93
    }
94
95
    /**
96
     * Make one or multiple PUT requests.
97
     *
98
     * @param mixed $urls
99
     * @param mixed $data
100
     * @param callable $callback
101
     * @return array
102
     */
103
    public static function put($urls, $data = null, callable $callback = null)
104
    {
105
        return static::make('put', $urls, $data, $callback);
106
    }
107
108
    /**
109
     * Make one or multiple requests.
110
     *
111
     * @param string $verb
112
     * @param mixed $urls
113
     * @param mixed $data
114
     * @param callable $callback
115
     * @return array
116
     */
117
    protected static function make($verb, $urls, $data, callable $callback = null)
118
    {
119
        if (!is_array($urls)) {
120
            $urls = [$urls => $data];
121
        } elseif (!(bool)count(array_filter(array_keys($urls), 'is_string'))) {
122
            foreach ($urls as $key => $url) {
123
                $urls[$url] = null;
124
                unset($urls[$key]);
125
            }
126
        }
127
128
        $dispatcher = new Dispatcher;
129
        $requests   = [];
130
        $dataStore  = [];
131
132
        foreach ($urls as $url => $data) {
133
            $requests[]  = new Request($url);
134
            $dataStore[] = $data;
135
        }
136
137
        new static($verb, $dispatcher, $requests, $dataStore, $callback);
138
139
        $requests  = $dispatcher->all();
140
        $responses = [];
141
142
        foreach ($requests as $request) {
143
            $responses[] = $request->getResponse();
144
        }
145
146
        return $responses;
147
    }
148
149
    /**
150
     * Constructs a `Curl` instance.
151
     *
152
     * @param string $verb
153
     * @param DispatcherInterface $dispatcher
154
     * @param array $requests
155
     * @param array $data
156
     * @param callable $callback
157
     */
158
    protected function __construct(
159
        $verb,
160
        DispatcherInterface $dispatcher,
161
        array $requests,
162
        array $data,
163
        callable $callback = null
164
    ) {
165
        $this->dispatcher = $dispatcher;
166
        $this->verb       = strtoupper($verb);
167
168
        foreach ($requests as $key => $request) {
169
            $this->requests[] = $request;
170
            $this->data[$key] = $data[$key];
171
        }
172
173
        $this->makeRequest($callback);
174
    }
175
176
    /**
177
     * Prepares and sends HTTP requests.
178
     *
179
     * @param callable $callback
180
     */
181
    protected function makeRequest(callable $callback = null)
182
    {
183
        // Foreach request:
184
        foreach ($this->requests as $key => $request) {
185
            $data = (isset($this->data[$key]) and $this->data[$key] !== null) ? $this->data[$key] : null;
186
187
            // Follow any 3xx HTTP status code.
188
            $request->setOption(CURLOPT_FOLLOWLOCATION, true);
189
190
            switch ($this->verb) {
191
                case 'DELETE':
192
                    $this->prepareDeleteRequest($request);
193
                    break;
194
                case 'GET':
195
                    $this->prepareGetRequest($request);
196
                    break;
197
                case 'POST':
198
                    $this->preparePostRequest($request, $data);
199
                    break;
200
                case 'PUT':
201
                    $this->preparePutRequest($request, $data);
202
                    break;
203
            }
204
205
            // Add the request to the dispatcher.
206
            $this->dispatcher->add($request);
207
        }
208
209
        // Execute the request(s).
210
        if ($callback !== null) {
211
            $this->dispatcher->execute($callback);
212
        } else {
213
            $this->dispatcher->execute();
214
        }
215
    }
216
217
    /**
218
     * Sets a request's HTTP verb to DELETE.
219
     *
220
     * @param RequestInterface $request
221
     */
222
    protected function prepareDeleteRequest(RequestInterface $request)
223
    {
224
        $request->setOption(CURLOPT_CUSTOMREQUEST, 'DELETE'); // Set request verb to DELETE.
225
    }
226
227
    /**
228
     * Sets a request's HTTP verb to GET.
229
     *
230
     * @param RequestInterface $request
231
     */
232
    protected function prepareGetRequest(RequestInterface $request)
233
    {
234
        $request->setOption(CURLOPT_HTTPGET, true); // Redundant, but reset the verb to GET.
235
    }
236
237
    /**
238
     * Sets a request's HTTP verb to POST.
239
     *
240
     * @param RequestInterface $request
241
     */
242
    protected function preparePostRequest(RequestInterface $request, $data)
243
    {
244
        if ($data !== null) {
245
            // Add the POST data to the request.
246
            $request->setOption(CURLOPT_POST, true);
247
            $request->setOption(CURLOPT_POSTFIELDS, $data);
248
        } else {
249
            $request->setOption(CURLOPT_CUSTOMREQUEST, 'POST');
250
        }
251
    }
252
253
    /**
254
     * Sets a request's HTTP verb to PUT.
255
     *
256
     * @param RequestInterface $request
257
     */
258
    protected function preparePutRequest(RequestInterface $request, $data)
259
    {
260
        $request->setOption(CURLOPT_CUSTOMREQUEST, 'PUT');
261
        if ($data !== null) {
262
            $request->setOption(CURLOPT_POSTFIELDS, $data);
263
        }
264
    }
265
}
266