diff --git a/packages/ep_products/Classes/Controller/CityController.php b/packages/ep_products/Classes/Controller/CityController.php
new file mode 100644
index 0000000..d4a1e63
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/CityController.php
@@ -0,0 +1,99 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\City;
+use EP\EpProducts\Domain\Repository\CityRepository;
+use EP\EpProducts\Service\ProductDataService;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class CityController extends ActionController
+{
+
+ /**
+ * @var CityRepository
+ */
+ protected $cityRepository;
+
+ /**
+ * @var ProductDataService
+ */
+ private $productDataService;
+
+ /**
+ * @param CityRepository $cityRepository
+ * @param ProductDataService $productDataService
+ */
+ public function __construct(CityRepository $cityRepository, ProductDataService $productDataService)
+ {
+ $this->cityRepository = $cityRepository;
+ $this->productDataService = $productDataService;
+ }
+
+ /**
+ * @param City $city
+ */
+ public function detailAction(?City $city = null): ResponseInterface
+ {
+ if (null === $city) {
+ $cityUid = ($this->settings['cityUid'] ?? '');
+ $city = $this->cityRepository->findByIdentifier($cityUid);
+ }
+
+ $teasers = [];
+
+ if (null !== $city) {
+ $filterSettings = [
+ 'cityUids' => [$cityUid]
+ ];
+ $teasers = $this->productDataService->getTeasergroup($filterSettings);
+ }
+
+ $this->view->assignMultiple([
+ 'city' => $city,
+ 'teasers' => $teasers,
+ 'filterSettings' => $filterSettings,
+ ]);
+ return $this->htmlResponse();
+ }
+
+ public function teasergroupAction(): ResponseInterface
+ {
+ $regionUid = (int)($this->settings['regionUid'] ?? '');
+ $countryUid = (int)($this->settings['countryUid'] ?? '');
+ $season = ($this->settings['season'] ?? '');
+ $citiesPid = (int)($this->settings['citiesStoragePid'] ?? '');
+
+ $cities = $this->cityRepository->getTeasersByCountryOrRegionAndSeason($regionUid, $countryUid, $season, $citiesPid);
+ $data = $this->request->getAttribute('currentContentObject')->data;
+ $this->view->assign('data', $data);
+ $this->view->assign('teasers', $cities);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/ConceptController.php b/packages/ep_products/Classes/Controller/ConceptController.php
new file mode 100644
index 0000000..23c5a67
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/ConceptController.php
@@ -0,0 +1,106 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\Concept;
+use EP\EpProducts\Domain\Repository\ConceptRepository;
+use EP\EpProducts\Service\ProductDataService;
+use EP\EpTheme\Domain\Repository\PageRepository;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class ConceptController extends ActionController
+{
+
+ /**
+ * @var ConceptRepository
+ */
+ protected $conceptRepository;
+
+ /**
+ * @var ProductDataService
+ */
+ protected $productDataService;
+
+ /**
+ * @var PageRepository
+ */
+ private $pageRepository;
+
+ /**
+ * @param ConceptRepository $conceptRepository
+ * @param ProductDataService $productDataService
+ * @param PageRepository $pageRepository
+ */
+ public function __construct(ConceptRepository $conceptRepository, ProductDataService $productDataService, PageRepository $pageRepository)
+ {
+ $this->conceptRepository = $conceptRepository;
+ $this->productDataService = $productDataService;
+ $this->pageRepository = $pageRepository;
+ }
+
+ /**
+ * @param Concept $concept
+ */
+ public function detailAction(?Concept $concept = null): ResponseInterface
+ {
+ if ($concept === null) {
+ $conceptUid = ($this->settings['conceptUid'] ?? '');
+ $concept = $this->conceptRepository->findByIdentifier($conceptUid);
+ }
+
+ $teaserConceptUids = GeneralUtility::trimExplode(',', ($this->settings['additionalConceptUids'] ?? ''));
+ if (null !== $concept) {
+ array_unshift($teaserConceptUids, $concept->getUid());
+ }
+
+ $filterSettings = ['conceptUids' => $teaserConceptUids];
+ $excludedConceptUids = GeneralUtility::trimExplode(',', ($this->settings['excludedConceptUids'] ?? ''), true);
+ $limit = ($this->settings['showMoreLink'] ?? '') ? 6 : 0;
+ $teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
+ $pages = $this->pageRepository->findPagesByPid((int)($this->settings['conceptsPageUid'] ?? ''));
+ $data = $this->request->getAttribute('currentContentObject')->data;
+
+ $this->view->assignMultiple([
+ 'teasers' => $teasers,
+ 'concept' => $concept,
+ 'filterSettings' => $filterSettings,
+ 'pages' => $pages,
+ 'data' => $data,
+ ]);
+ return $this->htmlResponse();
+ }
+
+ public function teasergroupAction(): ResponseInterface
+ {
+ $concepts = $this->conceptRepository->findAll();
+ $this->view->assign('teasers', $concepts);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/CountryController.php b/packages/ep_products/Classes/Controller/CountryController.php
new file mode 100644
index 0000000..ee5b235
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/CountryController.php
@@ -0,0 +1,80 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\Country;
+use EP\EpProducts\Domain\Repository\CountryRepository;
+use EP\EpProducts\Service\ProductDataService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class CountryController extends ActionController
+{
+
+ /**
+ * @var CountryRepository
+ */
+ protected $countryRepository;
+
+ /**
+ * @var ProductDataService
+ */
+ protected $productDataService;
+
+ /**
+ * @param CountryRepository $countryRepository
+ * @param ProductDataService $productDataService
+ */
+ public function __construct(CountryRepository $countryRepository, ProductDataService $productDataService)
+ {
+ $this->countryRepository = $countryRepository;
+ $this->productDataService = $productDataService;
+ }
+
+ /**
+ * @param Country $country
+ */
+ public function detailAction(?Country $country = null): ResponseInterface
+ {
+ if ($country === null) {
+ $countryUid = ($this->settings['countryUid'] ?? '');
+ $country = $this->countryRepository->findByIdentifier($countryUid);
+ }
+ $filterSettings = [
+ 'countryUids' => [ $countryUid ],
+ ];
+ $excludedConceptUids = GeneralUtility::trimExplode(',', ($this->settings['excludedConceptUids'] ?? ''), true);
+ $limit = ($this->settings['showMoreLink'] ?? '') ? 6 : 0;
+ $teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
+ $this->view->assign('teasers', $teasers);
+ $this->view->assign('country', $country);
+ $this->view->assign('filterSettings', $filterSettings);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/FaqController.php b/packages/ep_products/Classes/Controller/FaqController.php
new file mode 100644
index 0000000..5fceeaf
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/FaqController.php
@@ -0,0 +1,57 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Repository\FaqRepository;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class FaqController extends ActionController
+{
+
+ /**
+ * @var FaqRepository
+ */
+ protected $faqRepository;
+
+ /**
+ * @param FaqRepository $faqRepository
+ */
+ public function __construct(FaqRepository $faqRepository)
+ {
+ $this->faqRepository = $faqRepository;
+ }
+
+ public function detailAction(): ResponseInterface
+ {
+ $faqUids = ($this->settings['faqUids'] ?? '');
+ $faqs = $this->faqRepository->findByUids($faqUids);
+ $this->view->assign('faqs', $faqs);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/HotelController.php b/packages/ep_products/Classes/Controller/HotelController.php
new file mode 100644
index 0000000..87fc904
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/HotelController.php
@@ -0,0 +1,157 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\Product;
+use EP\EpProducts\Domain\Model\Hotel;
+use EP\EpProducts\Domain\Repository\HotelRepository;
+use EP\EpProducts\Domain\Repository\ProductRepository;
+use EP\EpProducts\Service\HotelDataService;
+use EP\EpProducts\Service\ProductDataService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class HotelController extends ActionController
+{
+
+ /**
+ * @var HotelRepository
+ */
+ protected $hotelRepository;
+
+ /**
+ * @var ProductRepository
+ */
+ protected $productRepository;
+
+ /**
+ * @var HotelDataService
+ */
+ protected $hotelDataService;
+
+ /**
+ * @var ProductDataService
+ */
+ protected $productDataService;
+
+ /**
+ * @param HotelDataService $hotelDataService
+ * @param HotelRepository $hotelRepository
+ * @param ProductRepository $productRepository
+ * @param ProductDataService $productDataService
+ */
+ public function __construct
+ (
+ HotelDataService $hotelDataService,
+ HotelRepository $hotelRepository,
+ ProductRepository $productRepository,
+ ProductDataService $productDataService
+ )
+ {
+ $this->hotelRepository = $hotelRepository;
+ $this->productRepository = $productRepository;
+ $this->hotelDataService = $hotelDataService;
+ $this->productDataService = $productDataService;
+ }
+
+ /**
+ * @param Hotel $hotel
+ */
+ public function detailAction(?Hotel $hotel = null): ResponseInterface
+ {
+ if ($hotel !== null) {
+ $hotelUid = $hotel->getUid();
+ } else {
+ $hotelUid = ($this->settings['hotelUid'] ?? '');
+ /** @var Hotel $hotel */
+ $hotel = $this->hotelRepository->findByIdentifier($hotelUid);
+ }
+ $filterSettings = [
+ 'hotelUid' => $hotelUid,
+ ];
+ $excludedConceptUids = GeneralUtility::trimExplode(',', ($this->settings['excludedConceptUids'] ?? ''), true);
+ $limit = ($this->settings['hideMoreLink'] ?? '') ? 0 : 6;
+ $teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
+ $this->view->assign('hotel', $hotel);
+ $this->view->assign('teasers', $teasers);
+ $this->view->assign('filterSettings', $filterSettings);
+ return $this->htmlResponse();
+ }
+
+ public function detailEventAction(): ResponseInterface
+ {
+ $productUid = ($this->settings['productUid'] ?? '');
+ /** @var Product $product */
+ $product = $this->productRepository->findByIdentifier($productUid);
+ $hotelUid = ($this->settings['hotelUid'] ?? '');
+ /** @var Hotel $hotel */
+ $hotel = $this->hotelRepository->findByIdentifier($hotelUid);
+ $this->view->assignMultiple([
+ 'product' => $product,
+ 'hotel' => $hotel,
+ ]);
+ return $this->htmlResponse();
+ }
+
+ public function teasergroupAction(): ResponseInterface
+ {
+ $criteria = [
+ 'regionUid' => (int) ($this->settings['regionUid'] ?? ''),
+ 'countryUid' => (int) ($this->settings['countryUid'] ?? ''),
+ 'conceptUid' => (int) ($this->settings['conceptUid'] ?? ''),
+ 'productUid' => (int) ($this->settings['productUid'] ?? ''),
+ 'category' => (int) ($this->settings['category'] ?? ''),
+ 'type' => (int) ($this->settings['type'] ?? ''),
+ ];
+ $bookable = $this->hotelDataService->getTeasersByCriteria($criteria);
+ $bookableHotelUids = array_keys($bookable);
+ $nonBookable = $this->hotelDataService->getDateIndependentTeasersByCriteria($criteria, $bookableHotelUids);
+ $data = $this->request->getAttribute('currentContentObject')->data;
+ $this->view->assign('data', $data);
+ $this->view->assign('bookable', $bookable);
+ $this->view->assign('nonBookable', $nonBookable);
+ return $this->htmlResponse();
+ }
+
+ public function dateIndependentTeasergroupAction(): ResponseInterface
+ {
+ $criteria = [
+ 'regionUid' => (int) ($this->settings['regionUid'] ?? ''),
+ 'countryUid' => (int) ($this->settings['countryUid'] ?? ''),
+ 'productUid' => (int) ($this->settings['productUid'] ?? ''),
+ 'category' => (int) ($this->settings['category'] ?? ''),
+ 'type' => (int) ($this->settings['type'] ?? ''),
+ ];
+ $hotels = $this->hotelDataService->getDateIndependentTeasersByCriteria($criteria);
+ $data = $this->request->getAttribute('currentContentObject')->data;
+ $this->view->assign('data', $data);
+ $this->view->assign('teasers', $hotels);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/MapController.php b/packages/ep_products/Classes/Controller/MapController.php
new file mode 100644
index 0000000..bcc3dc2
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/MapController.php
@@ -0,0 +1,126 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\Hotel;
+use EP\EpProducts\Domain\Model\Product;
+use EP\EpProducts\Domain\Repository\HotelRepository;
+use EP\EpProducts\Domain\Repository\ProductRepository;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
+
+class MapController extends ActionController
+{
+
+ /**
+ * @var HotelRepository
+ */
+ protected $hotelRepository;
+
+ /**
+ * @var ProductRepository
+ */
+ protected $productRepository;
+
+ /**
+ * @param HotelRepository $hotelRepository
+ * @param ProductRepository $productRepository
+ */
+ public function __construct(
+ HotelRepository $hotelRepository,
+ ProductRepository $productRepository
+ )
+ {
+ $this->hotelRepository = $hotelRepository;
+ $this->productRepository = $productRepository;
+ }
+
+ public function generalAction(): ResponseInterface
+ {
+ $markerData = [];
+ $selectedHotels = ($this->settings['hotelUids'] ?? '');
+ $hotelUids = GeneralUtility::trimExplode(',', $selectedHotels);
+ $hotels = $this->hotelRepository->getListByUids($hotelUids);
+ if ($hotels) {
+ foreach ($hotels as $hotel)
+ {
+ /** @var Hotel $hotel */
+ $markerData[] = [
+ 'name' => $hotel->getName(),
+ 'uri' => $this->getUriForPageUid($hotel->getDetailPage()),
+ 'teaser' => $hotel->getTeaser(),
+ 'lat' => $hotel->getLatitude(),
+ 'lng' => $hotel->getLongitude(),
+ ];
+ }
+ }
+
+ $selectedProducts = ($this->settings['productUids'] ?? '');
+ $productUids = GeneralUtility::trimExplode(',', $selectedProducts);
+ $products = $this->productRepository->getListByUids($productUids);
+ if ($products) {
+ foreach ($products as $product)
+ {
+ /** @var Product $product */
+ $hotel = $product->getHotels()->current();
+ if (null === $hotel || false === $hotel->isShowAsTeaser()) {
+ continue;
+ }
+ $markerData[] = [
+ 'name' => $product->getName(),
+ 'uri' => $this->getUriForPageUid($product->getDetailPage()),
+ 'externalLink' => $hotel->getExternalLink(),
+ 'teaser' => preg_replace("/[\r\n\t]/", "", $product->getTeaser()),
+ 'lat' => $hotel->getLatitude(),
+ 'lng' => $hotel->getLongitude(),
+ ];
+ }
+ }
+
+ $data = $this->request->getAttribute('currentContentObject')->data;
+ $this->view->assign('data', $data);
+ $this->view->assign('markerData', json_encode($markerData, JSON_THROW_ON_ERROR | JSON_HEX_APOS));
+ return $this->htmlResponse();
+ }
+
+ /**
+ * @param int $pageUid
+ * @return string
+ */
+ protected function getUriForPageUid($pageUid)
+ {
+ /** @var ContentObjectRenderer $contentObject */
+ $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
+ return $contentObject->typoLink_URL(
+ [
+ 'parameter' => $pageUid,
+ ]
+ );
+ }
+}
diff --git a/packages/ep_products/Classes/Controller/PricetableController.php b/packages/ep_products/Classes/Controller/PricetableController.php
new file mode 100644
index 0000000..0b34e6a
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/PricetableController.php
@@ -0,0 +1,42 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class PricetableController extends ActionController
+{
+
+ public function eventAction(): ResponseInterface
+ {
+ $productUid = ($this->settings['productUid'] ?? '');
+ $this->view->assign('productUid', $productUid);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/RegionController.php b/packages/ep_products/Classes/Controller/RegionController.php
new file mode 100644
index 0000000..7cbe622
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/RegionController.php
@@ -0,0 +1,97 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\Region;
+use EP\EpProducts\Domain\Repository\RegionRepository;
+use EP\EpProducts\Service\ProductDataService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class RegionController extends ActionController
+{
+
+ /**
+ * @var RegionRepository
+ */
+ protected $regionRepository;
+
+ /**
+ * @var ProductDataService
+ */
+ protected $productDataService;
+
+ /**
+ * @param RegionRepository $regionRepository
+ * @param ProductDataService $productDataService
+ */
+ public function __construct(RegionRepository $regionRepository, ProductDataService $productDataService)
+ {
+ $this->regionRepository = $regionRepository;
+ $this->productDataService = $productDataService;
+ }
+
+ /**
+ * @param Region $region
+ */
+ public function detailAction(?Region $region = null): ResponseInterface
+ {
+ if ($region === null) {
+ $regionUid = ($this->settings['regionUid'] ?? '');
+ $region = $this->regionRepository->findByIdentifier($regionUid);
+ }
+ $additionalRegionUids = GeneralUtility::trimExplode(',', ($this->settings['additionalRegionUids'] ?? ''), true);
+ $additionalRegionUids = array_map(function ($uid) {
+ return (int)$uid;
+ }, $additionalRegionUids);
+ $teaserRegionUids = array_merge([$region->getUid()], $additionalRegionUids);
+ $filterSettings = [
+ 'regionUids' => $teaserRegionUids,
+ ];
+ $excludedConceptUids = GeneralUtility::trimExplode(',', ($this->settings['excludedConceptUids'] ?? ''), true);
+ $limit = ($this->settings['hideMoreLink'] ?? '') ? 0 : 6;
+ $teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
+ $this->view->assign('teasers', $teasers);
+ $this->view->assign('region', $region);
+ $this->view->assign('filterSettings', $filterSettings);
+ return $this->htmlResponse();
+ }
+
+ public function teasergroupAction(): ResponseInterface
+ {
+ $countryUid = (int)($this->settings['countryUid'] ?? '');
+ $season = ($this->settings['season'] ?? '');
+ $regionsPid = (int)($this->settings['regionsStoragePid'] ?? '');
+ $regions = $this->regionRepository->getTeasersByCountryAndSeason($countryUid, $season, $regionsPid);
+ $data = $this->request->getAttribute('currentContentObject')->data;
+ $this->view->assign('data', $data);
+ $this->view->assign('teasers', $regions);
+ return $this->htmlResponse();
+ }
+
+}
diff --git a/packages/ep_products/Classes/Controller/TeamController.php b/packages/ep_products/Classes/Controller/TeamController.php
new file mode 100644
index 0000000..a0446b4
--- /dev/null
+++ b/packages/ep_products/Classes/Controller/TeamController.php
@@ -0,0 +1,98 @@
+, 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 Psr\Http\Message\ResponseInterface;
+use EP\EpProducts\Domain\Model\Teammember;
+use EP\EpProducts\Domain\Repository\TeammemberRepository;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class TeamController extends ActionController
+{
+ /**
+ * @var TeammemberRepository
+ */
+ protected $teammemberRepository;
+
+ /**
+ * @param TeammemberRepository $teammemberRepository
+ */
+ public function __construct(TeammemberRepository $teammemberRepository)
+ {
+ $this->teammemberRepository = $teammemberRepository;
+ }
+
+ public function listAction(): ResponseInterface
+ {
+ if (isset($this->settings['teamCategories']) && count(GeneralUtility::trimExplode(',', ($this->settings['teamCategories'] ?? ''), true)) > 0) {
+ $members = $this->teammemberRepository->findByCategories(GeneralUtility::trimExplode(',', ($this->settings['teamCategories'] ?? ''), true));
+ } else {
+ $members = $this->teammemberRepository->findAll();
+ }
+
+ $this->view->assign('members', $members);
+ return $this->htmlResponse();
+ }
+
+ /**
+ * @param Teammember $member
+ * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
+ * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
+ */
+ public function showAction(?Teammember $member = null): ResponseInterface
+ {
+ if ($member === null) {
+ return $this->redirect('list', null, null, null, null, 0, 302);
+ }
+
+ $this->view->assign('member', $member);
+ $this->view->assign('data', $this->request->getAttribute('currentContentObject')->data);
+ $this->view->assign('header', $this->coalesceHeader($member));
+ return $this->htmlResponse();
+ }
+
+ /**
+ * @param Teammember $member
+ *
+ * @return string
+ */
+ public function coalesceHeader(Teammember $member)
+ {
+ $data = $this->request->getAttribute('currentContentObject')->data;
+ if (isset($data['header']) && $data['header'] !== '') {
+ return $data['header'];
+ }
+
+ $firstCategory = current($member->getCategories()->toArray());
+ if ($firstCategory !== null && $firstCategory !== false) {
+ return $firstCategory->getTitle();
+ }
+
+ return '';
+ }
+}
diff --git a/packages/ep_products/Classes/Domain/Repository/AbstractRepository.php b/packages/ep_products/Classes/Domain/Repository/AbstractRepository.php
index 20470f3..2fc7bb6 100644
--- a/packages/ep_products/Classes/Domain/Repository/AbstractRepository.php
+++ b/packages/ep_products/Classes/Domain/Repository/AbstractRepository.php
@@ -96,7 +96,7 @@ abstract class AbstractRepository extends Repository
protected function addHotelFilterConditions(QueryBuilder $qb, array $filterSettings): void
{
// Hotel
- if ($filterSettings['hotelUid'] > 0) {
+ if (($filterSettings['hotelUid'] ?? 0) > 0) {
$qb->andWhere($qb->expr()->eq(
'date.hotel',
$qb->createNamedParameter((int)$filterSettings['hotelUid'], Connection::PARAM_INT)
diff --git a/packages/ep_products/Classes/Domain/Repository/FaqRepository.php b/packages/ep_products/Classes/Domain/Repository/FaqRepository.php
new file mode 100644
index 0000000..c0fd724
--- /dev/null
+++ b/packages/ep_products/Classes/Domain/Repository/FaqRepository.php
@@ -0,0 +1,63 @@
+, 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\Faq;
+use Doctrine\DBAL\ArrayParameterType;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
+
+class FaqRepository extends AbstractRepository
+{
+
+ /**
+ * @param string $uids
+ * @return array
+ * @throws \Doctrine\DBAL\DBALException
+ */
+ public function findByUids($uids)
+ {
+ /** @var DataMapper $dataMapper */
+ $dataMapper = GeneralUtility::makeInstance(DataMapper::class);
+ $uids = GeneralUtility::intExplode(',', (string)$uids, true);
+ if ($uids === []) {
+ return [];
+ }
+ $qb = $this->getDbConnection()->createQueryBuilder();
+ $qb
+ ->select('*')
+ ->from('tx_epproducts_domain_model_faq')
+ ->where('uid IN (:uids)')
+ ->setParameter('uids', $uids, ArrayParameterType::INTEGER);
+ $qb->getConcreteQueryBuilder()->orderBy('FIELD(uid, ' . implode(',', $uids) . ')');
+ $rows = $qb->executeQuery()->fetchAllAssociative();
+
+ return $dataMapper->map(Faq::class, $rows);
+ }
+
+}
diff --git a/packages/ep_products/Classes/Domain/Repository/TeammemberRepository.php b/packages/ep_products/Classes/Domain/Repository/TeammemberRepository.php
new file mode 100644
index 0000000..55ae8b6
--- /dev/null
+++ b/packages/ep_products/Classes/Domain/Repository/TeammemberRepository.php
@@ -0,0 +1,54 @@
+, 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!
+ ***************************************************************/
+class TeammemberRepository extends AbstractRepository
+{
+ /**
+ * @var array
+ */
+ protected $defaultOrderings = [
+ 'sorting' => 'ASC',
+ ];
+
+ /**
+ * @param array $categories
+ * @return array|QueryResultInterface
+ * @throws InvalidQueryException
+ */
+ public function findByCategories(array $categories = [])
+ {
+ $qb = $this->createQuery();
+
+ $qb->matching($qb->in('categories.uid', $categories));
+
+ return $qb->execute();
+ }
+}
diff --git a/packages/ep_products/Classes/Service/HotelDataService.php b/packages/ep_products/Classes/Service/HotelDataService.php
index 9a37881..d8f9161 100644
--- a/packages/ep_products/Classes/Service/HotelDataService.php
+++ b/packages/ep_products/Classes/Service/HotelDataService.php
@@ -79,8 +79,7 @@ class HotelDataService implements SingletonInterface
$hotelData['available'] = -1; // TODO: Needs improvement. '-1' actually means: no price/date info available
}
- $hotelCategory = array_key_exists($hotelData['hotelCategory'], Hotel::$categoryLabels) ?
- Hotel::$categoryLabels[$hotelData['hotelCategory']] : null;
+ $hotelCategory = Hotel::$categoryLabels[$hotelData['hotelCategory'] ?? ''] ?? null;
$dateStart = new \DateTime($hotelData['dateStart'] ?? 'now');
$dateEnd = new \DateTime($hotelData['dateEnd'] ?? 'now');
@@ -147,7 +146,7 @@ class HotelDataService implements SingletonInterface
'minDateStart' => null,
'maxDateEnd' => null,
'minPrice' => null,
- 'pseudoPrice' => $row['pseudoPrice'],
+ 'pseudoPrice' => $row['pseudoPrice'] ?? null,
'available' => 0,
'detailPage' => $row['hotelDetailPage'],
'name' => $row['hotelName'],
@@ -159,16 +158,18 @@ class HotelDataService implements SingletonInterface
'code' => $row['countryCode'],
],
'region' => [
- 'name' => $row['regionName'],
+ 'name' => $row['regionName'] ?? null,
]
];
}
$teaser =& $teasers[$hotelUid];
- $teaser['available'] += $row['available'];
+ // Hotels without dates (date-independent teasers) have no date columns: as PHP 7.4 read
+ // them, they count as not available, with today as date and no price
+ $teaser['available'] += $row['available'] ?? 0;
- $dateStart = new \DateTime($row['dateStart']);
- $dateEnd = new \DateTime($row['dateEnd']);
+ $dateStart = new \DateTime($row['dateStart'] ?? 'now');
+ $dateEnd = new \DateTime($row['dateEnd'] ?? 'now');
if ($teaser['minDateStart'] === null || $teaser['minDateStart'] > $dateStart) {
$teaser['minDateStart'] = $dateStart;
@@ -178,8 +179,8 @@ class HotelDataService implements SingletonInterface
$teaser['maxDateEnd'] = $dateEnd;
}
- if ($teaser['minPrice'] === null || $teaser['minPrice'] > $row['minPrice']) {
- $teaser['minPrice'] = $row['minPrice'];
+ if ($teaser['minPrice'] === null || $teaser['minPrice'] > ($row['minPrice'] ?? null)) {
+ $teaser['minPrice'] = $row['minPrice'] ?? null;
}
}
diff --git a/packages/ep_products/Configuration/FlexForms/flexform_city_detail.xml b/packages/ep_products/Configuration/FlexForms/flexform_city_detail.xml
new file mode 100644
index 0000000..b7662ec
--- /dev/null
+++ b/packages/ep_products/Configuration/FlexForms/flexform_city_detail.xml
@@ -0,0 +1,35 @@
+
+
Ski-
Pass
inklusive
+Lage
+