Skip to content

Keep relationship data when linking items from included #97

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

Merged
merged 1 commit into from
Sep 8, 2022
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
4 changes: 2 additions & 2 deletions src/Concerns/HasRelations.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ public function getRelationValue(string $name): ?DataInterface
// it is a relationship and will load and return the included items in the relationship
$method = Util::stringCamel($name);
if (method_exists($this, $method)) {
return $this->$method()->getIncluded();
return $this->$method()->getAssociated();
}

// If the "attribute" exists as a relationship on the model, we will return
// the included items in the relationship
if ($this->hasRelation($name)) {
return $this->getRelation($name)->getIncluded();
return $this->getRelation($name)->getAssociated();
}

return null;
Expand Down
38 changes: 34 additions & 4 deletions src/Interfaces/ManyRelationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@

interface ManyRelationInterface
{
/**
* @param \Swis\JsonApi\Client\Collection|null $data
*/
public function setData(?Collection $data);

/**
* @return \Swis\JsonApi\Client\Collection|null
*/
public function getData(): ?Collection;

/**
* @return bool
*/
public function hasData(): bool;

/**
* @param \Swis\JsonApi\Client\Collection $included
*/
public function setIncluded(Collection $included);

/**
* @return \Swis\JsonApi\Client\Collection
*/
public function getIncluded(): Collection;

/**
* @return bool
*/
public function hasIncluded(): bool;

/**
* @param \Swis\JsonApi\Client\Collection $included
*
Expand All @@ -23,14 +53,14 @@ public function associate(Collection $included);
public function dissociate();

/**
* @return bool
* @return \Swis\JsonApi\Client\Collection
*/
public function hasIncluded(): bool;
public function getAssociated(): Collection;

/**
* @return \Swis\JsonApi\Client\Collection
* @return bool
*/
public function getIncluded(): Collection;
public function hasAssociated(): bool;

/**
* @param bool $omitIncluded
Expand Down
38 changes: 34 additions & 4 deletions src/Interfaces/OneRelationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@

interface OneRelationInterface
{
/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface|null $data
*/
public function setData(?ItemInterface $data);

/**
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
*/
public function getData(): ?ItemInterface;

/**
* @return bool
*/
public function hasData(): bool;

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface|null $included
*/
public function setIncluded(?ItemInterface $included);

/**
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
*/
public function getIncluded(): ?ItemInterface;

/**
* @return bool
*/
public function hasIncluded(): bool;

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $included
*
Expand All @@ -22,14 +52,14 @@ public function associate(ItemInterface $included);
public function dissociate();

/**
* @return bool
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
*/
public function hasIncluded(): bool;
public function getAssociated(): ?ItemInterface;

/**
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
* @return bool
*/
public function getIncluded(): ?ItemInterface;
public function hasAssociated(): bool;

/**
* @param bool $omitIncluded
Expand Down
14 changes: 7 additions & 7 deletions src/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,26 +248,26 @@ public function getRelationships(): array
$relationships = [];

foreach ($this->getRelations() as $name => $relation) {
if (!$relation->hasIncluded()) {
if (!$relation->hasAssociated()) {
continue;
}

if ($relation instanceof OneRelationInterface) {
$relationships[$name]['data'] = null;

if ($relation->getIncluded() !== null) {
if ($relation->getAssociated() !== null) {
$relationships[$name]['data'] = [
'type' => $relation->getIncluded()->getType(),
'id' => $relation->getIncluded()->getId(),
'type' => $relation->getAssociated()->getType(),
'id' => $relation->getAssociated()->getId(),
];
if ($relation->getIncluded()->getMeta()) {
$relationships[$name]['data']['meta'] = $relation->getIncluded()->getMeta()->toArray();
if ($relation->getAssociated()->getMeta()) {
$relationships[$name]['data']['meta'] = $relation->getAssociated()->getMeta()->toArray();
}
}
} elseif ($relation instanceof ManyRelationInterface) {
$relationships[$name]['data'] = [];

foreach ($relation->getIncluded() as $item) {
foreach ($relation->getAssociated() as $item) {
$data = [
'type' => $item->getType(),
'id' => $item->getId(),
Expand Down
24 changes: 13 additions & 11 deletions src/Parsers/DocumentParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,27 +213,29 @@ function (ItemInterface $item) use ($keyedItems) {
foreach ($item->getRelations() as $name => $relation) {
if ($relation instanceof OneRelationInterface) {
/** @var \Swis\JsonApi\Client\Interfaces\ItemInterface|null $relatedItem */
$relatedItem = $relation->getIncluded();
$relatedItem = $relation->getData();

if ($relatedItem === null) {
continue;
}

$includedItem = $this->getItem($keyedItems, $relatedItem);
if ($includedItem !== null) {
$relation->associate($includedItem);
$relation->setIncluded($includedItem);
}
} elseif ($relation instanceof ManyRelationInterface) {
/** @var \Swis\JsonApi\Client\Collection $relatedCollection */
$relatedCollection = $relation->getIncluded();

/** @var \Swis\JsonApi\Client\Interfaces\ItemInterface $relatedItem */
foreach ($relatedCollection as $key => $relatedItem) {
$includedItem = $this->getItem($keyedItems, $relatedItem);
if ($includedItem !== null) {
$relatedCollection->put($key, $includedItem);
}
/** @var \Swis\JsonApi\Client\Collection|null $relatedCollection */
$relatedCollection = $relation->getData();

if ($relatedCollection === null) {
continue;
}

$relation->setIncluded(
$relatedCollection->map(function (ItemInterface $relatedItem) use ($keyedItems) {
return $this->getItem($keyedItems, $relatedItem) ?? $relatedItem;
})
);
}
}
}
Expand Down
50 changes: 49 additions & 1 deletion src/Relations/AbstractManyRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,37 @@
use Swis\JsonApi\Client\Interfaces\ManyRelationInterface;

/**
* @property \Swis\JsonApi\Client\Collection|false|null $data
* @property \Swis\JsonApi\Client\Collection|false|null $included
*/
abstract class AbstractManyRelation extends AbstractRelation implements ManyRelationInterface
{
/**
* @param \Swis\JsonApi\Client\Collection|null $data
*
* @return $this
*/
public function setData(?Collection $data)
{
$this->data = $data;

return $this;
}

/**
* @return \Swis\JsonApi\Client\Collection|null
*/
public function getData(): ?Collection
{
return $this->data ?: null;
}

/**
* @param \Swis\JsonApi\Client\Collection $included
*
* @return $this
*/
public function associate(Collection $included)
public function setIncluded(Collection $included)
{
$this->included = $included;

Expand All @@ -32,6 +53,33 @@ public function getIncluded(): Collection
return $this->included ?: new Collection();
}

/**
* @param \Swis\JsonApi\Client\Collection $included
*
* @return $this
*/
public function associate(Collection $included)
{
return $this->setData($included)
->setIncluded($included);
}

/**
* @return \Swis\JsonApi\Client\Collection
*/
public function getAssociated(): Collection
{
if ($this->hasIncluded()) {
return $this->getIncluded();
}

if ($this->hasData()) {
return $this->getData();
}

return new Collection();
}

/**
* Sort the included collection by the given key.
* You can also pass your own callback to determine how to sort the collection values.
Expand Down
52 changes: 50 additions & 2 deletions src/Relations/AbstractOneRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,37 @@
use Swis\JsonApi\Client\Interfaces\OneRelationInterface;

/**
* @property \Swis\JsonApi\Client\Interfaces\ItemInterface|false|null $data
* @property \Swis\JsonApi\Client\Interfaces\ItemInterface|false|null $included
*/
abstract class AbstractOneRelation extends AbstractRelation implements OneRelationInterface
{
/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $included
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface|null $data
*
* @return $this
*/
public function associate(ItemInterface $included)
public function setData(?ItemInterface $data)
{
$this->data = $data;

return $this;
}

/**
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
*/
public function getData(): ?ItemInterface
{
return $this->data ?: null;
}

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface|null $included
*
* @return $this
*/
public function setIncluded(?ItemInterface $included)
{
$this->included = $included;

Expand All @@ -31,4 +52,31 @@ public function getIncluded(): ?ItemInterface
{
return $this->included ?: null;
}

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $included
*
* @return $this
*/
public function associate(ItemInterface $included)
{
return $this->setData($included)
->setIncluded($included);
}

/**
* @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
*/
public function getAssociated(): ?ItemInterface
{
if ($this->hasIncluded()) {
return $this->getIncluded();
}

if ($this->hasData()) {
return $this->getData();
}

return null;
}
}
Loading