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.
Test Failed
Push — master ( 86daef...c5fc1e )
by sunsky
02:09
created

Request::head()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 *
4
 * @author  [email protected] [email protected]
5
 * Date: 2017/6/16
6
 * Time: 10:02
7
 * @version $Id: $
8
 * @since 1.0
9
 * @copyright Sina Corp.
10
 */
11
12
namespace MultiHttp;
13
14
use MultiHttp\Exception\InvalidArgumentException;
15
16
class Request extends Http {
17
	protected static $curlAlias = array(
18
		'url'             => 'CURLOPT_URL',
19
		'uri'             => 'CURLOPT_URL',
20
		'debug'           => 'CURLOPT_VERBOSE',//for debug verbose
21
		'method'          => 'CURLOPT_CUSTOMREQUEST',
22
		'data'            => 'CURLOPT_POSTFIELDS', // array or string , file begin with '@'
23
		'ua'              => 'CURLOPT_USERAGENT',
24
		'timeout'         => 'CURLOPT_TIMEOUT', // (secs) 0 means indefinitely
25
		'connect_timeout' => 'CURLOPT_CONNECTTIMEOUT',
26
		'referer'         => 'CURLOPT_REFERER',
27
		'binary'          => 'CURLOPT_BINARYTRANSFER',
28
		'port'            => 'CURLOPT_PORT',
29
		'header'          => 'CURLOPT_HEADER', // TRUE:include header
30
		'headers'         => 'CURLOPT_HTTPHEADER', // array
31
		'download'        => 'CURLOPT_FILE', // writing file stream (using fopen()), default is STDOUT
32
		'upload'          => 'CURLOPT_INFILE', // reading file stream
33
		'transfer'        => 'CURLOPT_RETURNTRANSFER', // TRUE:return string; FALSE:output directly (curl_exec)
34
		'follow_location' => 'CURLOPT_FOLLOWLOCATION',
35
		'timeout_ms'      => 'CURLOPT_TIMEOUT_MS', // milliseconds,  libcurl version > 7.36.0 ,
36
	);
37
	public $curlHandle;
38
    protected $options = array(
39
        'CURLOPT_MAXREDIRS' => 10,
40
        'header' => true,
41
        'method' => self::GET,
42
        'transfer' => true,
43
        'follow_location' => true,
44
        'timeout' => 0);
45
    protected $endCallback;
46
	protected $withURIQuery;
47
	protected static $logger;
48
	protected $uri;
49 2
50
	protected function __construct() {
51 2
52
	}
53 2
54 2
	public static function create() {
55
		return new self;
56
	}
57 1
58 1
	public function endCallback() {
59
		return $this->endCallback;
60
	}
61 2
62 2
	public function hasEndCallback() {
63
		return isset($this->endCallback);
64
	}
65 2
66 2
	public function onEnd(callable$callback) {
67
		if (!is_callable($callback)) {throw new InvalidArgumentException('callback not is callable :'.print_r(callback, 1));
68
		}
69 2
70 2
		$this->endCallback = $callback;
71
		return $this;
72
	}
73 2
74 2
	public function getURI() {
75
		return $this->uri;
76
	}
77
78
	/**
79
	 * @param $field alias or field name
80
	 * @return bool|mixed
81 2
	 */
82
	public function getIni($field) {
83
		$alias = self::optionAlias($field);
84 2
//		if (null === ($rawField = constant($alias))) {throw new InvalidArgumentException('field is invalid');
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
85 2
//		}
86
		return isset($this->options[$alias])?$this->options[$alias]:false;
87
	}
88 2
89
90
	public function addQuery($data) {
91
		if (!empty($data)) {
92
			if (is_array($data)) {
93
				$this->withURIQuery = http_build_query($data);
94
			} else if (is_string($data)) {
95 1
				$this->withURIQuery = $data;
96 1
			} else {
97 1
				throw new InvalidArgumentException('data must be array or string');
98 1
			}
99 1
		}
100 1
		return $this;
101
	}
102
103
	public function post($uri, array $payload = array(), array $options = array()) {
104
		return $this->ini(Http::POST, $uri, $payload, $options);
105 1
	}
106
107
	protected function ini($method, $url, array $data = array(), array $options = array()) {
108 1
		$options = array('url' => $url, 'method' => $method, 'data' => $data)+$options;
109 1
		$this->addOptions($options);
110
111
		return $this;
112 2
	}
113 2
114 2
	public function addOptions(array $options = array()) {
115
		$this->options = $options+$this->options;
116 2
        $this->uri = $this->options['url'];
117
        return $this;
118
	}
119 2
120 2
	/*  no body  */
121 2
122
	function put($uri, array $payload = array(), array $options = array()) {
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
		return $this->ini(Http::PUT, $uri, $payload, $options);
124 2
	}
125 2
126
	function patch($uri, array $payload = array(), array $options = array()) {
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...
127 2
		return $this->ini(Http::PATCH, $uri, $payload, $options);
128 1
	}
129 1
130
	public function get($uri, array $options = array()) {
131 2
		return $this->ini(Http::GET, $uri, array(), $options);
132 2
	}
133 2
134
	function options($uri, array $options = array()) {
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...
135
		return $this->ini(Http::OPTIONS, $uri, array(), $options);
136 2
	}
137
138
	function head($uri, array $options = array()) {
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...
139
		return $this->ini(Http::HEAD, $uri, array('CURLOPT_NOBODY' => true), $options);
140
	}
141
142
	function delete($uri, array $options = array()) {
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...
143
		return $this->ini(Http::DELETE, $uri, array(), $options);
144
	}
145
146
	function trace($uri, array $options = array()) {
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...
147
		return $this->ini(Http::TRACE, $uri, array(), $options);
148
	}
149 1
150 1
	/**
151
	 * @return Response
152
	 */
153 1
	public function send() {
154 1
        $this->applyOptions();
155
		$response = $this->makeResponse();
156
		if ($this->endCallback) {
157
			$func = $this->endCallback;
158
			$func($response);
159
		}
160
		return $response;
161
	}
162
163
	public function applyOptions() {
164
		$curl             = curl_init();
165 2
		$this->curlHandle = $curl;
166 2
		$this->prepare();
167
		return $this;
168
	}
169
170
	protected function prepare() {
171
        if (empty($this->options['url'])) {
172 1
            throw new InvalidArgumentException('url can not empty');
173 1
        }
174 1
175 1
        if (isset($this->options['data'])) {
176 1
            $this->options['data'] = is_array($this->options['data'])?http_build_query($this->options['data']):$this->options['data'];//for better compatibility
177 1
        }
178
        if (isset($this->withURIQuery)) {
179 1
            $this->options['url'] .= strpos($this->options['url'], '?') === FALSE?'?':'&';
180
            $this->options['url'] .= $this->withURIQuery;
181
        }
182 2
        if (isset($this->options['callback'])) {
183 2
            $this->onEnd($this->options['callback']);
184 2
            unset($this->options['callback']);
185 2
        }
186 2
		//swap ip and host
187
		if (!empty($this->options['ip'])) {
188
			$matches = array();
189 2
			preg_match('/\/\/([^\/]+)/', $this->options['url'], $matches);
190
			$host = $matches[1];
191 2
			if (empty($this->options['headers']) || !is_array($this->options['headers'])) {
192 1
				$this->options['headers'] = array('Host: '.$host);
193 1
			} else {
194 1
				$this->options['headers'][] = 'Host: '.$host;
195 1
			}
196 1
			$this->options['url'] = preg_replace('/\/\/([^\/]+)/', '//'.$this->options['ip'], $this->options['url']);
197
			unset($this->options['ip']);
198
			unset($host);
199
		}
200 1
		//process version
201 1
		if (!empty($this->options['http_version'])) {
202 1
			$version                                                             = $this->options['http_version'];
203
			if ($version == '1.0') {$this->options['CURLOPT_HTTP_VERSION']       = CURLOPT_HTTP_VERSION_1_0;
204
			} elseif ($version == '1.1') {$this->options['CURLOPT_HTTP_VERSION'] = CURLOPT_HTTP_VERSION_1_1;
205 2
			}
206
207
			unset($version);
208
		}
209
210
		//convert secs to milliseconds
211
		if (defined('CURLOPT_TIMEOUT_MS')) {
212
			if (!isset($this->options['timeout_ms'])) {
213
				$this->options['timeout_ms'] = intval($this->options['timeout']*1000);
214
			} else {
215 2
				$this->options['timeout_ms'] = intval($this->options['timeout_ms']);
216 2
			}
217 2
		}
218
219 1
220
		$cURLOptions = self::filterAndRaw($this->options);
221
222
        curl_setopt_array($this->curlHandle,  $cURLOptions);
223 2
224 2
		return $this;
225
	}
226 2
227
	protected static function filterAndRaw(array &$options) {
228
		$opts = array();
229 2
		foreach ($options as $key => $val) {
230
			$alias = self::optionAlias($key);
231
            $options[$alias] = $val;
232 2
            if ($alias) {$opts[constant($alias)] = $val;
233 2
            }
234 2
            unset($options[$key]);
235 2
        }
236 2
		return $opts;
237 2
	}
238
239
	/**
240 2
	 * @param $key
241 2
	 * @return mixed
242
	 */
243
	protected static function optionAlias($key) {
244
		$alias = false;
245
		if (isset(self::$curlAlias[$key])) {
246
			$alias = self::$curlAlias[$key];
247 2
		} elseif ((substr($key, 0, strlen('CURLOPT_')) == 'CURLOPT_') && defined($key)) {
248 2
			$alias = $key;
249 2
		}
250 2
		return $alias;
251 2
	}
252 2
	public function makeResponse($isMultiCurl = false) {
253
		$body     = $isMultiCurl?curl_multi_getcontent($this->curlHandle):curl_exec($this->curlHandle);
254 2
		$info     = curl_getinfo($this->curlHandle);
255
		$errno    = curl_errno($this->curlHandle);
256 2
		$error    = curl_error($this->curlHandle);
257 2
        $response = Response::create($this, $body, $info, $errno, $error);
258 2
        self::log($response);
259 2
		return $response;
260 2
	}
261 2
262 2
    private static function log(Response $response)
263
    {
264
        if (is_null(self::$logger)) {
265
            return;
266
        }
267
        if($response->hasErrors()){
268
            self::$logger->error($response->request->getURI() . "\t" . $response->error, array(
269
                'response' => print_r($response,1),
270
            ));
271
        }
272
273
    }
274
275
    public static function setLogger($logger)
276
    {
277
        self::$logger = $logger;
278
    }
279
}
280