Unable to uninstall base theme and subtheme via config sync at the same time

Created on 21 September 2018, over 6 years ago
Updated 8 September 2023, over 1 year ago

Problem/Motivation

while uninstalling themes during a config import (drush cim) I get the error message:
"The base theme $key cannot be uninstalled, because theme $sub_key depends on it."

but in the same config import I would also uninstall the sub theme.

on config import all the uninstalled themes should be in the same uninstall call, so that the test about
"Base themes cannot be uninstalled if sub themes are installed, and if they are not uninstalled at the same time." is possible.

/core/lib/Drupal/Core/Extension/ThemeInstaller.php Line 232:

      // Base themes cannot be uninstalled if sub themes are installed, and if
      // they are not uninstalled at the same time.
      // @todo https://www.drupal.org/node/474684 and
      //   https://www.drupal.org/node/1297856 themes should leverage the module
      //   dependency system.
      if (!empty($list[$key]->sub_themes)) {
        foreach ($list[$key]->sub_themes as $sub_key => $sub_label) {
          if (isset($list[$sub_key]) && !in_array($sub_key, $theme_list, TRUE)) {
            throw new \InvalidArgumentException("The base theme $key cannot be uninstalled, because theme $sub_key depends on it.");
          }
        }
      }

as a temporary solution I replaced

            throw new \InvalidArgumentException("The base theme $key cannot be uninstalled, because theme $sub_key depends on it.");

with a recursive call

            $this->uninstall([$sub_key]);

Steps to reproduce

  1. Install minimal and enable test themes to be installed.
  2. Export your configuration
  3. Install test_basetheme, test_subtheme and test_subsubtheme
  4. Try to import the configuration again - you won't be able to because it can't uninstall the themes

Proposed resolution

Fix \Drupal\Core\Config\ConfigImporter::createExtensionChangelist() to use the theme's sort information to ensure dependencies are processed in the correct order on install and uninstall.

Remaining tasks

User interface changes

None

API changes

The constructor of the following classes:

  • \Drupal\Core\Config\ConfigImporter
  • \Drupal\config\Form\ConfigSync
  • \Drupal\config\Form\ConfigSingleImportForm

now require an argument of extension.list.theme service implementing \Drupal\Core\Extension\ThemeExtensionList.

\Drupal\config\Form\ConfigSync and \Drupal\config\Form\ConfigSingleImportForm are forms and are consider to be internal.

Data model changes

None

Release notes snippet

N/a

🐛 Bug report
Status

Fixed

Version

10.1

Component
Theme 

Last updated about 1 hour ago

Created by

🇨🇭Switzerland ifux

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States smustgrave

    Actually noticed this bug while prepping a site for D10

    @trigger_error('Calling ' . __METHOD__ . ' without the $extension_list_theme argument is deprecated in drupal:9.4.0 and will be required in drupal:10.0.0
    

    1. Should be updated for 10.1.x and 11 now I think.

    Testing out the functionality by editing a contrib theme I'm using to base theme off stark.
    Before installing I exported my config
    Installed theme which installed stark
    Ran config import and got the error

    Applied fix
    Ran config import and both uninstalled.

    So this looks good just needs that 1 update.

  • 🇮🇳India _utsavsharma

    Addressed the pointer in #23.
    Please review.

  • Status changed to Needs review almost 2 years ago
  • Status changed to RTBC almost 2 years ago
  • 🇺🇸United States smustgrave

    Issue has been addressed

  • 🇬🇧United Kingdom catch
    +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
    @@ -448,9 +463,24 @@ protected function createExtensionChangelist() {
    +    // Set the actual module weights.
    

    Should this say theme weights?

    Also is there no API method for that anywhere?

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Yes it should say theme weights... it's about setting them in the array we're creating to do the ordering... so it's not setting the theme weights in the system... will fix this to be clearer. It's a copy/pasta so fixing it above too.

    Leaving at RTBC as this is only fixing a comment as @catch requested.

  • 🇬🇧United Kingdom catch

    @alexpott found 📌 Provide canonical extension sorting by dependencies in the extension system Active which covers my remaining concern here, which was apparently a remaining concern on a similar issue 9 years ago.

    Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x, thanks!

    • catch committed a36db890 on 10.0.x
      Issue #3001430 by alexpott, _utsavsharma, Oscaner, lauriii, smustgrave,...
  • Status changed to Fixed almost 2 years ago
    • catch committed fab2025f on 10.1.x
      Issue #3001430 by alexpott, _utsavsharma, Oscaner, lauriii, smustgrave,...
    • catch committed 95a2a252 on 9.5.x
      Issue #3001430 by alexpott, _utsavsharma, Oscaner, lauriii, smustgrave,...
  • Status changed to RTBC almost 2 years ago
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    I agree that we should fix this in 9.5 and 10.0 so here's a patch to remove the deprecation message as we should only be adding them in 10.1

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    I agree that we should fix this in 9.5 and 10.0 so here's a patch to remove the deprecation message as we should only be adding them in 10.1

    • catch committed 6f8aa738 on 10.0.x
      Issue #3001430 by alexpott, _utsavsharma, lauriii, Oscaner, catch,...
    • catch committed 6433cd0a on 9.5.x
      Issue #3001430 by alexpott, _utsavsharma, lauriii, Oscaner, catch,...
  • Status changed to Fixed almost 2 years ago
  • 🇬🇧United Kingdom catch

    Hmm fair enough, this is the tricky thing about best effort bc vs. backporting bugfixes with internal API changes. Committed/pushed to 10.0.x and 9.5.x, thanks! I don't think anyone's going to be overriding either class so hopefully this is moot.

  • Status changed to Needs work almost 2 years ago
  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    Just a couple of micronits

    1. +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
      @@ -166,6 +167,13 @@ class ConfigImporter {
      +  protected $themeExtensionList;
      
      +++ b/core/modules/config/src/Form/ConfigSingleImportForm.php
      @@ -104,6 +105,13 @@ class ConfigSingleImportForm extends ConfirmFormBase {
      +  protected $themeExtensionList;
      
      +++ b/core/modules/config/src/Form/ConfigSync.php
      @@ -121,6 +122,13 @@ class ConfigSync extends FormBase {
      +  protected $themeExtensionList;
      

      Let's add a property type-hint here for the D10 version.

    2. +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
      @@ -448,9 +463,24 @@ protected function createExtensionChangelist() {
      +    // Set the actual module weights.
      

      %s/module/theme

    3. +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
      @@ -687,6 +687,37 @@ public function testRequiredModuleValidation() {
      +   * Tests installing a base themes and sub themes during configuration import.
      

      %s/base themes/base theme

    4. +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
      @@ -687,6 +687,37 @@ public function testRequiredModuleValidation() {
      +    $this->assertTrue($this->container->get('theme_handler')->themeExists('test_basetheme'));
      +    $this->assertTrue($this->container->get('theme_handler')->themeExists('test_subsubtheme'));
      +    $this->assertTrue($this->container->get('theme_handler')->themeExists('test_subtheme'));
      ...
      +    $this->assertFalse($this->container->get('theme_handler')->themeExists('test_basetheme'));
      +    $this->assertFalse($this->container->get('theme_handler')->themeExists('test_subsubtheme'));
      +    $this->assertFalse($this->container->get('theme_handler')->themeExists('test_subtheme'));
      

      micronit: is it worth putting the theme_handler service into a local variable ?

      would probably need to assign it twice to allow for any container rebuild as a result of updating core.extension

  • Status changed to Fixed almost 2 years ago
  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    Ah crosspost

  • Automatically closed - issue fixed for 2 weeks with no activity.

  • Status changed to Fixed over 1 year ago
  • 🇳🇿New Zealand quietone

    Published the change record.

Production build 0.71.5 2024