Completed
Pull Request — master (#78)
by Michal
01:24
created

ConsoleRequest::makeRequest()   F

Complexity

Conditions 17
Paths 256

Size

Total Lines 94

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 306

Importance

Changes 0
Metric Value
dl 0
loc 94
ccs 0
cts 65
cp 0
rs 3.0775
c 0
b 0
f 0
cc 17
nc 256
nop 5
crap 306

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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