diff --git a/hotjar.module b/hotjar.module index 7697087..947ffdf 100644 --- a/hotjar.module +++ b/hotjar.module @@ -8,6 +8,7 @@ */ use Drupal\Component\Utility\Unicode; +use Drupal\hotjar\Form\HotjarAdminSettingsForm; /** * Define default path exclusion list to remove tracking from admin pages. @@ -29,6 +30,15 @@ function hotjar_help($route_name, \Drupal\Core\Routing\RouteMatchInterface $rout } } +/** + * Implements hook_rebuild(). + */ +function hotjar_rebuild() { + $config_factory = \Drupal::configFactory(); + $form = new HotjarAdminSettingsForm($config_factory); + $form->createAssets(); +} + /** * Get Hotjar settings. */ @@ -56,37 +66,21 @@ function hotjar_get_settings() { */ function hotjar_page_attachments(array &$attachments) { $settings = hotjar_get_settings(); - $id = $settings['account']; - $version = $settings['snippet_version']; - if (!$id || !_hotjar_access()) { + if (!$settings['account'] || !_hotjar_access()) { return; } - // Use escaped HotjarID. - $clean_id = json_encode($id, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT); - $clean_version = json_encode($version, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT); - - // Quote from the Hotjar dashboard: - // "The Tracking Code below should be placed in the tag of - // every page you want to track on your site." - $tracking_code = <<get('system.css_js_query_string') ?: '0'; $attachments['#attached']['html_head'][] = [ [ + '#type' => 'html_tag', '#tag' => 'script', - '#value' => $tracking_code, + '#attributes' => ['src' => $url . '?' . $query_string], ], - 'hotjar_tracking_code' + 'hotjar_script_tag', ]; } @@ -216,3 +210,42 @@ function _hotjar_check_status() { ); return !in_array($status, $not_tracked_status_codes); } + +/** + * Get Hotjar snippet code. + * + * @param string $id + * Hotjar account ID. + * @param string $version + * Hotjar API version. + * + * @return mixed|string + * Hotjar snippet. + */ +function _hotjar_get_snippet($id, $version) { + // Use escaped HotjarID. + $clean_id = json_encode($id, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT); + $clean_version = json_encode($version, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT); + + // Quote from the Hotjar dashboard: + // "The Tracking Code below should be placed in the tag of + // every page you want to track on your site." + $script = <<get('js.preprocess', TRUE) === TRUE || \Drupal::moduleHandler()->moduleExists('advagg')) { + $script = str_replace(["\n", ' '], '', $script); + } + + return $script; +} diff --git a/src/Form/HotjarAdminSettingsForm.php b/src/Form/HotjarAdminSettingsForm.php index c1f06e6..ce2246b 100644 --- a/src/Form/HotjarAdminSettingsForm.php +++ b/src/Form/HotjarAdminSettingsForm.php @@ -173,5 +173,51 @@ class HotjarAdminSettingsForm extends ConfigFormBase { ->save(); parent::submitForm($form, $form_state); + + $this->createAssets(); + } + + /** + * Prepares directory for and saves snippet files based on current settings. + * + * @return bool + * Whether the files were saved. + */ + public function createAssets(): bool { + $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 { + drupal_set_message($this->t('Failed to create or make writable the directory %directory, possibly due to a permissions problem. Make the directory writable.', array('%directory' => $directory)), 'warning'); + } + return $result; + } + + /** + * Saves JS snippet files based on current settings. + * + * @return bool + * Whether the files were saved. + */ + public function saveSnippets(): bool { + // @TODO Is this really necessary? + $settings = hotjar_get_settings(); + $snippet = _hotjar_get_snippet($settings['account'], $settings['snippet_version']); + $path = file_unmanaged_save_data($snippet, 'public://hotjar/hotjar.script.js', FILE_EXISTS_REPLACE); + $result = !$path; + if (!$result) { + drupal_set_message($this->t('Created three snippet files based on configuration.')); + \Drupal::service('asset.js.collection_optimizer')->deleteAll(); + _drupal_flush_css_js(); + } + else { + drupal_set_message($this->t('An error occurred saving one or more snippet files. Please try again or contact the site administrator if it persists.')); + } + return $result; } }