1 | <?php |
||
2 | /** |
||
3 | * ActiveRecord for API |
||
4 | * |
||
5 | * @link https://github.com/hiqdev/yii2-hiart |
||
6 | * @package yii2-hiart |
||
7 | * @license BSD-3-Clause |
||
8 | * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/) |
||
9 | */ |
||
10 | |||
11 | namespace hiqdev\hiart; |
||
12 | |||
13 | abstract class AbstractRequest implements RequestInterface |
||
14 | { |
||
15 | /** |
||
16 | * @var string response implementation to be specified in concrete implementation |
||
17 | */ |
||
18 | protected $responseClass; |
||
19 | |||
20 | /** |
||
21 | * @var string request handler implementation to be specified in concrete implementation |
||
22 | */ |
||
23 | protected $handlerClass; |
||
24 | |||
25 | /** |
||
26 | * @var QueryBuilderInterface |
||
27 | */ |
||
28 | protected $builder; |
||
29 | |||
30 | /** |
||
31 | * @var Query |
||
32 | */ |
||
33 | protected $query; |
||
34 | |||
35 | /** |
||
36 | * @var string Connection name |
||
37 | */ |
||
38 | protected $dbname; |
||
39 | |||
40 | /** |
||
41 | * @var array request method |
||
42 | */ |
||
43 | protected $method; |
||
44 | protected $uri; |
||
45 | protected $headers = []; |
||
46 | protected $body; |
||
47 | protected $version; |
||
48 | |||
49 | protected $isBuilt; |
||
50 | protected array $parts = []; |
||
51 | protected $fullUri; |
||
52 | |||
53 | abstract public function send($options = []); |
||
54 | |||
55 | 3 | public function __construct(QueryBuilderInterface $builder, Query $query) |
|
56 | { |
||
57 | 3 | $this->builder = $builder; |
|
58 | 3 | $this->query = $query; |
|
59 | 3 | } |
|
60 | |||
61 | public function getDbname() |
||
62 | { |
||
63 | return $this->dbname; |
||
64 | } |
||
65 | |||
66 | 2 | public function getMethod() |
|
67 | { |
||
68 | 2 | return $this->method; |
|
69 | } |
||
70 | |||
71 | public function getUri() |
||
72 | { |
||
73 | return $this->uri; |
||
74 | } |
||
75 | |||
76 | 2 | public function getFullUri() |
|
77 | { |
||
78 | 2 | if ($this->fullUri === null) { |
|
79 | 2 | $this->fullUri = $this->createFullUri(); |
|
80 | } |
||
81 | |||
82 | 2 | return $this->fullUri; |
|
83 | } |
||
84 | |||
85 | 2 | public function createFullUri() |
|
86 | { |
||
87 | 2 | return ($this->isFullUri($this->uri) ? '' : $this->getDb()->getBaseUri()) . $this->uri; |
|
88 | } |
||
89 | |||
90 | 2 | public function isFullUri($uri) |
|
91 | { |
||
92 | 2 | return preg_match('/^https?:\\/\\//i', (string)$uri); |
|
93 | } |
||
94 | |||
95 | 2 | public function getHeaders() |
|
96 | { |
||
97 | 2 | return $this->headers; |
|
98 | } |
||
99 | |||
100 | public function getBody() |
||
101 | { |
||
102 | return $this->body; |
||
103 | } |
||
104 | |||
105 | 2 | public function getVersion() |
|
106 | { |
||
107 | 2 | return $this->version; |
|
108 | } |
||
109 | |||
110 | /** |
||
111 | * @return Query |
||
112 | */ |
||
113 | 2 | public function getQuery() |
|
114 | { |
||
115 | 2 | return $this->query; |
|
116 | } |
||
117 | |||
118 | 2 | public function build() |
|
119 | { |
||
120 | 2 | if ($this->isBuilt === null) { |
|
121 | 2 | if (!empty($this->query)) { |
|
122 | 2 | $this->updateFromQuery(); |
|
123 | } |
||
124 | 2 | $this->isBuilt = true; |
|
125 | } |
||
126 | 2 | } |
|
127 | |||
128 | 2 | protected function updateFromQuery() |
|
129 | { |
||
130 | 2 | $this->builder->prepare($this->query); |
|
131 | |||
132 | 2 | $this->buildDbname(); |
|
133 | 2 | $this->buildAuth(); |
|
134 | 2 | $this->buildMethod(); |
|
135 | 2 | $this->buildUri(); |
|
136 | 2 | $this->buildQueryParams(); |
|
137 | 2 | $this->buildHeaders(); |
|
138 | 2 | $this->buildBody(); |
|
139 | 2 | $this->buildFormParams(); |
|
140 | 2 | $this->buildProtocolVersion(); |
|
141 | 2 | } |
|
142 | |||
143 | 2 | protected function buildDbname() |
|
144 | { |
||
145 | 2 | $this->dbname = $this->getDb()->name; |
|
146 | 2 | } |
|
147 | |||
148 | 2 | protected function buildAuth() |
|
149 | { |
||
150 | 2 | $this->builder->buildAuth($this->query); |
|
151 | 2 | } |
|
152 | |||
153 | 2 | protected function buildMethod() |
|
154 | { |
||
155 | 2 | $this->method = $this->builder->buildMethod($this->query) ?: 'GET'; |
|
0 ignored issues
–
show
|
|||
156 | 2 | } |
|
157 | |||
158 | 2 | protected function buildUri() |
|
159 | { |
||
160 | 2 | $this->uri = $this->builder->buildUri($this->query); |
|
161 | 2 | } |
|
162 | |||
163 | 2 | protected function buildQueryParams() |
|
164 | { |
||
165 | 2 | $params = $this->builder->buildQueryParams($this->query); |
|
166 | 2 | if (is_array($params)) { |
|
167 | 2 | $params = http_build_query($params, '', '&'); |
|
168 | } |
||
169 | 2 | if (!empty($params)) { |
|
170 | $this->uri .= '?' . $params; |
||
171 | } |
||
172 | 2 | } |
|
173 | |||
174 | 2 | protected function buildHeaders() |
|
175 | { |
||
176 | 2 | $this->headers = $this->builder->buildHeaders($this->query); |
|
177 | 2 | if (empty($this->headers['User-Agent'])) { |
|
178 | 2 | $this->headers['User-Agent'] = $this->prepareUserAgent(); |
|
179 | } |
||
180 | 2 | } |
|
181 | |||
182 | 2 | protected function buildBody() |
|
183 | { |
||
184 | 2 | $this->body = $this->builder->buildBody($this->query); |
|
185 | 2 | } |
|
186 | |||
187 | 2 | protected function buildFormParams() |
|
188 | { |
||
189 | 2 | $this->setFormParams($this->builder->buildFormParams($this->query)); |
|
190 | 2 | } |
|
191 | |||
192 | 2 | protected function setFormParams($params) |
|
193 | { |
||
194 | 2 | if (!empty($params)) { |
|
195 | $this->body = is_array($params) ? http_build_query($params, '', '&') : $params; |
||
196 | $this->headers['Content-Type'] = 'application/x-www-form-urlencoded'; |
||
197 | } |
||
198 | 2 | } |
|
199 | |||
200 | 2 | protected function buildProtocolVersion() |
|
201 | { |
||
202 | 2 | $this->version = $this->builder->buildProtocolVersion($this->query) ?: '1.1'; |
|
203 | 2 | } |
|
204 | |||
205 | 2 | public function serialize(): string |
|
206 | { |
||
207 | 2 | return serialize($this->__serialize()); |
|
208 | } |
||
209 | |||
210 | public function __serialize(): array |
||
211 | { |
||
212 | return $this->getParts(); |
||
213 | } |
||
214 | |||
215 | public function unserialize(string $serialized): void |
||
216 | { |
||
217 | 2 | $this->__unserialize(unserialize($serialized)); |
|
218 | } |
||
219 | 2 | ||
220 | 2 | public function __unserialize(array $serialized): void |
|
221 | 2 | { |
|
222 | 2 | foreach ($serialized as $key => $value) { |
|
223 | $this->{$key} = $value; |
||
224 | } |
||
225 | } |
||
226 | 2 | ||
227 | public function getParts(): array |
||
228 | { |
||
229 | 2 | if (empty($this->parts)) { |
|
230 | $this->build(); |
||
231 | 2 | foreach (['dbname', 'method', 'uri', 'headers', 'body', 'version'] as $key) { |
|
232 | $this->parts[$key] = $this->{$key}; |
||
233 | } |
||
234 | } |
||
235 | |||
236 | return $this->parts; |
||
237 | } |
||
238 | |||
239 | public function isRaw() |
||
240 | { |
||
241 | return !empty($this->query->options['raw']); |
||
242 | } |
||
243 | |||
244 | public function getHandler() |
||
245 | { |
||
246 | $handler = $this->getDb()->getHandler(); |
||
247 | if ($handler === null) { |
||
248 | $handler = $this->createHandler(); |
||
249 | } |
||
250 | |||
251 | return $handler; |
||
252 | } |
||
253 | |||
254 | protected function createHandler() |
||
255 | { |
||
256 | 2 | $config = $this->prepareHandlerConfig($this->getDb()->config); |
|
257 | |||
258 | 2 | return new $this->handlerClass($config); |
|
259 | } |
||
260 | |||
261 | protected function prepareHandlerConfig($config) |
||
262 | { |
||
263 | return $config; |
||
264 | 2 | } |
|
265 | |||
266 | 2 | protected function prepareUserAgent() |
|
267 | { |
||
268 | return $this->getDb()->getUserAgent(); |
||
269 | } |
||
270 | |||
271 | /** |
||
272 | * @return AbstractConnection|ConnectionInterface |
||
273 | */ |
||
274 | public function getDb() |
||
275 | { |
||
276 | return isset($this->builder) ? $this->builder->db : AbstractConnection::getDb($this->dbname); |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * @param string $header |
||
281 | * @param string $value |
||
282 | * @return $this |
||
283 | */ |
||
284 | public function addHeader($header, $value) |
||
285 | { |
||
286 | if (!isset($this->headers[$header])) { |
||
287 | $this->headers[$header] = []; |
||
288 | } |
||
289 | |||
290 | $this->headers[$header][] = $value; |
||
291 | |||
292 | return $this; |
||
293 | } |
||
294 | |||
295 | /** |
||
296 | * {@inheritdoc} |
||
297 | * Should be declared abstract, but it is not supported in PHP5. |
||
298 | */ |
||
299 | public static function isSupported() |
||
300 | { |
||
301 | return false; |
||
302 | } |
||
303 | } |
||
304 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.