feat: adopt new bpn-connect api modes for calendar and ical feed

This commit is contained in:
Björn Fromme
2026-06-12 17:13:36 +02:00
parent c559b0dc8c
commit a8e915ae38
3 changed files with 46 additions and 36 deletions
@@ -13,14 +13,27 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
class ApiClient class ApiClient
{ {
public function getCalendar($hotelCode, \DateTimeInterface $dateFrom, \DateTimeInterface $dateTo): array public const CALENDAR_MODE_DAYS = 'days';
{ public const CALENDAR_MODE_RANGES = 'ranges';
$response = $this->request('GET', 'api/v1/contingents/calendar', [
'query' => [ public function getCalendar(
$hotelCode,
\DateTimeInterface $dateFrom,
\DateTimeInterface $dateTo = null,
string $mode = self::CALENDAR_MODE_DAYS
): array {
$query = [
'hotelCode' => $hotelCode, 'hotelCode' => $hotelCode,
'dateFrom' => $dateFrom->format('Y-m-d'), 'dateFrom' => $dateFrom->format('Y-m-d'),
'dateTo' => $dateTo->format('Y-m-d'), 'mode' => $mode,
], ];
if (null !== $dateTo) {
$query['dateTo'] = $dateTo->format('Y-m-d');
}
$response = $this->request('GET', 'api/v1/contingents/calendar', [
'query' => $query,
]); ]);
$this->assertStatusCode($response, [Response::HTTP_OK], 'GET', 'api/v1/contingents/calendar'); $this->assertStatusCode($response, [Response::HTTP_OK], 'GET', 'api/v1/contingents/calendar');
@@ -80,7 +80,12 @@ class AjaxCalendarController extends ActionController
$calendar['error'] = true; $calendar['error'] = true;
} else { } else {
try { try {
$cacheIdentifier = $this->getCacheIdentifier($hotelCode, $apiDateFrom, $apiDateTo); $cacheIdentifier = $this->getCacheIdentifier(
$hotelCode,
$apiDateFrom,
$apiDateTo,
ApiClient::CALENDAR_MODE_DAYS
);
$cachedCalendar = $this->cache->get($cacheIdentifier); $cachedCalendar = $this->cache->get($cacheIdentifier);
if (false !== $cachedCalendar) { if (false !== $cachedCalendar) {
@@ -89,7 +94,8 @@ class AjaxCalendarController extends ActionController
$calendar = $this->apiClient->getCalendar( $calendar = $this->apiClient->getCalendar(
$hotelCode, $hotelCode,
new \DateTimeImmutable($apiDateFrom), new \DateTimeImmutable($apiDateFrom),
new \DateTimeImmutable($apiDateTo) new \DateTimeImmutable($apiDateTo),
ApiClient::CALENDAR_MODE_DAYS
); );
$this->cache->set($cacheIdentifier, $calendar, [], self::CACHE_TTL); $this->cache->set($cacheIdentifier, $calendar, [], self::CACHE_TTL);
} }
@@ -158,12 +164,13 @@ class AjaxCalendarController extends ActionController
]; ];
} }
private function getCacheIdentifier(string $hotelCode, string $dateFrom, string $dateTo): string private function getCacheIdentifier(string $hotelCode, string $dateFrom, string $dateTo, string $mode): string
{ {
return 'bpn_connect_calendar_' . sha1(implode('|', [ return 'bpn_connect_calendar_' . sha1(implode('|', [
$hotelCode, $hotelCode,
$dateFrom, $dateFrom,
$dateTo, $dateTo,
$mode,
])); ]));
} }
@@ -34,7 +34,6 @@ use TYPO3\CMS\Core\SingletonInterface;
class IcalService implements SingletonInterface class IcalService implements SingletonInterface
{ {
private const FEED_HORIZON = 'P1Y';
private const SUMMARY_UNAVAILABLE = 'Unavailable'; private const SUMMARY_UNAVAILABLE = 'Unavailable';
/** /**
@@ -66,10 +65,14 @@ class IcalService implements SingletonInterface
if ($hotelCode !== '') { if ($hotelCode !== '') {
$dateFrom = new \DateTimeImmutable('today'); $dateFrom = new \DateTimeImmutable('today');
$dateTo = $dateFrom->add(new \DateInterval(self::FEED_HORIZON))->sub(new \DateInterval('P1D'));
try { try {
$calendar = $this->apiClient->getCalendar($hotelCode, $dateFrom, $dateTo); $calendar = $this->apiClient->getCalendar(
$hotelCode,
$dateFrom,
null,
ApiClient::CALENDAR_MODE_RANGES
);
$calendarRows = isset($calendar['data']) && is_array($calendar['data']) ? $calendar['data'] : []; $calendarRows = isset($calendar['data']) && is_array($calendar['data']) ? $calendar['data'] : [];
} catch (\Throwable $e) { } catch (\Throwable $e) {
$calendarRows = []; $calendarRows = [];
@@ -92,41 +95,28 @@ class IcalService implements SingletonInterface
protected function generateUnavailableItems(array $calendarRows): void protected function generateUnavailableItems(array $calendarRows): void
{ {
usort($calendarRows, function (array $left, array $right): int { usort($calendarRows, function (array $left, array $right): int {
return strcmp((string) ($left['date'] ?? ''), (string) ($right['date'] ?? '')); return strcmp((string) ($left['date_from'] ?? ''), (string) ($right['date_from'] ?? ''));
}); });
$blockStart = null;
$lastDate = null;
foreach ($calendarRows as $row) { foreach ($calendarRows as $row) {
if (!isset($row['date'])) { if (!isset($row['date_from'], $row['date_to'])) {
continue; continue;
} }
$date = new \DateTimeImmutable($row['date']); if (!$this->isUnavailableStatus($row['status'] ?? 'OK')) {
$lastDate = $date;
if ($this->isUnavailableStatus($row['status'] ?? 'OK')) {
if (null === $blockStart) {
$blockStart = $date;
}
continue; continue;
} }
if (null !== $blockStart) { $dateFrom = new \DateTimeImmutable($row['date_from']);
$this->addBlockedItem([ $dateTo = new \DateTimeImmutable($row['date_to']);
'from' => $blockStart,
'to' => $date, if ($dateTo < $dateFrom) {
]); continue;
$blockStart = null;
}
} }
if (null !== $blockStart && null !== $lastDate) {
$this->addBlockedItem([ $this->addBlockedItem([
'from' => $blockStart, 'from' => $dateFrom,
'to' => $lastDate->add(new \DateInterval('P1D')), 'to' => $dateTo->add(new \DateInterval('P1D')),
]); ]);
} }
} }