* refactored with entity service, so the code can be tested

This commit is contained in:
Danyi Dávid 2016-08-01 17:30:43 +02:00
parent f3939bbd13
commit 2de0bf8add
35 changed files with 359 additions and 215 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
composer.phar composer.phar
phpunit.xml phpunit.xml
vendor/ vendor/
nbproject/private/

View File

@ -21,6 +21,7 @@ return [
Helper\UrlHelper::class => Helper\UrlHelperFactory::class, Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
'doctrine.entity_manager.orm_default' => \ContainerInteropDoctrine\EntityManagerFactory::class, 'doctrine.entity_manager.orm_default' => \ContainerInteropDoctrine\EntityManagerFactory::class,
'doctrine.hydrator' => \App\Hydrator\DoctrineObjectFactory::class, 'doctrine.hydrator' => \App\Hydrator\DoctrineObjectFactory::class,
\App\Service\Article\ArticleService::class => \App\Service\Article\ArticleServiceFactory::class,
], ],
], ],
]; ];

View File

@ -2,8 +2,7 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Entity\Article; use App\Service\EntityServiceInterface;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -12,38 +11,27 @@ class DeleteAction
{ {
/** /**
* @var EntityManager * @var EntityServiceInterface
*/ */
private $em; private $entityService;
public function __construct(EntityManager $em) public function __construct(EntityServiceInterface $entityService)
{ {
$this->em = $em; $this->entityService = $entityService;
} }
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
$id = $request->getAttribute('id'); $id = $request->getAttribute('id');
if (null === ($entity = $this->em->find(Article::class, $id))) { $result = $this->entityService->delete($id);
$ret = new JsonResponse([
'success' => false $return = new JsonResponse($result);
]);
return $ret->withStatus(404); if (false === $result) {
return $return->withStatus(500, 'Failed to delete record.');
} }
try { return $return;
$this->em->remove($entity);
$this->em->flush();
} catch (\Exception $ex) {
$ret = new JsonResponse([
'success' => false
]);
return $ret->withStatus(500);
}
return new JsonResponse([
'success' => true,
]);
} }
} }

View File

@ -2,16 +2,16 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFactory;
use App\Action\Article\DeleteAction; use App\Action\Article\DeleteAction;
use App\Service\Article\ArticleService;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
class DeleteFactory extends AbstractFactory class DeleteFactory
{ {
public function __invoke(ContainerInterface $container) public function __invoke(ContainerInterface $container)
{ {
$em = $this->getEntityManager($container); $entityService = $container->get(ArticleService::class);
return new DeleteAction($em); return new DeleteAction($entityService);
} }
} }

View File

@ -2,9 +2,7 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Entity\Article; use App\Service\EntityServiceInterface;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -13,39 +11,25 @@ class GetAction
{ {
/** /**
* @var EntityManager * @var EntityServiceInterface
*/ */
private $em; private $entityService;
public function __construct(EntityManager $em) public function __construct(EntityServiceInterface $entityService)
{ {
$this->em = $em; $this->entityService = $entityService;
} }
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
$id = $request->getAttribute('id'); $id = $request->getAttribute('id');
$qb = $this->em->createQueryBuilder(); $entity = $this->entityService->get($id);
$entity = $qb->select('a,u,c')
->from(Article::class, 'a')
->leftJoin('a.author', 'u')
->leftJoin('a.comments', 'c')
->where('a.id = :aid')
->setParameter('aid', $id)
->getQuery()
->getOneOrNullResult(Query::HYDRATE_ARRAY);
if (null === $entity) { if (null === $entity) {
$ret = new JsonResponse([ $ret = new JsonResponse(false);
'success' => false
]);
return $ret->withStatus(404); return $ret->withStatus(404);
} }
return new JsonResponse([ return new JsonResponse($entity);
'success' => true,
'result' => $entity,
]);
} }
} }

View File

@ -2,16 +2,16 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFactory;
use App\Action\Article\GetAction; use App\Action\Article\GetAction;
use App\Service\Article\ArticleService;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
class GetFactory extends AbstractFactory class GetFactory
{ {
public function __invoke(ContainerInterface $container) public function __invoke(ContainerInterface $container)
{ {
$em = $this->getEntityManager($container); $entityService = $container->get(ArticleService::class);
return new GetAction($em); return new GetAction($entityService);
} }
} }

View File

@ -2,8 +2,7 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Entity\Article; use App\Service\EntityServiceInterface;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -12,28 +11,17 @@ class ListAction
{ {
/** /**
* @var EntityManager * @var EntityServiceInterface
*/ */
private $em; private $entityService;
public function __construct(EntityManager $em) public function __construct(EntityServiceInterface $entityService)
{ {
$this->em = $em; $this->entityService = $entityService;
} }
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
$qb = $this->em->createQueryBuilder(); return new JsonResponse($this->entityService->getList());
$entities = $qb->select('a,u,c')
->from(Article::class, 'a')
->leftJoin('a.author', 'u')
->leftJoin('a.comments', 'c')
->getQuery()
->getArrayResult();
return new JsonResponse([
'success' => true,
'result' => $entities,
]);
} }
} }

View File

@ -2,16 +2,16 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFactory;
use App\Action\Article\ListAction; use App\Action\Article\ListAction;
use App\Service\Article\ArticleService;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
class ListFactory extends AbstractFactory class ListFactory
{ {
public function __invoke(ContainerInterface $container) public function __invoke(ContainerInterface $container)
{ {
$em = $this->getEntityManager($container); $entityService = $container->get(ArticleService::class);
return new ListAction($em); return new ListAction($entityService);
} }
} }

View File

@ -3,9 +3,7 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFormAction; use App\Action\AbstractFormAction;
use App\Entity\Article; use App\Service\EntityServiceInterface;
use App\Hydrator\DoctrineObject;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -14,32 +12,26 @@ class PostAction extends AbstractFormAction
{ {
/** /**
* @var EntityManager * @var EntityServiceInterface
*/ */
private $em; private $entityService;
/** public function __construct(EntityServiceInterface $entityService)
* @var DoctrineObject
*/
private $hydrator;
public function __construct(EntityManager $em, DoctrineObject $hydrator)
{ {
$this->em = $em; $this->entityService = $entityService;
$this->hydrator = $hydrator;
} }
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
$data = $this->getRequestData($request); $data = $this->getRequestData($request);
$entity = $this->hydrator->hydrate($data, new Article()); $result = $this->entityService->create($data);
$this->em->persist($entity);
$this->em->flush();
return new JsonResponse([ if (false === $result) {
'success' => true, $result = new JsonResponse(false);
'result' => $entity, return $result->withStatus(500, 'Failed to insert record.');
]); }
return new JsonResponse($result);
} }
} }

View File

@ -2,17 +2,16 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFactory;
use App\Action\Article\PostAction; use App\Action\Article\PostAction;
use App\Service\Article\ArticleService;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
class PostFactory extends AbstractFactory class PostFactory
{ {
public function __invoke(ContainerInterface $container) public function __invoke(ContainerInterface $container)
{ {
$em = $this->getEntityManager($container); $entityService = $container->get(ArticleService::class);
$hydrator = $this->getDoctrineHydrator($container); return new PostAction($entityService);
return new PostAction($em, $hydrator);
} }
} }

View File

@ -3,9 +3,7 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFormAction; use App\Action\AbstractFormAction;
use App\Entity\Article; use App\Service\EntityServiceInterface;
use App\Hydrator\DoctrineObject;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -14,40 +12,27 @@ class PutAction extends AbstractFormAction
{ {
/** /**
* @var EntityManager * @var EntityServiceInterface
*/ */
private $em; private $entityService;
/** public function __construct(EntityServiceInterface $entityService)
* @var DoctrineObject
*/
private $hydrator;
public function __construct(EntityManager $em, DoctrineObject $hydrator)
{ {
$this->em = $em; $this->entityService = $entityService;
$this->hydrator = $hydrator;
} }
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
$id = $request->getAttribute('id', false); $id = $request->getAttribute('id', false);
$data = $this->getRequestData($request);
if (null === ($entity = $this->em->find(Article::class, $id))) { $result = $this->entityService->modify($id, $data);
$ret = new JsonResponse([
'success' => false if (false === $result) {
]); $result = new JsonResponse(false);
return $ret->withStatus(404); return $result->withStatus(500, 'Failed to update record.');
} }
$data = $this->getRequestData($request); return new JsonResponse($result);
$entity = $this->hydrator->hydrate($data, $entity);
$this->em->persist($entity);
$this->em->flush();
return new JsonResponse([
'success' => true,
'result' => $entity,
]);
} }
} }

View File

@ -2,17 +2,16 @@
namespace App\Action\Article; namespace App\Action\Article;
use App\Action\AbstractFactory;
use App\Action\Article\PutAction; use App\Action\Article\PutAction;
use App\Service\Article\ArticleService;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
class PutFactory extends AbstractFactory class PutFactory
{ {
public function __invoke(ContainerInterface $container) public function __invoke(ContainerInterface $container)
{ {
$em = $this->getEntityManager($container); $entityService = $container->get(ArticleService::class);
$hydrator = $this->getDoctrineHydrator($container); return new PutAction($entityService);
return new PutAction($em, $hydrator);
} }
} }

View File

@ -2,9 +2,6 @@
namespace App\Action; namespace App\Action;
use App\Entity\User;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
@ -12,32 +9,10 @@ use Zend\Diactoros\Response\JsonResponse;
class HomePageAction class HomePageAction
{ {
/**
* @var EntityManager
*/
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
$qb = $this->em->createQueryBuilder();
$user = $qb->select('u, a, ac, uc')
->from(User::class, 'u')
->leftJoin('u.comments', 'uc')
->leftJoin('u.articles', 'a')
->leftJoin('a.comments', 'ac')
->where('u.id = :uid')
->setParameter('uid', 1)
->getQuery()
->getSingleResult(Query::HYDRATE_ARRAY);
return new JsonResponse([ return new JsonResponse([
'welcome' => 'Congratulations! You have reached our API endpoint.', 'welcome' => 'Congratulations! You have reached our API endpoint.',
'user' => $user,
]); ]);
} }
} }

View File

@ -10,7 +10,6 @@ class HomePageFactory
public function __invoke(ContainerInterface $container) public function __invoke(ContainerInterface $container)
{ {
$em = $container->get('doctrine.entity_manager.orm_default'); return new HomePageAction();
return new HomePageAction($em);
} }
} }

View File

@ -8,6 +8,7 @@ use Psr\Http\Message\ServerRequestInterface;
class PingAction class PingAction
{ {
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{ {
return new JsonResponse(['ack' => time()]); return new JsonResponse(['ack' => time()]);

View File

@ -12,7 +12,9 @@ use JsonSerializable;
*/ */
class Article implements JsonSerializable class Article implements JsonSerializable
{ {
use Traits\GetterSetter; use Traits\GetterSetter;
/** /**
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")

View File

@ -12,7 +12,9 @@ use JsonSerializable;
*/ */
class Comment implements JsonSerializable class Comment implements JsonSerializable
{ {
use Traits\GetterSetter; use Traits\GetterSetter;
/** /**
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")

View File

@ -2,7 +2,7 @@
namespace App\Entity\Traits; namespace App\Entity\Traits;
Trait GetterSetter trait GetterSetter
{ {
/** /**
@ -14,7 +14,7 @@ Trait GetterSetter
protected function getterName($field) protected function getterName($field)
{ {
return sprintf('get%s', ucfirst( return sprintf('get%s', ucfirst(
str_replace(' ', '', ucwords(str_replace('_', ' ', $field))) str_replace(' ', '', ucwords(str_replace('_', ' ', $field)))
)); ));
} }
@ -27,7 +27,7 @@ Trait GetterSetter
protected function setterName($field) protected function setterName($field)
{ {
return sprintf('set%s', ucfirst( return sprintf('set%s', ucfirst(
str_replace(' ', '', ucwords(str_replace('_', ' ', $field))) str_replace(' ', '', ucwords(str_replace('_', ' ', $field)))
)); ));
} }

View File

@ -12,7 +12,9 @@ use JsonSerializable;
*/ */
class User implements JsonSerializable class User implements JsonSerializable
{ {
use Traits\GetterSetter; use Traits\GetterSetter;
/** /**
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")

View File

@ -175,7 +175,7 @@ class DoctrineObject extends AbstractHydrator
? $object->getFilter() ? $object->getFilter()
: $this->filterComposite; : $this->filterComposite;
$data = array(); $data = [];
foreach ($fieldNames as $fieldName) { foreach ($fieldNames as $fieldName) {
if ($filter && !$filter->filter($fieldName)) { if ($filter && !$filter->filter($fieldName)) {
continue; continue;
@ -216,7 +216,7 @@ class DoctrineObject extends AbstractHydrator
? $object->getFilter() ? $object->getFilter()
: $this->filterComposite; : $this->filterComposite;
$data = array(); $data = [];
foreach ($fieldNames as $fieldName) { foreach ($fieldNames as $fieldName) {
if ($filter && !$filter->filter($fieldName)) { if ($filter && !$filter->filter($fieldName)) {
continue; continue;
@ -347,7 +347,7 @@ class DoctrineObject extends AbstractHydrator
{ {
$metadata = $this->metadata; $metadata = $this->metadata;
$identifierNames = $metadata->getIdentifierFieldNames($object); $identifierNames = $metadata->getIdentifierFieldNames($object);
$identifierValues = array(); $identifierValues = [];
if (empty($identifierNames)) { if (empty($identifierNames)) {
return $object; return $object;
@ -417,11 +417,10 @@ class DoctrineObject extends AbstractHydrator
$values = (array)$values; $values = (array)$values;
} }
$collection = array(); $collection = [];
// If the collection contains identifiers, fetch the objects from database // If the collection contains identifiers, fetch the objects from database
foreach ($values as $value) { foreach ($values as $value) {
if ($value instanceof $target) { if ($value instanceof $target) {
// assumes modifications have already taken place in object // assumes modifications have already taken place in object
$collection[] = $value; $collection[] = $value;
@ -432,7 +431,7 @@ class DoctrineObject extends AbstractHydrator
continue; continue;
} }
$find = array(); $find = [];
if (is_array($identifier)) { if (is_array($identifier)) {
foreach ($identifier as $field) { foreach ($identifier as $field) {
switch (gettype($value)) { switch (gettype($value)) {

View File

@ -36,7 +36,7 @@ class PropertyName implements FilterInterface
* *
* @var array * @var array
*/ */
protected $properties = array(); protected $properties = [];
/** /**
* Either an exclude or an include. * Either an exclude or an include.
@ -54,7 +54,7 @@ class PropertyName implements FilterInterface
$this->exclude = $exclude; $this->exclude = $exclude;
$this->properties = is_array($properties) $this->properties = is_array($properties)
? $properties ? $properties
: array($properties); : [$properties];
} }
public function filter($property) public function filter($property)

View File

@ -42,8 +42,8 @@ class AllowRemoveByReference extends AbstractCollectionStrategy
$collection = $this->getCollectionFromObjectByReference(); $collection = $this->getCollectionFromObjectByReference();
$collectionArray = $collection->toArray(); $collectionArray = $collection->toArray();
$toAdd = array_udiff($value, $collectionArray, array($this, 'compareObjects')); $toAdd = array_udiff($value, $collectionArray, [$this, 'compareObjects']);
$toRemove = array_udiff($collectionArray, $value, array($this, 'compareObjects')); $toRemove = array_udiff($collectionArray, $value, [$this, 'compareObjects']);
foreach ($toAdd as $element) { foreach ($toAdd as $element) {
$collection->add($element); $collection->add($element);

View File

@ -65,8 +65,8 @@ class AllowRemoveByValue extends AbstractCollectionStrategy
$collection = $collection->toArray(); $collection = $collection->toArray();
} }
$toAdd = new ArrayCollection(array_udiff($value, $collection, array($this, 'compareObjects'))); $toAdd = new ArrayCollection(array_udiff($value, $collection, [$this, 'compareObjects']));
$toRemove = new ArrayCollection(array_udiff($collection, $value, array($this, 'compareObjects'))); $toRemove = new ArrayCollection(array_udiff($collection, $value, [$this, 'compareObjects']));
$this->object->$adder($toAdd); $this->object->$adder($toAdd);
$this->object->$remover($toRemove); $this->object->$remover($toRemove);

View File

@ -42,7 +42,7 @@ class DisallowRemoveByReference extends AbstractCollectionStrategy
$collection = $this->getCollectionFromObjectByReference(); $collection = $this->getCollectionFromObjectByReference();
$collectionArray = $collection->toArray(); $collectionArray = $collection->toArray();
$toAdd = array_udiff($value, $collectionArray, array($this, 'compareObjects')); $toAdd = array_udiff($value, $collectionArray, [$this, 'compareObjects']);
foreach ($toAdd as $element) { foreach ($toAdd as $element) {
$collection->add($element); $collection->add($element);

View File

@ -63,7 +63,7 @@ class DisallowRemoveByValue extends AbstractCollectionStrategy
$collection = $collection->toArray(); $collection = $collection->toArray();
} }
$toAdd = new ArrayCollection(array_udiff($value, $collection, array($this, 'compareObjects'))); $toAdd = new ArrayCollection(array_udiff($value, $collection, [$this, 'compareObjects']));
$this->object->$adder($toAdd); $this->object->$adder($toAdd);

View File

@ -1,15 +1,17 @@
<?php <?php
namespace App\Action; namespace App\Service;
use App\Hydrator\DoctrineObject;
use Doctrine\ORM\EntityManager;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
abstract class AbstractFactory abstract class AbstractEntityServiceFactory
{ {
/** /**
* @param ContainerInterface $container * @param ContainerInterface $container
* @return \Doctrine\ORM\EntityManager * @return EntityManager
*/ */
protected function getEntityManager(ContainerInterface $container) protected function getEntityManager(ContainerInterface $container)
{ {
@ -18,7 +20,7 @@ abstract class AbstractFactory
/** /**
* @param ContainerInterface $container * @param ContainerInterface $container
* @return \App\Hydrator\DoctrineObject * @return DoctrineObject
*/ */
protected function getDoctrineHydrator(ContainerInterface $container) protected function getDoctrineHydrator(ContainerInterface $container)
{ {

View File

@ -0,0 +1,99 @@
<?php
namespace App\Service\Article;
use App\Entity\Article;
use App\Hydrator\DoctrineObject;
use App\Service\EntityServiceInterface;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query;
use Exception;
class ArticleService implements EntityServiceInterface
{
/**
* @var EntityManager
*/
private $em;
/**
* @var DoctrineObject
*/
private $hydrator;
public function __construct(EntityManager $em, DoctrineObject $hydrator)
{
$this->em = $em;
$this->hydrator = $hydrator;
}
public function getList()
{
$qb = $this->em->createQueryBuilder();
$entities = $qb->select('a,u,c')
->from(Article::class, 'a')
->leftJoin('a.author', 'u')
->leftJoin('a.comments', 'c')
->getQuery()
->getArrayResult();
return $entities;
}
public function get($id)
{
$qb = $this->em->createQueryBuilder();
$entity = $qb->select('a,u,c')
->from(Article::class, 'a')
->leftJoin('a.author', 'u')
->leftJoin('a.comments', 'c')
->where('a.id = :aid')
->setParameter('aid', $id)
->getQuery()
->getOneOrNullResult(Query::HYDRATE_ARRAY);
return $entity;
}
public function create($data)
{
$entity = $this->hydrator->hydrate($data, new Article());
try {
$this->em->persist($entity);
$this->em->flush();
} catch (Exception $ex) {
return false;
}
return $entity;
}
public function modify($id, $data)
{
if (null === ($entity = $this->em->find(Article::class, $id))) {
return false;
}
$entity = $this->hydrator->hydrate($data, $entity);
$this->em->persist($entity);
$this->em->flush();
return $entity;
}
public function delete($id)
{
if (null === ($entity = $this->em->find(Article::class, $id))) {
return false;
}
try {
$this->em->remove($entity);
$this->em->flush();
} catch (Exception $ex) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Service\Article;
use Interop\Container\ContainerInterface;
class ArticleServiceFactory extends \App\Service\AbstractEntityServiceFactory
{
public function __invoke(ContainerInterface $container)
{
$em = $this->getEntityManager($container);
$hydrator = $this->getDoctrineHydrator($container);
return new ArticleService($em, $hydrator);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Service;
use App\Hydrator\DoctrineObject;
use Doctrine\ORM\EntityManager;
interface EntityServiceInterface
{
public function __construct(EntityManager $em, DoctrineObject $hydrator);
public function getList();
public function get($id);
public function create($data);
public function modify($id, $data);
public function delete($id);
}

View File

@ -0,0 +1,38 @@
<?php
namespace AppTest\Action\Article;
use App\Action\Article\ListAction;
use App\Entity\User;
use App\Service\Article\ArticleService;
use App\Service\EntityServiceInterface;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest;
class ListActionTest extends \PHPUnit_Framework_TestCase
{
/** @var EntityServiceInterface */
protected $entityService;
protected function setUp()
{
$user = new User();
$entityService = $this->prophesize(ArticleService::class);
$entityService->willImplement(EntityServiceInterface::class);
$entityService->getList()->willReturn([]);
$this->entityService = $entityService;
}
public function testResponse()
{
$page = new ListAction($this->entityService->reveal());
$response = $page(new ServerRequest(['/api/article']), new Response(), function () {
});
$this->assertTrue($response instanceof Response);
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace AppTest\Action\Article;
use App\Action\Article\ListAction;
use App\Action\Article\ListFactory;
use App\Service\Article\ArticleService;
use Interop\Container\ContainerInterface;
use Zend\Expressive\Template\TemplateRendererInterface;
class ListFactoryTest extends \PHPUnit_Framework_TestCase
{
/** @var ContainerInterface */
protected $container;
protected function setUp()
{
$this->container = $this->prophesize(ContainerInterface::class);
$articleService = $this->prophesize(ArticleService::class);
$this->container->get(ArticleService::class)->willReturn($articleService);
}
public function testFactoryWithoutTemplate()
{
$factory = new ListFactory();
$this->container->has(TemplateRendererInterface::class)->willReturn(false);
$this->assertTrue($factory instanceof ListFactory);
$page = $factory($this->container->reveal());
$this->assertTrue($page instanceof ListAction);
}
public function testFactoryWithTemplate()
{
$factory = new ListFactory();
$this->container->has(TemplateRendererInterface::class)->willReturn(true);
$this->container
->get(TemplateRendererInterface::class)
->willReturn($this->prophesize(TemplateRendererInterface::class));
$this->assertTrue($factory instanceof ListFactory);
$homePage = $factory($this->container->reveal());
$this->assertTrue($homePage instanceof ListAction);
}
}

View File

@ -5,22 +5,21 @@ namespace AppTest\Action;
use App\Action\HomePageAction; use App\Action\HomePageAction;
use Zend\Diactoros\Response; use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequest;
use Zend\Expressive\Router\RouterInterface; use Doctrine\ORM\EntityManager;
class HomePageActionTest extends \PHPUnit_Framework_TestCase class HomePageActionTest extends \PHPUnit_Framework_TestCase
{ {
/** @var RouterInterface */
protected $router;
protected function setUp() protected function setUp()
{ {
$this->router = $this->prophesize(RouterInterface::class);
} }
public function testResponse() public function testResponse()
{ {
$homePage = new HomePageAction($this->router->reveal(), null); $homePage = new HomePageAction();
$response = $homePage(new ServerRequest(['/']), new Response(), function () { $response = $homePage(new ServerRequest(['/']), new Response(), function () {
}); });
$this->assertTrue($response instanceof Response); $this->assertTrue($response instanceof Response);

View File

@ -5,7 +5,7 @@ namespace AppTest\Action;
use App\Action\HomePageAction; use App\Action\HomePageAction;
use App\Action\HomePageFactory; use App\Action\HomePageFactory;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
use Zend\Expressive\Router\RouterInterface; use Doctrine\ORM\EntityManager;
use Zend\Expressive\Template\TemplateRendererInterface; use Zend\Expressive\Template\TemplateRendererInterface;
class HomePageFactoryTest extends \PHPUnit_Framework_TestCase class HomePageFactoryTest extends \PHPUnit_Framework_TestCase
@ -16,9 +16,9 @@ class HomePageFactoryTest extends \PHPUnit_Framework_TestCase
protected function setUp() protected function setUp()
{ {
$this->container = $this->prophesize(ContainerInterface::class); $this->container = $this->prophesize(ContainerInterface::class);
$router = $this->prophesize(RouterInterface::class); $em = $this->prophesize(EntityManager::class);
$this->container->get(RouterInterface::class)->willReturn($router); $this->container->get('doctrine.entity_manager.orm_default')->willReturn($em);
} }
public function testFactoryWithoutTemplate() public function testFactoryWithoutTemplate()