diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 0fd9e56..a256698 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -867,62 +867,6 @@ function comment_translation_configuration_element_submit($form, &$form_state) { } /** - * Implements hook_entity_load(). - * - * @see \Drupal\comment\Plugin\Field\FieldType\CommentItem::propertyDefinitions() - */ -function comment_entity_load($entities, $entity_type) { - if (!\Drupal::service('comment.manager')->getFields($entity_type)) { - // Do not query database when entity has no comment fields. - return; - } - // Load comment information from the database and update the entity's - // comment statistics properties, which are defined on each CommentItem field. - $result = \Drupal::service('comment.statistics')->read($entities, $entity_type); - foreach ($result as $record) { - $parts = explode('__', $record->field_id, 2); - list(, $field_name) = $parts; - - // Skip fields that entity does not have. - if (!$entities[$record->entity_id]->hasField($field_name)) { - continue; - } - $comment_statistics = $entities[$record->entity_id]->get($field_name); - $comment_statistics->cid = $record->cid; - $comment_statistics->last_comment_timestamp = $record->last_comment_timestamp; - $comment_statistics->last_comment_name = $record->last_comment_name; - $comment_statistics->last_comment_uid = $record->last_comment_uid; - $comment_statistics->comment_count = $record->comment_count; - } -} - -/** - * Implements hook_entity_insert(). - */ -function comment_entity_insert(EntityInterface $entity) { - // Allow bulk updates and inserts to temporarily disable the - // maintenance of the {comment_entity_statistics} table. - if (\Drupal::state()->get('comment.maintain_entity_statistics') && - $fields = \Drupal::service('comment.manager')->getFields($entity->getEntityTypeId())) { - \Drupal::service('comment.statistics')->create($entity, $fields); - } -} - -/** - * Implements hook_entity_predelete(). - */ -function comment_entity_predelete(EntityInterface $entity) { - $cids = db_select('comment', 'c') - ->fields('c', array('cid')) - ->condition('entity_id', $entity->id()) - ->condition('entity_type', $entity->getEntityTypeId()) - ->execute() - ->fetchCol(); - entity_delete_multiple('comment', $cids); - \Drupal::service('comment.statistics')->delete($entity); -} - -/** * Implements hook_node_update_index(). */ function comment_node_update_index(EntityInterface $node, $langcode) { @@ -978,8 +922,8 @@ function comment_node_update_index(EntityInterface $node, $langcode) { */ function comment_cron() { // Store the maximum possible comments per thread (used for node search - // ranking by reply count). - \Drupal::state()->set('comment.node_comment_statistics_scale', 1.0 / max(1, \Drupal::service('comment.statistics')->getMaximumCount('node'))); + // ranking by reply count). Only supports default 'comment' field. + \Drupal::state()->set('comment.node_comment_statistics_scale', 1.0 / max(1, \Drupal::service('comment.statistics')->getMaximumCount())); } /** diff --git a/core/modules/comment/lib/Drupal/comment/CommentStatistics.php b/core/modules/comment/lib/Drupal/comment/CommentStatistics.php index 5c67e84..2e3481c 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStatistics.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStatistics.php @@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityChangedInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Entity\FieldableDatabaseStorageController; use Drupal\Core\KeyValueStore\StateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\user\EntityOwnerInterface; @@ -68,79 +69,8 @@ public function __construct(Connection $database, AccountInterface $current_user /** * {@inheritdoc} */ - public function read($entities, $entity_type) { - return $this->database->select('comment_entity_statistics', 'ces') - ->fields('ces') - ->condition('ces.entity_id', array_keys($entities)) - ->condition('ces.entity_type', $entity_type) - ->execute(); - } - - /** - * {@inheritdoc} - */ - public function delete(EntityInterface $entity) { - $this->database->delete('comment_entity_statistics') - ->condition('entity_id', $entity->id()) - ->condition('entity_type', $entity->getEntityTypeId()) - ->execute(); - } - - /** - * {@inheritdoc} - */ - public function create(ContentEntityInterface $entity, $fields) { - $query = $this->database->insert('comment_entity_statistics') - ->fields(array( - 'entity_id', - 'entity_type', - 'field_id', - 'cid', - 'last_comment_timestamp', - 'last_comment_name', - 'last_comment_uid', - 'comment_count', - )); - foreach ($fields as $field_name => $detail) { - // Skip fields that entity does not have. - if (!$entity->hasField($field_name)) { - continue; - } - // Get the user ID from the entity if it's set, or default to the - // currently logged in user. - $last_comment_uid = 0; - if ($entity instanceof EntityOwnerInterface) { - $last_comment_uid = $entity->getOwnerId(); - } - if (!isset($last_comment_uid)) { - // Default to current user when entity does not implement - // EntityOwnerInterface or author is not set. - $last_comment_uid = $this->currentUser->id(); - } - // Default to REQUEST_TIME when entity does not have a changed property. - $last_comment_timestamp = REQUEST_TIME; - if ($entity instanceof EntityChangedInterface) { - $last_comment_timestamp = $entity->getChangedTime(); - } - $query->values(array( - 'entity_id' => $entity->id(), - 'entity_type' => $entity->getEntityTypeId(), - 'field_id' => $entity->getEntityTypeId() . '__' . $field_name, - 'cid' => 0, - 'last_comment_timestamp' => $last_comment_timestamp, - 'last_comment_name' => NULL, - 'last_comment_uid' => $last_comment_uid, - 'comment_count' => 0, - )); - } - $query->execute(); - } - - /** - * {@inheritdoc} - */ - public function getMaximumCount($entity_type) { - return $this->database->query('SELECT MAX(comment_count) FROM {comment_entity_statistics} WHERE entity_type = :entity_type', array(':entity_type' => $entity_type))->fetchField(); + public function getMaximumCount() { + return $this->database->query('SELECT MAX(comment_comment_count) FROM {node__comment}')->fetchField(); } /** @@ -152,16 +82,17 @@ public function getRankingInfo() { 'title' => t('Number of comments'), 'join' => array( 'type' => 'LEFT', - 'table' => 'comment_entity_statistics', + // @todo Work out how to make this work beyond default comment field. + 'table' => 'node__comment', 'alias' => 'ces', // Default to comment field as this is the most common use case for // nodes. - 'on' => "ces.entity_id = i.sid AND ces.entity_type = 'node' AND ces.field_id = 'node__comment'", + 'on' => "ces.entity_id = i.sid", ), // Inverse law that maps the highest reply count on the site to 1 and 0 // to 0. - 'score' => '2.0 - 2.0 / (1.0 + ces.comment_count * :scale)', - 'arguments' => array(':scale' => (float) \Drupal::state()->get('comment.node_comment_statistics_scale') ?: 0), + 'score' => '2.0 - 2.0 / (1.0 + ces.comment_comment_count * :scale)', + 'arguments' => array(':scale' => (float) $this->state->get('comment.node_comment_statistics_scale') ?: 0), ), ); } @@ -184,6 +115,9 @@ public function update(CommentInterface $comment) { ->execute() ->fetchField(); + $field_name = $comment->getFieldName(); + $field = $this->entityManager->getStorageController('field_config')->load($comment->getCommentedEntityTypeId() . '.' . $field_name); + $table_name = FieldableDatabaseStorageController::_fieldTableName($field); if ($count > 0) { // Comments exist. $last_reply = $this->database->select('comment', 'c') @@ -197,18 +131,17 @@ public function update(CommentInterface $comment) { ->execute() ->fetchObject(); // Use merge here because entity could be created before comment field. - $this->database->merge('comment_entity_statistics') + $this->database->merge($table_name) ->fields(array( - 'cid' => $last_reply->cid, - 'comment_count' => $count, - 'last_comment_timestamp' => $last_reply->changed, - 'last_comment_name' => $last_reply->uid ? '' : $last_reply->name, - 'last_comment_uid' => $last_reply->uid, + $field_name . '_cid' => $last_reply->cid, + $field_name . '_comment_count' => $count, + $field_name . '_last_comment_timestamp' => $last_reply->changed, + $field_name . '_last_comment_name' => $last_reply->uid ? '' : $last_reply->name, + $field_name . '_last_comment_uid' => $last_reply->uid, )) ->key(array( 'entity_id' => $comment->getCommentedEntityId(), - 'entity_type' => $comment->getCommentedEntityTypeId(), - 'field_id' => $comment->getFieldId(), + 'revision_id' => $comment->getCommentedEntityTypeId(), )) ->execute(); } @@ -223,21 +156,19 @@ public function update(CommentInterface $comment) { // EntityOwnerInterface or author is not set. $last_comment_uid = $this->currentUser->id(); } - $this->database->update('comment_entity_statistics') + $this->database->update($table_name) ->fields(array( - 'cid' => 0, - 'comment_count' => 0, + $field_name . 'cid' => 0, + $field_name . 'comment_count' => 0, // Use the created date of the entity if it's set, or default to // REQUEST_TIME. - 'last_comment_timestamp' => ($entity instanceof EntityChangedInterface) ? $entity->getChangedTime() : REQUEST_TIME, - 'last_comment_name' => '', + $field_name . 'last_comment_timestamp' => ($entity instanceof EntityChangedInterface) ? $entity->getChangedTime() : REQUEST_TIME, + $field_name . 'last_comment_name' => '', // Get the user ID from the entity if it's set, or default to the // currently logged in user. - 'last_comment_uid' => $last_comment_uid, + $field_name . 'last_comment_uid' => $last_comment_uid, )) ->condition('entity_id', $comment->getCommentedEntityId()) - ->condition('entity_type', $comment->getCommentedEntityTypeId()) - ->condition('field_id', $comment->getFieldId()) ->execute(); } } diff --git a/core/modules/comment/lib/Drupal/comment/CommentStatisticsInterface.php b/core/modules/comment/lib/Drupal/comment/CommentStatisticsInterface.php index dc34e96..b4954e6 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStatisticsInterface.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStatisticsInterface.php @@ -26,27 +26,6 @@ public function getRankingInfo(); /** - * Read comment statistics records for an array of entities. - * - * @param \Drupal\Core\Entity\EntityInterface[] $entities - * Array of entities on which commenting is enabled, keyed by id - * @param string $entity_type - * The entity type of the passed entities. - * - * @return object[] - * Array of statistics records keyed by entity id. - */ - public function read($entities, $entity_type); - - /** - * Delete comment statistics records for an entity. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity for which comment statistics should be deleted. - */ - public function delete(EntityInterface $entity); - - /** * Update or insert comment statistics records after a comment is added. * * @param \Drupal\comment\CommentInterface $comment @@ -59,24 +38,11 @@ public function update(CommentInterface $comment); * * Used to influence search rankings. * - * @param string $entity_type - * The entity type to consider when fetching the maximum comment count for. - * * @return int * The maximum number of comments for and entity of the given type. * * @see comment_update_index() */ - public function getMaximumCount($entity_type); - - /** - * Insert an empty record for the given entity. - * - * @param \Drupal\Core\Entity\ContentEntityInterface $entity - * The created entity for which a statistics record is to be initialized. - * @param array $fields - * Array of comment field definitions for the given entity. - */ - public function create(ContentEntityInterface $entity, $fields); + public function getMaximumCount(); } diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php index b50bafc..5a11ce3 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php @@ -72,9 +72,51 @@ public static function schema(FieldDefinitionInterface $field_definition) { 'not null' => TRUE, 'default' => 0, ), + 'cid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The {comment}.cid of the last comment.', + ), + 'last_comment_timestamp' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The Unix timestamp of the last comment that was posted within this node, from {comment}.changed.', + ), + 'last_comment_name' => array( + 'type' => 'varchar', + 'length' => 60, + 'not null' => FALSE, + 'description' => 'The name of the latest author to post a comment on this node, from {comment}.name.', + ), + 'last_comment_uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The user ID of the latest author to post a comment on this node, from {comment}.uid.', + ), + 'comment_count' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The total number of comments on this entity.', + ), + ), + 'indexes' => array( + 'last_comment_timestamp' => array('last_comment_timestamp'), + 'comment_count' => array('comment_count'), + 'last_comment_uid' => array('last_comment_uid'),), + 'foreign keys' => array( + 'last_comment_author' => array( + 'table' => 'users', + 'columns' => array( + 'last_comment_uid' => 'uid', + ), + ), ), - 'indexes' => array(), - 'foreign keys' => array(), ); }