File tree Expand file tree Collapse file tree 7 files changed +132
-18
lines changed
src/FreeElephants/JsonApi/DTO
tests/FreeElephants/JsonApi/DTO Expand file tree Collapse file tree 7 files changed +132
-18
lines changed Original file line number Diff line number Diff line change 1
1
name : CI
2
2
3
- on : push
3
+ on :
4
+ - push
5
+ - pull_request
4
6
5
7
jobs :
6
8
php-tests :
Original file line number Diff line number Diff line change @@ -6,10 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
7
7
## [ Unreleased]
8
8
9
+ ## [ 0.0.2] - 2025-03-14
10
+
11
+ ### Added
12
+ - AbstractCollection for handle array of resources in data field
13
+ - Exception on pass array as data into AbstractDocument constructor
14
+
9
15
## [ 0.0.1] - 2025-03-13
10
16
11
17
### Added
12
18
- Extract all DTO types from FreeElephants/json-api-php-toolkit to this project
13
19
14
- [ Unreleased ] : https://github.com/FreeElephants/json-api-dto/compare/0.0.1...HEAD
20
+ [ Unreleased ] : https://github.com/FreeElephants/json-api-dto/compare/0.0.2...HEAD
21
+ [ 0.0.2 ] : https://github.com/FreeElephants/json-api-dto/releases/tag/0.0.2
15
22
[ 0.0.1 ] : https://github.com/FreeElephants/json-api-dto/releases/tag/0.0.1
Original file line number Diff line number Diff line change
1
+ <?php
2
+ declare (strict_types=1 );
3
+
4
+ namespace FreeElephants \JsonApi \DTO ;
5
+
6
+ abstract class AbstractCollection extends TopLevel
7
+ {
8
+ public array $ data = [];
9
+
10
+ final public function __construct (array $ payload = [])
11
+ {
12
+ foreach ($ payload ['data ' ] as $ item ) {
13
+ $ dataItemClassName = $ this ->getDataItemClassName ();
14
+ $ this ->data [] = new $ dataItemClassName ($ item );
15
+ }
16
+ }
17
+
18
+ abstract public function getDataItemClassName (): string ;
19
+ }
Original file line number Diff line number Diff line change 7
7
/**
8
8
* @property AbstractResourceObject|mixed $data
9
9
*/
10
- abstract class AbstractDocument
10
+ abstract class AbstractDocument extends TopLevel
11
11
{
12
- final public function __construct (array $ data )
12
+ final public function __construct (array $ payload )
13
13
{
14
14
$ concreteClass = new \ReflectionClass ($ this );
15
15
$ dataProperty = $ concreteClass ->getProperty ('data ' );
16
16
/** @var \ReflectionNamedType $reflectionType */
17
17
$ reflectionType = $ dataProperty ->getType ();
18
18
$ dataClassName = $ reflectionType ->getName ();
19
- $ this ->data = new $ dataClassName ($ data ['data ' ]);
20
- }
21
-
22
- /**
23
- * @param MessageInterface $httpMessage
24
- * @return static
25
- */
26
- public static function fromHttpMessage (MessageInterface $ httpMessage ): self
27
- {
28
- $ httpMessage ->getBody ()->rewind ();
29
- $ rawJson = $ httpMessage ->getBody ()->getContents ();
30
- $ decodedJson = json_decode ($ rawJson , true );
31
-
32
- return new static ($ decodedJson );
19
+ if ($ dataClassName !== 'array ' ) {
20
+ $ data = new $ dataClassName ($ payload ['data ' ]);
21
+ } else {
22
+ throw new \UnexpectedValueException ('`data` property must be typed, for array of resources use AbstractCollection instead ' . self ::class);
23
+ }
24
+ $ this ->data = $ data ;
33
25
}
34
26
}
Original file line number Diff line number Diff line change
1
+ <?php
2
+ declare (strict_types=1 );
3
+
4
+ namespace FreeElephants \JsonApi \DTO ;
5
+
6
+ use Psr \Http \Message \MessageInterface ;
7
+
8
+ /**
9
+ * @property AbstractResourceObject|AbstractResourceObject[] $data
10
+ */
11
+ abstract class TopLevel
12
+ {
13
+ /**
14
+ * @param MessageInterface $httpMessage
15
+ * @return static
16
+ */
17
+ public static function fromHttpMessage (MessageInterface $ httpMessage ): self
18
+ {
19
+ $ httpMessage ->getBody ()->rewind ();
20
+ $ rawJson = $ httpMessage ->getBody ()->getContents ();
21
+ $ decodedJson = json_decode ($ rawJson , true );
22
+
23
+ return new static ($ decodedJson );
24
+ }
25
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ declare (strict_types=1 );
3
+
4
+ namespace FreeElephants \JsonApi \DTO ;
5
+
6
+ use FreeElephants \JsonApi \AbstractTestCase ;
7
+ use FreeElephants \JsonApi \DTO \Example \SomeCollectionDocument ;
8
+ use Nyholm \Psr7 \ServerRequest ;
9
+
10
+ class CollectionTest extends AbstractTestCase
11
+ {
12
+ public function testCollectionFromHttpMessage (): void
13
+ {
14
+ $ request = new ServerRequest ('GET ' , '/foos ' );
15
+ $ request ->getBody ()->write (<<<JSON
16
+ {
17
+ "data": [
18
+ {
19
+ "id": "123",
20
+ "type": "foo",
21
+ "attributes": {
22
+ "foo": "bar",
23
+ "date": "2012-04-23T18:25:43.511Z",
24
+ "nested": {
25
+ "someNestedStructure": {
26
+ "someKey": "someValue"
27
+ }
28
+ }
29
+ },
30
+ "relationships": {
31
+ "baz": {
32
+ "data": {
33
+ "type": "bazs",
34
+ "id": "baz-id"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ ]
40
+ }
41
+ JSON
42
+ );
43
+
44
+ $ collectionDto = SomeCollectionDocument::fromHttpMessage ($ request );
45
+
46
+ $ this ->assertCount (1 , $ collectionDto ->data );
47
+ $ this ->assertSame ('123 ' , $ collectionDto ->data [0 ]->id );
48
+ $ this ->assertSame ('foo ' , $ collectionDto ->data [0 ]->type );
49
+ }
50
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ declare (strict_types=1 );
3
+
4
+ namespace FreeElephants \JsonApi \DTO \Example ;
5
+
6
+ use FreeElephants \JsonApi \DTO \AbstractCollection ;
7
+ use FreeElephants \JsonApi \DTO \AbstractResourceObject ;
8
+
9
+ class SomeCollectionDocument extends AbstractCollection
10
+ {
11
+ public function getDataItemClassName (): string
12
+ {
13
+ return DataItemResourceObject::class;
14
+ }
15
+ }
16
+
17
+ class DataItemResourceObject extends AbstractResourceObject
18
+ {
19
+ }
You can’t perform that action at this time.
0 commit comments