Skip to content

Commit 58a68d8

Browse files
authored
Merge pull request #23 from maxyo/route
Added route info gen
2 parents d4e083e + cc51cd9 commit 58a68d8

19 files changed

+1138
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010
- Data Transfer Object classes generation from swagger spec
11+
- Route info in the request attribute
1112
- CacheableDispatcherFactoryProxy
1213
- JsonApiResponseFactory::createRelationshipResponse()
1314
- RateLimitMiddleware and related packages
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
<?php
2+
3+
namespace FreeElephants\JsonApiToolkit\JsonApi\Request;
4+
5+
use FreeElephants\JsonApiToolkit\JsonApi\Request\Route\RelationshipRoute;
6+
use FreeElephants\JsonApiToolkit\JsonApi\Request\Route\RouteFactory;
7+
use FreeElephants\JsonApiToolkit\JsonApi\Request\Route\RouteInterface;
8+
use Psr\Http\Message\ServerRequestInterface;
9+
use Psr\Http\Message\StreamInterface;
10+
use Psr\Http\Message\UriInterface;
11+
use stdClass;
12+
13+
class JsonApiServerRequestDecorator implements JsonApiServerRequestInterface
14+
{
15+
private ServerRequestInterface $request;
16+
private ?array $decodedBody;
17+
18+
public function __construct(ServerRequestInterface $request, RouteFactory $routeFactory)
19+
{
20+
$this->request = $request;
21+
}
22+
23+
public function getProtocolVersion()
24+
{
25+
return $this->request->getProtocolVersion();
26+
}
27+
28+
public function withProtocolVersion($version)
29+
{
30+
return $this->request->withProtocolVersion($version);
31+
}
32+
33+
public function getHeaders()
34+
{
35+
return $this->request->getHeaders();
36+
}
37+
38+
public function hasHeader($name)
39+
{
40+
return $this->request->hasHeader($name);
41+
}
42+
43+
public function getHeader($name)
44+
{
45+
return $this->request->getHeader($name);
46+
}
47+
48+
public function getHeaderLine($name)
49+
{
50+
return $this->request->getHeaderLine($name);
51+
}
52+
53+
public function withHeader($name, $value)
54+
{
55+
return $this->request->withHeader($name, $value);
56+
}
57+
58+
public function withAddedHeader($name, $value)
59+
{
60+
return $this->request->withAddedHeader($name, $value);
61+
}
62+
63+
public function withoutHeader($name)
64+
{
65+
return $this->request->withoutHeader($name);
66+
}
67+
68+
public function getBody()
69+
{
70+
return $this->request->getBody();
71+
}
72+
73+
public function withBody(StreamInterface $body)
74+
{
75+
return $this->request->withBody($body);
76+
}
77+
78+
public function getRequestTarget()
79+
{
80+
return $this->request->getRequestTarget();
81+
}
82+
83+
public function withRequestTarget($requestTarget)
84+
{
85+
return $this->request->withRequestTarget($requestTarget);
86+
}
87+
88+
public function getMethod()
89+
{
90+
return $this->request->getMethod();
91+
}
92+
93+
public function withMethod($method)
94+
{
95+
return $this->request->withMethod($method);
96+
}
97+
98+
public function getUri()
99+
{
100+
return $this->request->getUri();
101+
}
102+
103+
public function withUri(UriInterface $uri, $preserveHost = false)
104+
{
105+
return $this->request->withUri($uri, $preserveHost);
106+
}
107+
108+
public function getServerParams()
109+
{
110+
return $this->request->getServerParams();
111+
}
112+
113+
public function getCookieParams()
114+
{
115+
return $this->request->getCookieParams();
116+
}
117+
118+
public function withCookieParams(array $cookies)
119+
{
120+
return $this->request->withCookieParams($cookies);
121+
}
122+
123+
public function getQueryParams()
124+
{
125+
return $this->request->getQueryParams();
126+
}
127+
128+
public function withQueryParams(array $query)
129+
{
130+
return $this->request->withQueryParams($query);
131+
}
132+
133+
public function getUploadedFiles()
134+
{
135+
return $this->request->getUploadedFiles();
136+
}
137+
138+
public function withUploadedFiles(array $uploadedFiles)
139+
{
140+
return $this->request->withUploadedFiles($uploadedFiles);
141+
}
142+
143+
public function getParsedBody()
144+
{
145+
return $this->request->getParsedBody();
146+
}
147+
148+
public function withParsedBody($data)
149+
{
150+
return $this->request->withParsedBody($data);
151+
}
152+
153+
public function getAttributes()
154+
{
155+
return $this->request->getAttributes();
156+
}
157+
158+
public function getAttribute($name, $default = null)
159+
{
160+
return $this->request->getAttribute($name, $default);
161+
}
162+
163+
public function withAttribute($name, $value)
164+
{
165+
return $this->request->withAttribute($name, $value);
166+
}
167+
168+
public function withoutAttribute($name)
169+
{
170+
return $this->request->withoutAttribute($name);
171+
}
172+
173+
private function getRoute(): RouteInterface
174+
{
175+
return $this->request->getAttribute(JsonApiServerRequestInterface::ATTRIBUTE_ROUTE_NAME);
176+
}
177+
178+
private function getDecodedBody(): ?array
179+
{
180+
if (isset($this->decodedBody)) {
181+
return $this->decodedBody;
182+
}
183+
184+
$this->request->getBody()->rewind();
185+
$this->decodedBody = json_decode($this->request->getBody()->getContents(), true);
186+
187+
return $this->decodedBody;
188+
}
189+
190+
public function getDocumentId(): ?string
191+
{
192+
return $this->getDecodedBody()['data']['id'] ?? null;
193+
}
194+
195+
public function getDocumentType(): ?string
196+
{
197+
return $this->getDecodedBody()['data']['type'] ?? null;
198+
}
199+
200+
public function getPrimeAttributeName(): ?string
201+
{
202+
return $this->getRoute()->getRouteParamName();
203+
}
204+
205+
/**
206+
* @return mixed
207+
*/
208+
public function getPrimeAttributeValue()
209+
{
210+
return $this->getAttribute($this->getPrimeAttributeName());
211+
}
212+
213+
public function getEndpointTypeName(): string
214+
{
215+
return $this->getRoute()->getEndpointTypeName();
216+
}
217+
218+
/**
219+
* @see MemberTypeEnum
220+
*/
221+
public function getRelationshipOriginName(): string
222+
{
223+
return $this->getRoute()->getRelationshipOriginName();
224+
}
225+
226+
public function getRequestType(): int
227+
{
228+
return $this->getRoute()->getType();
229+
}
230+
231+
public function getDocumentAttributes(): ?stdClass
232+
{
233+
$this->request->getBody()->rewind();
234+
235+
$decodedBody = json_decode($this->request->getBody()->getContents());
236+
237+
return $decodedBody->data->attributes ?? null;
238+
}
239+
240+
/**
241+
* @return array<string, array>
242+
*/
243+
public function getRelationships(): array
244+
{
245+
$body = $this->getDecodedBody();
246+
247+
switch ($this->getRoute()->getType()) {
248+
case RouteInterface::TYPE_RESOURCES_COLLECTION:
249+
case RouteInterface::TYPE_RESOURCE:
250+
case RouteInterface::TYPE_MEMBER:
251+
$relationships = $body['data']['relationships'] ?? [];
252+
break;
253+
case RouteInterface::TYPE_RELATIONSHIP:
254+
/** @var RelationshipRoute $route */
255+
$route = $this->getRoute();
256+
$relationships = [$route->getRelationshipName() => $body];
257+
break;
258+
default:
259+
$relationships = [];
260+
}
261+
262+
return $relationships;
263+
}
264+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace FreeElephants\JsonApiToolkit\JsonApi\Request;
4+
5+
use Psr\Http\Message\ServerRequestInterface;
6+
7+
interface JsonApiServerRequestInterface extends ServerRequestInterface
8+
{
9+
const ATTRIBUTE_ROUTE_NAME = 'route';
10+
11+
public function getDocumentId(): ?string;
12+
13+
public function getDocumentType(): ?string;
14+
15+
public function getPrimeAttributeName(): ?string;
16+
17+
/**
18+
* @return mixed
19+
*/
20+
public function getPrimeAttributeValue();
21+
22+
public function getEndpointTypeName(): string;
23+
24+
/**
25+
* @see MemberTypeEnum
26+
*/
27+
public function getRelationshipOriginName(): string;
28+
29+
public function getRequestType(): int;
30+
31+
public function getDocumentAttributes(): ?object;
32+
33+
/**
34+
* @return array<string, array>
35+
*/
36+
public function getRelationships(): array;
37+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace FreeElephants\JsonApiToolkit\JsonApi\Request;
4+
5+
class MappingConfigProvider
6+
{
7+
public const ENDPOINT_TYPE_TO_DOCUMENT_TYPE = 0;
8+
public const RESOURCE_TYPE_TO_ROUTE_PARAM_KEY = 1;
9+
public const TYPE_TO_CLASSNAME = 2;
10+
11+
protected array $endpointTypeToDocumentTypeMapping;
12+
protected array $resourceTypeToRouteParamKeyTypeMapping;
13+
protected array $typenameToClassnameMapping;
14+
15+
/**
16+
* @example
17+
* [
18+
* ENDPOINT_TYPE_TO_DOCUMENT_TYPE => [
19+
* 'foo' => 'bar',
20+
* ],
21+
* ]
22+
*
23+
* @param array<int, array<string, string>> $mapping
24+
*/
25+
public function __construct(array $mapping)
26+
{
27+
$this->endpointTypeToDocumentTypeMapping = $mapping[self::ENDPOINT_TYPE_TO_DOCUMENT_TYPE] ?? [];
28+
$this->resourceTypeToRouteParamKeyTypeMapping = $mapping[self::RESOURCE_TYPE_TO_ROUTE_PARAM_KEY] ?? [];
29+
$this->typenameToClassnameMapping = $mapping[self::TYPE_TO_CLASSNAME] ?? [];
30+
}
31+
32+
public function isEndpointToDocumentMapped(string $endpointType): bool
33+
{
34+
return array_key_exists($endpointType, $this->endpointTypeToDocumentTypeMapping);
35+
}
36+
37+
public function isResourceToRouteParamKeyMapped(string $resourceType): bool
38+
{
39+
return array_key_exists($resourceType, $this->resourceTypeToRouteParamKeyTypeMapping);
40+
}
41+
42+
public function isTypenameToClassnameMapped(string $typename): bool
43+
{
44+
return array_key_exists($typename, $this->typenameToClassnameMapping);
45+
}
46+
47+
public function getDocumentTypeByEndpointType(string $endpointType): ?string
48+
{
49+
return $this->endpointTypeToDocumentTypeMapping[$endpointType] ?? null;
50+
}
51+
52+
public function getRouteParamKeyByResourceType(string $resourceType): ?string
53+
{
54+
return $this->resourceTypeToRouteParamKeyTypeMapping[$resourceType] ?? null;
55+
}
56+
57+
public function getClassnameByTypename(?string $typename): ?string
58+
{
59+
return $this->typenameToClassnameMapping[$typename] ?? null;
60+
}
61+
}

0 commit comments

Comments
 (0)