forked from Somnia/SomniaRooms
Added Validation to API requests.
- Added Symfony Validation Lib. - Updated API DTOs to include validation constraints.
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
"symfony/security-bundle": "7.0.*",
|
"symfony/security-bundle": "7.0.*",
|
||||||
"symfony/serializer": "7.0.*",
|
"symfony/serializer": "7.0.*",
|
||||||
"symfony/twig-bundle": "7.0.*",
|
"symfony/twig-bundle": "7.0.*",
|
||||||
|
"symfony/validator": "7.0.*",
|
||||||
"symfony/var-exporter": "7.0.4",
|
"symfony/var-exporter": "7.0.4",
|
||||||
"symfony/yaml": "7.0.*",
|
"symfony/yaml": "7.0.*",
|
||||||
"twig/extra-bundle": "^2.12|^3.0",
|
"twig/extra-bundle": "^2.12|^3.0",
|
||||||
|
|||||||
Generated
+9
-8
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "1f7a502767330ce66e9e7f69229604a3",
|
"content-hash": "974cb22b15d6dc64bd6dac49da5d671d",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
@@ -6582,16 +6582,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/validator",
|
"name": "symfony/validator",
|
||||||
"version": "v7.0.6",
|
"version": "v7.0.10",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/validator.git",
|
"url": "https://github.com/symfony/validator.git",
|
||||||
"reference": "a2df2c63b7944a162dee86ab8065f2f91b7d6e36"
|
"reference": "b3e4d838cdae9f2882402c2ad8018a27d469c075"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/validator/zipball/a2df2c63b7944a162dee86ab8065f2f91b7d6e36",
|
"url": "https://api.github.com/repos/symfony/validator/zipball/b3e4d838cdae9f2882402c2ad8018a27d469c075",
|
||||||
"reference": "a2df2c63b7944a162dee86ab8065f2f91b7d6e36",
|
"reference": "b3e4d838cdae9f2882402c2ad8018a27d469c075",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -6636,7 +6636,8 @@
|
|||||||
"Symfony\\Component\\Validator\\": ""
|
"Symfony\\Component\\Validator\\": ""
|
||||||
},
|
},
|
||||||
"exclude-from-classmap": [
|
"exclude-from-classmap": [
|
||||||
"/Tests/"
|
"/Tests/",
|
||||||
|
"/Resources/bin/"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
@@ -6656,7 +6657,7 @@
|
|||||||
"description": "Provides tools to validate values",
|
"description": "Provides tools to validate values",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/validator/tree/v7.0.6"
|
"source": "https://github.com/symfony/validator/tree/v7.0.10"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -6672,7 +6673,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-03-28T09:20:36+00:00"
|
"time": "2024-07-26T12:31:22+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/var-dumper",
|
"name": "symfony/var-dumper",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace App\Controller;
|
|||||||
use App\ApiErrorException;
|
use App\ApiErrorException;
|
||||||
use App\DTO\ApiErrorMessage;
|
use App\DTO\ApiErrorMessage;
|
||||||
use App\Entity\Booking;
|
use App\Entity\Booking;
|
||||||
use App\Entity\BookingCustomer;
|
|
||||||
use App\Entity\BookingRoom;
|
use App\Entity\BookingRoom;
|
||||||
use App\Repository\BookingRepository;
|
use App\Repository\BookingRepository;
|
||||||
use App\Repository\RoomCategoryRepository;
|
use App\Repository\RoomCategoryRepository;
|
||||||
@@ -18,8 +17,6 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
use Nelmio\ApiDocBundle\Annotation\Model;
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
||||||
@@ -51,10 +48,6 @@ class BookingController extends AbstractController
|
|||||||
#[MapRequestPayload()] BookingDetailsRequest $detailsRequest
|
#[MapRequestPayload()] BookingDetailsRequest $detailsRequest
|
||||||
): JsonResponse {
|
): JsonResponse {
|
||||||
|
|
||||||
if (\is_null($detailsRequest)) {
|
|
||||||
throw new ApiErrorException(new ApiErrorMessage(400, ApiErrorMessage::TYPE_INVALID_REQUEST_BODY_FORMAT));
|
|
||||||
}
|
|
||||||
|
|
||||||
$selectedBooking = $repoBooking->findOneBy(["refNumber" => $detailsRequest->refNumber]);
|
$selectedBooking = $repoBooking->findOneBy(["refNumber" => $detailsRequest->refNumber]);
|
||||||
if (\is_null($selectedBooking)) {
|
if (\is_null($selectedBooking)) {
|
||||||
throw new NotFoundHttpException('Booking not found');
|
throw new NotFoundHttpException('Booking not found');
|
||||||
@@ -87,18 +80,12 @@ class BookingController extends AbstractController
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
public function newBooking(
|
public function newBooking(
|
||||||
Request $request,
|
|
||||||
EntityManagerInterface $entityManager,
|
EntityManagerInterface $entityManager,
|
||||||
RoomCategoryRepository $repoCat,
|
RoomCategoryRepository $repoCat,
|
||||||
RoomAvailabilityRepository $repoAvailability,
|
RoomAvailabilityRepository $repoAvailability,
|
||||||
PricesService $priceSrv,
|
PricesService $priceSrv,
|
||||||
#[MapRequestPayload()] BookingCreateRequest $createRequest
|
#[MapRequestPayload()] BookingCreateRequest $createRequest
|
||||||
): JsonResponse {
|
): JsonResponse {
|
||||||
if (\is_null($createRequest)) {
|
|
||||||
throw new ApiErrorException(
|
|
||||||
new ApiErrorMessage(400, ApiErrorMessage::TYPE_INVALID_REQUEST_BODY_FORMAT)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$booking = new Booking();
|
$booking = new Booking();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace App\Controller;
|
|||||||
|
|
||||||
use App\ApiErrorException;
|
use App\ApiErrorException;
|
||||||
use App\DTO\ApiErrorMessage;
|
use App\DTO\ApiErrorMessage;
|
||||||
use App\Repository\FareTableRepository;
|
|
||||||
use App\Repository\RoomAvailabilityRepository;
|
use App\Repository\RoomAvailabilityRepository;
|
||||||
use App\Repository\RoomCategoryRepository;
|
use App\Repository\RoomCategoryRepository;
|
||||||
use App\Request\SearchAvailabilityPeriodRequest;
|
use App\Request\SearchAvailabilityPeriodRequest;
|
||||||
@@ -14,12 +13,10 @@ use App\Response\SearchPricesForCategoryResponse;
|
|||||||
use App\Service\PricesService;
|
use App\Service\PricesService;
|
||||||
use Nelmio\ApiDocBundle\Annotation\Model;
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
||||||
|
|
||||||
class SearchRoomsController extends AbstractController
|
class SearchRoomsController extends AbstractController
|
||||||
{
|
{
|
||||||
@@ -50,15 +47,9 @@ class SearchRoomsController extends AbstractController
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
public function getAvailabilityForPeriod(
|
public function getAvailabilityForPeriod(
|
||||||
Request $request,
|
|
||||||
RoomAvailabilityRepository $repoAvailability,
|
RoomAvailabilityRepository $repoAvailability,
|
||||||
#[MapRequestPayload()] SearchAvailabilityPeriodRequest $searchRequest
|
#[MapRequestPayload()] SearchAvailabilityPeriodRequest $searchRequest
|
||||||
): Response {
|
): JsonResponse {
|
||||||
if (\is_null($searchRequest)) {
|
|
||||||
throw new ApiErrorException(
|
|
||||||
new ApiErrorMessage(400, ApiErrorMessage::TYPE_INVALID_REQUEST_BODY_FORMAT)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($searchRequest->startDate >= $searchRequest->endDate) {
|
if ($searchRequest->startDate >= $searchRequest->endDate) {
|
||||||
throw new ApiErrorException(
|
throw new ApiErrorException(
|
||||||
@@ -78,13 +69,9 @@ class SearchRoomsController extends AbstractController
|
|||||||
#[Route('/api/search/availabilityDetails', name: 'app_search_availabilityDetails', methods: ["POST"], format: "json")]
|
#[Route('/api/search/availabilityDetails', name: 'app_search_availabilityDetails', methods: ["POST"], format: "json")]
|
||||||
#[OA\Tag(name: "Searchs")]
|
#[OA\Tag(name: "Searchs")]
|
||||||
public function getAvailabilityForPeriodDetails(
|
public function getAvailabilityForPeriodDetails(
|
||||||
Request $request,
|
|
||||||
RoomAvailabilityRepository $repoAvailability,
|
RoomAvailabilityRepository $repoAvailability,
|
||||||
#[MapRequestPayload()] SearchAvailabilityPeriodRequest $searchRequest
|
#[MapRequestPayload()] SearchAvailabilityPeriodRequest $searchRequest
|
||||||
): Response {
|
): JsonResponse {
|
||||||
if (\is_null($searchRequest)) {
|
|
||||||
throw new \Exception('Invalid Payload', 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$rs = $repoAvailability->getAvailabilityForPeriodDetails($searchRequest->startDate, $searchRequest->endDate);
|
$rs = $repoAvailability->getAvailabilityForPeriodDetails($searchRequest->startDate, $searchRequest->endDate);
|
||||||
|
|
||||||
@@ -119,16 +106,10 @@ class SearchRoomsController extends AbstractController
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
public function getPricesForCategoryOnPeriod(
|
public function getPricesForCategoryOnPeriod(
|
||||||
Request $request,
|
|
||||||
RoomCategoryRepository $repoCat,
|
RoomCategoryRepository $repoCat,
|
||||||
PricesService $priceService,
|
PricesService $priceService,
|
||||||
#[MapRequestPayload()] SearchPricesForCategoryRequest $searchRequest
|
#[MapRequestPayload()] SearchPricesForCategoryRequest $searchRequest
|
||||||
): Response {
|
): JsonResponse {
|
||||||
if (\is_null($searchRequest)) {
|
|
||||||
throw new ApiErrorException(
|
|
||||||
new ApiErrorMessage(400, ApiErrorMessage::TYPE_INVALID_REQUEST_BODY_FORMAT)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$roomCategory = $repoCat->find($searchRequest->roomCategory);
|
$roomCategory = $repoCat->find($searchRequest->roomCategory);
|
||||||
if ($roomCategory === null) {
|
if ($roomCategory === null) {
|
||||||
@@ -153,19 +134,4 @@ class SearchRoomsController extends AbstractController
|
|||||||
|
|
||||||
return $this->json(["results" => $rs]);
|
return $this->json(["results" => $rs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/debug/search', name: 'app_search_faresDebug')]
|
|
||||||
public function faresDebug(Request $request, PricesService $priceService, FareTableRepository $repoFareTable, RoomCategoryRepository $repoCat): Response
|
|
||||||
{
|
|
||||||
$fareTable[] = $repoFareTable->find(1);
|
|
||||||
$fareTable[] = $repoFareTable->find(2);
|
|
||||||
$cat = $repoCat->find(4);
|
|
||||||
|
|
||||||
$startDate = new \DateTime("2024-04-27");
|
|
||||||
$endDate = new \DateTime("2024-05-02");
|
|
||||||
|
|
||||||
$rs = $priceService->getFinalPricesForSearch($cat, $startDate, $endDate);
|
|
||||||
|
|
||||||
return $this->json($rs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace App\Entity;
|
|||||||
use App\Repository\BookingCustomerRepository;
|
use App\Repository\BookingCustomerRepository;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Annotation\Ignore;
|
use Symfony\Component\Serializer\Annotation\Ignore;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: BookingCustomerRepository::class)]
|
#[ORM\Entity(repositoryClass: BookingCustomerRepository::class)]
|
||||||
class BookingCustomer
|
class BookingCustomer
|
||||||
@@ -21,15 +22,20 @@ class BookingCustomer
|
|||||||
private ?Booking $booking = null;
|
private ?Booking $booking = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 64)]
|
#[ORM\Column(length: 64)]
|
||||||
|
#[Assert\NotBlank]
|
||||||
private ?string $name = null;
|
private ?string $name = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 255)]
|
#[ORM\Column(length: 255)]
|
||||||
|
#[Assert\NotBlank]
|
||||||
private ?string $surname = null;
|
private ?string $surname = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 255)]
|
#[ORM\Column(length: 255)]
|
||||||
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\Email]
|
||||||
private ?string $email = null;
|
private ?string $email = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 255)]
|
#[ORM\Column(length: 255)]
|
||||||
|
#[Assert\NotBlank]
|
||||||
private ?string $phoneNumber = null;
|
private ?string $phoneNumber = null;
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
|||||||
use Symfony\Component\HttpKernel\KernelEvents;
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||||
|
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
||||||
|
|
||||||
class ApiExceptionSubscriber implements EventSubscriberInterface
|
class ApiExceptionSubscriber implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
@@ -34,7 +35,25 @@ class ApiExceptionSubscriber implements EventSubscriberInterface
|
|||||||
* low-level exception, which should *not* be exposed
|
* low-level exception, which should *not* be exposed
|
||||||
*/
|
*/
|
||||||
if ($e instanceof HttpExceptionInterface) {
|
if ($e instanceof HttpExceptionInterface) {
|
||||||
$apiErrorMsg->setExtraData('detail', $e->getMessage());
|
//Check if it's a Validation error.
|
||||||
|
// When using MapRequestPayload() ValidationErrors throw HttpExceptions.
|
||||||
|
$prev = $e->getPrevious();
|
||||||
|
if ($prev instanceof ValidationFailedException) {
|
||||||
|
//Get validation error details.
|
||||||
|
$errorList = [];
|
||||||
|
$violationList = $prev->getViolations();
|
||||||
|
foreach ($violationList as $violation) {
|
||||||
|
$errorList[] = [
|
||||||
|
'field' => $violation->getPropertyPath(),
|
||||||
|
'message' => $violation->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$apiErrorMsg->setExtraData('detail', "Validation Error. See errorList for details");
|
||||||
|
$apiErrorMsg->setExtraData('errorList', $errorList);
|
||||||
|
} else {
|
||||||
|
//Get exception error message.
|
||||||
|
$apiErrorMsg->setExtraData('detail', $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,19 +3,26 @@
|
|||||||
namespace App\Request;
|
namespace App\Request;
|
||||||
|
|
||||||
use App\Entity\BookingCustomer;
|
use App\Entity\BookingCustomer;
|
||||||
|
use DateTimeInterface;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class BookingCreateRequest
|
class BookingCreateRequest
|
||||||
{
|
{
|
||||||
#[OA\Property(description: 'Booking Arrival date')]
|
#[OA\Property(description: 'Booking Arrival date')]
|
||||||
public \DateTime $arrivalDate;
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\GreaterThanOrEqual(value: 'today')]
|
||||||
|
public DateTimeInterface $arrivalDate;
|
||||||
|
|
||||||
#[OA\Property(description: 'Booking departure date')]
|
#[OA\Property(description: 'Booking departure date')]
|
||||||
public \DateTime $departureDate;
|
#[Assert\NotBlank]
|
||||||
|
public DateTimeInterface $departureDate;
|
||||||
|
|
||||||
#[OA\Property(
|
#[OA\Property(
|
||||||
description: 'Booking customer details',
|
description: 'Booking customer details',
|
||||||
)]
|
)]
|
||||||
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\Valid]
|
||||||
public BookingCustomer $customerDetails;
|
public BookingCustomer $customerDetails;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,5 +31,7 @@ class BookingCreateRequest
|
|||||||
#[OA\Property(
|
#[OA\Property(
|
||||||
description: 'Rooms to book',
|
description: 'Rooms to book',
|
||||||
)]
|
)]
|
||||||
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\Valid]
|
||||||
public array $rooms;
|
public array $rooms;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,21 @@
|
|||||||
namespace App\Request;
|
namespace App\Request;
|
||||||
|
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class BookingCreateRoomItem
|
class BookingCreateRoomItem
|
||||||
{
|
{
|
||||||
#[OA\Property(description: 'Room category ID')]
|
#[OA\Property(description: 'Room category ID')]
|
||||||
|
#[Assert\NotBlank]
|
||||||
public int $roomCategory;
|
public int $roomCategory;
|
||||||
|
|
||||||
#[OA\Property(description: 'Guest number for the room')]
|
#[OA\Property(description: 'Guest number for the room')]
|
||||||
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\GreaterThan(value: 0)]
|
||||||
public int $guestNumber;
|
public int $guestNumber;
|
||||||
|
|
||||||
#[OA\Property(description: 'Room amount')]
|
#[OA\Property(description: 'Room amount')]
|
||||||
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\GreaterThan(value: 0)]
|
||||||
public int $amount;
|
public int $amount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,16 @@
|
|||||||
namespace App\Request;
|
namespace App\Request;
|
||||||
|
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class BookingDetailsRequest
|
class BookingDetailsRequest
|
||||||
{
|
{
|
||||||
#[OA\Property(description: 'Booking reference number')]
|
#[OA\Property(description: 'Booking reference number')]
|
||||||
|
#[Assert\NotBlank]
|
||||||
public string $refNumber;
|
public string $refNumber;
|
||||||
|
|
||||||
#[OA\Property(maxLength: 255, description: 'Email associated to the booking')]
|
#[OA\Property(maxLength: 255, description: 'Email associated to the booking')]
|
||||||
|
#[Assert\NotBlank]
|
||||||
|
#[Assert\Email]
|
||||||
public string $email;
|
public string $email;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Request;
|
namespace App\Request;
|
||||||
|
|
||||||
|
use DateTimeInterface;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class SearchAvailabilityPeriodRequest
|
class SearchAvailabilityPeriodRequest
|
||||||
{
|
{
|
||||||
#[OA\Property(description: 'Period start date')]
|
#[OA\Property(description: 'Period start date')]
|
||||||
public \DateTime $startDate;
|
#[Assert\NotBlank]
|
||||||
|
public DateTimeInterface $startDate;
|
||||||
|
|
||||||
#[OA\Property(description: 'Period end date')]
|
#[OA\Property(description: 'Period end date')]
|
||||||
public \DateTime $endDate;
|
#[Assert\NotBlank]
|
||||||
|
public DateTimeInterface $endDate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,21 @@
|
|||||||
|
|
||||||
namespace App\Request;
|
namespace App\Request;
|
||||||
|
|
||||||
|
use DateTimeInterface;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
class SearchPricesForCategoryRequest
|
class SearchPricesForCategoryRequest
|
||||||
{
|
{
|
||||||
#[OA\Property(description: 'Room category ID')]
|
#[OA\Property(description: 'Room category ID')]
|
||||||
|
#[Assert\NotBlank]
|
||||||
public int $roomCategory;
|
public int $roomCategory;
|
||||||
|
|
||||||
#[OA\Property(description: 'Period start date')]
|
#[OA\Property(description: 'Period start date')]
|
||||||
public \DateTime $startDate;
|
#[Assert\NotBlank]
|
||||||
|
public DateTimeInterface $startDate;
|
||||||
|
|
||||||
#[OA\Property(description: 'Period end date')]
|
#[OA\Property(description: 'Period end date')]
|
||||||
public \DateTime $endDate;
|
#[Assert\NotBlank]
|
||||||
|
public DateTimeInterface $endDate;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user