Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure dissociating a related item results in valid JSON #42

Merged
merged 2 commits into from
Jan 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
N.B. This is a breaking change if you implement the interface yourself or extend the `DocumentClient`. [#34](https://github.com/swisnl/json-api-client/pull/34)
* `Repository` doesn't throw exceptions anymore. [#41](https://github.com/swisnl/json-api-client/pull/41)
N.B. This is a breaking change if you catch `DocumentNotFoundException` or `DocumentTypeException`. If you would like the old behaviour, you can simply extend the `Repository` and implement it yourself.
* A HasOne or MorphTo relation do not set a `[relationship]_id` field on the parent when associating a related item.

### Removed

Expand All @@ -27,6 +28,7 @@ N.B. This is a breaking change if you catch these exceptions.
### Fixed

* Do not fail on, but skip relationships without data [#38](https://github.com/swisnl/json-api-client/pull/38)
* Dissociating a related item now produces valid JSON

## [0.11.0] - 2018-12-21

Expand Down
48 changes: 34 additions & 14 deletions src/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,16 @@ public function getRelationships(): array
/** @var \Swis\JsonApi\Client\Interfaces\RelationInterface $relationship */
foreach ($this->relationships as $name => $relationship) {
if ($relationship instanceof HasOneRelation) {
$relationships[$name] = [
'data' => [
'type' => $relationship->getType(),
'id' => $relationship->getId(),
],
];
$relationships[$name] = ['data' => null];

if ($relationship->getIncluded() !== null) {
$relationships[$name] = [
'data' => [
'type' => $relationship->getType(),
'id' => $relationship->getId(),
],
];
}
} elseif ($relationship instanceof HasManyRelation) {
$relationships[$name]['data'] = [];

Expand All @@ -155,12 +159,16 @@ public function getRelationships(): array
];
}
} elseif ($relationship instanceof MorphToRelation) {
$relationships[$name] = [
'data' => [
'type' => $relationship->getIncluded()->getType(),
'id' => $relationship->getIncluded()->getId(),
],
];
$relationships[$name] = ['data' => null];

if ($relationship->getIncluded() !== null) {
$relationships[$name] = [
'data' => [
'type' => $relationship->getIncluded()->getType(),
'id' => $relationship->getIncluded()->getId(),
],
];
}
} elseif ($relationship instanceof MorphToManyRelation) {
$relationships[$name]['data'] = [];

Expand Down Expand Up @@ -302,6 +310,18 @@ public function hasRelationship(string $name): bool
return array_key_exists($name, $this->relationships);
}

/**
* @param $name
*
* @return static
*/
public function removeRelationship(string $name)
{
unset($this->relationships[$name]);

return $this;
}

/**
* Create a singular relation to another item.
*
Expand All @@ -316,7 +336,7 @@ public function hasOne(string $class, string $relationName = null)
$itemType = (new $class())->getType();

if (!array_key_exists($relationName, $this->relationships)) {
$this->relationships[$relationName] = new HasOneRelation($itemType, $this);
$this->relationships[$relationName] = new HasOneRelation($itemType);
}

return $this->relationships[$relationName];
Expand Down Expand Up @@ -354,7 +374,7 @@ public function morphTo(string $relationName = null)
$relationName = $relationName ?: snake_case(debug_backtrace()[1]['function']);

if (!array_key_exists($relationName, $this->relationships)) {
$this->relationships[$relationName] = new MorphToRelation($this);
$this->relationships[$relationName] = new MorphToRelation();
}

return $this->relationships[$relationName];
Expand Down
5 changes: 3 additions & 2 deletions src/Relations/AbstractOneRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
abstract class AbstractOneRelation extends AbstractRelation
{
/**
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface|null
*/
protected $included;

Expand All @@ -33,7 +33,6 @@ public function associate(DataInterface $included)
}

$this->setId($included->getId());
$this->setType($included->getType());

$this->included = $included;

Expand All @@ -45,6 +44,8 @@ public function associate(DataInterface $included)
*/
public function dissociate()
{
$this->setId(null);

$this->included = null;

return $this;
Expand Down
2 changes: 1 addition & 1 deletion src/Relations/AbstractRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function setType(string $type)
}

/**
* @return string|null
* @return string
*/
public function getType(): string
{
Expand Down
44 changes: 2 additions & 42 deletions src/Relations/HasOneRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,13 @@

namespace Swis\JsonApi\Client\Relations;

use Swis\JsonApi\Client\Interfaces\DataInterface;
use Swis\JsonApi\Client\Interfaces\ItemInterface;

class HasOneRelation extends AbstractOneRelation
{
/**
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface
* @param string $type
*/
protected $parentItem;

/**
* @param string $type
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
*/
public function __construct(string $type, ItemInterface $item)
public function __construct(string $type)
{
$this->type = $type;
$this->parentItem = $item;
}

/**
* @param \Swis\JsonApi\Client\Interfaces\DataInterface $included
*
* @throws \InvalidArgumentException
*
* @return $this
*/
public function associate(DataInterface $included)
{
$result = parent::associate($included);

// Set the $relation.'_id' on the parent
$this->parentItem->setAttribute($this->type.'_id', $this->getId());

return $result;
}

/**
* @return $this
*/
public function dissociate()
{
$result = parent::dissociate();

// Remove the $relation.'_id' on the parent
$this->parentItem->setAttribute($this->type.'_id', null);

return $result;
}
}
25 changes: 19 additions & 6 deletions src/Relations/MorphToRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,33 @@

namespace Swis\JsonApi\Client\Relations;

use Swis\JsonApi\Client\Interfaces\ItemInterface;
use Swis\JsonApi\Client\Interfaces\DataInterface;

class MorphToRelation extends AbstractOneRelation
{
/**
* @var \Swis\JsonApi\Client\Interfaces\ItemInterface
* {@inheritdoc}
*/
protected $parentItem;
public function associate(DataInterface $included)
{
parent::associate($included);

/* @var \Swis\JsonApi\Client\Interfaces\ItemInterface $included */

$this->type = $included->getType();

return $this;
}

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
* {@inheritdoc}
*/
public function __construct(ItemInterface $item)
public function dissociate()
{
$this->parentItem = $item;
parent::dissociate();

$this->type = null;

return $this;
}
}
Loading