Completed
Pull Request — master (#61)
by Michal
02:56 queued 40s
created

ConsoleRequest::normalizeValues()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 6.6

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 6
cts 10
cp 0.6
rs 9.3888
c 0
b 0
f 0
cc 5
nc 3
nop 1
crap 6.6
1
<?php
2
3
namespace Tomaj\NetteApi\Misc;
4
5
use Nette\Http\FileUpload;
6
use Tomaj\NetteApi\Handlers\ApiHandlerInterface;
7
use Tomaj\NetteApi\Params\InputParam;
8
9
class ConsoleRequest
10
{
11
    /** @var ApiHandlerInterface */
12
    private $handler;
13
14 3
    public function __construct(ApiHandlerInterface $handler)
15
    {
16 3
        $this->handler = $handler;
17 3
    }
18
19 3
    public function makeRequest(string $url, string $method, array $values, array $additionalValues = [], ?string $token = null): ConsoleResponse
20
    {
21 3
        list($postFields, $getFields, $cookieFields, $rawPost, $putFields) = $this->processValues($values);
22
23 3
        $postFields = array_merge($postFields, $additionalValues['postFields'] ?? []);
24 3
        $getFields = array_merge($getFields, $additionalValues['getFields'] ?? []);
25 3
        $cookieFields = array_merge($cookieFields, $additionalValues['cookieFields'] ?? []);
26 3
        $putFields = array_merge($putFields, $additionalValues['putFields'] ?? []);
27
28 3
        $postFields = $this->normalizeValues($postFields);
29 3
        $getFields = $this->normalizeValues($getFields);
30 3
        $putFields = $this->normalizeValues($putFields);
31
32 3
        if (count($getFields)) {
33 3
            $parts = [];
34 3
            foreach ($getFields as $key => $value) {
35 3
                $parts[] = "$key=$value";
36
            }
37 3
            $url = $url . '?' . implode('&', $parts);
38
        }
39
40 3
        $putRawPost = null;
41 3
        if (count($putFields)) {
42
            $parts = [];
43
            foreach ($putFields as $key => $value) {
44
                $parts[] = "$key=$value";
45
            }
46
            $putRawPost = implode('&', $parts);
47
        }
48
49 3
        $startTime = microtime(true);
50
51 3
        $curl = curl_init();
52 3
        curl_setopt($curl, CURLOPT_URL, $url);
53 3
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
54 3
        curl_setopt($curl, CURLOPT_NOBODY, false);
55 3
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
56 3
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
57 3
        curl_setopt($curl, CURLOPT_VERBOSE, false);
58 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
59 3
        curl_setopt($curl, CURLOPT_HEADER, true);
60
61 3
        if (count($postFields) || $rawPost || $putRawPost !== null) {
62
            curl_setopt($curl, CURLOPT_POST, true);
63
            curl_setopt($curl, CURLOPT_POSTFIELDS, count($postFields) ? $postFields : ($rawPost ?: $putRawPost));
64
        }
65
66 3
        if (count($cookieFields)) {
67
            $parts = [];
68
            foreach ($cookieFields as $key => $value) {
69
                $parts[] = "$key=$value";
70
            }
71
            curl_setopt($curl, CURLOPT_HTTPHEADER, ["Cookie: " . implode('&', $parts)]);
72
        }
73
74 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
75 3
        $headers = [];
76 3
        if ($token !== null && $token !== false) {
77
            $headers = ['Authorization: Bearer ' . $token];
78
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
79
        }
80
81 3
        $consoleResponse = new ConsoleResponse(
82 3
            $url,
83 2
            $method,
84 2
            $postFields,
85 2
            $getFields,
86 2
            $cookieFields,
87 2
            $headers,
88 2
            $rawPost
89
        );
90
91 3
        $response = curl_exec($curl);
92 3
        $elapsed = intval((microtime(true) - $startTime) * 1000);
93
94 3
        $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
95 3
        $responseHeaders = substr($response, 0, $headerSize);
96 3
        $responseBody = substr($response, $headerSize);
97
98 3
        $curlErrorNumber = curl_errno($curl);
99 3
        $curlError = curl_error($curl);
100 3
        if ($curlErrorNumber > 0) {
101 3
            $consoleResponse->logError($curlErrorNumber, $curlError, $elapsed);
102
        } else {
103
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
104
            $consoleResponse->logRequest($httpCode, $responseBody, $responseHeaders, $elapsed);
105
        }
106
107 3
        return $consoleResponse;
108
    }
109
110
    /**
111
     * Process given values to POST and GET fields
112
     *
113
     * @param array $values
114
     *
115
     * @return array
116
     */
117 3
    private function processValues(array $values): array
118
    {
119 3
        $params = $this->handler->params();
120
121 3
        $postFields = [];
122 3
        $rawPost = isset($values['post_raw']) ? $values['post_raw'] : false;
123 3
        $getFields = [];
124 3
        $putFields = [];
125 3
        $cookieFields = [];
126
127 3
        foreach ($values as $key => $value) {
128 3
            if (strstr($key, '___') !== false) {
129
                $parts = explode('___', $key);
130
                $key = $parts[0];
131
            }
132
133 3
            foreach ($params as $param) {
134 3
                $valueData = $this->processParam($param, $key, $value);
135 3
                if ($valueData === null) {
136 3
                    continue;
137
                }
138
139 3
                if ($param->isMulti()) {
140
                    if (in_array($param->getType(), [InputParam::TYPE_POST, InputParam::TYPE_FILE])) {
141
                        $postFields[$key][] = $valueData;
142
                    } elseif ($param->getType() == InputParam::TYPE_PUT) {
143
                        $putFields[$key][] = $valueData;
144
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
145
                        $cookieFields[$key][] = $valueData;
146
                    } else {
147
                        $getFields[$key][] = $valueData;
148
                    }
149
                } else {
150 3
                    if (in_array($param->getType(), [InputParam::TYPE_POST, InputParam::TYPE_FILE])) {
151
                        $postFields[$key] = $valueData;
152 3
                    } elseif ($param->getType() == InputParam::TYPE_PUT) {
153
                        $putFields[$key] = $valueData;
154 3
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
155
                        $cookieFields[$key] = $valueData;
156
                    } else {
157 3
                        $getFields[$key] = $valueData;
158
                    }
159
                }
160
            }
161
        }
162
163 3
        return [$postFields, $getFields, $cookieFields, $rawPost, $putFields];
164
    }
165
166
    /**
167
     * Process one param and returns value
168
     *
169
     * @param InputParam  $param   input param
170
     * @param string      $key     param key
171
     * @param mixed      $value   actual value from request
172
     *
173
     * @return string|null
174
     */
175 3
    private function processParam(InputParam $param, string $key, $value): ?string
176
    {
177 3
        if ($param->getKey() == $key) {
178 3
            $valueData = $value;
179
180 3
            if ($param->getType() === InputParam::TYPE_FILE) {
181
                /** @var FileUpload $file */
182
                $file = $value;
183
                if ($file->isOk()) {
184
                    $valueData = curl_file_create($file->getTemporaryFile(), $file->getContentType(), $file->getName());
185
                } else {
186
                    $valueData = false;
187
                }
188 3
            } elseif ($param->getType() === InputParam::TYPE_POST_RAW) {
189
                $valueData = file_get_contents('php://input');
190
            }
191
192 3
            return $valueData;
193
        }
194 3
        return null;
195
    }
196
197 3
    private function normalizeValues(array $values): array
198
    {
199 3
        $result = [];
200 3
        foreach ($values as $key => $value) {
201 3
            if (is_array($value)) {
202
                $counter = 0;
203
                foreach ($value as $innerValue) {
204
                    if ($innerValue != null) {
205
                        $result[$key . "[".$counter++."]"] = $innerValue;
206
                    }
207
                }
208
            } else {
209 3
                $result[$key] = $value;
210
            }
211
        }
212 3
        return $result;
213
    }
214
}
215