Issue #2050269 by lauriii: hook_library_info_alter() is not called for themes

8.0.x
Alex Pott 2015-04-16 16:44:37 +02:00
parent b676df9303
commit eb1ee5ab20
9 changed files with 183 additions and 25 deletions

View File

@ -1281,15 +1281,15 @@ services:
class: Drupal\Core\Asset\AssetDumper
library.discovery:
class: Drupal\Core\Asset\LibraryDiscovery
arguments: ['@library.discovery.collector', '@module_handler']
arguments: ['@library.discovery.collector', '@cache_tags.invalidator', '@module_handler', '@theme.manager']
library.discovery.collector:
class: Drupal\Core\Asset\LibraryDiscoveryCollector
arguments: ['@cache.discovery', '@lock', '@library.discovery.parser']
arguments: ['@cache.discovery', '@lock', '@library.discovery.parser', '@theme.manager']
tags:
- { name: needs_destruction }
library.discovery.parser:
class: Drupal\Core\Asset\LibraryDiscoveryParser
arguments: ['@app.root', '@module_handler']
arguments: ['@app.root', '@module_handler', '@theme.manager']
library.dependency_resolver:
class: Drupal\Core\Asset\LibraryDependencyResolver
arguments: ['@library.discovery']

View File

@ -8,7 +8,9 @@
namespace Drupal\Core\Asset;
use Drupal\Core\Cache\CacheCollectorInterface;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
/**
* Discovers available asset libraries in Drupal.
@ -22,6 +24,13 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
*/
protected $collector;
/**
* The cache tag invalidator.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface
*/
protected $cacheTagInvalidator;
/**
* The module handler.
*
@ -29,6 +38,13 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
*/
protected $moduleHandler;
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected $themeManager;
/**
* The final library definitions, statically cached.
*
@ -44,12 +60,18 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
*
* @param \Drupal\Core\Cache\CacheCollectorInterface $library_discovery_collector
* The library discovery cache collector.
* @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tag_invalidator
* The cache tag invalidator.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
* The theme manager.
*/
public function __construct(CacheCollectorInterface $library_discovery_collector, ModuleHandlerInterface $module_handler) {
public function __construct(CacheCollectorInterface $library_discovery_collector, CacheTagsInvalidatorInterface $cache_tag_invalidator, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
$this->collector = $library_discovery_collector;
$this->cacheTagInvalidator = $cache_tag_invalidator;
$this->moduleHandler = $module_handler;
$this->themeManager = $theme_manager;
}
/**
@ -64,6 +86,7 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
// specific data for this library; e.g., localization.
$library_name = "$extension/$name";
$this->moduleHandler->alter('library', $definition, $library_name);
$this->themeManager->alter('library', $definition, $library_name);
$this->libraryDefinitions[$extension][$name] = $definition;
}
}
@ -83,7 +106,7 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
* {@inheritdoc}
*/
public function clearCachedDefinitions() {
$this->collector->clear();
$this->cacheTagInvalidator->invalidateTags(['library_info']);
}
}

View File

@ -10,19 +10,13 @@ namespace Drupal\Core\Asset;
use Drupal\Core\Cache\CacheCollector;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
/**
* A CacheCollector implementation for building library extension info.
*/
class LibraryDiscoveryCollector extends CacheCollector {
/**
* The cache key.
*
* @var string
*/
protected $cacheKey = 'library_info';
/**
* The cache backend.
*
@ -44,6 +38,13 @@ class LibraryDiscoveryCollector extends CacheCollector {
*/
protected $discoveryParser;
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected $themeManager;
/**
* Constructs a CacheCollector object.
*
@ -56,12 +57,24 @@ class LibraryDiscoveryCollector extends CacheCollector {
* @param \Drupal\Core\Asset\LibraryDiscoveryParser $discovery_parser
* The library discovery parser.
*/
public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, LibraryDiscoveryParser $discovery_parser) {
parent::__construct($this->cacheKey, $cache, $lock, array($this->cacheKey));
public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, LibraryDiscoveryParser $discovery_parser, ThemeManagerInterface $theme_manager) {
$this->themeManager = $theme_manager;
parent::__construct(NULL, $cache, $lock, ['library_info']);
$this->discoveryParser = $discovery_parser;
}
/**
* {@inheritdoc}
*/
protected function getCid() {
if (!isset($this->cid)) {
$this->cid = 'library_info:' . $this->themeManager->getActiveTheme()->getName();
}
return $this->cid;
}
/**
* {@inheritdoc}
*/
@ -71,5 +84,4 @@ class LibraryDiscoveryCollector extends CacheCollector {
return $this->storage[$key];
}
}

View File

@ -11,6 +11,7 @@ use Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException;
use Drupal\Core\Asset\Exception\InvalidLibraryFileException;
use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Component\Serialization\Yaml;
use Drupal\Component\Utility\NestedArray;
@ -27,6 +28,13 @@ class LibraryDiscoveryParser {
*/
protected $moduleHandler;
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected $themeManager;
/**
* The app root.
*
@ -42,9 +50,10 @@ class LibraryDiscoveryParser {
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct($root, ModuleHandlerInterface $module_handler) {
public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
$this->root = $root;
$this->moduleHandler = $module_handler;
$this->themeManager = $theme_manager;
}
/**
@ -299,6 +308,7 @@ class LibraryDiscoveryParser {
// Allow modules to alter the module's registered libraries.
$this->moduleHandler->alter('library_info', $libraries, $extension);
$this->themeManager->alter('library_info', $libraries, $extension);
return $libraries;
}

View File

@ -0,0 +1,45 @@
<?php
/**
* @file
* Contains \Drupal\system\Tests\Asset\LibraryDiscoveryIntegrationTest.
*/
namespace Drupal\system\Tests\Asset;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the element info.
*
* @group Render
*/
class LibraryDiscoveryIntegrationTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->container->get('theme_handler')->install(['test_theme', 'classy']);
}
/**
* Ensures that the element info can be altered by themes.
*/
public function testElementInfoByTheme() {
/** @var \Drupal\Core\Theme\ThemeInitializationInterface $theme_initializer */
$theme_initializer = $this->container->get('theme.initialization');
/** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */
$theme_manager = $this->container->get('theme.manager');
/** @var \Drupal\Core\Render\ElementInfoManagerInterface $element_info */
$library_discovery = $this->container->get('library.discovery');
$theme_manager->setActiveTheme($theme_initializer->getActiveThemeByName('test_theme'));
$this->assertTrue($library_discovery->getLibraryByName('test_theme', 'kitten'));
}
}

View File

@ -29,6 +29,10 @@ function test_theme_element_info_alter(&$info) {
}
}
function test_theme_library_info_alter(&$libraries) {
$libraries['kitten']['js'][] = 'kittens.js';
}
/**
* Tests a theme implementing an alter hook.
*

View File

@ -40,6 +40,13 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
*/
protected $libraryDiscoveryCollector;
/**
* The mocked theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $themeManager;
/**
* Test library data.
*
@ -56,17 +63,21 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
),
);
protected $activeTheme;
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
$this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
$this->themeManager = $this->getMockBuilder('Drupal\Core\Theme\ThemeManagerInterface')
->disableOriginalConstructor()
->getMock();
$this->libraryDiscoveryParser = $this->getMockBuilder('Drupal\Core\Asset\LibraryDiscoveryParser')
->disableOriginalConstructor()
->getMock();
$this->libraryDiscoveryCollector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser);
}
/**
@ -75,10 +86,21 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
* @covers ::resolveCacheMiss
*/
public function testResolveCacheMiss() {
$this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
->disableOriginalConstructor()
->getMock();
$this->themeManager->expects($this->once())
->method('getActiveTheme')
->willReturn($this->activeTheme);
$this->activeTheme->expects($this->once())
->method('getName')
->willReturn('kitten_theme');
$this->libraryDiscoveryCollector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser, $this->themeManager);
$this->libraryDiscoveryParser->expects($this->once())
->method('buildByExtension')
->with('test')
->will($this->returnValue($this->libraryData));
->willReturn($this->libraryData);
$this->assertSame($this->libraryData, $this->libraryDiscoveryCollector->get('test'));
$this->assertSame($this->libraryData, $this->libraryDiscoveryCollector->get('test'));
@ -90,12 +112,23 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
* @covers ::destruct
*/
public function testDestruct() {
$this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
->disableOriginalConstructor()
->getMock();
$this->themeManager->expects($this->once())
->method('getActiveTheme')
->willReturn($this->activeTheme);
$this->activeTheme->expects($this->once())
->method('getName')
->willReturn('kitten_theme');
$this->libraryDiscoveryCollector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser, $this->themeManager);
$this->libraryDiscoveryParser->expects($this->once())
->method('buildByExtension')
->with('test')
->will($this->returnValue($this->libraryData));
->willReturn($this->libraryData);
$lock_key = 'library_info:Drupal\Core\Cache\CacheCollector';
$lock_key = 'library_info:kitten_theme:Drupal\Core\Cache\CacheCollector';
$this->lock->expects($this->once())
->method('acquire')
@ -103,11 +136,11 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
->will($this->returnValue(TRUE));
$this->cache->expects($this->exactly(2))
->method('get')
->with('library_info')
->will($this->returnValue(FALSE));
->with('library_info:kitten_theme')
->willReturn(FALSE);
$this->cache->expects($this->once())
->method('set')
->with('library_info', array('test' => $this->libraryData), Cache::PERMANENT, array('library_info'));
->with('library_info:kitten_theme', array('test' => $this->libraryData), Cache::PERMANENT, ['library_info']);
$this->lock->expects($this->once())
->method('release')
->with($lock_key);

View File

@ -51,6 +51,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
*/
protected $moduleHandler;
/**
* The mocked theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $themeManager;
/**
* The mocked lock backend.
*
@ -65,7 +72,8 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
parent::setUp();
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler);
$this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager);
}
/**

View File

@ -37,6 +37,20 @@ class LibraryDiscoveryTest extends UnitTestCase {
*/
protected $moduleHandler;
/**
* The mocked theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $themeManager;
/**
* The cache tags invalidator.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $cacheTagsInvalidator;
/**
* Test library data.
*
@ -63,11 +77,13 @@ class LibraryDiscoveryTest extends UnitTestCase {
protected function setUp() {
parent::setUp();
$this->cacheTagsInvalidator = $this->getMock('Drupal\Core\Cache\CacheTagsInvalidatorInterface');
$this->libraryDiscoveryCollector = $this->getMockBuilder('Drupal\Core\Asset\LibraryDiscoveryCollector')
->disableOriginalConstructor()
->getMock();
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->libraryDiscovery = new LibraryDiscovery($this->libraryDiscoveryCollector, $this->moduleHandler);
$this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
$this->libraryDiscovery = new LibraryDiscovery($this->libraryDiscoveryCollector, $this->cacheTagsInvalidator, $this->moduleHandler, $this->themeManager);
}
/**
@ -85,6 +101,13 @@ class LibraryDiscoveryTest extends UnitTestCase {
$this->logicalOr($this->libraryData['test_1'], $this->libraryData['test_2']),
$this->logicalOr('test/test_1', 'test/test_2')
);
$this->themeManager->expects($this->exactly(2))
->method('alter')
->with(
'library',
$this->logicalOr($this->libraryData['test_1'], $this->libraryData['test_2']),
$this->logicalOr('test/test_1', 'test/test_2')
);
$this->libraryDiscovery->getLibrariesbyExtension('test');
// Verify that subsequent calls don't trigger hook_library_info_alter()