LibraryDiscoveryCollector.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php
  2. namespace Drupal\Core\Asset;
  3. use Drupal\Component\Utility\NestedArray;
  4. use Drupal\Core\Asset\Exception\InvalidLibrariesExtendSpecificationException;
  5. use Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException;
  6. use Drupal\Core\Cache\CacheCollector;
  7. use Drupal\Core\Cache\CacheBackendInterface;
  8. use Drupal\Core\Lock\LockBackendInterface;
  9. use Drupal\Core\Theme\ThemeManagerInterface;
  10. /**
  11. * A CacheCollector implementation for building library extension info.
  12. */
  13. class LibraryDiscoveryCollector extends CacheCollector {
  14. /**
  15. * The library discovery parser.
  16. *
  17. * @var \Drupal\Core\Asset\LibraryDiscoveryParser
  18. */
  19. protected $discoveryParser;
  20. /**
  21. * The theme manager.
  22. *
  23. * @var \Drupal\Core\Theme\ThemeManagerInterface
  24. */
  25. protected $themeManager;
  26. /**
  27. * Constructs a CacheCollector object.
  28. *
  29. * @param \Drupal\Core\Cache\CacheBackendInterface $cache
  30. * The cache backend.
  31. * @param \Drupal\Core\Lock\LockBackendInterface $lock
  32. * The lock backend.
  33. * @param \Drupal\Core\Asset\LibraryDiscoveryParser $discovery_parser
  34. * The library discovery parser.
  35. * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
  36. * The theme manager.
  37. */
  38. public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, LibraryDiscoveryParser $discovery_parser, ThemeManagerInterface $theme_manager) {
  39. $this->themeManager = $theme_manager;
  40. parent::__construct(NULL, $cache, $lock, ['library_info']);
  41. $this->discoveryParser = $discovery_parser;
  42. }
  43. /**
  44. * {@inheritdoc}
  45. */
  46. protected function getCid() {
  47. if (!isset($this->cid)) {
  48. $this->cid = 'library_info:' . $this->themeManager->getActiveTheme()->getName();
  49. }
  50. return $this->cid;
  51. }
  52. /**
  53. * {@inheritdoc}
  54. */
  55. protected function resolveCacheMiss($key) {
  56. $this->storage[$key] = $this->getLibraryDefinitions($key);
  57. $this->persist($key);
  58. return $this->storage[$key];
  59. }
  60. /**
  61. * Returns the library definitions for a given extension.
  62. *
  63. * This also implements libraries-overrides for entire libraries that have
  64. * been specified by the LibraryDiscoveryParser.
  65. *
  66. * @param string $extension
  67. * The name of the extension for which library definitions will be returned.
  68. *
  69. * @return array
  70. * The library definitions for $extension with overrides applied.
  71. *
  72. * @throws \Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException
  73. */
  74. protected function getLibraryDefinitions($extension) {
  75. $libraries = $this->discoveryParser->buildByExtension($extension);
  76. foreach ($libraries as $name => $definition) {
  77. // Handle libraries that are marked for override or removal.
  78. // @see \Drupal\Core\Asset\LibraryDiscoveryParser::applyLibrariesOverride()
  79. if (isset($definition['override'])) {
  80. if ($definition['override'] === FALSE) {
  81. // Remove the library definition if FALSE is given.
  82. unset($libraries[$name]);
  83. }
  84. else {
  85. // Otherwise replace with existing library definition if it exists.
  86. // Throw an exception if it doesn't.
  87. list($replacement_extension, $replacement_name) = explode('/', $definition['override']);
  88. $replacement_definition = $this->get($replacement_extension);
  89. if (isset($replacement_definition[$replacement_name])) {
  90. $libraries[$name] = $replacement_definition[$replacement_name];
  91. }
  92. else {
  93. throw new InvalidLibrariesOverrideSpecificationException(sprintf('The specified library %s does not exist.', $definition['override']));
  94. }
  95. }
  96. }
  97. else {
  98. // If libraries are not overridden, then apply libraries-extend.
  99. $libraries[$name] = $this->applyLibrariesExtend($extension, $name, $definition);
  100. }
  101. }
  102. return $libraries;
  103. }
  104. /**
  105. * Applies the libraries-extend specified by the active theme.
  106. *
  107. * This extends the library definitions with the those specified by the
  108. * libraries-extend specifications for the active theme.
  109. *
  110. * @param string $extension
  111. * The name of the extension for which library definitions will be extended.
  112. * @param string $library_name
  113. * The name of the library whose definitions is to be extended.
  114. * @param $library_definition
  115. * The library definition to be extended.
  116. *
  117. * @return array
  118. * The library definition extended as specified by libraries-extend.
  119. *
  120. * @throws \Drupal\Core\Asset\Exception\InvalidLibrariesExtendSpecificationException
  121. */
  122. protected function applyLibrariesExtend($extension, $library_name, $library_definition) {
  123. $libraries_extend = $this->themeManager->getActiveTheme()->getLibrariesExtend();
  124. if (!empty($libraries_extend["$extension/$library_name"])) {
  125. foreach ($libraries_extend["$extension/$library_name"] as $library_extend_name) {
  126. if (!is_string($library_extend_name)) {
  127. // Only string library names are allowed.
  128. throw new InvalidLibrariesExtendSpecificationException('The libraries-extend specification for each library must be a list of strings.');
  129. }
  130. list($new_extension, $new_library_name) = explode('/', $library_extend_name, 2);
  131. $new_libraries = $this->get($new_extension);
  132. if (isset($new_libraries[$new_library_name])) {
  133. $library_definition = NestedArray::mergeDeep($library_definition, $new_libraries[$new_library_name]);
  134. }
  135. else {
  136. throw new InvalidLibrariesExtendSpecificationException(sprintf('The specified library "%s" does not exist.', $library_extend_name));
  137. }
  138. }
  139. }
  140. return $library_definition;
  141. }
  142. /**
  143. * {@inheritdoc}
  144. */
  145. public function reset() {
  146. parent::reset();
  147. $this->cid = NULL;
  148. }
  149. }