feat: groups price calculator admin crud, booking/offer flow and api
This commit is contained in:
+180
-25
@@ -2,13 +2,20 @@
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Model\CmsHotelData;
|
||||
use App\Model\CmsRegionData;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class CmsDataProvider
|
||||
{
|
||||
public function __construct(private readonly HttpClientInterface $httpClient, private readonly string $apiKey)
|
||||
{
|
||||
public function __construct(
|
||||
private readonly HttpClientInterface $httpClient,
|
||||
private readonly CacheInterface $cache,
|
||||
private readonly string $apiKey,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,33 +34,181 @@ class CmsDataProvider
|
||||
return $result['hotel']['images'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public function getHotelImages(string $hotelCode): ?array
|
||||
{
|
||||
return $this->getHotelDetails($hotelCode)?->images;
|
||||
}
|
||||
|
||||
public function getHotelDetails(string $hotelCode): ?CmsHotelData
|
||||
{
|
||||
$data = $this->fetchHotelDetails($hotelCode);
|
||||
|
||||
if (isset($data['success']) && false === $data['success']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->mapHotelData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* success?: bool,
|
||||
* message?: string,
|
||||
* name?: string,
|
||||
* address?: string,
|
||||
* description?: string,
|
||||
* features?: string,
|
||||
* room_types?: string,
|
||||
* additional_information?: string,
|
||||
* images?: array<string, mixed>,
|
||||
* icons?: array<string, bool|string>,
|
||||
* region?: array{
|
||||
* name: string,
|
||||
* latitude: float,
|
||||
* longitude: float,
|
||||
* webcam: string,
|
||||
* ski_area: string,
|
||||
* ski_area_extended: string,
|
||||
* description: string,
|
||||
* news: string,
|
||||
* length: int,
|
||||
* altitude: int,
|
||||
* lifts: int,
|
||||
* images: array<string, mixed>,
|
||||
* region_maps: list<string>,
|
||||
* },
|
||||
* }
|
||||
*/
|
||||
private function fetchHotelDetails(string $hotelCode): array
|
||||
{
|
||||
return $this->cache->get(
|
||||
sprintf('cms_hotel_%s', $hotelCode),
|
||||
function (ItemInterface $item) use ($hotelCode): array {
|
||||
$item->expiresAfter(3600);
|
||||
|
||||
try {
|
||||
$request = $this->httpClient->request('GET', 'api/hotel', [
|
||||
'query' => [
|
||||
'hotel' => $hotelCode,
|
||||
'key' => $this->apiKey,
|
||||
],
|
||||
]);
|
||||
} catch (ExceptionInterface $e) {
|
||||
$item->expiresAfter(0);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
try {
|
||||
$data = $request->toArray();
|
||||
} catch (ExceptionInterface $e) {
|
||||
$item->expiresAfter(0);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data see {@see self::fetchHotelDetails()} for the shape
|
||||
*/
|
||||
private function mapHotelData(array $data): CmsHotelData
|
||||
{
|
||||
return new CmsHotelData(
|
||||
name: $data['name'] ?? null,
|
||||
address: $data['address'] ?? null,
|
||||
images: $data['images'] ?? null,
|
||||
description: $data['description'] ?? null,
|
||||
features: $data['features'] ?? null,
|
||||
roomTypes: $data['room_types'] ?? null,
|
||||
additionalInformation: $data['additional_information'] ?? null,
|
||||
icons: $data['icons'] ?? null,
|
||||
region: isset($data['region']) ? $this->mapRegionData($data['region']) : null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $region see {@see self::fetchHotelDetails()} for the shape
|
||||
*/
|
||||
private function mapRegionData(array $region): CmsRegionData
|
||||
{
|
||||
return new CmsRegionData(
|
||||
name: $region['name'] ?? null,
|
||||
latitude: self::toFloatOrNull($region['latitude'] ?? null),
|
||||
longitude: self::toFloatOrNull($region['longitude'] ?? null),
|
||||
webcam: $region['webcam'] ?? null,
|
||||
skiArea: $region['ski_area'] ?? null,
|
||||
skiAreaExtended: $region['ski_area_extended'] ?? null,
|
||||
description: $region['description'] ?? null,
|
||||
news: $region['news'] ?? null,
|
||||
length: self::toIntOrNull($region['length'] ?? null),
|
||||
altitude: self::toIntOrNull($region['altitude'] ?? null),
|
||||
lifts: self::toIntOrNull($region['lifts'] ?? null),
|
||||
images: $region['images'] ?? null,
|
||||
regionMaps: $region['region_maps'] ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
private static function toIntOrNull(mixed $value): ?int
|
||||
{
|
||||
return is_numeric($value) ? (int) $value : null;
|
||||
}
|
||||
|
||||
private static function toFloatOrNull(mixed $value): ?float
|
||||
{
|
||||
return is_numeric($value) ? (float) $value : null;
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public function getProductDetails(string $productCode, ?string $hotelCode = null): array
|
||||
{
|
||||
try {
|
||||
$request = $this->httpClient->request('GET', 'api/product', [
|
||||
'query' => [
|
||||
'product' => $productCode,
|
||||
'hotel' => $hotelCode,
|
||||
'key' => $this->apiKey,
|
||||
],
|
||||
]);
|
||||
} catch (ExceptionInterface $e) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
return $this->cache->get(
|
||||
sprintf('cms_product_%s_%s', $productCode, $hotelCode ?? ''),
|
||||
function (ItemInterface $item) use ($productCode, $hotelCode): array {
|
||||
$item->expiresAfter(3600);
|
||||
|
||||
try {
|
||||
$data = $request->toArray();
|
||||
} catch (ExceptionInterface $e) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
try {
|
||||
$request = $this->httpClient->request('GET', 'api/product', [
|
||||
'query' => [
|
||||
'product' => $productCode,
|
||||
'hotel' => $hotelCode,
|
||||
'key' => $this->apiKey,
|
||||
],
|
||||
]);
|
||||
} catch (ExceptionInterface $e) {
|
||||
$item->expiresAfter(0);
|
||||
|
||||
return $data;
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
try {
|
||||
$data = $request->toArray();
|
||||
} catch (ExceptionInterface $e) {
|
||||
$item->expiresAfter(0);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user