diff --git a/core/modules/statistics/statistics.tokens.inc b/core/modules/statistics/statistics.tokens.inc index 467c6b4289a6..72f6500a6c8e 100644 --- a/core/modules/statistics/statistics.tokens.inc +++ b/core/modules/statistics/statistics.tokens.inc @@ -40,22 +40,29 @@ function statistics_tokens($type, $tokens, array $data, array $options, Bubbleab if ($type == 'node' & !empty($data['node'])) { $node = $data['node']; + /** @var \Drupal\statistics\StatisticsStorageInterface $stats_storage */ $stats_storage = \Drupal::service('statistics.storage.node'); + $node_view = NULL; + foreach ($tokens as $name => $original) { if ($name == 'total-count') { - $replacements[$original] = $stats_storage->fetchView($node->id())->getTotalCount(); + $node_view = $node_view ?? $stats_storage->fetchView($node->id()); + $replacements[$original] = $node_view ? $node_view->getTotalCount() : 0; } elseif ($name == 'day-count') { - $replacements[$original] = $stats_storage->fetchView($node->id())->getDayCount(); + $node_view = $node_view ?? $stats_storage->fetchView($node->id()); + $replacements[$original] = $node_view ? $node_view->getDayCount() : 0; } elseif ($name == 'last-view') { - $replacements[$original] = \Drupal::service('date.formatter')->format($stats_storage->fetchView($node->id())->getTimestamp()); + $node_view = $node_view ?? $stats_storage->fetchView($node->id()); + $replacements[$original] = $node_view ? \Drupal::service('date.formatter')->format($node_view->getTimestamp()) : t('never'); } } if ($created_tokens = $token_service->findWithPrefix($tokens, 'last-view')) { - $replacements += $token_service->generate('date', $created_tokens, ['date' => $stats_storage->fetchView($node->id())->getTimestamp()], $options, $bubbleable_metadata); + $node_view = $node_view ?? $stats_storage->fetchView($node->id()); + $replacements += $token_service->generate('date', $created_tokens, ['date' => $node_view ? $node_view->getTimestamp() : 0], $options, $bubbleable_metadata); } } diff --git a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php index 69e0185f9c98..d9c32ededd7c 100644 --- a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php +++ b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php @@ -28,6 +28,22 @@ class StatisticsTokenReplaceTest extends StatisticsTestBase { $this->drupalLogin($user); $node = $this->drupalCreateNode(['type' => 'page', 'uid' => $user->id()]); + /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */ + $date_formatter = $this->container->get('date.formatter'); + $request_time = \Drupal::time()->getRequestTime(); + + // Generate and test tokens. + $tests = []; + $tests['[node:total-count]'] = 0; + $tests['[node:day-count]'] = 0; + $tests['[node:last-view]'] = t('never'); + $tests['[node:last-view:short]'] = $date_formatter->format($request_time, 'short'); + + foreach ($tests as $input => $expected) { + $output = \Drupal::token()->replace($input, ['node' => $node], ['langcode' => $language_interface->getId()]); + $this->assertEqual($output, $expected, new FormattableMarkup('Statistics token %token replaced.', ['%token' => $input])); + } + // Hit the node. $this->drupalGet('node/' . $node->id()); // Manually calling statistics.php, simulating ajax behavior. @@ -45,8 +61,6 @@ class StatisticsTokenReplaceTest extends StatisticsTestBase { $tests = []; $tests['[node:total-count]'] = 1; $tests['[node:day-count]'] = 1; - /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */ - $date_formatter = $this->container->get('date.formatter'); $tests['[node:last-view]'] = $date_formatter->format($statistics->getTimestamp()); $tests['[node:last-view:short]'] = $date_formatter->format($statistics->getTimestamp(), 'short');