class SnippetBuilder in Hotjar 8.2
Same name and namespace in other branches
- 8 src/SnippetBuilder.php \Drupal\hotjar\SnippetBuilder
Snippet builder service.
@package Drupal\hotjar
Hierarchy
- class \Drupal\hotjar\SnippetBuilder implements ContainerInjectionInterface, SnippetBuilderInterface uses StringTranslationTrait
Expanded class hierarchy of SnippetBuilder
1 string reference to 'SnippetBuilder'
1 service uses SnippetBuilder
File
- src/
SnippetBuilder.php, line 21
Namespace
Drupal\hotjarView source
class SnippetBuilder implements SnippetBuilderInterface, ContainerInjectionInterface {
use StringTranslationTrait;
/**
* State storage.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* Config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Hotjar settings.
*
* @var \Drupal\hotjar\HotjarSettingsInterface
*/
protected $settings;
/**
* Module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* JS collection optimizer.
*
* @var \Drupal\Core\Asset\AssetCollectionOptimizerInterface
*/
protected $jsCollectionOptimizer;
/**
* Messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* The file handler under test.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* SnippetBuilder constructor.
*
* @param \Drupal\Core\State\StateInterface $state
* Store storage.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* Config factory.
* @param \Drupal\hotjar\HotjarSettingsInterface $settings
* Hotjar settings.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* Module handler.
* @param \Drupal\Core\Asset\AssetCollectionOptimizerInterface $js_collection_optimizer
* JS assets optimizer.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* Messenger service.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file handler.
*/
public function __construct(StateInterface $state, ConfigFactoryInterface $config_factory, HotjarSettingsInterface $settings, ModuleHandlerInterface $module_handler, AssetCollectionOptimizerInterface $js_collection_optimizer, MessengerInterface $messenger, FileSystemInterface $file_system) {
$this->state = $state;
$this->configFactory = $config_factory;
$this->settings = $settings;
$this->moduleHandler = $module_handler;
$this->jsCollectionOptimizer = $js_collection_optimizer;
$this->messenger = $messenger;
$this->fileSystem = $file_system;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('state'), $container
->get('config.factory'), $container
->get('hotjar.settings'), $container
->get('module_handler'), $container
->get('asset.js.collection_optimizer'), $container
->get('messenger'), $container
->get('file_system'));
}
/**
* {@inheritdoc}
*/
public function pageAttachment(array &$attachments) {
if ($this->settings
->getSetting('attachment_mode') === HotjarSettingsInterface::ATTACHMENT_MODE_DRUPAL_SETTINGS) {
$this
->pageAttachmentDrupalSettings($attachments);
}
else {
$this
->pageAttachmentBuilt($attachments);
}
}
/**
* Add page attachments when Build mode is in use.
*/
protected function pageAttachmentBuilt(array &$attachments) {
$uri = $this
->getSnippetPath();
$query_string = $this->state
->get('system.css_js_query_string') ?: '0';
$query_string_separator = strpos($uri, '?') !== FALSE ? '&' : '?';
$url = file_url_transform_relative(file_create_url($uri));
$attachments['#attached']['html_head'][] = [
[
'#type' => 'html_tag',
'#tag' => 'script',
'#attributes' => [
'src' => $url . $query_string_separator . $query_string,
],
],
'hotjar_script_tag',
];
}
/**
* Add page attachments when DrupalSettings mode is in use.
*/
protected function pageAttachmentDrupalSettings(array &$attachments) {
// Assets resolver will escape drupalSettings.
$clean_id = Html::escape((string) $this->settings
->getSetting('account'));
$clean_version = Html::escape($this->settings
->getSetting('snippet_version'));
$attachments['#attached']['drupalSettings']['hotjar']['account'] = $clean_id;
$attachments['#attached']['drupalSettings']['hotjar']['snippetVersion'] = $clean_version;
$attachments['#attached']['library'][] = 'hotjar/hotjar';
}
/**
* {@inheritdoc}
*/
public function createAssets() {
$this->settings
->getSettings(TRUE);
$result = TRUE;
$directory = dirname($this
->getSnippetPath());
if (!is_dir($directory) || !is_writable($directory)) {
$result = $this->fileSystem
->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
}
if ($result) {
$result = $this
->saveSnippets();
}
else {
$this->messenger
->addWarning($this
->t('Failed to create or make writable the directory %directory, possibly due to a permissions problem. Make the directory writable.', [
'%directory' => $directory,
]));
}
return $result;
}
/**
* Saves JS snippet files based on current settings.
*
* @return bool
* Whether the files were saved.
*/
protected function saveSnippets() {
$snippet = $this
->buildSnippet();
$snippet_path = $this
->getSnippetPath();
if ($this->fileSystem
->realpath($snippet_path)) {
$this->fileSystem
->delete($snippet_path);
}
$dir = $this->fileSystem
->realpath(dirname($snippet_path));
$this->fileSystem
->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
$path = $this->fileSystem
->saveData($snippet, $snippet_path, FileSystemInterface::EXISTS_REPLACE);
if ($path === FALSE) {
$this->messenger
->addMessage($this
->t('An error occurred saving one or more snippet files. Please try again or contact the site administrator if it persists.'));
return FALSE;
}
$this->messenger
->addMessage($this
->t('Created snippet file based on configuration.'));
$this->jsCollectionOptimizer
->deleteAll();
_drupal_flush_css_js();
return TRUE;
}
/**
* {@inheritdoc}
*/
public function buildSnippet() {
$id = $this->settings
->getSetting('account');
// Use escaped HotjarID.
$clean_id = $this
->escapeValue($id);
$clean_version = $this
->escapeValue($this->settings
->getSetting('snippet_version'));
// Quote from the Hotjar dashboard:
// The Tracking Code below should be placed in the <head> tag of
// every page you want to track on your site.
if ($id && $clean_id) {
$script = <<<HJ
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:{<span class="php-variable">$clean_id</span>},hjsv:{<span class="php-variable">$clean_version</span>}};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'//static.hotjar.com/c/hotjar-','.js?sv=');
HJ;
}
else {
$script = <<<HJ
// Empty HotjarID.
HJ;
}
// Allow other modules to modify or wrap the script.
$this->moduleHandler
->alter('hotjar_snippet', $script);
// Compact script if core aggregation or advagg module are enabled.
if ($this
->isJsPreprocessEnabled() || $this->moduleHandler
->moduleExists('advagg')) {
$script = str_replace([
"\n",
' ',
], '', $script);
}
return $script;
}
/**
* Escape value.
*/
protected function escapeValue($value) {
return json_encode($value, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
}
/**
* Checks if JS preprocess is enabled.
*
* @return bool
* Returns TRUE if JS preprocess is enabled.
*/
protected function isJsPreprocessEnabled() {
$config = $this->configFactory
->get('system.performance');
$configured = $config
->get('js.preprocess');
if (!isset($configured)) {
$configured = TRUE;
}
return $configured === TRUE;
}
/**
* Get snippet path.
*
* @return string
* Path to snippet.
*/
protected function getSnippetPath() {
return $this->settings
->getSetting('snippet_path');
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
SnippetBuilder:: |
protected | property | Config factory. | |
SnippetBuilder:: |
protected | property | The file handler under test. | |
SnippetBuilder:: |
protected | property | JS collection optimizer. | |
SnippetBuilder:: |
protected | property | Messenger. | |
SnippetBuilder:: |
protected | property | Module handler. | |
SnippetBuilder:: |
protected | property | Hotjar settings. | |
SnippetBuilder:: |
protected | property | State storage. | |
SnippetBuilder:: |
public | function |
Get Hotjar snippet code. Overrides SnippetBuilderInterface:: |
|
SnippetBuilder:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
|
SnippetBuilder:: |
public | function |
Prepares directory for and saves snippet files based on current settings. Overrides SnippetBuilderInterface:: |
|
SnippetBuilder:: |
protected | function | Escape value. | |
SnippetBuilder:: |
protected | function | Get snippet path. | |
SnippetBuilder:: |
protected | function | Checks if JS preprocess is enabled. | |
SnippetBuilder:: |
public | function |
Implements hook_page_attachment(). Overrides SnippetBuilderInterface:: |
|
SnippetBuilder:: |
protected | function | Add page attachments when Build mode is in use. | |
SnippetBuilder:: |
protected | function | Add page attachments when DrupalSettings mode is in use. | |
SnippetBuilder:: |
protected | function | Saves JS snippet files based on current settings. | |
SnippetBuilder:: |
public | function | SnippetBuilder constructor. | |
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. |