Completed
Pull Request — master (#26)
by
unknown
02:21
created

ConsoleRequest   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 222
Duplicated Lines 6.31 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 68.42%

Importance

Changes 13
Bugs 3 Features 4
Metric Value
wmc 34
c 13
b 3
f 4
lcom 1
cbo 3
dl 14
loc 222
ccs 91
cts 133
cp 0.6842
rs 9.2

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C makeRequest() 0 80 10
C processValues() 14 43 11
C processParam() 0 29 7
B normalizeValues() 0 17 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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, $rawPost) = $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(true);
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 ($rawPost) {
66
            curl_setopt($curl, CURLOPT_POST, true);
67
            curl_setopt($curl, CURLOPT_POSTFIELDS, $rawPost);
68
        }
69 3
        $cookieFields['PHPSESSID'] = session_id();
70 3
        if (count($cookieFields)) {
71 3
            $parts = [];
72 3
            foreach ($cookieFields as $key => $value) {
73 3
                $parts[] = "$key=$value";
74 3
            }
75 3
            curl_setopt($curl, CURLOPT_HTTPHEADER, ["Cookie: " . implode('&', $parts)]);
76 3
        }
77
78 3
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
79 3
        $headers = [];
80 3
        if ($token !== null && $token !== false) {
81
            $headers = ['Authorization: Bearer ' . $token];
82
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
83
        }
84
85 3
        $consoleResponse = new ConsoleResponse(
86 3
            $url,
87 3
            $method,
88 3
            $postFields,
89 3
            $getFields,
90 3
            $cookieFields,
91 3
            $headers,
92
            $rawPost
93 3
        );
94
        /** @see http://stackoverflow.com/questions/15627217/curl-not-passing-phpsessid */
95 3
        session_write_close();
96
97 3
        $response = curl_exec($curl);
98 3
        $elapsed = intval((microtime(true) - $startTime) * 1000);
99
100 3
        $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
101 3
        $responseHeaders = substr($response, 0, $headerSize);
102 3
        $responseBody = substr($response, $headerSize);
103
104 3
        $curlErrorNumber = curl_errno($curl);
105 3
        $curlError = curl_error($curl);
106 3
        if ($curlErrorNumber > 0) {
107 3
            $consoleResponse->logError($curlErrorNumber, $curlError, $elapsed);
108 3
        } else {
109
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
110
            $consoleResponse->logRequest($httpCode, $responseBody, $responseHeaders, $elapsed);
111
        }
112
113 3
        return $consoleResponse;
114
    }
115
116
    /**
117
     * Process given values to POST and GET fields
118
     *
119
     * @param array $values
120
     *
121
     * @return array
122
     */
123 3
    private function processValues(array $values)
124
    {
125 3
        $params = $this->handler->params();
126
127 3
        $postFields = [];
128 3
        $rawPost = isset($values['post_raw']) ? $values['post_raw'] : false;
129 3
        $getFields = [];
130 3
        $cookieFields = [];
131
132 3
        foreach ($values as $key => $value) {
133 3
            if (strstr($key, '___') !== false) {
134
                $parts = explode('___', $key);
135
                $key = $parts[0];
136
            }
137
138 3
            foreach ($params as $param) {
139 3
                $valueData = $this->processParam($param, $key, $value);
140 3
                if ($valueData === null) {
141 3
                    continue;
142
                }
143
144 3
                if ($param->isMulti()) {
145 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
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
148
                        $cookieFields[$key][] = $valueData;
149
                    } else {
150
                        $getFields[$key][] = $valueData;
151
                    }
152
                } else {
153 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...
154
                        $postFields[$key] = $valueData;
155 3
                    } elseif ($param->getType() == InputParam::TYPE_COOKIE) {
156
                        $cookieFields[$key] = $valueData;
157
                    } else {
158 3
                        $getFields[$key] = $valueData;
159
                    }
160
                }
161 3
            }
162 3
        }
163
164 3
        return [$postFields, $getFields, $cookieFields, $rawPost];
165
    }
166
167
    /**
168
     * Process one param and returns value
169
     *
170
     * @param InputParam  $param   input param
171
     * @param string      $key     param key
172
     * @param string      $value   actual value from request
173
     *
174
     * @return string
175
     */
176 3
    private function processParam(InputParam $param, $key, $value)
177
    {
178 3
        if ($param->getKey() == $key) {
179 3
            if (!$value) {
180
                return null;
181
            }
182
183 3
            $valueData = $value;
184
185 3
            if ($param->getType() == InputParam::TYPE_FILE) {
186
                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...
187
                    $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...
188
                } else {
189
                    $valueData = false;
190
                }
191
            }
192
193 3
            if ($param->getType() == InputParam::TYPE_POST_RAW) {
194
                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...
195
                    $valueData = $HTTP_RAW_POST_DATA;
196
                } else {
197
                    $valueData = file_get_contents('php://input');
198
                }
199
            }
200
201 3
            return $valueData;
202
        }
203 3
        return null;
204
    }
205
206
    /**
207
     * Normalize values array.
208
     *
209
     * @param $values
210
     * @return array
211
     */
212 3
    private function normalizeValues($values)
213
    {
214 3
        $result = [];
215 3
        foreach ($values as $key => $value) {
216 3
            if (is_array($value)) {
217
                $counter = 0;
218
                foreach ($value as $innerValue) {
219
                    if ($innerValue != null) {
220
                        $result[$key . "[".$counter++."]"] = $innerValue;
221
                    }
222
                }
223
            } else {
224 3
                $result[$key] = $value;
225
            }
226 3
        }
227 3
        return $result;
228
    }
229
}
230