Passed
Branch master (c2899a)
by
unknown
04:47
created

ResponseAbstract::response_headers_array()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
/**
3
 * Class ResponseAbstract
4
 *
5
 * @filesource   ResponseAbstract.php
6
 * @created      06.04.2016
7
 * @package      chillerlan\TinyCurl
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2015 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\TinyCurl;
14
15
use stdClass;
16
17
/**
18
 * @property mixed body
19
 * @property mixed error
20
 * @property mixed headers
21
 * @property mixed headers_array
22
 * @property mixed info
23
 * @property mixed json
24
 * @property mixed json_array
25
 */
26
abstract class ResponseAbstract implements ResponseInterface{
27
28
	/**
29
	 * @var resource
30
	 */
31
	protected $curl;
32
33
	/**
34
	 * @var \stdClass
35
	 */
36
	protected $curl_info;
37
38
	/**
39
	 * @var \stdClass
40
	 */
41
	protected $response_headers;
42
43
	/**
44
	 * @var \stdClass
45
	 */
46
	protected $response_error;
47
48
	/**
49
	 * @var mixed
50
	 */
51
	protected $response_body;
52
53
	/**
54
	 * Response constructor.
55
	 *
56
	 * @param resource $curl
57
	 *
58
	 * @throws \chillerlan\TinyCurl\ResponseException
59
	 */
60
	public function __construct($curl){
61
62
		if(!is_resource($curl)){
63
			throw new ResponseException('no cURL handle given');
64
		}
65
66
		$this->curl             = $curl;
67
		$this->curl_info        = new stdClass;
68
		$this->response_error   = new stdClass;
69
		$this->response_headers = new stdClass;
70
71
		$this->exec();
72
	}
73
74
	/**
75
	 * @param string $property
76
	 *
77
	 * @return mixed
78
	 */
79
	public function __get($property){
80
81
		switch($property){
82
			case 'body':
83
				return $this->getBody();
84
			case 'info':
85
				return $this->curl_info;
86
			case 'json':
87
				return json_decode($this->response_body);
88
			case 'json_array':
89
				return json_decode($this->response_body, true);
90
			case 'error':
91
				return $this->response_error;
92
			case 'headers':
93
				return $this->response_headers;
94
			case 'headers_array':
95
				return $this->response_headers_array($this->response_headers);
96
			default:
97
				return false;
98
		}
99
100
	}
101
102
	/**
103
	 * executes the cURL call, fills self::$response_body and calls self::getInfo()
104
	 */
105
	abstract protected function exec();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
106
107
	/**
108
	 * @param resource $curl
109
	 * @param string   $header_line
110
	 *
111
	 * @return int
112
	 *
113
	 * @link http://php.net/manual/function.curl-setopt.php CURLOPT_HEADERFUNCTION
114
	 */
115
	protected function headerLine(/** @noinspection PhpUnusedParameterInspection */$curl, $header_line){
116
		$header = explode(':', $header_line, 2);
117
118
		if(count($header) === 2){
119
			$this->response_headers->{trim(strtolower($header[0]))} = trim($header[1]);
120
		}
121
		elseif(substr($header_line, 0, 4) === 'HTTP'){
122
			$status = explode(' ', $header_line, 3);
123
124
			$this->response_headers->httpversion = explode('/', $status[0], 2)[1];
125
			$this->response_headers->statuscode  = intval($status[1]);
126
			$this->response_headers->statustext  = trim($status[2]);
127
		}
128
129
		return strlen($header_line);
130
	}
131
132
	/**
133
	 * @return \stdClass
134
	 */
135
	protected function getBody(){
136
		$body = new stdClass;
137
138
		$body->content      = $this->response_body;
139
		$body->length       = strlen($this->response_body);
140
		$body->content_type = $this->response_headers->content_type ?? $this->curl_info->content_type ?? null;
141
142
		return $body;
143
	}
144
145
	/**
146
	 *
147
	 */
148
	protected function getInfo(){
149
		$curl_info = curl_getinfo($this->curl);
150
151
		if(is_array($curl_info)){
152
			foreach($curl_info as $key => $value){
153
				$this->curl_info->{$key} = $value;
154
			}
155
		}
156
157
		$this->response_error->code    = curl_errno($this->curl);
158
		$this->response_error->message = curl_error($this->curl);
159
		$this->response_error->version = curl_version();
160
	}
161
162
	/**
163
	 * @param \stdClass $response_headers
164
	 *
165
	 * @return array
166
	 */
167
	protected function response_headers_array(\stdClass $response_headers):array {
168
		$headers = [];
169
170
		foreach($response_headers as $key => $value){
1 ignored issue
show
Bug introduced by
The expression $response_headers of type object<stdClass> is not traversable.
Loading history...
171
			$headers[$key] = $value;
172
		}
173
174
		return $headers;
175
	}
176
177
}
178