cookie_blocking_libraries-1.0.x-dev/src/LibrariesService.php
src/LibrariesService.php
<?php namespace Drupal\cookie_blocking_libraries; use Drupal\Core\Asset\LibraryDiscoveryInterface; use Drupal\Core\Cache\Cache; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ThemeHandlerInterface; /** * Libraries Service service. */ class LibrariesService implements LibrariesServiceInterface { /** * The module handler. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected ModuleHandlerInterface $moduleHandler; /** * The theme handler. * * @var \Drupal\Core\Extension\ThemeHandlerInterface */ protected ThemeHandlerInterface $themeHandler; /** * The library discovery service. * * @var \Drupal\Core\Asset\LibraryDiscoveryInterface */ protected LibraryDiscoveryInterface $libraryDiscovery; /** * The plugin manager. * * @var \Drupal\cookie_blocking_libraries\CookieImplementationPluginManager */ protected CookieImplementationPluginManager $pluginManager; /** * The enabled implementation plugin. * * @var \Drupal\cookie_blocking_libraries\CookieImplementationInterface|null */ protected CookieImplementationInterface|null $plugin; /** * Constructs a LibrariesService object. * * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler * The theme handler. * @param \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery * The library discovery service. * @param \Drupal\cookie_blocking_libraries\CookieImplementationPluginManager $plugin_manager * The plugin manager. */ public function __construct(ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, LibraryDiscoveryInterface $library_discovery, CookieImplementationPluginManager $plugin_manager) { $this->moduleHandler = $module_handler; $this->themeHandler = $theme_handler; $this->libraryDiscovery = $library_discovery; $this->pluginManager = $plugin_manager; } /** * {@inheritDoc} */ public function flushLibraries() : void { Cache::invalidateTags(['library_info']); \Drupal::service('asset.css.collection_optimizer')->deleteAll(); \Drupal::service('asset.js.collection_optimizer')->deleteAll(); _drupal_flush_css_js(); } /** * {@inheritDoc} */ public function getAllLibraries() : array { $modules = $this->moduleHandler->getModuleList(); $themes = $this->themeHandler->rebuildThemeData(); $extensions = array_merge($modules, $themes); // phpcs:ignore $root = \Drupal::root(); $libraries = ['core' => $this->libraryDiscovery->getLibrariesByExtension('core')]; foreach ($extensions as $extension_name => $extension) { $hasJs = FALSE; $module_libraries = $this->libraryDiscovery->getLibrariesByExtension($extension_name); foreach ($module_libraries as $library) { if (!empty($library['js'])) { $hasJs = TRUE; break; } } if ($hasJs) { $libraries[$extension_name] = $module_libraries; } } return $libraries; } /** * {@inheritDoc} */ public function getPageAttachments() : array { if (method_exists($this->moduleHandler, 'invokeAllWith')) { $implementations = []; $this->moduleHandler->invokeAllWith( 'page_attachments', function (callable $hook, string $module) use (&$implementations) { $implementations[$module] = []; try { $hook($implementations[$module]); if (isset($implementations[$module]["#attached"]["html_head"])) { foreach ($implementations[$module]["#attached"]["html_head"] as &$attachment) { $implementations[$module]['identifiers'][] = array_pop($attachment); } } } catch (\Throwable $ex) { $implementations[$module]['ex'] = $ex; } } ); } return $implementations; } /** * Get the enabled plugin. * * @return \Drupal\cookie_blocking_libraries\CookieImplementationInterface|null * The enabled plugin. */ public function getPlugin() : CookieImplementationInterface|null { if (!empty($this->plugin)) { return $this->plugin; } $this->plugin = $this->pluginManager->getEnabledPlugin(); return $this->plugin; } /** * {@inheritDoc} */ public function alterLibraries(array &$libraries, $extension) : void { if (empty($this->getPlugin())) { return; } $selections = \Drupal::config('cookie_blocking_libraries.categorisation_settings')->get('selections') ?? []; $type = $selections[$extension]['type'] ?? $this->getPlugin()->getDefaultCategory(); if ($type == '-nothing-') { return; } foreach ($libraries as &$library) { if (!empty($library['js'])) { foreach ($library['js'] as &$js) { $this->getPlugin()->alterLibrary($js, $extension, $type); } } } } /** * {@inheritDoc} */ public function alterAttachments(array &$attachments) : void { if (empty($this->getPlugin())) { return; } $selections = \Drupal::config('cookie_blocking_libraries.categorisation_settings')->get('attachments') ?? []; if (!empty($attachments["#attached"]["html_head"])) { foreach ($attachments["#attached"]["html_head"] as &$attachment) { $extension = array_pop($attachment); $attachment[] = $extension; foreach ($attachment as &$html) { if (isset($html['#tag']) && $html['#tag'] == 'script') { $type = $this->getAttachmentLibraryType($extension, $selections); if ($type == '-nothing-') { return; } $this->getPlugin()->alterAttachment($html, $extension, $type); } } } } } /** * Get the type from the categorisation form settings. * * @param string $identifier * The script attachment identifier. * @param array $config * The config. * * @return string * The identifed type, or the plugin's default. */ protected function getAttachmentLibraryType($identifier, array $config) { foreach ($config as $extension => $type) { if (substr($identifier, 0, strlen($extension)) == $extension) { return $type['type']; } if (isset($type['identifiers'])) { $identifiers = explode('|', $type['identifiers']); if (in_array($identifier, $identifiers)) { return $type['type']; } } } return $this->getPlugin()->getDefaultCategory(); } }