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();
}
}
