Skip to content
Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

- [#260](https://github.com/os2display/display-api-service/pull/260)
- Changed how exceptions are handled in InstantBook.

## [2.5.1] - 2025-06-23

- [#245](https://github.com/os2display/display-api-service/pull/245)
Expand Down
19 changes: 19 additions & 0 deletions config/packages/api_platform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,22 @@ api_platform:
email: [email protected]
license:
name: MIT

# @see https://api-platform.com/docs/core/errors/#exception-to-status-configuration-using-symfony
exception_to_status:
# The 4 following handlers are registered by default, keep those lines to prevent unexpected side effects
Symfony\Component\Serializer\Exception\ExceptionInterface: 400 # Use a raw status code (recommended)
ApiPlatform\Exception\InvalidArgumentException: !php/const Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST
ApiPlatform\ParameterValidator\Exception\ValidationExceptionInterface: 400
Doctrine\ORM\OptimisticLockException: 409

# Validation exception
ApiPlatform\Validator\Exception\ValidationException: !php/const Symfony\Component\HttpFoundation\Response::HTTP_UNPROCESSABLE_ENTITY

# App exception mappings
App\Exceptions\BadRequestException: 400
App\Exceptions\ForbiddenException: 403
App\Exceptions\NotFoundException: 404
App\Exceptions\NotAcceptableException: 406
App\Exceptions\ConflictException: 409
App\Exceptions\TooManyRequestsException: 429
28 changes: 28 additions & 0 deletions migrations/Version20250828084617.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20250828084617 extends AbstractMigration
{
public function getDescription(): string
{
return 'Rename interactive_slide to interactive_slide_config';
}

public function up(Schema $schema): void
{
$this->addSql('RENAME TABLE interactive_slide TO interactive_slide_config;');
$this->addSql('ALTER TABLE interactive_slide_config RENAME INDEX idx_138e544d9033212a TO IDX_D30060259033212A');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE interactive_slide_config RENAME INDEX idx_d30060259033212a TO IDX_138E544D9033212A');
$this->addSql('RENAME TABLE interactive_slide_config TO interactive_slide;');
}
}
29 changes: 21 additions & 8 deletions src/Controller/InteractiveController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@

use App\Entity\ScreenUser;
use App\Entity\Tenant\Slide;
use App\Entity\User;
use App\Exceptions\NotFoundException;
use App\Exceptions\BadRequestException;
use App\Exceptions\ConflictException;
use App\Exceptions\NotAcceptableException;
use App\Exceptions\TooManyRequestsException;
use App\Service\InteractiveSlideService;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

#[AsController]
final readonly class InteractiveController
Expand All @@ -22,18 +25,28 @@ public function __construct(
private Security $security,
) {}

/**
* @throws ConflictException
* @throws BadRequestException
* @throws NotAcceptableException
* @throws TooManyRequestsException
*/
public function __invoke(Request $request, Slide $slide): JsonResponse
{
$user = $this->security->getUser();

if (!($user instanceof ScreenUser)) {
throw new AccessDeniedHttpException('Only screen user can perform action.');
}

$tenant = $user->getActiveTenant();

$requestBody = $request->toArray();

$interactionRequest = $this->interactiveSlideService->parseRequestBody($requestBody);

$user = $this->security->getUser();

if (!($user instanceof User || $user instanceof ScreenUser)) {
throw new NotFoundException('User not found');
}
$actionResult = $this->interactiveSlideService->performAction($tenant, $slide, $interactionRequest);

return new JsonResponse($this->interactiveSlideService->performAction($user, $slide, $interactionRequest));
return new JsonResponse($actionResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Symfony\Component\Serializer\Annotation\Ignore;

#[ORM\Entity(repositoryClass: InteractiveSlideRepository::class)]
class InteractiveSlide extends AbstractTenantScopedEntity
class InteractiveSlideConfig extends AbstractTenantScopedEntity
{
#[Ignore]
#[ORM\Column(nullable: true)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

namespace App\Exceptions;

class InteractiveSlideException extends \Exception
class ForbiddenException extends \Exception
{
}
9 changes: 9 additions & 0 deletions src/Exceptions/NotAcceptableException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace App\Exceptions;

class NotAcceptableException extends \Exception
{
}
9 changes: 9 additions & 0 deletions src/Exceptions/TooManyRequestsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace App\Exceptions;

class TooManyRequestsException extends \Exception
{
}
Loading