diff --git a/src/DataProvider/PlaceCollectionDataProvider.php b/src/DataProvider/PlaceCollectionDataProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..f89871e18d330979e219c5c345233817e4d03a8e --- /dev/null +++ b/src/DataProvider/PlaceCollectionDataProvider.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + +namespace DBP\API\StarterBundle\DataProvider; + +use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface; +use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface; +use DBP\API\CoreBundle\Helpers\ArrayFullPaginator; +use DBP\API\StarterBundle\Entity\Place; +use DBP\API\StarterBundle\Service\PlaceProviderInterface; + +final class PlaceCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface +{ + private $api; + + public function __construct(PlaceProviderInterface $api) + { + $this->api = $api; + } + + public function supports(string $resourceClass, string $operationName = null, array $context = []): bool + { + return Place::class === $resourceClass; + } + + public function getCollection(string $resourceClass, string $operationName = null, array $context = []): ArrayFullPaginator + { + $perPage = 30; + $page = 1; + + $filters = $context['filters'] ?? []; + if (isset($filters['page'])) { + $page = (int) $filters['page']; + } + if (isset($filters['perPage'])) { + $perPage = (int) $filters['perPage']; + } + + return new ArrayFullPaginator($this->api->getPlaces(), $page, $perPage); + } +} diff --git a/src/DataProvider/PlaceItemDataProvider.php b/src/DataProvider/PlaceItemDataProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..e69721fb6ba423842929780293124b3922e4fc0d --- /dev/null +++ b/src/DataProvider/PlaceItemDataProvider.php @@ -0,0 +1,39 @@ +<?php + +declare(strict_types=1); + +namespace DBP\API\StarterBundle\DataProvider; + +use ApiPlatform\Core\DataProvider\ItemDataProviderInterface; +use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface; +use DBP\API\StarterBundle\Entity\Place; +use DBP\API\StarterBundle\Service\PlaceProviderInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + +final class PlaceItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface +{ + private $api; + + public function __construct(PlaceProviderInterface $api) + { + $this->api = $api; + } + + public function supports(string $resourceClass, string $operationName = null, array $context = []): bool + { + return Place::class === $resourceClass; + } + + /** + * @param array|int|string $id + */ + public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): Place + { + $place = $this->api->getPlaceById($id); + if ($place === null) { + throw new NotFoundHttpException(); + } + + return $place; + } +} diff --git a/src/DependencyInjection/DbpStarterExtension.php b/src/DependencyInjection/DbpStarterExtension.php index 058f349f1b1194dadc8c560e1fc9effce488332f..7e03ac7b1f5d8901ab05da6f4b4ded7292c4fdd8 100644 --- a/src/DependencyInjection/DbpStarterExtension.php +++ b/src/DependencyInjection/DbpStarterExtension.php @@ -13,10 +13,23 @@ class DbpStarterExtension extends Extension { public function load(array $configs, ContainerBuilder $container) { + $this->extendArrayParameter( + $container, 'api_platform.resource_class_directories', [__DIR__.'/../Entity']); + $loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') ); $loader->load('services.yaml'); } + + private function extendArrayParameter(ContainerBuilder $container, string $parameter, array $values) + { + if (!$container->hasParameter($parameter)) { + $container->setParameter($parameter, []); + } + $oldValues = $container->getParameter($parameter); + assert(is_array($oldValues)); + $container->setParameter($parameter, array_merge($oldValues, $values)); + } } diff --git a/src/Entity/Place.php b/src/Entity/Place.php new file mode 100644 index 0000000000000000000000000000000000000000..ef50736d3ad14c701d451192633a3b3ca398abbe --- /dev/null +++ b/src/Entity/Place.php @@ -0,0 +1,53 @@ +<?php + +declare(strict_types=1); + +namespace DBP\API\StarterBundle\Entity; + +use ApiPlatform\Core\Annotation\ApiProperty; +use ApiPlatform\Core\Annotation\ApiResource; +use Symfony\Component\Serializer\Annotation\Groups; + +/** + * @ApiResource( + * collectionOperations={"get"}, + * itemOperations={"get"}, + * iri="https://schema.org/Place", + * normalizationContext={"groups"={"Place:output"}, "jsonld_embed_context"=true} + * ) + */ +class Place +{ + /** + * @ApiProperty(identifier=true) + */ + private $identifier; + + /** + * @ApiProperty(iri="https://schema.org/name") + * @Groups({"Place:output"}) + * + * @var string + */ + private $name; + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getIdentifier(): string + { + return $this->identifier; + } + + public function setIdentifier(string $identifier): void + { + $this->identifier = $identifier; + } +} diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml index ac9d7afd6af249850eeffc7c57c9042e3ad379fc..2eec657704474839bfd63410d12fca609ac866d0 100644 --- a/src/Resources/config/services.yaml +++ b/src/Resources/config/services.yaml @@ -1,4 +1,19 @@ services: DBP\API\StarterBundle\Command\TestCommand: autowire: true - autoconfigure: true \ No newline at end of file + autoconfigure: true + + DBP\API\StarterBundle\DataProvider\PlaceCollectionDataProvider: + tags: [{ name: 'api_platform.collection_data_provider'}] + autowire: true + + DBP\API\StarterBundle\DataProvider\PlaceItemDataProvider: + tags: ['api_platform.item_data_provider'] + autowire: true + + DBP\API\StarterBundle\Service\ExternalApi: + autowire: true + autoconfigure: true + + DBP\API\StarterBundle\Service\PlaceProviderInterface: + '@DBP\API\StarterBundle\Service\ExternalApi' \ No newline at end of file diff --git a/src/Service/ExternalApi.php b/src/Service/ExternalApi.php index a65c6ccc8e8caa1a4b9df0dd895d663b3908cf96..0bd675d1b1681cab19c006177125f3173dd434bf 100644 --- a/src/Service/ExternalApi.php +++ b/src/Service/ExternalApi.php @@ -4,9 +4,40 @@ declare(strict_types=1); namespace DBP\API\StarterBundle\Service; -class ExternalApi +use DBP\API\StarterBundle\Entity\Place; + +class ExternalApi implements PlaceProviderInterface { + private $places; + public function __construct() { + $this->places = []; + $place1 = new Place(); + $place1->setIdentifier('graz'); + $place1->setName('Graz'); + + $place2 = new Place(); + $place2->setIdentifier('vienna'); + $place2->setName('Vienna'); + + $this->places[] = $place1; + $this->places[] = $place2; + } + + public function getPlaceById(string $identifier): ?Place + { + foreach ($this->places as $place) { + if ($place->getIdentifier() === $identifier) { + return $place; + } + } + + return null; + } + + public function getPlaces(): array + { + return $this->places; } } diff --git a/src/Service/PlaceProviderInterface.php b/src/Service/PlaceProviderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..2ff2aec799272ff0c5be2729d100c35428ace373 --- /dev/null +++ b/src/Service/PlaceProviderInterface.php @@ -0,0 +1,14 @@ +<?php + +declare(strict_types=1); + +namespace DBP\API\StarterBundle\Service; + +use DBP\API\StarterBundle\Entity\Place; + +interface PlaceProviderInterface +{ + public function getPlaceById(string $identifier): ?Place; + + public function getPlaces(): array; +}