diff --git a/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php b/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php
index bb59f502c3..f47b06630f 100644
--- a/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php
+++ b/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php
@@ -239,9 +239,9 @@ public function testBlockMigration() {
// Check statistic block settings.
$settings = [
- 'id' => 'broken',
+ 'id' => 'statistics_popular_block',
'label' => '',
- 'provider' => 'core',
+ 'provider' => 'statistics',
'label_display' => '0',
'top_day_num' => 7,
'top_all_num' => 8,
diff --git a/core/modules/search/src/Tests/SearchRankingTest.php b/core/modules/search/src/Tests/SearchRankingTest.php
index 28241d2af2..7293a06f8c 100644
--- a/core/modules/search/src/Tests/SearchRankingTest.php
+++ b/core/modules/search/src/Tests/SearchRankingTest.php
@@ -95,7 +95,7 @@ public function testRankings() {
$this->drupalPostForm(NULL, $edit, t('Save'));
// Enable counting of statistics.
- $this->config('statistics.settings')->set('count_content_views', 1)->save();
+ $this->config('statistics.settings')->set('entity_type_ids', ['node'])->save();
// Simulating content views is kind of difficult in the test. Leave that
// to the Statistics module. So instead go ahead and manually update the
diff --git a/core/modules/statistics/config/install/statistics.settings.yml b/core/modules/statistics/config/install/statistics.settings.yml
index 6686062923..8c73e19338 100644
--- a/core/modules/statistics/config/install/statistics.settings.yml
+++ b/core/modules/statistics/config/install/statistics.settings.yml
@@ -1,2 +1,2 @@
-count_content_views: 0
+entity_type_ids: {}
display_max_age: 3600
diff --git a/core/modules/statistics/config/schema/statistics.schema.yml b/core/modules/statistics/config/schema/statistics.schema.yml
index c72a227264..0c2cd05008 100644
--- a/core/modules/statistics/config/schema/statistics.schema.yml
+++ b/core/modules/statistics/config/schema/statistics.schema.yml
@@ -4,12 +4,15 @@ statistics.settings:
type: config_object
label: 'Statistics settings'
mapping:
- count_content_views:
- type: integer
- label: 'Count content views'
display_max_age:
type: integer
label: 'How long any statistics may be cached, i.e. the refresh interval'
+ entity_type_ids:
+ type: sequence
+ label: 'Entity Type IDs'
+ sequence:
+ type: string
+ label: 'Entity Type ID'
block.settings.statistics_popular_block:
type: block_settings
diff --git a/core/modules/statistics/migration_templates/statistics_settings.yml b/core/modules/statistics/migration_templates/statistics_settings.yml
index 1f5b5bbd0e..6a6bc0e4ff 100644
--- a/core/modules/statistics/migration_templates/statistics_settings.yml
+++ b/core/modules/statistics/migration_templates/statistics_settings.yml
@@ -10,7 +10,11 @@ source:
- statistics_flush_accesslog_timer
- statistics_count_content_views
process:
- 'count_content_views': statistics_count_content_views
+ entity_type_ids:
+ -
+ plugin: callback
+ callable: statistics_migrate_callback
+ source: statistics_count_content_views
destination:
plugin: config
config_name: statistics.settings
diff --git a/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php b/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php
index 0cccb1700b..8405fc5176 100644
--- a/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php
+++ b/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php
@@ -3,146 +3,42 @@
namespace Drupal\statistics;
use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\State\StateInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Provides the default database storage backend for statistics.
*/
-class NodeStatisticsDatabaseStorage implements StatisticsStorageInterface {
+class NodeStatisticsDatabaseStorage extends StatisticsDatabaseStorage {
- /**
- * The database connection used.
- *
- * @var \Drupal\Core\Database\Connection
- */
- protected $connection;
-
- /**
- * The state service.
- *
- * @var \Drupal\Core\State\StateInterface
- */
- protected $state;
-
- /**
- * The request stack.
- *
- * @var \Symfony\Component\HttpFoundation\RequestStack
- */
- protected $requestStack;
-
- /**
- * Constructs the statistics storage.
- *
- * @param \Drupal\Core\Database\Connection $connection
- * The database connection for the node view storage.
- * @param \Drupal\Core\State\StateInterface $state
- * The state service.
- */
- public function __construct(Connection $connection, StateInterface $state, RequestStack $request_stack) {
- $this->connection = $connection;
- $this->state = $state;
- $this->requestStack = $request_stack;
+ public function recordView($entity_type_id, $key, $id) {
+ return parent::recordView($entity_type_id, $key, $id); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function recordView($id) {
- return (bool) $this->connection
- ->merge('node_counter')
- ->key('nid', $id)
- ->fields([
- 'daycount' => 1,
- 'totalcount' => 1,
- 'timestamp' => $this->getRequestTime(),
- ])
- ->expression('daycount', 'daycount + 1')
- ->expression('totalcount', 'totalcount + 1')
- ->execute();
+ public function fetchView(EntityTypeInterface $entity_type, $id) {
+ return parent::fetchView($entity_type, $id); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function fetchViews($ids) {
- $views = $this->connection
- ->select('node_counter', 'nc')
- ->fields('nc', ['totalcount', 'daycount', 'timestamp'])
- ->condition('nid', $ids, 'IN')
- ->execute()
- ->fetchAll();
- foreach ($views as $id => $view) {
- $views[$id] = new StatisticsViewsResult($view->totalcount, $view->daycount, $view->timestamp);
- }
- return $views;
+ public function fetchAll(EntityTypeInterface $entity_type, $order = 'totalcount', $limit = 5) {
+ return parent::fetchAll($entity_type, $order, $limit); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function fetchView($id) {
- $views = $this->fetchViews([$id]);
- return reset($views);
+ public function deleteViews(EntityTypeInterface $entity_type, $id) {
+ return parent::deleteViews($entity_type, $id); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function fetchAll($order = 'totalcount', $limit = 5) {
- assert(in_array($order, ['totalcount', 'daycount', 'timestamp']), "Invalid order argument.");
-
- return $this->connection
- ->select('node_counter', 'nc')
- ->fields('nc', ['nid'])
- ->orderBy($order, 'DESC')
- ->range(0, $limit)
- ->execute()
- ->fetchCol();
+ public function maxTotalCount(EntityTypeInterface $entity_type) {
+ return parent::maxTotalCount($entity_type); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function deleteViews($id) {
- return (bool) $this->connection
- ->delete('node_counter')
- ->condition('nid', $id)
- ->execute();
+ public function createTable(EntityTypeInterface $entity_type) {
+ parent::createTable($entity_type); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function resetDayCount() {
- $statistics_timestamp = $this->state->get('statistics.day_timestamp') ?: 0;
- if (($this->getRequestTime() - $statistics_timestamp) >= 86400) {
- $this->state->set('statistics.day_timestamp', $this->getRequestTime());
- $this->connection->update('node_counter')
- ->fields(['daycount' => 0])
- ->execute();
- }
+ public function dropTable(EntityTypeInterface $entity_type) {
+ parent::dropTable($entity_type); // TODO: Change the autogenerated stub
}
- /**
- * {@inheritdoc}
- */
- public function maxTotalCount() {
- $query = $this->connection->select('node_counter', 'nc');
- $query->addExpression('MAX(totalcount)');
- $max_total_count = (int)$query->execute()->fetchField();
- return $max_total_count;
- }
-
- /**
- * Get current request time.
- *
- * @return int
- * Unix timestamp for current server request time.
- */
- protected function getRequestTime() {
- return $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME');
- }
}
diff --git a/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php
index 1802a4569c..a0805bb327 100644
--- a/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php
+++ b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php
@@ -83,7 +83,7 @@ public static function create(ContainerInterface $container, array $configuratio
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('entity.repository'),
- $container->get('statistics.storage.node'),
+ $container->get('statistics.storage'),
$container->get('renderer')
);
}
@@ -95,7 +95,7 @@ public function defaultConfiguration() {
return [
'top_day_num' => 0,
'top_all_num' => 0,
- 'top_last_num' => 0
+ 'top_last_num' => 0,
];
}
@@ -151,9 +151,10 @@ public function blockSubmit($form, FormStateInterface $form_state) {
*/
public function build() {
$content = [];
+ $entity_type = $this->entityTypeManager->getDefinition('node');
if ($this->configuration['top_day_num'] > 0) {
- $nids = $this->statisticsStorage->fetchAll('daycount', $this->configuration['top_day_num']);
+ $nids = $this->statisticsStorage->fetchAll($entity_type, 'daycount', $this->configuration['top_day_num']);
if ($nids) {
$content['top_day'] = $this->nodeTitleList($nids, $this->t("Today's:"));
$content['top_day']['#suffix'] = '
';
@@ -161,7 +162,7 @@ public function build() {
}
if ($this->configuration['top_all_num'] > 0) {
- $nids = $this->statisticsStorage->fetchAll('totalcount', $this->configuration['top_all_num']);
+ $nids = $this->statisticsStorage->fetchAll($entity_type, 'totalcount', $this->configuration['top_all_num']);
if ($nids) {
$content['top_all'] = $this->nodeTitleList($nids, $this->t('All time:'));
$content['top_all']['#suffix'] = '
';
@@ -169,7 +170,7 @@ public function build() {
}
if ($this->configuration['top_last_num'] > 0) {
- $nids = $this->statisticsStorage->fetchAll('timestamp', $this->configuration['top_last_num']);
+ $nids = $this->statisticsStorage->fetchAll($entity_type, 'timestamp', $this->configuration['top_last_num']);
$content['top_last'] = $this->nodeTitleList($nids, $this->t('Last viewed:'));
$content['top_last']['#suffix'] = '
';
}
diff --git a/core/modules/statistics/src/Plugin/views/field/EntityCounterTimestamp.php b/core/modules/statistics/src/Plugin/views/field/EntityCounterTimestamp.php
new file mode 100644
index 0000000000..9bc2a9c089
--- /dev/null
+++ b/core/modules/statistics/src/Plugin/views/field/EntityCounterTimestamp.php
@@ -0,0 +1,24 @@
+hasPermission('view post access counter');
+ }
+
+}
diff --git a/core/modules/statistics/src/Plugin/views/field/NodeCounterTimestamp.php b/core/modules/statistics/src/Plugin/views/field/NodeCounterTimestamp.php
index fb0eb3049e..037526920f 100644
--- a/core/modules/statistics/src/Plugin/views/field/NodeCounterTimestamp.php
+++ b/core/modules/statistics/src/Plugin/views/field/NodeCounterTimestamp.php
@@ -2,9 +2,6 @@
namespace Drupal\statistics\Plugin\views\field;
-use Drupal\views\Plugin\views\field\Date;
-use Drupal\Core\Session\AccountInterface;
-
/**
* Field handler to display the most recent time the node has been viewed.
*
@@ -12,13 +9,6 @@
*
* @ViewsField("node_counter_timestamp")
*/
-class NodeCounterTimestamp extends Date {
-
- /**
- * {@inheritdoc}
- */
- public function access(AccountInterface $account) {
- return $account->hasPermission('view post access counter');
- }
+class NodeCounterTimestamp extends EntityCounterTimestamp {
}
diff --git a/core/modules/statistics/src/StatisticsDatabaseStorage.php b/core/modules/statistics/src/StatisticsDatabaseStorage.php
new file mode 100644
index 0000000000..7aa57460a2
--- /dev/null
+++ b/core/modules/statistics/src/StatisticsDatabaseStorage.php
@@ -0,0 +1,240 @@
+connection = $connection;
+ $this->requestStack = $request_stack;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function recordView($entity_type_id, $key, $id) {
+ $table = $entity_type_id . '_counter';
+ try {
+ return (bool) $this->connection
+ ->merge($table)
+ ->key($key, $id)
+ ->fields([
+ 'daycount' => 1,
+ 'totalcount' => 1,
+ 'timestamp' => $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME'),
+ ])
+ ->expression('daycount', 'daycount + 1')
+ ->expression('totalcount', 'totalcount + 1')
+ ->execute();
+ }
+ catch (\Exception $e) {
+ $database_schema = $this->connection->schema();
+ if ($database_schema->tableExists($table)) {
+ throw $e;
+ }
+ else {
+ $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id);
+ $this->createTable($entity_type);
+ $this->recordView($entity_type_id, $key, $id);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchView(EntityTypeInterface $entity_type, $id) {
+ try {
+ $view = $this->connection
+ ->select($this->tableName($entity_type), 'c')
+ ->fields('c', ['totalcount', 'daycount', 'timestamp'])
+ ->condition($entity_type->getKey('id'), $id)
+ ->execute()
+ ->fetchObject();
+ if ($view) {
+ return new StatisticsViewsResult($view->totalcount, $view->daycount, $view->timestamp);
+ }
+ }
+ catch (\Exception $e) {
+ $this->catchException($entity_type, $e);
+ }
+ return NULL;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchAll(EntityTypeInterface $entity_type, $order = 'totalcount', $limit = 5) {
+ assert(in_array($order, ['totalcount', 'daycount', 'timestamp']), "Invalid order argument.");
+ try {
+ return $this->connection
+ ->select($this->tableName($entity_type), 'nc')
+ ->fields('nc', [$entity_type->getKey('id')])
+ ->orderBy($order, 'DESC')
+ ->range(0, $limit)
+ ->execute()
+ ->fetchCol();
+ }
+ catch (\Exception $e) {
+ $this->catchException($entity_type, $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteViews(EntityTypeInterface $entity_type, $id) {
+ try {
+ return (bool) $this->connection
+ ->delete($this->tableName($entity_type))
+ ->condition($entity_type->getKey('id'), $id)
+ ->execute();
+ }
+ catch (\Exception $e) {
+ $this->catchException($entity_type, $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function maxTotalCount(EntityTypeInterface $entity_type) {
+ try {
+ $query = $this->connection->select($this->tableName($entity_type), 'nc');
+ $query->addExpression('MAX(totalcount)');
+ $max_total_count = (int) $query->execute()->fetchField();
+ return $max_total_count;
+ }
+ catch (\Exception $e) {
+ $this->catchException($entity_type, $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createTable(EntityTypeInterface $entity_type) {
+ $entity_type_id = $entity_type->id();
+ $idKey = $entity_type->getKey('id');
+ $id_definition = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type_id)[$idKey];
+ if ($id_definition->getType() === 'integer') {
+ $id_schema = [
+ 'description' => "The {{$entity_type_id}}.$idKey for these statistics.",
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ];
+ }
+ else {
+ $id_schema = [
+ 'description' => "The {{$entity_type_id}}.$idKey for these statistics.",
+ 'type' => 'varchar_ascii',
+ 'length' => 128,
+ 'not null' => TRUE,
+ ];
+ }
+ $table = $entity_type_id . '_counter';
+ if (!$this->connection->schema()->tableExists($table)) {
+ $schema = [
+ 'description' => "Access statistics for {{$entity_type_id}}s.",
+ 'fields' => [
+ $idKey => $id_schema,
+ 'totalcount' => [
+ 'description' => "The total number of times the {{$entity_type_id}} has been viewed.",
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'big',
+ ],
+ 'daycount' => [
+ 'description' => "The total number of times the {{$entity_type_id}} has been viewed today.",
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'medium',
+ ],
+ 'timestamp' => [
+ 'description' => "The most recent time the {{$entity_type_id}} has been viewed.",
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ],
+ ],
+ 'primary key' => [$idKey],
+ ];
+ $this->connection->schema()->createTable($table, $schema);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dropTable(EntityTypeInterface $entity_type) {
+ if ($this->connection->schema()->tableExists($this->tableName($entity_type))) {
+ $this->connection->schema()->dropTable($this->tableName($entity_type));
+ }
+ }
+
+ /**
+ * Act on an exception when the table might not have been created.
+ *
+ * If the table does not yet exist, that's fine, but if the table exists and
+ * something else caused the exception, then propagate it.
+ *
+ * @param \Exception $e
+ * The exception.
+ *
+ * @throws \Exception
+ */
+ protected function catchException(EntityTypeInterface $entity_type,\Exception $e) {
+ if ($this->connection->schema()->tableExists($this->tableName($entity_type))) {
+ throw $e;
+ }
+ }
+
+ /**
+ * Generates the table name from the entity type.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ *
+ * @return string
+ */
+ protected function tableName(EntityTypeInterface $entity_type) {
+ $entity_type_id = $entity_type->id();
+ return $entity_type_id . '_counter';
+ }
+
+}
diff --git a/core/modules/statistics/src/StatisticsResetCount.php b/core/modules/statistics/src/StatisticsResetCount.php
new file mode 100644
index 0000000000..e87d7f1487
--- /dev/null
+++ b/core/modules/statistics/src/StatisticsResetCount.php
@@ -0,0 +1,66 @@
+connection = $connection;
+ $this->state = $state;
+ $this->time = $time;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resetDayCount($entity_type_id) {
+ $statistics_timestamp = $this->state->get('statistics.day_timestamp') ?: 0;
+ $time = $this->time->getRequestTime();
+ $table = $entity_type_id . '_counter';
+ if (($time - $statistics_timestamp) >= 86400 && $this->connection->schema()->tableExists($table)) {
+ $this->state->set('statistics.day_timestamp', $time);
+ $this->connection->update($table)
+ ->fields(['daycount' => 0])
+ ->execute();
+ }
+ }
+
+}
diff --git a/core/modules/statistics/src/StatisticsResetCountInterface.php b/core/modules/statistics/src/StatisticsResetCountInterface.php
new file mode 100644
index 0000000000..d4b493cfa3
--- /dev/null
+++ b/core/modules/statistics/src/StatisticsResetCountInterface.php
@@ -0,0 +1,18 @@
+entityTypeManager = $entity_type_manager;
+ $this->entityTypeRepository = $entity_type_repository;
+ $this->statisticsStorage = $statistics_storage;
$this->moduleHandler = $module_handler;
}
@@ -40,7 +71,10 @@ public function __construct(ConfigFactoryInterface $config_factory, ModuleHandle
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
- $container->get('module_handler')
+ $container->get('module_handler'),
+ $container->get('entity_type.manager'),
+ $container->get('entity_type.repository'),
+ $container->get('statistics.storage')
);
}
@@ -63,18 +97,27 @@ protected function getEditableConfigNames() {
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('statistics.settings');
+ $labels = $this->entityTypeRepository->getEntityTypeLabels(TRUE);
+ $labels = $labels[(string) $this->t('Content', [], ['context' => 'Entity type group'])];
+ $options = [];
+ foreach ($labels as $entity_type_id => $label) {
+ $options[$entity_type_id] = $this->t('Enable statistics for @entity_type', ['@entity_type' => $label]);
+ }
- // Content counter settings.
+ // Content entity counter settings.
$form['content'] = [
'#type' => 'details',
- '#title' => t('Content viewing counter settings'),
+ '#title' => $this->t('Content viewing counter settings'),
+ '#description' => $this->t('Increment a counter each time content is viewed.'),
'#open' => TRUE,
];
- $form['content']['statistics_count_content_views'] = [
- '#type' => 'checkbox',
- '#title' => t('Count content views'),
- '#default_value' => $config->get('count_content_views'),
- '#description' => t('Increment a counter each time content is viewed.'),
+
+ $form['content']['entity_type_ids'] = [
+ '#type' => 'checkboxes',
+ '#title' => $this->t('Select content'),
+ '#options' => $options,
+ '#default_value' => $config->get('entity_type_ids'),
+
];
return parent::buildForm($form, $form_state);
@@ -84,9 +127,19 @@ public function buildForm(array $form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
+ $entity_type_ids = $form_state->getValue('entity_type_ids');
$this->config('statistics.settings')
- ->set('count_content_views', $form_state->getValue('statistics_count_content_views'))
+ ->set('entity_type_ids', $entity_type_ids)
->save();
+ foreach (array_keys($entity_type_ids) as $entity_type_id) {
+ $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
+ if ($entity_type_ids[$entity_type_id] === $entity_type_id) {
+ $this->statisticsStorage->createTable($entity_type);
+ }
+ else {
+ $this->statisticsStorage->dropTable($entity_type);
+ }
+ }
// The popular statistics block is dependent on these settings, so clear the
// block plugin definitions cache.
diff --git a/core/modules/statistics/src/StatisticsStorageInterface.php b/core/modules/statistics/src/StatisticsStorageInterface.php
index ad6d6d5dce..cbe7af0d3f 100644
--- a/core/modules/statistics/src/StatisticsStorageInterface.php
+++ b/core/modules/statistics/src/StatisticsStorageInterface.php
@@ -2,6 +2,8 @@
namespace Drupal\statistics;
+use Drupal\Core\Entity\EntityTypeInterface;
+
/**
* Provides an interface defining Statistics Storage.
*
@@ -13,78 +15,87 @@
/**
* Count a entity view.
*
+ * @param string $entity_type_id
+ * The entity type ID.
+ * @param string $key
+ * The ID key of the entity to count.
* @param int $id
* The ID of the entity to count.
*
* @return bool
* TRUE if the entity view has been counted.
*/
- public function recordView($id);
-
- /**
- * Returns the number of times entities have been viewed.
- *
- * @param array $ids
- * An array of IDs of entities to fetch the views for.
- *
- * @return \Drupal\statistics\StatisticsViewsResult[]
- * An array of value objects representing the number of times each entity
- * has been viewed. The array is keyed by entity ID. If an ID does not
- * exist, it will not be present in the array.
- */
- public function fetchViews($ids);
+ public function recordView($entity_type_id, $key, $id);
/**
* Returns the number of times a single entity has been viewed.
*
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
* @param int $id
* The ID of the entity to fetch the views for.
*
- * @return \Drupal\statistics\StatisticsViewsResult|false
- * If the entity exists, a value object representing the number of times if
- * has been viewed. If it does not exist, FALSE is returned.
+ * @return \Drupal\statistics\StatisticsViewsResult|null
+ * The StatisticsViewsResult object if the result is present NULL otherwise.
*/
- public function fetchView($id);
+ public function fetchView(EntityTypeInterface $entity_type, $id);
/**
- * Returns the number of times a entity has been viewed.
+ * Returns the number of times an entity has been viewed.
*
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
* @param string $order
* The counter name to order by:
* - 'totalcount' The total number of views.
* - 'daycount' The number of views today.
* - 'timestamp' The unix timestamp of the last view.
- *
* @param int $limit
* The number of entity IDs to return.
*
* @return array
* An ordered array of entity IDs.
*/
- public function fetchAll($order = 'totalcount', $limit = 5);
+ public function fetchAll(EntityTypeInterface $entity_type, $order = 'totalcount', $limit = 5);
/**
* Delete counts for a specific entity.
*
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
* @param int $id
* The ID of the entity which views to delete.
*
* @return bool
* TRUE if the entity views have been deleted.
*/
- public function deleteViews($id);
-
- /**
- * Reset the day counter for all entities once every day.
- */
- public function resetDayCount();
+ public function deleteViews(EntityTypeInterface $entity_type, $id);
/**
* Returns the highest 'totalcount' value.
*
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
+ *
* @return int
* The highest 'totalcount' value.
*/
- public function maxTotalCount();
+ public function maxTotalCount(EntityTypeInterface $entity_type);
+
+ /**
+ * Creates entity counter table.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
+ */
+ public function createTable(EntityTypeInterface $entity_type);
+
+ /**
+ * Drops entity counter table.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
+ */
+ public function dropTable(EntityTypeInterface $entity_type);
}
diff --git a/core/modules/statistics/src/Tests/StatisticsTestBase.php b/core/modules/statistics/src/Tests/StatisticsTestBase.php
index 4f530cf9cd..d4b2d32a58 100644
--- a/core/modules/statistics/src/Tests/StatisticsTestBase.php
+++ b/core/modules/statistics/src/Tests/StatisticsTestBase.php
@@ -47,7 +47,7 @@ protected function setUp() {
// Enable logging.
$this->config('statistics.settings')
- ->set('count_content_views', 1)
+ ->set('entity_type_ids', ['node'])
->save();
}
diff --git a/core/modules/statistics/src/Tests/Views/IntegrationTest.php b/core/modules/statistics/src/Tests/Views/IntegrationTest.php
index 18f5581587..0f57663d08 100644
--- a/core/modules/statistics/src/Tests/Views/IntegrationTest.php
+++ b/core/modules/statistics/src/Tests/Views/IntegrationTest.php
@@ -58,7 +58,7 @@ protected function setUp() {
// Enable counting of content views.
$this->config('statistics.settings')
- ->set('count_content_views', 1)
+ ->set('entity_type_ids', ['node'])
->save();
}
@@ -75,7 +75,7 @@ public function testNodeCounterIntegration() {
global $base_url;
$stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
$client = \Drupal::httpClient();
- $client->post($stats_path, ['form_params' => ['nid' => $this->node->id()]]);
+ $client->post($stats_path, ['form_params' => ['type' => 'node', 'key' => 'nid', 'id' => $this->node->id()]]);
$this->drupalGet('test_statistics_integration');
$expected = statistics_get($this->node->id());
diff --git a/core/modules/statistics/statistics.install b/core/modules/statistics/statistics.install
index deac9010a4..20e8f597d5 100644
--- a/core/modules/statistics/statistics.install
+++ b/core/modules/statistics/statistics.install
@@ -9,53 +9,16 @@
* Implements hook_uninstall().
*/
function statistics_uninstall() {
+ $state = \Drupal::state();
+ $entity_type_manager = \Drupal::entityTypeManager();
+ $statistic_storage = \Drupal::service('statistics.storage');
// Remove states.
- \Drupal::state()->delete('statistics.node_counter_scale');
- \Drupal::state()->delete('statistics.day_timestamp');
-}
-
-/**
- * Implements hook_schema().
- */
-function statistics_schema() {
- $schema['node_counter'] = [
- 'description' => 'Access statistics for {node}s.',
- 'fields' => [
- 'nid' => [
- 'description' => 'The {node}.nid for these statistics.',
- 'type' => 'int',
- 'unsigned' => TRUE,
- 'not null' => TRUE,
- 'default' => 0,
- ],
- 'totalcount' => [
- 'description' => 'The total number of times the {node} has been viewed.',
- 'type' => 'int',
- 'unsigned' => TRUE,
- 'not null' => TRUE,
- 'default' => 0,
- 'size' => 'big',
- ],
- 'daycount' => [
- 'description' => 'The total number of times the {node} has been viewed today.',
- 'type' => 'int',
- 'unsigned' => TRUE,
- 'not null' => TRUE,
- 'default' => 0,
- 'size' => 'medium',
- ],
- 'timestamp' => [
- 'description' => 'The most recent time the {node} has been viewed.',
- 'type' => 'int',
- 'unsigned' => TRUE,
- 'not null' => TRUE,
- 'default' => 0,
- ],
- ],
- 'primary key' => ['nid'],
- ];
-
- return $schema;
+ $state->delete('statistics.day_timestamp');
+ $entity_types = \Drupal::configFactory()->get('statistics.settings')->get('entity_type_ids');
+ foreach (array_keys($entity_types) as $entity_type_id) {
+ $state->delete("statistics.{$entity_type_id}_counter_scale");
+ $statistic_storage->dropTable($entity_type_manager->getDefinition($entity_type_id));
+ }
}
/**
@@ -86,3 +49,15 @@ function statistics_update_8002() {
function statistics_update_8300() {
\Drupal::configFactory()->getEditable('statistics.settings')->clear('access_log')->save();
}
+
+/**
+ * Replace count_content_views settings with entity_type_ids setting.
+ */
+function statistics_update_8301() {
+ $config = \Drupal::configFactory()->getEditable('statistics.settings');
+ $value = $config->get('count_content_views') ? ['node' => 'node'] : [];
+ // Remove the old count_content_views configuration setting.
+ $config->clear('count_content_views')
+ // Set the new configuration setting for entity_type_ids to the initial value.
+ ->set('entity_type_ids', $value)->save();
+}
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index 4d7f42a33c..70e24b3e46 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -39,9 +39,45 @@ function statistics_help($route_name, RouteMatchInterface $route_match) {
* Implements hook_ENTITY_TYPE_view() for node entities.
*/
function statistics_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) {
- if (!$node->isNew() && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) {
+ if (!$node->isNew() && $view_mode === 'full' && node_is_page($node) && empty($node->in_preview)) {
$build['#attached']['library'][] = 'statistics/drupal.statistics';
- $settings = ['data' => ['nid' => $node->id()], 'url' => Url::fromUri('base:' . drupal_get_path('module', 'statistics') . '/statistics.php')->toString()];
+ $settings = [
+ 'data' => [
+ 'key' => 'nid',
+ 'id' => $node->id(),
+ 'type' => 'node',
+ ],
+ 'url' => Url::fromUri('base:' . drupal_get_path('module', 'statistics') . '/statistics.php')->toString(),
+ ];
+ $build['#attached']['drupalSettings']['statistics'] = $settings;
+ }
+}
+
+/**
+ * Implements hook_ENTITY_view() for node entities.
+ */
+function statistics_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
+ $entity_type_id = $entity->getEntityTypeId();
+ // @todo Remove this condition once statistics_node_view() is removed.
+ if ($entity_type_id === 'node') {
+ return;
+ }
+ $route_match = \Drupal::routeMatch();
+ $route_name = "entity.$entity_type_id.canonical";
+ if ($route_match->getRouteName() === $route_name) {
+ $page_entity = $route_match->getParameter($entity_type_id);
+ }
+ $entity_is_page = (!empty($page_entity) ? $page_entity->id() === $entity->id() : FALSE);
+ if (!$entity->isNew() && $view_mode === 'full' && $entity_is_page && empty($entity->in_preview)) {
+ $build['#attached']['library'][] = 'statistics/drupal.statistics';
+ $settings = [
+ 'data' => [
+ 'key' => $entity->getEntityType()->getKey('id'),
+ 'id' => $entity->id(),
+ 'type' => $entity_type_id,
+ ],
+ 'url' => Url::fromUri('base:' . drupal_get_path('module', 'statistics') . '/statistics.php')->toString(),
+ ];
$build['#attached']['drupalSettings']['statistics'] = $settings;
}
}
@@ -50,10 +86,11 @@ function statistics_node_view(array &$build, EntityInterface $node, EntityViewDi
* Implements hook_node_links_alter().
*/
function statistics_node_links_alter(array &$links, NodeInterface $entity, array &$context) {
- if ($context['view_mode'] != 'rss') {
+ $entity_types = \Drupal::config('statistics.settings')->get('entity_type_ids');
+ if (in_array('node', $entity_types, TRUE) && $context['view_mode'] != 'rss') {
$links['#cache']['contexts'][] = 'user.permissions';
if (\Drupal::currentUser()->hasPermission('view post access counter')) {
- $statistics = \Drupal::service('statistics.storage.node')->fetchView($entity->id());
+ $statistics = \Drupal::service('statistics.storage')->fetchView($entity->getEntityType(), $entity->id());
if ($statistics) {
$statistics_links['statistics_counter']['title'] = \Drupal::translation()->formatPlural($statistics->getTotalCount(), '1 view', '@count views');
$links['statistics'] = [
@@ -71,10 +108,16 @@ function statistics_node_links_alter(array &$links, NodeInterface $entity, array
* Implements hook_cron().
*/
function statistics_cron() {
- $storage = \Drupal::service('statistics.storage.node');
- $storage->resetDayCount();
- $max_total_count = $storage->maxTotalCount();
- \Drupal::state()->set('statistics.node_counter_scale', 1.0 / max(1.0, $max_total_count));
+ $statistics_reset_count = \Drupal::service('statistics.reset_count');
+ $storage = \Drupal::service('statistics.storage');
+ $state = \Drupal::state();
+ $entity_type_manager = \Drupal::entityTypeManager();
+ $entity_types = \Drupal::configFactory()->get('statistics.settings')->get('entity_type_ids');
+ foreach (array_filter($entity_types) as $entity_type_id) {
+ $statistics_reset_count->resetDayCount($entity_type_id);
+ $max_total_count = $storage->maxTotalCount($entity_type_manager->getDefinition($entity_type_id));
+ $state->set("statistics.{$entity_type_id}_counter_scale", 1.0 / max(1.0, $max_total_count));
+ }
}
/**
@@ -94,7 +137,8 @@ function statistics_cron() {
* be executed correctly.
*/
function statistics_title_list($dbfield, $dbrows) {
- if (in_array($dbfield, ['totalcount', 'daycount', 'timestamp'])) {
+ $entity_types = \Drupal::config('statistics.settings')->get('entity_type_ids');
+ if (in_array('node', $entity_types, TRUE) && in_array($dbfield, array('totalcount', 'daycount', 'timestamp'))) {
$query = db_select('node_field_data', 'n');
$query->addTag('node_access');
$query->join('node_counter', 's', 'n.nid = s.nid');
@@ -120,40 +164,58 @@ function statistics_title_list($dbfield, $dbrows) {
* Retrieves a node's "view statistics".
*
* @deprecated in Drupal 8.2.x, will be removed before Drupal 9.0.0.
- * Use \Drupal::service('statistics.storage.node')->fetchView($id).
+ * Use \Drupal::service('statistics.storage')->fetchView($entity_type, $id).
*/
function statistics_get($id) {
- if ($id > 0) {
- /** @var \Drupal\statistics\StatisticsViewsResult $statistics */
- $statistics = \Drupal::service('statistics.storage.node')->fetchView($id);
-
- // For backwards compatibility, return FALSE if an invalid node ID was
- // passed in.
- if (!($statistics instanceof StatisticsViewsResult)) {
- return FALSE;
- }
- return [
- 'totalcount' => $statistics->getTotalCount(),
- 'daycount' => $statistics->getDayCount(),
- 'timestamp' => $statistics->getTimestamp(),
- ];
+ $entity_type = \Drupal::entityTypeManager()->getDefinition('node');
+ /** @var \Drupal\statistics\StatisticsViewsResult $statistics */
+ $statistics = \Drupal::service('statistics.storage')->fetchView($entity_type, $id);
+ // For backwards compatibility, return FALSE if an invalid node ID was
+ // passed in.
+ if (!($statistics instanceof StatisticsViewsResult)) {
+ return FALSE;
}
+ return [
+ 'totalcount' => $statistics->getTotalCount(),
+ 'daycount' => $statistics->getDayCount(),
+ 'timestamp' => $statistics->getTimestamp(),
+ ];
}
/**
* Implements hook_ENTITY_TYPE_predelete() for node entities.
*/
function statistics_node_predelete(EntityInterface $node) {
- // Clean up statistics table when node is deleted.
- $id = $node->id();
- return \Drupal::service('statistics.storage.node')->deleteViews($id);
+ $entity_types = \Drupal::config('statistics.settings')->get('entity_type_ids');
+ if (in_array('node', $entity_types, TRUE)) {
+ // Clean up statistics table when node is deleted.
+ \Drupal::service('statistics.storage')
+ ->deleteViews($node->getEntityType(), $node->id());
+ }
+}
+
+/**
+ * Implements hook_ENTITY_predelete() for node entities.
+ */
+function statistics_entity_predelete(EntityInterface $entity) {
+ // @todo Remove this condition once statistics_node_view() is removed.
+ if ($entity->getEntityTypeId() === 'node') {
+ return;
+ }
+ $entity_types = \Drupal::config('statistics.settings')->get('entity_type_ids');
+ if (in_array($entity->getEntityTypeId(), $entity_types, TRUE)) {
+ // Clean up statistics table when entity is deleted.
+ \Drupal::service('statistics.storage')
+ ->deleteViews($entity->getEntityType(), $entity->id());
+ }
}
/**
* Implements hook_ranking().
*/
function statistics_ranking() {
- if (\Drupal::config('statistics.settings')->get('count_content_views')) {
+ $entity_types = \Drupal::configFactory()->get('statistics.settings')->get('entity_type_ids');
+ if (in_array('node', $entity_types, TRUE)) {
return [
'views' => [
'title' => t('Number of views'),
@@ -192,8 +254,15 @@ function statistics_preprocess_block(&$variables) {
* to count content views.
*/
function statistics_block_alter(&$definitions) {
- $statistics_count_content_views = \Drupal::config('statistics.settings')->get('count_content_views');
- if (empty($statistics_count_content_views)) {
+ $entity_types = \Drupal::config('statistics.settings')->get('entity_type_ids');
+ if (!empty($entity_types) && !in_array('node', $entity_types, TRUE)) {
unset($definitions['statistics_popular_block']);
}
}
+
+/**
+ * Callback for migration settings.
+ */
+function statistics_migrate_callback($source) {
+ return $source ? ['node'] : [];
+}
diff --git a/core/modules/statistics/statistics.php b/core/modules/statistics/statistics.php
index a43509eaf8..8090e02726 100644
--- a/core/modules/statistics/statistics.php
+++ b/core/modules/statistics/statistics.php
@@ -11,20 +11,32 @@
chdir('../../..');
$autoloader = require_once 'autoload.php';
-
-$kernel = DrupalKernel::createFromRequest(Request::createFromGlobals(), $autoloader, 'prod');
+$request = Request::createFromGlobals();
+$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->boot();
$container = $kernel->getContainer();
-$views = $container
+$entity_types = $container
->get('config.factory')
->get('statistics.settings')
- ->get('count_content_views');
+ ->get('entity_type_ids');
+$key = filter_input(INPUT_POST, 'key', FILTER_CALLBACK, ['options' => 'statistics_validate_machine_name']);
+$id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);
+$entity_type = filter_input(INPUT_POST, 'type', FILTER_CALLBACK, ['options' => 'statistics_validate_machine_name']);
+if ($key && $id && $entity_type && in_array($entity_type, $entity_types, TRUE)) {
+ $container->get('request_stack')->push($request);
+ $container->get('statistics.storage')->recordView($entity_type, $key, $id);
+}
-if ($views) {
- $nid = filter_input(INPUT_POST, 'nid', FILTER_VALIDATE_INT);
- if ($nid) {
- $container->get('request_stack')->push(Request::createFromGlobals());
- $container->get('statistics.storage.node')->recordView($nid);
- }
+/**
+ * Validate entity type machine name.
+ *
+ * @param string $machine_name
+ * The machine name.
+ *
+ * @return string|null
+ * The valid machine name or NULL.
+ */
+function statistics_validate_machine_name($machine_name) {
+ return preg_match('@[^a-z0-9_]+@', $machine_name) === 0 ? $machine_name : NULL;
}
diff --git a/core/modules/statistics/statistics.services.yml b/core/modules/statistics/statistics.services.yml
index cf15573024..d746a8bf8f 100644
--- a/core/modules/statistics/statistics.services.yml
+++ b/core/modules/statistics/statistics.services.yml
@@ -1,6 +1,12 @@
services:
- statistics.storage.node:
- class: Drupal\statistics\NodeStatisticsDatabaseStorage
- arguments: ['@database', '@state', '@request_stack']
+ statistics.storage:
+ class: Drupal\statistics\StatisticsDatabaseStorage
+ arguments: ['@database', '@request_stack']
+ tags:
+ - { name: backend_overridable }
+
+ statistics.reset_count:
+ class: Drupal\statistics\StatisticsResetCount
+ arguments: ['@database', '@state', '@datetime.time']
tags:
- { name: backend_overridable }
diff --git a/core/modules/statistics/statistics.views.inc b/core/modules/statistics/statistics.views.inc
index 03e73ffcfa..de5f06c5f8 100644
--- a/core/modules/statistics/statistics.views.inc
+++ b/core/modules/statistics/statistics.views.inc
@@ -9,68 +9,82 @@
* Implements hook_views_data().
*/
function statistics_views_data() {
- $data['node_counter']['table']['group'] = t('Content statistics');
+ $data = [];
+ $entity_type_manager = \Drupal::entityTypeManager();
+ $entity_types = \Drupal::configFactory()->get('statistics.settings')->get('entity_type_ids');
+ if (!empty($entity_types)) {
+ foreach (array_filter($entity_types) as $entity_type_id) {
+ if ($entity_type_manager->hasHandler($entity_type_id, 'views_data')) {
+ $table = $entity_type_id . '_counter';
+ $entity_type = $entity_type_manager->getDefinition($entity_type_id);
+ $base_table = $entity_type_manager->getHandler($entity_type_id, 'views_data')
+ ->getViewsTableForEntityType($entity_type);
+ $data[$table]['table']['group'] = t('@label statistics', ['@label' => $entity_type->getLabel()]);
- $data['node_counter']['table']['join'] = [
- 'node_field_data' => [
- 'left_field' => 'nid',
- 'field' => 'nid',
- ],
- ];
+ $data[$table]['table']['join'] = [
+ $base_table => [
+ 'left_field' => $entity_type->getKey('id'),
+ 'field' => $entity_type->getKey('id'),
+ ],
+ ];
- $data['node_counter']['totalcount'] = [
- 'title' => t('Total views'),
- 'help' => t('The total number of times the node has been viewed.'),
- 'field' => [
- 'id' => 'statistics_numeric',
- 'click sortable' => TRUE,
- ],
- 'filter' => [
- 'id' => 'numeric',
- ],
- 'argument' => [
- 'id' => 'numeric',
- ],
- 'sort' => [
- 'id' => 'standard',
- ],
- ];
+ $data[$table]['totalcount'] = [
+ 'title' => t('Total views'),
+ 'help' => t('The total number of times the @entity has been viewed.', ['@entity' => $entity_type->id()]),
+ 'field' => [
+ 'id' => 'statistics_numeric',
+ 'click sortable' => TRUE,
+ ],
+ 'filter' => [
+ 'id' => 'numeric',
+ ],
+ 'argument' => [
+ 'id' => 'numeric',
+ ],
+ 'sort' => [
+ 'id' => 'standard',
+ ],
+ ];
- $data['node_counter']['daycount'] = [
- 'title' => t('Views today'),
- 'help' => t('The total number of times the node has been viewed today.'),
- 'field' => [
- 'id' => 'statistics_numeric',
- 'click sortable' => TRUE,
- ],
- 'filter' => [
- 'id' => 'numeric',
- ],
- 'argument' => [
- 'id' => 'numeric',
- ],
- 'sort' => [
- 'id' => 'standard',
- ],
- ];
+ $data[$table]['daycount'] = [
+ 'title' => t('Views today'),
+ 'help' => t('The total number of times the @entity has been viewed today.', ['@entity' => $entity_type->id()]),
+ 'field' => [
+ 'id' => 'statistics_numeric',
+ 'click sortable' => TRUE,
+ ],
+ 'filter' => [
+ 'id' => 'numeric',
+ ],
+ 'argument' => [
+ 'id' => 'numeric',
+ ],
+ 'sort' => [
+ 'id' => 'standard',
+ ],
+ ];
- $data['node_counter']['timestamp'] = [
- 'title' => t('Most recent view'),
- 'help' => t('The most recent time the node has been viewed.'),
- 'field' => [
- 'id' => 'node_counter_timestamp',
- 'click sortable' => TRUE,
- ],
- 'filter' => [
- 'id' => 'date',
- ],
- 'argument' => [
- 'id' => 'date',
- ],
- 'sort' => [
- 'id' => 'standard',
- ],
- ];
+ $data[$table]['timestamp'] = [
+ 'title' => t('Most recent view'),
+ 'help' => t('The most recent time the @entity has been viewed.', ['@entity' => $entity_type->id()]),
+ 'field' => [
+ // @todo replace node_counter_timestamp with entity_counter_timestamp.
+ 'id' => 'node_counter_timestamp',
+ 'click sortable' => TRUE,
+ ],
+ 'filter' => [
+ 'id' => 'date',
+ ],
+ 'argument' => [
+ 'id' => 'date',
+ ],
+ 'sort' => [
+ 'id' => 'standard',
+ ],
+ ];
+ }
+ }
+ }
return $data;
}
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php b/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php
index f4c22bd8a7..4d1f72408e 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php
@@ -63,19 +63,19 @@ protected function setUp() {
*/
public function testStatisticsSettings() {
$config = $this->config('statistics.settings');
- $this->assertFalse($config->get('count_content_views'), 'Count content view log is disabled by default.');
+ $this->assertFalse($config->get('entity_type_ids'), 'No entity types are enabled by default.');
// Enable counter on content view.
- $edit['statistics_count_content_views'] = 1;
+ $edit['entity_type_ids[node]'] = 1;
$this->drupalPostForm('admin/config/system/statistics', $edit, t('Save configuration'));
$config = $this->config('statistics.settings');
- $this->assertTrue($config->get('count_content_views'), 'Count content view log is enabled.');
+ $this->assertEqual($config->get('entity_type_ids'), ['node' => 'node', 'user' => 0], 'Node is enabled.');
// Hit the node.
$this->drupalGet('node/' . $this->testNode->id());
// Manually calling statistics.php, simulating ajax behavior.
$nid = $this->testNode->id();
- $post = ['nid' => $nid];
+ $post = ['type' => 'node', 'key' => 'nid', 'id' => $nid];
global $base_url;
$stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
$this->client->post($stats_path, ['form_params' => $post]);
@@ -105,12 +105,12 @@ public function testStatisticsSettings() {
* Tests that when a node is deleted, the node counter is deleted too.
*/
public function testDeleteNode() {
- $this->config('statistics.settings')->set('count_content_views', 1)->save();
+ $this->config('statistics.settings')->set('entity_type_ids', ['node'])->save();
$this->drupalGet('node/' . $this->testNode->id());
// Manually calling statistics.php, simulating ajax behavior.
$nid = $this->testNode->id();
- $post = ['nid' => $nid];
+ $post = ['type' => 'node', 'key' => 'nid', 'id' => $nid];
global $base_url;
$stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
$this->client->post($stats_path, ['form_params' => $post]);
@@ -137,14 +137,14 @@ public function testDeleteNode() {
*/
public function testExpiredLogs() {
$this->config('statistics.settings')
- ->set('count_content_views', 1)
+ ->set('entity_type_ids', ['node'])
->save();
\Drupal::state()->set('statistics.day_timestamp', 8640000);
$this->drupalGet('node/' . $this->testNode->id());
// Manually calling statistics.php, simulating ajax behavior.
$nid = $this->testNode->id();
- $post = ['nid' => $nid];
+ $post = ['type' => 'node', 'key' => 'nid', 'id' => $nid];
global $base_url;
$stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
$this->client->post($stats_path, ['form_params' => $post]);
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php b/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php
index 09565aefae..cdc79a1532 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php
@@ -78,7 +78,7 @@ protected function setUp() {
// Enable access logging.
$this->config('statistics.settings')
- ->set('count_content_views', 1)
+ ->set('entity_type_ids', ['node'])
->save();
// Clear the logs.
@@ -112,17 +112,17 @@ public function testLogging() {
$this->drupalGet($path);
$settings = $this->getDrupalSettings();
$this->assertPattern($expected_library, 'Found statistics library JS on node page.');
- $this->assertIdentical($this->node->id(), $settings['statistics']['data']['nid'], 'Found statistics settings on node page.');
+ $this->assertIdentical($this->node->id(), $settings['statistics']['data']['id'], 'Found statistics settings on node page.');
// Verify the same when loading the site in a non-default language.
$this->drupalGet($this->language['langcode'] . '/' . $path);
$settings = $this->getDrupalSettings();
$this->assertPattern($expected_library, 'Found statistics library JS on a valid node page in a non-default language.');
- $this->assertIdentical($this->node->id(), $settings['statistics']['data']['nid'], 'Found statistics settings on valid node page in a non-default language.');
+ $this->assertIdentical($this->node->id(), $settings['statistics']['data']['id'], 'Found statistics settings on valid node page in a non-default language.');
// Manually call statistics.php to simulate ajax data collection behavior.
global $base_root;
- $post = ['nid' => $this->node->id()];
+ $post = ['type' => 'node', 'key' => 'nid', 'id' => $this->node->id()];
$this->client->post($base_root . $stats_path, ['form_params' => $post]);
$node_counter = statistics_get($this->node->id());
$this->assertIdentical($node_counter['totalcount'], '1');
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
index edebca166c..f015993bb7 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
@@ -26,7 +26,7 @@ public function testPopularContentBlock() {
$this->drupalGet('node/' . $node->id());
// Manually calling statistics.php, simulating ajax behavior.
$nid = $node->id();
- $post = http_build_query(['nid' => $nid]);
+ $post = http_build_query(['type' => 'node', 'key' => 'nid', 'id' => $nid]);
$headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
global $base_url;
$stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php b/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php
index 3be95e2ab6..16f8bf1b6c 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php
@@ -44,7 +44,7 @@ protected function setUp() {
// Enable logging.
$this->config('statistics.settings')
- ->set('count_content_views', 1)
+ ->set('entity_type_ids', ['node'])
->save();
}
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php
index 8402d221af..f2d024aca5 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php
@@ -23,8 +23,8 @@ public function testStatisticsTokenReplacement() {
// Hit the node.
$this->drupalGet('node/' . $node->id());
// Manually calling statistics.php, simulating ajax behavior.
- $nid = $node->id();
- $post = http_build_query(['nid' => $nid]);
+ $id = $node->id();
+ $post = http_build_query(['type' => 'node', 'key' => 'nid', 'id' => $id]);
$headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
global $base_url;
$stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
diff --git a/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php b/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php
index a9c18a733b..0c59024639 100644
--- a/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php
+++ b/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php
@@ -32,7 +32,7 @@ protected function setUp() {
*/
public function testStatisticsSettings() {
$config = $this->config('statistics.settings');
- $this->assertSame(1, $config->get('count_content_views'));
+ $this->assertSame(['node'], $config->get('entity_type_ids'));
$this->assertConfigSchema(\Drupal::service('config.typed'), 'statistics.settings', $config->get());
}
diff --git a/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php b/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php
index 36e270d8f6..0fdfbb0128 100644
--- a/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php
+++ b/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php
@@ -32,7 +32,7 @@ protected function setUp() {
*/
public function testStatisticsSettings() {
$config = $this->config('statistics.settings');
- $this->assertIdentical(1, $config->get('count_content_views'));
+ $this->assertIdentical(['node'], $config->get('entity_type_ids'));
$this->assertConfigSchema(\Drupal::service('config.typed'), 'statistics.settings', $config->get());
}