From 62ec922e1864166933e9af4b273ac9c2d2b66480 Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Fri, 11 Oct 2024 16:18:13 +0200 Subject: [PATCH 01/11] add new module hook filter service --- classes/Hook.php | 27 +++++++++++++++++++++++++ config/services/front/services_prod.yml | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/classes/Hook.php b/classes/Hook.php index bd6de9c5f5be7..6916fbef0540e 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -24,10 +24,12 @@ * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ +use PrestaShop\PrestaShop\Adapter\ContainerFinder; use PrestaShop\PrestaShop\Adapter\LegacyLogger; use PrestaShop\PrestaShop\Adapter\ServiceLocator; use PrestaShop\PrestaShop\Adapter\SymfonyContainer; use PrestaShop\PrestaShop\Core\Exception\CoreException; +use PrestaShop\PrestaShop\Core\Hook\HookModuleFilter; use PrestaShop\PrestaShop\Core\Module\WidgetInterface; class HookCore extends ObjectModel @@ -761,6 +763,12 @@ public static function getHookModuleExecList($hookName = null) } } + $hookModuleFilter = self::getHookModuleFilter(); + + if (!empty($hookModuleFilter) && !empty($modulesToInvoke)) { + $modulesToInvoke = $hookModuleFilter->filterHookModuleExecList($modulesToInvoke, $hookName); + } + return !empty($modulesToInvoke) ? $modulesToInvoke : false; } @@ -1109,6 +1117,25 @@ private static function getHookRegistry() return null; } + /** + * @return HookModuleFilter|null + * @throws \PrestaShop\PrestaShop\Core\Exception\ContainerNotFoundException + */ + private static function getHookModuleFilter() + { + $context = Context::getContext(); + $containerFinder = new ContainerFinder($context); + $serviceContainer = $containerFinder->getContainer(); + + try { + $hookModuleFilter = $serviceContainer->get('prestashop.hook.module.filter'); + } catch (Exception $e) { + return null; + } + + return $hookModuleFilter; + } + /** * Retrieves all modules registered to any hook, indexed by hok name. * diff --git a/config/services/front/services_prod.yml b/config/services/front/services_prod.yml index 47f7934f6084d..369f4b3635973 100644 --- a/config/services/front/services_prod.yml +++ b/config/services/front/services_prod.yml @@ -1,5 +1,6 @@ imports: - { resource: ../common.yml } + - { resource: ../../../modules/*/config/front_services.yml } services: _defaults: @@ -57,3 +58,8 @@ services: class: PrestaShopBundle\Translation\TranslatorLanguageLoader arguments: - '@prestashop.adapter.module.repository.module_repository' + + prestashop.hook.module.filter: + class: PrestaShop\PrestaShop\Core\Hook\HookModuleFilter + arguments: + - !tagged core.hook_module_exec_filter From 18101be4f13253c9e7c56776c96a97c2080f41af Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Fri, 11 Oct 2024 16:18:35 +0200 Subject: [PATCH 02/11] allow fetching front container from ContainerFinder --- src/Adapter/ContainerFinder.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Adapter/ContainerFinder.php b/src/Adapter/ContainerFinder.php index 9d80dcf0f4fa7..fa9de233ecfd6 100644 --- a/src/Adapter/ContainerFinder.php +++ b/src/Adapter/ContainerFinder.php @@ -28,6 +28,7 @@ use Context; use Controller; +use PrestaShop\PrestaShop\Adapter\ContainerBuilder as CustomContainerBuilder; use PrestaShop\PrestaShop\Core\Exception\ContainerNotFoundException; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -74,6 +75,12 @@ public function getContainer() return $container; } + $container = CustomContainerBuilder::getContainer('front', _PS_MODE_DEV_); + + if (null !== $container) { + return $container; + } + throw new ContainerNotFoundException('Kernel Container is not available'); } } From 94f726ad73268aca14d5704d57ae7daa3311acd1 Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Fri, 11 Oct 2024 16:19:34 +0200 Subject: [PATCH 03/11] add service and interface --- src/Core/Hook/HookModuleFilter.php | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/Core/Hook/HookModuleFilter.php diff --git a/src/Core/Hook/HookModuleFilter.php b/src/Core/Hook/HookModuleFilter.php new file mode 100644 index 0000000000000..8d301f513e6e7 --- /dev/null +++ b/src/Core/Hook/HookModuleFilter.php @@ -0,0 +1,46 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + */ + +namespace PrestaShop\PrestaShop\Core\Hook; + +class HookModuleFilter implements HookModuleFilterInterface +{ + private $hookModuleFilters; + + public function __construct(iterable $hookModuleFilters) + { + $this->hookModuleFilters = $hookModuleFilters; + } + + public function filterHookModuleExecList(array $modules, string $hookName): array + { + foreach ($this->hookModuleFilters as $hookModuleFilter) { + $modules = $hookModuleFilter->filterHookModuleExecList($modules, $hookName); + } + + return $modules; + } +} From 091c4c65fccc52ac64813b61d6b3d3cb194aa1a9 Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Fri, 11 Oct 2024 16:40:42 +0200 Subject: [PATCH 04/11] add missing interface --- src/Core/Hook/HookModuleFilterInterface.php | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/Core/Hook/HookModuleFilterInterface.php diff --git a/src/Core/Hook/HookModuleFilterInterface.php b/src/Core/Hook/HookModuleFilterInterface.php new file mode 100644 index 0000000000000..43d7a59f10dee --- /dev/null +++ b/src/Core/Hook/HookModuleFilterInterface.php @@ -0,0 +1,32 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + */ + +namespace PrestaShop\PrestaShop\Core\Hook; + +interface HookModuleFilterInterface +{ + public function filterHookModuleExecList(array $modules, string $hookName): array; +} From 274d232450ddd7f251f8e4b974cac0fd3d71e962 Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Fri, 11 Oct 2024 17:36:30 +0200 Subject: [PATCH 05/11] fix --- src/Adapter/ContainerFinder.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Adapter/ContainerFinder.php b/src/Adapter/ContainerFinder.php index fa9de233ecfd6..f74aa69888571 100644 --- a/src/Adapter/ContainerFinder.php +++ b/src/Adapter/ContainerFinder.php @@ -75,12 +75,12 @@ public function getContainer() return $container; } - $container = CustomContainerBuilder::getContainer('front', _PS_MODE_DEV_); - - if (null !== $container) { - return $container; + try { + $container = CustomContainerBuilder::getContainer('front', _PS_MODE_DEV_); + } catch (\Exception $e) { + throw new ContainerNotFoundException('Kernel Container is not available'); } - throw new ContainerNotFoundException('Kernel Container is not available'); + return $container; } } From 16b7f6f900319ed3edfbda2b9566553343fde4c6 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Sat, 12 Oct 2024 12:28:15 +0200 Subject: [PATCH 06/11] test fix for integration tests --- classes/Hook.php | 5 ++--- src/Adapter/ContainerFinder.php | 8 +------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/classes/Hook.php b/classes/Hook.php index 6916fbef0540e..2f1cdd2facf8d 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -24,6 +24,7 @@ * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ +use PrestaShop\PrestaShop\Adapter\ContainerBuilder; use PrestaShop\PrestaShop\Adapter\ContainerFinder; use PrestaShop\PrestaShop\Adapter\LegacyLogger; use PrestaShop\PrestaShop\Adapter\ServiceLocator; @@ -1123,9 +1124,7 @@ private static function getHookRegistry() */ private static function getHookModuleFilter() { - $context = Context::getContext(); - $containerFinder = new ContainerFinder($context); - $serviceContainer = $containerFinder->getContainer(); + $serviceContainer = ContainerBuilder::getContainer('front', _PS_MODE_DEV_); try { $hookModuleFilter = $serviceContainer->get('prestashop.hook.module.filter'); diff --git a/src/Adapter/ContainerFinder.php b/src/Adapter/ContainerFinder.php index f74aa69888571..e95dd4ff8a5bd 100644 --- a/src/Adapter/ContainerFinder.php +++ b/src/Adapter/ContainerFinder.php @@ -75,12 +75,6 @@ public function getContainer() return $container; } - try { - $container = CustomContainerBuilder::getContainer('front', _PS_MODE_DEV_); - } catch (\Exception $e) { - throw new ContainerNotFoundException('Kernel Container is not available'); - } - - return $container; + throw new ContainerNotFoundException('Kernel Container is not available'); } } From e15b85404e538710f00433891663132e1f473788 Mon Sep 17 00:00:00 2001 From: Krystian Podemski Date: Sat, 12 Oct 2024 14:24:37 +0200 Subject: [PATCH 07/11] clean non used namespaces --- classes/Hook.php | 1 - src/Adapter/ContainerFinder.php | 1 - 2 files changed, 2 deletions(-) diff --git a/classes/Hook.php b/classes/Hook.php index 2f1cdd2facf8d..ee7f0b9e4aa64 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -25,7 +25,6 @@ */ use PrestaShop\PrestaShop\Adapter\ContainerBuilder; -use PrestaShop\PrestaShop\Adapter\ContainerFinder; use PrestaShop\PrestaShop\Adapter\LegacyLogger; use PrestaShop\PrestaShop\Adapter\ServiceLocator; use PrestaShop\PrestaShop\Adapter\SymfonyContainer; diff --git a/src/Adapter/ContainerFinder.php b/src/Adapter/ContainerFinder.php index e95dd4ff8a5bd..9d80dcf0f4fa7 100644 --- a/src/Adapter/ContainerFinder.php +++ b/src/Adapter/ContainerFinder.php @@ -28,7 +28,6 @@ use Context; use Controller; -use PrestaShop\PrestaShop\Adapter\ContainerBuilder as CustomContainerBuilder; use PrestaShop\PrestaShop\Core\Exception\ContainerNotFoundException; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; From 386e4a3704697d3ea53e63d137c61d53a528ef3e Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Wed, 30 Oct 2024 16:12:50 +0100 Subject: [PATCH 08/11] remove useless import --- config/services/front/services_prod.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/config/services/front/services_prod.yml b/config/services/front/services_prod.yml index 369f4b3635973..c6f4a2f856932 100644 --- a/config/services/front/services_prod.yml +++ b/config/services/front/services_prod.yml @@ -1,6 +1,5 @@ imports: - { resource: ../common.yml } - - { resource: ../../../modules/*/config/front_services.yml } services: _defaults: From dbefe54ec81d06687033dcc56075c8df6954ab7b Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Thu, 7 Nov 2024 17:56:19 +0100 Subject: [PATCH 09/11] move service definition to common instead of service_prod (which includes common) --- config/services/common.yml | 5 +++++ config/services/front/services_prod.yml | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/services/common.yml b/config/services/common.yml index c3aa7b6c7afde..2d55e057e21c9 100644 --- a/config/services/common.yml +++ b/config/services/common.yml @@ -25,3 +25,8 @@ services: PrestaShopBundle\DependencyInjection\RuntimeConstEnvVarProcessor: public: false tags: ['container.env_var_processor'] + + prestashop.hook.module.filter: + class: PrestaShop\PrestaShop\Core\Hook\HookModuleFilter + arguments: + - !tagged core.hook_module_exec_filter diff --git a/config/services/front/services_prod.yml b/config/services/front/services_prod.yml index c6f4a2f856932..47f7934f6084d 100644 --- a/config/services/front/services_prod.yml +++ b/config/services/front/services_prod.yml @@ -57,8 +57,3 @@ services: class: PrestaShopBundle\Translation\TranslatorLanguageLoader arguments: - '@prestashop.adapter.module.repository.module_repository' - - prestashop.hook.module.filter: - class: PrestaShop\PrestaShop\Core\Hook\HookModuleFilter - arguments: - - !tagged core.hook_module_exec_filter From 4295f87e7b0743019ff41238e63e198230261565 Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Tue, 12 Nov 2024 09:30:54 +0100 Subject: [PATCH 10/11] fix service container fetching --- classes/Hook.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/classes/Hook.php b/classes/Hook.php index ee7f0b9e4aa64..fd0392f8a0ac4 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -1123,7 +1123,11 @@ private static function getHookRegistry() */ private static function getHookModuleFilter() { - $serviceContainer = ContainerBuilder::getContainer('front', _PS_MODE_DEV_); + $serviceContainer = SymfonyContainer::getInstance(); + + if (is_null($serviceContainer)) { + $serviceContainer = ContainerBuilder::getContainer('front', _PS_MODE_DEV_); + } try { $hookModuleFilter = $serviceContainer->get('prestashop.hook.module.filter'); From b806043aa6e45d51e10fa6dbe27719620e963c04 Mon Sep 17 00:00:00 2001 From: Matthieu Rolland Date: Tue, 12 Nov 2024 16:53:36 +0100 Subject: [PATCH 11/11] fix service availability issue --- classes/Hook.php | 2 +- config/services/common.yml | 3 +-- src/Core/Hook/HookModuleFilter.php | 12 ++++++++++++ src/Core/Hook/HookModuleFilterInterface.php | 4 ++++ .../Resources/config/services/core/common.yml | 5 +++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/classes/Hook.php b/classes/Hook.php index fd0392f8a0ac4..c4359bf6c387d 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -1130,7 +1130,7 @@ private static function getHookModuleFilter() } try { - $hookModuleFilter = $serviceContainer->get('prestashop.hook.module.filter'); + $hookModuleFilter = $serviceContainer->get(HookModuleFilter::class); } catch (Exception $e) { return null; } diff --git a/config/services/common.yml b/config/services/common.yml index 2d55e057e21c9..16e4fa452d7e9 100644 --- a/config/services/common.yml +++ b/config/services/common.yml @@ -26,7 +26,6 @@ services: public: false tags: ['container.env_var_processor'] - prestashop.hook.module.filter: - class: PrestaShop\PrestaShop\Core\Hook\HookModuleFilter + PrestaShop\PrestaShop\Core\Hook\HookModuleFilter: arguments: - !tagged core.hook_module_exec_filter diff --git a/src/Core/Hook/HookModuleFilter.php b/src/Core/Hook/HookModuleFilter.php index 8d301f513e6e7..b8e76752f0df2 100644 --- a/src/Core/Hook/HookModuleFilter.php +++ b/src/Core/Hook/HookModuleFilter.php @@ -26,6 +26,18 @@ namespace PrestaShop\PrestaShop\Core\Hook; +/** + * This service is responsible for filtering the list of modules for a given hook that is returned by + * the getHookModuleExecList method from Hook.php. It is called at the very end of getHookModuleExecList. + * + * How to use it to filter a list of modules for a hook: + * + * In your module, create a service which implements the HookModuleFilterInterface and give it + * the tag named core.hook_module_exec_filter. Then in your service, you can filter the list of modules + * in the filterHookModuleExecList method, according to your own logic. + * + * Your service will automatically be sent in this class's constructor, and be used to filter the list of modules. + */ class HookModuleFilter implements HookModuleFilterInterface { private $hookModuleFilters; diff --git a/src/Core/Hook/HookModuleFilterInterface.php b/src/Core/Hook/HookModuleFilterInterface.php index 43d7a59f10dee..4be6d8d0b194c 100644 --- a/src/Core/Hook/HookModuleFilterInterface.php +++ b/src/Core/Hook/HookModuleFilterInterface.php @@ -26,6 +26,10 @@ namespace PrestaShop\PrestaShop\Core\Hook; +/** + * This interface must be implemented by all services that will be used by the HookModuleFilter service. + * See HookModuleFilter.php for more explanations. + */ interface HookModuleFilterInterface { public function filterHookModuleExecList(array $modules, string $hookName): array; diff --git a/src/PrestaShopBundle/Resources/config/services/core/common.yml b/src/PrestaShopBundle/Resources/config/services/core/common.yml index be57c3ee5c02b..5dcc2faaf4202 100644 --- a/src/PrestaShopBundle/Resources/config/services/core/common.yml +++ b/src/PrestaShopBundle/Resources/config/services/core/common.yml @@ -1,2 +1,7 @@ imports: - { resource: ./circuit_breaker.yml } + +services: + PrestaShop\PrestaShop\Core\Hook\HookModuleFilter: + arguments: + - !tagged core.hook_module_exec_filter