Completed
Push — master ( 9af1fb...3b0552 )
by Tomas
05:09
created

ConsoleRequest::normalizeValues()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 8.125

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
ccs 7
cts 14
cp 0.5
rs 8.8571
cc 5
eloc 11
nc 3
nop 1
crap 8.125
1
<?php
2
3
namespace Tomaj\NetteApi\Misc;
4
5
use Tomaj\NetteApi\Handlers\ApiHandlerInterface;
6
use Tomaj\NetteApi\Params\InputParam;
7
8
class ConsoleRequest
9
{
10
    /**
11
     * @var ApiHandlerInterface
12
     */
13
    private $handler;
14
15
    /**
16
     * Create ConsoleRequest
17
     *
18
     * @param ApiHandlerInterface $handler
19
     */
20 3
    public function __construct(ApiHandlerInterface $handler)
21
    {
22 3
        $this->handler = $handler;
23 3
    }
24
25
    /**
26
     * Make request to API url
27
     *
28
     * @param string $url
29
     * @param string $method
30
     * @param array $values
31
     * @param array $additionalValues
32
     * @param string|null $token
33
     *
34
     * @return ConsoleResponse
35
     */
36 3
    public function makeRequest($url, $method, array $values, array $additionalValues = [], $token = null)
37
    {
38 3
        list($postFields, $getFields, $cookieFields, $rawPost, $putFields) = $this->processValues($values);
39
40 3
        if (isset($additionalValues['postFields'])) {
41
            $postFields = array_merge($postFields, $additionalValues['postFields']);
42
        }
43
44 3
        if (isset($additionalValues['getFields'])) {
45
            $getFields = array_merge($postFields, $additionalValues['getFields']);
46
        }
47
48 3
        if (isset($additionalValues['cookieFields'])) {
49
            $cookieFields = array_merge($postFields, $additionalValues['cookieFields']);
50
        }
51
52 3
        if (isset($additionalValues['putFields'])) {
53
            $putFields = array_merge($putFields, $additionalValues['putFields']);
54
        }
55
56 3
        $postFields = $this->normalizeValues($postFields);
57 3
        $getFields = $this->normalizeValues($getFields);
58 3
        $putFields = $this->normalizeValues($putFields);
59
60 3 View Code Duplication
        if (count($getFields)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
61 3
            $parts = [];
62 3
            foreach ($getFields as $key => $value) {
63 3
                $parts[] = "$key=$value";
64 1
            }
65 3
            $url = $url . '?' . implode('&', $parts);
66 1
        }
67
68 3
        $putRawPost = null;
69 3 View Code Duplication
        if (count($putFields)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
            $parts = [];
71
            foreach ($putFields as $key => $value) {
72
                $parts[] = "$key=$value";
73
            }
74
            $putRawPost = implode('&', $parts);
75
        }
76
77 3
        $startTime = microtime(true);
78
79 3
        $curl = curl_init();
80 3
        curl_setopt($curl, CURLOPT_URL, $url);
81 3
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
82 3
        curl_setopt($curl, CURLOPT_NOBODY, false);
83 3
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
84 3
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
85 3
        curl_setopt($curl, CURLOPT_VERBOSE, false);
86 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
87 3
        curl_setopt($curl, CURLOPT_HEADER, true);
88 3
        if (count($postFields)) {
89
            curl_setopt($curl, CURLOPT_POST, true);
90
            curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
91
        }
92 3
        if ($rawPost) {
93
            curl_setopt($curl, CURLOPT_POST, true);
94
            curl_setopt($curl, CURLOPT_POSTFIELDS, $rawPost);
95
        }
96 3
        if ($putRawPost) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $putRawPost of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
97
            curl_setopt($curl, CURLOPT_POST, true);
98
            curl_setopt($curl, CURLOPT_POSTFIELDS, $putRawPost);
99
        }
100 3
        if (count($cookieFields)) {
101
            $parts = [];
102
            foreach ($cookieFields as $key => $value) {
103
                $parts[] = "$key=$value";
104
            }
105
            curl_setopt($curl, CURLOPT_HTTPHEADER, ["Cookie: " . implode('&', $parts)]);
106
        }
107
108 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
109 3
        $headers = [];
110 3
        if ($token !== null && $token !== false) {
111
            $headers = ['Authorization: Bearer ' . $token];
112
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
113
        }
114
115 3
        $consoleResponse = new ConsoleResponse(
116 3
            $url,
117 3
            $method,
118 3
            $postFields,
119 3
            $getFields,
120 3
            $cookieFields,
121 3
            $headers,
122 2
            $rawPost
123 1
        );
124
125 3
        $response = curl_exec($curl);
126 3
        $elapsed = intval((microtime(true) - $startTime) * 1000);
127
128 3
        $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
129 3
        $responseHeaders = substr($response, 0, $headerSize);
130 3
        $responseBody = substr($response, $headerSize);
131
132 3
        $curlErrorNumber = curl_errno($curl);
133 3
        $curlError = curl_error($curl);
134 3
        if ($curlErrorNumber > 0) {
135 3
            $consoleResponse->logError($curlErrorNumber, $curlError, $elapsed);
136 1
        } else {
137
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
138
            $consoleResponse->logRequest($httpCode, $responseBody, $responseHeaders, $elapsed);
139
        }
140
141 3
        return $consoleResponse;
142
    }
143
144
    /**
145
     * Process given values to POST and GET fields
146
     *
147
     * @param array $values
148
     *
149
     * @return array
150
     */
151 3
    private function processValues(array $values)
152
    {
153 3
        $params = $this->handler->params();
154
155 3
        $postFields = [];
156 3
        $rawPost = isset($values['post_raw']) ? $values['post_raw'] : false;
157 3
        $getFields = [];
158 3
        $putFields = [];
159 3
        $cookieFields = [];
160
161 3
        foreach ($values as $key => $value) {
162 3
            if (strstr($key, '___') !== false) {
163
                $parts = explode('___', $key);
164
                $key = $parts[0];
165
            }
166
167 3
            foreach ($params as $param) {
168 3
                $valueData = $this->processParam($param, $key, $value);
169 3
                if ($valueData === null) {
170 3
                    continue;
171
                }
172
173 3
                if ($param->isMulti()) {
174
                    if (in_array($param->getType(), [InputParam::TYPE_POST, InputParam::TYPE_FILE])) {
175
                        $postFields[$key][] = $valueData;
176
                    } elseif ($param->getType() == InputParam::TYPE_PUT) {
177
                        $putFields[$key][] = $valueData;
178
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
179
                        $cookieFields[$key][] = $valueData;
180
                    } else {
181
                        $getFields[$key][] = $valueData;
182
                    }
183
                } else {
184 3
                    if (in_array($param->getType(), [InputParam::TYPE_POST, InputParam::TYPE_FILE])) {
185
                        $postFields[$key] = $valueData;
186 3
                    } elseif ($param->getType() == InputParam::TYPE_PUT) {
187
                        $putFields[$key] = $valueData;
188 3
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
189
                        $cookieFields[$key] = $valueData;
190
                    } else {
191 3
                        $getFields[$key] = $valueData;
192
                    }
193
                }
194 1
            }
195 1
        }
196
197 3
        return [$postFields, $getFields, $cookieFields, $rawPost, $putFields];
198
    }
199
200
    /**
201
     * Process one param and returns value
202
     *
203
     * @param InputParam  $param   input param
204
     * @param string      $key     param key
205
     * @param string      $value   actual value from request
206
     *
207
     * @return string
208
     */
209 3
    private function processParam(InputParam $param, $key, $value)
210
    {
211 3
        if ($param->getKey() == $key) {
212 3
            $valueData = $value;
213
214 3
            if ($param->getType() == InputParam::TYPE_FILE) {
215
                if ($value->isOk()) {
0 ignored issues
show
Bug introduced by
The method isOk cannot be called on $value (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
216
                    $valueData = curl_file_create($value->getTemporaryFile(), $value->getContentType(), $value->getName());
0 ignored issues
show
Bug introduced by
The method getTemporaryFile cannot be called on $value (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method getContentType cannot be called on $value (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method getName cannot be called on $value (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
217
                } else {
218
                    $valueData = false;
219
                }
220
            }
221
222 3
            if ($param->getType() == InputParam::TYPE_POST_RAW) {
223
                if (isset($HTTP_RAW_POST_DATA)) {
0 ignored issues
show
Bug introduced by
The variable $HTTP_RAW_POST_DATA seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
224
                    $valueData = $HTTP_RAW_POST_DATA;
225
                } else {
226
                    $valueData = file_get_contents('php://input');
227
                }
228
            }
229
230 3
            return $valueData;
231
        }
232 3
        return null;
233
    }
234
235
    /**
236
     * Normalize values array.
237
     *
238
     * @param $values
239
     * @return array
240
     */
241 3
    private function normalizeValues($values)
242
    {
243 3
        $result = [];
244 3
        foreach ($values as $key => $value) {
245 3
            if (is_array($value)) {
246
                $counter = 0;
247
                foreach ($value as $innerValue) {
248
                    if ($innerValue != null) {
249
                        $result[$key . "[".$counter++."]"] = $innerValue;
250
                    }
251
                }
252
            } else {
253 3
                $result[$key] = $value;
254
            }
255 1
        }
256 3
        return $result;
257
    }
258
}
259