Request2Curl::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 9
rs 10
1
<?php declare(strict_types=1);
2
3
namespace hiqdev\hiart\helpers;
4
5
use hiqdev\hiart\RequestInterface;
6
7
final class Request2Curl
8
{
9
    public const DOUBLE_QUOTE = '"';
10
11
    private ?string $method;
12
13
    private string $url;
14
15
    private ?string $body;
16
17
    private array $headers;
18
19
    private $guessedContentType;
20
21
    // not the full list, just special cases
22
    public const CONTENT_TYPE_FORM_DATA = 'multipart/form-data';
23
24
    public const CONTENT_TYPE_FORM_URL_ENCODED = 'x-www-form-urlencoded';
25
26
    public const CONTENT_TYPE_UNKNOWN = 'unknown';
27
28
    public function __construct(RequestInterface $request)
29
    {
30
        $this->method = $request->getMethod();
31
        $this->url = $request->getFullUri();
32
        $this->headers = $request->getHeaders();
0 ignored issues
show
Bug introduced by
The method getHeaders() does not exist on hiqdev\hiart\RequestInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to hiqdev\hiart\RequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

32
        /** @scrutinizer ignore-call */ 
33
        $this->headers = $request->getHeaders();
Loading history...
33
        $this->body = $request->getBody();
34
35
        $this->guessedContentType = $this->guessContentTypeFromHeaders();
36
        $this->removeContentLengthFromHeaders();
37
    }
38
39
    private function removeContentLengthFromHeaders(): void
40
    {
41
        $targetKey = 'content-length';
42
        $arrayFilterClosure = static fn($key) => !(strtolower($key) === $targetKey);
43
        $this->headers = array_filter($this->headers, $arrayFilterClosure, ARRAY_FILTER_USE_KEY);
44
    }
45
46
    private function guessContentTypeFromHeaders(): string
47
    {
48
        foreach ($this->getHeadersArray() as $header => $value) {
49
50
            if (strtolower($header) === 'content-type') {
51
52
                if (stripos($value, 'multipart/form-data') !== false) {
53
                    return self::CONTENT_TYPE_FORM_DATA;
54
                }
55
56
                if (stripos($value, 'www-form-urlencoded') !== false) {
57
                    return self::CONTENT_TYPE_FORM_URL_ENCODED;
58
                }
59
60
                return self::CONTENT_TYPE_UNKNOWN;
61
            }
62
        }
63
64
        return self::CONTENT_TYPE_UNKNOWN;
65
    }
66
67
    public function __toString(): string
68
    {
69
        return 'curl --insecure '
70
            . '-X ' . $this->getMethod()
71
            . ' ' . self::DOUBLE_QUOTE
72
            . $this->getFullURLPart()
73
            . self::DOUBLE_QUOTE
74
            . $this->getHeadersPart()
75
            . $this->getRequestBodyPart();
76
    }
77
78
    private function getMethod(): ?string
79
    {
80
        return $this->method;
81
    }
82
83
    private function getFullURLPart(): string
84
    {
85
        return $this->url;
86
    }
87
88
    private function getHeadersPart(): string
89
    {
90
        $result = '';
91
92
        foreach ($this->getHeadersArray() as $key => $value) {
93
94
            $result .= " -H '$key: $value'";
95
        }
96
97
        return $result;
98
    }
99
100
    private function getRequestBodyPart(): string
101
    {
102
        return match ($this->getMethod()) {
103
            'POST', 'PUT', 'PATCH', 'DELETE' => match ($this->guessedContentType) {
104
                self::CONTENT_TYPE_FORM_DATA => " --form '$this->body'",
105
                self::CONTENT_TYPE_FORM_URL_ENCODED => " --data '$this->body'",
106
            },
107
            'OPTIONS' => ''
108
        };
109
    }
110
111
    private function getHeadersArray(): array
112
    {
113
        return $this->headers;
114
    }
115
}
116