Issues (49)

src/Endpoint/ResourceEndpoint.php (7 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace DigitalCz\DigiSign\Endpoint;
6
7
use DigitalCz\DigiSign\DigiSignClient;
8
use DigitalCz\DigiSign\Exception\EmptyResultException;
9
use DigitalCz\DigiSign\Exception\ResponseException;
10
use DigitalCz\DigiSign\Exception\RuntimeException;
11
use DigitalCz\DigiSign\Resource\BaseResource;
12
use DigitalCz\DigiSign\Resource\Collection;
13
use DigitalCz\DigiSign\Resource\ListResource;
14
use DigitalCz\DigiSign\Resource\ResourceInterface;
15
use DigitalCz\DigiSign\Stream\FileResponse;
16
use Psr\Http\Message\ResponseInterface;
17
18
/**
19
 * @template T of ResourceInterface
20
 */
21
abstract class ResourceEndpoint implements EndpointInterface
22
{
23
    /** @var EndpointInterface  */
24
    protected $parent;
25
26
    /** @var string  */
27
    private $resourcePath;
28
29
    /** @var class-string<T> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
30
    private $resourceClass;
31
32
    /** @var mixed[] */
33
    private $resourceOptions;
34
35
    /**
36
     * @param class-string<T> $resourceClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
37
     * @param mixed[] $resourceOptions
38
     */
39
    public function __construct(
40
        EndpointInterface $parent,
41
        string $resourcePath,
42
        string $resourceClass = BaseResource::class,
43
        array $resourceOptions = []
44
    ) {
45
        $this->parent = $parent;
46
        $this->resourcePath = $resourcePath;
47
        $this->resourceClass = $resourceClass;
48
        $this->resourceOptions = $resourceOptions;
49
    }
50
51
    /**
52
     * @param mixed[] $options
53
     */
54
    public function request(string $method, string $path = '', array $options = []): ResponseInterface
55
    {
56
        $path = $this->preparePath($path);
57
        $options = $this->prepareOptions($options);
58
59
        return $this->parent->request($method, $path, $options);
60
    }
61
62
    /**
63
     * @param mixed[] $options
64
     */
65
    public function stream(string $method, string $path = '', array $options = []): FileResponse
66
    {
67
        return new FileResponse($this->request($method, $path, $options));
68
    }
69
70
    /**
71
     * @return class-string<T>
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
72
     */
73
    protected function getResourceClass(): string
74
    {
75
        return $this->resourceClass;
76
    }
77
78
    protected function getResourcePath(): string
79
    {
80
        return $this->resourcePath;
81
    }
82
83
    /**
84
     * @return mixed[]
85
     */
86
    protected function getResourceOptions(): array
87
    {
88
        return $this->resourceOptions;
89
    }
90
91
    /**
92
     * @param mixed[] $body
93
     * @return T&ResourceInterface
94
     */
95
    protected function makeCreateRequest(array $body): ResourceInterface
96
    {
97
        return $this->makeResource($this->postRequest('', ['json' => $body]));
98
    }
99
100
    /**
101
     * @param mixed[] $body
102
     */
103
    protected function makeUpdateRequest(string $id, array $body): ResourceInterface
104
    {
105
        return $this->makeResource($this->putRequest('/{id}', ['id' => $id, 'json' => $body]));
106
    }
107
108
    protected function makeDeleteRequest(string $id): void
109
    {
110
        $this->deleteRequest('/{id}', ['id' => $id]);
111
    }
112
113
    protected function makeGetRequest(string $id): ResourceInterface
114
    {
115
        return $this->makeResource($this->getRequest('/{id}', ['id' => $id]));
116
    }
117
118
    /**
119
     * @param mixed[] $query
120
     * @return ListResource<T>
121
     */
122
    protected function makeListRequest(array $query = []): ListResource
123
    {
124
        return $this->makeListResource($this->getRequest('', ['query' => $query]));
125
    }
126
127
    /**
128
     * @param mixed[] $options
129
     */
130
    protected function getRequest(string $function = '', array $options = []): ResponseInterface
131
    {
132
        return $this->request(self::METHOD_GET, $function, $options);
133
    }
134
135
    /**
136
     * @param mixed[] $options
137
     */
138
    protected function postRequest(string $function = '', array $options = []): ResponseInterface
139
    {
140
        return $this->request(self::METHOD_POST, $function, $options);
141
    }
142
143
    /**
144
     * @param mixed[] $options
145
     */
146
    protected function putRequest(string $function = '', array $options = []): ResponseInterface
147
    {
148
        return $this->request(self::METHOD_PUT, $function, $options);
149
    }
150
151
    /**
152
     * @param mixed[] $options
153
     */
154
    protected function patchRequest(string $function = '', array $options = []): ResponseInterface
155
    {
156
        return $this->request(self::METHOD_PATCH, $function, $options);
157
    }
158
159
    /**
160
     * @param mixed[] $options
161
     */
162
    protected function deleteRequest(string $function = '', array $options = []): ResponseInterface
163
    {
164
        return $this->request(self::METHOD_DELETE, $function, $options);
165
    }
166
167
    /**
168
     * @return mixed[]
169
     */
170
    protected function parseResponse(ResponseInterface $response): array
171
    {
172
        try {
173
            $result = DigiSignClient::parseResponse($response);
174
        } catch (RuntimeException $e) {
175
            throw new ResponseException($response, $e->getMessage(), null, $e);
176
        }
177
178
        if ($result === null) {
179
            throw new EmptyResultException();
180
        }
181
182
        return $result;
183
    }
184
185
    /**
186
     * @return T
187
     */
188
    protected function makeResource(ResponseInterface $response): ResourceInterface
189
    {
190
        return $this->createResource($response, $this->getResourceClass());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->createReso...is->getResourceClass()) returns the type DigitalCz\DigiSign\Resource\ResourceInterface which is incompatible with the documented return type DigitalCz\DigiSign\Endpoint\T.
Loading history...
191
    }
192
193
    /**
194
     * @param class-string<U> $resourceClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<U> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<U>.
Loading history...
195
     * @return U
196
     * @template U of ResourceInterface
197
     */
198
    protected function createResource(
199
        ResponseInterface $response,
200
        string $resourceClass = BaseResource::class
201
    ): ResourceInterface {
202
        $resource = new $resourceClass($this->parseResponse($response));
203
        $resource->setResponse($response);
204
205
        return $resource;
206
    }
207
208
    /**
209
     * @return ListResource<T>
210
     */
211
    protected function makeListResource(ResponseInterface $response): ListResource
212
    {
213
        return $this->createListResource($response, $this->getResourceClass());
214
    }
215
216
    /**
217
     * @param class-string<U> $resourceClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<U> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<U>.
Loading history...
218
     * @return ListResource<U>
219
     * @template U of ResourceInterface
220
     */
221
    protected function createListResource(
222
        ResponseInterface $response,
223
        string $resourceClass = BaseResource::class
224
    ): ListResource {
225
        $resource = new ListResource($this->parseResponse($response), $resourceClass);
226
        $resource->setResponse($response);
227
228
        return $resource;
229
    }
230
231
    /**
232
     * @param class-string<U> $resourceClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<U> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<U>.
Loading history...
233
     * @return Collection<U>
234
     * @template U of ResourceInterface
235
     */
236
    protected function createCollectionResource(
237
        ResponseInterface $response,
238
        string $resourceClass = BaseResource::class
239
    ): Collection {
240
        $collection = new Collection($this->parseResponse($response), $resourceClass);
241
        $collection->setResponse($response);
242
243
        return $collection;
244
    }
245
246
    /**
247
     * @param mixed[] $options
248
     * @return mixed[]
249
     */
250
    protected function prepareOptions(array $options): array
251
    {
252
        return array_merge($this->getResourceOptions(), $options);
253
    }
254
255
    protected function preparePath(string $path): string
256
    {
257
        return $this->getResourcePath() . $path;
258
    }
259
}
260