From ec23a41e373b352a5a44dac19f43fef0b51b008e Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sat, 2 May 2020 00:58:03 +0200 Subject: [PATCH] Add provider DTO and API endpoint --- config/routes.yaml | 5 + config/services.yaml | 14 ++- src/Controller/Api/v1/ProviderController.php | 31 ++++++ src/Model/Provider.php | 101 +++++++++++++++++++ src/Service/AggregateConverter.php | 34 +++++-- src/Service/ProviderConverter.php | 27 +++++ 6 files changed, 196 insertions(+), 16 deletions(-) create mode 100644 src/Controller/Api/v1/ProviderController.php create mode 100644 src/Model/Provider.php create mode 100644 src/Service/ProviderConverter.php diff --git a/config/routes.yaml b/config/routes.yaml index b42047c..d5f74b8 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -2,3 +2,8 @@ api_v1: resource: ../src/Controller/Api/v1 type: annotation prefix: /{provider}/api/v1 + +api_v1_providers: + path: /api/v1/providers + defaults: + _controller: '\App\Controller\Api\v1\ProviderController::index' diff --git a/config/services.yaml b/config/services.yaml index 9fe3e71..774f1d7 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -19,11 +19,14 @@ services: App\Provider\Provider: tags: [ app.provider ] + App\Service\Converter: + tags: [ app.converter ] + # makes classes in src/ available to be used as services # this creates a service per class whose id is the fully-qualified class name App\: resource: '../src/*' - exclude: '../src/{DependencyInjection,Exception,Modifie,Entity,Model,Migrations,Tests,Functions,Handler,Kernel.php}' + exclude: '../src/{DependencyInjection,Exception,Modifier,Entity,Model,Migrations,Tests,Functions,Handler,Kernel.php}' # controllers are imported separately to make sure services can be injected # as action arguments even if you don't extend any base controller class @@ -72,19 +75,14 @@ services: ProxyManager\Configuration: '@proxy.config' + # converter App\Service\AggregateConverter: arguments: - - !tagged_iterator app.converter + - !tagged_iterator app.converter App\Service\Converter: '@App\Service\AggregateConverter' - App\Service\EntityConverter: - tags: ['app.converter'] - - App\Service\ScheduledStopConverter: - tags: ['app.converter'] - # serializer configuration App\Service\SerializerContextFactory: arguments: diff --git a/src/Controller/Api/v1/ProviderController.php b/src/Controller/Api/v1/ProviderController.php new file mode 100644 index 0000000..67b0dcc --- /dev/null +++ b/src/Controller/Api/v1/ProviderController.php @@ -0,0 +1,31 @@ +all() + ->map(ref([$converter, 'convert'])) + ->values() + ->toArray() + ; + return $this->json($providers); + } +} diff --git a/src/Model/Provider.php b/src/Model/Provider.php new file mode 100644 index 0000000..854f8ec --- /dev/null +++ b/src/Model/Provider.php @@ -0,0 +1,101 @@ +id; + } + + public function setId(string $id): void + { + $this->id = $id; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getShortName(): string + { + return $this->shortName; + } + + public function setShortName(string $shortName): void + { + $this->shortName = $shortName; + } + + public function getAttribution(): ?string + { + return $this->attribution; + } + + public function setAttribution(?string $attribution): void + { + $this->attribution = $attribution; + } + + public function getLastUpdate(): ?Carbon + { + return $this->lastUpdate; + } + + public function setLastUpdate(?Carbon $lastUpdate): void + { + $this->lastUpdate = $lastUpdate; + } +} diff --git a/src/Service/AggregateConverter.php b/src/Service/AggregateConverter.php index e9087d1..f9e6dff 100644 --- a/src/Service/AggregateConverter.php +++ b/src/Service/AggregateConverter.php @@ -8,20 +8,19 @@ use function Kadet\Functional\Predicates\instance; class AggregateConverter implements Converter, CacheableConverter { private $converters; + private $cachedConverters; public function __construct(iterable $converters) { - $this->converters = collect($converters)->each(function (Converter $converter) { - if ($converter instanceof RecursiveConverter) { - $converter->setParent($this); - } - }); + $this->converters = $converters; } public function convert($entity) { + $this->ensureCachedConverters(); + /** @var Converter $converter */ - $converter = $this->converters->first(function (Converter $converter) use ($entity) { + $converter = $this->cachedConverters->first(function (Converter $converter) use ($entity) { return $converter->supports($entity); }); @@ -41,7 +40,9 @@ class AggregateConverter implements Converter, CacheableConverter public function getConverters(): Collection { - return clone $this->converters; + $this->ensureCachedConverters(); + + return clone $this->cachedConverters; } public function flushCache() @@ -57,8 +58,25 @@ class AggregateConverter implements Converter, CacheableConverter public function __clone() { - $this->converters = $this->converters->map(function ($object) { + $this->ensureCachedConverters(); + + $this->cachedConverters = $this->cachedConverters->map(function ($object) { return clone $object; }); } + + private function ensureCachedConverters() + { + if (!$this->cachedConverters) { + $this->cachedConverters = collect($this->converters) + ->filter(function (Converter $converter) { + return $converter !== $this; + }) + ->each(function (Converter $converter) { + if ($converter instanceof RecursiveConverter) { + $converter->setParent($this); + } + }); + } + } } diff --git a/src/Service/ProviderConverter.php b/src/Service/ProviderConverter.php new file mode 100644 index 0000000..f644553 --- /dev/null +++ b/src/Service/ProviderConverter.php @@ -0,0 +1,27 @@ + $entity->getIdentifier(), + 'shortName' => $entity->getShortName(), + 'name' => $entity->getName(), + 'attribution' => $entity->getAttribution(), + 'lastUpdate' => $entity->getLastUpdate() ? clone $entity->getLastUpdate() : null, + ]); + } + + public function supports($entity) + { + return $entity instanceof Provider; + } +}