Commit 08ce5a70 authored by alexpott's avatar alexpott

Issue #2448847 by dawehner, arlinsandbulte: [regression] Themes unable to...

Issue #2448847 by dawehner, arlinsandbulte: [regression] Themes unable to implement hook_theme_registry_alter()
parent 4b812ec9
......@@ -1092,7 +1092,9 @@ services:
class: Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry
theme.manager:
class: Drupal\Core\Theme\ThemeManager
arguments: ['@app.root', '@theme.registry', '@theme.negotiator', '@theme.initialization', '@request_stack', '@module_handler']
arguments: ['@app.root', '@theme.negotiator', '@theme.initialization', '@request_stack', '@module_handler']
calls:
- [setThemeRegistry, ['@theme.registry']]
theme.initialization:
class: Drupal\Core\Theme\ThemeInitialization
arguments: ['@app.root', '@theme_handler', '@state']
......@@ -1101,6 +1103,8 @@ services:
arguments: ['@app.root', '@cache.default', '@lock', '@module_handler', '@theme_handler', '@theme.initialization']
tags:
- { name: needs_destruction }
calls:
- [setThemeManager, ['@theme.manager']]
authentication:
class: Drupal\Core\Authentication\AuthenticationManager
tags:
......
......@@ -130,6 +130,13 @@ class Registry implements DestructableInterface {
*/
protected $themeHandler;
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected $themeManager;
/**
* Constructs a \Drupal\Core\Theme\Registry object.
*
......@@ -158,6 +165,16 @@ public function __construct($root, CacheBackendInterface $cache, LockBackendInte
$this->themeInitialization = $theme_initialization;
}
/**
* Sets the theme manager.
*
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
* The theme manager.
*/
public function setThemeManager(ThemeManagerInterface $theme_manager) {
$this->themeManager = $theme_manager;
}
/**
* Initializes a theme with a certain name.
*
......@@ -173,7 +190,7 @@ protected function init($theme_name = NULL) {
}
// Unless instantiated for a specific theme, use globals.
if (!isset($theme_name)) {
$this->theme = \Drupal::theme()->getActiveTheme();
$this->theme = $this->themeManager->getActiveTheme();
}
// Instead of the active theme, a specific theme was requested.
else {
......@@ -326,9 +343,9 @@ protected function build() {
// Finally, hooks provided by the theme itself.
$this->processExtension($cache, $this->theme->getName(), 'theme', $this->theme->getName(), $this->theme->getPath());
// Let modules alter the registry.
// Let modules and themes alter the registry.
$this->moduleHandler->alter('theme_registry', $cache);
// @todo Do we want to allow themes to take part?
$this->themeManager->alterForTheme($this->theme, 'theme_registry', $cache);
// @todo Implement more reduction of the theme registry entry.
// Optimize the registry to not have empty arrays for functions.
......
......@@ -62,8 +62,6 @@ class ThemeManager implements ThemeManagerInterface {
*
* @param string $root
* The app root.
* @param \Drupal\Core\Theme\Registry $theme_registry
* The theme registry.
* @param \Drupal\Core\Theme\ThemeNegotiatorInterface $theme_negotiator
* The theme negotiator.
* @param \Drupal\Core\Theme\ThemeInitialization $theme_initialization
......@@ -72,15 +70,27 @@ class ThemeManager implements ThemeManagerInterface {
* The request stack.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
*/
public function __construct($root, Registry $theme_registry, ThemeNegotiatorInterface $theme_negotiator, ThemeInitialization $theme_initialization, RequestStack $request_stack, ModuleHandlerInterface $module_handler) {
public function __construct($root, ThemeNegotiatorInterface $theme_negotiator, ThemeInitialization $theme_initialization, RequestStack $request_stack, ModuleHandlerInterface $module_handler) {
$this->root = $root;
$this->themeNegotiator = $theme_negotiator;
$this->themeRegistry = $theme_registry;
$this->themeInitialization = $theme_initialization;
$this->requestStack = $request_stack;
$this->moduleHandler = $module_handler;
}
/**
* Sets the theme registry.
*
* @param \Drupal\Core\Theme\Registry $theme_registry
* The theme registry.
*
* @return $this
*/
public function setThemeRegistry(Registry $theme_registry) {
$this->themeRegistry = $theme_registry;
return $this;
}
/**
* {@inheritdoc}
*/
......@@ -402,7 +412,7 @@ protected function initTheme(RouteMatchInterface $route_match = NULL) {
*
* @todo Should we cache some of these information?
*/
public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
public function alterForTheme(ActiveTheme $theme, $type, &$data, &$context1 = NULL, &$context2 = NULL) {
// Most of the time, $type is passed as a string, so for performance,
// normalize it to that. When passed as an array, usually the first item in
// the array is a generic type, and additional items in the array are more
......@@ -419,7 +429,6 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
}
$theme_keys = array();
$theme = $this->getActiveTheme();
foreach ($theme->getBaseThemes() as $base) {
$theme_keys[] = $base->getName();
}
......@@ -446,4 +455,12 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
}
}
/**
* {@inheritdoc}
*/
public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
$theme = $this->getActiveTheme();
$this->alterForTheme($theme, $type, $data, $context1, $context2);
}
}
......@@ -69,6 +69,8 @@ public function setActiveTheme(ActiveTheme $active_theme);
/**
* Passes alterable variables to specific $theme_TYPE_alter() implementations.
*
* It also invokes alter hooks for all base themes.
*
* $theme specifies the theme name of the active theme and all its base
* themes.
*
......@@ -122,4 +124,24 @@ public function setActiveTheme(ActiveTheme $active_theme);
*/
public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL);
/**
* Provides an alter hook for a specific theme.
*
* Similar to ::alter, it also invokes the alter hooks for the base themes.
*
* @param \Drupal\Core\Theme\ActiveTheme $theme
* A manually specified theme.
* @param string|array $type
* A string describing the type of the alterable $data.
* @param mixed $data
* The variable that will be passed to $theme_TYPE_alter() implementations
* @param mixed $context1
* (optional) An additional variable that is passed by reference.
* @param mixed $context2
* (optional) An additional variable that is passed by reference.
*
* @see ::alter
*/
public function alterForTheme(ActiveTheme $theme, $type, &$data, &$context1 = NULL, &$context2 = NULL);
}
......@@ -23,7 +23,7 @@ class RegistryTest extends KernelTestBase {
*
* @var array
*/
public static $modules = array('theme_test');
public static $modules = array('theme_test', 'system');
protected $profile = 'testing';
/**
......@@ -72,8 +72,11 @@ public function testMultipleSubThemes() {
$theme_handler->install(['test_basetheme', 'test_subtheme', 'test_subsubtheme']);
$registry_subsub_theme = new Registry(\Drupal::root(), \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_subsubtheme');
$registry_subsub_theme->setThemeManager(\Drupal::theme());
$registry_sub_theme = new Registry(\Drupal::root(), \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_subtheme');
$registry_sub_theme->setThemeManager(\Drupal::theme());
$registry_base_theme = new Registry(\Drupal::root(), \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_basetheme');
$registry_base_theme->setThemeManager(\Drupal::theme());
$preprocess_functions = $registry_subsub_theme->get()['theme_test_template_test']['preprocess functions'];
$this->assertIdentical([
......@@ -96,4 +99,20 @@ public function testMultipleSubThemes() {
'test_basetheme_preprocess_theme_test_template_test',
], $preprocess_functions);
}
/**
* Tests that the theme registry can be altered by themes.
*/
public function testThemeRegistryAlterByTheme() {
/** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
$theme_handler = \Drupal::service('theme_handler');
$theme_handler->install(['test_theme']);
$theme_handler->setDefault('test_theme');
$registry = new Registry(\Drupal::root(), \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme');
$registry->setThemeManager(\Drupal::theme());
$this->assertEqual('value', $registry->get()['theme_test_template_test']['variables']['additional']);
}
}
......@@ -94,3 +94,10 @@ function test_theme_theme_test_function_suggestions__theme_override($variables)
function test_theme_theme_test_function_suggestions__module_override($variables) {
return 'Theme function overridden based on new theme suggestion provided by a module.';
}
/**
* Implements hook_theme_registry_alter().
*/
function test_theme_theme_registry_alter(&$registry) {
$registry['theme_test_template_test']['variables']['additional'] = 'value';
}
......@@ -59,6 +59,13 @@ class RegistryTest extends UnitTestCase {
*/
protected $themeInitialization;
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $themeManager;
/**
* {@inheritdoc}
*/
......@@ -70,6 +77,7 @@ protected function setUp() {
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
$this->themeInitialization = $this->getMock('Drupal\Core\Theme\ThemeInitializationInterface');
$this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
$this->setupTheme();
}
......@@ -124,6 +132,7 @@ public function testGetRegistryForModule() {
protected function setupTheme($theme_name = NULL) {
$this->registry = new TestRegistry($this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization, $theme_name);
$this->registry->setThemeManager($this->themeManager);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment