1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Zmaglica\RickAndMortyApiWrapper\Api; |
4
|
|
|
|
5
|
|
|
abstract class AbstractApi |
6
|
|
|
{ |
7
|
|
|
protected $client; |
8
|
|
|
protected $uri; |
9
|
|
|
protected $ids = null; |
10
|
|
|
protected $page = 1; |
11
|
|
|
protected $arguments = []; |
12
|
|
|
protected $supportedFilters = []; |
13
|
|
|
protected $model; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Send HTTP Request to API |
17
|
|
|
* |
18
|
|
|
* @param null $uri |
19
|
|
|
* @param null $arguments |
20
|
|
|
* @param bool $async |
21
|
|
|
* @return mixed |
22
|
|
|
*/ |
23
|
|
|
public function sendRequest($uri = null, $arguments = null, $async = false) |
24
|
|
|
{ |
25
|
|
|
/* |
26
|
|
|
* For custom uri |
27
|
|
|
*/ |
28
|
|
|
if ($uri === null) { |
29
|
|
|
$uri = $this->uri; |
30
|
|
|
} |
31
|
|
|
/* |
32
|
|
|
* For raw API requests |
33
|
|
|
*/ |
34
|
|
|
if ($arguments === null) { |
35
|
|
|
$arguments = $this->arguments; |
36
|
|
|
} |
37
|
|
|
$promise = $this->client->getAsync($uri, $arguments); |
|
|
|
|
38
|
|
|
if (!$async) { |
39
|
|
|
$response = $promise->wait(); |
40
|
|
|
|
41
|
|
|
return new $this->model($response, $this); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
return $promise; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
public function get($ids = null) |
48
|
|
|
{ |
49
|
|
|
$uri = $this->getUri($ids ?? $this->ids); |
50
|
|
|
|
51
|
|
|
return $this->sendRequest($uri); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
public function all() |
55
|
|
|
{ |
56
|
|
|
return $this->sendRequest($this->getUri()); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param array $params |
61
|
|
|
* @return $this |
62
|
|
|
*/ |
63
|
|
|
public function where(array $params) |
64
|
|
|
{ |
65
|
|
|
if (!isset($this->arguments['query'])) { |
66
|
|
|
$this->arguments['query'] = []; |
67
|
|
|
} |
68
|
|
|
if (isset($params['id'])) { |
69
|
|
|
$this->ids = $params['id']; |
70
|
|
|
/* |
71
|
|
|
* Remove id param because id doesn't exists in filtering |
72
|
|
|
*/ |
73
|
|
|
unset($params['id']); |
74
|
|
|
} |
75
|
|
|
$this->arguments['query'] = array_merge($this->arguments['query'], $params); |
76
|
|
|
|
77
|
|
|
return $this; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* You can set ids and add additional filters and then execute API request |
82
|
|
|
* |
83
|
|
|
* @param $ids |
84
|
|
|
* @return AbstractApi |
85
|
|
|
*/ |
86
|
|
|
public function whereId($ids) |
87
|
|
|
{ |
88
|
|
|
return $this->where(['id' => $ids]); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Send raw uri to API |
93
|
|
|
* @param string $uri |
94
|
|
|
*/ |
95
|
|
|
public function raw(string $uri) |
96
|
|
|
{ |
97
|
|
|
$this->sendRequest($uri, []); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Clear all arguments and ids |
102
|
|
|
* |
103
|
|
|
* @return $this |
104
|
|
|
*/ |
105
|
|
|
public function clear() |
106
|
|
|
{ |
107
|
|
|
$this->ids = null; |
108
|
|
|
$this->arguments['query'] = []; |
109
|
|
|
|
110
|
|
|
return $this; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Get arguments/filters for API |
115
|
|
|
* @return array |
116
|
|
|
*/ |
117
|
|
|
public function getArguments() |
118
|
|
|
{ |
119
|
|
|
return $this->arguments; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Set page for request |
124
|
|
|
* |
125
|
|
|
* @param int $page |
126
|
|
|
* @return $this |
127
|
|
|
*/ |
128
|
|
|
public function setPage(int $page) |
129
|
|
|
{ |
130
|
|
|
$this->page = $page; |
131
|
|
|
$this->where(['page' => $page]); |
132
|
|
|
|
133
|
|
|
return $this; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Increment page to simulate pagination |
138
|
|
|
* @return $this |
139
|
|
|
*/ |
140
|
|
|
public function nextPage() |
141
|
|
|
{ |
142
|
|
|
$this->page++; |
143
|
|
|
$this->where(['page' => $this->page]); |
144
|
|
|
|
145
|
|
|
return $this; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Decrement page to simulate pagination |
150
|
|
|
* @return $this |
151
|
|
|
*/ |
152
|
|
|
public function previousPage() |
153
|
|
|
{ |
154
|
|
|
/* |
155
|
|
|
* Minimum page number is 1 |
156
|
|
|
*/ |
157
|
|
|
if ($this->page < 2) { |
158
|
|
|
$this->page--; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
$this->where(['page' => $this->page]); |
162
|
|
|
|
163
|
|
|
return $this; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Parse ids and prepare uri |
168
|
|
|
* @param null $ids |
169
|
|
|
* @return string |
170
|
|
|
*/ |
171
|
|
|
public function getUri($ids = null) |
172
|
|
|
{ |
173
|
|
|
$this->ids = $ids ?? $this->ids; |
174
|
|
|
if ($this->ids) { |
175
|
|
|
if (is_array($this->ids)) { |
176
|
|
|
$uri = $this->uri . '/' . implode(',', $this->ids); |
177
|
|
|
} else { |
178
|
|
|
$uri = $this->uri . '/' . $this->ids; |
179
|
|
|
} |
180
|
|
|
} else { |
181
|
|
|
$uri = $this->uri; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
return $uri; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Used for nesting where function with API filter values |
189
|
|
|
* Example: whereName('Rick') will internally call where function with argument ['name' => 'Rick'] |
190
|
|
|
* @param $name |
191
|
|
|
* @param $arguments |
192
|
|
|
* @return $this |
193
|
|
|
*/ |
194
|
|
|
public function __call($name, $arguments) |
195
|
|
|
{ |
196
|
|
|
if (strpos($name, 'where') !== 0) { |
197
|
|
|
throw new \BadFunctionCallException(); |
198
|
|
|
} |
199
|
|
|
$filterValue = strtolower(substr($name, 5)); |
200
|
|
|
if (!in_array($filterValue, $this->supportedFilters)) { |
201
|
|
|
throw new \BadFunctionCallException(); |
202
|
|
|
} |
203
|
|
|
if (count($arguments) === 1) { |
204
|
|
|
$arguments = $arguments[0]; |
205
|
|
|
} |
206
|
|
|
$this->where([$filterValue => $arguments]); |
207
|
|
|
|
208
|
|
|
return $this; |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
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.