diff --git a/CHANGELOG-7.3.md b/CHANGELOG-7.3.md index 16280404cd..feb0aac46a 100644 --- a/CHANGELOG-7.3.md +++ b/CHANGELOG-7.3.md @@ -16,6 +16,7 @@ - Raised minimum required version of Symfony components to 6.4 - Set the default value of blSkipDebitOldBankInfo to true - Add to basket does not force a refresh of order confirmation step [#0007254](https://bugs.oxid-esales.com/view.php?id=7254) +- Optimized module installation/uninstallation process ### Removed - PHPUnit v10 support diff --git a/source/Application/Controller/Admin/ModuleSortList.php b/source/Application/Controller/Admin/ModuleSortList.php index e0169f4358..f3f1d3e553 100644 --- a/source/Application/Controller/Admin/ModuleSortList.php +++ b/source/Application/Controller/Admin/ModuleSortList.php @@ -8,8 +8,12 @@ namespace OxidEsales\EshopCommunity\Application\Controller\Admin; use OxidEsales\Eshop\Core\Registry; +use OxidEsales\EshopCommunity\Core\Di\ContainerFacade; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ShopConfigurationDaoBridgeInterface; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\ClassExtensionsChainDaoInterface; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ClassExtensionsChain; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ShopConfiguration; +use OxidEsales\EshopCommunity\Internal\Transition\Utility\ContextInterface; /** * Extensions sorting list handler. @@ -72,16 +76,10 @@ public function save() $sanitizedClassExtensionsChain = $this->sanitizeClassExtensionsChain($classExtensionsChainFromRequest); - $container = $this->getContainer(); - $shopConfigurationDao = $container->get(ShopConfigurationDaoBridgeInterface::class); - $shopConfiguration = $shopConfigurationDao->get(); - - $chain = $shopConfiguration->getClassExtensionsChain(); - $chain->setChain($sanitizedClassExtensionsChain); - - $shopConfiguration->setClassExtensionsChain($chain); - - $shopConfigurationDao->save($shopConfiguration); + ContainerFacade::get(ClassExtensionsChainDaoInterface::class)->saveChain( + ContainerFacade::get(ContextInterface::class)->getCurrentShopId(), + new ClassExtensionsChain($sanitizedClassExtensionsChain) + ); } /** diff --git a/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridge.php b/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridge.php index e33982d799..82cf1df8e9 100644 --- a/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridge.php +++ b/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridge.php @@ -10,7 +10,6 @@ namespace OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\ShopConfigurationDaoInterface; -use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\ModuleEnvironmentConfigurationDaoInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ShopConfiguration; use OxidEsales\EshopCommunity\Internal\Transition\Utility\ContextInterface; @@ -22,9 +21,6 @@ public function __construct( ) { } - /** - * @return ShopConfiguration - */ public function get(): ShopConfiguration { return $this->shopConfigurationDao->get( @@ -32,9 +28,6 @@ public function get(): ShopConfiguration ); } - /** - * @param ShopConfiguration $shopConfiguration - */ public function save(ShopConfiguration $shopConfiguration) { $this->shopConfigurationDao->save( diff --git a/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridgeInterface.php b/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridgeInterface.php index 059117d8ef..b45d1a0ab5 100644 --- a/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridgeInterface.php +++ b/source/Internal/Framework/Module/Configuration/Bridge/ShopConfigurationDaoBridgeInterface.php @@ -17,13 +17,10 @@ */ interface ShopConfigurationDaoBridgeInterface { - /** - * @return ShopConfiguration - */ public function get(): ShopConfiguration; /** - * @param ShopConfiguration $shopConfiguration + * @deprecated use ModuleConfigurationDaoInterface::save() and ClassExtensionsChainDaoInterface::saveChain() instead */ public function save(ShopConfiguration $shopConfiguration); } diff --git a/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDao.php b/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDao.php index 0784d32e5b..65b591d739 100644 --- a/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDao.php +++ b/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDao.php @@ -95,6 +95,11 @@ public function deleteAll(int $shopId): void $this->filesystem->remove($this->getModulesConfigurationDirectory($shopId)); } + public function delete(string $moduleId, int $shopId): void + { + $this->filesystem->remove($this->getModuleConfigurationFilePath($shopId, $moduleId)); + } + public function exists(string $moduleId, int $shopId): bool { return in_array($moduleId, $this->getModuleIds($shopId), true); diff --git a/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoInterface.php b/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoInterface.php index 6720710e63..970dbeb5d3 100644 --- a/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoInterface.php +++ b/source/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoInterface.php @@ -13,19 +13,12 @@ interface ModuleConfigurationDaoInterface { - /** - * @param string $moduleId - * @param int $shopId - * @return ModuleConfiguration - */ public function get(string $moduleId, int $shopId): ModuleConfiguration; - /** - * @param ModuleConfiguration $moduleConfiguration - * @param int $shopId - */ public function save(ModuleConfiguration $moduleConfiguration, int $shopId); + public function delete(string $moduleId, int $shopId): void; + /** * @param int $shopId * @return ModuleConfiguration[] diff --git a/source/Internal/Framework/Module/Configuration/Dao/ShopConfigurationDaoInterface.php b/source/Internal/Framework/Module/Configuration/Dao/ShopConfigurationDaoInterface.php index 23d542c203..0208aa7219 100644 --- a/source/Internal/Framework/Module/Configuration/Dao/ShopConfigurationDaoInterface.php +++ b/source/Internal/Framework/Module/Configuration/Dao/ShopConfigurationDaoInterface.php @@ -21,8 +21,7 @@ interface ShopConfigurationDaoInterface public function get(int $shopId): ShopConfiguration; /** - * @param ShopConfiguration $shopConfiguration - * @param int $shopId + * @deprecated use ModuleConfigurationDaoInterface::save() and ClassExtensionsChainDaoInterface::saveChain() instead */ public function save(ShopConfiguration $shopConfiguration, int $shopId): void; diff --git a/source/Internal/Framework/Module/Configuration/bootstrap-services.yaml b/source/Internal/Framework/Module/Configuration/bootstrap-services.yaml index 42bdf4f7e4..f923005b80 100644 --- a/source/Internal/Framework/Module/Configuration/bootstrap-services.yaml +++ b/source/Internal/Framework/Module/Configuration/bootstrap-services.yaml @@ -12,6 +12,7 @@ services: OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\ClassExtensionsChainDaoInterface: class: OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\ClassExtensionsChainDao + public: true OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\TemplateExtensionChainDaoInterface: class: OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\TemplateExtensionChainDao diff --git a/source/Internal/Framework/Module/Install/Service/ModuleConfigurationInstaller.php b/source/Internal/Framework/Module/Install/Service/ModuleConfigurationInstaller.php index 4b3ca89cc0..e47530d447 100644 --- a/source/Internal/Framework/Module/Install/Service/ModuleConfigurationInstaller.php +++ b/source/Internal/Framework/Module/Install/Service/ModuleConfigurationInstaller.php @@ -9,9 +9,11 @@ namespace OxidEsales\EshopCommunity\Internal\Framework\Module\Install\Service; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\ClassExtensionsChainDaoInterface; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\ModuleConfigurationDaoInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\ShopConfigurationDaoInterface; -use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Exception\ModuleConfigurationNotFoundException; -use OxidEsales\EshopCommunity\Internal\Framework\Module\MetaData\Dao\ModuleConfigurationDaoInterface; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ModuleConfiguration; +use OxidEsales\EshopCommunity\Internal\Framework\Module\MetaData\Dao\ModuleConfigurationDaoInterface as MetadataDaoInterface; use OxidEsales\EshopCommunity\Internal\Transition\Utility\BasicContextInterface; use Symfony\Component\Filesystem\Path; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Service\{ @@ -24,81 +26,69 @@ public function __construct( private ShopConfigurationDaoInterface $shopConfigurationDao, private BasicContextInterface $context, private ModuleConfigurationMergingServiceInterface $moduleConfigurationMergingService, - private ModuleConfigurationDaoInterface $metadataModuleConfigurationDao + private MetadataDaoInterface $metadataModuleConfigurationDao, + private ModuleConfigurationDaoInterface $moduleConfigurationDao, + private ClassExtensionsChainDaoInterface $classExtensionsChainDao ) { } - /** - * @param string $moduleSourcePath - */ public function install(string $moduleSourcePath): void { $moduleConfiguration = $this->metadataModuleConfigurationDao->get($moduleSourcePath); $moduleConfiguration->setModuleSource($this->getModuleSourceRelativePath($moduleSourcePath)); foreach ($this->shopConfigurationDao->getAll() as $shopId => $shopConfiguration) { - $this->moduleConfigurationMergingService->merge($shopConfiguration, $moduleConfiguration); - $this->shopConfigurationDao->save($shopConfiguration, $shopId); + $mergedModuleConfiguration = $this + ->moduleConfigurationMergingService + ->merge($shopConfiguration, $moduleConfiguration) + ->getModuleConfiguration($moduleConfiguration->getId()); + + $this->moduleConfigurationDao->save($mergedModuleConfiguration, $shopId); + $this->classExtensionsChainDao->saveChain($shopId, $shopConfiguration->getClassExtensionsChain()); } } - /** - * @param string $moduleSourcePath - * - * @throws ModuleConfigurationNotFoundException - */ public function uninstall(string $moduleSourcePath): void { $moduleConfiguration = $this->metadataModuleConfigurationDao->get($moduleSourcePath); foreach ($this->shopConfigurationDao->getAll() as $shopId => $shopConfiguration) { if ($shopConfiguration->hasModuleConfiguration($moduleConfiguration->getId())) { - $shopConfiguration->deleteModuleConfiguration($moduleConfiguration->getId()); + $this->removeModuleConfiguration($moduleConfiguration, $shopId); } - $this->shopConfigurationDao->save($shopConfiguration, $shopId); } } - /** - * @param string $moduleId - * - * @throws ModuleConfigurationNotFoundException - */ public function uninstallById(string $moduleId): void { foreach ($this->shopConfigurationDao->getAll() as $shopId => $shopConfiguration) { if ($shopConfiguration->hasModuleConfiguration($moduleId)) { - $shopConfiguration->deleteModuleConfiguration($moduleId); + $this->removeModuleConfiguration($shopConfiguration->getModuleConfiguration($moduleId), $shopId); } - $this->shopConfigurationDao->save($shopConfiguration, $shopId); } } - /** - * @param string $moduleSourcePath - * - * @return bool - */ public function isInstalled(string $moduleSourcePath): bool { $moduleConfiguration = $this->metadataModuleConfigurationDao->get($moduleSourcePath); - foreach ($this->shopConfigurationDao->getAll() as $shopId => $shopConfiguration) { - if ($shopConfiguration->hasModuleConfiguration($moduleConfiguration->getId())) { - return true; - } - } - - return false; + return $this->shopConfigurationDao->get($this->context->getDefaultShopId()) + ->hasModuleConfiguration($moduleConfiguration->getId()); } - /** - * @param string $moduleSourcePath - * - * @return string - */ private function getModuleSourceRelativePath(string $moduleSourcePath): string { return Path::makeRelative($moduleSourcePath, $this->context->getShopRootPath()); } + + public function removeModuleConfiguration(ModuleConfiguration $moduleConfiguration, int $shopId): void + { + $this->moduleConfigurationDao->delete($moduleConfiguration->getId(), $shopId); + + $chain = $this->classExtensionsChainDao->getChain($shopId); + foreach ($moduleConfiguration->getClassExtensions() as $classExtension) { + $chain->removeExtension($classExtension); + } + $this->classExtensionsChainDao->saveChain($shopId, $chain); + } } diff --git a/tests/ContainerTrait.php b/tests/ContainerTrait.php index b29126bc1c..79fd80bea6 100644 --- a/tests/ContainerTrait.php +++ b/tests/ContainerTrait.php @@ -18,7 +18,6 @@ use UnitEnum; /** - * @internal * @mixin Container */ trait ContainerTrait diff --git a/tests/Integration/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoTest.php b/tests/Integration/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoTest.php index e7740f6c5f..3b989176ac 100644 --- a/tests/Integration/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoTest.php +++ b/tests/Integration/Internal/Framework/Module/Configuration/Dao/ModuleConfigurationDaoTest.php @@ -84,6 +84,23 @@ public function testGetAllOrdersConfigurationsById(): void + public function testDelete(): void + { + $moduleConfiguration = new ModuleConfiguration(); + $moduleConfiguration + ->setId('testDeleteId') + ->setModuleSource('test'); + + $dao = $this->get(ModuleConfigurationDaoInterface::class); + $dao->save($moduleConfiguration, 1); + + $this->assertTrue($dao->exists('testDeleteId', 1)); + + $dao->delete('testDeleteId', 1); + + $this->assertFalse($dao->exists('testDeleteId', 1)); + } + public function testDeleteAll(): void { $moduleConfiguration = new ModuleConfiguration(); diff --git a/tests/Integration/Internal/Framework/Module/Install/Service/ModuleConfigurationInstallerTest.php b/tests/Integration/Internal/Framework/Module/Install/Service/ModuleConfigurationInstallerTest.php index 5cd0a0e013..c1faa17b25 100644 --- a/tests/Integration/Internal/Framework/Module/Install/Service/ModuleConfigurationInstallerTest.php +++ b/tests/Integration/Internal/Framework/Module/Install/Service/ModuleConfigurationInstallerTest.php @@ -9,6 +9,7 @@ namespace OxidEsales\EshopCommunity\Tests\Integration\Internal\Framework\Module\Install\Service; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\Chain\ClassExtensionsChainDaoInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\ModuleConfigurationDaoInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Dao\ProjectConfigurationDaoInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataMapper\{ @@ -171,8 +172,11 @@ private function assertProjectConfigurationHasModuleConfigurationForAllShops(): private function assertModuleConfigurationDeletedForAllShops(): void { - foreach ($this->get(ShopConfigurationDaoInterface::class)->getAll() as $shopConfiguration) { + foreach ($this->get(ShopConfigurationDaoInterface::class)->getAll() as $shopId => $shopConfiguration) { $this->assertFalse($shopConfiguration->hasModuleConfiguration($this->testModuleId)); + + $chain = $this->get(ClassExtensionsChainDaoInterface::class)->getChain($shopId)->getChain(); + $this->assertNotContains('testModuleClassExtendsShopClass', $chain['shopClass'] ?? []); } }