HttpClient::request()   C
last analyzed

Complexity

Conditions 12
Paths 144

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 6.6
c 0
b 0
f 0
cc 12
nc 144
nop 6

How to fix   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
namespace BWC\Share\Net\HttpClient;
4
5
use BWC\Share\Net\ContentType;
6
7
8
class HttpClient implements HttpClientInterface
9
{
10
    private $_curl;
11
12
    private $_timeout_ms = 10000;
13
14
    protected $_accept;
15
16
    private $_header;
17
18
    private $_statusCode;
19
20
    private $_errorText;
21
22
23
    function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
24
        $this->_curl = curl_init();
25
        curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true);
26
    }
27
28
29
    function getTimeoutMS() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
30
        return $this->_timeout_ms;
31
    }
32
33
    function setTimeoutMS($milliseconds) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
34
        $this->_timeout_ms = $milliseconds;
35
    }
36
37
    /**
38
     * @param $path
39
     * @return void
40
     */
41
    public function setCaPath($path)
42
    {
43
        if ($path) {
44
            curl_setopt($this->_curl, CURLOPT_CAPATH, $path);
45
        }
46
    }
47
48
    /**
49
     * @param $file
50
     * @return void
51
     */
52
    public function setCaFile($file)
53
    {
54
        if ($file) {
55
            curl_setopt($this->_curl, CURLOPT_CAINFO, $file);
56
        }
57
    }
58
59
    /**
60
     * @param bool $value
61
     * @return void
62
     */
63
    public function looseSslCheck($value)
64
    {
65
        if ($value) {
66
            curl_setopt($this->_curl, CURLOPT_SSL_VERIFYPEER, false);
67
            curl_setopt($this->_curl, CURLOPT_SSL_VERIFYHOST, 0);
68
        } else {
69
            curl_setopt($this->_curl, CURLOPT_SSL_VERIFYPEER, true);
70
            curl_setopt($this->_curl, CURLOPT_SSL_VERIFYHOST, 2);
71
        }
72
    }
73
74
    /**
75
     * @return int
76
     */
77
    function getStatusCode() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
78
        return $this->_statusCode;
79
    }
80
81
    /**
82
     * @return string
83
     */
84
    function getErrorText() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
85
        return $this->_errorText;
86
    }
87
    /**
88
     * @return string
89
     */
90
    function getHeader() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
91
        return $this->_header;
92
    }
93
94
95
96
    /**
97
     * @param string $username
98
     * @param string $password
99
     * @return void
100
     */
101
    function setCredentials($username, $password) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
102
        curl_setopt($this->_curl, CURLOPT_USERPWD, $username.':'.$password);
103
    }
104
105
106
    /**
107
     * @param string $type   mime type for Accept http header, like text/xml or application/json
108
     * @return void
109
     */
110
    function accept($type) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
111
        $this->_accept = $type;
112
    }
113
114
115
116
    /**
117
     * @param string $url
118
     * @param array $queryData
119
     * @param array $arrHeaders
120
     * @return string
121
     */
122
    function get($url, array $queryData = array(), array $arrHeaders = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
123
        $arrHeaders[] = 'Content-length: 0';
124
        $result = $this->request($url, 'GET', $queryData, null, null, $arrHeaders);
125
        return $result;
126
    }
127
128
129
    function post($url, array $queryData = array(), $postData, $contentType = null, array $arrHeaders = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
130
        $result = $this->request($url, 'POST', $queryData, $postData, $contentType, $arrHeaders);
0 ignored issues
show
Bug introduced by
It seems like $postData defined by parameter $postData on line 129 can also be of type object; however, BWC\Share\Net\HttpClient\HttpClient::request() does only seem to accept array|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $contentType defined by parameter $contentType on line 129 can also be of type string; however, BWC\Share\Net\HttpClient\HttpClient::request() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
131
        return $result;
132
    }
133
134
    /**
135
     * @param string $url
136
     * @param array $queryData
137
     * @param array $arrHeaders
138
     * @return string
139
     */
140
    function delete($url, array $queryData = array(), array $arrHeaders = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
141
        $result = $this->request($url, 'DELETE', $queryData, null, null, $arrHeaders);
142
        return $result;
143
    }
144
145
146
    /**
147
     * @param $url
148
     * @param $method
149
     * @param array $queryData
150
     * @param array|string $postData
151
     * @param null $contentType
152
     * @param array $arrHeaders
153
     * @return string
154
     */
155
    function request($url, $method, array $queryData, $postData, $contentType = null, array $arrHeaders = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
156
        $this->_header = null;
157
        $header = $arrHeaders ?: array();
158
        $header[] = sprintf('Host: %s', parse_url($url, PHP_URL_HOST));
159
        if ($this->_accept && !isset($header['Accept']))
160
            $header[] = 'Accept: '.$this->_accept;
161
        if ($queryData) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $queryData of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
162
            $url = rtrim($url, '?');
163
            $url .= '?'.http_build_query($queryData);
164
        }
165
        if ($contentType) {
166
            $header[] = 'Content-Type: '.$contentType;
167
        }
168
        if ($postData) {
169
            if (is_array($postData)) {
170
                $postData = http_build_query($postData);
171
            } else if (is_object($postData)) {
172
                $postData = urlencode(json_encode($postData));
173
            } else if (!$contentType) {
174
                $postData = urlencode((string)$postData);
175
            } else {
176
                $postData = (string)$postData;
177
            }
178
            curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $postData);
179
            $header[] = 'Content-Length: '.strlen($postData);
180
            $header[] = 'Content-Type: '.($contentType ?: ContentType::FORM_URLENCODED);
181
        }
182
        curl_setopt($this->_curl, CURLOPT_URL, $url);
183
        curl_setopt($this->_curl, CURLOPT_CUSTOMREQUEST, $method);
184
        curl_setopt($this->_curl, CURLOPT_HEADER, 1);
185
        curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $header);
186
        curl_setopt($this->_curl, CURLOPT_CONNECTTIMEOUT_MS, $this->_timeout_ms ?: 10000);
187
        $response = curl_exec($this->_curl);
188
        $header_size = curl_getinfo($this->_curl, CURLINFO_HEADER_SIZE);
189
        $this->_header = substr($response, 0, $header_size);
190
        $body = substr($response, $header_size);
191
        $this->_statusCode = curl_getinfo($this->_curl, CURLINFO_HTTP_CODE);
192
        $this->_errorText = curl_error($this->_curl);
193
        return $body;
194
    }
195
196
}
197