Skip to content

Commit b8d1ae8

Browse files
authored
Merge pull request #45 from swisnl/feature/improve-relations
Refactor relations
2 parents 5270798 + 7c6eb7c commit b8d1ae8

16 files changed

+204
-275
lines changed

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
66

77
## [Unreleased]
88

9-
* Nothing
9+
This release includes changes to some interfaces. This is a breaking change if you use these interfaces in your own code.
10+
11+
### Added
12+
13+
* Added `OneRelationInterface` and `ManyRelationInterface` to differentiate between singular and plural relations.
14+
15+
### Changed
16+
17+
* Moved `setType` and `getType` from `RelationInterface` to a separate interface; `TypedRelationInterface`.
18+
* Added type hints to `ItemInterface::setRelation`.
19+
* Added return type hint to `Item::hasAttribute`.
20+
21+
### Removed
22+
23+
* Removed `RelationInterface` in favor of `OneRelationInterface` and `ManyRelationInterface`.
24+
* Removed `setId` and `getId` from `HasOneRelation` and `MorphToRelation`. These operations should be performed on the included item.
25+
* Removed `setType` and `getType` from morph relations. Use regular relations if you want to set the type.
1026

1127
## [0.13.0] - 2019-01-14
1228

src/Interfaces/ItemInterface.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,16 @@ public function getAvailableRelations(): array;
7878
/**
7979
* Set the specific relationship in the model.
8080
*
81-
* @param string $relation
82-
* @param mixed $value
81+
* @param string $relation
82+
* @param DataInterface $value
8383
*
8484
* @return static
8585
*/
86-
public function setRelation($relation, $value);
86+
public function setRelation(string $relation, DataInterface $value);
8787

8888
/**
8989
* @TODO: MEGA TODO. Set up a serializer for the Item so that we can remove this, getRelationships etc
9090
*
91-
* @throws \Exception
92-
*
9391
* @return \Swis\JsonApi\Client\Collection
9492
*/
9593
public function getIncluded();
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Swis\JsonApi\Client\Interfaces;
4+
5+
use Swis\JsonApi\Client\Collection;
6+
7+
interface ManyRelationInterface
8+
{
9+
/**
10+
* @param \Swis\JsonApi\Client\Collection $included
11+
*
12+
* @return static
13+
*/
14+
public function associate(Collection $included);
15+
16+
/**
17+
* @return static
18+
*/
19+
public function dissociate();
20+
21+
/**
22+
* @return bool
23+
*/
24+
public function hasIncluded(): bool;
25+
26+
/**
27+
* @return \Swis\JsonApi\Client\Collection
28+
*/
29+
public function getIncluded(): Collection;
30+
31+
/**
32+
* @param bool $omitIncluded
33+
*
34+
* @return static
35+
*/
36+
public function setOmitIncluded(bool $omitIncluded);
37+
38+
/**
39+
* @return bool
40+
*/
41+
public function shouldOmitIncluded(): bool;
42+
}

src/Interfaces/RelationInterface.php renamed to src/Interfaces/OneRelationInterface.php

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,39 @@
22

33
namespace Swis\JsonApi\Client\Interfaces;
44

5-
interface RelationInterface
5+
interface OneRelationInterface
66
{
77
/**
8-
* @return string
9-
*/
10-
public function getType(): string;
11-
12-
/**
13-
* @param string $type
14-
*
15-
* @return static
16-
*/
17-
public function setType(string $type);
18-
19-
/**
20-
* @param \Swis\JsonApi\Client\Interfaces\DataInterface $included
8+
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $included
219
*
2210
* @return static
2311
*/
24-
public function associate(DataInterface $included);
12+
public function associate(ItemInterface $included);
2513

2614
/**
2715
* @return static
2816
*/
2917
public function dissociate();
3018

31-
/**
32-
* @return \Swis\JsonApi\Client\Collection|\Swis\JsonApi\Client\Interfaces\DataInterface|\Swis\JsonApi\Client\Interfaces\ItemInterface|null
33-
*/
34-
public function getIncluded();
35-
3619
/**
3720
* @return bool
3821
*/
3922
public function hasIncluded(): bool;
4023

4124
/**
42-
* @return bool
25+
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
4326
*/
44-
public function shouldOmitIncluded(): bool;
27+
public function getIncluded();
4528

4629
/**
4730
* @param bool $omitIncluded
4831
*
4932
* @return static
5033
*/
5134
public function setOmitIncluded(bool $omitIncluded);
35+
36+
/**
37+
* @return bool
38+
*/
39+
public function shouldOmitIncluded(): bool;
5240
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Swis\JsonApi\Client\Interfaces;
4+
5+
interface TypedRelationInterface
6+
{
7+
/**
8+
* @return string
9+
*/
10+
public function getType(): string;
11+
12+
/**
13+
* @param string $type
14+
*
15+
* @return static
16+
*/
17+
public function setType(string $type);
18+
}

src/Item.php

Lines changed: 33 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
namespace Swis\JsonApi\Client;
44

55
use Jenssegers\Model\Model;
6+
use Swis\JsonApi\Client\Interfaces\DataInterface;
67
use Swis\JsonApi\Client\Interfaces\ItemInterface;
7-
use Swis\JsonApi\Client\Interfaces\RelationInterface;
8+
use Swis\JsonApi\Client\Interfaces\ManyRelationInterface;
9+
use Swis\JsonApi\Client\Interfaces\OneRelationInterface;
810
use Swis\JsonApi\Client\Relations\HasManyRelation;
911
use Swis\JsonApi\Client\Relations\HasOneRelation;
1012
use Swis\JsonApi\Client\Relations\MorphToManyRelation;
@@ -23,14 +25,14 @@ class Item extends Model implements ItemInterface
2325
protected $id;
2426

2527
/**
26-
* Contains the initial values (Which fields are pre-filled on CREATE-form).
28+
* Contains the initial values.
2729
*
2830
* @var array
2931
*/
3032
protected $initial = [];
3133

3234
/**
33-
* @var \Swis\JsonApi\Client\Interfaces\RelationInterface[]
35+
* @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface[]|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface[]
3436
*/
3537
protected $relationships = [];
3638

@@ -135,30 +137,8 @@ public function getRelationships(): array
135137
{
136138
$relationships = [];
137139

138-
/** @var \Swis\JsonApi\Client\Interfaces\RelationInterface $relationship */
139140
foreach ($this->relationships as $name => $relationship) {
140-
if ($relationship instanceof HasOneRelation) {
141-
$relationships[$name] = ['data' => null];
142-
143-
if ($relationship->getIncluded() !== null) {
144-
$relationships[$name] = [
145-
'data' => [
146-
'type' => $relationship->getType(),
147-
'id' => $relationship->getId(),
148-
],
149-
];
150-
}
151-
} elseif ($relationship instanceof HasManyRelation) {
152-
$relationships[$name]['data'] = [];
153-
154-
foreach ($relationship->getIncluded() as $item) {
155-
$relationships[$name]['data'][] =
156-
[
157-
'type' => $relationship->getType(),
158-
'id' => $item->getId(),
159-
];
160-
}
161-
} elseif ($relationship instanceof MorphToRelation) {
141+
if ($relationship instanceof OneRelationInterface) {
162142
$relationships[$name] = ['data' => null];
163143

164144
if ($relationship->getIncluded() !== null) {
@@ -169,7 +149,7 @@ public function getRelationships(): array
169149
],
170150
];
171151
}
172-
} elseif ($relationship instanceof MorphToManyRelation) {
152+
} elseif ($relationship instanceof ManyRelationInterface) {
173153
$relationships[$name]['data'] = [];
174154

175155
foreach ($relationship->getIncluded() as $item) {
@@ -188,8 +168,6 @@ public function getRelationships(): array
188168
/**
189169
* @TODO: MEGA TODO. Set up a serializer for the Item so that we can remove this, getRelationships etc
190170
*
191-
* @throws \Exception
192-
*
193171
* @return \Swis\JsonApi\Client\Collection
194172
*/
195173
public function getIncluded(): Collection
@@ -201,23 +179,22 @@ public function getIncluded(): Collection
201179
continue;
202180
}
203181

204-
$includedFromRelationship = $relationship->getIncluded();
205-
if ($includedFromRelationship instanceof ItemInterface) {
206-
if ($includedFromRelationship->canBeIncluded()) {
207-
$included->push($includedFromRelationship->toJsonApiArray());
182+
if ($relationship instanceof OneRelationInterface) {
183+
/** @var \Swis\JsonApi\Client\Interfaces\ItemInterface $item */
184+
$item = $relationship->getIncluded();
185+
if ($item->canBeIncluded()) {
186+
$included->push($item->toJsonApiArray());
208187
}
209-
$included = $included->merge($includedFromRelationship->getIncluded());
210-
} elseif ($includedFromRelationship instanceof Collection) {
211-
$includedFromRelationship->each(
188+
$included = $included->merge($item->getIncluded());
189+
} elseif ($relationship instanceof ManyRelationInterface) {
190+
$relationship->getIncluded()->each(
212191
function (ItemInterface $item) use (&$included) {
213192
if ($item->canBeIncluded()) {
214193
$included->push($item->toJsonApiArray());
215194
}
216195
$included = $included->merge($item->getIncluded());
217196
}
218197
);
219-
} else {
220-
throw new \Exception('Not yet implemented');
221198
}
222199
}
223200

@@ -269,7 +246,7 @@ public function getAttribute($key)
269246
*
270247
* @return bool
271248
*/
272-
public function hasAttribute($key)
249+
public function hasAttribute($key): bool
273250
{
274251
return array_key_exists($key, $this->attributes);
275252
}
@@ -279,7 +256,7 @@ public function hasAttribute($key)
279256
*
280257
* @param string $key
281258
*
282-
* @return \Swis\JsonApi\Client\Interfaces\DataInterface
259+
* @return \Swis\JsonApi\Client\Interfaces\DataInterface|null
283260
*/
284261
public function getRelationValue($key)
285262
{
@@ -295,6 +272,8 @@ public function getRelationValue($key)
295272
if ($this->hasRelationship($key)) {
296273
return $this->getRelationship($key)->getIncluded();
297274
}
275+
276+
return null;
298277
}
299278

300279
/**
@@ -306,18 +285,15 @@ public function getRelationValue($key)
306285
*/
307286
public function __isset($key)
308287
{
309-
$result = (isset($this->attributes[$key]) || isset($this->relationships[snake_case($key)])) ||
310-
($this->hasGetMutator($key) && !is_null($this->getAttributeValue($key)));
311-
312-
return $result;
288+
return parent::__isset($key) || $this->hasRelationship($key) || $this->hasRelationship(snake_case($key));
313289
}
314290

315291
/**
316-
* @param $name
292+
* @param string $name
317293
*
318-
* @return \Swis\JsonApi\Client\Interfaces\RelationInterface
294+
* @return \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface
319295
*/
320-
public function getRelationship(string $name): RelationInterface
296+
public function getRelationship(string $name)
321297
{
322298
return $this->relationships[$name];
323299
}
@@ -355,10 +331,9 @@ public function removeRelationship(string $name)
355331
public function hasOne(string $class, string $relationName = null)
356332
{
357333
$relationName = $relationName ?: snake_case(debug_backtrace()[1]['function']);
358-
$itemType = (new $class())->getType();
359334

360335
if (!array_key_exists($relationName, $this->relationships)) {
361-
$this->relationships[$relationName] = new HasOneRelation($itemType);
336+
$this->relationships[$relationName] = new HasOneRelation((new $class())->getType());
362337
}
363338

364339
return $this->relationships[$relationName];
@@ -375,10 +350,9 @@ public function hasOne(string $class, string $relationName = null)
375350
public function hasMany(string $class, string $relationName = null)
376351
{
377352
$relationName = $relationName ?: snake_case(debug_backtrace()[1]['function']);
378-
$itemType = (new $class())->getType();
379353

380354
if (!array_key_exists($relationName, $this->relationships)) {
381-
$this->relationships[$relationName] = new HasManyRelation($itemType);
355+
$this->relationships[$relationName] = new HasManyRelation((new $class())->getType());
382356
}
383357

384358
return $this->relationships[$relationName];
@@ -481,24 +455,22 @@ public function getAvailableRelations(): array
481455
}
482456

483457
/**
484-
* Set the specific relationship in the model.
458+
* Set the specific relationship on the model.
485459
*
486-
* @param string $relation
487-
* @param mixed $value
460+
* @param string $relation
461+
* @param \Swis\JsonApi\Client\Interfaces\DataInterface $value
488462
*
489463
* @return static
490464
*/
491-
public function setRelation($relation, $value)
465+
public function setRelation(string $relation, DataInterface $value)
492466
{
493467
if (method_exists($this, $relation)) {
494-
/** @var \Swis\JsonApi\Client\Interfaces\RelationInterface $relationObject */
468+
/** @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface $relationObject */
495469
$relationObject = $this->$relation();
470+
} elseif ($value instanceof Collection) {
471+
$relationObject = $this->morphToMany(snake_case($relation));
496472
} else {
497-
if ($value instanceof Collection) {
498-
$relationObject = $this->morphToMany(snake_case($relation));
499-
} else {
500-
$relationObject = $this->morphTo(snake_case($relation));
501-
}
473+
$relationObject = $this->morphTo(snake_case($relation));
502474
}
503475

504476
$relationObject->associate($value);

0 commit comments

Comments
 (0)