Skip to content

Commit

Permalink
Merge pull request #55 from swisnl/feature/change-repository-save
Browse files Browse the repository at this point in the history
Change Repository::save to accept an Item instead of an ItemDocument
  • Loading branch information
JaZo authored Jul 11, 2019
2 parents ada2e66 + dd8627e commit 257824b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 41 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

* Nothing
### Changed

* Change signature of `RepositoryInterface::save()`. It should now receive an `ItemInterface` instead of a `ItemDocumentInterface`.

## [0.19.0] - 2019-07-10

Expand Down
22 changes: 11 additions & 11 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -253,29 +253,22 @@ $repository->all(['include' => 'author', 'page' => ['limit' => 15, 'offset' => 0
```


## DocumentFactory

The `Repository` and `DocumentClient` both require `ItemDocumentInterface` instances when creating or updating resources.
Such documents can easily be created using the `DocumentFactory` by giving it a `DataInterface` instance.
This can be an `ItemInterface`, usually created by the [ItemHydrator](#itemhydrator), or a `Collection`.


## ItemHydrator

The `ItemHydrator` can be used to fill/hydrate an item and its relations using an associative array with attributes.
This is useful if you would like to hydrate an item with POST data from your request:

``` php
$typeMapper = app(Swis\JsonApi\Client\TypeMapper::class);
$itemDocumentBuilder = app(Swis\JsonApi\Client\ItemDocumentBuilder::class);
$itemHydrator = app(Swis\JsonApi\Client\ItemHydrator::class);
$blogRepository = app(App\Repositiories\BlogRepository::class);

$itemDocument = $itemDocumentBuilder->build(
$item = $itemHydrator->hydrate(
$typeMapper->getMapping('blog'),
request()->all(['title', 'author', 'date', 'content', 'tags']),
request()->id
);
$blogRepository->save($itemDocument);
$blogRepository->save($item);
```

### Relations
Expand All @@ -300,7 +293,7 @@ $attributes = [
56,
],
];
$itemDocument = $itemDocumentBuilder->build($typeMapper->getMapping('blog'), $attributes);
$itemDocument = $itemHydrator->hydrate($typeMapper->getMapping('blog'), $attributes);

echo json_encode($itemDocument, JSON_PRETTY_PRINT);

Expand Down Expand Up @@ -376,6 +369,13 @@ It can take everything your request factory takes as input data and returns the
It does not parse or validate the response or hydrate items!


## DocumentFactory

The `DocumentClient` requires `ItemDocumentInterface` instances when creating or updating resources.
Such documents can easily be created using the `DocumentFactory` by giving it a `DataInterface` instance.
This can be an `ItemInterface`, usually created by the [ItemHydrator](#itemhydrator), or a `Collection`.


## Service Provider

The `\Swis\JsonApi\Client\Providers\ServiceProvider` registers the `TypeMapper`, `JsonApi\Parser` and both clients; `Client` and `DocumentClient`.
Expand Down
4 changes: 2 additions & 2 deletions src/Interfaces/RepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public function all();
public function find(string $id);

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemDocumentInterface $document
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
*
* @return \Swis\JsonApi\Client\Interfaces\ItemDocumentInterface
*/
public function save(ItemDocumentInterface $document);
public function save(ItemInterface $item);

/**
* @param string $id
Expand Down
44 changes: 27 additions & 17 deletions src/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Swis\JsonApi\Client;

use Swis\JsonApi\Client\Interfaces\DocumentClientInterface;
use Swis\JsonApi\Client\Interfaces\ItemDocumentInterface;
use Swis\JsonApi\Client\Interfaces\ItemInterface;
use Swis\JsonApi\Client\Interfaces\RepositoryInterface;

class Repository implements RepositoryInterface
Expand All @@ -13,17 +13,24 @@ class Repository implements RepositoryInterface
*/
protected $client;

/**
* @var \Swis\JsonApi\Client\DocumentFactory
*/
protected $documentFactory;

/**
* @var string
*/
protected $endpoint = '';

/**
* @param \Swis\JsonApi\Client\Interfaces\DocumentClientInterface $client
* @param \Swis\JsonApi\Client\DocumentFactory $documentFactory
*/
public function __construct(DocumentClientInterface $client)
public function __construct(DocumentClientInterface $client, DocumentFactory $documentFactory)
{
$this->client = $client;
$this->documentFactory = $documentFactory;
}

/**
Expand Down Expand Up @@ -74,42 +81,45 @@ public function find(string $id, array $parameters = [])
}

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemDocumentInterface $document
* @param array $parameters
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
* @param array $parameters
*
* @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
*/
public function save(ItemDocumentInterface $document, array $parameters = [])
public function save(ItemInterface $item, array $parameters = [])
{
if ($document->getData()->isNew()) {
return $this->saveNew($document, $parameters);
if ($item->isNew()) {
return $this->saveNew($item, $parameters);
}

return $this->saveExisting($document, $parameters);
return $this->saveExisting($item, $parameters);
}

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemDocumentInterface $document
* @param array $parameters
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
* @param array $parameters
*
* @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
*/
protected function saveNew(ItemDocumentInterface $document, array $parameters = [])
protected function saveNew(ItemInterface $item, array $parameters = [])
{
return $this->getClient()->post($this->getEndpoint().'?'.http_build_query($parameters), $document);
return $this->getClient()->post(
$this->getEndpoint().'?'.http_build_query($parameters),
$this->documentFactory->make($item)
);
}

/**
* @param \Swis\JsonApi\Client\Interfaces\ItemDocumentInterface $document
* @param array $parameters
* @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
* @param array $parameters
*
* @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
*/
protected function saveExisting(ItemDocumentInterface $document, array $parameters = [])
protected function saveExisting(ItemInterface $item, array $parameters = [])
{
return $this->getClient()->patch(
$this->getEndpoint().'/'.urlencode($document->getData()->getId()).'?'.http_build_query($parameters),
$document
$this->getEndpoint().'/'.urlencode($item->getId()).'?'.http_build_query($parameters),
$this->documentFactory->make($item)
);
}

Expand Down
21 changes: 11 additions & 10 deletions tests/RepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PHPUnit\Framework\TestCase;
use Swis\JsonApi\Client\Document;
use Swis\JsonApi\Client\DocumentFactory;
use Swis\JsonApi\Client\Interfaces\DocumentClientInterface;
use Swis\JsonApi\Client\Item;
use Swis\JsonApi\Client\ItemDocument;
Expand All @@ -18,7 +19,7 @@ public function it_can_get_the_client()
{
/** @var \PHPUnit\Framework\MockObject\MockObject|\Swis\JsonApi\Client\Interfaces\DocumentClientInterface $client */
$client = $this->getMockBuilder(DocumentClientInterface::class)->getMock();
$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($client, $repository->getClient());
}
Expand All @@ -30,7 +31,7 @@ public function it_can_get_the_endpoint()
{
/** @var \PHPUnit\Framework\MockObject\MockObject|\Swis\JsonApi\Client\Interfaces\DocumentClientInterface $client */
$client = $this->getMockBuilder(DocumentClientInterface::class)->getMock();
$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame('mocks', $repository->getEndpoint());
}
Expand All @@ -50,7 +51,7 @@ public function it_can_get_all()
->with('mocks?foo=bar')
->willReturn($document);

$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($document, $repository->all(['foo' => 'bar']));
}
Expand All @@ -70,7 +71,7 @@ public function it_can_take_one()
->with('mocks?foo=bar')
->willReturn($document);

$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($document, $repository->take(['foo' => 'bar']));
}
Expand All @@ -90,7 +91,7 @@ public function it_can_find_one()
->with('mocks/1?foo=bar')
->willReturn($document);

$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($document, $repository->find(1, ['foo' => 'bar']));
}
Expand All @@ -111,9 +112,9 @@ public function it_can_save_new()
->with('mocks?foo=bar')
->willReturn($document);

$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($document, $repository->save($document, ['foo' => 'bar']));
$this->assertSame($document, $repository->save(new Item(), ['foo' => 'bar']));
}

/**
Expand All @@ -132,9 +133,9 @@ public function it_can_save_existing()
->with('mocks/1?foo=bar')
->willReturn($document);

$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($document, $repository->save($document, ['foo' => 'bar']));
$this->assertSame($document, $repository->save((new Item())->setId(1), ['foo' => 'bar']));
}

/**
Expand All @@ -152,7 +153,7 @@ public function it_can_delete()
->with('mocks/1?foo=bar')
->willReturn($document);

$repository = new MockRepository($client);
$repository = new MockRepository($client, new DocumentFactory());

$this->assertSame($document, $repository->delete(1, ['foo' => 'bar']));
}
Expand Down

0 comments on commit 257824b

Please sign in to comment.