Skip to content
This repository has been archived by the owner on Jan 2, 2023. It is now read-only.

Allow serializers to add links #79

Merged
merged 1 commit into from
Jan 26, 2016
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
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ $document->setMeta(['key' => 'value']);
They also allow you to add links in a similar way:

```php
$resource = new Resource;
$resource = new Resource($data, $serializer);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Resource constructor expects those parameters

$resource->addLink('self', 'url');
$resource->setLinks(['key' => 'value']);
```
Expand All @@ -131,6 +131,19 @@ $document->addPaginationLinks(
100 // The total number of results
);
```
Serializers can provide links as well:

```php
use Tobscure\JsonApi\AbstractSerializer;

class PostSerializer extends AbstractSerializer
{
// ...

public function getLinks($post) {
return ['self' => '/posts/' . $post->id];
}
}

### Parameters

Expand Down
12 changes: 10 additions & 2 deletions src/AbstractSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ public function getAttributes($model, array $fields = null)
return [];
}

/**
* {@inheritdoc}
*/
public function getLinks($model)
{
return [];
}

/**
* {@inheritdoc}
*
Expand All @@ -72,9 +80,9 @@ public function getRelationship($model, $name)
/**
* Removes all dashes from relationsship and uppercases the following letter.
* @example If relationship parent-page is needed the the function name will be changed to parentPage
*
*
* @param string Name of the function
*
*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those trailing whitespaces were removed by my IDE, but I guess this is fine

* @return string New function name
*/
private function replaceDashWithUppercase($name)
Expand Down
10 changes: 9 additions & 1 deletion src/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,16 @@ public function toArray()
$array['relationships'] = $relationships;
}

$links = [];
if (! empty($this->links)) {
$array['links'] = $this->links;
$links = $this->links;
}
$serializerLinks = $this->serializer->getLinks($this->data);
if (! empty($serializerLinks)) {
$links = array_merge($serializerLinks, $links);
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should a Resource instance's links take precedence over the serializer links?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I assumed (and what is covered by a test), but frankly I wasn't really sure about it.. And after thinking about it again it might be more flexible if a serializer can overrule resource links.
In the original patch by @bnchdrff it was also the other way around - should I swap it?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, didn't see the test and misread the order of array_merge arguments – the current behaviour is fine.

if (! empty($links)) {
$array['links'] = $links;
}

return $array;
Expand Down
8 changes: 8 additions & 0 deletions src/SerializerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public function getId($model);
*/
public function getAttributes($model, array $fields = null);

/**
* Get the links array.
*
* @param mixed $model
* @return array
*/
public function getLinks($model);

/**
* Get a relationship.
*
Expand Down
35 changes: 33 additions & 2 deletions tests/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ public function testToArrayReturnsArray()
{
$data = (object) ['id' => '123', 'foo' => 'bar', 'baz' => 'qux'];

$resource = new Resource($data, new PostSerializer4);
$resource = new Resource($data, new PostSerializer4WithLinks);

$this->assertEquals([
'type' => 'posts',
'id' => '123',
'attributes' => [
'foo' => 'bar',
'baz' => 'qux'
]
],
'links' => [
'self' => '/posts/123'
],
], $resource->toArray());
}

Expand Down Expand Up @@ -118,6 +121,27 @@ public function testCanMergeWithAnotherResource()
]
], $resource1->toArray());
}

public function testLinksMergeWithSerializerLinks()
{
$post1 = (object) ['id' => '123', 'foo' => 'bar', 'comments' => [1]];

$resource1 = new Resource($post1, new PostSerializer4WithLinks());
$resource1->addLink('self', 'overridden/by/resource');
$resource1->addLink('related', '/some/other/comment');

$this->assertEquals([
'type' => 'posts',
'id' => '123',
'attributes' => [
'foo' => 'bar'
],
'links' => [
'self' => 'overridden/by/resource',
'related' => '/some/other/comment'
],
], $resource1->toArray());
}
}

class PostSerializer4 extends AbstractSerializer
Expand All @@ -143,6 +167,13 @@ public function comments($post)
return new Relationship(new Collection($post->comments, new CommentSerializer));
}
}
class PostSerializer4WithLinks extends PostSerializer4

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each class must be in a file by itself

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah well.. nit pick yourself ;)

{
public function getLinks($post)
{
return ['self' => sprintf('/posts/%s', $post->id)];
}
}

class CommentSerializer extends AbstractSerializer
{
Expand Down