Loading component_library.module +25 −33 Original line number Diff line number Diff line Loading @@ -12,53 +12,45 @@ use Drupal\component_library\Form\ComponentOverrideForm; use Drupal\Component\Serialization\Json; use Drupal\Component\Serialization\Yaml; use Drupal\component_library\Entity\ComponentLibraryPattern; use Drupal\Core\Asset\AttachedAssetsInterface; use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Extension\Extension; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Drupal\component_library\Entity\ComponentLibraryAsset; /** * Implements hook_library_info_build(). */ function component_library_library_info_build() { $libraries = []; /** @var \Drupal\component_library\Entity\ComponentLibraryAsset $asset_entities */ $asset_entities = ComponentLibraryAsset::loadMultiple(); /** @var \Drupal\Core\File\FileSystemInterface $file_system */ $file_system = \Drupal::service('file_system'); foreach ($asset_entities as $asset) { $library_name = 'component_library.' . $asset->get('id'); foreach (['css', 'js'] as $asset_type) { $path = 'public://component_library_assets/' . $asset->get('id') . '/' . $asset_type; if (file_exists($path) && $asset->get($asset_type)) { $files = $file_system->scanDirectory($path, '/.*/'); foreach ($files as $file) { if ($asset_type == 'css') { $asset_path = _file_url_generator_backwards_compatibility($file->uri); $libraries[$library_name]['css']['base'][$asset_path] = []; } elseif ($asset_type == 'js') { $asset_path = _file_url_generator_backwards_compatibility($file->uri); $libraries[$library_name]['js'][$asset_path] = []; } } } \Drupal::service('component_library.asset')->processAllAssetPaths(function ($path_info) use (&$libraries) { $type = $path_info['type']; $path = $path_info['path']; $id = $path_info['id']; if ($type === 'css') { $libraries["component_library.$id"][$type]['theme'][$path] = []; } else { $libraries["component_library.$id"][$type][$path] = []; } }); return $libraries; } function _file_url_generator_backwards_compatibility($file_uri) { if (version_compare(Drupal::VERSION, '9.3', '>=')) { /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */ $file_url_generator = \Drupal::service('file_url_generator'); return $file_url_generator->generateString($file_uri); } else { return file_create_url($file_uri); } /** * Implements hook_css_alter(). */ function component_library_css_alter(&$css, AttachedAssetsInterface $assets) { \Drupal::service('component_library.asset')->processAllAssetPaths(function ($path_info) use (&$css) { $path = $path_info['path']; $path = ltrim($path, '/'); if ($path_info['type'] === 'css' && !empty($css[$path])) { // Ensure our css overrides are loaded after the theme. $css[$path]['group'] = CSS_AGGREGATE_THEME; $css[$path]['weight'] = 999999999999; } }); } /** Loading component_library.services.yml +3 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ services: class: Drupal\component_library\Routing\NotAdminRouteSubscriber tags: - { name: event_subscriber } component_library.asset: class: Drupal\component_library\Asset arguments: [] component_library.override_mode: class: Drupal\component_library\OverrideMode arguments: ['@theme.manager', '@theme.registry', '@entity_type.manager', '@redirect.destination', '@logger.factory', '@renderer', '@event_dispatcher', '@uuid', '@twig.loader.component_override', '@config.factory', '@current_user'] Loading src/Asset.php 0 → 100644 +32 −0 Original line number Diff line number Diff line <?php namespace Drupal\component_library; use Drupal\component_library\Entity\ComponentLibraryAsset; class Asset { public function processAllAssetPaths(callable $callback, $url = TRUE) { $assets = ComponentLibraryAsset::loadMultiple(); foreach ($assets as $asset) { $paths = $asset->get('paths'); foreach ($paths as $path_info) { $path_info['id'] = $asset->id(); if ($url) { $path_info['path'] = $this->fileUrlGenerator($path_info['path']); } \call_user_func($callback, $path_info); } } } private function fileUrlGenerator($file_uri) { if (version_compare(\Drupal::VERSION, '9.3', '>=')) { return \Drupal::service('file_url_generator')->generateString($file_uri); } else { return file_create_url($file_uri); } } } src/Entity/ComponentLibraryAsset.php +6 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ use Drupal\Core\Entity\EntityStorageInterface; * "theme", * "css", * "js", * "paths", * } * ) */ Loading Loading @@ -89,6 +90,11 @@ class ComponentLibraryAsset extends ConfigEntityBase { */ protected $js = []; /** * The library files that were generated. */ protected array $paths = []; /** * {@inheritdoc} */ Loading src/Form/ComponentLibraryAssetForm.php +8 −3 Original line number Diff line number Diff line Loading @@ -156,12 +156,11 @@ class ComponentLibraryAssetForm extends EntityForm { * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $result = parent::save($form, $form_state); // Re-create the files on disk and make sure they are read when aggregation // is enabled. ComponentLibraryAsset::clearFiles($this->entity); $this->generateLibraryFiles($form_state); $result = parent::save($form, $form_state); $message_args = ['%label' => $this->entity->label()]; $message = $result == SAVED_NEW Loading Loading @@ -293,19 +292,25 @@ class ComponentLibraryAssetForm extends EntityForm { * The form state after submission of the form. */ protected function generateLibraryFiles(FormStateInterface $form_state) { $paths = []; foreach (array_keys($form_state->get('library_files')) as $asset_type) { $dir = 'public://component_library_assets/' . $form_state->getValue('id') . '/' . $asset_type; $this->fileSystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); foreach ($form_state->getValue($asset_type) as $library_file) { $file_name = $library_file['name']; $file_path = "$dir/$file_name.$asset_type"; $this->fileSystem->saveData( $path = $this->fileSystem->saveData( $library_file['code'], $file_path, FileSystemInterface::EXISTS_REPLACE ); $paths[] = [ 'type' => $asset_type, 'path' => $path, ]; } } $this->getEntity()->set('paths', $paths); $this->libraryDiscovery->clearCachedDefinitions(); } Loading Loading
component_library.module +25 −33 Original line number Diff line number Diff line Loading @@ -12,53 +12,45 @@ use Drupal\component_library\Form\ComponentOverrideForm; use Drupal\Component\Serialization\Json; use Drupal\Component\Serialization\Yaml; use Drupal\component_library\Entity\ComponentLibraryPattern; use Drupal\Core\Asset\AttachedAssetsInterface; use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Extension\Extension; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Drupal\component_library\Entity\ComponentLibraryAsset; /** * Implements hook_library_info_build(). */ function component_library_library_info_build() { $libraries = []; /** @var \Drupal\component_library\Entity\ComponentLibraryAsset $asset_entities */ $asset_entities = ComponentLibraryAsset::loadMultiple(); /** @var \Drupal\Core\File\FileSystemInterface $file_system */ $file_system = \Drupal::service('file_system'); foreach ($asset_entities as $asset) { $library_name = 'component_library.' . $asset->get('id'); foreach (['css', 'js'] as $asset_type) { $path = 'public://component_library_assets/' . $asset->get('id') . '/' . $asset_type; if (file_exists($path) && $asset->get($asset_type)) { $files = $file_system->scanDirectory($path, '/.*/'); foreach ($files as $file) { if ($asset_type == 'css') { $asset_path = _file_url_generator_backwards_compatibility($file->uri); $libraries[$library_name]['css']['base'][$asset_path] = []; } elseif ($asset_type == 'js') { $asset_path = _file_url_generator_backwards_compatibility($file->uri); $libraries[$library_name]['js'][$asset_path] = []; } } } \Drupal::service('component_library.asset')->processAllAssetPaths(function ($path_info) use (&$libraries) { $type = $path_info['type']; $path = $path_info['path']; $id = $path_info['id']; if ($type === 'css') { $libraries["component_library.$id"][$type]['theme'][$path] = []; } else { $libraries["component_library.$id"][$type][$path] = []; } }); return $libraries; } function _file_url_generator_backwards_compatibility($file_uri) { if (version_compare(Drupal::VERSION, '9.3', '>=')) { /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */ $file_url_generator = \Drupal::service('file_url_generator'); return $file_url_generator->generateString($file_uri); } else { return file_create_url($file_uri); } /** * Implements hook_css_alter(). */ function component_library_css_alter(&$css, AttachedAssetsInterface $assets) { \Drupal::service('component_library.asset')->processAllAssetPaths(function ($path_info) use (&$css) { $path = $path_info['path']; $path = ltrim($path, '/'); if ($path_info['type'] === 'css' && !empty($css[$path])) { // Ensure our css overrides are loaded after the theme. $css[$path]['group'] = CSS_AGGREGATE_THEME; $css[$path]['weight'] = 999999999999; } }); } /** Loading
component_library.services.yml +3 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ services: class: Drupal\component_library\Routing\NotAdminRouteSubscriber tags: - { name: event_subscriber } component_library.asset: class: Drupal\component_library\Asset arguments: [] component_library.override_mode: class: Drupal\component_library\OverrideMode arguments: ['@theme.manager', '@theme.registry', '@entity_type.manager', '@redirect.destination', '@logger.factory', '@renderer', '@event_dispatcher', '@uuid', '@twig.loader.component_override', '@config.factory', '@current_user'] Loading
src/Asset.php 0 → 100644 +32 −0 Original line number Diff line number Diff line <?php namespace Drupal\component_library; use Drupal\component_library\Entity\ComponentLibraryAsset; class Asset { public function processAllAssetPaths(callable $callback, $url = TRUE) { $assets = ComponentLibraryAsset::loadMultiple(); foreach ($assets as $asset) { $paths = $asset->get('paths'); foreach ($paths as $path_info) { $path_info['id'] = $asset->id(); if ($url) { $path_info['path'] = $this->fileUrlGenerator($path_info['path']); } \call_user_func($callback, $path_info); } } } private function fileUrlGenerator($file_uri) { if (version_compare(\Drupal::VERSION, '9.3', '>=')) { return \Drupal::service('file_url_generator')->generateString($file_uri); } else { return file_create_url($file_uri); } } }
src/Entity/ComponentLibraryAsset.php +6 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ use Drupal\Core\Entity\EntityStorageInterface; * "theme", * "css", * "js", * "paths", * } * ) */ Loading Loading @@ -89,6 +90,11 @@ class ComponentLibraryAsset extends ConfigEntityBase { */ protected $js = []; /** * The library files that were generated. */ protected array $paths = []; /** * {@inheritdoc} */ Loading
src/Form/ComponentLibraryAssetForm.php +8 −3 Original line number Diff line number Diff line Loading @@ -156,12 +156,11 @@ class ComponentLibraryAssetForm extends EntityForm { * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $result = parent::save($form, $form_state); // Re-create the files on disk and make sure they are read when aggregation // is enabled. ComponentLibraryAsset::clearFiles($this->entity); $this->generateLibraryFiles($form_state); $result = parent::save($form, $form_state); $message_args = ['%label' => $this->entity->label()]; $message = $result == SAVED_NEW Loading Loading @@ -293,19 +292,25 @@ class ComponentLibraryAssetForm extends EntityForm { * The form state after submission of the form. */ protected function generateLibraryFiles(FormStateInterface $form_state) { $paths = []; foreach (array_keys($form_state->get('library_files')) as $asset_type) { $dir = 'public://component_library_assets/' . $form_state->getValue('id') . '/' . $asset_type; $this->fileSystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); foreach ($form_state->getValue($asset_type) as $library_file) { $file_name = $library_file['name']; $file_path = "$dir/$file_name.$asset_type"; $this->fileSystem->saveData( $path = $this->fileSystem->saveData( $library_file['code'], $file_path, FileSystemInterface::EXISTS_REPLACE ); $paths[] = [ 'type' => $asset_type, 'path' => $path, ]; } } $this->getEntity()->set('paths', $paths); $this->libraryDiscovery->clearCachedDefinitions(); } Loading