feat: turn search_trips into the website's travel search

This commit is contained in:
fromme committed 2026-10-08 13:14:12 +02:00
1 parent bfdedefae3
commit 4ab2714bde
12 files changed
+693 -151

No files matched your search

+41
View File
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\Enum;
/**
* The accommodation type of a TYPO3 hotel record (`type` in the content feed), as the
* website's travel search filters it ("Unterkunft"). Values and labels follow the website's
* Hotel::$typeLabels.
*/
enum HotelType: int
{
case HolidayFlat = 1;
case SportsClub = 2;
case Apartment = 3;
case GuestHouse = 4;
case Pension = 5;
public function label(): string
{
return match ($this) {
self::HolidayFlat => 'Ferienwohnung',
self::SportsClub => 'Sportclub',
self::Apartment => 'Apartment',
self::GuestHouse => 'Gästehaus',
self::Pension => 'Pension',
};
}
public static function fromLabel(string $label): ?self
{
foreach (self::cases() as $case) {
if (0 === strcasecmp($case->label(), trim($label))) {
return $case;
}
}
return null;
}
}
+59
View File
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace App\Enum;
/**
* Room type as the website's travel search filters it ("Zimmerarten").
*
* Taken from the room's capacity, as TYPO3's RoomTypeResolver does since the room-code
* mapping was retired: `maxPax` 1-8 maps directly, 9 and up is "9er+". A bed shared with
* other customers is sold per bed (`maxPax` 1), so it is recognised by its label instead;
* without that, a bed in a dorm would count as an Einzelzimmer.
*/
enum RoomType: string
{
case ForOne = 'EZ';
case ForTwo = 'DZ';
case ForThree = '3er';
case ForFour = '4er';
case ForFive = '5er';
case ForSix = '6er';
case ForSeven = '7er';
case ForEight = '8er';
case ForNinePlus = '9er+';
case WithOthers = 'mit anderen';
/** The "Babypreis 0-2 Jährige" row: priced like a room, but not one. */
public const BABY_CODE = 'Baby';
/** Label phrases (lower case) that mark a bed shared with other customers. */
private const WITH_OTHERS_MARKERS = ['bett im', 'mit ander'];
/**
* Null for the baby row, which is not a room.
*/
public static function classify(?string $code, ?string $label, ?int $maxPax, ?int $minPax): ?self
{
if (self::BABY_CODE === trim((string) $code)) {
return null;
}
$label = mb_strtolower((string) $label);
foreach (self::WITH_OTHERS_MARKERS as $marker) {
if (str_contains($label, $marker)) {
return self::WithOthers;
}
}
$pax = ($maxPax ?? 0) > 0 ? (int) $maxPax : (int) $minPax;
return match (true) {
$pax >= 9 => self::ForNinePlus,
$pax >= 1 => [1 => self::ForOne, self::ForTwo, self::ForThree, self::ForFour, self::ForFive, self::ForSix, self::ForSeven, self::ForEight][$pax],
// No usable occupancy: TYPO3 files it under "mit anderen" as well.
default => self::WithOthers,
};
}
}