From 600cf8f3cbe35506453a8bd15bdb62e6f72e6e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Tue, 1 Jul 2025 10:45:07 +0200 Subject: [PATCH] fix: limit hotels to configured folder when importing contingents --- .../Service/ContingentImportService.php | 73 +++++++++++-------- .../Configuration/TypoScript/setup.typoscript | 1 + 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/public/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php b/public/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php index 1ae0d231..bf99af8e 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php @@ -47,7 +47,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac /** * @var string[] */ -// protected $ignoredRoomTypes = ['PDGS', 'TEAM']; + // protected $ignoredRoomTypes = ['PDGS', 'TEAM']; protected $ignoredRoomTypes = ['PDGS']; /** @@ -58,7 +58,12 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac /** * @var int */ - protected $pid = 0; + protected $contingentsPid = 0; + + /** + * @var int + */ + protected $hotelsPid = 0; /** * @var Connection @@ -66,7 +71,6 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac protected $db; /** - * @param ConfigurationManagerInterface $manager * @throws \Doctrine\DBAL\DBALException */ public function __construct(ConfigurationManagerInterface $manager) @@ -76,16 +80,25 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $settings = GeneralUtility::removeDotsFromTS( $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT) ); + if (isset($settings['plugin']['tx_epproducts']['persistence']['storagePid'])) { - $this->pid = $settings['plugin']['tx_epproducts']['persistence']['storagePid']; + $this->contingentsPid = $settings['plugin']['tx_epproducts']['persistence']['storagePid']; } elseif (isset($settings['module']['tx_epproducts']['persistence']['storagePid'])) { - $this->pid = $settings['module']['tx_epproducts']['persistence']['storagePid']; + $this->contingentsPid = $settings['module']['tx_epproducts']['persistence']['storagePid']; } + + if (isset($settings['plugin']['tx_epproducts']['settings']['hotelsPid'])) { + $this->hotelsPid = $settings['plugin']['tx_epproducts']['settings']['hotelsPid']; + } elseif (isset($settings['module']['tx_epproducts']['settings']['hotelsPid'])) { + $this->hotelsPid = $settings['module']['tx_epproducts']['settings']['hotelsPid']; + } + $this->db = $this->getDbConnection(); } /** * @return int + * * @throws \Doctrine\DBAL\DBALException */ public function import() @@ -96,6 +109,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $this->clearTable(); $this->copyTable(); $this->clearTempTable(); + return $contingentCount; } @@ -118,7 +132,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $path = GeneralUtility::getFileAbsFileName(self::XML_PATH); $folder = opendir($path); while (($fileName = readdir($folder)) !== false) { - if (strpos($fileName, 'HotelZimmer') === 0) { + if (0 === strpos($fileName, 'HotelZimmer')) { $dateCount += $this->parseContingentXmlFile($path, $fileName); } } @@ -128,11 +142,12 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac /** * @param string $fileName + * * @return int */ public function parseContingentXmlFile($path, $fileName) { - $filePath = sprintf('%s/%s', $path , $fileName); + $filePath = sprintf('%s/%s', $path, $fileName); if (null === $xmlData = $this->loadXmlFile($filePath)) { return 0; @@ -143,13 +158,14 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac public function loadXmlFile($file): ?\SimpleXMLElement { - libxml_use_internal_errors (true); + libxml_use_internal_errors(true); if (!file_exists($file)) { return null; } /** @var \SimpleXMLElement $xmlData */ if (!$xmlData = simplexml_load_string(file_get_contents($file))) { libxml_clear_errors(); + return null; } @@ -161,7 +177,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac */ public function createTempTable() { - $this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_contingent_temp LIKE tx_epproducts_domain_model_contingent'); + $this->db->executeStatement('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_contingent_temp LIKE tx_epproducts_domain_model_contingent'); } /** @@ -169,7 +185,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac */ public function clearTable() { - $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_contingent'); + $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_contingent'); } /** @@ -177,7 +193,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac */ public function copyTable() { - $this->db->exec('INSERT INTO tx_epproducts_domain_model_contingent SELECT * FROM tx_epproducts_domain_model_contingent_temp'); + $this->db->executeStatement('INSERT INTO tx_epproducts_domain_model_contingent SELECT * FROM tx_epproducts_domain_model_contingent_temp'); } /** @@ -185,11 +201,10 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac */ public function clearTempTable() { - $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_contingent_temp'); + $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_contingent_temp'); } /** - * @param \SimpleXMLElement $xmlContingent * @return int */ protected function parseContingent(\SimpleXMLElement $xmlContingent) @@ -197,14 +212,14 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $hotelCode = (string) $xmlContingent['code']; $sql = 'SELECT h.uid uid FROM tx_epproducts_domain_model_hotel h - LEFT JOIN tx_epproducts_domain_model_matchcode m ON (h.uid = m.entity AND m.entity_type = "hotel" AND m.deleted = 0) - WHERE h.deleted = 0 AND h.hidden = 0 AND h.code = :code OR m.code = :code + WHERE h.deleted = 0 AND h.hidden = 0 AND h.code = :code AND h.pid = :pid LIMIT 0,1'; - $hotelData = $this->db->fetchAssoc($sql, ['code' => $hotelCode]); + $hotelData = $this->db->fetchAssociative($sql, ['code' => $hotelCode, 'pid' => $this->hotelsPid]); // Skip import in case hotel can't be found - if ($hotelData === false) { + if (false === $hotelData) { $this->logger->warning('hotel not found', ['code' => $hotelCode]); + return 0; } @@ -212,7 +227,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $hotelData['code'] = (string) $xmlContingent['code']; if ($xmlContingent->idbuspro_kontingent_aus) { - $linkedProductId = (int)$xmlContingent->idbuspro_kontingent_aus; + $linkedProductId = (int) $xmlContingent->idbuspro_kontingent_aus; $path = GeneralUtility::getFileAbsFileName(self::XML_PATH); if (null === $xmlContingent = $this->loadXmlFile(sprintf('%s/HotelZimmer_%d.xml', $path, $linkedProductId))) { return 0; @@ -221,6 +236,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac if (empty($xmlContingent->kapazitaeten)) { $this->logger->warning('hotel has no contingents', ['code' => $hotelCode]); + return 0; } @@ -231,31 +247,30 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac /** * @param \SimpleXMLElement $xmlTypes + * * @return array */ protected function parseRoomTypes($xmlTypes) { $types = []; - foreach ($xmlTypes->unterbringung as $xmlType) - { + foreach ($xmlTypes->unterbringung as $xmlType) { $idBusPro = (string) $xmlType['idbuspro']; $code = (string) $xmlType['code']; $types[] = [ 'idBusPro' => $idBusPro, 'link' => isset($xmlType['idbuspro_kontingent_aus']) ? (string) $xmlType['idbuspro_kontingent_aus'] : null, - 'pax' => (int) $xmlType['pax_max'], + 'pax' => (int) $xmlType['pax_max'], 'code' => $code, 'label' => (string) $xmlType['zimmerbezeichnung'], - 'ctrl' => $code === self::ROOMCODE_STATUS, + 'ctrl' => self::ROOMCODE_STATUS === $code, ]; } + return $types; } /** * @param \SimpleXMLElement|\SimpleXMLElement[] $xmlDates - * @param array $hotelData - * @param array $roomTypes * * @return int */ @@ -277,7 +292,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac } $this->calculateContingent($xmlRoom, $roomType, $date, $hotelData); } - $dateCount++; + ++$dateCount; } return $dateCount; @@ -288,10 +303,10 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $availablePax = 0; $capacity = 0; $status = Contingent::STATUS_OK; - $isControlRoom = $roomType['ctrl'] === true; - if ($isControlRoom && (string) $xmlRoom['status'] === 'A') { + $isControlRoom = true === $roomType['ctrl']; + if ($isControlRoom && 'A' === (string) $xmlRoom['status']) { $status = Contingent::STATUS_ONREQUEST; - } elseif ($isControlRoom && (string) $xmlRoom['status'] === 'S') { + } elseif ($isControlRoom && 'S' === (string) $xmlRoom['status']) { $status = Contingent::STATUS_BLOCKED; } else { $capacity = (int) $xmlRoom['kontingent'] * (int) $roomType['pax']; @@ -306,7 +321,7 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac $this->db->insert( 'tx_epproducts_domain_model_contingent_temp', [ - 'pid' => $this->pid, + 'pid' => $this->contingentsPid, 'hotel' => $hotelData['uid'], 'hotel_code' => $hotelData['code'], 'hotel_bus_pro_id' => $hotelData['busProId'], diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index 389db905..4e2411fc 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -25,6 +25,7 @@ plugin.tx_epproducts { } settings { productsPid = {$plugin.tx_epproducts.settings.productsStoragePid} + hotelsPid = {$plugin.tx_epproducts.settings.hotelsStoragePid} destinationsStoragePid = {$plugin.tx_epproducts.settings.destinationsStoragePid} regionsStoragePid = {$plugin.tx_epproducts.settings.regionsStoragePid} citiesStoragePid = {$plugin.tx_epproducts.settings.citiesStoragePid}