Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.89% covered (success)
88.89%
88 / 99
85.71% covered (success)
85.71%
12 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
Http
88.89% covered (success)
88.89%
88 / 99
85.71% covered (success)
85.71%
12 / 14
63.78
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setSendClient
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setFetchClient
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getSendClient
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFetchClient
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFetchedResult
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 hasFetchClient
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 send
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 getStates
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getStateById
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
19.26
 getStateByModel
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 getStateByTimestamp
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
4
 getStateByDate
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
6
 getSnapshot
66.67% covered (warning)
66.67%
12 / 18
0.00% covered (danger)
0.00%
0 / 1
25.48
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 */
14namespace Pop\Audit\Adapter;
15
16use Pop\Http\Client;
17
18/**
19 * Auditor HTTP class
20 *
21 * @category   Pop
22 * @package    Pop\Audit
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    2.0.0
27 */
28class 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}