diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/DateRepository.php b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/DateRepository.php index b2833dea..fe389c77 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/DateRepository.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/DateRepository.php @@ -2,43 +2,13 @@ namespace EP\EpProducts\Domain\Repository; -/*************************************************************** - * - * Copyright notice - * - * (c) 2016 Björn Fromme , 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\Product; use TYPO3\CMS\Core\Database\Connection; class DateRepository extends AbstractRepository { - /** - * @param Product $product - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getDateRange(Product $product = null) + public function getDateRange(Product $product = null): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -71,13 +41,7 @@ class DateRepository extends AbstractRepository return [$dateRangeFrom, $dateRangeTo]; } - /** - * @param string $search - * @param array $filterSettings - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function searchHotels($search, array $filterSettings) + public function searchHotels(string $search, array $filterSettings): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -98,6 +62,13 @@ class DateRepository extends AbstractRepository ]) ; + if (null !== $filterSettings['productsPid']) { + $qb->andWhere($qb->expr()->eq( + 'date.product_pid', + $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT)) + ); + } + $this->addDateFilterConditions($query, $filterSettings); $this->addDurationFilterConditions($query, $filterSettings); $this->addPaxFilterConditions($query, $filterSettings); @@ -106,14 +77,7 @@ class DateRepository extends AbstractRepository return $query->execute()->fetchAllAssociative(); } - /** - * @param string $search - * @param array $filterSettings - * @param array $excludedConceptUids - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function searchProducts($search, array $filterSettings, $excludedConceptUids = []) + public function searchProducts(string $search, array $filterSettings, array $excludedConceptUids = []): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -140,12 +104,20 @@ class DateRepository extends AbstractRepository ]) ; - if (count($excludedConceptUids) > 0) { - $qb - ->andWhere('concept NOT IN (:excludedConceptUids)') - ->setParameter('excludedConceptUids', $excludedConceptUids, Connection::PARAM_INT_ARRAY) - ; + if (null !== $filterSettings['productsPid']) { + $qb->andWhere($qb->expr()->eq( + 'date.product_pid', + $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT)) + ); } + + if (count($excludedConceptUids) > 0) { + $qb->andWhere($qb->expr()->notIn( + 'concept', + $qb->createNamedParameter($excludedConceptUids, Connection::PARAM_INT_ARRAY)) + ); + } + $this->addDateFilterConditions($query, $filterSettings); $this->addDurationFilterConditions($query, $filterSettings); $this->addPaxFilterConditions($query, $filterSettings); @@ -154,16 +126,12 @@ class DateRepository extends AbstractRepository return $query->execute()->fetchAllAssociative(); } - /** - * @param string $type - * @param string $search - * @param array $filterSettings - * @param array $excludedRegionUids - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function searchDestinations($type, $search, array $filterSettings, $excludedRegionUids = []) - { + public function searchDestinations( + string $type, + string $search, + array $filterSettings, + array $excludedRegionUids = [] + ): array { $qb = $this->getDbConnection()->createQueryBuilder(); $query = $qb @@ -183,6 +151,13 @@ class DateRepository extends AbstractRepository ]) ; + if (null !== $filterSettings['productsPid']) { + $qb->andWhere($qb->expr()->eq( + 'date.product_pid', + $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT)) + ); + } + $this->addDateFilterConditions($query, $filterSettings); $this->addDurationFilterConditions($query, $filterSettings); $this->addPaxFilterConditions($query, $filterSettings); diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php index 537fd9a5..a3983b57 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php @@ -2,31 +2,6 @@ namespace EP\EpProducts\Domain\Repository; -/*************************************************************** - * - * Copyright notice - * - * (c) 2016 Björn Fromme , 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\Date; use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Product; @@ -34,21 +9,14 @@ use TYPO3\CMS\Core\Database\Connection; class ProductRepository extends AbstractRepository { - - /** - * @param array $productUids - * @param array $hotelUids - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getWatchlist(array $productUids, array $hotelUids) + public function getWatchlist(array $productUids, array $hotelUids): array { $qb = $this->getDbConnection()->createQueryBuilder(); $query = $qb ->select( - 'date.concept as conceptUid', 'date.concept_name as conceptName', 'date.concept_code as conceptCode', - 'date.product as productUid', 'date.product_name as productName', + 'date.concept as conceptUid', 'date.concept_name as conceptName', + 'date.concept_code as conceptCode', 'date.product as productUid', 'date.product_name as productName', 'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature', 'date.country as countryUid','date.country_name as countryName', 'date.country_code as countryCode', 'date.region as regionUid', 'date.region_name as regionName', 'date.region_feature as regionFeature', @@ -61,35 +29,33 @@ class ProductRepository extends AbstractRepository 'date.pseudo_price as pseudoPrice' ) ->from('tx_epproducts_domain_model_date', 'date') - ->where('date.product IN (:productUids)') - ->andWhere('date.hotel IN (:hotelUids)') - ->andWhere('date.product_searchable = 1') + ->where($qb->expr()->in( + 'date.product', + $qb->createNamedParameter($productUids, Connection::PARAM_INT_ARRAY)) + ) + ->andWhere($qb->expr()->in( + 'date.hotel', + $qb->createNamedParameter($hotelUids, Connection::PARAM_INT_ARRAY)) + ) + ->andWhere($qb->expr()->eq('date.product_searchable', 1)) ->orderBy('date.concept_sorting') ->addOrderBy('date.product_name') ->addOrderBy('date.min_price') ->addOrderBy('date.date_start') ->addOrderBy('date.hotel_name') - ->setParameter('productUids', $productUids, Connection::PARAM_INT_ARRAY) - ->setParameter('hotelUids', $hotelUids, Connection::PARAM_INT_ARRAY) ; return $query->execute()->fetchAllAssociative(); } - /** - * @param array $filterSettings - * @param array $excludedConceptUids - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getSearchResult(array $filterSettings, $excludedConceptUids = []) + public function getSearchResult(array $filterSettings, array $excludedConceptUids = []): array { $qb = $this->getDbConnection()->createQueryBuilder(); $query = $qb ->select( - 'date.concept as conceptUid', 'date.concept_name as conceptName', 'date.concept_code as conceptCode', - 'date.concept_sorting as conceptSorting', + 'date.concept as conceptUid', 'date.concept_name as conceptName', + 'date.concept_code as conceptCode', 'date.concept_sorting as conceptSorting', 'date.product as productUid', 'date.product_name as productName', 'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature', 'date.daytrip as daytrip', 'date.country as countryUid','date.country_name as countryName', @@ -108,7 +74,7 @@ class ProductRepository extends AbstractRepository ) ->from('tx_epproducts_domain_model_date', 'date') ->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid') - ->where('date.product_searchable = 1') + ->where($qb->expr()->eq('date.product_searchable', 1)) ->andWhere('date.date_start >= NOW()') ->groupBy('date.product') ->addGroupBy('date.hotel') @@ -123,10 +89,10 @@ class ProductRepository extends AbstractRepository ; if (count($excludedConceptUids) > 0) { - $qb - ->andWhere('concept NOT IN (:excludedConceptUids)') - ->setParameter('excludedConceptUids', $excludedConceptUids, Connection::PARAM_INT_ARRAY) - ; + $qb->andWhere($qb->expr()->notIn( + 'concept', + $qb->createNamedParameter($excludedConceptUids, Connection::PARAM_INT_ARRAY)) + ); } $this->addFiltersettingsConditions($query, $filterSettings); @@ -134,14 +100,7 @@ class ProductRepository extends AbstractRepository return $query->execute()->fetchAllAssociative(); } - /** - * @param array $filterSettings - * @param array $excludedConceptUids - * @param int $limit - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getTeasers(array $filterSettings, $excludedConceptUids = [], $limit = 0) + public function getTeasers(array $filterSettings, array $excludedConceptUids = [], int $limit = 0): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -173,6 +132,13 @@ class ProductRepository extends AbstractRepository ->addOrderBy('date_start') ; + if (null !== $filterSettings['productsPid']) { + $qb->andWhere($qb->expr()->eq( + 'date.product_pid', + $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT)) + ); + } + if ($limit > 0) { $query->setMaxResults($limit); } @@ -180,10 +146,10 @@ class ProductRepository extends AbstractRepository if (empty($filterSettings['productUid'])) { $query->andWhere('product_searchable = 1'); } else { - $query - ->andWhere('product = :productUid') - ->setParameter('productUid', (int)$filterSettings['productUid']) - ; + $query->andWhere($qb->expr()->eq( + 'product', + $qb->createNamedParameter($filterSettings['productUid'], Connection::PARAM_INT)) + ); } $this->addDateFilterConditions($query, $filterSettings); @@ -193,24 +159,16 @@ class ProductRepository extends AbstractRepository $this->addTransportationFilterConditions($query, $filterSettings); if (count($excludedConceptUids) > 0) { - $qb - ->andWhere('concept NOT IN (:excludedConceptUids)') - ->setParameter('excludedConceptUids', $excludedConceptUids, Connection::PARAM_INT_ARRAY) - ; + $qb->andWhere($qb->expr()->notIn( + 'concept', + $qb->createNamedParameter($excludedConceptUids, Connection::PARAM_INT_ARRAY)) + ); } return $query->execute()->fetchAllAssociative(); } - /** - * @param Product $product - * @param Hotel $hotel - * @param array $filterSettings - * @param Date $date - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getPricetable(Product $product, Hotel $hotel, array $filterSettings, Date $date = null) + public function getPricetable(Product $product, Hotel $hotel, array $filterSettings, Date $date = null): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -229,19 +187,28 @@ class ProductRepository extends AbstractRepository ->addOrderBy('room.pax', 'ASC') ->addOrderBy('room.price', 'ASC') ->where('date.date_start >= NOW()') - ->andWhere('date.product = :product') - ->andWhere('date.hotel = :hotel') - ->setParameters([ - 'product' => $product->getUid(), - 'hotel' => $hotel->getUid(), - ]) + ->andWhere($qb->expr()->eq( + 'date.product', + $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT)) + ) + ->andWhere($qb->expr()->eq( + 'date.hotel', + $qb->createNamedParameter($hotel->getUid(), Connection::PARAM_INT)) + ) ; + if (null !== $filterSettings['productsPid']) { + $qb->andWhere($qb->expr()->eq( + 'date.product_pid', + $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT)) + ); + } + if ($date !== null) { - $query - ->andWhere('date.uid = :date') - ->setParameter('date', $date->getUid()) - ; + $query->andWhere($qb->expr()->eq( + 'date.uid', + $qb->createNamedParameter($date->getUid(), Connection::PARAM_INT)) + ); } $this->addFiltersettingsConditions($query, $filterSettings); @@ -249,14 +216,7 @@ class ProductRepository extends AbstractRepository return $query->execute()->fetchAllAssociative(); } - /** - * @param Product $product - * @param Hotel $hotel - * @param array $filterSettings - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getAvailableDates(Product $product, Hotel $hotel, array $filterSettings) + public function getAvailableDates(Product $product, Hotel $hotel, array $filterSettings): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -275,49 +235,49 @@ class ProductRepository extends AbstractRepository ->orderBy('date.date_start', 'ASC') ->addOrderBy('date.min_price', 'ASC') ->where('date.date_start >= NOW()') - ->andWhere('date.product = :product') - ->andWhere('date.hotel = :hotel') + ->andWhere($qb->expr()->eq( + 'date.product', + $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT)) + ) + ->andWhere($qb->expr()->eq( + 'date.hotel', + $qb->createNamedParameter($hotel->getUid(), Connection::PARAM_INT)) + ) ->groupBy('date.date_start') - ->setParameters([ - 'product' => $product->getUid(), - 'hotel' => $hotel->getUid(), - ]) ; + if (null !== $filterSettings['productsPid']) { + $qb->andWhere($qb->expr()->eq( + 'date.product_pid', + $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT)) + ); + } + $this->addFiltersettingsConditions($query, $filterSettings, true); return $query->execute()->fetchAllAssociative(); } - /** - * @param Product $product - * @return bool - * @throws \Doctrine\DBAL\DBALException - */ - public function hasDates(Product $product) + public function hasDates(Product $product): bool { $qb = $this->getDbConnection()->createQueryBuilder(); - $query = $qb + $result = $qb ->select('date.uid') ->from('tx_epproducts_domain_model_date', 'date') - ->where('date.product = :product') - ->setParameter('product', $product->getUid()) + ->where($qb->expr()->eq( + 'date.product', + $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT)) + ) ->setMaxResults(1) ->execute() - ->fetchColumn() + ->fetchOne() ; - return $query !== false; + return $result !== false; } - /** - * @param Product $product - * @param Hotel $hotel - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getDatesForExport(Product $product, Hotel $hotel) + public function getDatesForExport(Product $product, Hotel $hotel): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -337,23 +297,20 @@ class ProductRepository extends AbstractRepository ->orderBy('date.date_start', 'ASC') ->addOrderBy('date.min_price', 'ASC') ->where('date.date_start >= NOW()') - ->andWhere('date.product = :product') - ->andWhere('date.hotel = :hotel') - ->setParameters([ - 'product' => $product->getUid(), - 'hotel' => $hotel->getUid(), - ]) + ->andWhere($qb->expr()->eq( + 'date.product', + $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT)) + ) + ->andWhere($qb->expr()->eq( + 'date.hotel', + $qb->createNamedParameter($hotel->getUid(), Connection::PARAM_INT)) + ) ; return $query->execute()->fetchAllAssociative(); } - /** - * @param Product $product - * @return array - * @throws \Doctrine\DBAL\DBALException - */ - public function getEventPriceTable(Product $product) + public function getEventPriceTable(Product $product): array { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -369,8 +326,10 @@ class ProductRepository extends AbstractRepository ->from('tx_epproducts_domain_model_date', 'date') ->innerJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid') ->innerJoin('date', 'tx_epproducts_domain_model_hotel', 'hotel', 'hotel.uid = date.hotel') - ->where('date.product = :productUid') - ->setParameter('productUid', $product->getUid()) + ->where($qb->expr()->eq( + 'date.product', + $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT)) + ) ; return $query->execute()->fetchAllAssociative(); diff --git a/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php b/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php index fa23c414..a0c66c50 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php @@ -116,7 +116,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @return int * @throws \Doctrine\DBAL\DBALException */ - public function import($path) + public function import($path): int { $this->db = $this->getDbConnection(); $this->getRoomMappings(); @@ -129,6 +129,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface $this->copyTables(); $this->clearTempTables(); $this->cacheService->clearPageCache(); + return $dateCount; } @@ -147,13 +148,14 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * * @return bool */ - public function checkActiveUpload($path) + public function checkActiveUpload($path): bool { $tempFile = $path . '/.pureftpd-upload.*'; + return count(glob($tempFile)) > 0; } - public function parseXmlFilesForProducts($path) + public function parseXmlFilesForProducts($path): int { $dateCount = 0; @@ -172,7 +174,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param string $file * @return int */ - public function parseProductXmlFile($file) + public function parseProductXmlFile($file): int { if (!file_exists($file)) { $this->logger->error('product xml not found', ['file' => $file]); @@ -193,60 +195,50 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface return $this->parseProduct($xmlData->reise[0]); } - /** - * @throws \Doctrine\DBAL\DBALException - */ - public function createTempTables() + public function createTempTables(): void { - $this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_date_temp LIKE tx_epproducts_domain_model_date'); - $this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_room_temp LIKE tx_epproducts_domain_model_room'); + $this->db->executeStatement('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_date_temp LIKE tx_epproducts_domain_model_date'); + $this->db->executeStatement('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_room_temp LIKE tx_epproducts_domain_model_room'); } - /** - * @throws \Doctrine\DBAL\DBALException - */ - public function clearTables() + public function clearTables(): void { - $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_date'); - $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_room'); + $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_date'); + $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_room'); } - /** - * @throws \Doctrine\DBAL\DBALException - */ - public function copyTables() + public function copyTables(): void { - $this->db->exec('INSERT INTO tx_epproducts_domain_model_date SELECT * FROM tx_epproducts_domain_model_date_temp'); - $this->db->exec('INSERT INTO tx_epproducts_domain_model_room SELECT * FROM tx_epproducts_domain_model_room_temp'); + $this->db->executeStatement('INSERT INTO tx_epproducts_domain_model_date SELECT * FROM tx_epproducts_domain_model_date_temp'); + $this->db->executeStatement('INSERT INTO tx_epproducts_domain_model_room SELECT * FROM tx_epproducts_domain_model_room_temp'); } - /** - * @throws \Doctrine\DBAL\DBALException - */ - public function clearTempTables() + public function clearTempTables(): void { - $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_date_temp'); - $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_room_temp'); + $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_date_temp'); + $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_room_temp'); } /** * @param \SimpleXMLElement $xmlProduct * @return int */ - protected function parseProduct(\SimpleXMLElement $xmlProduct) + protected function parseProduct(\SimpleXMLElement $xmlProduct): int { $code = (string) $xmlProduct->attributes()['code']; $busProId = (int) $xmlProduct->attributes()['idbuspro']; $dateCount = 0; $sql = ' - SELECT p.uid uid, p.daytrip daytrip, p.hide_booking_button, p.important important, p.name product_name, - p.searchable product_searchable, p.detail_page product_detail_page, p.keywords product_keywords, - p.teaser product_teaser, p.feature product_feature, p.subline product_subline, p.country country, - p.region region, p.city city, p.path_segment slug, p.season season, - cnt.name country_name, cnt.code country_code, cnt.keywords country_keywords, r.name region_name, - r.keywords region_keywords, r.feature region_feature, c.name city_name, c.keywords city_keywords, - p.concept concept, con.name concept_name, con.code concept_code, con.sorting concept_sorting + SELECT p.uid uid, p.pid pid, p.daytrip daytrip, p.hide_booking_button, p.important important, + p.name product_name, p.searchable product_searchable, p.detail_page product_detail_page, + p.keywords product_keywords, p.teaser product_teaser, p.feature product_feature, + p.subline product_subline, p.country country, p.region region, p.city city, p.path_segment slug, + p.season season, p.concept concept, + cnt.name country_name, cnt.code country_code, cnt.keywords country_keywords, r.name region_name, + r.keywords region_keywords, r.feature region_feature, + c.name city_name, c.keywords city_keywords, + con.name concept_name, con.code concept_code, con.sorting concept_sorting FROM tx_epproducts_domain_model_product p INNER JOIN tx_epproducts_domain_model_country cnt ON p.country = cnt.uid INNER JOIN tx_epproducts_domain_model_region r ON p.region = r.uid @@ -285,7 +277,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param array $product * @return int */ - protected function parseDates(\SimpleXMLElement $xmlDate, array $product) + protected function parseDates(\SimpleXMLElement $xmlDate, array $product): int { $dateCount = 0; foreach ($xmlDate->hotel as $xmlHotel) { @@ -328,7 +320,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param \SimpleXMLElement $xmlDate * @return array */ - protected function createDateRecord(array $product, \SimpleXMLElement $xmlDate) + protected function createDateRecord(array $product, \SimpleXMLElement $xmlDate): array { $dateStart = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['termin']); $dateEnd = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['bis']); @@ -340,6 +332,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface $date = [ 'pid' => $this->pid, 'product' => $product['uid'], + 'product_pid' => $product['pid'], 'product_name' => $product['product_name'], 'product_fact' => $product['product_fact'], 'product_searchable' => $product['product_searchable'], @@ -480,13 +473,14 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param array $date * @return bool */ - protected function parseHotel(\SimpleXMLElement $xmlHotel, array &$date) + protected function parseHotel(\SimpleXMLElement $xmlHotel, array &$date): bool { $code = (string) $xmlHotel->attributes()['code']; $busProId = (string) $xmlHotel->attributes()['idbuspro']; if (!array_key_exists($code, $this->hotelMappings)) { $this->logger->warning('hotel not found', ['code' => $code]); + return false; } @@ -520,6 +514,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface $date['hotel_detail_page'] = $hotel['detail_page']; $date['earlybird'] = $hotel['earlybird']; $date['new'] = $hotel['new']; + return true; } @@ -529,7 +524,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param array $date * @param array $services */ - protected function parseRooms(\SimpleXMLElement $xmlHotel, $hotelUid, array &$date, array $services) + protected function parseRooms(\SimpleXMLElement $xmlHotel, $hotelUid, array &$date, array $services): void { $minPriceOverall = 0; $minPriceAvailable = 0; @@ -557,10 +552,6 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface $available = (int) $roomXml->attributes()['verfuegbar']; $price = (int) $roomXml->attributes()['preis']; - // Skip all unavailable rooms -// if (!$available) { -// continue; -// } // Skip rooms with zero price _and_ zero availability. if (!$available && !$price) { continue; @@ -623,7 +614,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param array $services * @return int */ - protected function determineDiscount(array $services) + protected function determineDiscount(array $services): int { foreach ($services as $key => $section) { foreach ($section as $service) { @@ -642,7 +633,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param bool $skipWithoutPrice * @return array */ - protected function parseService(\SimpleXMLElement $xmlData, $serviceLabel, $skipWithoutPrice = false) + protected function parseService(\SimpleXMLElement $xmlData, string $serviceLabel, bool $skipWithoutPrice = false): array { $data = []; $services = $xmlData->xpath($serviceLabel . '/leistung'); @@ -703,7 +694,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param string $label * @return array */ - protected function parseSelectionGroup(\SimpleXMLElement $xmlDate, $label) + protected function parseSelectionGroup(\SimpleXMLElement $xmlDate, string $label): array { $data = []; $selectionGroup = $xmlDate->xpath('selektiongruppe[@bezeichnung="' . $label . '"]/selektion'); @@ -725,7 +716,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param array $services * @param array $date */ - protected function processBusConditions(array $services, array &$date) + protected function processBusConditions(array $services, array &$date): void { if (!array_key_exists('BUS', $services)) { return; @@ -738,7 +729,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface } } - protected function getRoomMappings() + protected function getRoomMappings(): void { $sql = 'SELECT code, type FROM tx_epproducts_domain_model_roommapping'; $roomMappings = $this->db->fetchAllAssociative($sql); @@ -747,7 +738,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface } } - protected function getHotelMappings() + protected function getHotelMappings(): void { $sql = ' SELECT u.code code, u.uid uid, h.name name, h.type type, @@ -787,9 +778,9 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface /** * @param string $table * @param int $uid - * @return array + * @return string */ - protected function getTopFactForRecord($table, $uid) + protected function getTopFactForRecord($table, $uid): string { $sql = ' SELECT f.name @@ -807,7 +798,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface * @param array $services * @param array $list */ - protected function addServices(array $services, array &$list) + protected function addServices(array $services, array &$list): void { foreach ($services as $key => $section) { if (!array_key_exists($key, $list)) { @@ -817,7 +808,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface } } - protected function importPickups() + protected function importPickups(): void { libxml_use_internal_errors (true); $path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport/zustiege.xml'); diff --git a/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php b/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php index 649543bb..d6150405 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/FilterService.php @@ -33,6 +33,7 @@ use EP\EpProducts\Domain\Repository\DateRepository; use Symfony\Component\OptionsResolver\OptionsResolver; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; class FilterService implements SingletonInterface { @@ -45,11 +46,18 @@ class FilterService implements SingletonInterface protected $dateRepository; /** - * @param DateRepository $dateRepository + * @var ConfigurationManagerInterface */ - public function __construct(DateRepository $dateRepository) + protected $configurationManager; + + /** + * @param DateRepository $dateRepository + * @param ConfigurationManagerInterface $configurationManager + */ + public function __construct(DateRepository $dateRepository, ConfigurationManagerInterface $configurationManager) { $this->dateRepository = $dateRepository; + $this->configurationManager = $configurationManager; } public function getNormalizedFilterSettings(array $filterSettings = [], array $forcedConceptUids = []): array @@ -79,6 +87,9 @@ class FilterService implements SingletonInterface array_push($filterSettings['conceptUids'], ...$forcedConceptUids); } + $typoScriptSettings = $this->getTypoScriptSettings(); + $filterSettings['productsPid'] = $typoScriptSettings['productsPid'] ?? null; + return $filterSettings; } @@ -323,4 +334,14 @@ class FilterService implements SingletonInterface return $filterSettings; } + + protected function getTypoScriptSettings(): array + { + $settings = $this + ->configurationManager + ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT); + + return $settings['plugin.']['tx_epproducts.']['settings.']; + } + } diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index 81c1a2a8..9c4e4db5 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -24,6 +24,7 @@ plugin.tx_epproducts { } } settings { + productsPid = {$plugin.tx_epproducts.settings.productsStoragePid} destinationsStoragePid = {$plugin.tx_epproducts.settings.destinationsStoragePid} snowReportStoragePid = {$plugin.tx_epproducts.settings.snowReportStoragePid} defaultSearchPageUid = {$plugin.tx_epproducts.settings.defaultSearchPageUid} diff --git a/public/typo3conf/ext/ep_products/ext_tables.sql b/public/typo3conf/ext/ep_products/ext_tables.sql index 170ea8bd..fdb72387 100644 --- a/public/typo3conf/ext/ep_products/ext_tables.sql +++ b/public/typo3conf/ext/ep_products/ext_tables.sql @@ -123,6 +123,7 @@ CREATE TABLE tx_epproducts_domain_model_date pseudo_price int(11) DEFAULT '0' NOT NULL, available int(11) DEFAULT '0' NOT NULL, product int(11) unsigned DEFAULT '0', + product_pid int(11) unsigned DEFAULT '0', daytrip tinyint(1) unsigned DEFAULT '0' NOT NULL, hide_booking_button tinyint(1) unsigned DEFAULT '0' NOT NULL, important tinyint(1) unsigned DEFAULT '0' NOT NULL, @@ -189,7 +190,7 @@ CREATE TABLE tx_epproducts_domain_model_date l10n_diffsource mediumblob, PRIMARY KEY (uid), - KEY parent (pid), + KEY parent (pid, product_pid), KEY t3ver_oid (t3ver_oid, t3ver_wsid), KEY language (l10n_parent, sys_language_uid), KEY aggregates (date_start, date_end, min_price),