Problem/Motivation

There is no way to access the default theme for the active domain. In the Domain Theme module, this was achieved by the `domain_theme_lookup` function, however, there is nothing in Domain Theme Switch to provide similar functionality.

One use-case is the Mailsystem module’s domain option for email themes.

How to reproduce

When we try to open /admin/config got the following error:

The website encountered an unexpected error. Please try again later.
TypeError: Argument 4 passed to Drupal\domain_theme_switch\Theme\ThemeSwitchNegotiator::__construct() must be an instance of Drupal\domain_theme_switch\DomainThemeLookup, instance of Drupal\Core\Config\ConfigFactory given, called in /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/Container.php on line 281 in Drupal\domain_theme_switch\Theme\ThemeSwitchNegotiator->__construct() (line 72 of modules/contrib/domain_theme_switch/src/Theme/ThemeSwitchNegotiator.php).
Drupal\domain_theme_switch\Theme\ThemeSwitchNegotiator->__construct(Object, Object, Object, Object) (Line: 281)
Drupal\Component\DependencyInjection\Container->createService(Array, 'theme.negotiator.domain_theme_switch') (Line: 173)
Drupal\Component\DependencyInjection\Container->get('theme.negotiator.domain_theme_switch') (Line: 20)
Drupal\Core\DependencyInjection\ClassResolver->getInstanceFromDefinition('theme.negotiator.domain_theme_switch') (Line: 65)
Drupal\Core\Theme\ThemeNegotiator->determineActiveTheme(Object) (Line: 405)
Drupal\Core\Theme\ThemeManager->initTheme(Object) (Line: 96)
Drupal\Core\Theme\ThemeManager->getActiveTheme() (Line: 41)
Drupal\domain_config\DomainConfigLibraryDiscoveryCollector->getCid() (Line: 340)
Drupal\Core\Cache\CacheCollector->lazyLoadCache() (Line: 144)
Drupal\Core\Cache\CacheCollector->get('select2') (Line: 44)
Drupal\Core\Asset\LibraryDiscovery->getLibrariesByExtension('select2') (Line: 58)
Drupal\Core\Asset\LibraryDiscovery->getLibraryByName('select2', 'select2.min') (Line: 32)
select2_requirements('runtime')
call_user_func_array('select2_requirements', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('requirements', Array) (Line: 111)
Drupal\system\SystemManager->listRequirements() (Line: 95)
Drupal\system\SystemManager->checkRequirements() (Line: 102)
Drupal\system\Controller\SystemController->overview('system.admin_config')
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 91)
Drupal\shield\ShieldMiddleware->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Proposed resolution

I propose adding a getter for the ThemeSwitchNegotiator’s `defaultTheme` variable.

Comments

qymanab created an issue. See original summary.

josephdpurcell’s picture

Status: Active » Needs work

Overall this makes sense to me. I do not see tests, but there are none for the module. I did not manually test this either.

One minor change:

+++ b/src/Theme/ThemeSwitchNegotiator.php
@@ -125,6 +125,14 @@ class ThemeSwitchNegotiator implements ThemeNegotiatorInterface {
+   * @return string|null

Method should have a title

qymanab’s picture

StatusFileSize
new690 bytes
qymanab’s picture

Status: Needs work » Needs review
josephdpurcell’s picture

Status: Needs review » Reviewed & tested by the community

This looks correct and it applies cleanly to the latest branch and I see no code style violations.

Setting to RTBC to get visibility to this proposal. Resolution to this blocks #2941723: Reimplement the domain option in theme settings.

abramm’s picture

Version: 8.x-1.4 » 8.x-1.x-dev
Status: Reviewed & tested by the community » Needs work

Hi,

The defaultTheme is set in applies() method and thus may not be available before this method is called. The variable is only meant to be used internally.

I'd suggest either:

1) Fetching the default theme right from the config:

$domain = \Drupal::service('domain.negotiator')->getActiveDomain();
    $config = \Drupal::config('domain_theme_switch.settings')->get($domain->id() . '_site');

or
2) Refactoring ThemeSwitchNegotiator. Both defaultTheme and adminTheme properties could be removed. Instead, a new service may be implemented to return default & admin themes.

qymanab’s picture

StatusFileSize
new4.43 KB

Changes:

- adds a DomainThemeLookup service
- refactors ThemeSwitchNegotiator to use the service

qymanab’s picture

Status: Needs work » Needs review
josephdpurcell’s picture

Status: Needs review » Needs work

Three requested changes:

  1. +++ b/domain_theme_switch.services.yml
    @@ -1,6 +1,10 @@
    +    class: Drupal\domain_theme_switch\Service\DomainThemeLookup
    

    Because this module is so lighteweight, I think this can simply be put at Drupal\domain_theme_switch\DomainThemeLookup

  2. +++ b/domain_theme_switch.services.yml
    @@ -1,6 +1,10 @@
    +    - { name: theme_negotiator, priority: 10 }
    

    Irrelevant change? No need to remove indentation here

  3. +++ b/src/Theme/ThemeSwitchNegotiator.php
    @@ -97,15 +86,16 @@ class ThemeSwitchNegotiator implements ThemeNegotiatorInterface {
    +    $theme_lookup = \Drupal::getContainer()->get('domain_theme_switch.domain_theme_lookup');
    

    Pass this in as a dependency via the __constructor

qymanab’s picture

StatusFileSize
new4.42 KB
new4.88 KB
qymanab’s picture

Status: Needs work » Needs review
josephdpurcell’s picture

Status: Needs review » Needs work

Overall this looks good. A few code style things:

  1. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,48 @@
    + * Class DomainThemeLookup
    

    Comments end in a period

    Perhaps elaborate here--what is the point of this class?

    A service that retrieves theme settings based on the domain.

  2. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,48 @@
    +   *   The config factory.
    

    This line is not needed, see https://www.drupal.org/node/1354#var

  3. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,48 @@
    +    $this->configFactory = $config_factory;
    

    Consider instead:
    $this->config = $config_factory->get('domain_theme_switch.settings'). This prevents needing to get the config bucket with every call in this class

  4. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,48 @@
    +   *   The domain id.
    

    Typically "id" is written as "ID", see https://www.drupal.org/docs/develop/standards/coding-standards#naming

  5. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,48 @@
    +  public function getAdminTheme( $domain_id) {
    

    Avoid extra whitespace after opening parenthesis

  6. +++ b/src/Theme/ThemeSwitchNegotiator.php
    @@ -68,17 +68,16 @@ class ThemeSwitchNegotiator implements ThemeNegotiatorInterface {
    +
    

    Avoid unnecessary whitespace

abramm’s picture

Thank you guys! I like the progress on this issue.
The only concern I have is the DomainThemeLookup class; can we please add an interface for it and refer the interface instead? Just in case someone wants to decorate the service.

qymanab’s picture

StatusFileSize
new5.09 KB
new2.77 KB
qymanab’s picture

Status: Needs work » Needs review
josephdpurcell’s picture

Status: Needs review » Needs work
  1. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,41 @@
    +   *   The config factory.
    

    This goes above the @var, see https://www.drupal.org/node/1354#var

  2. +++ b/src/DomainThemeLookup.php
    @@ -0,0 +1,41 @@
    +   * @param ConfigFactoryInterface $config_factory
    

    Taking code style strictly, this requires a description, see https://www.drupal.org/node/1354#param

  3. +++ b/src/DomainThemeLookupInterface.php
    @@ -0,0 +1,29 @@
    +   * @return string
    

    And this requires a description, see https://www.drupal.org/node/1354#return

  4. +++ b/src/DomainThemeLookupInterface.php
    @@ -0,0 +1,29 @@
    +   * @return string
    

    Same

  5. +++ b/src/Theme/ThemeSwitchNegotiator.php
    @@ -68,17 +68,17 @@ class ThemeSwitchNegotiator implements ThemeNegotiatorInterface {
    +   * @param \Drupal\domain_theme_switch\DomainThemeLookup
    

    Same

  6. +++ b/src/Theme/ThemeSwitchNegotiator.php
    @@ -68,17 +68,17 @@ class ThemeSwitchNegotiator implements ThemeNegotiatorInterface {
    +
    

    Remove extra whitespace

qymanab’s picture

StatusFileSize
new2.34 KB
new5.83 KB
josephdpurcell’s picture

Status: Needs work » Reviewed & tested by the community

This looks great! I see no code style violations. I did not see tests nor did I manually test.

Setting to RTBC.

abramm’s picture

Thanks for the patch.
I'm a bit busy this week but I'll try to have a look.

vuil’s picture

Issue summary: View changes
vuil’s picture

The patch #17 works for us. Thanks a lot.

abramm’s picture

Verified the patch, committing to 8.x-1.x.

  • 90a8644 committed on 8.x-1.x
    Issue #3014053 by qymanab, josephdpurcell@gmail.com, abramm, vuil:...
abramm’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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