feat: configurable myep domain per site to replace theme parameter

This commit is contained in:
Björn Fromme
2026-01-27 17:35:13 +01:00
parent 8d1408d77c
commit d4b44d3138
11 changed files with 100 additions and 92 deletions
@@ -38,6 +38,7 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Serializer;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Extbase\Object\ObjectManager;
@@ -114,7 +115,8 @@ class ExportCommandController extends Command
*/ */
protected function exportXml(Reseller $reseller, $destinationFolder) protected function exportXml(Reseller $reseller, $destinationFolder)
{ {
$data = $this->resellerDataService->preprocessAll($reseller); $myEpUrl = $this->getMyEpUrl();
$data = $this->resellerDataService->preprocessAll($reseller, $myEpUrl);
$encoders = [new XmlEncoder('products')]; $encoders = [new XmlEncoder('products')];
$normalizers = [new ObjectNormalizer()]; $normalizers = [new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders); $serializer = new Serializer($normalizers, $encoders);
@@ -140,8 +142,10 @@ class ExportCommandController extends Command
*/ */
protected function exportCsv(Reseller $reseller, $type, $destinationFolder) protected function exportCsv(Reseller $reseller, $type, $destinationFolder)
{ {
$myEpUrl = $this->getMyEpUrl();
$data = $this->resellerDataService->preprocessAll( $data = $this->resellerDataService->preprocessAll(
$reseller, $reseller,
$myEpUrl,
static::$imageDimensions[$type], static::$imageDimensions[$type],
$type $type
); );
@@ -163,4 +167,12 @@ class ExportCommandController extends Command
} }
fclose($fileHandle); fclose($fileHandle);
} }
protected function getMyEpUrl(): string
{
$config = GeneralUtility::makeInstance(ExtensionConfiguration::class)
->get('ep_products');
return $config['myEpUrl'] ?? 'https://my.ep-reisen.de';
}
} }
@@ -80,8 +80,14 @@ class AjaxContingentController extends ActionController
*/ */
public function roomsAction(Hotel $hotel, Product $product, \DateTime $dateFrom, \DateTime $dateTo) public function roomsAction(Hotel $hotel, Product $product, \DateTime $dateFrom, \DateTime $dateTo)
{ {
$template = $this->settings['bpnBookingUrlTemplateCode']; $myEpUrl = $this->settings['myEpUrl'];
$rooms = $this->contingentDataService->getAvailableRooms($dateFrom, $dateTo, $hotel, $product, $template); $rooms = $this->contingentDataService->getAvailableRooms(
$dateFrom->format('Y-m-d'),
$dateTo->format('Y-m-d'),
$hotel,
$product,
$myEpUrl
);
return \json_encode($rooms); return \json_encode($rooms);
} }
@@ -127,16 +127,10 @@ class AjaxDateController extends ActionController
$altLabel = $product->getAltLabel(); $altLabel = $product->getAltLabel();
} }
} }
// Disabled, not working anyways, reseller subdomains are not registered since TYPO3 10.*
// if ($reseller = $this->resellerDataService->getResellerForCurrentDomain()) {
// $paCode = $reseller['paCode'];
// }
$datesTable = $this->dateService->getDatesTable([ $datesTable = $this->dateService->getDatesTable([
'product' => $product, 'product' => $product,
'hotel' => $hotel, 'hotel' => $hotel,
'filterSettings' => $filterSettings, 'filterSettings' => $filterSettings,
'template' => $this->settings['bpnBookingUrlTemplateCode'],
'paCode' => $paCode,
]); ]);
$hasSurchargeOrDiscount = $this->dateService->checkSurcharcheOrDiscount($datesTable); $hasSurchargeOrDiscount = $this->dateService->checkSurcharcheOrDiscount($datesTable);
@@ -117,23 +117,23 @@ class AjaxTableController extends ActionController
/** /**
* @param Product $product * @param Product $product
* @param Hotel $hotel * @param Hotel $hotel
* @param string $paCode * @param string|null $dateFrom
* @param string $dateFrom * @param string|null $dateTo
* @param string $dateTo * @param string|null $myEpUrl
*/ */
public function datestableAction public function datestableAction(
(
Product $product, Product $product,
Hotel $hotel, Hotel $hotel,
string $dateFrom = null, string $dateFrom = null,
string $dateTo = null, string $dateTo = null,
string $bpnBookingUrlTemplateCode = null string $myEpUrl = null
): void { ): void {
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
$filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids);
$filterSettings['dateFrom'] = $dateFrom; $filterSettings['dateFrom'] = $dateFrom;
$filterSettings['dateTo'] = $dateTo; $filterSettings['dateTo'] = $dateTo;
$paCode = GeneralUtility::_GET('pa'); $paCode = GeneralUtility::_GET('pa');
$myEpUrl = $myEpUrl ?? $this->settings['myEpUrl'];
$dates = $this->dateService->getDatesTable([ $dates = $this->dateService->getDatesTable([
'product' => $product, 'product' => $product,
@@ -141,10 +141,6 @@ class AjaxTableController extends ActionController
'filterSettings' => $filterSettings, 'filterSettings' => $filterSettings,
]); ]);
// if ($reseller = $this->resellerDataService->getResellerForCurrentDomain()) {
// $paCode = $reseller['paCode'];
// }
if (1 === count($dates)) { if (1 === count($dates)) {
$date = reset($dates); $date = reset($dates);
$this->forward( $this->forward(
@@ -157,7 +153,7 @@ class AjaxTableController extends ActionController
'date' => $date['dateUid'], 'date' => $date['dateUid'],
'paCode' => $paCode, 'paCode' => $paCode,
'singleDate' => true, 'singleDate' => true,
'bpnBookingUrlTemplateCode' => $bpnBookingUrlTemplateCode ?? $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
] ]
); );
} }
@@ -166,7 +162,7 @@ class AjaxTableController extends ActionController
$allDates = $this->dateService->preprocessDatesTable([ $allDates = $this->dateService->preprocessDatesTable([
'dateTableData' => $dates, 'dateTableData' => $dates,
'template' => $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
'paCode' => $paCode, 'paCode' => $paCode,
'showBookingButton' => false === $product->getHideBookingButton(), 'showBookingButton' => false === $product->getHideBookingButton(),
'nonBookableDateUids' => $nonBookableDateUids, 'nonBookableDateUids' => $nonBookableDateUids,
@@ -205,7 +201,7 @@ class AjaxTableController extends ActionController
'allDates' => $allDates, 'allDates' => $allDates,
'bookableDates' => $bookableDates, 'bookableDates' => $bookableDates,
'bookable' => $product->getBookable(), 'bookable' => $product->getBookable(),
'unavailable' => count($allDates) === 0, 'unavailable' => 0 === count($allDates),
'product' => $product, 'product' => $product,
'hotel' => $hotel, 'hotel' => $hotel,
'altProductLink' => $altProductLink, 'altProductLink' => $altProductLink,
@@ -215,7 +211,7 @@ class AjaxTableController extends ActionController
'hasDiscount' => $hasSurchargeOrDiscount['discount'], 'hasDiscount' => $hasSurchargeOrDiscount['discount'],
'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept, 'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept,
'nonBookableInfo' => $nonBookableInfo, 'nonBookableInfo' => $nonBookableInfo,
'bpnBookingUrlTemplateCode' => $bpnBookingUrlTemplateCode, 'myEpUrl' => $myEpUrl,
]); ]);
} }
@@ -223,26 +219,26 @@ class AjaxTableController extends ActionController
* @param Product $product * @param Product $product
* @param Hotel $hotel * @param Hotel $hotel
* @param Date $date * @param Date $date
* @param string $paCode
* @param bool $singleDate * @param bool $singleDate
* @param string|null $myEpUrl
*/ */
public function pricetableAction public function pricetableAction(
(
Product $product, Product $product,
Hotel $hotel, Hotel $hotel,
Date $date, Date $date,
bool $singleDate = false, bool $singleDate = false,
string $bpnBookingUrlTemplateCode = null string $myEpUrl = null
): void { ): void {
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
$filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids);
$myEpUrl = $myEpUrl ?? $this->settings['myEpUrl'];
$priceTable = $this->dateService->getPriceTable([ $priceTable = $this->dateService->getPriceTable([
'product' => $product, 'product' => $product,
'hotel' => $hotel, 'hotel' => $hotel,
'filterSettings' => $filterSettings, 'filterSettings' => $filterSettings,
'date' => $date, 'date' => $date,
'template' => $bpnBookingUrlTemplateCode ?? $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
'paCode' => GeneralUtility::_GET('pa'), 'paCode' => GeneralUtility::_GET('pa'),
]); ]);
$hasSurchargeOrDiscount = $this->dateService->checkSurcharcheOrDiscount($priceTable); $hasSurchargeOrDiscount = $this->dateService->checkSurcharcheOrDiscount($priceTable);
@@ -263,31 +259,32 @@ class AjaxTableController extends ActionController
'hotel' => $hotel, 'hotel' => $hotel,
'servicesIncluded' => $date->getServicesIncluded(), 'servicesIncluded' => $date->getServicesIncluded(),
'prices' => $priceTable, 'prices' => $priceTable,
'unavailable' => count($priceTable) === 0, 'unavailable' => 0 === count($priceTable),
'hasIncludedServices' => $hasIncludedServices, 'hasIncludedServices' => $hasIncludedServices,
'hasSurcharge' => $hasSurchargeOrDiscount['surcharge'], 'hasSurcharge' => $hasSurchargeOrDiscount['surcharge'],
'hasDiscount' => $hasSurchargeOrDiscount['discount'], 'hasDiscount' => $hasSurchargeOrDiscount['discount'],
'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept, 'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept,
'isSingleDate' => $singleDate, 'isSingleDate' => $singleDate,
'nonBookableInfo' => $nonBookableInfo, 'nonBookableInfo' => $nonBookableInfo,
'bpnBookingUrlTemplateCode' => $bpnBookingUrlTemplateCode ?? $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
]); ]);
} }
/** /**
* @param Product $product * @param Product $product
* @param Hotel $hotel * @param Hotel $hotel
* @param string $bpnBookingUrlTemplateCode * @param string|null $myEpUrl
*/ */
public function pricetableHtmlAction(Product $product, Hotel $hotel, string $bpnBookingUrlTemplateCode = null): void public function pricetableHtmlAction(Product $product, Hotel $hotel, string $myEpUrl = null): void
{ {
$nonBookableInfo = $this->getNonBookableInfobox($product); $nonBookableInfo = $this->getNonBookableInfobox($product);
$myEpUrl = $myEpUrl ?? $this->settings['myEpUrl'];
$priceTable = $this->dateService->getPriceTable([ $priceTable = $this->dateService->getPriceTable([
'product' => $product, 'product' => $product,
'hotel' => $hotel, 'hotel' => $hotel,
'filterSettings' => $this->filterService->getNormalizedFilterSettings(), 'filterSettings' => $this->filterService->getNormalizedFilterSettings(),
'template' => $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
'paCode' => GeneralUtility::_GET('pa'), 'paCode' => GeneralUtility::_GET('pa'),
'sortByRoom' => true, 'sortByRoom' => true,
]); ]);
@@ -297,15 +294,15 @@ class AjaxTableController extends ActionController
'pricetable' => $priceTable, 'pricetable' => $priceTable,
'hasIncludedServices' => $hasIncludedServices, 'hasIncludedServices' => $hasIncludedServices,
'nonBookableInfo' => $nonBookableInfo, 'nonBookableInfo' => $nonBookableInfo,
'bpnBookingUrlTemplateCode' => $bpnBookingUrlTemplateCode ?? $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
]); ]);
} }
/** /**
* @param Product $product * @param Product $product
* @param string $bpnBookingUrlTemplateCode * @param string|null $myEpUrl
*/ */
public function eventPricetableAction(Product $product, string $bpnBookingUrlTemplateCode = null): void public function eventPricetableAction(Product $product, string $myEpUrl = null): void
{ {
$roomTypes = GeneralUtility::trimExplode(',', $this->settings['priceTableRoomTypes']); $roomTypes = GeneralUtility::trimExplode(',', $this->settings['priceTableRoomTypes']);
$roomTypesPax = array_map(function ($type) { $roomTypesPax = array_map(function ($type) {
@@ -313,14 +310,14 @@ class AjaxTableController extends ActionController
}, $roomTypes); }, $roomTypes);
$roomTypesLabels = array_map(function ($type) { $roomTypesLabels = array_map(function ($type) {
$label = (int) $type . 'er'; $label = (int) $type . 'er';
if (strpos($type, '+') !== false) { if (false !== strpos($type, '+')) {
$label .= '+'; $label .= '+';
} }
return $label; return $label;
}, $roomTypes); }, $roomTypes);
$maxPax = max($roomTypesPax); $maxPax = max($roomTypesPax);
$template = $this->settings['bpnBookingUrlTemplateCode']; $myEpUrl = $myEpUrl ?? $this->settings['myEpUrl'];
$priceTable = $this->dateService->getEventPriceTable($product, $maxPax, $template); $priceTable = $this->dateService->getEventPriceTable($product, $maxPax, $myEpUrl);
$hasIncludedServices = $this->dateService->hasIncludedServices($priceTable); $hasIncludedServices = $this->dateService->hasIncludedServices($priceTable);
$nonBookableInfo = $this->getNonBookableInfobox($product); $nonBookableInfo = $this->getNonBookableInfobox($product);
$categories = [ $categories = [
@@ -337,7 +334,7 @@ class AjaxTableController extends ActionController
'categories' => $categories, 'categories' => $categories,
'themekey' => $this->settings['themekey'], 'themekey' => $this->settings['themekey'],
'nonBookableInfo' => $nonBookableInfo, 'nonBookableInfo' => $nonBookableInfo,
'bpnBookingUrlTemplateCode' => $bpnBookingUrlTemplateCode ?? $this->settings['bpnBookingUrlTemplateCode'], 'myEpUrl' => $myEpUrl,
]); ]);
} }
@@ -346,30 +343,30 @@ class AjaxTableController extends ActionController
* @param Product $product * @param Product $product
* @param string $dateFrom * @param string $dateFrom
* @param string $dateTo * @param string $dateTo
* @param string $bpnBookingUrlTemplateCode * @param string|null $myEpUrl
*/ */
public function daytripRoomsAction( public function daytripRoomsAction(
Hotel $hotel, Hotel $hotel,
Product $product, Product $product,
string $dateFrom, string $dateFrom,
string $dateTo, string $dateTo,
string $bpnBookingUrlTemplateCode = null string $myEpUrl = null
): void { ): void {
$period = new Period($dateFrom, $dateTo); $period = new Period($dateFrom, $dateTo);
$nights = (int)$period->dateInterval()->format('%a') + 1; $nights = (int) $period->dateInterval()->format('%a') + 1;
$myEpUrl = $myEpUrl ?? $this->settings['myEpUrl'];
if (2 > $nights) { if (2 > $nights) {
$rooms = []; $rooms = [];
} else { } else {
$template = $this->settings['bpnBookingUrlTemplateCode'];
$rooms = $this $rooms = $this
->contingentDataService ->contingentDataService
->getAvailableRooms($dateFrom, $dateTo, $hotel, $product, $template); ->getAvailableRooms($dateFrom, $dateTo, $hotel, $product, $myEpUrl);
} }
$this->view->assign('nights', $nights); $this->view->assign('nights', $nights);
$this->view->assign('rooms', $rooms); $this->view->assign('rooms', $rooms);
$this->view->assign('bpnBookingUrlTemplateCode', $bpnBookingUrlTemplateCode ?? $this->settings['bpnBookingUrlTemplateCode']); $this->view->assign('myEpUrl', $myEpUrl);
} }
/** /**
@@ -80,7 +80,8 @@ class ResellerController extends ActionController
); );
} }
$productData = $this->resellerDataService->preprocessSingle($product, $reseller); $myEpUrl = $this->settings['myEpUrl'] ?? 'https://my.ep-reisen.de';
$productData = $this->resellerDataService->preprocessSingle($product, $reseller, $myEpUrl);
$this->view->assign('reseller', $reseller); $this->view->assign('reseller', $reseller);
$this->view->assign('productData', $productData); $this->view->assign('productData', $productData);
@@ -71,11 +71,11 @@ class ContingentDataService
} }
/** /**
* @param \DateTime $dateFrom * @param string $dateFrom
* @param \DateTime $dateTo * @param string $dateTo
* @param Hotel $hotel * @param Hotel $hotel
* @param Product $product * @param Product $product
* @param string $template * @param string $myEpUrl
* @return array * @return array
* @throws \Doctrine\DBAL\DBALException * @throws \Doctrine\DBAL\DBALException
*/ */
@@ -84,7 +84,7 @@ class ContingentDataService
string $dateTo, string $dateTo,
Hotel $hotel, Hotel $hotel,
Product $product, Product $product,
string $template = 'base' string $myEpUrl
) { ) {
$data = $this->contingentRepository->getAvailableRooms($dateFrom, $dateTo, $hotel, $product); $data = $this->contingentRepository->getAvailableRooms($dateFrom, $dateTo, $hotel, $product);
$period = new Period($dateFrom, $dateTo); $period = new Period($dateFrom, $dateTo);
@@ -95,7 +95,7 @@ class ContingentDataService
$row['bookingUrl'] = BookingUrlUtility::generateUrl([ $row['bookingUrl'] = BookingUrlUtility::generateUrl([
'dateId' => $row['busProId'], 'dateId' => $row['busProId'],
'hotelId' => $row['hotelBusProId'], 'hotelId' => $row['hotelBusProId'],
'theme' => $template, 'myEpUrl' => $myEpUrl,
]); ]);
$row['summer'] = $row['season'] === 's'; $row['summer'] = $row['season'] === 's';
@@ -119,7 +119,7 @@ class DateService implements SingletonInterface
$hotel = $resolvedOptions['hotel']; $hotel = $resolvedOptions['hotel'];
$filterSettings = $resolvedOptions['filterSettings']; $filterSettings = $resolvedOptions['filterSettings'];
$date = $resolvedOptions['date']; $date = $resolvedOptions['date'];
$template = $resolvedOptions['template']; $myEpUrl = $resolvedOptions['myEpUrl'];
$paCode = $resolvedOptions['paCode']; $paCode = $resolvedOptions['paCode'];
if ($filterSettings === null) { if ($filterSettings === null) {
@@ -130,7 +130,7 @@ class DateService implements SingletonInterface
return $this->preprocessPriceTable([ return $this->preprocessPriceTable([
'priceTableData' => $this->productRepository->getPricetable($product, $hotel, $filterSettings, $date), 'priceTableData' => $this->productRepository->getPricetable($product, $hotel, $filterSettings, $date),
'template' => $template, 'myEpUrl' => $myEpUrl,
'paCode' => $paCode, 'paCode' => $paCode,
'showBookingButton' => false === $product->getHideBookingButton(), 'showBookingButton' => false === $product->getHideBookingButton(),
'nonBookableDateUids' => $nonBookableDateUids, 'nonBookableDateUids' => $nonBookableDateUids,
@@ -139,10 +139,9 @@ class DateService implements SingletonInterface
protected function configurePriceTableOptions(OptionsResolver $resolver) protected function configurePriceTableOptions(OptionsResolver $resolver)
{ {
$resolver->setRequired(['product', 'hotel']); $resolver->setRequired(['product', 'hotel', 'myEpUrl']);
$resolver->setDefined(['filterSettings', 'date', 'paCode']); $resolver->setDefined(['filterSettings', 'date', 'paCode']);
$resolver->setDefaults([ $resolver->setDefaults([
'template' => 'base',
'date' => null, 'date' => null,
'sortByRoom' => true, 'sortByRoom' => true,
]); ]);
@@ -181,12 +180,12 @@ class DateService implements SingletonInterface
$resolver->setAllowedTypes('hotel', Hotel::class); $resolver->setAllowedTypes('hotel', Hotel::class);
} }
public function getEventPriceTable(Product $product, int $maxPax = 99, string $template = 'base'): array public function getEventPriceTable(Product $product, int $maxPax, string $myEpUrl): array
{ {
return $this->preprocessEventPriceTable([ return $this->preprocessEventPriceTable([
'priceTableData' => $this->productRepository->getEventPriceTable($product), 'priceTableData' => $this->productRepository->getEventPriceTable($product),
'maxPax' => $maxPax, 'maxPax' => $maxPax,
'template' => $template, 'myEpUrl' => $myEpUrl,
]); ]);
} }
@@ -194,7 +193,7 @@ class DateService implements SingletonInterface
{ {
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
$resolver->setDefined(['paCode', 'showBookingButton', 'nonBookableDateUids']); $resolver->setDefined(['paCode', 'showBookingButton', 'nonBookableDateUids']);
$resolver->setRequired(['priceTableData', 'template']); $resolver->setRequired(['priceTableData', 'myEpUrl']);
$resolver->setDefault('showBookingButton', true); $resolver->setDefault('showBookingButton', true);
$resolvedOptions = $resolver->resolve($options); $resolvedOptions = $resolver->resolve($options);
@@ -204,7 +203,7 @@ class DateService implements SingletonInterface
]; ];
$priceTableData = $resolvedOptions['priceTableData']; $priceTableData = $resolvedOptions['priceTableData'];
$template = $resolvedOptions['template']; $myEpUrl = $resolvedOptions['myEpUrl'];
$paCode = $resolvedOptions['paCode']; $paCode = $resolvedOptions['paCode'];
$nonBookableDateUids = $resolvedOptions['nonBookableDateUids']; $nonBookableDateUids = $resolvedOptions['nonBookableDateUids'];
@@ -216,7 +215,7 @@ class DateService implements SingletonInterface
$bookingUrl = BookingUrlUtility::generateUrl([ $bookingUrl = BookingUrlUtility::generateUrl([
'dateId' => $row['dateBusProId'], 'dateId' => $row['dateBusProId'],
'hotelId' => $row['hotelBusProId'], 'hotelId' => $row['hotelBusProId'],
'theme' => $template, 'myEpUrl' => $myEpUrl,
'paCode' => $paCode, 'paCode' => $paCode,
'returnPageUid' => $row['productDetailPage'] ?? null, 'returnPageUid' => $row['productDetailPage'] ?? null,
]); ]);
@@ -281,7 +280,7 @@ class DateService implements SingletonInterface
{ {
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
$resolver->setDefined(['paCode', 'showBookingButton', 'nonBookableDateUids']); $resolver->setDefined(['paCode', 'showBookingButton', 'nonBookableDateUids']);
$resolver->setRequired(['dateTableData', 'template']); $resolver->setRequired(['dateTableData', 'myEpUrl']);
$resolver->setDefault('showBookingButton', true); $resolver->setDefault('showBookingButton', true);
$resolver->setDefault('nonBookableDateUids', []); $resolver->setDefault('nonBookableDateUids', []);
$resolvedOptions = $resolver->resolve($options); $resolvedOptions = $resolver->resolve($options);
@@ -289,7 +288,7 @@ class DateService implements SingletonInterface
$dateTable = []; $dateTable = [];
$dateTableData = $resolvedOptions['dateTableData']; $dateTableData = $resolvedOptions['dateTableData'];
$template = $resolvedOptions['template']; $myEpUrl = $resolvedOptions['myEpUrl'];
$paCode = $resolvedOptions['paCode']; $paCode = $resolvedOptions['paCode'];
$nonBookableDateUids = $resolvedOptions['nonBookableDateUids']; $nonBookableDateUids = $resolvedOptions['nonBookableDateUids'];
@@ -305,8 +304,8 @@ class DateService implements SingletonInterface
$dateEnd = new \DateTime($row['dateEnd']); $dateEnd = new \DateTime($row['dateEnd']);
$bookingUrl = BookingUrlUtility::generateUrl([ $bookingUrl = BookingUrlUtility::generateUrl([
'dateId' => $row['dateBusProId'], 'dateId' => $row['dateBusProId'],
'hotelId' =>$row['hotelBusProId'], 'hotelId' => $row['hotelBusProId'],
'theme' => $template, 'myEpUrl' => $myEpUrl,
'paCode' => $paCode, 'paCode' => $paCode,
'returnPageUid' => $row['productDetailPage'] ?? null, 'returnPageUid' => $row['productDetailPage'] ?? null,
]); ]);
@@ -339,16 +338,15 @@ class DateService implements SingletonInterface
{ {
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
$resolver->setDefined('paCode'); $resolver->setDefined('paCode');
$resolver->setRequired(['priceTableData']); $resolver->setRequired(['priceTableData', 'myEpUrl']);
$resolver->setDefaults([ $resolver->setDefaults([
'maxPax' => 99, 'maxPax' => 99,
'template' => 'base',
]); ]);
$resolvedOptions = $resolver->resolve($options); $resolvedOptions = $resolver->resolve($options);
$priceTableData = $resolvedOptions['priceTableData']; $priceTableData = $resolvedOptions['priceTableData'];
$maxPax = $resolvedOptions['maxPax']; $maxPax = $resolvedOptions['maxPax'];
$template = $resolvedOptions['template']; $myEpUrl = $resolvedOptions['myEpUrl'];
$paCode = $resolvedOptions['paCode']; $paCode = $resolvedOptions['paCode'];
$priceTable = [ $priceTable = [
@@ -381,7 +379,7 @@ class DateService implements SingletonInterface
'bookingUrl' => BookingUrlUtility::generateUrl([ 'bookingUrl' => BookingUrlUtility::generateUrl([
'dateId' => $row['dateBusProId'], 'dateId' => $row['dateBusProId'],
'hotelId' => $row['hotelBusProId'], 'hotelId' => $row['hotelBusProId'],
'theme' => $template, 'myEpUrl' => $myEpUrl,
'paCode' => $paCode, 'paCode' => $paCode,
'returnPageUid' => $row['productDetailPage'] ?? null, 'returnPageUid' => $row['productDetailPage'] ?? null,
]), ]),
@@ -59,22 +59,23 @@ class ResellerDataService implements SingletonInterface
/** /**
* @param Reseller $reseller * @param Reseller $reseller
* @param array $imageProcessingInstructions * @param string $myEpUrl
* @param array|null $imageProcessingInstructions
* @param string $type * @param string $type
* @return array * @return array
* @throws \Doctrine\DBAL\DBALException * @throws \Doctrine\DBAL\DBALException
*/ */
public function preprocessAll(Reseller $reseller, array $imageProcessingInstructions = null, $type = 'facebook') public function preprocessAll(Reseller $reseller, string $myEpUrl, array $imageProcessingInstructions = null, $type = 'facebook')
{ {
$data = []; $data = [];
$products = $reseller->getProducts(); $products = $reseller->getProducts();
foreach ($products as $product) foreach ($products as $product) {
{
/** @var Product $product */ /** @var Product $product */
$data['product'][] = $this->preprocessSingle( $data['product'][] = $this->preprocessSingle(
$product, $product,
$reseller, $reseller,
$myEpUrl,
$imageProcessingInstructions, $imageProcessingInstructions,
$type $type
); );
@@ -86,7 +87,8 @@ class ResellerDataService implements SingletonInterface
/** /**
* @param Product $product * @param Product $product
* @param Reseller $reseller * @param Reseller $reseller
* @param array $imageProcessingInstructions * @param string $myEpUrl
* @param array|null $imageProcessingInstructions
* @param string $type * @param string $type
* @return array * @return array
* @throws \Doctrine\DBAL\DBALException * @throws \Doctrine\DBAL\DBALException
@@ -94,10 +96,11 @@ class ResellerDataService implements SingletonInterface
public function preprocessSingle( public function preprocessSingle(
Product $product, Product $product,
Reseller $reseller, Reseller $reseller,
string $myEpUrl,
array $imageProcessingInstructions = null, array $imageProcessingInstructions = null,
$type = 'facebook' $type = 'facebook'
) { ) {
$queryData = $type !== 'google' ? [] : [ $queryData = 'google' !== $type ? [] : [
'utm_source' => 'google', 'utm_source' => 'google',
'utm_medium' => 'cpc', 'utm_medium' => 'cpc',
'utm_campaign' => 'dynamisches-remarketing', 'utm_campaign' => 'dynamisches-remarketing',
@@ -113,8 +116,7 @@ class ResellerDataService implements SingletonInterface
$hotels = $product->getHotels(); $hotels = $product->getHotels();
$paCode = $reseller->getPaCode(); $paCode = $reseller->getPaCode();
foreach ($hotels as $hotel) foreach ($hotels as $hotel) {
{
/** @var Hotel $hotel */ /** @var Hotel $hotel */
$hotelData = SerializedHotel::fromEntity($hotel); $hotelData = SerializedHotel::fromEntity($hotel);
$data['hotels']['hotel'][] = $hotelData; $data['hotels']['hotel'][] = $hotelData;
@@ -122,7 +124,7 @@ class ResellerDataService implements SingletonInterface
$hotelData['dates']['date'] = []; $hotelData['dates']['date'] = [];
} else { } else {
$dates = $this->productRepository->getDatesForExport($product, $hotel); $dates = $this->productRepository->getDatesForExport($product, $hotel);
$hotelData['dates']['date'] = $this->preprocessDates($dates, $paCode); $hotelData['dates']['date'] = $this->preprocessDates($dates, $myEpUrl, $paCode);
} }
} }
@@ -131,15 +133,15 @@ class ResellerDataService implements SingletonInterface
/** /**
* @param array $dates * @param array $dates
* @param string $paCode * @param string $myEpUrl
* @param string|null $paCode
* @return array * @return array
*/ */
public function preprocessDates(array $dates, $paCode = null) public function preprocessDates(array $dates, string $myEpUrl, $paCode = null)
{ {
$data = []; $data = [];
foreach ($dates as $row) foreach ($dates as $row) {
{
if (!isset($data[$row['dateStart']])) { if (!isset($data[$row['dateStart']])) {
$date = Date::fromArray($row); $date = Date::fromArray($row);
$data[$row['dateStart']] = $date; $data[$row['dateStart']] = $date;
@@ -148,6 +150,7 @@ class ResellerDataService implements SingletonInterface
$data[$row['dateStart']]['bookingurl'] = BookingUrlUtility::generateUrl([ $data[$row['dateStart']]['bookingurl'] = BookingUrlUtility::generateUrl([
'dateId' => $row['dateBusProId'], 'dateId' => $row['dateBusProId'],
'hotelId' => $row['hotelBusProId'], 'hotelId' => $row['hotelBusProId'],
'myEpUrl' => $myEpUrl,
'paCode' => $paCode, 'paCode' => $paCode,
]); ]);
@@ -3,7 +3,6 @@
namespace EP\EpProducts\Utility; namespace EP\EpProducts\Utility;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Routing\RouterInterface; use TYPO3\CMS\Core\Routing\RouterInterface;
use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -12,22 +11,15 @@ class BookingUrlUtility
{ {
public static function generateUrl(array $options): string public static function generateUrl(array $options): string
{ {
$config = GeneralUtility::makeInstance(ExtensionConfiguration::class)
->get('ep_products');
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
$resolver->setDefined(['paCode', 'returnPageUid']); $resolver->setDefined(['paCode', 'returnPageUid']);
$resolver->setRequired(['dateId', 'hotelId']); $resolver->setRequired(['dateId', 'hotelId', 'myEpUrl']);
$resolver->setDefaults([
'theme' => 'base',
]);
$resolvedOptions = $resolver->resolve($options); $resolvedOptions = $resolver->resolve($options);
$query = [ $query = [
'date_id' => $resolvedOptions['dateId'], 'date_id' => $resolvedOptions['dateId'],
'hotel_id' => $resolvedOptions['hotelId'], 'hotel_id' => $resolvedOptions['hotelId'],
'theme' => $resolvedOptions['theme'],
]; ];
if (null !== $resolvedOptions['paCode']) { if (null !== $resolvedOptions['paCode']) {
@@ -41,6 +33,8 @@ class BookingUrlUtility
$query['r'] = (string) $site->getRouter()->generateUri((int) $resolvedOptions['returnPageUid'], [], '', RouterInterface::ABSOLUTE_URL); $query['r'] = (string) $site->getRouter()->generateUri((int) $resolvedOptions['returnPageUid'], [], '', RouterInterface::ABSOLUTE_URL);
} }
return $config['myEpUrl'].'/bookings/create?'.http_build_query($query); $myEpUrl = rtrim($resolvedOptions['myEpUrl'], '/');
return $myEpUrl . '/bookings/create?' . http_build_query($query);
} }
} }
@@ -54,6 +54,8 @@ plugin.tx_epproducts {
searchLogIgnoreIps = searchLogIgnoreIps =
# cat=epproducts/140/120; type=string; label=Concept UIDs to trigger inquiry form on product detail page (CSV) # cat=epproducts/140/120; type=string; label=Concept UIDs to trigger inquiry form on product detail page (CSV)
groupInquiryFormConceptUids = groupInquiryFormConceptUids =
# cat=epproducts/140/200; type=string; label=MyE&P Base URL
myEpUrl = https://my.ep-reisen.de
} }
persistence { persistence {
# cat=epproducts/100/100; type=string; label=Default storage PID # cat=epproducts/100/100; type=string; label=Default storage PID
@@ -52,6 +52,7 @@ plugin.tx_epproducts {
groupsPriceToEmail = {$plugin.tx_epproducts.settings.groupsPriceToEmail} groupsPriceToEmail = {$plugin.tx_epproducts.settings.groupsPriceToEmail}
groupsPriceToName = {$plugin.tx_epproducts.settings.groupsPriceToName} groupsPriceToName = {$plugin.tx_epproducts.settings.groupsPriceToName}
groupInquiryFormConceptUids = {$plugin.tx_epproducts.settings.groupInquiryFormConceptUids} groupInquiryFormConceptUids = {$plugin.tx_epproducts.settings.groupInquiryFormConceptUids}
myEpUrl = {$plugin.tx_epproducts.settings.myEpUrl}
logoImage = {$plugin.tx_eptheme.settings.logoImage} logoImage = {$plugin.tx_eptheme.settings.logoImage}
themekey = {$plugin.tx_eptheme.settings.themekey} themekey = {$plugin.tx_eptheme.settings.themekey}
globalConceptCode = {$plugin.tx_eptheme.settings.globalConceptCode} globalConceptCode = {$plugin.tx_eptheme.settings.globalConceptCode}