View source
<?php
namespace Drupal\hotjar;
use Drupal\Core\Asset\AssetCollectionOptimizerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
class SnippetBuilder implements SnippetBuilderInterface, ContainerInjectionInterface {
use StringTranslationTrait;
protected $state;
protected $configFactory;
protected $settings;
protected $moduleHandler;
protected $jsCollectionOptimizer;
protected $messenger;
public function __construct(StateInterface $state, ConfigFactoryInterface $config_factory, HotjarSettingsInterface $settings, ModuleHandlerInterface $module_handler, AssetCollectionOptimizerInterface $js_collection_optimizer, MessengerInterface $messenger) {
$this->state = $state;
$this->configFactory = $config_factory;
$this->settings = $settings;
$this->moduleHandler = $module_handler;
$this->jsCollectionOptimizer = $js_collection_optimizer;
$this->messenger = $messenger;
}
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'));
}
public function pageAttachment(array &$attachments) {
$uri = 'public://hotjar/hotjar.script.js';
$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',
];
}
public function createAssets() {
$result = TRUE;
$directory = 'public://hotjar';
if (!is_dir($directory) || !is_writable($directory)) {
$result = file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_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;
}
protected function saveSnippets() {
$snippet = $this
->buildSnippet();
$path = file_unmanaged_save_data($snippet, 'public://hotjar/hotjar.script.js', FILE_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;
}
protected function buildSnippet() {
$clean_id = $this
->escapeValue($this->settings
->getSetting('account'));
$clean_version = $this
->escapeValue($this->settings
->getSetting('snippet_version'));
$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;
if ($this
->isJsPreprocessEnabled() || $this->moduleHandler
->moduleExists('advagg')) {
$script = str_replace([
"\n",
' ',
], '', $script);
}
return $script;
}
protected function escapeValue($value) {
return json_encode($value, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
}
protected function isJsPreprocessEnabled() {
$config = $this->configFactory
->get('system.performance');
return $config
->get('js.preprocess', TRUE) === TRUE;
}
}