Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.89% |
88 / 99 |
|
85.71% |
12 / 14 |
CRAP | |
0.00% |
0 / 1 |
Http | |
88.89% |
88 / 99 |
|
85.71% |
12 / 14 |
63.78 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
setSendClient | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setFetchClient | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getSendClient | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFetchClient | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFetchedResult | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
hasFetchClient | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
send | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
getStates | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getStateById | |
66.67% |
10 / 15 |
|
0.00% |
0 / 1 |
19.26 | |||
getStateByModel | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
getStateByTimestamp | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
4 | |||
getStateByDate | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
6 | |||
getSnapshot | |
66.67% |
12 / 18 |
|
0.00% |
0 / 1 |
25.48 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (https://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@noladev.com> |
7 | * @copyright Copyright (c) 2009-2025 NOLA Interactive, LLC. |
8 | * @license https://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Audit\Adapter; |
15 | |
16 | use Pop\Http\Client; |
17 | |
18 | /** |
19 | * Auditor HTTP class |
20 | * |
21 | * @category Pop |
22 | * @package Pop\Audit |
23 | * @author Nick Sagona, III <dev@noladev.com> |
24 | * @copyright Copyright (c) 2009-2025 NOLA Interactive, LLC. |
25 | * @license https://www.popphp.org/license New BSD License |
26 | * @version 2.0.2 |
27 | */ |
28 | class Http extends AbstractAdapter |
29 | { |
30 | |
31 | /** |
32 | * Client to send the audit results |
33 | * @var ?Client |
34 | */ |
35 | protected ?Client $sendClient = null; |
36 | |
37 | /** |
38 | * Client to fetch the audit results |
39 | * @var ?Client |
40 | */ |
41 | protected ?Client $fetchClient = null; |
42 | |
43 | /** |
44 | * Constructor |
45 | * |
46 | * Instantiate the HTTP adapter object |
47 | * |
48 | * @param Client $sendClient |
49 | * @param ?Client $fetchClient |
50 | */ |
51 | public function __construct(Client $sendClient, ?Client $fetchClient = null) |
52 | { |
53 | $this->setSendClient($sendClient); |
54 | if ($fetchClient !== null) { |
55 | $this->setFetchClient($fetchClient); |
56 | } |
57 | } |
58 | |
59 | /** |
60 | * Set the send stream |
61 | * |
62 | * @param Client $sendClient |
63 | * @return Http |
64 | */ |
65 | public function setSendClient(Client $sendClient): Http |
66 | { |
67 | $this->sendClient = $sendClient; |
68 | return $this; |
69 | } |
70 | |
71 | /** |
72 | * Set the fetch stream |
73 | * |
74 | * @param Client $fetchClient |
75 | * @return Http |
76 | */ |
77 | public function setFetchClient(Client $fetchClient): Http |
78 | { |
79 | $this->fetchClient = $fetchClient; |
80 | return $this; |
81 | } |
82 | |
83 | /** |
84 | * Get the send stream |
85 | * |
86 | * @return Client |
87 | */ |
88 | public function getSendClient(): Client |
89 | { |
90 | return $this->sendClient; |
91 | } |
92 | |
93 | /** |
94 | * Get the fetch stream |
95 | * |
96 | * @return Client |
97 | */ |
98 | public function getFetchClient(): Client |
99 | { |
100 | return $this->fetchClient; |
101 | } |
102 | |
103 | /** |
104 | * Get the fetched result |
105 | * |
106 | * @return mixed |
107 | */ |
108 | public function getFetchedResult(): mixed |
109 | { |
110 | $resultResponse = null; |
111 | |
112 | if (($this->fetchClient->hasResponse()) && ($this->fetchClient->getResponse()->hasBody())) { |
113 | $resultResponse = $this->fetchClient->getResponse()->getParsedResponse(); |
114 | } |
115 | |
116 | return $resultResponse; |
117 | } |
118 | |
119 | /** |
120 | * Determine if the adapter has a fetch stream |
121 | * |
122 | * @return bool |
123 | */ |
124 | public function hasFetchClient(): bool |
125 | { |
126 | return ($this->fetchClient !== null); |
127 | } |
128 | |
129 | /** |
130 | * Send the results of the audit |
131 | * |
132 | * @throws Exception|Client\Exception|Client\Handler\Exception|\Pop\Http\Exception |
133 | * @return Client\Response |
134 | */ |
135 | public function send(): Client\Response |
136 | { |
137 | if ($this->action === null) { |
138 | throw new Exception('The model state differences have not been resolved.'); |
139 | } |
140 | if (($this->model === null) || ($this->modelId === null)) { |
141 | throw new Exception('The model has not been set.'); |
142 | } |
143 | |
144 | $this->sendClient->setData($this->prepareData()); |
145 | return $this->sendClient->send(); |
146 | } |
147 | |
148 | /** |
149 | * Get model states |
150 | * |
151 | * @param array $fields |
152 | * @return array |
153 | */ |
154 | public function getStates(array $fields = []): array |
155 | { |
156 | if (!empty($fields)) { |
157 | $this->fetchClient->setData($fields); |
158 | } |
159 | $this->fetchClient->send(); |
160 | |
161 | $results = $this->getFetchedResult(); |
162 | |
163 | return (is_array($results)) ? $results : []; |
164 | } |
165 | |
166 | /** |
167 | * Get model state by ID |
168 | * |
169 | * @param int|string $id |
170 | * @param bool $asQuery |
171 | * @return array |
172 | */ |
173 | public function getStateById(int|string $id, bool $asQuery = false): array |
174 | { |
175 | $origUrl = $this->fetchClient->getRequest()->getUri()->getFullUri(); |
176 | |
177 | if ($asQuery) { |
178 | $this->fetchClient->addData('id', $id); |
179 | } else { |
180 | $this->fetchClient->getRequest()->getUri()->setUri($origUrl . '/' . $id); |
181 | } |
182 | |
183 | $this->fetchClient->send(); |
184 | $parsedResult = $this->getFetchedResult(); |
185 | |
186 | $result = (is_array($parsedResult)) ? $parsedResult : [$parsedResult]; |
187 | |
188 | if (is_array($result) && !empty($result['old']) && is_string($result['old'])) { |
189 | if ((json_decode($result['old']) !== false) && (json_last_error() == JSON_ERROR_NONE)) { |
190 | $result['old'] = json_decode($result['old'], true); |
191 | } |
192 | } |
193 | if (is_array($result) && !empty($result['new']) && is_string($result['new'])) { |
194 | if ((json_decode($result['new']) !== false) && (json_last_error() == JSON_ERROR_NONE)) { |
195 | $result['new'] = json_decode($result['new'], true); |
196 | } |
197 | } |
198 | |
199 | $this->fetchClient->getRequest()->getUri()->setUri($origUrl); |
200 | |
201 | return $result; |
202 | } |
203 | |
204 | /** |
205 | * Get model state by model |
206 | * |
207 | * @param string $model |
208 | * @param int|string|null $modelId |
209 | * @return array |
210 | */ |
211 | public function getStateByModel(string $model, int|string|null $modelId = null): array |
212 | { |
213 | $fields = [ |
214 | 'filter' => [ |
215 | 'model = ' . $model |
216 | ] |
217 | ]; |
218 | |
219 | if ($modelId !== null) { |
220 | $fields['filter'][] = 'model_id = ' . $modelId; |
221 | } |
222 | |
223 | $this->fetchClient->setData($fields); |
224 | $this->fetchClient->send(); |
225 | |
226 | $results = $this->getFetchedResult(); |
227 | |
228 | return (is_array($results)) ? $results : []; |
229 | } |
230 | |
231 | /** |
232 | * Get model state by timestamp |
233 | * |
234 | * @param string $from |
235 | * @param ?string $backTo |
236 | * @return array |
237 | */ |
238 | public function getStateByTimestamp(string $from, ?string $backTo = null): array |
239 | { |
240 | $from = date('Y-m-d H:i:s', $from); |
241 | |
242 | if ($backTo !== null) { |
243 | $backTo = date('Y-m-d H:i:s', $backTo); |
244 | } |
245 | |
246 | $fields = [ |
247 | 'filter' => [ |
248 | 'timestamp <= ' . $from |
249 | ] |
250 | ]; |
251 | |
252 | if ($backTo !== null) { |
253 | $fields['filter'][] = 'timestamp >= ' . $backTo; |
254 | } |
255 | |
256 | $this->fetchClient->setData($fields); |
257 | $this->fetchClient->send(); |
258 | |
259 | $results = $this->getFetchedResult(); |
260 | |
261 | return (is_array($results)) ? $results : []; |
262 | } |
263 | |
264 | /** |
265 | * Get model state by date |
266 | * |
267 | * @param string $from |
268 | * @param ?string $backTo |
269 | * @return array |
270 | */ |
271 | public function getStateByDate(string $from, ?string $backTo = null): array |
272 | { |
273 | if (!str_contains($from, ' ')) { |
274 | $from .= ' 23:59:59'; |
275 | } |
276 | |
277 | if ($backTo !== null) { |
278 | if (!str_contains($backTo, ' ')) { |
279 | $backTo .= ' 00:00:00'; |
280 | } |
281 | } |
282 | |
283 | $fields = [ |
284 | 'filter' => [ |
285 | 'timestamp <= ' . $from |
286 | ] |
287 | ]; |
288 | |
289 | if ($backTo !== null) { |
290 | $fields['filter'][] = 'timestamp >= ' . $backTo; |
291 | } |
292 | |
293 | $this->fetchClient->setData($fields); |
294 | $this->fetchClient->send(); |
295 | |
296 | $results = $this->getFetchedResult(); |
297 | |
298 | return (is_array($results)) ? $results : []; |
299 | } |
300 | |
301 | /** |
302 | * Get model snapshot by ID |
303 | * |
304 | * @param int|string $id |
305 | * @param bool $post |
306 | * @return array |
307 | */ |
308 | public function getSnapshot(int|string $id, bool $post = false): array |
309 | { |
310 | $url = $this->fetchClient->getRequest()->getUri()->getFullUri(); |
311 | $this->fetchClient->getRequest()->getUri()->setUri($url . '/' . $id); |
312 | $this->fetchClient->send(); |
313 | |
314 | $parsedResult = $this->getFetchedResult(); |
315 | |
316 | $result = (is_array($parsedResult)) ? $parsedResult : [$parsedResult]; |
317 | |
318 | if (is_array($result) && !empty($result['old']) && is_string($result['old'])) { |
319 | if ((json_decode($result['old']) !== false) && (json_last_error() == JSON_ERROR_NONE)) { |
320 | $result['old'] = json_decode($result['old'], true); |
321 | } |
322 | } |
323 | if (is_array($result) && !empty($result['new']) && is_string($result['new'])) { |
324 | if ((json_decode($result['new']) !== false) && (json_last_error() == JSON_ERROR_NONE)) { |
325 | $result['new'] = json_decode($result['new'], true); |
326 | } |
327 | } |
328 | |
329 | $snapshot = []; |
330 | |
331 | if (!($post) && !empty($result['old'])) { |
332 | $snapshot = $result['old']; |
333 | } else if (($post) && !empty($result['new'])) { |
334 | $snapshot = $result['new']; |
335 | } |
336 | |
337 | $this->fetchClient->getRequest()->getUri()->setUri($url); |
338 | |
339 | return $snapshot; |
340 | } |
341 | |
342 | } |