diff --git a/core/lib/Drupal/Core/Asset/Exception/InvalidLibrariesOverrideSpecificationException.php b/core/lib/Drupal/Core/Asset/Exception/InvalidLibrariesOverrideSpecificationException.php new file mode 100644 index 0000000..89667aa --- /dev/null +++ b/core/lib/Drupal/Core/Asset/Exception/InvalidLibrariesOverrideSpecificationException.php @@ -0,0 +1,15 @@ +getLibraryByName($new_extension, $new_name); - } - else { + $override = $extension[$name]['override']; + if ($override === FALSE) { + // Remove the library definition if false is given. unset($extension[$name]); return FALSE; } + else { + // Otherwise replace with existing library definition if it exists. + // Throw an exception if it doesn't. + list($new_extension, $new_name) = explode('/', $override); + if ($library = $this->getLibraryByName($new_extension, $new_name)) { + $extension[$name] = $library; + } + else { + throw new InvalidLibrariesOverrideSpecificationException(sprintf('The specified library %s does not exist.', $override)); + } + } } return $extension[$name]; } diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php index b861ec6..f6de366 100644 --- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Asset; use Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException; +use Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException; use Drupal\Core\Asset\Exception\InvalidLibraryFileException; use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -335,13 +336,12 @@ protected function parseLibraryInfo($extension, $path) { protected function applyLibrariesOverride($libraries, $extension) { $active_theme = $this->themeManager->getActiveTheme(); $libraries_overrides = $active_theme->getLibrariesOverride(); - $theme_path = $active_theme->getPath(); foreach ($libraries as $name => $library) { // Process libraries overrides. foreach ($libraries_overrides as $asset => $override) { // Active theme defines an override for this library. if ($asset === "$extension/$name") { - // Active theme defines an override for the whole library. Use the + // The active theme defines an override for the whole library. Use the // override key to specify that this library will be overridden when // it is called. // @see \Drupal\Core\Asset\LibraryDiscovery::getLibraryByName() @@ -356,12 +356,12 @@ protected function applyLibrariesOverride($libraries, $extension) { // Active theme defines an override for an asset within this library. // Throw an exception if the asset is not properly specified. if (substr_count($asset, '/') < 3) { - throw new \LogicException(sprintf('Library asset %s is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".', $asset)); + throw new InvalidLibrariesOverrideSpecificationException(sprintf('Library asset %s is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".', $asset)); } list(, , $sub_key, $value) = explode('/', $asset, 4); if ($sub_key === 'drupalSettings') { // drupalSettings may not be overridden. - throw new \LogicException(sprintf('drupalSettings may not be overridden in libraries-override. Trying to override %s. Use hook_library_info_alter() instead.', $asset)); + throw new InvalidLibrariesOverrideSpecificationException(sprintf('drupalSettings may not be overridden in libraries-override. Trying to override %s. Use hook_library_info_alter() instead.', $asset)); } elseif ($sub_key === 'css') { // SMACSS category should be incorporated into the asset name. @@ -373,12 +373,17 @@ protected function applyLibrariesOverride($libraries, $extension) { $parents = [$sub_key, $value]; $new_parents = [$sub_key, $override]; } - // Remove asset to be overridden, but keep its attributes. - $attributes = NestedArray::getValue($libraries[$name], $parents); - NestedArray::unsetValue($libraries[$name], $parents); - if ($override) { - // Replace with an override if specified. - NestedArray::setValue($libraries[$name], $new_parents, $attributes); + // Get the attributes of the asset to be overridden. If the key does + // not exist, then throw an exception. + $key_exists = NULL; + $attributes = NestedArray::getValue($libraries[$name], $parents, $key_exists); + if ($key_exists) { + // Remove asset to be overridden, but keep its attributes. + NestedArray::unsetValue($libraries[$name], $parents); + if ($override) { + // Replace with an override if specified. + NestedArray::setValue($libraries[$name], $new_parents, $attributes); + } } } } diff --git a/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php b/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php index e29508c..7d7c7b9 100644 --- a/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php +++ b/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Asset; +use Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException; use Drupal\simpletest\KernelTestBase; /** @@ -101,11 +102,11 @@ public function testLibrariesOverrideDrupalSettings() { // Assert that drupalSettings cannot be overridden and throws an exception. try { $library_discovery->getLibraryByName('core', 'drupal.ajax'); - $this->fail('Throw LogicException when trying to override drupalSettings'); + $this->fail('Throw Exception when trying to override drupalSettings'); } - catch (\LogicException $e) { + catch (InvalidLibrariesOverrideSpecificationException $e) { $expected_message = 'drupalSettings may not be overridden in libraries-override. Trying to override core/drupal.ajax/drupalSettings/ajaxPageState. Use hook_library_info_alter() instead.'; - $this->assertEqual($e->getMessage(), $expected_message, 'Throw LogicException when trying to override drupalSettings'); + $this->assertEqual($e->getMessage(), $expected_message, 'Throw Exception when trying to override drupalSettings'); } } @@ -129,11 +130,11 @@ public function testLibrariesOverrideMalformedAsset() { // Assert that improperly formed asset "specs" throw an exception. try { $library_discovery->getLibraryByName('core', 'drupal.dialog'); - $this->fail('Throw LogicException when specifying invalid override'); + $this->fail('Throw Exception when specifying invalid override'); } - catch (\LogicException $e) { + catch (InvalidLibrariesOverrideSpecificationException $e) { $expected_message = 'Library asset core/drupal.dialog/css is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".'; - $this->assertEqual($e->getMessage(), $expected_message, 'Throw LogicException when specifying invalid override'); + $this->assertEqual($e->getMessage(), $expected_message, 'Throw Exception when specifying invalid override'); } } @@ -172,7 +173,7 @@ public function testLibrariesOverrideOtherAssetLibraryNames() { } /** - * Tests that base theme libraries-remove still apply in sub themes. + * Tests that base theme libraries-override still apply in sub themes. */ public function testBaseThemeLibrariesOverrideInSubTheme() { $this->container->get('theme_handler')->install(['test_subtheme']); diff --git a/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml b/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml index 0939c27..e6e6f1f 100644 --- a/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml +++ b/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml @@ -5,5 +5,6 @@ version: VERSION base theme: classy core: 8.x libraries-override: - # drupalSettings libraries override. Should throw a \LogicException. + # drupalSettings libraries override. Should throw a + # \Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException. core/drupal.ajax/drupalSettings/ajaxPageState: { } diff --git a/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml b/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml index ecba74e..befe8d8 100644 --- a/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml +++ b/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml @@ -5,5 +5,6 @@ version: VERSION base theme: classy core: 8.x libraries-override: - # A malformed library asset name. Should throw a \LogicException. + # A malformed library asset name. Should throw a + # \Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException. core/drupal.dialog/css: false