From fad85ee2dde60d4a8e36f8a173150a5f9940ba1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Skowro=C5=84ski?= Date: Fri, 19 Jan 2024 21:19:23 +0100 Subject: [PATCH] Adjust config and existing code --- config/api_platform/resources/Attendance.yaml | 32 ++--- config/api_platform/resources/ModList.yaml | 39 ++++--- config/packages/api_platform.yaml | 33 ++++-- config/packages/security.yaml | 2 +- config/services.yaml | 4 - src/Api/Controller/GetModListByNameAction.php | 28 ----- .../AttendanceInputDataTransformer.php | 23 ++-- .../AttendanceOutputDataTransformer.php | 25 ++-- .../Dlc/DlcOutputDataTransformer.php | 29 ++--- .../Mod/ModOutputDataTransformer.php | 41 +++---- .../ModListDetailsOutputDataTransformer.php | 52 +++------ .../ModList/ModListOutputDataTransformer.php | 29 ++--- src/Api/Input/Attendance/AttendanceInput.php | 24 +--- .../Output/Attendance/AttendanceOutput.php | 49 +------- src/Api/Output/Dlc/DlcOutput.php | 73 ++---------- src/Api/Output/Mod/ModOutput.php | 109 ++---------------- .../Output/ModList/ModListDetailsOutput.php | 47 +++----- src/Api/Output/ModList/ModListOutput.php | 73 ++---------- .../Attendance/AttendanceProcessor.php | 38 ++++++ .../Attendance/AttendanceDataProvider.php | 31 +++++ .../Provider/Common/AbstractDataProvider.php | 64 ++++++++++ .../Provider/ModList/ModListDataProvider.php | 31 +++++ .../ModList/ModListDetailsDataProvider.php | 31 +++++ .../Normalizer/PaginatorNormalizer.php | 12 +- .../UserLocaleRequestSubscriber.php | 3 + .../Attendance/UniqueAttendanceValidator.php | 4 +- tests/functional.suite.yml | 2 +- .../Api/ModList/GetModListsByIdCest.php | 3 +- 28 files changed, 395 insertions(+), 536 deletions(-) delete mode 100644 src/Api/Controller/GetModListByNameAction.php create mode 100644 src/Api/Processor/Attendance/AttendanceProcessor.php create mode 100644 src/Api/Provider/Attendance/AttendanceDataProvider.php create mode 100644 src/Api/Provider/Common/AbstractDataProvider.php create mode 100644 src/Api/Provider/ModList/ModListDataProvider.php create mode 100644 src/Api/Provider/ModList/ModListDetailsDataProvider.php diff --git a/config/api_platform/resources/Attendance.yaml b/config/api_platform/resources/Attendance.yaml index 99b0063d..6124d00a 100644 --- a/config/api_platform/resources/Attendance.yaml +++ b/config/api_platform/resources/Attendance.yaml @@ -1,17 +1,19 @@ -App\Entity\Attendance\Attendance: - attributes: - input: 'App\Api\Input\Attendance\AttendanceInput' - output: 'App\Api\Output\Attendance\AttendanceOutput' +resources: + App\Entity\Attendance\Attendance: + operations: + ApiPlatform\Metadata\GetCollection: + provider: 'App\Api\Provider\Attendance\AttendanceDataProvider' + output: 'App\Api\Output\Attendance\AttendanceOutput' + filters: + - 'attendance.search_filter' + - 'attendance.date_filter' + - 'attendance.order_filter' - itemOperations: - get: ~ + ApiPlatform\Metadata\Get: + provider: 'App\Api\Provider\Attendance\AttendanceDataProvider' + output: 'App\Api\Output\Attendance\AttendanceOutput' - collectionOperations: - get: - filters: - - 'attendance.search_filter' - - 'attendance.date_filter' - - 'attendance.order_filter' - - post: - input: 'App\Api\Input\Attendance\AttendanceInput' + ApiPlatform\Metadata\Post: + input: 'App\Api\Input\Attendance\AttendanceInput' + processor: 'App\Api\Processor\Attendance\AttendanceProcessor' + output: 'App\Api\Output\Attendance\AttendanceOutput' diff --git a/config/api_platform/resources/ModList.yaml b/config/api_platform/resources/ModList.yaml index bef532ea..925264ee 100644 --- a/config/api_platform/resources/ModList.yaml +++ b/config/api_platform/resources/ModList.yaml @@ -1,21 +1,22 @@ -App\Entity\ModList\ModList: - attributes: - output: 'App\Api\Output\ModList\ModListOutput' +resources: + App\Entity\ModList\ModList: + operations: + ApiPlatform\Metadata\GetCollection: + provider: 'App\Api\Provider\ModList\ModListDataProvider' + output: 'App\Api\Output\ModList\ModListOutput' + filters: + - 'mod_list.search_filter' + - 'mod_list.date_filter' + - 'mod_list.order_filter' - itemOperations: - get: - output: 'App\Api\Output\ModList\ModListDetailsOutput' + ApiPlatform\Metadata\Get: + provider: 'App\Api\Provider\ModList\ModListDetailsDataProvider' + output: 'App\Api\Output\ModList\ModListDetailsOutput' - get_by_name: - method: 'GET' - path: '/mod-lists/by-name/{name}' - controller: 'App\Api\Controller\GetModListByNameAction' - output: 'App\Api\Output\ModList\ModListDetailsOutput' - read: false - - collectionOperations: - get: - filters: - - 'mod_list.search_filter' - - 'mod_list.date_filter' - - 'mod_list.order_filter' + get_by_name: + provider: 'App\Api\Provider\ModList\ModListDetailsDataProvider' + output: 'App\Api\Output\ModList\ModListDetailsOutput' + class: 'ApiPlatform\Metadata\Get' + method: 'GET' + uriTemplate: '/mod-lists/by-name/{name}' + controller: 'ApiPlatform\Action\PlaceholderAction' diff --git a/config/packages/api_platform.yaml b/config/packages/api_platform.yaml index 4d0c3f7f..11983979 100644 --- a/config/packages/api_platform.yaml +++ b/config/packages/api_platform.yaml @@ -1,18 +1,37 @@ +imports: + - { resource: ../api_platform/filters/ } + api_platform: - title: Hello API Platform - version: 1.0.0 + title: "%app.api.name%" + version: "%app.api.version%" + show_webby: false + + swagger: + versions: [ 3 ] + api_keys: + apiKey: + name: '%env(APP_SECURITY_API_KEY_HEADER_NAME)%' + type: header + + path_segment_name_generator: api_platform.path_segment_name_generator.dash + + mapping: + paths: [ '%kernel.project_dir%/config/api_platform/resources' ] + formats: - jsonld: ['application/ld+json'] + json: [ 'application/json' ] + docs_formats: - jsonld: ['application/ld+json'] - jsonopenapi: ['application/vnd.openapi+json'] - html: ['text/html'] + html: [ 'text/html' ] + defaults: stateless: true cache_headers: - vary: ['Content-Type', 'Authorization', 'Origin'] + vary: [ 'Content-Type', 'Authorization', 'Origin' ] extra_properties: standard_put: true rfc_7807_compliant_errors: true + normalization_context: + skip_null_values: false event_listeners_backward_compatibility_layer: false keep_legacy_inflector: false diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 86292877..c95cf4c9 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -20,7 +20,7 @@ security: lazy: true stateless: true pattern: ^/api/attendances - methods: ['POST'] + methods: [ 'POST' ] custom_authenticators: - App\Security\Authenticator\ApiKeyAuthenticator diff --git a/config/services.yaml b/config/services.yaml index a863933c..9ee435da 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -39,10 +39,6 @@ services: resource: '../src/Controller/' tags: [ 'controller.service_arguments' ] - App\Api\Controller\: - resource: '../src/Api/Controller/' - tags: [ 'controller.service_arguments' ] - # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones App\Security\Authenticator\DiscordAuthenticator: diff --git a/src/Api/Controller/GetModListByNameAction.php b/src/Api/Controller/GetModListByNameAction.php deleted file mode 100644 index 63d7d8d5..00000000 --- a/src/Api/Controller/GetModListByNameAction.php +++ /dev/null @@ -1,28 +0,0 @@ -modListRepository->findOneByName($name); - - if (!$modList) { - throw new NotFoundHttpException('Not Found'); - } - - return $modList; - } -} diff --git a/src/Api/DataTransformer/Attendance/AttendanceInputDataTransformer.php b/src/Api/DataTransformer/Attendance/AttendanceInputDataTransformer.php index 1f027452..c1822faf 100644 --- a/src/Api/DataTransformer/Attendance/AttendanceInputDataTransformer.php +++ b/src/Api/DataTransformer/Attendance/AttendanceInputDataTransformer.php @@ -4,33 +4,26 @@ namespace App\Api\DataTransformer\Attendance; -use ApiPlatform\Core\DataTransformer\DataTransformerInterface; use ApiPlatform\Validator\ValidatorInterface; use App\Api\Input\Attendance\AttendanceInput; use App\Entity\Attendance\Attendance; use Ramsey\Uuid\Uuid; -class AttendanceInputDataTransformer implements DataTransformerInterface +class AttendanceInputDataTransformer { public function __construct( private ValidatorInterface $validator ) { } - public function transform($object, string $to, array $context = []): Attendance + public function transform(AttendanceInput $attendanceInput): Attendance { - /** @var AttendanceInput $object */ - $this->validator->validate($object); + $this->validator->validate($attendanceInput); - return new Attendance(Uuid::uuid4(), $object->getMissionId(), $object->getPlayerId()); - } - - public function supportsTransformation($data, string $to, array $context = []): bool - { - if ($data instanceof Attendance) { - return false; - } - - return Attendance::class === $to && null !== ($context['input']['class'] ?? null); + return new Attendance( + Uuid::uuid4(), + $attendanceInput->missionId, + $attendanceInput->playerId + ); } } diff --git a/src/Api/DataTransformer/Attendance/AttendanceOutputDataTransformer.php b/src/Api/DataTransformer/Attendance/AttendanceOutputDataTransformer.php index 3cd7082e..435ec16d 100644 --- a/src/Api/DataTransformer/Attendance/AttendanceOutputDataTransformer.php +++ b/src/Api/DataTransformer/Attendance/AttendanceOutputDataTransformer.php @@ -4,27 +4,18 @@ namespace App\Api\DataTransformer\Attendance; -use ApiPlatform\Core\DataTransformer\DataTransformerInterface; use App\Api\Output\Attendance\AttendanceOutput; use App\Entity\Attendance\Attendance; -class AttendanceOutputDataTransformer implements DataTransformerInterface +class AttendanceOutputDataTransformer { - public function transform($object, string $to, array $context = []): AttendanceOutput + public function transform(Attendance $attendance): AttendanceOutput { - /** @var Attendance $object */ - $output = new AttendanceOutput(); - - $output->setId($object->getId()->toString()); - $output->setCreatedAt($object->getCreatedAt()); - $output->setMissionId($object->getMissionId()); - $output->setPlayerId($object->getPlayerId()); - - return $output; - } - - public function supportsTransformation($data, string $to, array $context = []): bool - { - return AttendanceOutput::class === $to && $data instanceof Attendance; + return new AttendanceOutput( + $attendance->getId()->toString(), + $attendance->getMissionId(), + $attendance->getPlayerId(), + $attendance->getCreatedAt(), + ); } } diff --git a/src/Api/DataTransformer/Dlc/DlcOutputDataTransformer.php b/src/Api/DataTransformer/Dlc/DlcOutputDataTransformer.php index 6bf3dc5e..aca60109 100644 --- a/src/Api/DataTransformer/Dlc/DlcOutputDataTransformer.php +++ b/src/Api/DataTransformer/Dlc/DlcOutputDataTransformer.php @@ -4,29 +4,20 @@ namespace App\Api\DataTransformer\Dlc; -use ApiPlatform\Core\DataTransformer\DataTransformerInterface; use App\Api\Output\Dlc\DlcOutput; use App\Entity\Dlc\Dlc; -class DlcOutputDataTransformer implements DataTransformerInterface +class DlcOutputDataTransformer { - public function transform($object, string $to, array $context = []): DlcOutput + public function transform(Dlc $dlc): DlcOutput { - /** @var Dlc $object */ - $output = new DlcOutput(); - - $output->setId($object->getId()->toString()); - $output->setName($object->getName()); - $output->setCreatedAt($object->getCreatedAt()); - $output->setLastUpdatedAt($object->getLastUpdatedAt()); - $output->setAppId($object->getAppId()); - $output->setDirectory($object->getDirectory()); - - return $output; - } - - public function supportsTransformation($data, string $to, array $context = []): bool - { - return DlcOutput::class === $to && $data instanceof Dlc; + return new DlcOutput( + $dlc->getId()->toString(), + $dlc->getName(), + $dlc->getAppId(), + $dlc->getDirectory(), + $dlc->getCreatedAt(), + $dlc->getLastUpdatedAt() + ); } } diff --git a/src/Api/DataTransformer/Mod/ModOutputDataTransformer.php b/src/Api/DataTransformer/Mod/ModOutputDataTransformer.php index 1575e01b..009298ff 100644 --- a/src/Api/DataTransformer/Mod/ModOutputDataTransformer.php +++ b/src/Api/DataTransformer/Mod/ModOutputDataTransformer.php @@ -4,7 +4,6 @@ namespace App\Api\DataTransformer\Mod; -use ApiPlatform\Core\DataTransformer\DataTransformerInterface; use App\Api\Output\Mod\ModOutput; use App\Entity\Mod\AbstractMod; use App\Entity\Mod\DirectoryMod; @@ -12,34 +11,20 @@ use App\Entity\Mod\Enum\ModTypeEnum; use App\Entity\Mod\SteamWorkshopMod; -class ModOutputDataTransformer implements DataTransformerInterface +class ModOutputDataTransformer { - public function transform($object, string $to, array $context = []): ModOutput + public function transform(AbstractMod $mod): ModOutput { - /** @var AbstractMod $object */ - $output = new ModOutput(); - - $output->setId($object->getId()->toString()); - $output->setName($object->getName()); - $output->setStatus($object->getStatus()?->value); - $output->setCreatedAt($object->getCreatedAt()); - $output->setLastUpdatedAt($object->getLastUpdatedAt()); - - if ($object instanceof SteamWorkshopMod) { - $output->setType($object->getType()->value); - $output->setSource(ModSourceEnum::STEAM_WORKSHOP->value); - $output->setItemId($object->getItemId()); - } elseif ($object instanceof DirectoryMod) { - $output->setType(ModTypeEnum::SERVER_SIDE->value); - $output->setSource(ModSourceEnum::DIRECTORY->value); - $output->setDirectory($object->getDirectory()); - } - - return $output; - } - - public function supportsTransformation($data, string $to, array $context = []): bool - { - return ModOutput::class === $to && $data instanceof AbstractMod; + return new ModOutput( + $mod->getId()->toString(), + $mod->getName(), + $mod instanceof SteamWorkshopMod ? ModSourceEnum::STEAM_WORKSHOP->value : ModSourceEnum::DIRECTORY->value, + $mod instanceof SteamWorkshopMod ? $mod->getType()->value : ModTypeEnum::SERVER_SIDE->value, + $mod->getStatus()?->value, + $mod instanceof SteamWorkshopMod ? $mod->getItemId() : null, + $mod instanceof DirectoryMod ? $mod->getDirectory() : null, + $mod->getCreatedAt(), + $mod->getLastUpdatedAt(), + ); } } diff --git a/src/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php b/src/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php index cb47cc58..2456e119 100644 --- a/src/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php +++ b/src/Api/DataTransformer/ModList/ModListDetailsOutputDataTransformer.php @@ -4,55 +4,41 @@ namespace App\Api\DataTransformer\ModList; -use ApiPlatform\Core\DataTransformer\DataTransformerInterface; use App\Api\DataTransformer\Dlc\DlcOutputDataTransformer; use App\Api\DataTransformer\Mod\ModOutputDataTransformer; -use App\Api\Output\Dlc\DlcOutput; -use App\Api\Output\Mod\ModOutput; use App\Api\Output\ModList\ModListDetailsOutput; use App\Api\Output\ModList\ModListOutput; use App\Entity\Dlc\Dlc; +use App\Entity\Mod\AbstractMod; use App\Entity\ModList\ModList; use App\Repository\Mod\ModRepository; -class ModListDetailsOutputDataTransformer implements DataTransformerInterface +class ModListDetailsOutputDataTransformer { public function __construct( - private ModOutputDataTransformer $modDataTransformer, + private ModOutputDataTransformer $modOutputDataTransformer, private DlcOutputDataTransformer $dlcOutputDataTransformer, private ModRepository $modRepository ) { } - public function transform($object, string $to, array $context = []): ModListOutput + public function transform(ModList $modList): ModListOutput { - /** @var ModList $object */ - $output = new ModListDetailsOutput(); - - $output->setId($object->getId()->toString()); - $output->setName($object->getName()); - $output->setActive($object->isActive()); - $output->setApproved($object->isApproved()); - $output->setCreatedAt($object->getCreatedAt()); - $output->setLastUpdatedAt($object->getLastUpdatedAt()); - - $mods = []; - foreach ($this->modRepository->findIncludedMods($object) as $mod) { - $mods[] = $this->modDataTransformer->transform($mod, ModOutput::class, $context); - } - $output->setMods($mods); - - $dlcs = array_map( - fn (Dlc $dlc) => $this->dlcOutputDataTransformer->transform($dlc, DlcOutput::class, $context), - $object->getDlcs() + return new ModListDetailsOutput( + $modList->getId()->toString(), + $modList->getName(), + $modList->isActive(), + $modList->isApproved(), + $modList->getCreatedAt(), + $modList->getLastUpdatedAt(), + array_map( + fn (AbstractMod $mod) => $this->modOutputDataTransformer->transform($mod), + $this->modRepository->findIncludedMods($modList) + ), + array_map( + fn (Dlc $dlc) => $this->dlcOutputDataTransformer->transform($dlc), + $modList->getDlcs() + ), ); - $output->setDlcs($dlcs); - - return $output; - } - - public function supportsTransformation($data, string $to, array $context = []): bool - { - return ModListDetailsOutput::class === $to && $data instanceof ModList; } } diff --git a/src/Api/DataTransformer/ModList/ModListOutputDataTransformer.php b/src/Api/DataTransformer/ModList/ModListOutputDataTransformer.php index 0f51f897..6d8180bb 100644 --- a/src/Api/DataTransformer/ModList/ModListOutputDataTransformer.php +++ b/src/Api/DataTransformer/ModList/ModListOutputDataTransformer.php @@ -4,29 +4,20 @@ namespace App\Api\DataTransformer\ModList; -use ApiPlatform\Core\DataTransformer\DataTransformerInterface; use App\Api\Output\ModList\ModListOutput; use App\Entity\ModList\ModList; -class ModListOutputDataTransformer implements DataTransformerInterface +class ModListOutputDataTransformer { - public function transform($object, string $to, array $context = []): ModListOutput + public function transform(ModList $modList): ModListOutput { - /** @var ModList $object */ - $output = new ModListOutput(); - - $output->setId($object->getId()->toString()); - $output->setName($object->getName()); - $output->setActive($object->isActive()); - $output->setApproved($object->isApproved()); - $output->setCreatedAt($object->getCreatedAt()); - $output->setLastUpdatedAt($object->getLastUpdatedAt()); - - return $output; - } - - public function supportsTransformation($data, string $to, array $context = []): bool - { - return ModListOutput::class === $to && $data instanceof ModList; + return new ModListOutput( + $modList->getId()->toString(), + $modList->getName(), + $modList->isActive(), + $modList->isApproved(), + $modList->getCreatedAt(), + $modList->getLastUpdatedAt(), + ); } } diff --git a/src/Api/Input/Attendance/AttendanceInput.php b/src/Api/Input/Attendance/AttendanceInput.php index 090c0b2d..4132c899 100644 --- a/src/Api/Input/Attendance/AttendanceInput.php +++ b/src/Api/Input/Attendance/AttendanceInput.php @@ -13,29 +13,9 @@ class AttendanceInput { #[Assert\NotBlank] #[Assert\Length(max: 255)] - private ?string $missionId = null; + public string $missionId; #[Assert\NotBlank] #[SteamProfileId] - private ?int $playerId = null; - - public function getMissionId(): ?string - { - return $this->missionId; - } - - public function setMissionId(?string $missionId): void - { - $this->missionId = $missionId; - } - - public function getPlayerId(): ?int - { - return $this->playerId; - } - - public function setPlayerId(?int $playerId): void - { - $this->playerId = $playerId; - } + public int $playerId; } diff --git a/src/Api/Output/Attendance/AttendanceOutput.php b/src/Api/Output/Attendance/AttendanceOutput.php index 28927ad9..92fb7fae 100644 --- a/src/Api/Output/Attendance/AttendanceOutput.php +++ b/src/Api/Output/Attendance/AttendanceOutput.php @@ -6,48 +6,11 @@ class AttendanceOutput { - private ?string $id = null; - private ?\DateTimeInterface $createdAt = null; - private ?string $missionId = null; - private ?int $playerId = null; - - public function getId(): ?string - { - return $this->id; - } - - public function setId(?string $id): void - { - $this->id = $id; - } - - public function getCreatedAt(): ?\DateTimeInterface - { - return $this->createdAt; - } - - public function setCreatedAt(?\DateTimeInterface $createdAt): void - { - $this->createdAt = $createdAt; - } - - public function getMissionId(): ?string - { - return $this->missionId; - } - - public function setMissionId(?string $missionId): void - { - $this->missionId = $missionId; - } - - public function getPlayerId(): ?int - { - return $this->playerId; - } - - public function setPlayerId(?int $playerId): void - { - $this->playerId = $playerId; + public function __construct( + public string $id, + public string $missionId, + public int $playerId, + public ?\DateTimeInterface $createdAt, + ) { } } diff --git a/src/Api/Output/Dlc/DlcOutput.php b/src/Api/Output/Dlc/DlcOutput.php index b3d73b4f..c7911eb1 100644 --- a/src/Api/Output/Dlc/DlcOutput.php +++ b/src/Api/Output/Dlc/DlcOutput.php @@ -6,70 +6,13 @@ class DlcOutput { - private ?string $id = null; - private ?string $name = null; - private ?\DateTimeInterface $createdAt = null; - private ?\DateTimeInterface $lastUpdatedAt = null; - private ?int $appId = null; - private ?string $directory = null; - - public function getId(): ?string - { - return $this->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 getCreatedAt(): ?\DateTimeInterface - { - return $this->createdAt; - } - - public function setCreatedAt(?\DateTimeInterface $createdAt): void - { - $this->createdAt = $createdAt; - } - - public function getLastUpdatedAt(): ?\DateTimeInterface - { - return $this->lastUpdatedAt; - } - - public function setLastUpdatedAt(?\DateTimeInterface $lastUpdatedAt): void - { - $this->lastUpdatedAt = $lastUpdatedAt; - } - - public function getAppId(): ?int - { - return $this->appId; - } - - public function setAppId(?int $appId): void - { - $this->appId = $appId; - } - - public function getDirectory(): ?string - { - return $this->directory; - } - - public function setDirectory(?string $directory): void - { - $this->directory = $directory; + public function __construct( + public string $id, + public string $name, + public int $appId, + public string $directory, + public \DateTimeInterface $createdAt, + public ?\DateTimeInterface $lastUpdatedAt, + ) { } } diff --git a/src/Api/Output/Mod/ModOutput.php b/src/Api/Output/Mod/ModOutput.php index 1cb7d0c5..5feb4e52 100644 --- a/src/Api/Output/Mod/ModOutput.php +++ b/src/Api/Output/Mod/ModOutput.php @@ -6,103 +6,16 @@ class ModOutput { - private ?string $id = null; - private ?string $name = null; - private ?\DateTimeInterface $createdAt = null; - private ?\DateTimeInterface $lastUpdatedAt = null; - private ?string $source = null; - private ?string $status = null; - private ?string $type = null; - private ?int $itemId = null; - private ?string $directory = null; - - public function getId(): ?string - { - return $this->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 getCreatedAt(): ?\DateTimeInterface - { - return $this->createdAt; - } - - public function setCreatedAt(?\DateTimeInterface $createdAt): void - { - $this->createdAt = $createdAt; - } - - public function getLastUpdatedAt(): ?\DateTimeInterface - { - return $this->lastUpdatedAt; - } - - public function setLastUpdatedAt(?\DateTimeInterface $lastUpdatedAt): void - { - $this->lastUpdatedAt = $lastUpdatedAt; - } - - public function getSource(): ?string - { - return $this->source; - } - - public function setSource(?string $source): void - { - $this->source = $source; - } - - public function getStatus(): ?string - { - return $this->status; - } - - public function setStatus(?string $status): void - { - $this->status = $status; - } - - public function getType(): ?string - { - return $this->type; - } - - public function setType(?string $type): void - { - $this->type = $type; - } - - public function getItemId(): ?int - { - return $this->itemId; - } - - public function setItemId(?int $itemId): void - { - $this->itemId = $itemId; - } - - public function getDirectory(): ?string - { - return $this->directory; - } - - public function setDirectory(?string $directory): void - { - $this->directory = $directory; + public function __construct( + public string $id, + public string $name, + public string $source, + public string $type, + public ?string $status, + public ?int $itemId, + public ?string $directory, + public ?\DateTimeInterface $createdAt, + public ?\DateTimeInterface $lastUpdatedAt, + ) { } } diff --git a/src/Api/Output/ModList/ModListDetailsOutput.php b/src/Api/Output/ModList/ModListDetailsOutput.php index 1becb13e..482e6853 100644 --- a/src/Api/Output/ModList/ModListDetailsOutput.php +++ b/src/Api/Output/ModList/ModListDetailsOutput.php @@ -9,38 +9,27 @@ class ModListDetailsOutput extends ModListOutput { - private array $mods = []; - private array $dlcs = []; - - /** - * @return ModOutput[] - */ - public function getMods(): array - { - return $this->mods; - } - /** * @param ModOutput[] $mods - */ - public function setMods(array $mods): void - { - $this->mods = $mods; - } - - /** - * @return DlcOutput[] - */ - public function getDlcs(): array - { - return $this->dlcs; - } - - /** * @param DlcOutput[] $dlcs */ - public function setDlcs(array $dlcs): void - { - $this->dlcs = $dlcs; + public function __construct( + string $id, + string $name, + bool $active, + bool $approved, + \DateTimeInterface $createdAt, + ?\DateTimeInterface $lastUpdatedAt, + public array $mods, + public array $dlcs + ) { + parent::__construct( + $id, + $name, + $active, + $approved, + $createdAt, + $lastUpdatedAt + ); } } diff --git a/src/Api/Output/ModList/ModListOutput.php b/src/Api/Output/ModList/ModListOutput.php index 4a8c4161..1be77130 100644 --- a/src/Api/Output/ModList/ModListOutput.php +++ b/src/Api/Output/ModList/ModListOutput.php @@ -6,70 +6,13 @@ class ModListOutput { - private ?string $id = null; - private ?string $name = null; - private bool $active; - private bool $approved; - private ?\DateTimeInterface $createdAt = null; - private ?\DateTimeInterface $lastUpdatedAt = null; - - public function getId(): ?string - { - return $this->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 isActive(): bool - { - return $this->active; - } - - public function setActive(bool $active): void - { - $this->active = $active; - } - - public function isApproved(): bool - { - return $this->approved; - } - - public function setApproved(bool $approved): void - { - $this->approved = $approved; - } - - public function getCreatedAt(): ?\DateTimeInterface - { - return $this->createdAt; - } - - public function setCreatedAt(?\DateTimeInterface $createdAt): void - { - $this->createdAt = $createdAt; - } - - public function getLastUpdatedAt(): ?\DateTimeInterface - { - return $this->lastUpdatedAt; - } - - public function setLastUpdatedAt(?\DateTimeInterface $lastUpdatedAt): void - { - $this->lastUpdatedAt = $lastUpdatedAt; + public function __construct( + public string $id, + public string $name, + public bool $active, + public bool $approved, + public \DateTimeInterface $createdAt, + public ?\DateTimeInterface $lastUpdatedAt, + ) { } } diff --git a/src/Api/Processor/Attendance/AttendanceProcessor.php b/src/Api/Processor/Attendance/AttendanceProcessor.php new file mode 100644 index 00000000..8255708c --- /dev/null +++ b/src/Api/Processor/Attendance/AttendanceProcessor.php @@ -0,0 +1,38 @@ +validator->validate($data); + + $attendance = $this->attendanceInputDataTransformer->transform($data); + + $this->persistProcessor->process($attendance, $operation, $uriVariables, $context); + + return $this->attendanceOutputDataTransformer->transform($attendance); + } +} diff --git a/src/Api/Provider/Attendance/AttendanceDataProvider.php b/src/Api/Provider/Attendance/AttendanceDataProvider.php new file mode 100644 index 00000000..2af1717d --- /dev/null +++ b/src/Api/Provider/Attendance/AttendanceDataProvider.php @@ -0,0 +1,31 @@ +attendanceOutputDataTransformer->transform($data); + } +} diff --git a/src/Api/Provider/Common/AbstractDataProvider.php b/src/Api/Provider/Common/AbstractDataProvider.php new file mode 100644 index 00000000..871290e2 --- /dev/null +++ b/src/Api/Provider/Common/AbstractDataProvider.php @@ -0,0 +1,64 @@ +collectionProvider->provide($operation, $uriVariables, $context); + + return new Pagination\TraversablePaginator( + $this->transformCollection($paginator->getIterator(), $operation, $uriVariables, $context), + $paginator->getCurrentPage(), + $paginator->getItemsPerPage(), + $paginator->getTotalItems(), + ); + } + + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + if (null !== $item) { + $item = $this->provideTransformedData($item, $operation, $uriVariables, $context); + } + + return $item; + } + + public function provideTransformedData( + mixed $data, + Operation $operation, + array $uriVariables = [], + array $context = [] + ): object { + return $data; + } + + private function transformCollection( + \Traversable $collection, + Operation $operation, + array $uriVariables = [], + array $context = [] + ): \Traversable { + foreach ($collection as $item) { + yield $this->provideTransformedData($item, $operation, $uriVariables, $context); + } + } +} diff --git a/src/Api/Provider/ModList/ModListDataProvider.php b/src/Api/Provider/ModList/ModListDataProvider.php new file mode 100644 index 00000000..b4c07274 --- /dev/null +++ b/src/Api/Provider/ModList/ModListDataProvider.php @@ -0,0 +1,31 @@ +modListOutputDataTransformer->transform($data); + } +} diff --git a/src/Api/Provider/ModList/ModListDetailsDataProvider.php b/src/Api/Provider/ModList/ModListDetailsDataProvider.php new file mode 100644 index 00000000..854e91ae --- /dev/null +++ b/src/Api/Provider/ModList/ModListDetailsDataProvider.php @@ -0,0 +1,31 @@ +modListDetailsOutputDataTransformer->transform($data); + } +} diff --git a/src/Api/Serializer/Normalizer/PaginatorNormalizer.php b/src/Api/Serializer/Normalizer/PaginatorNormalizer.php index 3908f4f5..63f70c67 100644 --- a/src/Api/Serializer/Normalizer/PaginatorNormalizer.php +++ b/src/Api/Serializer/Normalizer/PaginatorNormalizer.php @@ -4,7 +4,7 @@ namespace App\Api\Serializer\Normalizer; -use ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator; +use ApiPlatform\State\Pagination\TraversablePaginator; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; @@ -13,9 +13,11 @@ class PaginatorNormalizer implements NormalizerInterface, NormalizerAwareInterfa { use NormalizerAwareTrait; - public function normalize($object, string $format = null, array $context = []): array + /** + * @param TraversablePaginator $object + */ + public function normalize(mixed $object, string $format = null, array $context = []): array { - /** @var Paginator $object */ $data = []; foreach ($object->getIterator() as $item) { $data[] = $this->normalizer->normalize($item, $format, $context); @@ -31,8 +33,8 @@ public function normalize($object, string $format = null, array $context = []): ]; } - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization(mixed $data, string $format = null): bool { - return $data instanceof Paginator && 'json' === $format; + return $data instanceof TraversablePaginator && 'json' === $format; } } diff --git a/src/EventSubscriber/UserLocaleRequestSubscriber.php b/src/EventSubscriber/UserLocaleRequestSubscriber.php index 9480ddd1..42d16255 100644 --- a/src/EventSubscriber/UserLocaleRequestSubscriber.php +++ b/src/EventSubscriber/UserLocaleRequestSubscriber.php @@ -44,6 +44,9 @@ public function onKernelRequest(RequestEvent $event): void } $request = $event->getRequest(); + if (str_starts_with($request->getRequestUri(), '/api')) { + return; + } $negotiatedLanguage = $request->getLocale(); $acceptLanguage = $request->headers->get('Accept-Language'); diff --git a/src/Validator/Attendance/UniqueAttendanceValidator.php b/src/Validator/Attendance/UniqueAttendanceValidator.php index 118da96b..065b540d 100644 --- a/src/Validator/Attendance/UniqueAttendanceValidator.php +++ b/src/Validator/Attendance/UniqueAttendanceValidator.php @@ -22,8 +22,8 @@ public function validate(mixed $value, Constraint $constraint): void throw new UnexpectedTypeException($constraint, UniqueAttendance::class); } - $missionId = $value->getMissionId(); - $playerId = $value->getPlayerId(); + $missionId = $value->missionId; + $playerId = $value->playerId; if (!$missionId || !$playerId) { return; diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml index 743a6895..0f7ff15b 100644 --- a/tests/functional.suite.yml +++ b/tests/functional.suite.yml @@ -4,7 +4,7 @@ modules: - Symfony: app_path: 'src' environment: 'test' - cache_router: true + cache_router: false # Needs to be disabled in order to work correctly with Api Platform 3 routes rebootable_client: false authenticator: true - Doctrine2: diff --git a/tests/functional/Api/ModList/GetModListsByIdCest.php b/tests/functional/Api/ModList/GetModListsByIdCest.php index faa915ef..634bf601 100644 --- a/tests/functional/Api/ModList/GetModListsByIdCest.php +++ b/tests/functional/Api/ModList/GetModListsByIdCest.php @@ -52,9 +52,10 @@ public function getModListByIdUsingValidApiKeyWhenModListDoesNotExist(Functional $I->seeResponseCodeIs(HttpCode::NOT_FOUND); $I->seeResponseContainsJson([ - 'type' => 'https://tools.ietf.org/html/rfc2616#section-10', 'title' => 'An error occurred', 'detail' => 'Not Found', + 'status' => HttpCode::NOT_FOUND, + 'type' => '/errors/404', ]); }