GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 3758f0...0a4cf0 )
by Dirk
07:13 queued 04:47
created

CurlBuilder   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 3.57%

Importance

Changes 12
Bugs 6 Features 3
Metric Value
wmc 26
c 12
b 6
f 3
lcom 1
cbo 0
dl 0
loc 241
ccs 3
cts 84
cp 0.0357
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A create() 0 4 1
A execute() 0 4 1
A hasErrors() 0 4 1
A getErrors() 0 4 1
A getErrorNumber() 0 4 1
A getInfo() 0 4 1
A getHeaders() 0 4 1
A close() 0 4 1
A setOption() 0 6 1
A setOptions() 0 6 1
A parseHeaders() 0 12 3
C execFollow() 0 69 12
1
<?php
2
/**
3
 * Copyright 2015 Dirk Groenen
4
 *
5
 * (c) Dirk Groenen <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace DirkGroenen\Pinterest\Utils;
12
13
class CurlBuilder {
14
15
    /**
16
     * Contains the curl instance
17
     *
18
     * @var resource
19
     */
20
    private $curl;
21
22
    /**
23
     * Array containing headers from last performed request
24
     *
25
     * @var array
26
     */
27
    private $headers;
28
29
    /**
30
     * Constructor
31
     */
32 37
    public function __construct()
33
    {
34 37
        $this->curl = curl_init();
35 37
    }
36
37
    /**
38
     * Return a new instance of the CurlBuilder
39
     *
40
     * @access public
41
     * @return CurlBuilder
42
     */
43
    public function create()
44
    {
45
        return new self();
46
    }
47
48
    /**
49
     * Sets an option in the curl instance
50
     *
51
     * @access public
52
     * @param  string   $option
53
     * @param  false|string    $value
54
     * @return $this
55
     */
56
    public function setOption($option, $value)
57
    {
58
        curl_setopt($this->curl, $option, $value);
59
60
        return $this;
61
    }
62
63
    /**
64
     * Sets multiple options at the same time
65
     *
66
     * @access public
67
     * @param  array   $options
68
     * @return $this
69
     */
70
    public function setOptions(array $options = [])
71
    {
72
        curl_setopt_array($this->curl, $options);
73
74
        return $this;
75
    }
76
77
    /**
78
     * Execute the curl request
79
     *
80
     * @access public
81
     * @return false|string
82
     */
83
    public function execute()
84
    {
85
        return $this->execFollow();
86
    }
87
88
    /**
89
     * Check if the curl request ended up with errors
90
     *
91
     * @access public
92
     * @return integer
93
     */
94
    public function hasErrors()
95
    {
96
        return curl_errno($this->curl);
97
    }
98
99
    /**
100
     * Get curl errors
101
     *
102
     * @access public
103
     * @return string
104
     */
105
    public function getErrors()
106
    {
107
        return curl_error($this->curl);
108
    }
109
110
    /**
111
     * Get last curl error number
112
     *
113
     * @access public
114
     * @return int
115
     */
116
    public function getErrorNumber()
117
    {
118
        return curl_errno($this->curl);
119
    }
120
121
    /**
122
     * Get curl info key
123
     *
124
     * @access public
125
     * @param  string  $key
126
     * @return string
127
     */
128
    public function getInfo($key)
129
    {
130
        return curl_getinfo($this->curl, $key);
131
    }
132
133
    /**
134
     * Get headers
135
     *
136
     * @access public
137
     * @return string
138
     */
139
    public function getHeaders()
140
    {
141
        return $this->headers;
142
    }
143
144
    /**
145
     * Close the curl resource
146
     *
147
     * @access public
148
     * @return void
149
     */
150
    public function close()
151
    {
152
        curl_close($this->curl);
153
    }
154
155
    /**
156
     * Parse string headers into array
157
     *
158
     * @access private
159
     * @param string $headers
160
     * @return array
161
     */
162
    private function parseHeaders($headers) {
163
        $result = array();
164
        foreach (explode("\n", $headers) as $row) {
165
            $header = explode(':', $row, 2);
166
            if (count($header) == 2) {
167
                $result[$header[0]] = trim($header[1]);
168
            } else {
169
                $result[] = $header[0];
170
            }
171
        }
172
        return $result;
173
    }
174
175
    /**
176
     * Function which acts as a replacement for curl's default
177
     * FOLLOW_LOCATION option, since that gives errors when
178
     * combining it with open basedir.
179
     *
180
     * @see http://slopjong.de/2012/03/31/curl-follow-locations-with-safe_mode-enabled-or-open_basedir-set/
181
     * @access private
182
     * @return false|string
183
     */
184
    private function execFollow() {
185
        $mr = 5;
186
        $body = null;
187
188
        if (ini_get("open_basedir") == "" && ini_get("safe_mode" == "Off")) {
189
            $this->setOptions(array(
190
                CURLOPT_FOLLOWLOCATION => $mr > 0,
191
                CURLOPT_MAXREDIRS => $mr
192
            ));
193
        } else {
194
            $this->setOption(CURLOPT_FOLLOWLOCATION, false);
195
196
            if ($mr > 0) {
197
                $original_url = $this->getInfo(CURLINFO_EFFECTIVE_URL);
198
                $newurl = $original_url;
199
200
                $this->setOptions(array(
201
                    CURLOPT_HEADER => true,
202
                    CURLOPT_FORBID_REUSE => false
203
                ));
204
205
                do {
206
                    $this->setOption(CURLOPT_URL, $newurl);
207
208
                    $response = curl_exec($this->curl);
209
210
                    $header_size = $this->getInfo(CURLINFO_HEADER_SIZE);
211
                    $header = substr($response, 0, $header_size);
212
                    $body = substr($response, $header_size);
213
214
                    if ($this->getErrorNumber()) {
215
                        $code = 0;
216
                    } else {
217
                        $code = $this->getInfo(CURLINFO_HTTP_CODE);
218
219
                        if ($code == 301 || $code == 302) {
220
                            preg_match('/Location:(.*?)\n/i', $header, $matches);
221
                            $newurl = trim(array_pop($matches));
222
                        } else {
223
                            $code = 0;
224
                        }
225
                    }
226
                } while ($code && --$mr);
227
228
                if (!$mr) {
229
                    if ($mr === null) {
230
                        trigger_error('Too many redirects.', E_USER_WARNING);
231
                    }
232
233
                    return false;
234
                }
235
236
                $this->headers = $this->parseHeaders($header);
237
            }
238
        }
239
240
        if (!$body) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $body of type string|null is loosely compared to false; 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...
241
            $this->setOption(CURLOPT_HEADER, true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a false|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
242
            $response = $this->execute();
243
244
            $header_size = $this->getInfo(CURLINFO_HEADER_SIZE);
245
            $header = substr($response, 0, $header_size);
246
            $body = substr($response, $header_size);
247
248
            $this->headers = $this->parseHeaders($header);
249
        }
250
251
        return $body;
252
    }
253
}