class ContainerManager in GoogleTagManager 8
Defines the Google tag container manager.
Hierarchy
- class \Drupal\google_tag\Entity\ContainerManager implements ContainerManagerInterface uses StringTranslationTrait
Expanded class hierarchy of ContainerManager
1 string reference to 'ContainerManager'
1 service uses ContainerManager
File
- src/
Entity/ ContainerManager.php, line 18
Namespace
Drupal\google_tag\EntityView source
class ContainerManager implements ContainerManagerInterface {
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The module configuration.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $config;
/**
* The file system.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* The cache backend.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* The logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* {@inheritdoc}
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, FileSystemInterface $file_system, CacheBackendInterface $cache, MessengerInterface $messenger, LoggerChannelFactoryInterface $logger_factory) {
$this->entityTypeManager = $entity_type_manager;
$this->config = $config_factory
->get('google_tag.settings');
$this->fileSystem = $file_system;
$this->cache = $cache;
$this->messenger = $messenger;
$this->logger = $logger_factory
->get('google_tag');
}
/**
* {@inheritdoc}
*/
public function createAssets(ConfigEntityInterface $container) {
$include_script_as_file = $this->config
->get('include_file');
if (!$include_script_as_file) {
return $this
->saveSnippets($container);
}
$result = TRUE;
$directory = $container
->snippetDirectory();
if (!is_dir($directory) || !_google_tag_is_writable($directory) || !_google_tag_is_executable($directory)) {
$result = _file_prepare_directory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
}
if ($result) {
$result = $this
->saveSnippets($container);
}
else {
$args = [
'%directory' => $directory,
];
$message = 'The directory %directory could not be prepared for use, possibly due to file system permissions. The directory either does not exist, or is not writable or searchable.';
$this
->displayMessage($message, $args, MessengerInterface::TYPE_ERROR);
$this->logger
->error($message, $args);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function saveSnippets(ConfigEntityInterface $container) {
$include_script_as_file = $this->config
->get('include_file');
// Save the altered snippets after hook_google_tag_snippets_alter().
$result = TRUE;
$snippets = $container
->snippets();
foreach ($snippets as $type => $snippet) {
if ($include_script_as_file && $type != 'noscript') {
// Write to file.
$uri = $container
->snippetURI($type);
$path = $this->fileSystem
->saveData($snippet, $uri, FileSystemInterface::EXISTS_REPLACE);
$result = !$path ? FALSE : $result;
}
else {
// Write to cache (noscript is always inline).
$cid = $container
->snippetCid($type);
$this->cache
->set($cid, $snippet, CacheBackendInterface::CACHE_PERMANENT, $container
->getCacheTags());
}
}
$args = [
'@count' => count($snippets),
'%container' => $container
->get('label'),
];
if (!$result) {
$message = 'An error occurred saving @count snippet files for %container container. Contact the site administrator if this persists.';
$this
->displayMessage($message, $args, MessengerInterface::TYPE_ERROR);
$this->logger
->error($message, $args);
}
else {
$message = 'Created @count snippet files for %container container based on configuration.';
$this
->displayMessage($message, $args);
// Reset the URL query argument so browsers reload snippet files.
_drupal_flush_css_js();
}
return $result;
}
/**
* Displays a message to admin users.
*
* @param string $message
* The message to display.
* @param array $args
* (optional) An associative array of replacements.
* @param string $type
* (optional) The message type. Defaults to 'status'.
*/
public function displayMessage($message, array $args = [], $type = MessengerInterface::TYPE_STATUS) {
global $_google_tag_display_message;
if ($_google_tag_display_message) {
$this->messenger
->addMessage($this
->t($message, $args), $type, TRUE);
}
}
/**
* Returns container entity IDs.
*
* @return array
* The entity ID array.
*/
public function loadContainerIDs() {
return $this->entityTypeManager
->getStorage('google_tag_container')
->getQuery()
->condition('status', 1)
->sort('weight')
->execute();
}
/**
* {@inheritdoc}
*/
public function getScriptAttachments(array &$attachments) {
$ids = $this
->loadContainerIDs();
$containers = $this->entityTypeManager
->getStorage('google_tag_container')
->loadMultiple($ids);
foreach ($containers as $container) {
if (!$container
->insertSnippet()) {
continue;
}
if (!$this
->findAssets($container)) {
// Create snippet files (e.g. after cache rebuild).
$this
->createAssets($container);
}
static $weight = 9;
$include_script_as_file = $this->config
->get('include_file');
$include_classes = $container
->get('include_classes');
// @todo Only want one data_layer snippet even with multiple containers.
// If user sorts containers such that the first does not define the data
// layer, then validate this or adjust for it here.
// Sort the items being added and put the data_layer at top?
$types = $include_classes ? [
'data_layer',
'script',
] : [
'script',
];
// Add data_layer and script snippets to head (no longer by default).
$function = $include_script_as_file ? 'fileTag' : 'inlineTag';
foreach ($types as $type) {
$attachments['#attached']['html_head'][] = $container
->{$function}($type, $weight++);
}
}
}
/**
* {@inheritdoc}
*/
public function getNoScriptAttachments(array &$page) {
$ids = $this
->loadContainerIDs();
$containers = $this->entityTypeManager
->getStorage('google_tag_container')
->loadMultiple($ids);
foreach ($containers as $container) {
if (!$container
->insertSnippet()) {
continue;
}
$page += $container
->noscriptTag();
}
}
/**
* {@inheritdoc}
*/
public function createAllAssets() {
$ids = $this
->loadContainerIDs();
if (!$ids) {
return TRUE;
}
// Create snippet files for enabled containers.
$containers = $this->entityTypeManager
->getStorage('google_tag_container')
->loadMultiple($ids);
$result = TRUE;
foreach ($containers as $container) {
$result = !$this
->createAssets($container) ? FALSE : $result;
}
return $result;
}
/**
* {@inheritdoc}
*/
public function deleteAllAssets() {
if ($this->config
->get('flush_snippets')) {
$directory = $this->config
->get('uri');
if (!empty($directory)) {
// Remove any stale files (e.g. module update or machine name change).
return $this->fileSystem
->deleteRecursive($directory . '/google_tag');
}
}
$ids = $this
->loadContainerIDs();
if (!$ids) {
return TRUE;
}
// Delete snippet files for enabled containers.
$containers = $this->entityTypeManager
->getStorage('google_tag_container')
->loadMultiple($ids);
$result = TRUE;
foreach ($containers as $container) {
$result = !$this
->deleteAssets($container) ? FALSE : $result;
}
return $result;
}
/**
* {@inheritdoc}
*/
public function deleteAssets(ConfigEntityInterface $container) {
$include_classes = $container
->get('include_classes');
$types = $include_classes ? [
'data_layer',
'script',
'noscript',
] : [
'script',
'noscript',
];
$directory = $container
->snippetDirectory();
$result = TRUE;
if (!empty($directory) && is_dir($directory)) {
$result = $this->fileSystem
->deleteRecursive($directory);
}
$args = [
'@count' => count($types),
'%container' => $container
->get('label'),
];
if (!$result) {
$message = 'An error occurred deleting @count snippet files for %container container. Contact the site administrator if this persists.';
$this
->displayMessage($message, $args, MessengerInterface::TYPE_ERROR);
$this->logger
->error($message, $args);
}
else {
$message = 'Deleted @count snippet files for %container container.';
$this
->displayMessage($message, $args);
// In case this is not called during core cache rebuild, then [OMIT?]
// Reset the URL query argument so browsers reload snippet files.
// @todo Do these snippet files have the js token in a query argument? Yes. [OMIT]
_drupal_flush_css_js();
}
return $result;
}
/**
* {@inheritdoc}
*/
public function findAssets(ConfigEntityInterface $container) {
$include_script_as_file = $this->config
->get('include_file');
$include_classes = $container
->get('include_classes');
$types = $include_classes ? [
'data_layer',
'script',
'noscript',
] : [
'script',
'noscript',
];
foreach ($types as $type) {
if ($include_script_as_file && $type != 'noscript') {
$uri = $container
->snippetURI($type);
if (!is_file($uri)) {
return FALSE;
}
}
else {
if (!($cache = $this->cache
->get($container
->snippetCid($type)))) {
return FALSE;
}
}
}
return TRUE;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ContainerManager:: |
protected | property | The cache backend. | |
ContainerManager:: |
protected | property | The module configuration. | |
ContainerManager:: |
protected | property | The entity type manager. | |
ContainerManager:: |
protected | property | The file system. | |
ContainerManager:: |
protected | property | The logger. | |
ContainerManager:: |
protected | property | The messenger. | |
ContainerManager:: |
public | function |
Prepares directory for and saves snippet files for all containers. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function |
Prepares directory for and saves snippet files for a container. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function |
Deletes snippet files for all containers. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function |
Deletes snippet files for a container. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function | Displays a message to admin users. | |
ContainerManager:: |
public | function |
Finds snippet files for a container. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function |
Adds render array items of page top attachments. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function |
Adds render array items of page attachments. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function | Returns container entity IDs. | |
ContainerManager:: |
public | function |
Saves JS snippet files based on current settings. Overrides ContainerManagerInterface:: |
|
ContainerManager:: |
public | function |
Constructs a ContainerManager. Overrides ContainerManagerInterface:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |