Completed
Push — master ( cb2641...d94a3c )
by Tomas
02:48
created

ConsoleRequest::makeRequest()   C

Complexity

Conditions 9
Paths 32

Size

Total Lines 72
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 10.1394

Importance

Changes 6
Bugs 1 Features 3
Metric Value
c 6
b 1
f 3
dl 0
loc 72
ccs 44
cts 58
cp 0.7586
rs 6.0413
cc 9
eloc 52
nc 32
nop 4
crap 10.1394

How to fix   Long Method   

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
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 string|null $token
32
     *
33
     * @return ConsoleResponse
34
     */
35 3
    public function makeRequest($url, $method, array $values, $token = null)
36
    {
37 3
        list($postFields, $getFields, $cookieFields) = $this->processValues($values);
38
39 3
        $postFields = $this->normalizeValues($postFields);
40 3
        $getFields = $this->normalizeValues($getFields);
41
42 3
        if (count($getFields)) {
43 3
            $parts = [];
44 3
            foreach ($getFields as $key => $value) {
45 3
                $parts[] = "$key=$value";
46 3
            }
47 3
            $url = $url . '?' . implode('&', $parts);
48 3
        }
49
50 3
        $startTime = microtime();
51
52 3
        $curl = curl_init();
53 3
        curl_setopt($curl, CURLOPT_URL, $url);
54 3
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
55 3
        curl_setopt($curl, CURLOPT_NOBODY, false);
56 3
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
57 3
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
58 3
        curl_setopt($curl, CURLOPT_VERBOSE, false);
59 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
60 3
        curl_setopt($curl, CURLOPT_HEADER, true);
61 3
        if (count($postFields)) {
62
            curl_setopt($curl, CURLOPT_POST, true);
63
            curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
64
        }
65 3
        if (count($cookieFields)) {
66
            $parts = [];
67
            foreach ($cookieFields as $key => $value) {
68
                $parts[] = "$key=$value";
69
            }
70
            curl_setopt($curl, CURLOPT_HTTPHEADER, ["Cookie: " . implode('&', $parts)]);
71
        }
72
73 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
74 3
        $headers = [];
75 3
        if ($token !== null && $token !== false) {
76
            $headers = ['Authorization: Bearer ' . $token];
77
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
78
        }
79
80 3
        $consoleResponse = new ConsoleResponse(
81 3
            $url,
82 3
            $method,
83 3
            $postFields,
84 3
            $getFields,
85 3
            $cookieFields,
86
            $headers
87 3
        );
88
89 3
        $response = curl_exec($curl);
90 3
        $elapsed = intval((microtime() - $startTime) * 1000);
91
92 3
        $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
93 3
        $responseHeaders = substr($response, 0, $headerSize);
94 3
        $responseBody = substr($response, $headerSize);
95
96 3
        $curlErrorNumber = curl_errno($curl);
97 3
        $curlError = curl_error($curl);
98 3
        if ($curlErrorNumber > 0) {
99 3
            $consoleResponse->logError($curlErrorNumber, $curlError, $elapsed);
100 3
        } else {
101
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
102
            $consoleResponse->logRequest($httpCode, $responseBody, $responseHeaders, $elapsed);
103
        }
104
105 3
        return $consoleResponse;
106
    }
107
108
    /**
109
     * Process given values to POST and GET fields
110
     *
111
     * @param array $values
112
     *
113
     * @return array
114
     */
115 3
    private function processValues(array $values)
116
    {
117 3
        $params = $this->handler->params();
118
119 3
        $postFields = [];
120 3
        $getFields = [];
121 3
        $cookieFields = [];
122
123 3
        foreach ($values as $key => $value) {
124 3
            if (strstr($key, '___') !== false) {
125
                $parts = explode('___', $key);
126
                $key = $parts[0];
127
            }
128
129 3
            foreach ($params as $param) {
130 3
                $valueData = $this->processParam($param, $key, $value);
131
132 3
                if ($valueData === null) {
133 3
                    continue;
134
                }
135
136 3
                if ($param->isMulti()) {
137 View Code Duplication
                    if (in_array($param->getType(), [InputParam::TYPE_POST, InputParam::TYPE_FILE])) {
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...
138
                        $postFields[$key][] = $valueData;
139
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
140
                        $cookieFields[$key][] = $valueData;
141
                    } else {
142
                        $getFields[$key][] = $valueData;
143
                    }
144
                } else {
145 3 View Code Duplication
                    if (in_array($param->getType(), [InputParam::TYPE_POST, InputParam::TYPE_FILE])) {
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...
146
                        $postFields[$key] = $valueData;
147 3
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
148
                        $cookieFields[$key] = $valueData;
149
                    } else {
150 3
                        $getFields[$key] = $valueData;
151
                    }
152
                }
153 3
            }
154 3
        }
155
156 3
        return [$postFields, $getFields, $cookieFields];
157
    }
158
159
    /**
160
     * Process one param and returns value
161
     *
162
     * @param InputParam  $param   input param
163
     * @param string      $key     param key
164
     * @param string      $value   actual value from request
165
     *
166
     * @return string
167
     */
168 3
    private function processParam(InputParam $param, $key, $value)
169
    {
170 3
        if ($param->getKey() == $key) {
171 3
            if (!$value) {
172
                return null;
173
            }
174
175 3
            $valueData = $value;
176
177 3
            if ($param->getType() == InputParam::TYPE_FILE) {
178
                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...
179
                    $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...
180
                } else {
181
                    $valueData = false;
182
                }
183
            }
184
185 3
            return $valueData;
186
        }
187 3
        return null;
188
    }
189
190
    /**
191
     * Normalize values array.
192
     *
193
     * @param $values
194
     * @return array
195
     */
196 3
    private function normalizeValues($values)
197
    {
198 3
        $result = [];
199 3
        foreach ($values as $key => $value) {
200 3
            if (is_array($value)) {
201
                $counter = 0;
202
                foreach ($value as $innerValue) {
203
                    if ($innerValue != null) {
204
                        $result[$key . "[".$counter++."]"] = $innerValue;
205
                    }
206
                }
207
            } else {
208 3
                $result[$key] = $value;
209
            }
210 3
        }
211 3
        return $result;
212
    }
213
}
214