Skip to content

Compound Documents #10

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 4 commits into from
Mar 29, 2017
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
75 changes: 64 additions & 11 deletions src/Document/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

namespace JsonApiPhp\JsonApi\Document;

use JsonApiPhp\JsonApi\Document\Resource\IdentifiableResource;
use JsonApiPhp\JsonApi\Document\Resource\ResourceObject;
use JsonApiPhp\JsonApi\HasLinksAndMeta;

final class Document implements \JsonSerializable
Expand All @@ -23,11 +25,13 @@ final class Document implements \JsonSerializable

use HasLinksAndMeta;

protected $data;
protected $errors;
protected $meta;
protected $jsonapi;
protected $links;
private $data;
private $errors;
private $meta;
private $jsonapi;
private $links;
private $included;
private $sparse = false;

/**
* Use named constructors instead
Expand All @@ -50,14 +54,14 @@ public static function fromErrors(Error ...$errors): self
return $doc;
}

public static function fromData(PrimaryDataInterface $data): self
public static function fromResource(IdentifiableResource $data): self
{
$doc = new self;
$doc->data = $data;
return $doc;
}

public static function fromDataItems(PrimaryDataItemInterface ...$data): self
public static function fromResources(IdentifiableResource ...$data): self
{
$doc = new self;
$doc->data = $data;
Expand All @@ -74,19 +78,68 @@ public function setApiMeta(array $meta): void
$this->jsonapi['meta'] = $meta;
}

public function setIncluded(IdentifiableResource ...$included)
{
$this->included = $included;
}

public function setSparse()
{
$this->sparse = true;
}

public function jsonSerialize()
{
if ($this->included && !$this->sparse) {
foreach ($this->included as $resource) {
if ($this->hasLinkTo($resource)) {
continue;
}
throw new \LogicException("Full linkage is required for $resource");
}
}
return array_filter(
[
'data' => $this->data,
'errors' => $this->errors,
'meta' => $this->meta,
'data' => $this->data,
'errors' => $this->errors,
'meta' => $this->meta,
'jsonapi' => $this->jsonapi,
'links' => $this->links,
'links' => $this->links,
'included' => $this->included,
],
function ($v) {
return null !== $v;
}
);
}

private function hasLinkTo(IdentifiableResource $resource): bool
{
if (!$this->data) {
return false;
}

foreach ($this->toDataItems() as $my_resource) {
if ($my_resource instanceof ResourceObject) {
if ($my_resource->hasRelationTo($resource)) {
return true;
}
}
}
return false;
}

/**
* @return IdentifiableResource[]
*/
private function toDataItems(): array
{
if ($this->data instanceof IdentifiableResource) {
return [$this->data];
} elseif (is_array($this->data)) {
return $this->data;
} else {
return [];
}
}
}
23 changes: 0 additions & 23 deletions src/Document/PrimaryDataInterface.php

This file was deleted.

19 changes: 0 additions & 19 deletions src/Document/PrimaryDataItemInterface.php

This file was deleted.

29 changes: 29 additions & 0 deletions src/Document/Resource/IdentifiableResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
*
* * This file is part of JSON:API implementation for PHP.
* *
* * (c) Alexey Karapetov <[email protected]>
* *
* * For the full copyright and license information, please view the LICENSE
* * file that was distributed with this source code.
*
*/

namespace JsonApiPhp\JsonApi\Document\Resource;

abstract class IdentifiableResource implements \JsonSerializable
{
protected $id;
protected $type;

public function isEqualTo(IdentifiableResource $that): bool
{
return $this->type === $that->type && $this->id === $that->id;
}

public function __toString()
{
return "$this->type:$this->id";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@

namespace JsonApiPhp\JsonApi\Document\Resource;

use JsonApiPhp\JsonApi\Document\PrimaryDataInterface;

final class NullDataInterface implements PrimaryDataInterface
final class NullData extends IdentifiableResource
{
public function isEqualTo(IdentifiableResource $that): bool
{
return false;
}

public function jsonSerialize()
{
return null;
Expand Down
13 changes: 13 additions & 0 deletions src/Document/Resource/Relationship/Linkage.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace JsonApiPhp\JsonApi\Document\Resource\Relationship;

use JsonApiPhp\JsonApi\Document\Resource\IdentifiableResource;
use JsonApiPhp\JsonApi\Document\Resource\ResourceId;

final class Linkage implements \JsonSerializable
Expand Down Expand Up @@ -50,6 +51,18 @@ public static function fromManyResourceIds(ResourceId ...$data): self
return $linkage;
}

public function isLinkedTo(IdentifiableResource $resource): bool
{
if ($this->data) {
foreach ((array)$this->data as $my_resource) {
if ($resource->isEqualTo($my_resource)) {
return true;
}
}
}
return false;
}

public function jsonSerialize()
{
return $this->data;
Expand Down
17 changes: 13 additions & 4 deletions src/Document/Resource/Relationship/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@

namespace JsonApiPhp\JsonApi\Document\Resource\Relationship;

use JsonApiPhp\JsonApi\Document\Resource\IdentifiableResource;
use JsonApiPhp\JsonApi\HasLinksAndMeta;

final class Relationship implements \JsonSerializable
{
use HasLinksAndMeta;

private $data;
/**
* @var Linkage
*/
private $linkage = null;
private $meta;
private $links;

Expand Down Expand Up @@ -49,18 +53,23 @@ public static function fromRelatedLink(string $link, array $meta = null): self
return $r;
}

public static function fromLinkage(Linkage $data): self
public static function fromLinkage(Linkage $linkage): self
{
$r = new self;
$r->data = $data;
$r->linkage = $linkage;
return $r;
}

public function isLinkedTo(IdentifiableResource $resource): bool
{
return ($this->linkage && $this->linkage->isLinkedTo($resource));
}

public function jsonSerialize()
{
return array_filter(
[
'data' => $this->data,
'data' => $this->linkage,
'links' => $this->links,
'meta' => $this->meta,
],
Expand Down
6 changes: 1 addition & 5 deletions src/Document/Resource/ResourceId.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@

namespace JsonApiPhp\JsonApi\Document\Resource;

use JsonApiPhp\JsonApi\Document\PrimaryDataInterface;
use JsonApiPhp\JsonApi\Document\PrimaryDataItemInterface;
use JsonApiPhp\JsonApi\HasMeta;

final class ResourceId implements PrimaryDataInterface, PrimaryDataItemInterface
final class ResourceId extends IdentifiableResource
{
use HasMeta;

private $type;
private $id;
private $meta;

public function __construct(string $type, string $id = null, array $meta = [])
Expand Down
34 changes: 24 additions & 10 deletions src/Document/Resource/ResourceObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@

namespace JsonApiPhp\JsonApi\Document\Resource;

use JsonApiPhp\JsonApi\Document\PrimaryDataInterface;
use JsonApiPhp\JsonApi\Document\PrimaryDataItemInterface;
use JsonApiPhp\JsonApi\Document\Resource\Relationship\Relationship;
use JsonApiPhp\JsonApi\HasLinksAndMeta;

final class ResourceObject implements PrimaryDataInterface, PrimaryDataItemInterface
final class ResourceObject extends IdentifiableResource
{
use HasLinksAndMeta;

private $id;
private $type;
private $meta;
private $links;
private $attributes;
Expand Down Expand Up @@ -55,16 +51,34 @@ public function setRelationship(string $name, Relationship $relationship): void
$this->relationships[$name] = $relationship;
}

public function hasRelationTo(IdentifiableResource $resource): bool
{
if ($this->relationships) {
/** @var Relationship $relationship */
foreach ($this->relationships as $relationship) {
if ($relationship->isLinkedTo($resource)) {
return true;
}
}
}
return false;
}

public function toId(): ResourceId
{
return new ResourceId($this->type, $this->id);
}

public function jsonSerialize()
{
return array_filter(
[
'type' => $this->type,
'id' => $this->id,
'attributes' => $this->attributes,
'type' => $this->type,
'id' => $this->id,
'attributes' => $this->attributes,
'relationships' => $this->relationships,
'links' => $this->links,
'meta' => $this->meta,
'links' => $this->links,
'meta' => $this->meta,
],
function ($v) {
return null !== $v;
Expand Down
Loading