Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
78 / 78 |
|
100.00% |
28 / 28 |
CRAP | |
100.00% |
1 / 1 |
AbstractAdapter | |
100.00% |
78 / 78 |
|
100.00% |
28 / 28 |
49 | |
100.00% |
1 / 1 |
setModel | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setModelId | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getModel | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getModelId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAction | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getOriginal | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getModified | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setUsername | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setUserId | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setDomain | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setRoute | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setMethod | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setMetadata | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
addMetadata | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getUsername | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getUserId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDomain | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRoute | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMethod | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasMetadata | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getMetadata | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
setStateData | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getStateData | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
hasStateData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
setDiff | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
5 | |||
resolveDiff | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
7 | |||
hasDiff | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
prepareData | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
5 | |||
send | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getStates | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getStateById | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getStateByModel | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getStateByTimestamp | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getStateByDate | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getSnapshot | n/a |
0 / 0 |
n/a |
0 / 0 |
0 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Audit\Adapter; |
15 | |
16 | /** |
17 | * Auditor abstract adapter |
18 | * |
19 | * @category Pop |
20 | * @package Pop\Audit |
21 | * @author Nick Sagona, III <dev@nolainteractive.com> |
22 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
23 | * @license http://www.popphp.org/license New BSD License |
24 | * @version 2.0.0 |
25 | */ |
26 | abstract class AbstractAdapter implements AdapterInterface |
27 | { |
28 | |
29 | /** |
30 | * Constants for action states |
31 | * @var int |
32 | */ |
33 | const CREATED = 'created'; |
34 | const UPDATED = 'updated'; |
35 | const DELETED = 'deleted'; |
36 | |
37 | /** |
38 | * Model name |
39 | * @var ?string |
40 | */ |
41 | protected ?string $model = null; |
42 | |
43 | /** |
44 | * Model ID |
45 | * @var int|string|null |
46 | */ |
47 | protected int|string|null $modelId = null; |
48 | |
49 | /** |
50 | * Action (created, updated, deleted) |
51 | * @var ?string |
52 | */ |
53 | protected ?string $action = null; |
54 | |
55 | /** |
56 | * Original model state differences |
57 | * @var array |
58 | */ |
59 | protected array $original = []; |
60 | |
61 | /** |
62 | * Modified model state differences |
63 | * @var array |
64 | */ |
65 | protected array $modified = []; |
66 | |
67 | /** |
68 | * Final state data |
69 | * @var array |
70 | */ |
71 | protected array $stateData = []; |
72 | |
73 | /** |
74 | * Username |
75 | * @var ?string |
76 | */ |
77 | protected ?string $username = null; |
78 | |
79 | /** |
80 | * User ID |
81 | * @var int|string|null |
82 | */ |
83 | protected int|string|null $userId = null; |
84 | |
85 | /** |
86 | * Domain |
87 | * @var ?string |
88 | */ |
89 | protected ?string $domain = null; |
90 | |
91 | /** |
92 | * Route |
93 | * @var ?string |
94 | */ |
95 | protected ?string $route = null; |
96 | |
97 | /** |
98 | * Method |
99 | * @var ?string |
100 | */ |
101 | protected ?string $method = null; |
102 | |
103 | /** |
104 | * Metadata |
105 | * @var array |
106 | */ |
107 | protected array$metadata = []; |
108 | |
109 | /** |
110 | * Set the model name |
111 | * |
112 | * @param string $model |
113 | * @return AbstractAdapter |
114 | */ |
115 | public function setModel(string $model): AbstractAdapter |
116 | { |
117 | $this->model = $model; |
118 | return $this; |
119 | } |
120 | |
121 | /** |
122 | * Set the model ID |
123 | * |
124 | * @param int|string $modelId |
125 | * @return AbstractAdapter |
126 | */ |
127 | public function setModelId(int|string $modelId): AbstractAdapter |
128 | { |
129 | $this->modelId = $modelId; |
130 | return $this; |
131 | } |
132 | |
133 | /** |
134 | * Get the model name |
135 | * |
136 | * @return string|null |
137 | */ |
138 | public function getModel(): string|null |
139 | { |
140 | return $this->model; |
141 | } |
142 | |
143 | /** |
144 | * Get the model ID |
145 | * |
146 | * @return int|string|null |
147 | */ |
148 | public function getModelId(): int|string|null |
149 | { |
150 | return $this->modelId; |
151 | } |
152 | |
153 | /** |
154 | * Get the action |
155 | * |
156 | * @return string|null |
157 | */ |
158 | public function getAction(): string|null |
159 | { |
160 | return $this->action; |
161 | } |
162 | |
163 | /** |
164 | * Get the original model state differences |
165 | * |
166 | * @return array |
167 | */ |
168 | public function getOriginal(): array |
169 | { |
170 | return $this->original; |
171 | } |
172 | |
173 | /** |
174 | * Get the modified model state differences |
175 | * |
176 | * @return array |
177 | */ |
178 | public function getModified(): array |
179 | { |
180 | return $this->modified; |
181 | } |
182 | |
183 | /** |
184 | * Set the username |
185 | * |
186 | * @param string $username |
187 | * @return AbstractAdapter |
188 | */ |
189 | public function setUsername(string $username): AbstractAdapter |
190 | { |
191 | $this->username = $username; |
192 | return $this; |
193 | } |
194 | |
195 | /** |
196 | * Set the user ID |
197 | * |
198 | * @param int|string $userId |
199 | * @return AbstractAdapter |
200 | */ |
201 | public function setUserId(int|string $userId): AbstractAdapter |
202 | { |
203 | $this->userId = $userId; |
204 | return $this; |
205 | } |
206 | |
207 | /** |
208 | * Set the domain |
209 | * |
210 | * @param string $domain |
211 | * @return AbstractAdapter |
212 | */ |
213 | public function setDomain(string $domain): AbstractAdapter |
214 | { |
215 | $this->domain = $domain; |
216 | return $this; |
217 | } |
218 | |
219 | /** |
220 | * Set the route |
221 | * |
222 | * @param string $route |
223 | * @return AbstractAdapter |
224 | */ |
225 | public function setRoute($route): AbstractAdapter |
226 | { |
227 | $this->route = $route; |
228 | return $this; |
229 | } |
230 | |
231 | /** |
232 | * Set the method |
233 | * |
234 | * @param string $method |
235 | * @return AbstractAdapter |
236 | */ |
237 | public function setMethod(string $method): AbstractAdapter |
238 | { |
239 | $this->method = $method; |
240 | return $this; |
241 | } |
242 | |
243 | /** |
244 | * Set the metadata |
245 | * |
246 | * @param array $metadata |
247 | * @return AbstractAdapter |
248 | */ |
249 | public function setMetadata(array $metadata): AbstractAdapter |
250 | { |
251 | $this->metadata = $metadata; |
252 | return $this; |
253 | } |
254 | |
255 | /** |
256 | * Add to the metadata |
257 | * |
258 | * @param string $name |
259 | * @param mixed $value |
260 | * @return AbstractAdapter |
261 | */ |
262 | public function addMetadata(string $name, mixed $value): AbstractAdapter |
263 | { |
264 | $this->metadata[$name] = $value; |
265 | return $this; |
266 | } |
267 | |
268 | /** |
269 | * Get the username |
270 | * |
271 | * @return string|null |
272 | */ |
273 | public function getUsername(): string|null |
274 | { |
275 | return $this->username; |
276 | } |
277 | |
278 | /** |
279 | * Get the user ID |
280 | * |
281 | * @return int|string|null |
282 | */ |
283 | public function getUserId(): int|string|null |
284 | { |
285 | return $this->userId; |
286 | } |
287 | |
288 | /** |
289 | * Get the domain |
290 | * |
291 | * @return string|null |
292 | */ |
293 | public function getDomain(): string|null |
294 | { |
295 | return $this->domain; |
296 | } |
297 | |
298 | /** |
299 | * Get the route |
300 | * |
301 | * @return string|null |
302 | */ |
303 | public function getRoute(): string|null |
304 | { |
305 | return $this->route; |
306 | } |
307 | |
308 | /** |
309 | * Get the method |
310 | * |
311 | * @return string|null |
312 | */ |
313 | public function getMethod(): string|null |
314 | { |
315 | return $this->method; |
316 | } |
317 | |
318 | /** |
319 | * Determine if there is metadata |
320 | * |
321 | * @param ?string $name |
322 | * @return bool |
323 | */ |
324 | public function hasMetadata(?string $name = null): bool |
325 | { |
326 | if ($name !== null) { |
327 | return isset($this->metadata[$name]); |
328 | } else { |
329 | return !empty($this->metadata); |
330 | } |
331 | } |
332 | |
333 | /** |
334 | * Get the metadata |
335 | * |
336 | * @param ?string $name |
337 | * @return mixed |
338 | */ |
339 | public function getMetadata(?string $name = null): mixed |
340 | { |
341 | if ($name !== null) { |
342 | return (isset($this->metadata[$name])) ? $this->metadata[$name] : null; |
343 | } else { |
344 | return $this->metadata; |
345 | } |
346 | } |
347 | |
348 | /** |
349 | * Set the final state data |
350 | * |
351 | * @param array $state |
352 | * @return AbstractAdapter |
353 | */ |
354 | public function setStateData(array $state): AbstractAdapter |
355 | { |
356 | $this->stateData = $state; |
357 | return $this; |
358 | } |
359 | |
360 | /** |
361 | * Get the final state |
362 | * |
363 | * @param ?string $name |
364 | * @return mixed |
365 | */ |
366 | public function getStateData(?string $name = null): mixed |
367 | { |
368 | if ($name !== null) { |
369 | return (isset($this->stateData[$name])) ? $this->stateData[$name] : null; |
370 | } else { |
371 | return $this->stateData; |
372 | } |
373 | } |
374 | |
375 | /** |
376 | * Determine if there is final state data |
377 | * |
378 | * @param ?string $name |
379 | * @return bool |
380 | */ |
381 | public function hasStateData(?string $name = null): bool |
382 | { |
383 | return ($name !== null) ? array_key_exists($name, $this->stateData) : !empty($this->stateData); |
384 | } |
385 | |
386 | /** |
387 | * Set the differences in values between the model states (that have already been processed) |
388 | * |
389 | * @param array $old |
390 | * @param array $new |
391 | * @return AbstractAdapter |
392 | */ |
393 | public function setDiff(array $old = [], array $new = []): AbstractAdapter |
394 | { |
395 | $this->original = $old; |
396 | $this->modified = $new; |
397 | |
398 | if (empty($old) && !empty($new)) { |
399 | $this->action = AbstractAdapter::CREATED; |
400 | } else if (empty($new) && !empty($old)) { |
401 | $this->action = AbstractAdapter::DELETED; |
402 | } else { |
403 | $this->action = AbstractAdapter::UPDATED; |
404 | } |
405 | |
406 | return $this; |
407 | } |
408 | |
409 | /** |
410 | * Resolve the differences in values between the model states |
411 | * |
412 | * @param array $old |
413 | * @param array $new |
414 | * @param bool $state |
415 | * @return AbstractAdapter |
416 | */ |
417 | public function resolveDiff(array $old = [], array $new = [], bool $state = true): AbstractAdapter |
418 | { |
419 | if ($state) { |
420 | $this->setStateData($new); |
421 | } |
422 | if (empty($old) && !empty($new)) { |
423 | $this->modified = $new; |
424 | $this->action = AbstractAdapter::CREATED; |
425 | } else if (empty($new) && !empty($old)) { |
426 | $this->original = $old; |
427 | $this->action = AbstractAdapter::DELETED; |
428 | } else { |
429 | $keys = array_keys(array_diff($old, $new)); |
430 | foreach ($keys as $key) { |
431 | $this->original[$key] = $old[$key]; |
432 | $this->modified[$key] = $new[$key]; |
433 | } |
434 | $this->action = AbstractAdapter::UPDATED; |
435 | } |
436 | |
437 | return $this; |
438 | } |
439 | |
440 | /** |
441 | * Check if the model states are different |
442 | * |
443 | * @return bool |
444 | */ |
445 | public function hasDiff(): bool |
446 | { |
447 | return (($this->action !== null) && ($this->original !== $this->modified)); |
448 | } |
449 | |
450 | /** |
451 | * Prepare data |
452 | * |
453 | * @param bool $jsonEncode |
454 | * @return array |
455 | */ |
456 | public function prepareData(bool $jsonEncode = true): array |
457 | { |
458 | return [ |
459 | 'user_id' => $this->userId, |
460 | 'username' => $this->username, |
461 | 'domain' => $this->domain, |
462 | 'route' => $this->route, |
463 | 'method' => $this->method, |
464 | 'model' => $this->model, |
465 | 'model_id' => $this->modelId, |
466 | 'action' => $this->action, |
467 | 'old' => ($jsonEncode) ? json_encode($this->original) : $this->original, |
468 | 'new' => ($jsonEncode) ? json_encode($this->modified) : $this->modified, |
469 | 'state' => ($jsonEncode) ? json_encode($this->stateData) : $this->stateData, |
470 | 'metadata' => ($jsonEncode) ? json_encode($this->metadata) : $this->metadata, |
471 | 'timestamp' => date('Y-m-d H:i:s') |
472 | ]; |
473 | } |
474 | |
475 | /** |
476 | * Send the results of the audit |
477 | * |
478 | * @return mixed |
479 | */ |
480 | abstract public function send(): mixed; |
481 | |
482 | /** |
483 | * Get model states |
484 | * |
485 | * @return array |
486 | */ |
487 | abstract public function getStates(): array; |
488 | |
489 | /** |
490 | * Get model state by ID |
491 | * |
492 | * @param int|string $id |
493 | * @return array |
494 | */ |
495 | abstract public function getStateById(int|string $id): array; |
496 | |
497 | /** |
498 | * Get model state by model |
499 | * |
500 | * @param string $model |
501 | * @param int|string|null $modelId |
502 | * @return array |
503 | */ |
504 | abstract public function getStateByModel(string $model, int|string|null $modelId = null): array; |
505 | |
506 | /** |
507 | * Get model state by timestamp |
508 | * |
509 | * @param string $from |
510 | * @param ?string $backTo |
511 | * @return array |
512 | */ |
513 | abstract public function getStateByTimestamp(string $from, ?string $backTo = null): array; |
514 | |
515 | /** |
516 | * Get model state by date |
517 | * |
518 | * @param string $from |
519 | * @param ?string $backTo |
520 | * @return array |
521 | */ |
522 | abstract public function getStateByDate(string $from, ?string $backTo = null): array; |
523 | |
524 | /** |
525 | * Get model snapshot by ID |
526 | * |
527 | * @param int|string $id |
528 | * @param bool $post |
529 | * @return array |
530 | */ |
531 | abstract public function getSnapshot(int|string $id, bool $post = false): array; |
532 | |
533 | } |