Loading README.md +42 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,20 @@ This module is intended for internal site analytics, treating page views and downloads as events which are recorded to a usage_data table. ## Installation 1. Install module as usual. 2. Allow to execute custom controller in your .htaccess. Below the Statistics module's rule add similar condition: RewriteCond %{REQUEST_URI} !/modules/contrib/usage_data/usage_data\.php$ ## Data structure You can then pull your data out with Views Database Connector (drupal.org/project/views_database_connector) or by writing your own queries. You can add your own columns to the usage_data table by writing Loading @@ -14,7 +28,34 @@ The default structure is as follows: | 1 | view | 2 | node | /about | 1635444980 | 1 | admin | administrator | 1 | | 2 | download | 30 | media | /reports | 1635444981 | 2 | editor | content_manager | 1 | Please be responsible when collecting data from your users. ## Redis queue 1. Make sure that you enabled and setup <a href="https://www.drupal.org/project/redis" target="_blank">Redis</a> module. 2. Add to your settings.php: # Use this to only use Redis for a specific queue (usage_data_records in this case). $settings['queue_service_usage_data_records'] = 'queue.redis'; ## Click tracking Your tracked link should have ```data-usage=""``` attribute with usage data as a JSON string. For example: <a href="https://example.com/search?arg1=1&arg2=2" data-usage="{'entity_id':'27','entity_type_id':'media'}">Tracked link</a> #### Parameters: Required: - entity_type_id - entity type id. - entity_id - entity id. Optional: - path - if empty it will be set from the link href or current page url. ## **Authors:** Nia Kathoni (nikathone) & Daniel Cothran (andileco) config/install/usage_data.settings.yml 0 → 100644 +6 −0 Original line number Diff line number Diff line generic: enabled: 1 redis_queue: 0 legacy: enabled: 0 redis_queue: 0 js/statistics.js +30 −5 Original line number Diff line number Diff line Loading @@ -8,12 +8,37 @@ 'use strict'; $(document).ready(function () { // Track view event. if (drupalSettings.usage_data.data) { $.ajax({ type: 'POST', cache: false, url: drupalSettings.usage_data.url, data: drupalSettings.usage_data.data }); } // Track click event. $('[data-usage]').on('click', function (e, options) { var data = JSON.parse($(this).attr('data-usage')); if (!data) { return; } // Add path info if not set. if (!data['path']) { var href = $(this).attr('href') ? $(this).attr('href') : location.href; data['path'] = href.replace(location.origin, ''); } $.ajax({ type: 'POST', cache: false, url: drupalSettings.usage_data.url, data: { 'type': 'click', 'info': data } }); }); }); })(jQuery, Drupal, drupalSettings); src/Form/SettingsForm.php 0 → 100644 +132 −0 Original line number Diff line number Diff line <?php namespace Drupal\usage_data\Form; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\usage_data\Plugin\UsageTypeManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Usage Data settings form management. */ class SettingsForm extends ConfigFormBase { /** * Usage type manager. * * @var \Drupal\usage_data\Plugin\UsageTypeManagerInterface */ protected UsageTypeManagerInterface $usageTypeManager; /** * Plugin definitions. * * @var array */ protected array $definitions; /** * The module handler. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected ModuleHandlerInterface $moduleHandler; /** * Creates a SettingsForm instance. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * Config factory class instance. * @param \Drupal\usage_data\Plugin\UsageTypeManagerInterface $usageTypeManager * The usage type manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler to invoke the alter hook with. */ public function __construct(ConfigFactoryInterface $config_factory, UsageTypeManagerInterface $usageTypeManager, ModuleHandlerInterface $module_handler) { parent::__construct($config_factory); $this->usageTypeManager = $usageTypeManager; $this->moduleHandler = $module_handler; $this->definitions = $this->usageTypeManager->getDefinitions(); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), $container->get('plugin.manager.usage_type'), $container->get('module_handler') ); } /** * {@inheritdoc} */ public function getFormId() { return 'usage_data_settings_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form = parent::buildForm($form, $form_state); foreach ($this->definitions as $definition) { $id = $definition['id']; $config = $this->config('usage_data.settings')->get($id); $form[$id] = [ '#type' => 'details', '#title' => $definition['label'], '#collapsible' => TRUE, '#open' => TRUE, ]; $form[$id][$id . '_enabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Enable plugin'), '#default_value' => isset($config['enabled']) ? $config['enabled'] : FALSE, ]; $form[$id][$id . '_redis_queue'] = [ '#type' => 'checkbox', '#title' => $this->t('Use Redis queue'), '#description' => $this->t('1. Enable and setup <a href="https://www.drupal.org/project/redis" target="_blank">Redis</a> module.<br> 2. Add to your settings.php:<br>$settings[\'queue_service_usage_data_records\'] = \'queue.redis\';'), '#default_value' => isset($config['redis_queue']) ? $config['redis_queue'] : FALSE, '#disabled' => !$this->moduleHandler->moduleExists('redis'), ]; } return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $config = $this->config('usage_data.settings'); foreach ($this->definitions as $definition) { $id = $definition['id']; $values = $config->get($id); $values['enabled'] = $form_state->getValue($id . '_enabled'); $values['redis_queue'] = $form_state->getValue($id . '_redis_queue'); $config->set($id, $values); } $config->save(); parent::submitForm($form, $form_state); } /** * {@inheritdoc} */ protected function getEditableConfigNames() { return ['usage_data.settings']; } } src/Plugin/QueueWorker/UsageDataRecords.php 0 → 100644 +27 −0 Original line number Diff line number Diff line <?php namespace Drupal\usage_data\Plugin\QueueWorker; use Drupal\Core\Queue\QueueWorkerBase; /** * Save Usage Data records to the database. * * @QueueWorker( * id = "usage_data_records", * title = @Translation("Usage Data records process"), * cron = {"time" = 90} * ) */ class UsageDataRecords extends QueueWorkerBase { /** * {@inheritdoc} */ public function processItem($data) { /** @var \Drupal\usage_data\UsageDataDatabaseStorage $databaseStorage */ $databaseStorage = \Drupal::service('usage_data.storage.database'); $databaseStorage->recordUsage($data); } } Loading
README.md +42 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,20 @@ This module is intended for internal site analytics, treating page views and downloads as events which are recorded to a usage_data table. ## Installation 1. Install module as usual. 2. Allow to execute custom controller in your .htaccess. Below the Statistics module's rule add similar condition: RewriteCond %{REQUEST_URI} !/modules/contrib/usage_data/usage_data\.php$ ## Data structure You can then pull your data out with Views Database Connector (drupal.org/project/views_database_connector) or by writing your own queries. You can add your own columns to the usage_data table by writing Loading @@ -14,7 +28,34 @@ The default structure is as follows: | 1 | view | 2 | node | /about | 1635444980 | 1 | admin | administrator | 1 | | 2 | download | 30 | media | /reports | 1635444981 | 2 | editor | content_manager | 1 | Please be responsible when collecting data from your users. ## Redis queue 1. Make sure that you enabled and setup <a href="https://www.drupal.org/project/redis" target="_blank">Redis</a> module. 2. Add to your settings.php: # Use this to only use Redis for a specific queue (usage_data_records in this case). $settings['queue_service_usage_data_records'] = 'queue.redis'; ## Click tracking Your tracked link should have ```data-usage=""``` attribute with usage data as a JSON string. For example: <a href="https://example.com/search?arg1=1&arg2=2" data-usage="{'entity_id':'27','entity_type_id':'media'}">Tracked link</a> #### Parameters: Required: - entity_type_id - entity type id. - entity_id - entity id. Optional: - path - if empty it will be set from the link href or current page url. ## **Authors:** Nia Kathoni (nikathone) & Daniel Cothran (andileco)
config/install/usage_data.settings.yml 0 → 100644 +6 −0 Original line number Diff line number Diff line generic: enabled: 1 redis_queue: 0 legacy: enabled: 0 redis_queue: 0
js/statistics.js +30 −5 Original line number Diff line number Diff line Loading @@ -8,12 +8,37 @@ 'use strict'; $(document).ready(function () { // Track view event. if (drupalSettings.usage_data.data) { $.ajax({ type: 'POST', cache: false, url: drupalSettings.usage_data.url, data: drupalSettings.usage_data.data }); } // Track click event. $('[data-usage]').on('click', function (e, options) { var data = JSON.parse($(this).attr('data-usage')); if (!data) { return; } // Add path info if not set. if (!data['path']) { var href = $(this).attr('href') ? $(this).attr('href') : location.href; data['path'] = href.replace(location.origin, ''); } $.ajax({ type: 'POST', cache: false, url: drupalSettings.usage_data.url, data: { 'type': 'click', 'info': data } }); }); }); })(jQuery, Drupal, drupalSettings);
src/Form/SettingsForm.php 0 → 100644 +132 −0 Original line number Diff line number Diff line <?php namespace Drupal\usage_data\Form; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\usage_data\Plugin\UsageTypeManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Usage Data settings form management. */ class SettingsForm extends ConfigFormBase { /** * Usage type manager. * * @var \Drupal\usage_data\Plugin\UsageTypeManagerInterface */ protected UsageTypeManagerInterface $usageTypeManager; /** * Plugin definitions. * * @var array */ protected array $definitions; /** * The module handler. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected ModuleHandlerInterface $moduleHandler; /** * Creates a SettingsForm instance. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * Config factory class instance. * @param \Drupal\usage_data\Plugin\UsageTypeManagerInterface $usageTypeManager * The usage type manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler to invoke the alter hook with. */ public function __construct(ConfigFactoryInterface $config_factory, UsageTypeManagerInterface $usageTypeManager, ModuleHandlerInterface $module_handler) { parent::__construct($config_factory); $this->usageTypeManager = $usageTypeManager; $this->moduleHandler = $module_handler; $this->definitions = $this->usageTypeManager->getDefinitions(); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), $container->get('plugin.manager.usage_type'), $container->get('module_handler') ); } /** * {@inheritdoc} */ public function getFormId() { return 'usage_data_settings_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form = parent::buildForm($form, $form_state); foreach ($this->definitions as $definition) { $id = $definition['id']; $config = $this->config('usage_data.settings')->get($id); $form[$id] = [ '#type' => 'details', '#title' => $definition['label'], '#collapsible' => TRUE, '#open' => TRUE, ]; $form[$id][$id . '_enabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Enable plugin'), '#default_value' => isset($config['enabled']) ? $config['enabled'] : FALSE, ]; $form[$id][$id . '_redis_queue'] = [ '#type' => 'checkbox', '#title' => $this->t('Use Redis queue'), '#description' => $this->t('1. Enable and setup <a href="https://www.drupal.org/project/redis" target="_blank">Redis</a> module.<br> 2. Add to your settings.php:<br>$settings[\'queue_service_usage_data_records\'] = \'queue.redis\';'), '#default_value' => isset($config['redis_queue']) ? $config['redis_queue'] : FALSE, '#disabled' => !$this->moduleHandler->moduleExists('redis'), ]; } return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $config = $this->config('usage_data.settings'); foreach ($this->definitions as $definition) { $id = $definition['id']; $values = $config->get($id); $values['enabled'] = $form_state->getValue($id . '_enabled'); $values['redis_queue'] = $form_state->getValue($id . '_redis_queue'); $config->set($id, $values); } $config->save(); parent::submitForm($form, $form_state); } /** * {@inheritdoc} */ protected function getEditableConfigNames() { return ['usage_data.settings']; } }
src/Plugin/QueueWorker/UsageDataRecords.php 0 → 100644 +27 −0 Original line number Diff line number Diff line <?php namespace Drupal\usage_data\Plugin\QueueWorker; use Drupal\Core\Queue\QueueWorkerBase; /** * Save Usage Data records to the database. * * @QueueWorker( * id = "usage_data_records", * title = @Translation("Usage Data records process"), * cron = {"time" = 90} * ) */ class UsageDataRecords extends QueueWorkerBase { /** * {@inheritdoc} */ public function processItem($data) { /** @var \Drupal\usage_data\UsageDataDatabaseStorage $databaseStorage */ $databaseStorage = \Drupal::service('usage_data.storage.database'); $databaseStorage->recordUsage($data); } }