Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.50% covered (success)
92.50%
74 / 80
83.33% covered (warning)
83.33%
10 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
Result
92.50% covered (success)
92.50%
74 / 80
83.33% covered (warning)
83.33%
10 / 12
33.46
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setResponse
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 testMeta
86.84% covered (warning)
86.84%
33 / 38
0.00% covered (danger)
0.00%
0 / 1
10.23
 getRequest
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getResponse
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEntity
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 getCollection
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 getData
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getMeta
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getIds
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 setData
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace BO\Zmsclient;
4
5use BO\Mellon\Valid;
6use BO\Mellon\Validator;
7use BO\Zmsentities\Metaresult;
8use BO\Zmsentities\Collection\Base as BaseCollection;
9use BO\Zmsentities\Schema\Entity;
10use BO\Zmsentities\Schema\Factory;
11use Psr\Http\Message\RequestInterface;
12use Psr\Http\Message\ResponseInterface;
13
14/**
15 * Handle default response
16 */
17class Result
18{
19    /**
20     * @var ResponseInterface
21     */
22    protected $response;
23
24    /**
25     * @var RequestInterface|null
26     */
27    protected $request;
28
29    /**
30     * @var Entity[]|null
31     */
32    protected $data = null;
33
34    /**
35     * @var Metaresult|null
36     */
37    protected $meta = null;
38
39    /**
40     * @param ResponseInterface $response
41     * @param RequestInterface|null $request (optional) reference for better error messages
42     */
43    public function __construct(
44        ResponseInterface $response,
45        ?RequestInterface $request = null
46    ) {
47        $this->request = $request;
48        $this->response = $response;
49    }
50
51    /**
52     * Parse response and the object values
53     * @param ResponseInterface $response
54     * @return self
55     */
56    public function setResponse(ResponseInterface $response)
57    {
58        $body = Validator::value((string) $response->getBody())->isJson();
59        $this->testMeta($body, $response);
60        $result = $body->getValue();
61        if (array_key_exists("data", $result)) {
62            $this->setData($result['data']);
63        }
64        return $this;
65    }
66
67    /**
68     * Test meta data on errors
69     *
70     * @param Valid $body
71     * @param ResponseInterface $response
72     *
73     * @throws Exception
74     *
75     * @return void
76     */
77    protected function testMeta($body, ResponseInterface $response)
78    {
79        if ($body->hasFailed()) {
80            $content = (string) $response->getBody();
81            throw new Exception\ApiFailed(
82                'API-Call failed, JSON parsing with error: ' . (string) ($body->getMessages() ?? '')
83                . ' - Snippet: ' . substr(\strip_tags($content), 0, 2000) . '[...]',
84                $response,
85                $this->request
86            );
87        }
88        $result = $body->getValue();
89        if (!$result || !array_key_exists("meta", $result)) {
90            throw new Exception(
91                'Missing "meta" value on result, API-Call failed.',
92                $response,
93                $this->request
94            );
95        }
96        $entity = Factory::create($result['meta'])->getEntity();
97        if (!$entity instanceof Metaresult) {
98            throw new Exception(
99                'Missing "meta" value on result, API-Call failed.',
100                $response,
101                $this->request
102            );
103        }
104        $this->meta = $entity;
105        if (($entity['error'] ?? false) == true) {
106            $message = $entity['message'] ? $entity['message'] : ($entity['exception'] ?? '');
107            $exception = new Exception(
108                'API-Error: ' . $message,
109                $response,
110                $this->request
111            );
112            if (isset($entity['trace'])) {
113                $exception->trace = $entity['trace'];
114            }
115            $exception->originalMessage = $entity['message'] ?? null;
116            if (array_key_exists('data', $result)) {
117                $exception->data = $result['data'];
118            }
119            if (isset($entity['exception'])) {
120                $exception->template = $entity['exception'];
121            }
122            throw $exception;
123        }
124    }
125
126    /**
127     * Get the origin request
128     *
129     * @return RequestInterface|null
130     */
131    public function getRequest()
132    {
133        return $this->request;
134    }
135
136    /**
137     * Get the origin response
138     *
139     * @return ResponseInterface
140     */
141    public function getResponse()
142    {
143        return $this->response;
144    }
145
146    /**
147     * Get the origin response
148     *
149     * @return bool
150     */
151    public function isStatus(int|string $statuscode)
152    {
153        return $this->getResponse()->getStatusCode() == $statuscode;
154    }
155
156    /**
157     * Description
158     *
159     * @return Entity|null
160     */
161    public function getEntity()
162    {
163        $data = $this->getData();
164        if ($data === null || $data === []) {
165            return null;
166        }
167        return $data[array_key_first($data)];
168    }
169
170    /**
171     * Description
172     */
173    public function getCollection(): mixed
174    {
175        $collection = null;
176        $entity = $this->getEntity();
177        if ($entity !== null) {
178            $class = get_class($entity);
179            $alias = ucfirst(preg_replace('#^.*\\\#', '', $class) ?? '');
180            $className = "\\BO\\Zmsentities\\Collection\\" . $alias . "List";
181            if (class_exists($className) && is_a($className, BaseCollection::class, true)) {
182                /** @psalm-suppress UnsafeInstantiation */
183                $collection = new $className($this->getData());
184            }
185        }
186        return $collection;
187    }
188
189    /**
190     * Description
191     *
192     * @return Entity[]|null
193     */
194    public function getData()
195    {
196        if (null === $this->data) {
197            $this->setResponse($this->response);
198        }
199        return $this->data;
200    }
201
202    /**
203     * Description
204     *
205     * @return Metaresult|null
206     */
207    public function getMeta()
208    {
209        if (null === $this->meta) {
210            $this->setResponse($this->response);
211        }
212        return $this->meta;
213    }
214
215    /**
216     * Get the list of IDs from the data
217     *
218     * @return string
219     */
220    public function getIds()
221    {
222        $data = $this->getData() ?? [];
223        $idList = [];
224
225        foreach ($data as $item) {
226            $idList[] = $item->getId();
227        }
228
229        return implode(',', array_unique($idList));
230    }
231
232    /**
233     * Set entity from response
234     *
235     * @param array $data
236     *
237     * @return self
238     */
239    public function setData(array $data)
240    {
241        if (array_key_exists('$schema', $data)) {
242            $data = [$data];
243        }
244        foreach ($data as $entityData) {
245            if (!array_key_exists('$schema', $entityData)) {
246                $entityData['$schema'] = $data[0]['$schema'];
247            }
248            $this->data[] = Factory::create($entityData)->getEntity();
249        }
250        return $this;
251    }
252}