• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

webeweb / core-library / 3799187254

pending completion
3799187254

push

github

webeweb
Update CHANGELOG

48790 of 48928 relevant lines covered (99.72%)

48.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.92
/src/curl/Request/AbstractRequest.php
1
<?php
2

3
/*
4
 * This file is part of the core-library package.
5
 *
6
 * (c) 2017 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace WBW\Library\Curl\Request;
13

14
use DateTime;
15
use InvalidArgumentException;
16
use WBW\Library\Curl\Api\RequestInterface;
17
use WBW\Library\Curl\Api\ResponseInterface;
18
use WBW\Library\Curl\Configuration\Configuration;
19
use WBW\Library\Curl\Exception\RequestCallException;
20
use WBW\Library\Curl\Factory\CurlFactory;
21
use WBW\Library\Curl\Helper\CurlHelper;
22

23
/**
24
 * Abstract request.
25
 *
26
 * @author webeweb <https://github.com/webeweb>
27
 * @package WBW\Library\Curl\Request
28
 * @abstract
29
 */
30
abstract class AbstractRequest implements RequestInterface {
31

32
    /**
33
     * Configuration.
34
     *
35
     * @var Configuration
36
     */
37
    private $configuration;
38

39
    /**
40
     * Headers.
41
     *
42
     * @var array
43
     */
44
    private $headers;
45

46
    /**
47
     * Method.
48
     *
49
     * @var string
50
     */
51
    private $method;
52

53
    /**
54
     * POST data.
55
     *
56
     * @var array
57
     */
58
    private $postData;
59

60
    /**
61
     * Query data.
62
     *
63
     * @var array
64
     */
65
    private $queryData;
66

67
    /**
68
     * Resource path.
69
     *
70
     * @var string
71
     */
72
    private $resourcePath;
73

74
    /**
75
     * Constructor.
76
     *
77
     * @param string $method The Method.
78
     * @param Configuration $configuration The configuration.
79
     * @param string|null $resourcePath The resource path.
80
     * @throws InvalidArgumentException Throws an invalid argument exception if the method is invalid.
81
     */
82
    protected function __construct(string $method, Configuration $configuration, ?string $resourcePath) {
83
        $this->setConfiguration($configuration);
266✔
84
        $this->setHeaders([]);
266✔
85
        $this->setMethod($method);
266✔
86
        $this->setQueryData([]);
266✔
87
        $this->setPostData([]);
266✔
88
        $this->setResourcePath($resourcePath);
266✔
89
    }
76✔
90

91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function addHeader(string $name, string $value): RequestInterface {
95
        $this->headers[$name] = $value;
70✔
96
        return $this;
70✔
97
    }
98

99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function addPostData(string $name, string $value): RequestInterface {
103
        $this->postData[$name] = $value;
35✔
104
        return $this;
35✔
105
    }
106

107
    /**
108
     * {@inheritdoc}
109
     */
110
    public function addQueryData(string $name, string $value): RequestInterface {
111
        $this->queryData[$name] = $value;
70✔
112
        return $this;
70✔
113
    }
114

115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function call(): ResponseInterface {
119

120
        $requestHeader = $this->mergeHeaders();
119✔
121
        $requestBody   = http_build_query($this->getPostData());
119✔
122

123
        if (true === in_array("Content-Type: application/json", $requestHeader)) {
119✔
124
            $requestBody = json_encode($this->getPostData());
14✔
125
        }
126

127
        $requestUrl = $this->mergeUrl();
119✔
128
        if (0 < count($this->getQueryData())) {
119✔
129
            $requestUrl = implode("?", [$requestUrl, http_build_query($this->getQueryData())]);
56✔
130
        }
131

132
        $stream = CurlHelper::initStream($requestUrl, $this->getConfiguration());
119✔
133

134
        CurlHelper::setHeaders($stream, $requestHeader);
119✔
135
        CurlHelper::setPost($stream, $this->getMethod(), $requestBody);
119✔
136
        CurlHelper::setProxy($stream, $this->getConfiguration());
119✔
137
        CurlHelper::setReturnTransfer($stream);
119✔
138
        CurlHelper::setSsl($stream, $this->getConfiguration());
119✔
139
        CurlHelper::setTimeout($stream, $this->getConfiguration());
119✔
140
        CurlHelper::setUserAgent($stream, $this->getConfiguration());
119✔
141
        CurlHelper::setVerbose($stream, $this->getConfiguration(), $requestUrl, $requestBody);
119✔
142

143
        $curlExec    = curl_exec($stream);
119✔
144
        $curlGetInfo = curl_getinfo($stream, CURLINFO_HEADER_SIZE);
119✔
145

146
        $responseHeader = $this->parseheader(substr($curlExec, 0, $curlGetInfo));
119✔
147
        $responseBody   = substr($curlExec, $curlGetInfo);
119✔
148
        $responseInfo   = curl_getinfo($stream);
119✔
149

150
        if (true === $this->getConfiguration()->getDebug()) {
119✔
151
            $msg = (new DateTime())->format("c") . " [DEBUG] $requestUrl" . PHP_EOL . "HTTP response body ~BEGIN~" . PHP_EOL . print_r($responseBody, true) . PHP_EOL . "~END~" . PHP_EOL;
7✔
152
            error_log($msg, 3, $this->getConfiguration()->getDebugFile());
7✔
153
        }
154

155
        $response = $this->prepareResponse($requestBody, $requestHeader, $requestUrl, $responseBody, $responseHeader, $responseInfo);
119✔
156

157
        $curlHttpCode = $responseInfo["http_code"];
119✔
158
        if (200 <= $curlHttpCode && $curlHttpCode <= 299) {
119✔
159
            return $response;
112✔
160
        }
161

162
        $msg = curl_errno($stream);
14✔
163
        if (0 === $curlHttpCode) {
14✔
164
            if (false === empty(curl_error($stream))) {
7✔
165
                $msg = "Call to $requestUrl failed : " . curl_error($stream);
7✔
166
            } else {
167
                $msg = "Call to $requestUrl failed, but for an unknown reason. This could happen if you are disconnected from the network.";
×
168
            }
169
        }
170

171
        throw new RequestCallException($msg, $curlHttpCode, $response);
14✔
172
    }
173

174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function clearHeaders(): RequestInterface {
178
        return $this->setHeaders([]);
7✔
179
    }
180

181
    /**
182
     * {@inheritdoc}
183
     */
184
    public function clearPostData(): RequestInterface {
185
        return $this->setPostData([]);
7✔
186
    }
187

188
    /**
189
     * {@inheritdoc}
190
     */
191
    public function clearQueryData(): RequestInterface {
192
        return $this->setQueryData([]);
7✔
193
    }
194

195
    /**
196
     * {@inheritdoc}
197
     */
198
    public function getConfiguration(): Configuration {
199
        return $this->configuration;
168✔
200
    }
201

202
    /**
203
     * {@inheritdoc}
204
     */
205
    public function getHeaders(): array {
206
        return $this->headers;
182✔
207
    }
208

209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function getMethod(): string {
213
        return $this->method;
168✔
214
    }
215

216
    /**
217
     * {@inheritdoc}
218
     */
219
    public function getPostData(): array {
220
        return $this->postData;
189✔
221
    }
222

223
    /**
224
     * {@inheritdoc}
225
     */
226
    public function getQueryData(): array {
227
        return $this->queryData;
182✔
228
    }
229

230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function getResourcePath(): string {
234
        return $this->resourcePath;
168✔
235
    }
236

237
    /**
238
     * Merge the headers.
239
     *
240
     * @return array Returns the merged headers.
241
     */
242
    private function mergeHeaders(): array {
243

244
        $headers = [];
119✔
245
        foreach (array_merge($this->getConfiguration()->getHeaders(), $this->getHeaders()) as $key => $value) {
119✔
246
            $headers[] = implode(": ", [$key, $value]);
63✔
247
        }
248

249
        return $headers;
119✔
250
    }
251

252
    /**
253
     * Merge the URL.
254
     *
255
     * @return string Returns the merged URL.
256
     */
257
    private function mergeUrl(): string {
258

259
        $mergedURL = [
85✔
260
            $this->getConfiguration()->getHost(),
119✔
261
        ];
85✔
262

263
        if (null !== $this->getResourcePath() && "" !== $this->getResourcePath()) {
119✔
264
            $mergedURL[] = $this->getResourcePath();
119✔
265
        }
266

267
        return implode("/", $mergedURL);
119✔
268
    }
269

270
    /**
271
     * Parse the raw header.
272
     *
273
     * @param string $rawHeader The raw header.
274
     * @return array Returns the headers.
275
     */
276
    private function parseHeader(string $rawHeader): array {
277

278
        $headers = [];
119✔
279
        $key     = "";
119✔
280

281
        foreach (explode("\n", $rawHeader) as $h) {
119✔
282
            $h = explode(":", $h, 2);
119✔
283
            if (true === isset($h[1])) {
119✔
284
                if (false === isset($headers[$h[0]])) {
112✔
285
                    $headers[$h[0]] = trim($h[1]);
112✔
286
                } else if (true === is_array($headers[$h[0]])) {
×
287
                    $headers[$h[0]] = array_merge($headers[$h[0]], [trim($h[1])]);
×
288
                } else {
289
                    $headers[$h[0]] = array_merge([$headers[$h[0]]], [trim($h[1])]);
×
290
                }
291
                $key = $h[0];
112✔
292
            } else {
293
                if ("\t" === substr($h[0], 0, 1)) {
119✔
294
                    $headers[$key] .= "\r\n\t" . trim($h[0]);
×
295
                } else if (!$key) {
119✔
296
                    $headers[0] = trim($h[0]);
119✔
297
                }
298
                trim($h[0]);
119✔
299
            }
300
        }
301

302
        return $headers;
119✔
303
    }
304

305
    /**
306
     * Prepare a response.
307
     *
308
     * @param string $requestBody The request body.
309
     * @param array $requestHeader The request header.
310
     * @param string $requestUri The request URI.
311
     * @param string $responseBody The response body.
312
     * @param array $responseHeader The response header.
313
     * @param array $responseInfo The response info.
314
     * @return ResponseInterface Returns the response.
315
     */
316
    private function prepareResponse(string $requestBody, array $requestHeader, string $requestUri, string $responseBody, array $responseHeader, array $responseInfo): ResponseInterface {
317

318
        $response = CurlFactory::newCURLResponse();
119✔
319
        $response->setRequestBody($requestBody);
119✔
320
        $response->setRequestHeader($requestHeader);
119✔
321
        $response->setRequestUrl($requestUri);
119✔
322
        $response->setResponseBody($responseBody);
119✔
323
        $response->setResponseHeader($responseHeader);
119✔
324
        $response->setResponseInfo($responseInfo);
119✔
325

326
        return $response;
119✔
327
    }
328

329
    /**
330
     * {@inheritdoc}
331
     */
332
    public function removeHeader(string $name): RequestInterface {
333

334
        if (true === array_key_exists($name, $this->headers)) {
7✔
335
            unset($this->headers[$name]);
7✔
336
        }
337

338
        return $this;
7✔
339
    }
340

341
    /**
342
     * {@inheritdoc}
343
     */
344
    public function removePostData(string $name): RequestInterface {
345

346
        if (true === array_key_exists($name, $this->postData)) {
7✔
347
            unset($this->postData[$name]);
7✔
348
        }
349

350
        return $this;
7✔
351
    }
352

353
    /**
354
     * {@inheritdoc}
355
     */
356
    public function removeQueryData(string $name): RequestInterface {
357

358
        if (true === array_key_exists($name, $this->queryData)) {
7✔
359
            unset($this->queryData[$name]);
7✔
360
        }
361

362
        return $this;
7✔
363
    }
364

365
    /**
366
     * Set the configuration.
367
     *
368
     * @param Configuration $configuration The configuration.
369
     * @return RequestInterface Returns this request.
370
     */
371
    protected function setConfiguration(Configuration $configuration): RequestInterface {
372
        $this->configuration = $configuration;
266✔
373
        return $this;
266✔
374
    }
375

376
    /**
377
     * Set the headers.
378
     *
379
     * @param array $headers The headers.
380
     * @return RequestInterface Returns this request.
381
     */
382
    protected function setHeaders(array $headers): RequestInterface {
383
        $this->headers = $headers;
266✔
384
        return $this;
266✔
385
    }
386

387
    /**
388
     * Set the method.
389
     *
390
     * @param string $method The method.
391
     * @return RequestInterface Returns this request.
392
     * @throws InvalidArgumentException Throws an invalid argument exception if the method is invalid.
393
     */
394
    protected function setMethod(string $method): RequestInterface {
395

396
        switch ($method) {
397
            case self::METHOD_DELETE:
266✔
398
            case self::METHOD_GET:
245✔
399
            case self::METHOD_HEAD:
133✔
400
            case self::METHOD_OPTIONS:
112✔
401
            case self::METHOD_PATCH:
91✔
402
            case self::METHOD_POST:
70✔
403
            case self::METHOD_PUT:
21✔
404
                $this->method = $method;
266✔
405
                break;
266✔
406
            default:
407
                throw new InvalidArgumentException(sprintf('The HTTP method "%s" is invalid', $method));
×
408
        }
409

410
        return $this;
266✔
411
    }
412

413
    /**
414
     * Set the POST data.
415
     *
416
     * @param array $postData The POST data.
417
     * @return RequestInterface Returns this request.
418
     */
419
    protected function setPostData(array $postData): RequestInterface {
420
        $this->postData = $postData;
266✔
421
        return $this;
266✔
422
    }
423

424
    /**
425
     * Set the query data.
426
     *
427
     * @param array $queryData The query data.
428
     * @return RequestInterface Returns this request.
429
     */
430
    protected function setQueryData(array $queryData): RequestInterface {
431
        $this->queryData = $queryData;
266✔
432
        return $this;
266✔
433
    }
434

435
    /**
436
     * {@inheritdoc}
437
     */
438
    public function setResourcePath(?string $resourcePath): RequestInterface {
439
        $this->resourcePath = preg_replace("/^\//", "", trim($resourcePath));
266✔
440
        return $this;
266✔
441
    }
442
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc