Skip to content

Commit 2b6901a

Browse files
authored
Merge pull request #52 from swisnl/feature/refactor-document-builders
Refactor both DocumentBuilders to one DocumentFactory
2 parents 24b4864 + f097242 commit 2b6901a

16 files changed

+390
-323
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88

99
### Added
1010

11-
* Added facades for `CollectionDocumentBuilder`, `ItemDocumentBuilder`, `ItemHydrator` and `TypeMapper`.
11+
* Added `DocumentFactory`.
12+
* Added facades for `DocumentFactory`, `ItemHydrator` and `TypeMapper`.
1213

1314
### Changed
1415

1516
* The `TypeMapper` now checks if the class exists in the setter instead of the getter.
1617
* The `ItemHydrator` now also hydrates the id if provided.
18+
* Added `hasType`, `hasAttributes`, `hasRelationships` and `getRelations` to `ItemInterface`.
19+
* Removed `canBeIncluded` and `getIncluded` from `ItemInterface` as the `DocumentFactory` is now responsible for gathering the included items.
20+
21+
### Removed
22+
23+
* Removed `CollectionDocumentBuilder` and `ItemDocumentBuilder` in favor of `DocumentFactory`.
1724

1825
## [0.18.0] - 2019-07-01
1926

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@
5959
"Swis\\JsonApi\\Client\\Providers\\ServiceProvider"
6060
],
6161
"aliases":{
62-
"CollectionDocumentBuilder": "Swis\\JsonApi\\Client\\Facades\\CollectionDocumentBuilderFacade",
63-
"ItemDocumentBuilder": "Swis\\JsonApi\\Client\\Facades\\ItemDocumentBuilderFacade",
62+
"DocumentFactory": "Swis\\JsonApi\\Client\\Facades\\DocumentFactoryFacade",
6463
"ItemHydrator": "Swis\\JsonApi\\Client\\Facades\\ItemHydratorFacade",
6564
"TypeMapper": "Swis\\JsonApi\\Client\\Facades\\TypeMapperFacade"
6665
}

src/CollectionDocumentBuilder.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/DocumentFactory.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Swis\JsonApi\Client;
4+
5+
use Swis\JsonApi\Client\Interfaces\DataInterface;
6+
use Swis\JsonApi\Client\Interfaces\DocumentInterface;
7+
use Swis\JsonApi\Client\Interfaces\ItemInterface;
8+
9+
class DocumentFactory
10+
{
11+
/**
12+
* @param \Swis\JsonApi\Client\Interfaces\DataInterface $data
13+
*
14+
* @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
15+
*/
16+
public function make(DataInterface $data): DocumentInterface
17+
{
18+
if ($data instanceof ItemInterface) {
19+
$document = new ItemDocument();
20+
} elseif ($data instanceof Collection) {
21+
$document = new CollectionDocument();
22+
} else {
23+
throw new \InvalidArgumentException(sprintf('%s is not supported as input', get_class($data)));
24+
}
25+
26+
return $document->setData($data)->setIncluded($this->getIncluded($data));
27+
}
28+
29+
/**
30+
* @param \Swis\JsonApi\Client\Interfaces\DataInterface $data
31+
*
32+
* @return \Swis\JsonApi\Client\Collection
33+
*/
34+
private function getIncluded(DataInterface $data): Collection
35+
{
36+
return Collection::wrap($data)
37+
->flatMap(
38+
function (ItemInterface $item) {
39+
return $this->getIncludedFromItem($item);
40+
}
41+
)
42+
->unique(
43+
static function (ItemInterface $item) {
44+
return sprintf('%s:%s', $item->getType(), $item->getId());
45+
}
46+
)
47+
->values();
48+
}
49+
50+
/**
51+
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
52+
*
53+
* @return \Swis\JsonApi\Client\Collection
54+
*/
55+
private function getIncludedFromItem(ItemInterface $item): Collection
56+
{
57+
return Collection::make($item->getRelations())
58+
->reject(
59+
static function ($relationship) {
60+
/* @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface $relationship */
61+
return $relationship->shouldOmitIncluded() || !$relationship->hasIncluded();
62+
}
63+
)
64+
->flatMap(
65+
static function ($relationship) {
66+
/* @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface $relationship */
67+
return Collection::wrap($relationship->getIncluded());
68+
}
69+
)
70+
->flatMap(
71+
function (ItemInterface $item) {
72+
return Collection::wrap($item)->merge($this->getIncludedFromItem($item));
73+
}
74+
)
75+
->filter(
76+
function (ItemInterface $item) {
77+
return $this->itemCanBeIncluded($item);
78+
}
79+
);
80+
}
81+
82+
/**
83+
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
84+
*
85+
* @return bool
86+
*/
87+
private function itemCanBeIncluded(ItemInterface $item): bool
88+
{
89+
return $item->hasType()
90+
&& $item->hasId()
91+
&& ($item->hasAttributes() || $item->hasRelationships());
92+
}
93+
}

src/Facades/CollectionDocumentBuilderFacade.php

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Swis\JsonApi\Client\Facades;
4+
5+
use Illuminate\Support\Facades\Facade;
6+
use Swis\JsonApi\Client\DocumentFactory;
7+
8+
/**
9+
* @method static \Swis\JsonApi\Client\Interfaces\DocumentInterface make(\Swis\JsonApi\Client\Interfaces\DataInterface $data)
10+
*
11+
* @see \Swis\JsonApi\Client\DocumentFactory
12+
*/
13+
class DocumentFactoryFacade extends Facade
14+
{
15+
/**
16+
* {@inheritdoc}
17+
*/
18+
protected static function getFacadeAccessor()
19+
{
20+
return DocumentFactory::class;
21+
}
22+
}

src/Facades/ItemDocumentBuilderFacade.php

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/Interfaces/ItemInterface.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public function setId(? string $id);
3434
*/
3535
public function getType(): string;
3636

37+
/**
38+
* @return bool
39+
*/
40+
public function hasType(): bool;
41+
3742
/**
3843
* @param string $type
3944
*
@@ -97,6 +102,16 @@ public function getAttribute($key);
97102
*/
98103
public function setAttribute($key, $value);
99104

105+
/**
106+
* @return bool
107+
*/
108+
public function hasAttributes(): bool;
109+
110+
/**
111+
* @return bool
112+
*/
113+
public function hasRelationships(): bool;
114+
100115
/**
101116
* @return array
102117
*/
@@ -115,14 +130,7 @@ public function getAvailableRelations(): array;
115130
public function setRelation(string $relation, DataInterface $value, Links $links = null, Meta $meta = null);
116131

117132
/**
118-
* @TODO: MEGA TODO. Set up a serializer for the Item so that we can remove this, getRelationships etc
119-
*
120-
* @return \Swis\JsonApi\Client\Collection
121-
*/
122-
public function getIncluded();
123-
124-
/**
125-
* @return bool
133+
* @return \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface[]
126134
*/
127-
public function canBeIncluded(): bool;
135+
public function getRelations(): array;
128136
}

src/Item.php

Lines changed: 18 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -161,66 +161,12 @@ public function getRelationships(): array
161161
return $relationships;
162162
}
163163

164-
/**
165-
* @TODO: MEGA TODO. Set up a serializer for the Item so that we can remove this, getRelationships etc
166-
*
167-
* @return \Swis\JsonApi\Client\Collection
168-
*/
169-
public function getIncluded(): Collection
170-
{
171-
$included = new Collection();
172-
173-
foreach ($this->relationships as $name => $relationship) {
174-
if ($relationship->shouldOmitIncluded() || !$relationship->hasIncluded()) {
175-
continue;
176-
}
177-
178-
if ($relationship instanceof OneRelationInterface) {
179-
/** @var \Swis\JsonApi\Client\Interfaces\ItemInterface $item */
180-
$item = $relationship->getIncluded();
181-
if ($item->canBeIncluded()) {
182-
$included->push($item->toJsonApiArray());
183-
}
184-
$included = $included->merge($item->getIncluded());
185-
} elseif ($relationship instanceof ManyRelationInterface) {
186-
$relationship->getIncluded()->each(
187-
function (ItemInterface $item) use (&$included) {
188-
if ($item->canBeIncluded()) {
189-
$included->push($item->toJsonApiArray());
190-
}
191-
$included = $included->merge($item->getIncluded());
192-
}
193-
);
194-
}
195-
}
196-
197-
return $included
198-
->unique(
199-
function (array $item) {
200-
return $item['type'].':'.$item['id'];
201-
}
202-
)
203-
->values();
204-
}
205-
206164
/**
207165
* @return bool
208166
*/
209-
public function canBeIncluded(): bool
167+
public function hasRelationships(): bool
210168
{
211-
if (empty($this->getType())) {
212-
return false;
213-
}
214-
215-
if (null === $this->getId()) {
216-
return false;
217-
}
218-
219-
if (empty($this->relationships) && empty($this->toArray())) {
220-
return false;
221-
}
222-
223-
return true;
169+
return !empty($this->getRelationships());
224170
}
225171

226172
/**
@@ -261,6 +207,14 @@ public function hasAttribute($key): bool
261207
return array_key_exists($key, $this->attributes);
262208
}
263209

210+
/**
211+
* @return bool
212+
*/
213+
public function hasAttributes(): bool
214+
{
215+
return !empty($this->toArray());
216+
}
217+
264218
/**
265219
* @param string $key
266220
* @param mixed $value
@@ -510,4 +464,12 @@ public function setRelation(string $relation, DataInterface $value, Links $links
510464

511465
return $this;
512466
}
467+
468+
/**
469+
* @return array
470+
*/
471+
public function getRelations(): array
472+
{
473+
return $this->relationships;
474+
}
513475
}

src/ItemDocumentBuilder.php

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)