diff --git a/core/lib/Drupal/Core/Extension/ModuleRequiredByThemesUninstallValidator.php b/core/lib/Drupal/Core/Extension/ModuleRequiredByThemesUninstallValidator.php index bc44b9ba14..620a8684d1 100644 --- a/core/lib/Drupal/Core/Extension/ModuleRequiredByThemesUninstallValidator.php +++ b/core/lib/Drupal/Core/Extension/ModuleRequiredByThemesUninstallValidator.php @@ -2,7 +2,6 @@ namespace Drupal\Core\Extension; -use Drupal\Core\Config\ConfigFactory; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; @@ -27,20 +26,6 @@ class ModuleRequiredByThemesUninstallValidator implements ModuleUninstallValidat */ protected $themeExtensionList; - /** - * The config factory to get the installed themes. - * - * @var \Drupal\Core\Config\ConfigFactory - */ - protected $configFactory; - - /** - * An array of modules that themes depend on. - * - * @var array - */ - protected $modulesThemesDependOn; - /** * Constructs a new ModuleRequiredByThemesUninstallValidator. * @@ -50,15 +35,11 @@ class ModuleRequiredByThemesUninstallValidator implements ModuleUninstallValidat * The module extension list. * @param \Drupal\Core\Extension\ThemeExtensionList $extension_list_theme * A extension discovery instance. - * @param \Drupal\Core\Config\ConfigFactory $config_factory - * The config factory to get the installed themes. */ - public function __construct(TranslationInterface $string_translation, ModuleExtensionList $extension_list_module, ThemeExtensionList $extension_list_theme = NULL, ConfigFactory $config_factory = NULL) { + public function __construct(TranslationInterface $string_translation, ModuleExtensionList $extension_list_module, ThemeExtensionList $extension_list_theme) { $this->stringTranslation = $string_translation; $this->moduleExtensionList = $extension_list_module; $this->themeExtensionList = $extension_list_theme; - $this->configFactory = $config_factory; - $this->getModulesThemesDependOn(); } /** @@ -67,10 +48,11 @@ public function __construct(TranslationInterface $string_translation, ModuleExte public function validate($module) { $reasons = []; - if (isset($this->modulesThemesDependOn[$module])) { - $module_name = $this->moduleExtensionList->get($module)->info['name']; - $theme_names = implode(", ", $this->modulesThemesDependOn[$module]); - $reasons[] = $this->formatPlural(count($theme_names), + $modules_themes_depend_on = $this->getModulesThemesDependOn(); + if (isset($modules_themes_depend_on[$module])) { + $module_name = $this->getModuleName($module); + $theme_names = implode(", ", $modules_themes_depend_on[$module]); + $reasons[] = $this->formatPlural(count($modules_themes_depend_on[$module]), 'The @module_name module is required by the theme @theme_names', 'The @module_name module is required by the themes @theme_names', ['@module_name' => $module_name, '@theme_names' => $theme_names]); @@ -79,18 +61,34 @@ public function validate($module) { return $reasons; } + /** + * Gets the name of a module. + * + * @param string $module + * The module machine name. + * + * @return string + * The module name. + */ + protected function getModuleName($module) { + return $this->moduleExtensionList->get($module)->info['name']; + } + /** * Populate $this->modulesThemesDependOn with modules themes depend on. */ protected function getModulesThemesDependOn() { + $modules_themes_depend_on = []; $installed_themes = $this->themeExtensionList->getAllInstalledInfo(); foreach ($this->themeExtensionList->getAllInstalledInfo() as $theme) { foreach ($theme['dependencies'] as $dependency) { if (!isset($installed_themes[$dependency])) { - $this->modulesThemesDependOn[$dependency][] = $theme['name']; + $modules_themes_depend_on[$dependency][] = $theme['name']; } } } + + return $modules_themes_depend_on; } } diff --git a/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php b/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php index 096f46d5f5..dc5f999f16 100644 --- a/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php +++ b/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php @@ -2,7 +2,6 @@ namespace Drupal\Core\Extension; -use Drupal\Core\Config\ConfigFactory; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; @@ -20,20 +19,6 @@ class RequiredModuleUninstallValidator implements ModuleUninstallValidatorInterf */ protected $moduleExtensionList; - /** - * The theme extension list. - * - * @var \Drupal\Core\Extension\ThemeExtensionList - */ - protected $themeExtensionList; - - /** - * The config factory to get the installed themes. - * - * @var \Drupal\Core\Config\ConfigFactory - */ - protected $configFactory; - /** * Constructs a new RequiredModuleUninstallValidator. * @@ -41,26 +26,10 @@ class RequiredModuleUninstallValidator implements ModuleUninstallValidatorInterf * The string translation service. * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module * The module extension list. - * @param \Drupal\Core\Extension\ThemeExtensionList $extension_list_theme - * A extension discovery instance. - * @param \Drupal\Core\Config\ConfigFactory $config_factory - * The config factory to get the installed themes. */ - public function __construct(TranslationInterface $string_translation, ModuleExtensionList $extension_list_module, ThemeExtensionList $extension_list_theme = NULL, ConfigFactory $config_factory = NULL) { + public function __construct(TranslationInterface $string_translation, ModuleExtensionList $extension_list_module) { $this->stringTranslation = $string_translation; $this->moduleExtensionList = $extension_list_module; - - if ($extension_list_theme === NULL) { - @trigger_error('The extension.list.theme service must be passed to' . __NAMESPACE__ . '\RequiredModuleUninstallValidator::__construct. It was added in Drupal 8.9.0 and will be required before Drupal 9.0.0.', E_USER_DEPRECATED); - $extension_list_theme = \Drupal::service('extension.list.theme'); - } - $this->themeExtensionList = $extension_list_theme; - - if ($config_factory === NULL) { - @trigger_error('The config.factory service must be passed to' . __NAMESPACE__ . '\RequiredModuleUninstallValidator::__construct. It was added in Drupal 8.9.0 and will be required before Drupal 9.0.0.', E_USER_DEPRECATED); - $config_factory = \Drupal::service('config.factory'); - } - $this->configFactory = $config_factory; } /** @@ -72,10 +41,6 @@ public function validate($module) { if (!empty($module_info['required'])) { $reasons[] = $this->t('The @module module is required', ['@module' => $module_info['name']]); } - elseif (!empty($this->getEnabledThemesThatDependOnModule($module))) { - $reasons[] = $this->t('The @module module is required', ['@module' => $module_info['name']]); - } - return $reasons; } @@ -95,20 +60,4 @@ protected function getModuleInfoByModule($module) { return []; } - /** - * Returns an array of themes that depend on a module. - * - * @param string $module - * The name of the module. - * - * @return array - * An array of theme machine names. Empty if no themes depend on the module. - */ - protected function getEnabledThemesThatDependOnModule($module) { - $installed_themes = $this->configFactory->get('core.extension')->get('theme'); - return array_filter(array_keys($installed_themes), function ($theme_name) use ($module) { - return isset($this->themeExtensionList->get($theme_name)->module_dependencies[$module]); - }); - } - } diff --git a/core/lib/Drupal/Core/ProxyClass/Extension/ModuleRequiredByThemesUninstallValidator.php b/core/lib/Drupal/Core/ProxyClass/Extension/ModuleRequiredByThemesUninstallValidator.php new file mode 100644 index 0000000000..601f482e4d --- /dev/null +++ b/core/lib/Drupal/Core/ProxyClass/Extension/ModuleRequiredByThemesUninstallValidator.php @@ -0,0 +1,88 @@ +container = $container; + $this->drupalProxyOriginalServiceId = $drupal_proxy_original_service_id; + } + + /** + * Lazy loads the real service from the container. + * + * @return object + * Returns the constructed real service. + */ + protected function lazyLoadItself() + { + if (!isset($this->service)) { + $this->service = $this->container->get($this->drupalProxyOriginalServiceId); + } + + return $this->service; + } + + /** + * {@inheritdoc} + */ + public function validate($module) + { + return $this->lazyLoadItself()->validate($module); + } + + /** + * {@inheritdoc} + */ + public function setStringTranslation(\Drupal\Core\StringTranslation\TranslationInterface $translation) + { + return $this->lazyLoadItself()->setStringTranslation($translation); + } + + } + +} diff --git a/core/tests/Drupal/Tests/Core/Extension/ModuleRequiredByThemesUninstallValidatorTest.php b/core/tests/Drupal/Tests/Core/Extension/ModuleRequiredByThemesUninstallValidatorTest.php new file mode 100644 index 0000000000..ed45ac4630 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Extension/ModuleRequiredByThemesUninstallValidatorTest.php @@ -0,0 +1,96 @@ +moduleRequiredByThemeUninstallValidator = $this->getMockBuilder('Drupal\Core\Extension\ModuleRequiredByThemesUninstallValidator') + ->disableOriginalConstructor() + ->setMethods(['getModulesThemesDependOn', 'getModuleName']) + ->getMock(); + $this->moduleRequiredByThemeUninstallValidator->setStringTranslation($this->getStringTranslationStub()); + } + + /** + * @covers ::validate + */ + public function testValidateNoThemeDependency() { + $this->moduleRequiredByThemeUninstallValidator->expects($this->once()) + ->method('getModulesThemesDependOn') + ->willReturn([]); + + $module = $this->randomMachineName(); + $expected = []; + $reasons = $this->moduleRequiredByThemeUninstallValidator->validate($module); + $this->assertSame($expected, $reasons); + } + + /** + * @covers ::validate + */ + public function testValidateOneThemeDependency() { + $module = 'single_module'; + $module_name = 'Single Module'; + $theme_name = 'One Theme'; + $this->moduleRequiredByThemeUninstallValidator->expects($this->once()) + ->method('getModulesThemesDependOn') + ->willReturn([ + $module => [$theme_name], + ]); + $this->moduleRequiredByThemeUninstallValidator->expects($this->once()) + ->method('getModuleName') + ->willReturn($module_name); + + $expected = [ + "The $module_name module is required by the theme $theme_name", + ]; + $reasons = $this->moduleRequiredByThemeUninstallValidator->validate($module); + $this->assertSame($expected, $this->castSafeStrings($reasons)); + } + + /** + * @covers ::validate + */ + public function testValidateTwoThemeDependencies() { + $module = 'popular_module'; + $module_name = 'Popular Module'; + $theme_name_1 = 'First Theme'; + $theme_name_2 = 'Second Theme'; + $this->moduleRequiredByThemeUninstallValidator->expects($this->once()) + ->method('getModulesThemesDependOn') + ->willReturn([ + $module => [$theme_name_1, $theme_name_2], + ]); + $this->moduleRequiredByThemeUninstallValidator->expects($this->once()) + ->method('getModuleName') + ->willReturn($module_name); + + $expected = [ + "The $module_name module is required by the themes $theme_name_1, $theme_name_2", + ]; + $reasons = $this->moduleRequiredByThemeUninstallValidator->validate($module); + $this->assertSame($expected, $this->castSafeStrings($reasons)); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Extension/RequiredModuleUninstallValidatorTest.php b/core/tests/Drupal/Tests/Core/Extension/RequiredModuleUninstallValidatorTest.php index e00a1435d5..a22a42eb91 100644 --- a/core/tests/Drupal/Tests/Core/Extension/RequiredModuleUninstallValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/RequiredModuleUninstallValidatorTest.php @@ -25,7 +25,7 @@ protected function setUp() { parent::setUp(); $this->uninstallValidator = $this->getMockBuilder('Drupal\Core\Extension\RequiredModuleUninstallValidator') ->disableOriginalConstructor() - ->setMethods(['getModuleInfoByModule', 'getEnabledThemesThatDependOnModule']) + ->setMethods(['getModuleInfoByModule']) ->getMock(); $this->uninstallValidator->setStringTranslation($this->getStringTranslationStub()); }