* api implementation

* no auth yet
* images renamed to reflect name-prefix changes
* yearservice now gets years from judge data
This commit is contained in:
Dávid Danyi 2018-05-11 18:21:48 +02:00
parent be7bc7279d
commit 064b614ba8
23 changed files with 227 additions and 57 deletions

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -69,7 +69,7 @@ class Awardee implements JsonSerializable
* @param int $id * @param int $id
* @return Awardee * @return Awardee
*/ */
public function setId(int $id): Awardee public function setId(?int $id): Awardee
{ {
$this->id = $id; $this->id = $id;
return $this; return $this;
@ -78,7 +78,7 @@ class Awardee implements JsonSerializable
/** /**
* @return int * @return int
*/ */
public function getYear(): int public function getYear(): ?int
{ {
return $this->year; return $this->year;
} }
@ -96,7 +96,7 @@ class Awardee implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getName(): string public function getName(): ?string
{ {
return $this->name; return $this->name;
} }
@ -114,7 +114,7 @@ class Awardee implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getText(): string public function getText(): ?string
{ {
return $this->text; return $this->text;
} }
@ -132,7 +132,7 @@ class Awardee implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getImageLabel(): string public function getImageLabel(): ?string
{ {
return $this->imageLabel; return $this->imageLabel;
} }
@ -141,7 +141,7 @@ class Awardee implements JsonSerializable
* @param string $imageLabel * @param string $imageLabel
* @return Awardee * @return Awardee
*/ */
public function setImageLabel(string $imageLabel): Awardee public function setImageLabel(?string $imageLabel): Awardee
{ {
$this->imageLabel = $imageLabel; $this->imageLabel = $imageLabel;
return $this; return $this;
@ -150,7 +150,7 @@ class Awardee implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getSlug(): string public function getSlug(): ?string
{ {
return $this->slug; return $this->slug;
} }

View File

@ -34,6 +34,12 @@ class Judge implements JsonSerializable
*/ */
private $name; private $name;
/**
* @ORM\Column(name="prefix", type="string", length=14, nullable=true)
* @var string
*/
private $prefix;
/** /**
* @ORM\Column(name="slug", type="string", length=250) * @ORM\Column(name="slug", type="string", length=250)
* @Gedmo\Slug(fields={"name"}) * @Gedmo\Slug(fields={"name"})
@ -42,12 +48,11 @@ class Judge implements JsonSerializable
private $slug; private $slug;
/** /**
* @ORM\OneToMany(targetEntity="JudgeTitle", mappedBy="judge") * @ORM\OneToMany(targetEntity="JudgeTitle", mappedBy="judge", cascade={"persist", "remove"}, orphanRemoval=true)
* @var Collection|JudgeTitle[] * @var Collection|JudgeTitle[]
*/ */
private $titles; private $titles;
public function __construct() public function __construct()
{ {
$this->titles = new ArrayCollection(); $this->titles = new ArrayCollection();
@ -56,7 +61,7 @@ class Judge implements JsonSerializable
/** /**
* @return int * @return int
*/ */
public function getId(): int public function getId(): ?int
{ {
return $this->id; return $this->id;
} }
@ -65,7 +70,7 @@ class Judge implements JsonSerializable
* @param int $id * @param int $id
* @return Judge * @return Judge
*/ */
public function setId(int $id): Judge public function setId(?int $id): Judge
{ {
$this->id = $id; $this->id = $id;
return $this; return $this;
@ -74,7 +79,7 @@ class Judge implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getName(): string public function getName(): ?string
{ {
return $this->name; return $this->name;
} }
@ -92,7 +97,25 @@ class Judge implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getSlug(): string public function getPrefix(): ?string
{
return $this->prefix;
}
/**
* @param string $prefix
* @return Judge
*/
public function setPrefix(?string $prefix): Judge
{
$this->prefix = $prefix;
return $this;
}
/**
* @return string
*/
public function getSlug(): ?string
{ {
return $this->slug; return $this->slug;
} }
@ -110,11 +133,23 @@ class Judge implements JsonSerializable
/** /**
* @return JudgeTitle[]|Collection * @return JudgeTitle[]|Collection
*/ */
public function getTitles() public function getTitles(): ?Collection
{ {
return $this->titles; return $this->titles;
} }
/**
* @param \Traversable $titles
* @return Judge
*/
public function addTitles(\Traversable $titles): Judge
{
foreach ($titles as $title) {
$this->addTitle($title);
}
return $this;
}
/** /**
* @param JudgeTitle $title * @param JudgeTitle $title
* @return Judge * @return Judge
@ -123,6 +158,7 @@ class Judge implements JsonSerializable
{ {
if(!$this->titles->contains($title)) { if(!$this->titles->contains($title)) {
$this->titles->add($title); $this->titles->add($title);
$title->setJudge($this);
} }
return $this; return $this;
} }
@ -135,6 +171,19 @@ class Judge implements JsonSerializable
{ {
if($this->titles->contains($title)) { if($this->titles->contains($title)) {
$this->titles->removeElement($title); $this->titles->removeElement($title);
$title->setJudge(null);
}
return $this;
}
/**
* @param \Traversable $titles
* @return Judge
*/
public function removeTitles(\Traversable $titles): Judge
{
foreach ($titles as $title) {
$this->removeTitle($title);
} }
return $this; return $this;
} }
@ -143,7 +192,7 @@ class Judge implements JsonSerializable
* @param JudgeTitle[]|Collection $titles * @param JudgeTitle[]|Collection $titles
* @return Judge * @return Judge
*/ */
public function setTitles($titles) public function setTitles($titles): Judge
{ {
$this->titles = $titles; $this->titles = $titles;
return $this; return $this;
@ -157,6 +206,7 @@ class Judge implements JsonSerializable
return [ return [
'id' => $this->getId(), 'id' => $this->getId(),
'name' => $this->getName(), 'name' => $this->getName(),
'prefix' => $this->getPrefix(),
'titles' => $this->getTitles()->getValues(), 'titles' => $this->getTitles()->getValues(),
'slug' => $this->getSlug(), 'slug' => $this->getSlug(),
]; ];

View File

@ -39,7 +39,7 @@ class JudgeTitle implements JsonSerializable
/** /**
* @ORM\ManyToOne(targetEntity="Judge", inversedBy="titles") * @ORM\ManyToOne(targetEntity="Judge", inversedBy="titles")
* @ORM\JoinColumn(name="title_id", referencedColumnName="id") * @ORM\JoinColumn(name="judge_id", referencedColumnName="id")
* @var Judge * @var Judge
*/ */
private $judge; private $judge;
@ -47,7 +47,7 @@ class JudgeTitle implements JsonSerializable
/** /**
* @return int * @return int
*/ */
public function getId(): int public function getId(): ?int
{ {
return $this->id; return $this->id;
} }
@ -56,7 +56,7 @@ class JudgeTitle implements JsonSerializable
* @param int $id * @param int $id
* @return JudgeTitle * @return JudgeTitle
*/ */
public function setId(int $id): JudgeTitle public function setId(?int $id): JudgeTitle
{ {
$this->id = $id; $this->id = $id;
return $this; return $this;
@ -65,7 +65,7 @@ class JudgeTitle implements JsonSerializable
/** /**
* @return int * @return int
*/ */
public function getYear(): int public function getYear(): ?int
{ {
return $this->year; return $this->year;
} }
@ -83,7 +83,7 @@ class JudgeTitle implements JsonSerializable
/** /**
* @return string * @return string
*/ */
public function getTitle(): string public function getTitle(): ?string
{ {
return $this->title; return $this->title;
} }
@ -101,7 +101,7 @@ class JudgeTitle implements JsonSerializable
/** /**
* @return Judge * @return Judge
*/ */
public function getJudge(): Judge public function getJudge(): ?Judge
{ {
return $this->judge; return $this->judge;
} }
@ -110,7 +110,7 @@ class JudgeTitle implements JsonSerializable
* @param Judge $judge * @param Judge $judge
* @return JudgeTitle * @return JudgeTitle
*/ */
public function setJudge(Judge $judge): JudgeTitle public function setJudge(?Judge $judge): JudgeTitle
{ {
$this->judge = $judge; $this->judge = $judge;
return $this; return $this;

View File

@ -20,16 +20,63 @@ class AwardeeHandler extends AbstractCrudHandler
$this->awardeeManager = $awardeeManager; $this->awardeeManager = $awardeeManager;
} }
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
*/
public function getList(ServerRequestInterface $request): ResponseInterface public function getList(ServerRequestInterface $request): ResponseInterface
{ {
$entities = $this->awardeeManager->getAwardees(); $entities = $this->awardeeManager->getAwardees();
return new JsonResponse($entities); return new JsonResponse($entities);
} }
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
*/
public function get(ServerRequestInterface $request): ResponseInterface public function get(ServerRequestInterface $request): ResponseInterface
{ {
$id = $request->getAttribute(static::IDENTIFIER_NAME); $id = $request->getAttribute(static::IDENTIFIER_NAME);
$entity = $this->awardeeManager->getAwardee((int)$id); $entity = $this->awardeeManager->getAwardee((int)$id);
return new JsonResponse($entity); return new JsonResponse($entity);
} }
/**
* @param ServerRequestInterface $request
* @return JsonResponse
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function create(ServerRequestInterface $request): ResponseInterface
{
$data = $this->getRequestData($request);
$entity = $this->awardeeManager->create($data);
return new JsonResponse($entity);
}
/**
* @param ServerRequestInterface $request
* @return JsonResponse
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function update(ServerRequestInterface $request): ResponseInterface
{
$id = $request->getAttribute(static::IDENTIFIER_NAME);
$data = $this->getRequestData($request);
$entity = $this->awardeeManager->update((int)$id, $data);
return new JsonResponse($entity);
}
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function delete(ServerRequestInterface $request): ResponseInterface
{
$id = $request->getAttribute(static::IDENTIFIER_NAME);
return new JsonResponse($this->awardeeManager->delete((int)$id));
}
} }

View File

@ -67,4 +67,16 @@ class JudgesHandler extends AbstractCrudHandler
$entity = $this->judgeManager->update((int)$id, $data); $entity = $this->judgeManager->update((int)$id, $data);
return new JsonResponse($entity); return new JsonResponse($entity);
} }
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function delete(ServerRequestInterface $request): ResponseInterface
{
$id = $request->getAttribute(static::IDENTIFIER_NAME);
return new JsonResponse($this->judgeManager->delete((int)$id));
}
} }

View File

@ -10,7 +10,6 @@ use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\HtmlResponse; use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Response\RedirectResponse;
use Zend\Expressive\Helper\UrlHelper; use Zend\Expressive\Helper\UrlHelper;
use Zend\Expressive\Template\TemplateRendererInterface; use Zend\Expressive\Template\TemplateRendererInterface;
@ -33,8 +32,7 @@ class AwardeeHandler implements RequestHandlerInterface
AwardeeManager $awardeeManager, AwardeeManager $awardeeManager,
UrlHelper $urlHelper, UrlHelper $urlHelper,
JudgeManager $judgeManager JudgeManager $judgeManager
) ) {
{
$this->template = $template; $this->template = $template;
$this->awardeeManager = $awardeeManager; $this->awardeeManager = $awardeeManager;
$this->urlHelper = $urlHelper; $this->urlHelper = $urlHelper;

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace App\Handler; namespace App\Handler;
use App\Entity\Awardee; use App\Entity\JudgeTitle;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@ -37,7 +37,7 @@ class AwardeeRedirectHandler implements RequestHandlerInterface
{ {
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
$maxYear = $qb->select('max(a.year)') $maxYear = $qb->select('max(a.year)')
->from(Awardee::class, 'a') ->from(JudgeTitle::class, 'a')
->getQuery() ->getQuery()
->getSingleScalarResult(); ->getSingleScalarResult();

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Plates; namespace App\Plates;
use App\Entity\Awardee; use App\Entity\Awardee;
use App\Service\YearManager;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Knp\Menu\ItemInterface; use Knp\Menu\ItemInterface;
use Knp\Menu\Matcher\Matcher; use Knp\Menu\Matcher\Matcher;
@ -24,16 +25,20 @@ class NavigationExtension implements ExtensionInterface
/** @var EntityManager */ /** @var EntityManager */
private $entityManager; private $entityManager;
/** @var YearManager */
private $yearManager;
/** @var MenuItem */ /** @var MenuItem */
private $menu; private $menu;
public function __construct( public function __construct(
RouterInterface $router, RouterInterface $router,
EntityManager $entityManager EntityManager $entityManager,
) YearManager $yearManager
{ ) {
$this->router = $router; $this->router = $router;
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->yearManager = $yearManager;
} }
/** /**
@ -84,10 +89,6 @@ class NavigationExtension implements ExtensionInterface
'uri' => $this->getUriFromRouter('the-prize.article', ['article' => 'gran-prize-award-events']) 'uri' => $this->getUriFromRouter('the-prize.article', ['article' => 'gran-prize-award-events'])
]); ]);
// $this->menu->addChild(strtoupper("Judges"), [
// 'uri' => $this->getUriFromRouter('judges')
// ]);
$awardeesMenu = $this->menu->addChild(strtoupper("Awards"), [ $awardeesMenu = $this->menu->addChild(strtoupper("Awards"), [
'uri' => $this->getUriFromRouter('awardees') 'uri' => $this->getUriFromRouter('awardees')
]); ]);
@ -101,17 +102,7 @@ class NavigationExtension implements ExtensionInterface
private function populateAwardeesSubmenu(ItemInterface $awardeesMenu) private function populateAwardeesSubmenu(ItemInterface $awardeesMenu)
{ {
$qb = $this->entityManager->createQueryBuilder(); $years = $this->yearManager->getYears();
$result = $qb->select('a.year')
->from(Awardee::class, 'a')
->orderBy('a.year', 'DESC')
->getQuery()
->getScalarResult();
$years = array_unique(array_map(function ($item) {
return $item['year'];
}, $result));
foreach ($years as $year) { foreach ($years as $year) {
$yearItem = $awardeesMenu->addChild($year, [ $yearItem = $awardeesMenu->addChild($year, [
'uri' => $this->getUriFromRouter('awardees-by-year', ['year' => $year]) 'uri' => $this->getUriFromRouter('awardees-by-year', ['year' => $year])

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Plates; namespace App\Plates;
use App\Service\YearManager;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Zend\Expressive\Plates\Exception\MissingHelperException; use Zend\Expressive\Plates\Exception\MissingHelperException;
@ -23,6 +24,7 @@ class NavigationExtensionFactory
$router = $container->get(RouterInterface::class); $router = $container->get(RouterInterface::class);
$entityManager = $container->get(EntityManager::class); $entityManager = $container->get(EntityManager::class);
return new NavigationExtension($router, $entityManager); $yearManager = $container->get(YearManager::class);
return new NavigationExtension($router, $entityManager, $yearManager);
} }
} }

View File

@ -6,15 +6,22 @@ namespace App\Service;
use App\Entity\Awardee; use App\Entity\Awardee;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use DoctrineExpressiveModule\Hydrator\DoctrineObject;
class AwardeeManager class AwardeeManager
{ {
/** @var EntityManager */ /** @var EntityManager */
private $entityManager; private $entityManager;
public function __construct(EntityManager $entityManager) /** @var DoctrineObject */
{ private $hydrator;
public function __construct(
EntityManager $entityManager,
DoctrineObject $hydrator
) {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->hydrator = $hydrator;
} }
public function getAwardees(): ?array public function getAwardees(): ?array
@ -54,4 +61,50 @@ class AwardeeManager
]); ]);
return $awardee; return $awardee;
} }
/**
* @return Awardee
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function create($data): Awardee
{
/** @var Awardee $awardee */
$awardee = $this->hydrator->hydrate($data, new Awardee());
$this->entityManager->persist($awardee);
$this->entityManager->flush();
return $awardee;
}
/**
* @param int $id
* @param $data
* @return Awardee
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function update(int $id, $data): Awardee
{
$awardee = $this->entityManager->getRepository(Awardee::class)->find($id);
/** @var Awardee $awardee */
$awardee = $this->hydrator->hydrate($data, $awardee);
$this->entityManager->persist($awardee);
$this->entityManager->flush();
return $awardee;
}
/**
* @param int $id
* @return bool
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function delete(int $id): bool {
if (null !== ($entity = $this->getAwardee($id))) {
$this->entityManager->remove($entity);
$this->entityManager->flush();
return true;
}
return false;
}
} }

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Service; namespace App\Service;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use DoctrineExpressiveModule\Hydrator\DoctrineObject;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
class AwardeeManagerFactory class AwardeeManagerFactory
@ -12,6 +13,7 @@ class AwardeeManagerFactory
public function __invoke(ContainerInterface $container) : AwardeeManager public function __invoke(ContainerInterface $container) : AwardeeManager
{ {
$entityManager = $container->get(EntityManager::class); $entityManager = $container->get(EntityManager::class);
return new AwardeeManager($entityManager); $hydrator = $container->get(DoctrineObject::class);
return new AwardeeManager($entityManager, $hydrator);
} }
} }

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace App\Service; namespace App\Service;
use App\Entity\Judge; use App\Entity\Judge;
@ -11,6 +13,7 @@ class JudgeManager
/** @var EntityManager */ /** @var EntityManager */
private $entityManager; private $entityManager;
/** @var DoctrineObject */
private $hydrator; private $hydrator;
public function __construct( public function __construct(
@ -38,10 +41,11 @@ class JudgeManager
public function getJudgesByYear(int $year) public function getJudgesByYear(int $year)
{ {
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
return $qb->select('j') return $qb->select('j,t')
->from(Judge::class, 'j') ->from(Judge::class, 'j')
->innerJoin('j.titles', 't') ->innerJoin('j.titles', 't')
->where('t.year = :year') ->where('t.year = :year')
->orderBy('j.name', 'ASC')
->setParameter('year', $year) ->setParameter('year', $year)
->getQuery() ->getQuery()
->getArrayResult(); ->getArrayResult();
@ -89,4 +93,20 @@ class JudgeManager
$this->entityManager->flush(); $this->entityManager->flush();
return $judge; return $judge;
} }
/**
* @param int $id
* @return bool
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function delete(int $id): bool
{
if (null !== ($entity = $this->getJudge($id))) {
$this->entityManager->remove($entity);
$this->entityManager->flush();
return true;
}
return false;
}
} }

View File

@ -29,11 +29,6 @@ class YearManager
return $year['year']; return $year['year'];
}, $years); }, $years);
$thisYear = date("Y");
if (!in_array($thisYear, $filteredYears)) {
array_unshift($filteredYears, $thisYear);
}
return $filteredYears; return $filteredYears;
} }
} }

View File

@ -3,8 +3,8 @@
<?php foreach ($judges as $judge): ?> <?php foreach ($judges as $judge): ?>
<section class="judge"> <section class="judge">
<img class="profile" src="<?= $this->serverurl(sprintf('/img/judges/%s.jpg', $judge['slug'])) ?>"> <img class="profile" src="<?= $this->serverurl(sprintf('/img/judges/%s.jpg', $judge['slug'])) ?>">
<span class="title"><?= $judge['name']?></span><br> <span class="title"><?= $judge['prefix'].$judge['name']?></span><br>
<span class="description"><?= $judge['title']?></span> <span class="description"><?= $judge['titles'][0]['title']?></span>
</section> </section>
<?php endforeach; ?> <?php endforeach; ?>
</section> </section>