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
![]() |
|||
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 |