From d07c07786f69ced8dc16627c3a7b59f2086cb446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Mon, 16 Aug 2021 10:58:24 +0200 Subject: [PATCH] WIP Refactor filter/search logic --- .../Classes/Controller/AjaxDateController.php | 9 +- .../Controller/AjaxSearchController.php | 34 +- .../Controller/AjaxSearchbarController.php | 25 +- .../Controller/AjaxTableController.php | 11 +- .../Controller/AjaxWatchlistController.php | 14 - .../Classes/Controller/ProductController.php | 4 +- .../Classes/Controller/SearchController.php | 76 +-- .../Classes/Domain/Model/FilterSettings.php | 503 ------------------ .../Classes/Domain/Model/SearchParams.php | 297 ----------- .../Domain/Repository/AbstractRepository.php | 6 +- .../StaticSearchParamsMiddleware.php | 15 +- .../Classes/Service/DateService.php | 66 +-- .../Classes/Service/FilterService.php | 141 +++-- .../Classes/Service/FilterSettingsEncoder.php | 10 +- .../Classes/Service/ProductDataService.php | 16 +- .../Classes/Service/SearchResultService.php | 24 +- .../Service/SearchResultUrlService.php | 96 ---- .../RequestArgumentTypeConversionTrait.php | 35 +- .../FilterSettingsEncoderViewHelper.php | 7 +- .../Private/Partials/Search/Result.html | 35 +- .../Private/Templates/AjaxWatchlist/List.html | 29 +- 21 files changed, 285 insertions(+), 1168 deletions(-) delete mode 100644 public/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php delete mode 100644 public/typo3conf/ext/ep_products/Classes/Domain/Model/SearchParams.php delete mode 100644 public/typo3conf/ext/ep_products/Classes/Service/SearchResultUrlService.php diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php index 297f36bc..f6438df8 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php @@ -109,12 +109,9 @@ class AjaxDateController extends ActionController public function datesAction(Product $product, Hotel $hotel = null, $paCode = null, $dateFrom = null, $dateTo = null) { $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - $filterSettings = $this->filterService->getDefaultFilterSettings( - $forcedConceptUids, - false, - $dateFrom, - $dateTo - ); + $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); + $filterSettings['dateFrom'] = $dateFrom; + $filterSettings['dateTo'] = $dateTo; $altProductLink = null; $altLabel = null; diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchController.php index 267631bc..449ef9bd 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchController.php @@ -28,7 +28,6 @@ namespace EP\EpProducts\Controller; ***************************************************************/ use EP\EpProducts\Service\FilterService; -use EP\EpProducts\Service\SearchResultUrlService; use EP\EpProducts\Service\SearchResultService; use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait; use EP\EpProducts\Utility\DateUtility; @@ -50,36 +49,29 @@ class AjaxSearchController extends ActionController */ protected $searchResultService; - /** - * @var SearchResultUrlService - */ - protected $searchResultUrlService; - /** * @param FilterService $filterService * @param SearchResultService $searchResultService - * @param SearchResultUrlService $searchResultUrlService */ - public function __construct - ( - FilterService $filterService, - SearchResultService $searchResultService, - SearchResultUrlService $searchResultUrlService - ) { + public function __construct(FilterService $filterService, SearchResultService $searchResultService) + { parent::__construct(); $this->filterService = $filterService; $this->searchResultService = $searchResultService; - $this->searchResultUrlService = $searchResultUrlService; + } + + public function initializeSearchresultAction() + { + $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); + $this->processFilterSettingsArgument($forcedConceptUids); } /** * @param array $filterSettings */ - public function searchresultAction(array $filterSettings = []) + public function searchresultAction(array $filterSettings) { - $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - $dateSelected = false; $organic = true; $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); @@ -94,14 +86,12 @@ class AjaxSearchController extends ActionController ->searchResultService ->getResult($filterSettings, $excludedConceptUids); - if ($searchResult->getTotal() === 0) { - $filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids); + if (0 === $searchResult->getTotal()) { + $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); $searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids); $organic = false; } - $this->searchResultUrlService->process($searchResult, $this->settings['defaultDetailPageUid']); - $filterOptions = $this->filterService->getFilterOptions( $filterSettings, $excludedConceptUids, @@ -117,7 +107,7 @@ class AjaxSearchController extends ActionController 'searchresult', ['filterSettings' => $filterSettings], 'Search', - null, + 'epproducts', 'searchresult' ) ; diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchbarController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchbarController.php index d3e6dc0d..c4aee202 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchbarController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxSearchbarController.php @@ -27,8 +27,8 @@ namespace EP\EpProducts\Controller; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Domain\Model\SearchParams; use EP\EpProducts\Service\FilterService; +use EP\EpProducts\Service\SearchResultService; use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; @@ -44,12 +44,19 @@ class AjaxSearchbarController extends ActionController protected $filterService; /** - * @param FilterService $filterService + * @var SearchResultService */ - public function __construct(FilterService $filterService) + protected $searchResultService; + + /** + * @param FilterService $filterService + * @param SearchResultService $searchResultService + */ + public function __construct(FilterService $filterService, SearchResultService $searchResultService) { parent::__construct(); $this->filterService = $filterService; + $this->searchResultService = $searchResultService; } public function initializeAction() @@ -58,18 +65,18 @@ class AjaxSearchbarController extends ActionController } /** - * @param SearchParams $searchParams + * @param array $searchParams * @return string */ - public function updateAction(SearchParams $searchParams = null) + public function updateAction(array $searchParams = null) { $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - if ($searchParams === null) { - $searchParams = new SearchParams(); - $filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids); + if (null === $searchParams) { + $searchParams = $this->searchResultService->getNormalizedSearchParams(); + $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); } else { - $filterSettings = $searchParams->toFilterSettings(); + $filterSettings = $this->filterService->getFilterSettingsFromSearchParams($searchParams); } $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); $excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']); diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php index d32e7308..55ab9d3c 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php @@ -75,12 +75,6 @@ class AjaxTableController extends ActionController $this->resellerDataService = $resellerDataService; } - public function initializeAction() - { - $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - $this->processFilterSettingsArgument($forcedConceptUids); - } - /** * @param Product $product * @param Hotel $hotel @@ -98,11 +92,12 @@ class AjaxTableController extends ActionController $paCode = null ) { $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - $filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids, false); + $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); if ($reseller = $this->resellerDataService->getResellerForCurrentDomain()) { $paCode = $reseller['paCode']; } + $priceTable = $this->dateService->getPriceTable([ 'product' => $product, 'hotel' => $hotel, @@ -138,7 +133,7 @@ class AjaxTableController extends ActionController $pricetable = $this->dateService->getPriceTable([ 'product' => $product, 'hotel' => $hotel, - 'filterSettings' => $this->filterService->getDefaultFilterSettings(), + 'filterSettings' => $this->filterService->getNormalizedFilterSettings(), 'template' => $this->settings['bpnBookingUrlTemplateCode'], 'paCode' => $paCode, ]); diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxWatchlistController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxWatchlistController.php index ccbae858..45dbc8d3 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxWatchlistController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxWatchlistController.php @@ -30,7 +30,6 @@ namespace EP\EpProducts\Controller; use EP\EpProducts\Domain\Repository\ProductRepository; use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\SearchResultService; -use EP\EpProducts\Service\SearchResultUrlService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; @@ -47,11 +46,6 @@ class AjaxWatchlistController extends ActionController */ protected $searchResultService; - /** - * @var SearchResultUrlService - */ - protected $searchResultUrlService; - /** * @var FilterService */ @@ -60,14 +54,12 @@ class AjaxWatchlistController extends ActionController /** * @param ProductRepository $productRepository * @param SearchResultService $searchResultService - * @param SearchResultUrlService $searchResultUrlService * @param FilterService $filterService */ public function __construct ( ProductRepository $productRepository, SearchResultService $searchResultService, - SearchResultUrlService $searchResultUrlService, FilterService $filterService ) { @@ -75,7 +67,6 @@ class AjaxWatchlistController extends ActionController $this->productRepository = $productRepository; $this->searchResultService = $searchResultService; - $this->searchResultUrlService = $searchResultUrlService; $this->filterService = $filterService; } @@ -107,11 +98,6 @@ class AjaxWatchlistController extends ActionController $watchlistData = $this->productRepository->getWatchlist($productUids, $hotelUids); $watchlist = $this->searchResultService->preprocess($watchlistData); - $options = [ - 'defaultDetailPageUid' => $this->settings['defaultDetailPageUid'], - ]; - $this->searchResultUrlService->process($watchlist, $options); - $this->view->assignMultiple([ 'watchlist' => $watchlist->getData(), 'total' => $watchlist->getTotal() diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php b/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php index 1d6846fc..3d765613 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php @@ -117,7 +117,7 @@ class ProductController extends ActionController } // Redirect to search page in case no product can be determined if ($product === null) { - $filterSettings = $this->filterService->getDefaultFilterSettings(); + $filterSettings = $this->filterService->getNormalizedFilterSettings(); $this->redirect( 'searchresult', 'Search', @@ -202,7 +202,7 @@ class ProductController extends ActionController $pricetable = $this->dateService->getPriceTable([ 'product' => $product, 'hotel' => $hotel, - 'filterSettings' => $this->filterService->getDefaultFilterSettings(), + 'filterSettings' => $this->filterService->getNormalizedFilterSettings(), ]); $this->view->assign('pricetable', $pricetable); } diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/SearchController.php b/public/typo3conf/ext/ep_products/Classes/Controller/SearchController.php index 12cb6972..9da8efe4 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/SearchController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/SearchController.php @@ -27,16 +27,13 @@ namespace EP\EpProducts\Controller; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Domain\Model\SearchParams; use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\FilterSettingsEncoder; use EP\EpProducts\Service\SearchResultService; -use EP\EpProducts\Service\SearchResultUrlService; use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait; use EP\EpProducts\Utility\DateUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; -use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException; class SearchController extends ActionController { @@ -53,53 +50,27 @@ class SearchController extends ActionController */ private $searchResultService; - /** - * @var SearchResultUrlService - */ - private $searchResultUrlService; - - /** - * @var array - */ - protected $defaultFilterSettings; - - /** - * @var \EP\EpProducts\Domain\Model\FilterOptions - */ - protected $defaultFilterOptions; - /** * @param FilterService $filterService */ - public function __construct - ( - FilterService $filterService, - SearchResultService $searchResultService, - SearchResultUrlService $searchResultUrlService - ) { + public function __construct(FilterService $filterService, SearchResultService $searchResultService) + { parent::__construct(); + $this->filterService = $filterService; $this->searchResultService = $searchResultService; - $this->searchResultUrlService = $searchResultUrlService; - $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true); - $excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids'], true); - $this->defaultFilterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids); - $this->defaultFilterOptions = $this->filterService->getFilterOptions( - $this->defaultFilterSettings, - $excludedConceptUids, - $excludedRegionUids, - $forcedConceptUids - ); } public function searchbarAction() { $fixed = (bool)$this->settings['fixed']; - $searchParams = new SearchParams($GLOBALS['TSFE']->id); + $searchParams = $this->searchResultService->getNormalizedSearchParams(); + $filterSettings = $this->filterService->getNormalizedFilterSettings(); + $filterOptions = $this->filterService->getFilterOptions($filterSettings); + $this->view->assignMultiple([ - 'filterSettings' => $this->defaultFilterSettings, - 'filterOptions' => $this->defaultFilterOptions, + 'filterSettings' => $filterSettings, + 'filterOptions' => $filterOptions, 'searchParams' => $searchParams, 'fixed' => $fixed, ]); @@ -107,10 +78,13 @@ class SearchController extends ActionController public function searchboxAction() { - $searchParams = new SearchParams($GLOBALS['TSFE']->id); + $searchParams = $this->searchResultService->getNormalizedSearchParams(); + $filterSettings = $this->filterService->getNormalizedFilterSettings(); + $filterOptions = $this->filterService->getFilterOptions($filterSettings); + $this->view->assignMultiple([ - 'filterSettings' => $this->defaultFilterSettings, - 'filterOptions' => $this->defaultFilterOptions, + 'filterSettings' => $filterSettings, + 'filterOptions' => $filterOptions, 'searchParams' => $searchParams, ]); } @@ -121,11 +95,11 @@ class SearchController extends ActionController } /** - * @param SearchParams $searchParams + * @param array $searchParams */ - public function processSearchAction(SearchParams $searchParams) + public function processSearchAction(array $searchParams) { - $filterSettings = $searchParams->toFilterSettings(); + $filterSettings = $this->filterService->getFilterSettingsFromSearchParams($searchParams); $redirectUri = $this->uriBuilder ->reset() @@ -144,13 +118,13 @@ class SearchController extends ActionController public function initializeSearchresultAction() { $forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); - //$this->processFilterSettingsArgument($forcedConceptUids); + $this->processFilterSettingsArgument($forcedConceptUids); } /** * @param array $filterSettings */ - public function searchresultAction(array $filterSettings = []) + public function searchresultAction(array $filterSettings) { $dateSelected = false; $organic = true; @@ -165,13 +139,11 @@ class SearchController extends ActionController $searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids); if ($searchResult->getTotal() === 0) { - $filterSettings = $this->defaultFilterSettings; + $filterSettings = $this->filterService->getNormalizedFilterSettings([], $forcedConceptUids); $searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids); $organic = false; } - $this->searchResultUrlService->process($searchResult, $this->settings['defaultDetailPageUid']); - $filterOptions = $this->filterService->getFilterOptions( $filterSettings, $excludedConceptUids, @@ -187,7 +159,7 @@ class SearchController extends ActionController 'searchresult', ['filterSettings' => $filterSettings], 'Search', - null, + 'epproducts', 'searchresult' ) ; @@ -208,11 +180,11 @@ class SearchController extends ActionController /** * @param string $encodedFilterSettings - * @throws StopActionException */ public function staticresultAction($encodedFilterSettings) { - $filterSettings = FilterSettingsEncoder::decode($encodedFilterSettings); + $filterSettingsEncoder = new FilterSettingsEncoder(); + $filterSettings = $filterSettingsEncoder->decode($encodedFilterSettings); $this->forward( 'searchresult', diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php b/public/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php deleted file mode 100644 index a72e3630..00000000 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php +++ /dev/null @@ -1,503 +0,0 @@ -, dreipunktnull - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use EP\EpProducts\Utility\TypeConversionUtility; -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Mvc\Request; - -class FilterSettings implements \JsonSerializable -{ - - public const DURATION_SHORT = 4; - public const DURATION_LONG = 5; - - /** - * @var array - */ - protected $priceRanges = []; - - /** - * @var array - */ - protected $countryUids = []; - - /** - * @var array - */ - protected $regionUids = []; - - /** - * @var array - */ - protected $cityUids = []; - - /** - * @var array - */ - protected $conceptUids = []; - - /** - * @var int - */ - protected $hotelUid = 0; - - /** - * @var int - */ - protected $productUid = 0; - - /** - * @var \DateTime - */ - protected $dateFrom; - - /** - * @var \DateTime - */ - protected $dateTo; - - /** - * @var int - */ - protected $nights = 0; - - /** - * @var int - */ - protected $pax = 0; - - /** - * @var array - */ - protected $boardTypes = []; - - /** - * @var array - */ - protected $hotelTypes = []; - - /** - * @var array - */ - protected $roomTypes = []; - - /** - * @var bool - */ - protected $bus; - - public function __construct(\DateTime $dateFrom = null, \DateTime $dateTo = null) - { - if ($dateFrom !== null) { - $this->setDateFrom($dateFrom); - } - - if ($dateTo !== null) { - $this->setDateTo($dateTo); - } - } - - public static function fromSearchParams(SearchParams $searchParams): self - { - $filterSettings = new self; - if ($searchParams->getDestinationType() && $searchParams->getDestinationUid()) { - $destinationUid = $searchParams->getDestinationUid(); - switch ($searchParams->getDestinationType()) { - case SearchParams::DESTINATION_TYPE_COUNTRY: - $filterSettings->setCountryUids([$destinationUid]); - break; - case SearchParams::DESTINATION_TYPE_REGION: - $filterSettings->setRegionUids([$destinationUid]); - break; - case SearchParams::DESTINATION_TYPE_CITY: - $filterSettings->setCityUids([$destinationUid]); - break; - case SearchParams::DESTINATION_TYPE_CONCEPT: - $filterSettings->setConceptUids([$destinationUid]); - break; - } - } - if (null !== $searchParams->getDateFrom()) { - $filterSettings->setDateFrom($searchParams->getDateFrom()); - } - if (null !== $searchParams->getDateTo()) { - $filterSettings->setDateTo($searchParams->getDateTo()); - } - if (null !== $searchParams->getPriceRange()) { - $filterSettings->setPriceRanges([$searchParams->getPriceRange()]); - } - if (null !== $searchParams->getPax()) { - $filterSettings->setPax($searchParams->getPax()); - } - if (null !== $searchParams->getNights()) { - $filterSettings->setNights($searchParams->getNights()); - } - - return $filterSettings; - } - - public static function fromStaticSearchParams(array $searchParams): self - { - $filterSettings = new self; - if (!empty($searchParams['country'])) { - $filterSettings->setCountryUids([$searchParams['country']]); - } - if (!empty($searchParams['region'])) { - $filterSettings->setRegionUids([$searchParams['region']]); - } - if (!empty($searchParams['concept'])) { - $conceptUids = GeneralUtility::trimExplode(',', $searchParams['concept']); - $filterSettings->setConceptUids($conceptUids); - } - if (!empty($searchParams['hotel'])) { - $filterSettings->setHotelUid($searchParams['hotel']); - } - if (!empty($searchParams['product'])) { - $filterSettings->setProductUid($searchParams['product']); - } - if (!empty($searchParams['hotel_types'])) { - $hotelTypes = explode(',', $searchParams['hotel_types']); - $filterSettings->setHotelTypes($hotelTypes); - } - if (!empty($searchParams['bus'])) { - $filterSettings->setBus((bool) $searchParams['bus']); - } - if (!empty($searchParams['date_from']) && $searchParams['date_from'] !== '0000-00-00') { - $dateFrom = new \DateTime($searchParams['date_from']); - $filterSettings->setDateFrom($dateFrom); - } - if (!empty($searchParams['date_to']) && $searchParams['date_to'] !== '0000-00-00') { - $dateTo = new \DateTime($searchParams['date_to']); - $filterSettings->setDateTo($dateTo); - } - if (!empty($searchParams['pax']) && (int) $searchParams['pax'] > 0) { - $filterSettings->setPax($searchParams['pax']); - } - return $filterSettings; - } - - public static function fromRequest(Request $request): self - { - $requestArgument = $request->getArgument('filterSettings'); - - $filterSettings = is_array($requestArgument) ? - $requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR); - - if ($requestArgument instanceof FilterSettings) { - $filterSettingsObject = $requestArgument; - } else { - $filterSettings['dateFrom'] = !empty($filterSettings['dateFrom']) ? new \DateTime($filterSettings['dateFrom']) : null; - $filterSettings['dateTo'] = !empty($filterSettings['dateTo']) ? new \DateTime($filterSettings['dateTo']) : null; - - if (!empty($filterSettings['bus'])) { - $filterSettings['bus'] = \in_array($filterSettings['bus'], [ true, 'true', '1' ], true); - } else { - $filterSettings['bus'] = null; - } - - $filterSettingsObject = new FilterSettings(); - - foreach ($filterSettings as $key => $value) { - $setter = 'set' . ucfirst($key); - $value = TypeConversionUtility::convertType($value); - if (method_exists($filterSettingsObject, $setter)) { - $filterSettingsObject->{$setter}($value); - } - } - } - - return $filterSettingsObject; - } - - /** - * @return array - */ - public function getPriceRanges() - { - return $this->priceRanges; - } - - /** - * @param array $priceRanges - */ - public function setPriceRanges($priceRanges) - { - $this->priceRanges = $priceRanges; - } - - /** - * @return array - */ - public function getCountryUids() - { - return $this->countryUids; - } - - /** - * @param array $countryUids - */ - public function setCountryUids(?array $countryUids) - { - $this->countryUids = $countryUids; - } - - /** - * @return array - */ - public function getRegionUids() - { - return $this->regionUids; - } - - /** - * @param array $regionUids - */ - public function setRegionUids(?array $regionUids) - { - $this->regionUids = $regionUids; - } - - /** - * @return array - */ - public function getCityUids() - { - return $this->cityUids; - } - - /** - * @param array $cityUids - */ - public function setCityUids(?array $cityUids) - { - $this->cityUids = $cityUids; - } - - /** - * @return array - */ - public function getConceptUids() - { - return $this->conceptUids; - } - - /** - * @param array $conceptUids - */ - public function setConceptUids(?array $conceptUids) - { - $this->conceptUids = $conceptUids; - } - - /** - * @return int - */ - public function getHotelUid() - { - return $this->hotelUid; - } - - /** - * @param int $hotelUid - */ - public function setHotelUid($hotelUid) - { - $this->hotelUid = (int) $hotelUid; - } - - /** - * @return int - */ - public function getProductUid() - { - return $this->productUid; - } - - /** - * @param int $productUid - */ - public function setProductUid($productUid) - { - $this->productUid = (int) $productUid; - } - - /** - * @return \DateTime - */ - public function getDateFrom() - { - return $this->dateFrom; - } - - /** - * @param \DateTime $dateFrom - */ - public function setDateFrom(\DateTimeInterface $dateFrom = null) - { - $this->dateFrom = $dateFrom; - } - - /** - * @return \DateTime - */ - public function getDateTo() - { - return $this->dateTo; - } - - /** - * @param \DateTime $dateTo - */ - public function setDateTo(\DateTimeInterface $dateTo = null) - { - if ($this->dateFrom !== null && $dateTo !== null && $dateTo < $this->dateFrom) { - $dateTo = $this->dateFrom; - } - $this->dateTo = $dateTo; - } - - /** - * @return int - */ - public function getNights() { - return $this->nights; - } - - /** - * @param int $nights - */ - public function setNights($nights) { - $this->nights = (int) $nights; - } - - /** - * @return int - */ - public function getPax() { - return $this->pax; - } - - /** - * @param int $pax - */ - public function setPax($pax) { - $this->pax = (int) $pax; - } - - /** - * @return array - */ - public function getBoardTypes() - { - return $this->boardTypes; - } - - /** - * @param array $boardTypes - */ - public function setBoardTypes(?array $boardTypes) - { - $this->boardTypes = $boardTypes; - } - - /** - * @return array - */ - public function getHotelTypes() - { - return $this->hotelTypes; - } - - /** - * @param array $hotelTypes - */ - public function setHotelTypes(?array $hotelTypes) - { - $this->hotelTypes = $hotelTypes; - } - - /** - * @return array - */ - public function getRoomTypes() - { - return $this->roomTypes; - } - - /** - * @param array $roomTypes - */ - public function setRoomTypes(?array $roomTypes) - { - $this->roomTypes = $roomTypes; - } - - /** - * @return bool - */ - public function getBus() - { - return $this->bus; - } - - /** - * @param bool $bus - */ - public function setBus($bus) - { - $this->bus = $bus; - } - - public function toArray(): array - { - return [ - 'priceRanges' => $this->getPriceRanges(), - 'countryUids' => $this->getCountryUids(), - 'regionUids' => $this->getRegionUids(), - 'cityUids' => $this->getCityUids(), - 'conceptUids' => $this->getConceptUids(), - 'hotelUid' => $this->getHotelUid(), - 'productUid' => $this->getProductUid(), - 'nights' => $this->getNights(), - 'pax' => $this->getPax(), - 'boardTypes' => $this->getBoardTypes(), - 'hotelTypes' => $this->getHotelTypes(), - 'roomTypes' => $this->getRoomTypes(), - 'dateFrom' => ($this->getDateFrom() !== null) ? $this->getDateFrom()->format('Y-m-d') : null, - 'dateTo' => ($this->getDateTo() !== null) ? $this->getDateTo()->format('Y-m-d') : null, - 'bus' => $this->getBus(), - ]; - } - - public function jsonSerialize() - { - return $this->toArray(); - } - -} diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Model/SearchParams.php b/public/typo3conf/ext/ep_products/Classes/Domain/Model/SearchParams.php deleted file mode 100644 index b976c98a..00000000 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Model/SearchParams.php +++ /dev/null @@ -1,297 +0,0 @@ -, dreipunktnull - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use EP\EpProducts\Utility\TypeConversionUtility; -use TYPO3\CMS\Extbase\Mvc\Request; - -class SearchParams implements \JsonSerializable -{ - public const DESTINATION_TYPE_COUNTRY = 'country'; - public const DESTINATION_TYPE_REGION = 'region'; - public const DESTINATION_TYPE_CITY = 'city'; - public const DESTINATION_TYPE_CONCEPT = 'concept'; - - /** - * @var int - */ - protected $priceRange; - - /** - * @var \DateTime - */ - protected $dateFrom; - - /** - * @var \DateTime - */ - protected $dateTo; - - /** - * @var int - */ - protected $destinationUid; - - /** - * @var string - */ - protected $destinationType; - - /** - * @var int - */ - protected $nights; - - /** - * @var int - */ - protected $pax = 1; - - /** - * @var int - */ - protected $pageUid; - - /** - * @param int $pageUid - */ - public function __construct(int $pageUid = 0) - { - $this->setPageUid($pageUid); - } - - public static function fromRequest(Request $request): self - { - $requestArgument = $request->getArgument('searchParams'); - $searchParams = is_array($requestArgument) ? - $requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR); - - $searchParams['dateFrom'] = !empty($searchParams['dateFrom']) ? new \DateTime($searchParams['dateFrom']) : null; - $searchParams['dateTo'] = !empty($searchParams['dateTo']) ? new \DateTime($searchParams['dateTo']) : null; - - $searchParamsObject = new self; - - foreach ($searchParams as $key => $value) { - $setter = 'set' . ucfirst($key); - $value = TypeConversionUtility::convertType($value); - if (method_exists($searchParamsObject, $setter)) { - $searchParamsObject->{$setter}($value); - } - } - - return $searchParamsObject; - } - - /** - * @return int - */ - public function getPriceRange() - { - return $this->priceRange; - } - - /** - * @param int $priceRange - */ - public function setPriceRange($priceRange) - { - $this->priceRange = $priceRange; - } - - /** - * @return \DateTime - */ - public function getDateFrom() - { - return $this->dateFrom; - } - - /** - * @param \DateTime $dateFrom - */ - public function setDateFrom(\DateTime $dateFrom = null) - { - $this->dateFrom = $dateFrom; - } - - /** - * @return \DateTime - */ - public function getDateTo() - { - return $this->dateTo; - } - - /** - * @param \DateTime $dateTo - */ - public function setDateTo(\DateTime $dateTo = null) - { - $this->dateTo = $dateTo; - } - - /** - * @return int - */ - public function getDestinationUid() - { - return $this->destinationUid; - } - - /** - * @param int $destinationUid - */ - public function setDestinationUid($destinationUid) - { - $this->destinationUid = $destinationUid; - } - - /** - * @return string - */ - public function getDestinationType() - { - return $this->destinationType; - } - - /** - * @param string $destinationType - */ - public function setDestinationType($destinationType) - { - $this->destinationType = $destinationType; - } - - /** - * @return int - */ - public function getNights() - { - return $this->nights; - } - - /** - * @param int $nights - */ - public function setNights($nights) - { - $this->nights = $nights; - } - - /** - * @return int - */ - public function getPax() - { - return $this->pax; - } - - /** - * @param int $pax - */ - public function setPax($pax) - { - $this->pax = $pax; - } - - /** - * @return int - */ - public function getPageUid() - { - return $this->pageUid; - } - - /** - * @param int $pageUid - */ - public function setPageUid($pageUid) - { - $this->pageUid = $pageUid; - } - - public function toFilterSettings(): array - { - $filterSettings = []; - - if ($this->getDestinationType() && $this->getDestinationUid()) { - $destinationUid = $this->getDestinationUid(); - switch ($this->getDestinationType()) { - case SearchParams::DESTINATION_TYPE_COUNTRY: - $filterSettings['countryUids'] = [ $destinationUid ]; - break; - case SearchParams::DESTINATION_TYPE_REGION: - $filterSettings['regionUids'] = [ $destinationUid ]; - break; - case SearchParams::DESTINATION_TYPE_CITY: - $filterSettings['cityUids'] = [ $destinationUid ]; - break; - case SearchParams::DESTINATION_TYPE_CONCEPT: - $filterSettings['conceptUids'] = [ $destinationUid ]; - break; - } - } - if (null !== $this->getDateFrom()) { - $filterSettings['dateFrom'] = $this->getDateFrom()->format('Y-m-d'); - } - if (null !== $this->getDateTo()) { - $filterSettings['dateTo'] = $this->getDateTo()->format('Y-m-d'); - } - if (null !== $this->getPriceRange()) { - $filterSettings['priceRanges'] = [ $this->getPriceRange() ]; - } - if (null !== $this->getPax()) { - $filterSettings['pax'] = $this->getPax(); - } - if (null !== $this->getNights()) { - $filterSettings['nights'] = $this->getNights(); - } - - return $filterSettings; - } - - public function toArray(): array - { - return [ - 'priceRange' => $this->getPriceRange(), - 'destinationUid' => $this->getDestinationUid(), - 'destinationType' => $this->getDestinationType(), - 'nights' => $this->getNights(), - 'pax' => $this->getPax(), - 'pageUid' => $this->getPageUid(), - 'dateFrom' => ($this->getDateFrom() !== null) ? $this->getDateFrom()->format('Y-m-d') : null, - 'dateTo' => ($this->getDateTo() !== null) ? $this->getDateTo()->format('Y-m-d') : null, - ]; - } - - public function jsonSerialize() - { - return $this->toArray(); - } - -} diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/AbstractRepository.php b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/AbstractRepository.php index 1590ecb0..8d7d2e70 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/AbstractRepository.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/AbstractRepository.php @@ -28,7 +28,7 @@ namespace EP\EpProducts\Domain\Repository; ***************************************************************/ use EP\EpProducts\Domain\Model\FilterOptions; -use EP\EpProducts\Domain\Model\FilterSettings; +use EP\EpProducts\Service\FilterService; use EP\EpProducts\Traits\DbConnectionTrait; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Query\QueryBuilder; @@ -165,12 +165,12 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit return; } $nights = (int)$filterSettings['nights']; - if ($nights === FilterSettings::DURATION_SHORT) { + if ($nights === FilterService::DURATION_SHORT) { $query ->andWhere('date.nights <= :nights') ->setParameter('nights', $nights) ; - } elseif ($nights === FilterSettings::DURATION_LONG) { + } elseif ($nights === FilterService::DURATION_LONG) { $query ->andWhere('date.nights >= :nights') ->setParameter('nights', $nights) diff --git a/public/typo3conf/ext/ep_products/Classes/Middleware/StaticSearchParamsMiddleware.php b/public/typo3conf/ext/ep_products/Classes/Middleware/StaticSearchParamsMiddleware.php index 46225d9b..d2127df2 100644 --- a/public/typo3conf/ext/ep_products/Classes/Middleware/StaticSearchParamsMiddleware.php +++ b/public/typo3conf/ext/ep_products/Classes/Middleware/StaticSearchParamsMiddleware.php @@ -27,7 +27,7 @@ namespace EP\EpProducts\Middleware; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Domain\Model\FilterSettings; +use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\FilterSettingsEncoder; use EP\EpProducts\Traits\DbConnectionTrait; use Psr\Http\Message\ResponseInterface; @@ -36,6 +36,8 @@ use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use TYPO3\CMS\Core\Http\NormalizedParams; use TYPO3\CMS\Core\Http\RedirectResponse; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Object\ObjectManager; class StaticSearchParamsMiddleware implements MiddlewareInterface { @@ -78,8 +80,15 @@ class StaticSearchParamsMiddleware implements MiddlewareInterface return $handler->handle($request); } - $filterSettings = FilterSettings::fromStaticSearchParams($row); - $encodedFilterSettings = rawurlencode(FilterSettingsEncoder::encode($filterSettings)); + /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */ + $objectManager = GeneralUtility::makeInstance(ObjectManager::class); + + /** @var \EP\EpProducts\Service\FilterService $filterService */ + $filterService = $objectManager->get(FilterService::class); + + $filterSettings = $filterService->getFilterSettingsFromStaticSearchParams($row); + $filterSettingsEncoder = new FilterSettingsEncoder(); + $encodedFilterSettings = rawurlencode($filterSettingsEncoder->encode($filterSettings)); $redirectUri = self::SEARCH_RESULT_URI . $encodedFilterSettings . '/'; diff --git a/public/typo3conf/ext/ep_products/Classes/Service/DateService.php b/public/typo3conf/ext/ep_products/Classes/Service/DateService.php index d51fb5f6..eb4e1863 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/DateService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/DateService.php @@ -27,7 +27,6 @@ namespace EP\EpProducts\Service; ***************************************************************/ use EP\EpProducts\Domain\Model\Date; -use EP\EpProducts\Domain\Model\FilterSettings; use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Repository\DateRepository; @@ -112,7 +111,7 @@ class DateService implements SingletonInterface $paCode = $resolvedOptions['paCode']; if ($filterSettings === null) { - $filterSettings = $this->filterService->getDefaultFilterSettings(); + $filterSettings = $this->filterService->getNormalizedFilterSettings(); } $nonBookableDateUids = GeneralUtility::trimExplode(',', $product->getNonBookableDates(), true); @@ -152,7 +151,7 @@ class DateService implements SingletonInterface $paCode = $resolvedOptions['paCode']; if ($filterSettings === null) { - $filterSettings = $this->filterService->getDefaultFilterSettings(); + $filterSettings = $this->filterService->getNormalizedFilterSettings(); } $nonBookableDateUids = GeneralUtility::trimExplode(',', $product->getNonBookableDates(), true); @@ -196,67 +195,6 @@ class DateService implements SingletonInterface ]); } - public function getAutocompleteOptions - ( - FilterSettings $filterSettings, - string $search, - array $excludedConceptUids = [], - array $excludedRegionUids = [] - ) - { - $destinations = [ - 'country' => [ - 'label' => 'Länder', - 'options' => [], - ], - 'region' => [ - 'label' => 'Gebiete', - 'options' => [], - ], - 'city' => [ - 'label' => 'Orte', - 'options' => [], - ], - 'hotel' => [ - 'label' => 'Unterkünfte', - 'options' => [], - ], - 'product' => [ - 'label' => 'Reiseangebote', - 'options' => [], - ], - ]; - - $search = mb_strtolower(trim($search)); - - foreach ($destinations as $type => $dummy) { - switch ($type) { - case 'hotel': - $result = $this->dateRepository->searchHotels($search, $filterSettings); - break; - case 'product': - $result = $this->dateRepository->searchProducts($search, $filterSettings, $excludedConceptUids); - break; - default: - $result = $this->dateRepository->searchDestinations( - $type, - $search, - $filterSettings, - $excludedRegionUids - ); - } - - foreach ($result as $row) { - $destinations[$type]['options'][] = [ - 'uid' => $row['uid'], - 'name' => $row['name'], - ]; - } - } - - return $destinations; - } - public function preprocessPriceTable(array $options): array { $resolver = new OptionsResolver(); diff --git a/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php b/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php index 67d16338..5ecc4a02 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php @@ -28,8 +28,8 @@ namespace EP\EpProducts\Service; ***************************************************************/ use EP\EpProducts\Domain\Model\FilterOptions; -use EP\EpProducts\Domain\Model\FilterSettings; use EP\EpProducts\Domain\Repository\DateRepository; +use Symfony\Component\OptionsResolver\OptionsResolver; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -37,6 +37,9 @@ use TYPO3\CMS\Core\Utility\PathUtility; class FilterService implements SingletonInterface { + public const DURATION_SHORT = 4; + public const DURATION_LONG = 5; + /** * @var array */ @@ -55,29 +58,108 @@ class FilterService implements SingletonInterface $this->dateRepository = $dateRepository; } - public function getDefaultFilterSettings - ( - array $forcedConceptUids = [], - bool $respectBookableDaterange = true, - string $dateFromYmd = null, - string $dateToYmd = null - ): array { - $filterSettings = []; + public function getNormalizedFilterSettings(array $filterSettings = [], array $forcedConceptUids = []): array + { + $optionsResolver = new OptionsResolver(); + $optionsResolver->setDefaults([ + 'priceRanges' => [], + 'countryUids' => [], + 'regionUids' => [], + 'cityUids' => [], + 'conceptUids' => [], + 'boardTypes' => [], + 'hotelTypes' => [], + 'roomTypes' => [], + 'hotelUid' => 0, + 'productUid' => 0, + 'dateFrom' => null, + 'dateTo' => null, + 'nights' => 0, + 'pax' => 0, + 'bus' => null, + ]); - [ $dateFrom, $dateTo ] = $this->constrainDateRange($this->dateRepository->getDateRange()); + $filterSettings = $optionsResolver->resolve($filterSettings); - if (null !== $dateFromYmd) { - $filterSettings['dateFrom'] = $dateFromYmd; - } elseif (!$respectBookableDaterange) { - $dateFrom = (new \DateTime('now'))->format('Y-m-d'); + if (count($forcedConceptUids) > 0) { + array_push($filterSettings['conceptUids'], ...$forcedConceptUids); } - if (null !== $dateToYmd) { - $filterSettings['dateTo'] = $dateToYmd; + return $filterSettings; + } + + public function getFilterSettingsFromSearchParams(array $searchParams): array + { + $filterSettings = $this->getNormalizedFilterSettings(); + + if ($searchParams['destinationType'] && $searchParams['destinationUid']) { + switch ($searchParams['destinationType']) { + case SearchResultService::DESTINATION_TYPE_COUNTRY: + $filterSettings['countryUids'] = [ $searchParams['destinationUid'] ]; + break; + case SearchResultService::DESTINATION_TYPE_REGION: + $filterSettings['regionUids'] = [ $searchParams['destinationUid'] ]; + break; + case SearchResultService::DESTINATION_TYPE_CITY: + $filterSettings['cityUids'] = [ $searchParams['destinationUid'] ]; + break; + case SearchResultService::DESTINATION_TYPE_CONCEPT: + $filterSettings['conceptUids'] = [ $searchParams['destinationUid'] ]; + break; + } + } + if ($searchParams['dateFrom']) { + $filterSettings['dateFrom'] = $searchParams['dateFrom']; + } + if ($searchParams['dateTo']) { + $filterSettings['dateTo'] = $searchParams['dateTo']; + } + if ($searchParams['priceRange']) { + $filterSettings['priceRanges'] = [ $searchParams['priceRange'] ]; + } + if ($searchParams['pax']) { + $filterSettings['pax'] = $searchParams['pax']; + } + if ($searchParams['nights']) { + $filterSettings['nights'] = $searchParams['nights']; } - if ($forcedConceptUids) { - $filterSettings['conceptUids'] = $forcedConceptUids; + return $filterSettings; + } + + public function getFilterSettingsFromStaticSearchParams(array $staticSearchParams): array + { + $filterSettings = $this->getNormalizedFilterSettings(); + + if (!empty($staticSearchParams['country'])) { + $filterSettings['countryUids'] = [ $staticSearchParams['country'] ]; + } + if (!empty($staticSearchParams['region'])) { + $filterSettings['regionUids'] = [ $staticSearchParams['region'] ]; + } + if (!empty($staticSearchParams['concept'])) { + $filterSettings['conceptUids'] = GeneralUtility::trimExplode(',', $staticSearchParams['concept'], true); + } + if (!empty($staticSearchParams['hotel'])) { + $filterSettings['hotelUid'] = $staticSearchParams['hotel']; + } + if (!empty($staticSearchParams['product'])) { + $filterSettings['productUid'] = $staticSearchParams['product']; + } + if (!empty($staticSearchParams['hotel_types'])) { + $filterSettings['hotelTypes'] = GeneralUtility::trimExplode(',', $staticSearchParams['hotel_types'], true); + } + if (!empty($staticSearchParams['bus'])) { + $filterSettings['bus'] = (bool)$staticSearchParams['bus']; + } + if (!empty($staticSearchParams['date_from']) && $staticSearchParams['date_from'] !== '0000-00-00') { + $filterSettings['dateFrom'] = $staticSearchParams['date_from']; + } + if (!empty($staticSearchParams['date_to']) && $staticSearchParams['date_to'] !== '0000-00-00') { + $filterSettings['dateTo'] = $staticSearchParams['date_to']; + } + if (!empty($staticSearchParams['pax']) && (int)$staticSearchParams['pax'] > 0) { + $filterSettings['pax'] = $staticSearchParams['pax']; } return $filterSettings; @@ -118,8 +200,7 @@ class FilterService implements SingletonInterface $absPath = ExtensionManagementUtility::extPath('ep_theme'); $baseUrl = '/' . PathUtility::stripPathSitePrefix($absPath); - foreach ($filterOptionsData as $row) - { + foreach ($filterOptionsData as $row) { // Date if (null === $dateMin || $row['dateStart'] < $dateMin) { $dateMin = $row['dateStart']; @@ -134,7 +215,7 @@ class FilterService implements SingletonInterface } // Nights - $duration = (int) $row['nights'] <= 4 ? FilterSettings::DURATION_SHORT : FilterSettings::DURATION_LONG; + $duration = (int) $row['nights'] <= 4 ? self::DURATION_SHORT : self::DURATION_LONG; if (!\in_array($duration, $nights, false)) { $nights[] = $duration; @@ -235,25 +316,9 @@ class FilterService implements SingletonInterface return $filterOptions; } - public function constrainDateRange(array $dateRange, FilterSettings $filterSettings = null): array - { - [ $dateFrom, $dateTo ] = $dateRange; - if ($filterSettings !== null) { - $filterSettingsDateFrom = $filterSettings->getDateFrom(); - if ($filterSettingsDateFrom !== null && $filterSettingsDateFrom > $dateFrom) { - $dateFrom = $filterSettings->getDateFrom(); - } - $filterSettingsDateTo = $filterSettings->getDateTo(); - if ($filterSettingsDateTo !== null && $filterSettingsDateTo < $dateTo) { - $dateTo = $filterSettings->getDateTo(); - } - } - return [$dateFrom, $dateTo]; - } - public function getFiltersettingsFromSettings(array $settings): array { - $filterSettings = []; + $filterSettings = $this->getNormalizedFilterSettings(); if (isset($settings['regionUid']) && (int) $settings['regionUid'] > 0) { $filterSettings['regionUids'] = [ $settings['regionUid'] ]; } elseif (isset($settings['countryUid']) && (int) $settings['countryUid'] > 0) { diff --git a/public/typo3conf/ext/ep_products/Classes/Service/FilterSettingsEncoder.php b/public/typo3conf/ext/ep_products/Classes/Service/FilterSettingsEncoder.php index 3e10fb8d..9ab3fe69 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/FilterSettingsEncoder.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/FilterSettingsEncoder.php @@ -34,7 +34,7 @@ class FilterSettingsEncoder /** * @return array */ - protected static function getMapping() + protected function getMapping() { return [ [ 'countryUids', 'array' ], @@ -54,10 +54,10 @@ class FilterSettingsEncoder ]; } - public static function encode(array $filterSettings): string + public function encode(array $filterSettings): string { $encoded = []; - foreach (static::getMapping() as $property) { + foreach ($this->getMapping() as $property) { [$name, $type] = $property; if (!isset($filterSettings[$name])) { $encoded[] = ''; @@ -76,11 +76,11 @@ class FilterSettingsEncoder return implode('|', $encoded); } - public static function decode(string $data): array + public function decode(string $data): array { $decoded = []; $values = explode('|', $data); - foreach (static::getMapping() as $index => $property) + foreach ($this->getMapping() as $index => $property) { [$name, $type] = $property; $value = $values[$index]; diff --git a/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php b/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php index 865580f0..0400cabf 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/ProductDataService.php @@ -26,7 +26,6 @@ namespace EP\EpProducts\Service; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Domain\Model\FilterSettings; use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Repository\HotelRepository; use EP\EpProducts\Domain\Repository\ProductRepository; @@ -83,11 +82,11 @@ class ProductDataService implements SingletonInterface } /** - * @param FilterSettings $filterSettings + * @param array $filterSettings * * @return array */ - public function getTeaser(FilterSettings $filterSettings) + public function getTeaser(array $filterSettings) { $teaserData = $this->productRepository->getTeasers($filterSettings); $teasers = $this->preprocessTeasergroup($teaserData); @@ -141,15 +140,12 @@ class ProductDataService implements SingletonInterface $teaser['busIncluded'] = true; } - $dateStart = new \DateTime($row['dateStart']); - $dateEnd = new \DateTime($row['dateEnd']); - - if ($teaser['minDateStart'] === null || $teaser['minDateStart'] > $dateStart) { - $teaser['minDateStart'] = $dateStart; + if ($teaser['minDateStart'] === null || $teaser['minDateStart'] > $row['dateStart']) { + $teaser['minDateStart'] = $row['dateStart']; } - if ($teaser['maxDateEnd'] === null || $teaser['maxDateEnd'] < $dateEnd) { - $teaser['maxDateEnd'] = $dateEnd; + if ($teaser['maxDateEnd'] === null || $teaser['maxDateEnd'] < $row['dateEnd']) { + $teaser['maxDateEnd'] = $row['dateEnd']; } if ($teaser['minPrice'] === null || $teaser['minPrice'] > $row['minPrice']) { diff --git a/public/typo3conf/ext/ep_products/Classes/Service/SearchResultService.php b/public/typo3conf/ext/ep_products/Classes/Service/SearchResultService.php index 6f24f450..7f6982e1 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/SearchResultService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/SearchResultService.php @@ -26,14 +26,19 @@ namespace EP\EpProducts\Service; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Domain\Model\FilterSettings; use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\SearchResult; use EP\EpProducts\Domain\Repository\ProductRepository; +use Symfony\Component\OptionsResolver\OptionsResolver; use TYPO3\CMS\Core\SingletonInterface; class SearchResultService implements SingletonInterface { + public const DESTINATION_TYPE_COUNTRY = 'country'; + public const DESTINATION_TYPE_REGION = 'region'; + public const DESTINATION_TYPE_CITY = 'city'; + public const DESTINATION_TYPE_CONCEPT = 'concept'; + /** * @var ProductRepository */ @@ -66,6 +71,23 @@ class SearchResultService implements SingletonInterface $this->flagIconService = $flagIconService; } + public function getNormalizedSearchParams(array $searchParams = []): array + { + $optionsResolver = new OptionsResolver(); + $optionsResolver->setDefaults([ + 'priceRange' => null, + 'dateFrom' => null, + 'dateTo' => null, + 'destinationUid' => null, + 'destinationType' => null, + 'nights' => null, + 'pax' => 1, + 'pageUid' => null, + ]); + + return $optionsResolver->resolve($searchParams); + } + public function getResult(array $filterSettings, array $excludedConceptUids = []): SearchResult { $searchResultData = $this->productRepository->getSearchResult($filterSettings, $excludedConceptUids); diff --git a/public/typo3conf/ext/ep_products/Classes/Service/SearchResultUrlService.php b/public/typo3conf/ext/ep_products/Classes/Service/SearchResultUrlService.php deleted file mode 100644 index fbc74495..00000000 --- a/public/typo3conf/ext/ep_products/Classes/Service/SearchResultUrlService.php +++ /dev/null @@ -1,96 +0,0 @@ -, dreipunktnull - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use EP\EpProducts\Domain\Model\SearchResult; -use Symfony\Component\OptionsResolver\OptionsResolver; -use TYPO3\CMS\Core\SingletonInterface; -use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; - -class SearchResultUrlService implements SingletonInterface -{ - /** - * @var UriBuilder - */ - protected $uriBuilder; - - /** - * @param UriBuilder $uriBuilder - */ - public function __construct(UriBuilder $uriBuilder) - { - $this->uriBuilder = $uriBuilder; - } - - /** - * @param SearchResult $searchResult - * @param int $defaultDetailPageUid - */ - public function process(SearchResult $searchResult, $defaultDetailPageUid): void - { - $data = $searchResult->getData(); - - foreach ($data as $conceptUid => $conceptData) { - foreach ($conceptData['items'] as $key => $item) { - $detailPageUid = $this->getProductPageUid($item['product']['detailPage'], $defaultDetailPageUid); - $arguments = [ - 'product' => $item['product']['uid'], - 'hotel' => $item['hotel']['uid'], - ]; - $uri = $this - ->uriBuilder - ->reset() - ->setTargetPageUid($detailPageUid) - ->setCreateAbsoluteUri(true) - ->uriFor('detail', $arguments, 'Product', 'epproducts', 'product_detail') - ; - $data[$conceptUid]['items'][$key]['detailPageUri'] = $uri; - } - } - - $searchResult->setData($data); - } - - /** - * @param mixed $uid - * @param int $defaultUid - * @return int - */ - protected function getProductPageUid($uid, int $defaultUid): int - { - if (is_numeric($uid)) { - return (int) $uid; - } - - if (strpos($uid, 't3://') !== false) { - parse_str(parse_url($uid, PHP_URL_QUERY), $arguments); - return (int) $arguments['uid']; - } - - return $defaultUid; - } -} diff --git a/public/typo3conf/ext/ep_products/Classes/Traits/RequestArgumentTypeConversionTrait.php b/public/typo3conf/ext/ep_products/Classes/Traits/RequestArgumentTypeConversionTrait.php index 7584ff12..d864f3df 100644 --- a/public/typo3conf/ext/ep_products/Classes/Traits/RequestArgumentTypeConversionTrait.php +++ b/public/typo3conf/ext/ep_products/Classes/Traits/RequestArgumentTypeConversionTrait.php @@ -27,9 +27,8 @@ namespace EP\EpProducts\Traits; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Domain\Model\FilterSettings; -use EP\EpProducts\Domain\Model\SearchParams; use EP\EpProducts\Service\FilterService; +use EP\EpProducts\Service\SearchResultService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Object\ObjectManager; @@ -41,11 +40,22 @@ trait RequestArgumentTypeConversionTrait */ public function processSearchParamsArgument() { - if ($this->request->hasArgument('searchParams')) { - $searchParamsObject = SearchParams::fromRequest($this->request); + /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */ + $objectManager = GeneralUtility::makeInstance(ObjectManager::class); - $this->request->setArgument('searchParams', $searchParamsObject); + /** @var SearchResultService $searchResultService */ + $searchResultService = $objectManager->get(SearchResultService::class); + + if (!$this->request->hasArgument('searchParams')) { + $searchParams = $searchResultService->getNormalizedSearchParams(); + } else { + $requestArgument = $this->request->getArgument('searchParams'); + $searchParamsFromRequest = is_array($requestArgument) ? + $requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR); + $searchParams = $searchResultService->getNormalizedSearchParams($searchParamsFromRequest); } + + $this->request->setArgument('searchParams', $searchParams); } /** @@ -61,18 +71,15 @@ trait RequestArgumentTypeConversionTrait $filterService = $objectManager->get(FilterService::class); if (!$this->request->hasArgument('filterSettings')) { - $filterSettingsObject = $filterService->getDefaultFilterSettings($forcedConceptUids); + $filterSettings = $filterService->getNormalizedFilterSettings([], $forcedConceptUids); } else { - $filterSettingsObject = FilterSettings::fromRequest($this->request); - - if ($forcedConceptUids) { - $conceptUids = $filterSettingsObject->getConceptUids(); - array_push($conceptUids, ...$forcedConceptUids); - $filterSettingsObject->setConceptUids($conceptUids); - } + $requestArgument = $this->request->getArgument('filterSettings'); + $filterSettingsFromRequest = is_array($requestArgument) ? + $requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR); + $filterSettings = $this->filterService->getNormalizedFilterSettings($filterSettingsFromRequest, $forcedConceptUids); } - $this->request->setArgument('filterSettings', $filterSettingsObject); + $this->request->setArgument('filterSettings', $filterSettings); } } diff --git a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/FilterSettingsEncoderViewHelper.php b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/FilterSettingsEncoderViewHelper.php index bc75754e..aba18bc5 100644 --- a/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/FilterSettingsEncoderViewHelper.php +++ b/public/typo3conf/ext/ep_theme/Classes/ViewHelpers/FilterSettingsEncoderViewHelper.php @@ -28,7 +28,6 @@ namespace EP\EpTheme\ViewHelpers; ***************************************************************/ use EP\EpProducts\Service\FilterSettingsEncoder; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; @@ -69,8 +68,8 @@ class FilterSettingsEncoderViewHelper extends AbstractViewHelper return ''; } - /** @var \EP\EpProducts\Service\FilterSettingsEncoder $encoder */ - $encoder = GeneralUtility::makeInstance(FilterSettingsEncoder::class); - return $encoder::encode($argument); + $encoder = new FilterSettingsEncoder(); + + return $encoder->encode($argument); } } diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Search/Result.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Search/Result.html index fb101f10..791d9aa0 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Search/Result.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Search/Result.html @@ -21,6 +21,9 @@
+ + +

@@ -31,7 +34,11 @@
{item.country.name} - + @@ -40,7 +47,7 @@ title="{item.hotel.images.resized.s.0.title}" alt="{item.hotel.images.resized.s.0.alt}"> - +
{section.concept.name} @@ -106,11 +113,15 @@ - - - {item.dates -> f:count()} {f:if(condition: '{item.dates -> f:count()} > 1', then: 'Termine', else: 'Termin')} - - + + + {item.dates -> f:count()} {f:if(condition: '{item.dates -> f:count()} > 1', then: 'Termine', else: 'Termin')} + + @@ -121,10 +132,14 @@
+ + +