Skip to content

Commit

Permalink
Add relationships collection actions
Browse files Browse the repository at this point in the history
  • Loading branch information
R3VoLuT1OneR committed Apr 16, 2018
1 parent a5189e5 commit da77141
Show file tree
Hide file tree
Showing 39 changed files with 1,545 additions and 226 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,12 @@ Route request `DELETE http://localhost/api/{resourceKey}/{id}`.
Response

HTTP STATUS 204 NO CONTENT

# Development

## Generate doctrine migration diff
We using doctrine migrations for unit tests database schema.

```
php ./vendor/bin/doctrine-migrations migrations:diff
```
4 changes: 4 additions & 0 deletions migrations.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<?php
$loader = require __DIR__ . '/vendor/autoload.php';

\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

return [
'migrations_namespace' => 'Pz\Doctrine\Rest\Tests\Migrations',
'migrations_directory' => __DIR__.'/tests/migrations'
Expand Down
2 changes: 1 addition & 1 deletion src/Doctrine/Rest/Action/DeleteAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class DeleteAction extends RestAction
*/
public function handle($request)
{
$entity = $this->repository()->findByIdentifier($request);
$entity = $this->repository()->findById($request->getId());

$this->authorize($request, $entity);

Expand Down
2 changes: 1 addition & 1 deletion src/Doctrine/Rest/Action/ItemAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ItemAction extends RestAction
*/
public function handle($request)
{
$entity = $this->repository()->findByIdentifier($request);
$entity = $this->repository()->findById($request->getId());

$this->authorize($request, $entity);

Expand Down
75 changes: 75 additions & 0 deletions src/Doctrine/Rest/Action/Related/RelatedCollectionAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php namespace Pz\Doctrine\Rest\Action\Related;

use Pz\Doctrine\Rest\Action\CollectionAction as BaseCollectionAction;
use Pz\Doctrine\Rest\Contracts\RestRequestContract;
use Pz\Doctrine\Rest\RestRepository;

use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\QueryBuilder;
use League\Fractal\TransformerAbstract;
use Pz\Doctrine\Rest\Traits\RelatedAction;

/**
* Action for providing collection (list or array) of data with API.
*/
class RelatedCollectionAction extends BaseCollectionAction
{
use RelatedAction;

/**
* RelatedRestAction constructor.
*
* @param RestRepository $repository
* @param string $mappedBy
* @param RestRepository $related
* @param TransformerAbstract $transformer
*/
public function __construct(RestRepository $repository, $mappedBy, RestRepository $related, $transformer)
{
parent::__construct($repository, $transformer);
$this->mappedBy = $mappedBy;
$this->related = $related;
}

/**
* Related repository used as default repository for collection queries.
*
* @return RestRepository
*/
public function repository()
{
return $this->related;
}

/**
* Base entity repository.
*
* @return RestRepository
*/
public function base()
{
return $this->repository;
}

/**
* Add filter by relation entity.
*
* @param RestRequestContract $request
* @param QueryBuilder $qb
*
* @return $this
* @throws \Pz\Doctrine\Rest\Exceptions\RestException
*/
protected function applyFilter(RestRequestContract $request, QueryBuilder $qb)
{
$entity = $this->base()->findById($request->getId());

$relateCriteria = Criteria::create();
$relateCriteria->andWhere($relateCriteria->expr()->eq($this->mappedBy(), $entity->getId()));

$qb->innerJoin($qb->getRootAliases()[0].'.'.$this->mappedBy(), $this->mappedBy());
$qb->addCriteria($relateCriteria);

parent::applyFilter($request, $qb);
}
}
51 changes: 51 additions & 0 deletions src/Doctrine/Rest/Action/Related/RelatedItemAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php namespace Pz\Doctrine\Rest\Action\Related;

use Pz\Doctrine\Rest\Action\ItemAction as BaseItemAction;
use Pz\Doctrine\Rest\Contracts\RestRequestContract;
use Pz\Doctrine\Rest\Resource\Item;
use Pz\Doctrine\Rest\Resource\NullResource;
use Pz\Doctrine\Rest\RestResponse;
use Pz\Doctrine\Rest\RestRepository;
use Pz\Doctrine\Rest\Traits\RelatedAction;

use League\Fractal\TransformerAbstract;

class RelatedItemAction extends BaseItemAction
{
use RelatedAction;

/**
* RelatedRestAction constructor.
*
* @param RestRepository $repository
* @param string $field
* @param RestRepository $related
* @param TransformerAbstract $transformer
*/
public function __construct(RestRepository $repository, $field, RestRepository $related, $transformer)
{
parent::__construct($repository, $transformer);
$this->related = $related;
$this->field = $field;
}

/**
* @param RestRequestContract $request
*
* @return RestResponse
*/
public function handle($request)
{
$entity = $this->repository()->findById($request->getId());

$this->authorize($request, $entity);

if ($relatedEntity = $this->getProperty($entity, $this->field())) {
return $this->response()->resource($request,
new Item($relatedEntity, $this->transformer())
);
}

return $this->response()->resource($request, new NullResource());
}
}
59 changes: 59 additions & 0 deletions src/Doctrine/Rest/Action/Related/RelatedItemCreateAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php namespace Pz\Doctrine\Rest\Action\Related;

use League\Fractal\TransformerAbstract;
use Pz\Doctrine\Rest\Contracts\JsonApiResource;
use Pz\Doctrine\Rest\Contracts\RestRequestContract;
use Pz\Doctrine\Rest\Exceptions\RestException;
use Pz\Doctrine\Rest\Resource\Item;
use Pz\Doctrine\Rest\RestAction;
use Pz\Doctrine\Rest\RestRepository;
use Pz\Doctrine\Rest\RestResponse;
use Pz\Doctrine\Rest\Traits\CanHydrate;
use Pz\Doctrine\Rest\Traits\RelatedAction;

class RelatedItemCreateAction extends RestAction
{
use RelatedAction;
use CanHydrate;

/**
* RelatedRestAction constructor.
*
* @param RestRepository $repository
* @param string $field
* @param RestRepository $related
* @param TransformerAbstract $transformer
*/
public function __construct(RestRepository $repository, $field, RestRepository $related, $transformer)
{
parent::__construct($repository, $transformer);
$this->related = $related;
$this->field = $field;
}

/**
* @param RestRequestContract $request
*
* @return RestResponse
* @throws RestException
*/
public function handle($request)
{
$entity = $this->repository()->findById($request->getId());
$data = $request->getData();
$this->authorize($request, $entity);

if (isset($data['id']) && isset($data['type'])) {
$item = $this->getRelatedEntity($data);
} else {
$scope = $entity->getResourceKey().'.'.$this->field();
/** @var JsonApiResource $item */
$item = $this->hydrateEntity($this->related()->getClassName(), $data, $scope);
}

$this->setProperty($entity, $this->field(), $item);
$this->repository()->getEntityManager()->flush($entity);

return $this->response()->resource($request, new Item($item, $this->transformer()));
}
}
77 changes: 0 additions & 77 deletions src/Doctrine/Rest/Action/RelatedCollectionAction.php

This file was deleted.

52 changes: 0 additions & 52 deletions src/Doctrine/Rest/Action/RelatedItemAction.php

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php namespace Pz\Doctrine\Rest\Action\Relationships;

use Doctrine\ORM\Tools\Pagination\Paginator;
use League\Fractal\Pagination\DoctrinePaginatorAdapter;
use Pz\Doctrine\Rest\Action\Related\RelatedCollectionAction;
use Pz\Doctrine\Rest\Contracts\RestRequestContract;
use Pz\Doctrine\Rest\Resource\Collection;
use Pz\Doctrine\Rest\RestResponse;

class RelationshipsCollectionAction extends RelatedCollectionAction
{
/**
* @param RestRequestContract $request
*
* @return RestResponse
*/
protected function handle($request)
{
$request->isRelationships(true);
return parent::handle($request);
}
}
Loading

0 comments on commit da77141

Please sign in to comment.