Issue #3015650 by kim.pepper, andypost, Berdir, vacho, jibran, mikelutz, alexpott, larowlan, dpi: Remove tracker.pages.inc

merge-requests/55/head
Alex Pott 2019-10-03 09:15:53 +01:00
parent 7430b7a65f
commit 3ed7550648
No known key found for this signature in database
GPG Key ID: 31905460D4A69276
7 changed files with 332 additions and 173 deletions

View File

@ -0,0 +1,264 @@
<?php
namespace Drupal\tracker\Controller;
use Drupal\comment\CommentStatisticsInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\PagerSelectExtender;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Controller for tracker pages.
*/
class TrackerController extends ControllerBase {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The database replica connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $databaseReplica;
/**
* The comment statistics.
*
* @var \Drupal\comment\CommentStatisticsInterface
*/
protected $commentStatistics;
/**
* The date formatter.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
/**
* The node storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $nodeStorage;
/**
* Constructs a TrackerController object.
*
* @param \Drupal\Core\Database\Connection $database
* The database connection.
* @param \Drupal\Core\Database\Connection $databaseReplica
* The database replica connection.
* @param \Drupal\comment\CommentStatisticsInterface $commentStatistics
* The comment statistics.
* @param \Drupal\Core\Datetime\DateFormatterInterface $dateFormatter
* The date formatter.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct(Connection $database, Connection $databaseReplica, CommentStatisticsInterface $commentStatistics, DateFormatterInterface $dateFormatter, EntityTypeManagerInterface $entityTypeManager) {
$this->database = $database;
$this->databaseReplica = $databaseReplica;
$this->commentStatistics = $commentStatistics;
$this->dateFormatter = $dateFormatter;
$this->entityTypeManager = $entityTypeManager;
$this->nodeStorage = $entityTypeManager->getStorage('node');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('database'),
$container->get('database.replica'),
$container->get('comment.statistics'),
$container->get('date.formatter'),
$container->get('entity_type.manager')
);
}
/**
* Title callback for the tracker.user_tab route.
*
* @param \Drupal\user\UserInterface $user
* The user.
*
* @return string
* The title.
*/
public function getTitle(UserInterface $user) {
return $user->getDisplayName();
}
/**
* Checks access for the users recent content tracker page.
*
* @param \Drupal\user\UserInterface $user
* The user being viewed.
* @param \Drupal\Core\Session\AccountInterface $account
* The account viewing the page.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*/
public function checkAccess(UserInterface $user, AccountInterface $account) {
return AccessResult::allowedIf($account->isAuthenticated() && $user->id() == $account->id())
->cachePerUser();
}
/**
* Builds content for the tracker controllers.
*
* @param \Drupal\user\UserInterface|null $user
* (optional) The user account.
*
* @return array
* The render array.
*/
public function buildContent(UserInterface $user = NULL) {
if ($user) {
$query = $this->database->select('tracker_user', 't')
->extend(PagerSelectExtender::class)
->addMetaData('base_table', 'tracker_user')
->condition('t.uid', $user->id());
}
else {
$query = $this->databaseReplica->select('tracker_node', 't')
->extend(PagerSelectExtender::class)
->addMetaData('base_table', 'tracker_node');
}
// This array acts as a placeholder for the data selected later
// while keeping the correct order.
$tracker_data = $query
->addTag('node_access')
->fields('t', ['nid', 'changed'])
->condition('t.published', 1)
->orderBy('t.changed', 'DESC')
->limit(25)
->execute()
->fetchAllAssoc('nid');
$cacheable_metadata = new CacheableMetadata();
$rows = [];
if (!empty($tracker_data)) {
// Load nodes into an array with the same order as $tracker_data.
/** @var \Drupal\node\NodeInterface[] $nodes */
$nodes = $this->nodeStorage->loadMultiple(array_keys($tracker_data));
// Enrich the node data.
$result = $this->commentStatistics->read($nodes, 'node', FALSE);
foreach ($result as $statistics) {
// The node ID may not be unique; there can be multiple comment fields.
// Make comment_count the total of all comments.
$nid = $statistics->entity_id;
if (empty($nodes[$nid]->comment_count)
|| !is_numeric($tracker_data[$nid]->comment_count)) {
$tracker_data[$nid]->comment_count = $statistics->comment_count;
}
else {
$tracker_data[$nid]->comment_count += $statistics->comment_count;
}
// Make the last comment timestamp reflect the latest comment.
if (!isset($tracker_data[$nid]->last_comment_timestamp)) {
$tracker_data[$nid]->last_comment_timestamp = $statistics->last_comment_timestamp;
}
else {
$tracker_data[$nid]->last_comment_timestamp = max($tracker_data[$nid]->last_comment_timestamp, $statistics->last_comment_timestamp);
}
}
// Display the data.
foreach ($nodes as $node) {
// Set the last activity time from tracker data. This also takes into
// account comment activity, so getChangedTime() is not used.
$last_activity = $tracker_data[$node->id()]->changed;
$owner = $node->getOwner();
$row = [
'type' => node_get_type_label($node),
'title' => [
'data' => [
'#type' => 'link',
'#url' => $node->toUrl(),
'#title' => $node->getTitle(),
],
'data-history-node-id' => $node->id(),
'data-history-node-timestamp' => $node->getChangedTime(),
],
'author' => [
'data' => [
'#theme' => 'username',
'#account' => $owner,
],
],
'comments' => [
'class' => ['comments'],
'data' => $tracker_data[$node->id()]->comment_count ?? 0,
'data-history-node-last-comment-timestamp' => $tracker_data[$node->id()]->last_comment_timestamp ?? 0,
],
'last updated' => [
'data' => t('@time ago', [
'@time' => $this->dateFormatter->formatTimeDiffSince($last_activity),
]),
],
];
$rows[] = $row;
// Add node and node owner to cache tags.
$cacheable_metadata->addCacheTags($node->getCacheTags());
if ($owner) {
$cacheable_metadata->addCacheTags($owner->getCacheTags());
}
}
}
// Add the list cache tag for nodes.
$cacheable_metadata->addCacheTags($this->nodeStorage->getEntityType()->getListCacheTags());
$page['tracker'] = [
'#rows' => $rows,
'#header' => [
$this->t('Type'),
$this->t('Title'),
$this->t('Author'),
$this->t('Comments'),
$this->t('Last updated'),
],
'#type' => 'table',
'#empty' => $this->t('No content available.'),
];
$page['pager'] = [
'#type' => 'pager',
'#weight' => 10,
];
$page['#sorted'] = TRUE;
$cacheable_metadata->addCacheContexts(['user.node_grants:view']);
// Display the reading history if that module is enabled.
if ($this->moduleHandler()->moduleExists('history')) {
// Reading history is tracked for authenticated users only.
if ($this->currentUser()->isAuthenticated()) {
$page['#attached']['library'][] = 'tracker/history';
}
$cacheable_metadata->addCacheContexts(['user.roles:authenticated']);
}
$cacheable_metadata->applyTo($page);
return $page;
}
}

View File

@ -2,19 +2,18 @@
namespace Drupal\tracker\Controller;
use Drupal\Core\Controller\ControllerBase;
@trigger_error(__NAMESPACE__ . '\TrackerPage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\tracker\Controller\TrackerController instead. See https://www.drupal.org/node/3030645', E_USER_DEPRECATED);
/**
* Controller for tracker.page route.
*/
class TrackerPage extends ControllerBase {
class TrackerPage extends TrackerController {
/**
* Content callback for the tracker.page route.
*/
public function getContent() {
module_load_include('inc', 'tracker', 'tracker.pages');
return tracker_page();
return $this->buildContent();
}
}

View File

@ -2,38 +2,20 @@
namespace Drupal\tracker\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Session\AccountInterface;
@trigger_error(__NAMESPACE__ . '\TrackerUserRecent is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\tracker\Controller\TrackerController instead. See https://www.drupal.org/node/3030645', E_USER_DEPRECATED);
use Drupal\user\UserInterface;
/**
* Controller for tracker.users_recent_content route.
*/
class TrackerUserRecent extends ControllerBase {
class TrackerUserRecent extends TrackerController {
/**
* Content callback for the tracker.users_recent_content route.
*/
public function getContent(UserInterface $user) {
module_load_include('inc', 'tracker', 'tracker.pages');
return tracker_page($user);
}
/**
* Checks access for the users recent content tracker page.
*
* @param \Drupal\user\UserInterface $user
* The user being viewed.
* @param \Drupal\Core\Session\AccountInterface $account
* The account viewing the page.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*/
public function checkAccess(UserInterface $user, AccountInterface $account) {
return AccessResult::allowedIf($account->isAuthenticated() && $user->id() == $account->id())
->cachePerUser();
return $this->buildContent($user);
}
}

View File

@ -2,27 +2,20 @@
namespace Drupal\tracker\Controller;
use Drupal\Core\Controller\ControllerBase;
@trigger_error(__NAMESPACE__ . '\TrackerUserTab is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\tracker\Controller\TrackerController instead. See https://www.drupal.org/node/3030645', E_USER_DEPRECATED);
use Drupal\user\UserInterface;
/**
* Controller for tracker.user_tab route.
*/
class TrackerUserTab extends ControllerBase {
class TrackerUserTab extends TrackerController {
/**
* Content callback for the tracker.user_tab route.
*/
public function getContent(UserInterface $user) {
module_load_include('inc', 'tracker', 'tracker.pages');
return tracker_page($user);
}
/**
* Title callback for the tracker.user_tab route.
*/
public function getTitle(UserInterface $user) {
return $user->getAccountName();
return $this->buildContent($user);
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Drupal\Tests\tracker\Kernel;
use Drupal\KernelTests\KernelTestBase;
/**
* @group tracker
* @group legacy
*/
class TrackerLegacyTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'comment',
'tracker',
'history',
'node',
'node_test',
'user',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('node');
$this->installSchema('node', 'node_access');
$this->installSchema('tracker', 'tracker_node');
$this->installSchema('tracker', 'tracker_user');
}
/**
* @expectedDeprecation tracker_page is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\tracker\Controller\TrackerController::buildContent() instead. See https://www.drupal.org/node/3030645
*/
public function testDeprecatedTrackerPage() {
module_load_include('inc', 'tracker', 'tracker.pages');
$this->assertNotEmpty(tracker_page());
}
}

View File

@ -5,8 +5,7 @@
* User page callbacks for tracker.module.
*/
use Drupal\Core\Cache\Cache;
use Drupal\node\Entity\Node;
use Drupal\tracker\Controller\TrackerController;
/**
* Page callback: Generates a page of tracked nodes for the site.
@ -19,135 +18,13 @@ use Drupal\node\Entity\Node;
*
* @return array
* A renderable array.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\tracker\Controller\TrackerController::buildContent() instead.
*
* @see https://www.drupal.org/node/3030645
*/
function tracker_page($account = NULL) {
if ($account) {
$query = \Drupal::database()->select('tracker_user', 't')
->extend('Drupal\Core\Database\Query\PagerSelectExtender')
->addMetaData('base_table', 'tracker_user')
->condition('t.uid', $account->id());
}
else {
$query = \Drupal::service('database.replica')->select('tracker_node', 't')
->extend('Drupal\Core\Database\Query\PagerSelectExtender')
->addMetaData('base_table', 'tracker_node');
}
// This array acts as a placeholder for the data selected later
// while keeping the correct order.
$tracker_data = $query
->addTag('node_access')
->fields('t', ['nid', 'changed'])
->condition('t.published', 1)
->orderBy('t.changed', 'DESC')
->limit(25)
->execute()
->fetchAllAssoc('nid');
$cache_tags = [];
$rows = [];
if (!empty($tracker_data)) {
// Load nodes into an array with the same order as $tracker_data.
$nodes = Node::loadMultiple(array_keys($tracker_data));
// Enrich the node data.
$result = \Drupal::service('comment.statistics')->read($nodes, 'node', FALSE);
foreach ($result as $statistics) {
// The node ID may not be unique; there can be multiple comment fields.
// Make comment_count the total of all comments.
$nid = $statistics->entity_id;
if (empty($nodes[$nid]->comment_count)
|| !is_numeric($nodes[$nid]->comment_count)) {
$nodes[$nid]->comment_count = $statistics->comment_count;
}
else {
$nodes[$nid]->comment_count += $statistics->comment_count;
}
// Make the last comment timestamp reflect the latest comment.
if (!isset($nodes[$nid]->last_comment_timestamp)) {
$nodes[$nid]->last_comment_timestamp = $statistics->last_comment_timestamp;
}
else {
$nodes[$nid]->last_comment_timestamp = max($nodes[$nid]->last_comment_timestamp, $statistics->last_comment_timestamp);
}
}
// Display the data.
foreach ($nodes as $node) {
// Set the last activity time from tracker data. This also takes into
// account comment activity, so getChangedTime() is not used.
$node->last_activity = $tracker_data[$node->id()]->changed;
// Determine the number of comments.
$comments = 0;
if ($node->comment_count) {
$comments = $node->comment_count;
}
$row = [
'type' => node_get_type_label($node),
'title' => [
'data' => [
'#type' => 'link',
'#url' => $node->toUrl(),
'#title' => $node->getTitle(),
],
'data-history-node-id' => $node->id(),
'data-history-node-timestamp' => $node->getChangedTime(),
],
'author' => [
'data' => [
'#theme' => 'username',
'#account' => $node->getOwner(),
],
],
'comments' => [
'class' => ['comments'],
'data' => $comments,
'data-history-node-last-comment-timestamp' => $node->last_comment_timestamp,
],
'last updated' => [
'data' => t('@time ago', [
'@time' => \Drupal::service('date.formatter')->formatTimeDiffSince($node->last_activity),
]),
],
];
$rows[] = $row;
// Add node and node owner to cache tags.
$cache_tags = Cache::mergeTags($cache_tags, $node->getCacheTags());
if ($node->getOwner()) {
$cache_tags = Cache::mergeTags($cache_tags, $node->getOwner()->getCacheTags());
}
}
}
// Add the list cache tag for nodes.
$cache_tags = Cache::mergeTags($cache_tags, \Drupal::entityTypeManager()->getDefinition('node')->getListCacheTags());
$page['tracker'] = [
'#rows' => $rows,
'#header' => [t('Type'), t('Title'), t('Author'), t('Comments'), t('Last updated')],
'#type' => 'table',
'#empty' => t('No content available.'),
];
$page['pager'] = [
'#type' => 'pager',
'#weight' => 10,
];
$page['#sorted'] = TRUE;
$page['#cache']['tags'] = $cache_tags;
$page['#cache']['contexts'][] = 'user.node_grants:view';
// Display the reading history if that module is enabled.
if (\Drupal::moduleHandler()->moduleExists('history')) {
// Reading history is tracked for authenticated users only.
if (\Drupal::currentUser()->isAuthenticated()) {
$page['#attached']['library'][] = 'tracker/history';
}
$page['#cache']['contexts'][] = 'user.roles:authenticated';
}
return $page;
@trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\tracker\Controller\TrackerController::buildContent() instead. See https://www.drupal.org/node/3030645', E_USER_DEPRECATED);
return \Drupal::classResolver(TrackerController::class)->buildContent($account);
}

View File

@ -1,7 +1,7 @@
tracker.page:
path: '/activity'
defaults:
_controller: '\Drupal\tracker\Controller\TrackerPage::getContent'
_controller: '\Drupal\tracker\Controller\TrackerController::buildContent'
_title: 'Recent content'
requirements:
_permission: 'access content'
@ -9,18 +9,18 @@ tracker.page:
tracker.users_recent_content:
path: '/activity/{user}'
defaults:
_controller: '\Drupal\tracker\Controller\TrackerUserRecent::getContent'
_controller: '\Drupal\tracker\Controller\TrackerController::buildContent'
_title: 'My recent content'
requirements:
_permission: 'access content'
_custom_access: '\Drupal\tracker\Controller\TrackerUserRecent::checkAccess'
_custom_access: '\Drupal\tracker\Controller\TrackerController::checkAccess'
user: \d+
tracker.user_tab:
path: '/user/{user}/activity'
defaults:
_controller: '\Drupal\tracker\Controller\TrackerUserTab::getContent'
_title_callback: '\Drupal\tracker\Controller\TrackerUserTab::getTitle'
_controller: '\Drupal\tracker\Controller\TrackerController::buildContent'
_title_callback: '\Drupal\tracker\Controller\TrackerController::getTitle'
requirements:
_permission: 'access content'
_entity_access: 'user.view'