From f58d5035298f5b5d28ac49e8e3993d8655a6a222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Sat, 15 Feb 2020 17:26:08 +0100 Subject: [PATCH] Enable limiting of dates on detail pages according to teasers --- config/sites/ep-reisen/config.yaml | 11 ++++ .../Classes/Controller/AjaxDateController.php | 11 +++- .../Classes/Controller/ProductController.php | 13 +++- .../Classes/Service/FilterService.php | 14 ++++- .../Classes/Service/ProductDataService.php | 3 +- .../Configuration/TypoScript/setup.typoscript | 4 +- .../ext/ep_products/ext_localconf.php | 3 +- .../ViewHelpers/Uri/ProductViewHelper.php | 63 +++++++++++-------- .../Assets/js/components/ProductDetail.vue | 17 ++++- .../Private/Partials/Product/Teaser.html | 27 +------- .../Private/Partials/Product/TeaserWide.html | 12 +--- .../Private/Templates/Product/Detail.html | 2 + .../Templates/Product/Teasergroup.html | 4 +- 13 files changed, 109 insertions(+), 75 deletions(-) diff --git a/config/sites/ep-reisen/config.yaml b/config/sites/ep-reisen/config.yaml index 8fbc375c..27e5cdc1 100644 --- a/config/sites/ep-reisen/config.yaml +++ b/config/sites/ep-reisen/config.yaml @@ -109,6 +109,12 @@ routeEnhancers: _arguments: product_uid: product hotel_uid: hotel + - + routePath: '/angebot/{date_from}/{date_to}' + _controller: 'Product::detail' + _arguments: + date_from: dateFrom + date_to: dateTo defaultController: 'Product::detail' aspects: product_uid: @@ -119,6 +125,11 @@ routeEnhancers: type: PersistedAliasMapper tableName: tx_epproducts_domain_model_hotel routeFieldName: uid + requirements: + product_uid: '\d' + hotel_uid: '\d' + date_from: '\d{4}-\d{2}-\d{2}' + date_to: '\d{4}-\d{2}-\d{2}' BookingLinkPlugin: type: Extbase extension: EpProducts diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php index 1ee271c2..ac225e3f 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php @@ -95,11 +95,13 @@ class AjaxDateController extends ActionController * @param Product $product * @param Hotel $hotel * @param string $paCode + * @param string $dateFrom + * @param string $dateTo * * @return string * @throws \Doctrine\DBAL\DBALException */ - public function datesAction(Product $product, Hotel $hotel = null, $paCode = null) + public function datesAction(Product $product, Hotel $hotel = null, $paCode = null, $dateFrom = null, $dateTo = null) { if ($hotel === null) { return json_encode([ @@ -111,7 +113,12 @@ class AjaxDateController extends ActionController } $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - $filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids, false); + $filterSettings = $this->filterService->getDefaultFilterSettings( + $forcedConceptUids, + false, + $dateFrom, + $dateTo + ); $altProductLink = null; $altLabel = null; diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php b/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php index 582ce8f8..78df9083 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php @@ -100,12 +100,16 @@ class ProductController extends ActionController /** * @param Product $product * @param Hotel $hotel + * @param string $dateFrom + * @param string $dateTo * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException */ public function detailAction( Product $product = null, - Hotel $hotel = null + Hotel $hotel = null, + $dateFrom = null, + $dateTo = null ) { // Get product to display from flexform settings if not provided via url if ($product === null) { @@ -142,6 +146,7 @@ class ProductController extends ActionController $hotel = reset($product->getHotels()->toArray()); } } + $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); $isProductWithExcludedConcept = ($product->getConcept() !== null) && \in_array($product->getConcept()->getUid(), $excludedConceptUids, false); @@ -154,6 +159,8 @@ class ProductController extends ActionController 'isProductWithExcludedConcept' => $isProductWithExcludedConcept, 'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept, 'currentPageUid' => $GLOBALS['TSFE']->id, + 'dateFrom' => $dateFrom, + 'dateTo' => $dateTo, ]); } @@ -193,9 +200,13 @@ class ProductController extends ActionController $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true); $limit = $this->settings['showMoreLink'] ? 4 : 0; $teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit); + $dateFrom = $this->settings['dateFrom'] ? date('Y-m-d', $this->settings['dateFrom']) : null; + $dateTo = $this->settings['dateTo'] ? date('Y-m-d', $this->settings['dateTo']) : null; $this->view->assign('teasers', $teasers); $this->view->assign('dateAuto', $dateAuto); $this->view->assign('filterSettings', $filterSettings); + $this->view->assign('dateFrom', $dateFrom); + $this->view->assign('dateTo', $dateTo); } } diff --git a/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php b/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php index aaa6bf62..e1ae2912 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php @@ -60,12 +60,22 @@ class FilterService implements SingletonInterface /** * @param array $forcedConceptUids * @param bool $respectBookableDaterange - * + * @param string $dateFromYmd + * @param string $dateToYmd * @return FilterSettings + * @throws \Exception */ - public function getDefaultFilterSettings(array $forcedConceptUids = [], $respectBookableDaterange = true) + public function getDefaultFilterSettings(array $forcedConceptUids = [], $respectBookableDaterange = true, $dateFromYmd = null, $dateToYmd = null) { [ $dateFrom, $dateTo ] = $this->constrainDateRange($this->getDateRange()); + + if (null !== $dateFromYmd) { + $dateFrom = new \DateTime($dateFromYmd); + } + if (null !== $dateToYmd) { + $dateTo = new \DateTime($dateToYmd); + } + if (!$respectBookableDaterange) { $dateFrom = new \DateTime('now'); } diff --git a/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php b/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php index 184e0e53..ddc01ded 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php @@ -180,8 +180,7 @@ class ProductDataService implements SingletonInterface */ public function createTeaserData(array $teaserData) { - $hotelCategory = array_key_exists($teaserData['hotelCategory'], Hotel::$categoryLabels) ? - Hotel::$categoryLabels[$teaserData['hotelCategory']] : null; + $hotelCategory = Hotel::$categoryLabels[$teaserData['hotelCategory']] ?? null; // Use compound key, hotel is not unique $key = $teaserData['hotelUid'] . ':' . $teaserData['productUid']; diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index 301e12b4..5b330dbe 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -95,7 +95,9 @@ plugin.tx_epproducts { } } } - features.requireCHashArgumentForActionArguments = 0 + features { + requireCHashArgumentForActionArguments = 0 + } } config.tx_extbase.persistence.classes { diff --git a/public/typo3conf/ext/ep_products/ext_localconf.php b/public/typo3conf/ext/ep_products/ext_localconf.php index d69395e4..7beb7c56 100644 --- a/public/typo3conf/ext/ep_products/ext_localconf.php +++ b/public/typo3conf/ext/ep_products/ext_localconf.php @@ -404,7 +404,8 @@ $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'ref'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'pa'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_searchresult[searchParams]'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_searchresult[filterSettings]'; -$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_product_detail[filterSettings]'; +$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_product_detail[dateFrom]'; +$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_product_detail[dateTo]'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_reseller[reseller]'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_ajax[months]'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_ajax[month]'; diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Uri/ProductViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Uri/ProductViewHelper.php index 9eef7f4d..c37cb234 100644 --- a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Uri/ProductViewHelper.php +++ b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/Uri/ProductViewHelper.php @@ -27,6 +27,7 @@ namespace EP\EpTheme\ViewHelpers\Uri; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use EP\EpEvents\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Product; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -42,12 +43,12 @@ class ProductViewHelper extends AbstractViewHelper { parent::initializeArguments(); - $this->registerArgument('product', Product::class, 'The product', true); - $this->registerArgument('hotel', 'mixed', 'The hotel'); - $this->registerArgument('linkHotel', 'bool', 'Whether to link the hotel', false, false); - $this->registerArgument('referringPageUid', 'int', 'Uid of the referring page'); - $this->registerArgument('defaultDetailPageUid', 'int', 'Uid of default page for product details'); - $this->registerArgument('origin', 'string', 'Origin of the link'); + $this->registerArgument('product', 'array', 'The product'); + $this->registerArgument('hotel', 'array', 'The hotel'); + $this->registerArgument('dateFrom', 'string', 'Date to limit table on detail page by (Y-m-d)'); + $this->registerArgument('dateTo', 'string', 'Date to limit table on detail page by (Y-m-d)'); + $this->registerArgument('forceHotelUid', 'bool', 'Whether to force link a hotel'); + $this->registerArgument('slug', 'string', 'Slug to append to resulting uri'); } /** @@ -63,35 +64,45 @@ class ProductViewHelper extends AbstractViewHelper ) { $product = $arguments['product']; + $hotel = $arguments['hotel']; - if ($product->getDetailPage()) { + $linkArguments = null; + + if ($arguments['forceHotelUid']) { + $linkArguments = [ + 'product' => $product['uid'], + 'hotel' => $hotel['uid'], + ]; + } elseif ($arguments['dateFrom'] || $arguments['dateTo']) { + $linkArguments = [ + 'dateFrom' => $arguments['dateFrom'], + 'dateTo' => $arguments['dateTo'], + ]; + } + + if (null !== $linkArguments) { + $uri = $renderingContext + ->getControllerContext() + ->getUriBuilder() + ->reset() + ->setTargetPageUid($product['detailPage']) + ->uriFor('detail', $linkArguments, 'Product', 'epproducts', 'product_detail') + ; + } else { /** @var ContentObjectRenderer $contentObject */ $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class); - return $contentObject->typoLink_URL( + $uri = $contentObject->typoLink_URL( [ - 'parameter' => $product->getDetailPage(), + 'parameter' => $product['detailPage'], ] ); } - $pageUid = $arguments['defaultDetailPageUid']; - $uriArguments = [ 'product' => $product ]; - if ((int) $arguments['referringPageUid'] > 0) { - $uriArguments['referringPageUid'] = $arguments['referringPageUid']; + if ($arguments['slug']) { + $uri .= $arguments['slug'].'/'; } - if ($arguments['origin'] !== null) { - $uriArguments['origin'] = $arguments['origin']; - } - if ((bool) $arguments['linkHotel'] && $arguments['hotel'] !== null) { - $uriArguments['hotel'] = $arguments['hotel']; - } - return $renderingContext - ->getControllerContext() - ->getUriBuilder() - ->reset() - ->setTargetPageUid($pageUid) - ->uriFor('detail', $uriArguments, 'Product', 'epproducts', 'product_detail') - ; + + return $uri; } } diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue index cbc22ec8..8cef8f8c 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue @@ -78,6 +78,14 @@ daytrip: { type: Number, default: 0 + }, + dateFrom: { + type: String, + default: null + }, + dateTo: { + type: String, + default: null } }, computed: { @@ -91,12 +99,15 @@ this.datesShow = true; this.priceTableShow = false; this.detailShow = false; + const data = $.param({ + 'tx_epproducts_ajax[paCode]': this.$store.state.config.paCode, + 'tx_epproducts_ajax[dateFrom]': this.dateFrom, + 'tx_epproducts_ajax[dateTo]': this.dateTo + }); axios({ url: this.uris['dates'], method: 'post', - data: { - paCode: this.$store.state.config.paCode - } + data: data }).then(response => { const json = response.data; if (json.dates.length === 1) { diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/Teaser.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/Teaser.html index 12d42cd8..4d474e24 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/Teaser.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/Teaser.html @@ -6,30 +6,9 @@
- - - - - - - - - - - - - - - - + + +
diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/TeaserWide.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/TeaserWide.html index 88cd9f4a..d845827e 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/TeaserWide.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Product/TeaserWide.html @@ -5,17 +5,7 @@ xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"> - - - - - - - - - - - + {ep:uri.product(forceHotelUid: teaser.forceHotelUid, product: teaser.product, hotel: teaser.hotel, dateFrom: dateFrom, dateTo: dateTo, slug: slug) -> f:variable(name: 'teaserUrl')} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html index 62e3f194..d579aa70 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html @@ -20,6 +20,8 @@ :bus-pro-id="{product.busProId -> f:format.raw()}" name-internal="{product.nameInternal -> f:format.raw()}" :daytrip="{product.daytrip -> v:variable.convert(type: 'int')}" + date-from="{dateFrom}" + date-to="{dateTo}" inline-template>
diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Teasergroup.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Teasergroup.html index bc7fcaeb..423e542b 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Teasergroup.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Teasergroup.html @@ -12,11 +12,11 @@ - +
- +