--- /home/shaal/Downloads/allow-themes-to-declare-dependencies-1-474684-194.patch 2019-10-30 16:03:44.030482589 -0400
+++ /home/shaal/Downloads/allow-themes-to-declare-dependencies-474684-203.patch 2019-10-30 17:01:26.134133162 -0400
@@ -1,8 +1,8 @@
diff --git a/core/core.services.yml b/core/core.services.yml
-index 08b09d9953..e612ba0453 100644
+index 582f0bd907..0694089def 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
-@@ -540,7 +540,7 @@ services:
+@@ -553,7 +553,7 @@ services:
arguments: ['@app.root', '@config.factory', '@extension.list.theme']
theme_installer:
class: Drupal\Core\Extension\ThemeInstaller
@@ -12,10 +12,10 @@
# entity* services instead.
entity.manager:
diff --git a/core/lib/Drupal/Core/Extension/ThemeExtensionList.php b/core/lib/Drupal/Core/Extension/ThemeExtensionList.php
-index 07a2f3f8f6..453ee04089 100644
+index 5722d1c2fe..2c35f0535b 100644
--- a/core/lib/Drupal/Core/Extension/ThemeExtensionList.php
+++ b/core/lib/Drupal/Core/Extension/ThemeExtensionList.php
-@@ -52,6 +52,7 @@ class ThemeExtensionList extends ExtensionList {
+@@ -51,6 +51,7 @@ class ThemeExtensionList extends ExtensionList {
'libraries' => [],
'libraries_extend' => [],
'libraries_override' => [],
@@ -23,7 +23,7 @@
];
/**
-@@ -141,6 +142,17 @@ protected function doList() {
+@@ -140,6 +141,17 @@ protected function doList() {
// sub-themes.
$this->fillInSubThemeData($themes, $sub_themes);
@@ -183,7 +183,7 @@
+
}
diff --git a/core/modules/system/src/Controller/SystemController.php b/core/modules/system/src/Controller/SystemController.php
-index 106f4e2915..ac6b856de7 100644
+index f27cc01eb1..4d29f333f5 100644
--- a/core/modules/system/src/Controller/SystemController.php
+++ b/core/modules/system/src/Controller/SystemController.php
@@ -10,6 +10,7 @@
@@ -202,7 +202,7 @@
foreach ($themes as &$theme) {
if (!empty($theme->info['hidden'])) {
-@@ -232,9 +234,35 @@ public function themesPage() {
+@@ -231,9 +233,35 @@ public function themesPage() {
$theme->incompatible_base = (isset($theme->info['base theme']) && !($theme->base_themes === array_filter($theme->base_themes)));
// Confirm that the theme engine is available.
$theme->incompatible_engine = isset($theme->info['engine']) && !isset($theme->owner);
@@ -210,50 +210,50 @@
+ $theme->incompatible_module = FALSE;
}
+
-+ // Check module dependencies.
-+ if ($theme->module_dependencies) {
-+ if (empty($modules)) {
-+ $modules = system_rebuild_module_data();
-+ }
-+ foreach ($theme->module_dependencies as $dependency => $version) {
-+ if ($incompatible = ModulesListForm::checkDependencyMessage($modules, $dependency, $version)) {
-+ $theme->module_dependencies[$dependency] = $incompatible;
-+ $theme->incompatible_module = TRUE;
-+ continue;
++ // Check module dependencies.
++ if ($theme->module_dependencies) {
++ if (empty($modules)) {
++ $modules = system_rebuild_module_data();
+ }
++ foreach ($theme->module_dependencies as $dependency => $version) {
++ if ($incompatible = ModulesListForm::checkDependencyMessage($modules, $dependency, $version)) {
++ $theme->module_dependencies[$dependency] = $incompatible;
++ $theme->incompatible_module = TRUE;
++ continue;
++ }
+
-+ // Only display visible modules.
-+ if (!empty($modules[$dependency]->hidden)) {
-+ unset($theme->module_dependencies[$dependency]);
-+ continue;
-+ }
++ // Only display visible modules.
++ if (!empty($modules[$dependency]->hidden)) {
++ unset($theme->module_dependencies[$dependency]);
++ continue;
++ }
+
-+ $name = $modules[$dependency]->info['name'];
-+ $theme->module_dependencies[$dependency] = $modules[$dependency]->status ? $this->t('@module', ['@module' => $name]) : $this->t('@module (disabled)', ['@module' => $name]);
++ $name = $modules[$dependency]->info['name'];
++ $theme->module_dependencies[$dependency] = $modules[$dependency]->status ? $this->t('@module', ['@module' => $name]) : $this->t('@module (disabled)', ['@module' => $name]);
++ }
+ }
-+ }
+
$theme->operations = [];
-- if (!empty($theme->status) || !$theme->incompatible_core && !$theme->incompatible_php && !$theme->incompatible_base && !$theme->incompatible_engine) {
-+ if (!empty($theme->status) || !$theme->incompatible_core && !$theme->incompatible_php && !$theme->incompatible_base && !$theme->incompatible_engine && !$theme->incompatible_module) {
+- if (!empty($theme->status) || !$theme->info['core_incompatible'] && !$theme->incompatible_php && !$theme->incompatible_base && !$theme->incompatible_engine) {
++ if (!empty($theme->status) || !$theme->info['core_incompatible'] && !$theme->incompatible_core && !$theme->incompatible_php && !$theme->incompatible_base && !$theme->incompatible_engine && !$theme->incompatible_module) {
// Create the operations links.
$query['theme'] = $theme->getName();
if ($this->themeAccess->checkAccess($theme->getName())) {
diff --git a/core/modules/system/src/Controller/ThemeController.php b/core/modules/system/src/Controller/ThemeController.php
-index 31be59ed1a..f1ae735c61 100644
+index 0a8ad31cf8..8cfbd49d3f 100644
--- a/core/modules/system/src/Controller/ThemeController.php
+++ b/core/modules/system/src/Controller/ThemeController.php
-@@ -6,6 +6,7 @@
- use Drupal\Core\Config\PreExistingConfigException;
+@@ -7,6 +7,7 @@
use Drupal\Core\Config\UnmetDependenciesException;
use Drupal\Core\Controller\ControllerBase;
+ use Drupal\Core\Extension\ThemeExtensionList;
+use Drupal\Core\DrupalKernelInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\HttpFoundation\Request;
-@@ -23,6 +24,13 @@ class ThemeController extends ControllerBase {
+ use Drupal\Core\Extension\ThemeInstallerInterface;
+ use Drupal\system\Form\ThemeExperimentalConfirmForm;
+@@ -40,6 +41,13 @@ class ThemeController extends ControllerBase {
*/
- protected $themeHandler;
+ protected $themeInstaller;
+ /**
+ * The Drupal kernel.
@@ -265,52 +265,54 @@
/**
* Constructs a new ThemeController.
*
-@@ -30,10 +38,13 @@ class ThemeController extends ControllerBase {
- * The theme handler.
- * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+@@ -51,12 +59,15 @@ class ThemeController extends ControllerBase {
* The config factory.
+ * @param \Drupal\Core\Extension\ThemeInstallerInterface $theme_installer
+ * The theme installer.
+ * @param \Drupal\Core\DrupalKernelInterface $kernel
+ * The Drupal kernel.
*/
-- public function __construct(ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory) {
-+ public function __construct(ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory, DrupalKernelInterface $kernel) {
+- public function __construct(ThemeHandlerInterface $theme_handler, ThemeExtensionList $theme_list, ConfigFactoryInterface $config_factory, ThemeInstallerInterface $theme_installer) {
++ public function __construct(ThemeHandlerInterface $theme_handler, ThemeExtensionList $theme_list, ConfigFactoryInterface $config_factory, ThemeInstallerInterface $theme_installer, DrupalKernelInterface $kernel) {
$this->themeHandler = $theme_handler;
+ $this->themeList = $theme_list;
$this->configFactory = $config_factory;
+ $this->themeInstaller = $theme_installer;
+ $this->kernel = $kernel;
}
/**
-@@ -42,7 +53,8 @@ public function __construct(ThemeHandlerInterface $theme_handler, ConfigFactoryI
- public static function create(ContainerInterface $container) {
- return new static(
+@@ -67,7 +78,8 @@ public static function create(ContainerInterface $container) {
$container->get('theme_handler'),
-- $container->get('config.factory')
-+ $container->get('config.factory'),
+ $container->get('extension.list.theme'),
+ $container->get('config.factory'),
+- $container->get('theme_installer')
++ $container->get('theme_installer'),
+ $container->get('kernel')
);
}
-@@ -75,6 +87,7 @@ public function uninstall(Request $request) {
+@@ -99,6 +111,7 @@ public function uninstall(Request $request) {
+ $this->messenger()->addError($this->t('%theme is the default theme and cannot be uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
}
else {
- $this->themeHandler->uninstall([$theme]);
+ $this->updateDependencies(\Drupal::getContainer());
+ $this->themeInstaller->uninstall([$theme]);
$this->messenger()->addStatus($this->t('The %theme theme has been uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
}
+@@ -137,9 +150,30 @@ public function install(Request $request) {
}
-@@ -106,9 +119,28 @@ public function install(Request $request) {
- if (isset($theme)) {
try {
+ // Get an up-to-date list of modules in the system.
+ $previously_installed_modules = $this->moduleHandler()->getModuleList();
- if ($this->themeHandler->install([$theme])) {
-- $themes = $this->themeHandler->listInfo();
-- $this->messenger()->addStatus($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']]));
+ if ($this->themeInstaller->install([$theme])) {
+ $themes = $this->themeHandler->listInfo();
+ $this->messenger()->addStatus($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']]));
+ $this->updateDependencies(\Drupal::getContainer());
+ $theme_data = $this->themeHandler->listInfo();
+ if ($theme_data[$theme]->module_dependencies) {
-+ $module_data = system_rebuild_module_data();
++ $module_data = \Drupal::service('extension.list.module')->getList();
+ $newly_installed_modules = array_diff_key($theme_data[$theme]->module_dependencies, $previously_installed_modules);
+ $newly_installed_modules_names = array_map(function ($module_name) use ($module_data) {
+ return $module_data[$module_name]->info['name'];
@@ -320,7 +322,7 @@
+ $this->messenger()->addStatus($this->formatPlural(count($newly_installed_modules_names), 'The %theme theme and its module dependency, %name, have been installed.', 'The %theme theme and its @count module dependencies have been installed: %names.', [
+ '%theme' => $theme_data[$theme]->info['name'],
+ '%name' => $newly_installed_modules_names[0],
-+ '%names' => implode(', ', $newly_installed_modules_names),
++ '%names' => implode(', ', $newly_installed_modules_names),
+ ]));
+ }
+ else {
@@ -329,7 +331,7 @@
}
else {
$this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
-@@ -190,4 +222,34 @@ public function setDefaultTheme(Request $request) {
+@@ -249,4 +283,34 @@ public function setDefaultTheme(Request $request) {
throw new AccessDeniedHttpException();
}
@@ -348,65 +350,65 @@
+ * add the trait that supplies this method from that issue.
+ */
+ protected function updateDependencies(ContainerInterface $container) {
-+ $vars = get_object_vars($this);
-+ foreach ($vars as $key => $value) {
-+ if (is_object($value) && isset($value->_serviceId)) {
-+ $this->$key = $container->get($value->_serviceId);
-+ continue;
-+ }
-+
-+ // Special case the container, which might not have a service ID.
-+ if ($value instanceof ContainerInterface) {
-+ $this->$key = $container;
++ $vars = get_object_vars($this);
++ foreach ($vars as $key => $value) {
++ if (is_object($value) && isset($value->_serviceId)) {
++ $this->$key = $container->get($value->_serviceId);
+ continue;
-+ }
-+ }
++ }
++
++ // Special case the container, which might not have a service ID.
++ if ($value instanceof ContainerInterface) {
++ $this->$key = $container;
++ continue;
++ }
++ }
+ }
+
}
diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
-index c2ade11b7a..e83121b3ba 100644
+index f32dad0909..7cfd417041 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
-@@ -197,11 +197,47 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+@@ -210,11 +210,47 @@ public function buildForm(array $form, FormStateInterface $form_state) {
return $form;
}
-+ /**
-+ * Determines a message for missing/invalid theme/module dependencies.
-+ *
-+ * @param array $modules
-+ * The list of existing modules.
-+ * @param string $dependency
-+ * The module dependency to check.
-+ * @param array $version
-+ * Version requirement data from the module or theme declaring the
-+ * dependency we are checking.
-+ *
-+ * @return string|null
-+ * NULL if compatible, otherwise a string describing the incompatibility.
++ /**
++ * Determines a message for missing/invalid theme/module dependencies.
++ *
++ * @param array $modules
++ * The list of existing modules.
++ * @param string $dependency
++ * The module dependency to check.
++ * @param array $version
++ * Version requirement data from the module or theme declaring the
++ * dependency we are checking.
++ *
++ * @return string|null
++ * NULL if compatible, otherwise a string describing the incompatibility.
+ */
-+ public static function checkDependencyMessage(array $modules, $dependency, $version) {
-+ if (!isset($modules[$dependency])) {
-+ return t('@module (missing)', ['@module' => Unicode::ucfirst($dependency)]);
-+ }
-+ else {
-+ $name = $modules[$dependency]->info['name'];
-+ // Check if it is incompatible with the dependency's version.
-+ if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
-+ return t('@module (incompatible with version @version)', [
-+ '@module' => $name . $incompatible_version,
-+ '@version' => $modules[$dependency]->info['version'],
-+ ]);
-+ }
-+ // Ensure that incompatible modules cannot be installed.
-+ if ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) {
-+ return t('@module (incompatible with this version of Drupal core)', [
-+ '@module' => $name,
-+ ]);
-+ }
-+ }
-+ }
++ public static function checkDependencyMessage(array $modules, $dependency, $version) {
++ if (!isset($modules[$dependency])) {
++ return t('@module (missing)', ['@module' => Unicode::ucfirst($dependency)]);
++ }
++ else {
++ $name = $modules[$dependency]->info['name'];
++ // Check if it is incompatible with the dependency's version.
++ if ($incompatible_version = \Dependency::isCompatible($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
++ return t('@module (incompatible with version @version)', [
++ '@module' => $name . $incompatible_version,
++ '@version' => $modules[$dependency]->info['version'],
++ ]);
++ }
++ // Ensure that incompatible modules cannot be installed.
++ if ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) {
++ return t('@module (incompatible with this version of Drupal core)', [
++ '@module' => $name,
++ ]);
++ }
++ }
++ }
+
/**
* Builds a table row for the system modules page.
@@ -417,61 +419,19 @@
* @param \Drupal\Core\Extension\Extension $module
* The module for which to build the form row.
* @param $distribution
-@@ -309,38 +345,19 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
- // If this module requires other modules, add them to the array.
- /** @var \Drupal\Core\Extension\Dependency $dependency_object */
- foreach ($module->requires as $dependency => $dependency_object) {
-- if (!isset($modules[$dependency])) {
-- $row['#requires'][$dependency] = $this->t('@module (missing)', ['@module' => Unicode::ucfirst($dependency)]);
-- $row['enable']['#disabled'] = TRUE;
-+ // Only display missing or visible modules.
-+ if (!empty($modules[$dependency]->hidden)) {
-+ continue;
- }
-- // Only display visible modules.
-- elseif (empty($modules[$dependency]->hidden)) {
-- $name = $modules[$dependency]->info['name'];
-- // Disable the module's checkbox if it is incompatible with the
-- // dependency's version.
-- if (!$dependency_object->isCompatible(str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
-- $row['#requires'][$dependency] = $this->t('@module (@constraint) (incompatible with version @version)', [
-- '@module' => $name,
-- '@constraint' => $dependency_object->getConstraintString(),
-- '@version' => $modules[$dependency]->info['version'],
-- ]);
-- $row['enable']['#disabled'] = TRUE;
-- }
-- // Disable the checkbox if the dependency is incompatible with this
-- // version of Drupal core.
-- elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) {
-- $row['#requires'][$dependency] = $this->t('@module (incompatible with this version of Drupal core)', [
-- '@module' => $name,
-- ]);
-- $row['enable']['#disabled'] = TRUE;
-- }
-- elseif ($modules[$dependency]->status) {
-- $row['#requires'][$dependency] = $this->t('@module', ['@module' => $name]);
-- }
-- else {
-- $row['#requires'][$dependency] = $this->t('@module (disabled)', ['@module' => $name]);
-- }
-+
-+ if ($incompatible = static::checkDependencyMessage($modules, $dependency, $version)) {
-+ $row['#requires'][$dependency] = $incompatible;
-+ $row['enable']['#disabled'] = TRUE;
+@@ -329,6 +365,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
+ if (!isset($modules[$dependency])) {
+ $row['#requires'][$dependency] = $this->t('@module (missing)', ['@module' => $dependency]);
+ $row['enable']['#disabled'] = TRUE;
+ continue;
}
-+
-+ $name = $modules[$dependency]->info['name'];
-+ $row['#requires'][$dependency] = $modules[$dependency]->status ? $this->t('@module', ['@module' => $name]) : $this->t('@module (disabled)', ['@module' => $name]);
- }
-
- // If this module is required by other modules, list those, and then make it
+ // Only display visible modules.
+ elseif (empty($modules[$dependency]->hidden)) {
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
-index 799869bbc3..9431642e78 100644
+index 661677b51a..4edb955909 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
-@@ -165,6 +165,8 @@ function template_preprocess_system_modules_details(&$variables) {
+@@ -166,6 +166,8 @@ function template_preprocess_system_modules_details(&$variables) {
];
$module['requires'] = $renderer->render($requires);
}
@@ -480,7 +440,7 @@
if (!empty($module['#required_by'])) {
$required_by = [
'#theme' => 'item_list',
-@@ -290,6 +292,12 @@ function template_preprocess_system_themes_page(&$variables) {
+@@ -291,6 +293,12 @@ function template_preprocess_system_themes_page(&$variables) {
$current_theme['is_default'] = $theme->is_default;
$current_theme['is_admin'] = $theme->is_admin;
@@ -492,8 +452,8 @@
+
// Make sure to provide feedback on compatibility.
$current_theme['incompatible'] = '';
- if (!empty($theme->incompatible_core)) {
-@@ -310,6 +318,9 @@ function template_preprocess_system_themes_page(&$variables) {
+ if (!empty($theme->info['core_incompatible'])) {
+@@ -311,6 +319,9 @@ function template_preprocess_system_themes_page(&$variables) {
elseif (!empty($theme->incompatible_engine)) {
$current_theme['incompatible'] = t('This theme requires the theme engine @theme_engine to operate correctly.', ['@theme_engine' => $theme->info['engine']]);
}
@@ -543,7 +503,7 @@
* The library discovery service.
*
diff --git a/core/tests/Drupal/KernelTests/Core/Render/ElementInfoIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Render/ElementInfoIntegrationTest.php
-index cd33fcb6dc..512a3bd40a 100644
+index f5b58c6445..e79c843684 100644
--- a/core/tests/Drupal/KernelTests/Core/Render/ElementInfoIntegrationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Render/ElementInfoIntegrationTest.php
@@ -11,6 +11,11 @@
@@ -559,7 +519,7 @@
* {@inheritdoc}
*/
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
-index 5c650d4f46..85fe4f2c7c 100644
+index d625c2d9f6..32046d79e8 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
@@ -6,6 +6,7 @@
@@ -570,7 +530,7 @@
/**
* Tests installing and uninstalling of themes.
-@@ -347,6 +348,22 @@ public function testThemeInfoAlter() {
+@@ -345,6 +346,22 @@ public function testThemeInfoAlter() {
$this->assertFalse(isset($theme_list[$name]->info['regions']['test_region']));
}