From 6bd71f0ec574ab3e720dc89e08c2ad5725a884d3 Mon Sep 17 00:00:00 2001 From: Kacper Donat <kadet1090@gmail.com> Date: Wed, 12 Feb 2020 20:08:56 +0100 Subject: [PATCH] Add service subscriber to database repository --- .../UnsupportedModifierException.php | 14 +++++ ...andler.php => IdFilterDatabaseHandler.php} | 7 +-- src/Modifiers/{WithId.php => IdFilter.php} | 2 +- src/Provider/Database/DatabaseRepository.php | 61 +++++++++++++++++-- .../Database/GenericLineRepository.php | 29 ++++----- .../Database/GenericOperatorRepository.php | 7 ++- .../Database/GenericScheduleRepository.php | 5 ++ .../Database/GenericStopRepository.php | 5 ++ .../Database/GenericTrackRepository.php | 7 ++- .../Database/GenericTripRepository.php | 5 ++ 10 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 src/Exception/UnsupportedModifierException.php rename src/Handlers/Database/{WithIdDatabaseHandler.php => IdFilterDatabaseHandler.php} (86%) rename src/Modifiers/{WithId.php => IdFilter.php} (94%) diff --git a/src/Exception/UnsupportedModifierException.php b/src/Exception/UnsupportedModifierException.php new file mode 100644 index 0000000..4dbd2bf --- /dev/null +++ b/src/Exception/UnsupportedModifierException.php @@ -0,0 +1,14 @@ +<?php + +namespace App\Exception; + +use App\Modifiers\Modifier; +use App\Provider\Repository; + +class UnsupportedModifierException extends \Exception +{ + public static function createFromModifier(Modifier $modifier, Repository $repository) + { + return new static(sprintf("Modifier %s is not supported by %s.", get_class($modifier), get_class($repository))); + } +} diff --git a/src/Handlers/Database/WithIdDatabaseHandler.php b/src/Handlers/Database/IdFilterDatabaseHandler.php similarity index 86% rename from src/Handlers/Database/WithIdDatabaseHandler.php rename to src/Handlers/Database/IdFilterDatabaseHandler.php index 1cbb324..58a89db 100644 --- a/src/Handlers/Database/WithIdDatabaseHandler.php +++ b/src/Handlers/Database/IdFilterDatabaseHandler.php @@ -3,14 +3,13 @@ namespace App\Handlers\Database; use App\Handlers\ModifierHandler; -use App\Modifiers\WithId; +use App\Modifiers\IdFilter; use App\Event\HandleDatabaseModifierEvent; use App\Event\HandleModifierEvent; use App\Service\IdUtils; use function Kadet\Functional\apply; -use function Kadet\Functional\ref; -class WithIdDatabaseHandler implements ModifierHandler +class IdFilterDatabaseHandler implements ModifierHandler { /** * @var IdUtils @@ -28,7 +27,7 @@ class WithIdDatabaseHandler implements ModifierHandler return; } - /** @var WithId $modifier */ + /** @var IdFilter $modifier */ $modifier = $event->getModifier(); $builder = $event->getBuilder(); $alias = $event->getMeta()['alias']; diff --git a/src/Modifiers/WithId.php b/src/Modifiers/IdFilter.php similarity index 94% rename from src/Modifiers/WithId.php rename to src/Modifiers/IdFilter.php index 883db0f..e2f570c 100644 --- a/src/Modifiers/WithId.php +++ b/src/Modifiers/IdFilter.php @@ -5,7 +5,7 @@ namespace App\Modifiers; use App\Exception\InvalidOptionException; use App\Modifiers\Modifier; -class WithId implements Modifier +class IdFilter implements Modifier { /** @var string|array */ private $id; diff --git a/src/Provider/Database/DatabaseRepository.php b/src/Provider/Database/DatabaseRepository.php index 3a97eff..4f4dce3 100644 --- a/src/Provider/Database/DatabaseRepository.php +++ b/src/Provider/Database/DatabaseRepository.php @@ -2,15 +2,19 @@ namespace App\Provider\Database; -use App\Entity\Entity; use App\Entity\ProviderEntity; +use App\Event\HandleDatabaseModifierEvent; +use App\Exception\UnsupportedModifierException; use App\Model\Referable; +use App\Provider\Repository; use App\Service\Converter; use App\Service\IdUtils; use Doctrine\ORM\EntityManagerInterface; -use Kadet\Functional as f; +use Doctrine\ORM\QueryBuilder; +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; -class DatabaseRepository +abstract class DatabaseRepository implements ServiceSubscriberInterface, Repository { /** @var EntityManagerInterface */ protected $em; @@ -24,22 +28,30 @@ class DatabaseRepository /** @var Converter */ protected $converter; + /** @var ContainerInterface */ + protected $handlers; + /** * DatabaseRepository constructor. * * @param EntityManagerInterface $em */ - public function __construct(EntityManagerInterface $em, IdUtils $id, Converter $converter) - { + public function __construct( + EntityManagerInterface $em, + IdUtils $id, + Converter $converter, + ContainerInterface $handlers + ) { $this->em = $em; $this->id = $id; $this->converter = $converter; + $this->handlers = $handlers; } /** @return static */ public function withProvider(ProviderEntity $provider) { - $result = clone $this; + $result = clone $this; $result->provider = $provider; return $result; @@ -56,4 +68,41 @@ class DatabaseRepository return $this->em->getReference($class, $id); } + + protected function processQueryBuilder(QueryBuilder $builder, iterable $modifiers, array $meta = []) + { + foreach ($modifiers as $modifier) { + $event = new HandleDatabaseModifierEvent($modifier, $this, $builder, array_merge([ + 'provider' => $this->provider, + ], $meta)); + + $class = get_class($modifier); + + if (!$this->handlers->has($class)) { + throw UnsupportedModifierException::createFromModifier($modifier, $this); + } + + $handler = $this->handlers->get($class); + + $handler->process($event); + } + } + + /** + * Returns array describing handlers for each modifier type. Syntax is as follows: + * [ IdFilter::class => IdFilterDatabaseHandler::class ] + * + * It is internally used as part of service subscriber. + * + * @return array + */ + protected abstract static function getHandlers(); + + /** + * @inheritDoc + */ + public static function getSubscribedServices() + { + return static::getHandlers(); + } } diff --git a/src/Provider/Database/GenericLineRepository.php b/src/Provider/Database/GenericLineRepository.php index 66d3cc0..6982cb1 100644 --- a/src/Provider/Database/GenericLineRepository.php +++ b/src/Provider/Database/GenericLineRepository.php @@ -5,11 +5,11 @@ namespace App\Provider\Database; use App\Entity\LineEntity; use App\Event\HandleDatabaseModifierEvent; use App\Handlers\Database\LimitDatabaseHandler; -use App\Handlers\Database\WithIdDatabaseHandler; +use App\Handlers\Database\IdFilterDatabaseHandler; use App\Handlers\ModifierHandler; use App\Model\Line; use App\Modifiers\Limit; -use App\Modifiers\WithId; +use App\Modifiers\IdFilter; use App\Provider\LineRepository; use App\Modifiers\Modifier; use Tightenco\Collect\Support\Collection; @@ -24,12 +24,12 @@ class GenericLineRepository extends DatabaseRepository implements LineRepository public function getById($id): ?Line { - return $this->first(new WithId($id)); + return $this->first(new IdFilter($id)); } public function getManyById($ids): Collection { - return $this->all(new WithId($ids)); + return $this->all(new IdFilter($ids)); } public function first(Modifier ...$modifiers) @@ -45,26 +45,21 @@ class GenericLineRepository extends DatabaseRepository implements LineRepository ->select('line') ; - foreach ($modifiers as $modifier) { - $event = new HandleDatabaseModifierEvent($modifier, $this, $builder, [ - 'alias' => 'line', - 'provider' => $this->provider, - ]); - - $handler = $this->getHandlers()[get_class($modifier)]; - - $handler->process($event); - } + $this->processQueryBuilder($builder, $modifiers, [ + 'alias' => 'line', + 'entity' => LineEntity::class, + 'type' => Line::class, + ]); return collect($builder->getQuery()->execute())->map(f\ref([$this, 'convert'])); } /** @return ModifierHandler[] */ - private function getHandlers() + protected static function getHandlers() { return [ - WithId::class => new WithIdDatabaseHandler($this->id), - Limit::class => new LimitDatabaseHandler(), + IdFilter::class => IdFilterDatabaseHandler::class, + Limit::class => LimitDatabaseHandler::class, ]; } } diff --git a/src/Provider/Database/GenericOperatorRepository.php b/src/Provider/Database/GenericOperatorRepository.php index 946eff6..929d994 100644 --- a/src/Provider/Database/GenericOperatorRepository.php +++ b/src/Provider/Database/GenericOperatorRepository.php @@ -30,4 +30,9 @@ class GenericOperatorRepository extends DatabaseRepository implements OperatorRe return collect($operators); } -} \ No newline at end of file + + protected static function getHandlers() + { + return []; + } +} diff --git a/src/Provider/Database/GenericScheduleRepository.php b/src/Provider/Database/GenericScheduleRepository.php index 551c288..e1c2c29 100644 --- a/src/Provider/Database/GenericScheduleRepository.php +++ b/src/Provider/Database/GenericScheduleRepository.php @@ -70,4 +70,9 @@ class GenericScheduleRepository extends DatabaseRepository implements ScheduleRe ]); }); } + + protected static function getHandlers() + { + return []; + } } diff --git a/src/Provider/Database/GenericStopRepository.php b/src/Provider/Database/GenericStopRepository.php index 8dc1972..fe7b017 100644 --- a/src/Provider/Database/GenericStopRepository.php +++ b/src/Provider/Database/GenericStopRepository.php @@ -83,4 +83,9 @@ class GenericStopRepository extends DatabaseRepository implements StopRepository $stop->setDestinations($destinations[$this->id->generate($this->provider, $stop->getId())]); }); } + + protected static function getHandlers() + { + return []; + } } diff --git a/src/Provider/Database/GenericTrackRepository.php b/src/Provider/Database/GenericTrackRepository.php index 9a25d44..53bd235 100644 --- a/src/Provider/Database/GenericTrackRepository.php +++ b/src/Provider/Database/GenericTrackRepository.php @@ -64,4 +64,9 @@ class GenericTrackRepository extends DatabaseRepository implements TrackReposito return collect($tracks)->map(f\ref([$this, 'convert'])); } -} \ No newline at end of file + + protected static function getHandlers() + { + return []; + } +} diff --git a/src/Provider/Database/GenericTripRepository.php b/src/Provider/Database/GenericTripRepository.php index e85f178..3944e18 100644 --- a/src/Provider/Database/GenericTripRepository.php +++ b/src/Provider/Database/GenericTripRepository.php @@ -25,4 +25,9 @@ class GenericTripRepository extends DatabaseRepository implements TripRepository return $this->convert($trip); } + + protected static function getHandlers() + { + return []; + } }