From 36675eaafc9a85ad3a9324fca004437f01ea65a8 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Tue, 12 Aug 2014 17:40:09 -0700 Subject: [PATCH] Issue #2280861 by roderik, pcambra: CommentStatistics service followup. --- core/modules/comment/comment.install | 2 +- .../modules/comment/src/CommentStatistics.php | 5 ++- .../src/CommentStatisticsInterface.php | 5 ++- core/modules/comment/src/CommentStorage.php | 20 +--------- .../comment/src/CommentStorageInterface.php | 18 --------- core/modules/comment/src/Entity/Comment.php | 10 ++--- .../tests/src/Entity/CommentLockTest.php | 4 ++ core/modules/tracker/tracker.pages.inc | 38 +++++++++---------- 8 files changed, 35 insertions(+), 67 deletions(-) diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 4ce2b37cffe6..64aa6bd78f23 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -27,7 +27,7 @@ function comment_uninstall() { */ function comment_install() { // By default, maintain entity statistics for comments. - // @see \Drupal\comment\CommentStorage::updateEntityStatistics(). + // @see \Drupal\comment\CommentStatisticsInterface \Drupal::state()->set('comment.maintain_entity_statistics', TRUE); } diff --git a/core/modules/comment/src/CommentStatistics.php b/core/modules/comment/src/CommentStatistics.php index 164e8aa0bef2..0f2e93603dec 100644 --- a/core/modules/comment/src/CommentStatistics.php +++ b/core/modules/comment/src/CommentStatistics.php @@ -68,8 +68,9 @@ public function __construct(Connection $database, AccountInterface $current_user /** * {@inheritdoc} */ - public function read($entities, $entity_type) { - $stats = $this->database->select('comment_entity_statistics', 'ces') + public function read($entities, $entity_type, $accurate = TRUE) { + $options = $accurate ? array() : array('target' => 'replica'); + $stats = $this->database->select('comment_entity_statistics', 'ces', $options) ->fields('ces') ->condition('ces.entity_id', array_keys($entities)) ->condition('ces.entity_type', $entity_type) diff --git a/core/modules/comment/src/CommentStatisticsInterface.php b/core/modules/comment/src/CommentStatisticsInterface.php index 92a0b7af45ea..5e54a169b04b 100644 --- a/core/modules/comment/src/CommentStatisticsInterface.php +++ b/core/modules/comment/src/CommentStatisticsInterface.php @@ -32,11 +32,14 @@ public function getRankingInfo(); * Array of entities on which commenting is enabled, keyed by id * @param string $entity_type * The entity type of the passed entities. + * @param boolean $accurate + * (optional) Indicates if results must be completely up to date. If set to + * FALSE, a replica database will used if available. Defaults to TRUE. * * @return object[] * Array of statistics records. */ - public function read($entities, $entity_type); + public function read($entities, $entity_type, $accurate = TRUE); /** * Delete comment statistics records for an entity. diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php index 2d5541e54cd0..9639d597b731 100644 --- a/core/modules/comment/src/CommentStorage.php +++ b/core/modules/comment/src/CommentStorage.php @@ -25,13 +25,6 @@ */ class CommentStorage extends ContentEntityDatabaseStorage implements CommentStorageInterface { - /** - * The comment statistics service. - * - * @var \Drupal\comment\CommentStatisticsInterface - */ - protected $statistics; - /** * The current user. * @@ -50,14 +43,11 @@ class CommentStorage extends ContentEntityDatabaseStorage implements CommentStor * The entity manager. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. - * @param \Drupal\comment\CommentStatisticsInterface $comment_statistics - * The comment statistics service. * @param \Drupal\Core\Session\AccountInterface $current_user * The current user. */ - public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, CommentStatisticsInterface $comment_statistics, AccountInterface $current_user, CacheBackendInterface $cache) { + public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, AccountInterface $current_user, CacheBackendInterface $cache) { parent::__construct($entity_info, $database, $entity_manager, $cache); - $this->statistics = $comment_statistics; $this->currentUser = $current_user; } @@ -69,19 +59,11 @@ public static function createInstance(ContainerInterface $container, EntityTypeI $entity_info, $container->get('database'), $container->get('entity.manager'), - $container->get('comment.statistics'), $container->get('current_user'), $container->get('cache.entity') ); } - /** - * {@inheritdoc} - */ - public function updateEntityStatistics(CommentInterface $comment) { - $this->statistics->update($comment); - } - /** * {@inheritdoc} */ diff --git a/core/modules/comment/src/CommentStorageInterface.php b/core/modules/comment/src/CommentStorageInterface.php index 9087e5c72ba7..9eb4a668454d 100644 --- a/core/modules/comment/src/CommentStorageInterface.php +++ b/core/modules/comment/src/CommentStorageInterface.php @@ -107,24 +107,6 @@ public function getChildCids(array $comments); */ public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0); - /** - * Updates the comment statistics for a given node. - * - * The {comment_entity_statistics} table has the following fields: - * - last_comment_timestamp: The timestamp of the last comment for the entity, - * or the entity created timestamp if no comments exist for the entity. - * - last_comment_name: The name of the anonymous poster for the last comment. - * - last_comment_uid: The user ID of the poster for the last comment for - * this entity, or the entity author's user ID if no comments exist for the - * entity. - * - comment_count: The total number of approved/published comments on this - * entity. - * - * @param \Drupal\comment\CommentInterface $comment - * The comment being saved. - */ - public function updateEntityStatistics(CommentInterface $comment); - /** * Returns the number of unapproved comments. * diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index 1bb7ef0f2547..bb6c872291f8 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -76,9 +76,9 @@ public function preSave(EntityStorageInterface $storage) { $thread = $this->getThread(); if (empty($thread)) { if ($this->threadLock) { - // As preSave() is protected, this can only happen when this class - // is extended in a faulty manner. - throw new \LogicException('preSave is called again without calling postSave() or releaseThreadLock()'); + // Thread lock was not released after being set previously. + // This suggests there's a bug in code using this class. + throw new \LogicException('preSave() is called again without calling postSave() or releaseThreadLock()'); } if (!$this->hasParentComment()) { // This is a comment with no parent comment (depth 0): we start @@ -146,7 +146,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { $this->releaseThreadLock(); // Update the {comment_entity_statistics} table prior to executing the hook. - $storage->updateEntityStatistics($this); + \Drupal::service('comment.statistics')->update($this); } /** @@ -169,7 +169,7 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti entity_delete_multiple('comment', $child_cids); foreach ($entities as $id => $entity) { - $storage->updateEntityStatistics($entity); + \Drupal::service('comment.statistics')->update($entity); } } diff --git a/core/modules/comment/tests/src/Entity/CommentLockTest.php b/core/modules/comment/tests/src/Entity/CommentLockTest.php index a9a04f4ec8c8..af6a7f7ce806 100644 --- a/core/modules/comment/tests/src/Entity/CommentLockTest.php +++ b/core/modules/comment/tests/src/Entity/CommentLockTest.php @@ -27,6 +27,7 @@ public function testLocks() { $container->set('module_handler', $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface')); $container->set('current_user', $this->getMock('Drupal\Core\Session\AccountInterface')); $container->set('cache.test', $this->getMock('Drupal\Core\Cache\CacheBackendInterface')); + $container->set('comment.statistics', $this->getMock('Drupal\comment\CommentStatisticsInterface')); $request_stack = new RequestStack(); $request_stack->push(Request::create('/')); $container->set('request_stack', $request_stack); @@ -85,7 +86,10 @@ public function testLocks() { ->method('getListCacheTags') ->will($this->returnValue(array('comments' => TRUE))); $storage = $this->getMock('Drupal\comment\CommentStorageInterface'); + + // preSave() should acquire the lock. (This is what's really being tested.) $comment->preSave($storage); + // Release the acquired lock before exiting the test. $comment->postSave($storage); } diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc index 0aac664d66a1..a88b75451654 100644 --- a/core/modules/tracker/tracker.pages.inc +++ b/core/modules/tracker/tracker.pages.inc @@ -45,28 +45,24 @@ function tracker_page($account = NULL) { $rows = array(); if (!empty($tracker_data)) { - $nids = array_keys($tracker_data); - $nodes = node_load_multiple($nids); - // @todo This should be actually filtering on the desired language and just - // fall back to the default language. - $result = db_query(" - SELECT - n.nid, - SUM(l.comment_count) AS comment_count - FROM {node_field_data} n - INNER JOIN {comment_entity_statistics} l - ON n.nid = l.entity_id AND l.entity_type = 'node' - INNER JOIN {users} u - ON n.uid = u.uid - WHERE n.nid IN (:nids) - AND n.default_langcode = 1 - GROUP BY n.nid - ORDER BY n.changed DESC", array( - ':nids' => array_keys($nodes) - ), array('target' => 'replica'))->fetchAllKeyed(); - foreach ($result as $nid => $comment_count) { + // Load nodes into an array with the same order as $tracker_data. + $nodes = entity_load_multiple('node', 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; + } + $nodes[$nid]->last_activity = $tracker_data[$nid]->changed; - $nodes[$nid]->comment_count = $comment_count; } // Display the data. -- GitLab