diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 08cd8e3..5a49458 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -182,7 +182,7 @@ function comment_menu_link_defaults_alter(&$links) { /** * Returns a menu title which includes the number of unapproved comments. * - * @todo Move to the comment manager and replace by a entity query? + * @deprecated Deprecated since Drupal 8.x-dev, to be removed in Drupal 8.0. */ function comment_count_unpublished() { $count = \Drupal::entityQuery('comment') @@ -249,11 +249,11 @@ function comment_field_config_delete(FieldConfigInterface $field) { function comment_field_instance_config_delete(FieldInstanceConfigInterface $instance) { if ($instance->getType() == 'comment') { // Delete all comments that used by the entity bundle. - $comments = \Drupal::entityQuery('comment') + $cids = \Drupal::entityQuery('comment') ->condition('field_id', $instance->getEntityTypeId() . '__' . $instance->getName()) ->condition('entity_type', $instance->getEntityTypeId()) ->execute(); - entity_delete_multiple('comment', $comments); + entity_delete_multiple('comment', $cids); } } @@ -281,63 +281,40 @@ function comment_permission() { } /** - * Finds the most recent comments that are available to the current user. - * - * @param integer $number - * (optional) The maximum number of comments to find. Defaults to 10. - * - * @return - * An array of comment objects or an empty array if there are no recent - * comments visible to the current user. - */ -function comment_get_recent($number = 10) { - return \Drupal::entityManager() - ->getStorageController('comment') - ->loadRecent($number); -} - -/** * Calculates the page number for the first new comment. * * @param int $num_comments - * Number of comments. - * @param int $new_replies - * Number of new replies. + * The total number of comments that the entity has. + * @param int $new_comments + * The number of new comments that the entity has. * @param \Drupal\Core\Entity\EntityInterface $entity - * The first new comment entity. + * The entity that has the comments. * @param string $field_name - * The field name on the entity to which comments are attached to. + * The field name on the entity to which comments are attached. * * @return array|null * An array "page=X" if the page number is greater than zero; NULL otherwise. */ -function comment_new_page_count($num_comments, $new_replies, EntityInterface $entity, $field_name = 'comment') { +function comment_new_page_count($num_comments, $new_comments, EntityInterface $entity, $field_name = 'comment') { $instance = \Drupal::service('field.info')->getInstance($entity->getEntityTypeId(), $entity->bundle(), $field_name); - $mode = $instance->getSetting('default_mode'); $comments_per_page = $instance->getSetting('per_page'); - $pagenum = NULL; - $flat = $mode == COMMENT_MODE_FLAT ? TRUE : FALSE; + if ($num_comments <= $comments_per_page) { // Only one page of comments. $pageno = 0; } - elseif ($flat) { + elseif ($instance->getSetting('default_mode') == COMMENT_MODE_FLAT) { // Flat comments. - $count = $num_comments - $new_replies; + $count = $num_comments - $new_comments; $pageno = $count / $comments_per_page; } else { // Threaded comments. - $pageno = \Drupal::entityManager() - ->getStorageController('comment') - ->getThreadedNewCommentPage($entity, $new_replies, $comments_per_page, $field_name); + $pageno = \Drupal::entityManager()->getStorage('comment') + ->getThreadedNewCommentPageNr($entity, $new_comments, $comments_per_page, $field_name); } - if ($pageno >= 1) { - $pagenum = array('page' => intval($pageno)); - } - - return $pagenum; + return $pageno ? array('page' => $pageno) : NULL; } /** @@ -359,25 +336,6 @@ function comment_entity_build_defaults_alter(array &$build, EntityInterface $ent return $build; } -function theme_comment_block($variables) { - $items = array(); - $number = $variables['number']; - foreach (comment_get_recent($number) as $comment) { - $items[] = l($comment->subject->value, 'comment/' . $comment->id(), array('fragment' => 'comment-' . $comment->id())) . ' ' . t('@time ago', array('@time' => format_interval(REQUEST_TIME - $comment->getChangedTime()))) . ''; - } - - if ($items) { - $item_list = array( - '#theme' => 'item_list', - '#items' => $items, - ); - return drupal_render($item_list); - } - else { - return t('No comments available.'); - } -} - /** * Implements hook_node_links_alter(). */ @@ -586,62 +544,13 @@ function comment_add(EntityInterface $entity, $field_name = 'comment', $pid = NU * @return int[] * An array of the IDs of the comment to be displayed. * - * To display threaded comments in the correct order we keep a 'thread' field - * and order by that value. This field keeps this data in - * a way which is easy to update and convenient to use. - * - * A "thread" value starts at "1". If we add a child (A) to this comment, - * we assign it a "thread" = "1.1". A child of (A) will have "1.1.1". Next - * brother of (A) will get "1.2". Next brother of the parent of (A) will get - * "2" and so on. - * - * First of all note that the thread field stores the depth of the comment: - * depth 0 will be "X", depth 1 "X.X", depth 2 "X.X.X", etc. - * - * Now to get the ordering right, consider this example: - * - * 1 - * 1.1 - * 1.1.1 - * 1.2 - * 2 - * - * If we "ORDER BY thread ASC" we get the above result, and this is the - * natural order sorted by time. However, if we "ORDER BY thread DESC" - * we get: - * - * 2 - * 1.2 - * 1.1.1 - * 1.1 - * 1 - * - * Clearly, this is not a natural way to see a thread, and users will get - * confused. The natural order to show a thread by time desc would be: - * - * 2 - * 1 - * 1.2 - * 1.1 - * 1.1.1 - * - * which is what we already did before the standard pager patch. To achieve - * this we simply add a "/" at the end of each "thread" value. This way, the - * thread fields will look like this: - * - * 1/ - * 1.1/ - * 1.1.1/ - * 1.2/ - * 2/ - * - * we add "/" since this char is, in ASCII, higher than every number, so if - * now we "ORDER BY thread DESC" we get the correct order. However this would - * spoil the reverse ordering, "ORDER BY thread ASC" -- here, we do not need - * to consider the trailing "/" so we use a substring only. + * @deprecated Deprecated since Drupal 8.x-dev, to be removed in Drupal 8.0. + * Use \Drupal::entityManager()->getStorage('comment')->loadThread() instead, + * which returns objects instead of IDs. */ function comment_get_thread(EntityInterface $entity, $field_name, $mode, $comments_per_page, $pager_id = 0) { - return \Drupal::entityManager()->getStorageController('comment')->loadThread($entity, $field_name, $mode, $comments_per_page, $pager_id); + $nodes = \Drupal::entityManager()->getStorage('comment')->loadThread($entity, $field_name, $mode, $comments_per_page, $pager_id); + return array_keys($nodes); } /** @@ -853,12 +762,10 @@ function comment_entity_predelete(EntityInterface $entity) { // entity type that has an integer ID, $entity->id() might be a string // containing a number), and then cast it to an integer when querying. if ($entity->getEntityType()->isFieldable() && is_numeric($entity->id())) { - $cids = db_select('comment', 'c') - ->fields('c', array('cid')) + $cids = \Drupal::entityQuery('comment') ->condition('entity_id', (int) $entity->id()) ->condition('entity_type', $entity->getEntityTypeId()) - ->execute() - ->fetchCol(); + ->execute(); entity_delete_multiple('comment', $cids); \Drupal::service('comment.statistics')->delete($entity); } @@ -904,7 +811,9 @@ function comment_node_update_index(EntityInterface $node, $langcode) { $instance = \Drupal::service('field.info')->getInstance('node', $node->getType(), $field_name); $mode = $instance->getSetting('default_mode'); $comments_per_page = $instance->getSetting('per_page'); - if ($node->get($field_name)->status && $comments = comment_get_thread($node, $field_name, $mode, $comments_per_page)) { + if ($node->get($field_name)->status + && $comments = \Drupal::entityManager()->getStorage('comment') + ->loadThread($node, $field_name, $mode, $comments_per_page)) { comment_prepare_thread($comments); $build = comment_view_multiple($comments); $return .= drupal_render($build); @@ -983,7 +892,10 @@ function comment_user_cancel($edit, $account, $method) { * Implements hook_user_predelete(). */ function comment_user_predelete($account) { - $cids = \Drupal::entityManager()->getStorageController('comment')->loadUsersComments($account); + $cids = \Drupal::entityQuery('comment') + ->condition('uid', $account->id()) + ->condition('status', CommentInterface::PUBLISHED) + ->execute(); entity_delete_multiple('comment', $cids); } @@ -1094,11 +1006,13 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam * @return int * The display ordinal for the comment. * - * @see comment_get_display_page() - * @see field_info_instance(). + * @deprecated Deprecated since Drupal 8.x-dev, to be removed in Drupal 8.0. + * Use \Drupal::entityManager()->getStorage('comment')->getDisplayOrdinal() + * instead. (Note 2nd argument is different). */ function comment_get_display_ordinal($cid, $instance) { - return \Drupal::entityManager()->getStorageController('comment')->getCommentDisplayOrdinal($cid, $instance); + return \Drupal::entityManager()->getStorage('comment') + ->getDisplayOrdinal($cid, $instance->getSetting('default_mode')); } /** diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorage.php b/core/modules/comment/lib/Drupal/comment/CommentStorage.php index 0f09834..7f79673 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorage.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorage.php @@ -92,7 +92,7 @@ public function updateEntityStatistics(CommentInterface $comment) { /** * {@inheritdoc} */ - public function getMaxThread(EntityInterface $comment) { + public function getMaxThread(CommentInterface $comment) { $query = $this->database->select('comment', 'c') ->condition('entity_id', $comment->getCommentedEntityId()) ->condition('field_id', $comment->getFieldId()) @@ -105,7 +105,7 @@ public function getMaxThread(EntityInterface $comment) { /** * {@inheritdoc} */ - public function getMaxThreadPerThread(EntityInterface $comment) { + public function getMaxThreadPerThread(CommentInterface $comment) { $query = $this->database->select('comment', 'c') ->condition('entity_id', $comment->getCommentedEntityId()) ->condition('field_id', $comment->getFieldId()) @@ -119,57 +119,109 @@ public function getMaxThreadPerThread(EntityInterface $comment) { /** * {@inheritdoc} */ - public function getChildCids(array $comments) { - return $this->database->select('comment', 'c') - ->fields('c', array('cid')) - ->condition('pid', array_keys($comments)) - ->execute() - ->fetchCol(); + public function getDisplayOrdinal($cid, $comment_mode) { + // Count how many comments (c1) are before $cid (c2) in display order. This + // is the 0-based display ordinal. + $query = $this->database->select('comment', 'c1'); + $query->innerJoin('comment', 'c2', 'c2.entity_id = c1.entity_id AND c2.entity_type = c1.entity_type AND c2.field_id = c1.field_id'); + $query->addExpression('COUNT(*)', 'count'); + $query->condition('c2.cid', $cid); + if (!user_access('administer comments')) { + $query->condition('c1.status', CommentInterface::PUBLISHED); + } + + if ($comment_mode == COMMENT_MODE_FLAT) { + // For rendering flat comments, cid is used for ordering comments due to + // unpredictable behavior with timestamp, so we make the same assumption + // here. + $query->condition('c1.cid', $cid, '<'); + } + else { + // For threaded comments, the c.thread column is used for ordering. We can + // use the sorting code for comparison, but must remove the trailing + // slash. + $query->where('SUBSTRING(c1.thread, 1, (LENGTH(c1.thread) - 1)) < SUBSTRING(c2.thread, 1, (LENGTH(c2.thread) - 1))'); + } + + return $query->execute()->fetchField(); } /** * {@inheritdoc} */ - public function loadRecent($number = 10) { - $query = db_select('comment', 'c'); - $query->addMetaData('base_table', 'comment'); - $query->fields('c', array('cid')) - ->condition('c.status', CommentInterface::PUBLISHED); - if (\Drupal::moduleHandler()->moduleExists('node')) { - // Special case to filter by published content. - $query->innerJoin('node_field_data', 'n', "n.nid = c.entity_id AND c.entity_type = 'node'"); - $query->addTag('node_access'); - // @todo This should be actually filtering on the desired node status field - // language and just fall back to the default language. - $query - ->condition('n.status', NODE_PUBLISHED) - ->condition('n.default_langcode', 1); - } - $cids = $query - ->orderBy('c.created', 'DESC') - // Additionally order by cid to ensure that comments with the same - // timestamp are returned in the exact order posted. - ->orderBy('c.cid', 'DESC') - ->range(0, $number) + public function getChildCids(array $comments) { + return $this->database->select('comment', 'c') + ->fields('c', array('cid')) + ->condition('pid', array_keys($comments)) ->execute() ->fetchCol(); - - $comments = array(); - if ($cids) { - $comments = $this->loadMultiple($cids); - } - - return $comments; } /** * {@inheritdoc} + * + * To display threaded comments in the correct order we keep a 'thread' field + * and order by that value. This field keeps this data in + * a way which is easy to update and convenient to use. + * + * A "thread" value starts at "1". If we add a child (A) to this comment, + * we assign it a "thread" = "1.1". A child of (A) will have "1.1.1". Next + * brother of (A) will get "1.2". Next brother of the parent of (A) will get + * "2" and so on. + * + * First of all note that the thread field stores the depth of the comment: + * depth 0 will be "X", depth 1 "X.X", depth 2 "X.X.X", etc. + * + * Now to get the ordering right, consider this example: + * + * 1 + * 1.1 + * 1.1.1 + * 1.2 + * 2 + * + * If we "ORDER BY thread ASC" we get the above result, and this is the + * natural order sorted by time. However, if we "ORDER BY thread DESC" + * we get: + * + * 2 + * 1.2 + * 1.1.1 + * 1.1 + * 1 + * + * Clearly, this is not a natural way to see a thread, and users will get + * confused. The natural order to show a thread by time desc would be: + * + * 2 + * 1 + * 1.2 + * 1.1 + * 1.1.1 + * + * which is what we already did before the standard pager patch. To achieve + * this we simply add a "/" at the end of each "thread" value. This way, the + * thread fields will look like this: + * + * 1/ + * 1.1/ + * 1.1.1/ + * 1.2/ + * 2/ + * + * we add "/" since this char is, in ASCII, higher than every number, so if + * now we "ORDER BY thread DESC" we get the correct order. However this would + * spoil the reverse ordering, "ORDER BY thread ASC" -- here, we do not need + * to consider the trailing "/" so we use a substring only. */ - public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page, $pager_id) { - $query = db_select('comment', 'c') - ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); - if ($pager_id) { - $query->element($pager_id); + public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0) { + $query = $this->database->select('comment', 'c'); + if ($comments_per_page > 0) { + $query = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender') + ->limit($comments_per_page); + if ($pager_id) { + $query->element($pager_id); + } } $query->addField('c', 'cid'); $query @@ -180,10 +232,9 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment ->addTag('comment_filter') ->addMetaData('base_table', 'comment') ->addMetaData('entity', $entity) - ->addMetaData('field_name', $field_name) - ->limit($comments_per_page); + ->addMetaData('field_name', $field_name); - $count_query = db_select('comment', 'c'); + $count_query = $this->database->select('comment', 'c'); $count_query->addExpression('COUNT(*)'); $count_query ->condition('c.entity_id', $entity->id()) @@ -195,7 +246,7 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment ->addMetaData('entity', $entity) ->addMetaData('field_name', $field_name); - if (!user_access('administer comments')) { + if (!\Drupal::currentUser()->hasPermission('administer comments')) { $query->condition('c.status', CommentInterface::PUBLISHED); $count_query->condition('c.status', CommentInterface::PUBLISHED); } @@ -224,61 +275,16 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment /** * {@inheritdoc} */ - public function loadUsersComments(EntityInterface $account) { - return db_query('SELECT c.cid FROM {comment} c WHERE uid = :uid and c.status = :status', array(':uid' => $account->id(), ':status' => CommentInterface::PUBLISHED))->fetchCol(); - } - - /** - * {@inheritdoc} - */ - public function loadCommentingUsers(EntityInterface $node, $entity_type = 'node') { - return db_query('SELECT DISTINCT c.uid FROM {comment} c WHERE entity_id = :nid AND entity_type=:type', array(':nid' => $node->id(), ':type' => $entity_type))->fetchCol(); - } - - /** - * {@inheritdoc} - */ - public function getHighestCommentCount() { - return db_query('SELECT MAX(comment_count) FROM {comment_entity_statistics}')->fetchField(); + public function getCommentingUserIds(EntityInterface $entity) { + return $this->database->query('SELECT DISTINCT c.uid FROM {comment} c WHERE entity_id = :id AND entity_type=:type', array(':id' => $entity->id(), ':type' => $entity->getEntityTypeId()))->fetchCol(); } /** * {@inheritdoc} */ - public function getCommentDisplayOrdinal($cid, $instance) { - // Count how many comments (c1) are before $cid (c2) in display order. This - // is the 0-based display ordinal. - $query = db_select('comment', 'c1'); - $query->innerJoin('comment', 'c2', 'c2.entity_id = c1.entity_id AND c2.entity_type = c1.entity_type AND c2.field_id = c1.field_id'); - $query->addExpression('COUNT(*)', 'count'); - $query->condition('c2.cid', $cid); - if (!user_access('administer comments')) { - $query->condition('c1.status', CommentInterface::PUBLISHED); - } - - if ($instance->getSetting('default_mode') == COMMENT_MODE_FLAT) { - // For flat comments, cid is used for ordering comments due to - // unpredictable behavior with timestamp, so we make the same assumption - // here. - $query->condition('c1.cid', $cid, '<'); - } - else { - // For threaded comments, the c.thread column is used for ordering. We can - // use the sorting code for comparison, but must remove the trailing - // slash. - // @see CommentRenderController. - $query->where('SUBSTRING(c1.thread, 1, (LENGTH(c1.thread) -1)) < SUBSTRING(c2.thread, 1, (LENGTH(c2.thread) -1))'); - } - - return $query->execute()->fetchField(); - } - - /** - * {@inheritdoc} - */ - public function getThreadedNewCommentPage(EntityInterface $entity, $new_replies, $comments_per_page, $field_name) { + public function getThreadedNewCommentPageNr(EntityInterface $entity, $new_replies, $comments_per_page, $field_name) { // 1. Find all the threads with a new comment. - $unread_threads_query = db_select('comment') + $unread_threads_query = $this->database->select('comment') ->fields('comment', array('thread')) ->condition('entity_id', $entity->id()) ->condition('entity_type', $entity->getEntityTypeId()) @@ -289,7 +295,7 @@ public function getThreadedNewCommentPage(EntityInterface $entity, $new_replies, ->range(0, $new_replies); // 2. Find the first thread. - $first_thread_query = db_select($unread_threads_query, 'thread'); + $first_thread_query = $this->database->select($unread_threads_query, 'thread'); $first_thread_query->addExpression('SUBSTRING(thread, 1, (LENGTH(thread) - 1))', 'torder'); $first_thread = $first_thread_query ->fields('thread', array('thread')) @@ -302,7 +308,7 @@ public function getThreadedNewCommentPage(EntityInterface $entity, $new_replies, $first_thread = substr($first_thread, 0, -1); // Find the number of the first comment of the first unread thread. - $count = db_query('SELECT COUNT(*) FROM {comment} WHERE entity_id = :entity_id + $count = $this->database->query('SELECT COUNT(*) FROM {comment} WHERE entity_id = :entity_id AND entity_type = :entity_type AND field_id = :field_id AND status = :status AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array( @@ -313,53 +319,7 @@ public function getThreadedNewCommentPage(EntityInterface $entity, $new_replies, ':thread' => $first_thread, ))->fetchField(); - return $count / $comments_per_page; - } - - /** - * {@inheritdoc} - */ - public function getLatestNodesWithStats($nodes) { - // @todo This should be actually filtering on the desired language and just - // fall back to the default language. - // @todo Find better way to send this over. Plain DB object is probably not - // the best way to go. - return 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' => $nodes - ), array('target' => 'slave'))->fetchAllKeyed(); - } - - /** - * {@inheridoc} - */ - public function getCommentOverview($header, $status, $limit = 50) { - $query = db_select('comment', 'c') - ->extend('Drupal\Core\Database\Query\PagerSelectExtender') - ->extend('Drupal\Core\Database\Query\TableSortExtender'); - if (\Drupal::moduleHandler()->moduleExists('node')) { - // Special case to ensure node access works. - $query->leftJoin('node_field_data', 'n', "n.nid = c.entity_id AND c.entity_type = 'node'"); - $query->addTag('node_access'); - } - return $query - ->fields('c', array('cid', 'subject', 'name', 'changed', 'entity_id', 'entity_type', 'field_id')) - ->condition('c.status', $status) - ->limit($limit) - ->orderByHeader($header) - ->execute() - ->fetchAllAssoc('cid'); + return floor($count / $comments_per_page); } } diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorageInterface.php b/core/modules/comment/lib/Drupal/comment/CommentStorageInterface.php index 75036a3..f2c0cb5 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorageInterface.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorageInterface.php @@ -16,51 +16,56 @@ interface CommentStorageInterface extends EntityStorageInterface { /** - * Get the maximum encoded thread value for the top level comments. + * Gets the maximum encoded thread value for the top level comments. * - * @param EntityInterface $comment + * @param \Drupal\comment\CommentInterface $comment * A comment entity. * * @return string * The maximum encoded thread value among the top level comments of the * node $comment belongs to. */ - public function getMaxThread(EntityInterface $comment); + public function getMaxThread(CommentInterface $comment); /** - * Get the maximum encoded thread value for the children of this comment. + * Gets the maximum encoded thread value for the children of this comment. * - * @param EntityInterface $comment + * @param \Drupal\comment\CommentInterface $comment * A comment entity. * * @return string * The maximum encoded thread value among all replies of $comment. */ - public function getMaxThreadPerThread(EntityInterface $comment); + public function getMaxThreadPerThread(CommentInterface $comment); /** - * Gets the comment ids of the passed comment entities' children. + * Gets the 0-based display ordinal for a comment (i.e. the number of comments + * which should be displayed before the given comment). * - * @param array $comments - * An array of comment entities keyed by their ids. - * @return array - * The entity ids of the passed comment entities' children as an array. + * @param int $cid + * The comment ID. + * @param int $comment_mode + * Comment mode (COMMENT_MODE_FLAT or COMMENT_MODE_THREADED). + * + * @return int + * The display ordinal for the comment. */ - public function getChildCids(array $comments); + public function getDisplayOrdinal($cid, $comment_mode); /** - * Loads latest comments. + * Gets the comment ids of the passed comment entities' children. * - * @param int $number - * Number of latest comments to load. All comments will be returned if NULL. - * @return array - * Array of most recent comments objects. + * @param \Drupal\comment\CommentInterface[] $comments + * An array of comment entities keyed by their ids. * + * @return array + * Array of entity ids of the passed comment entities' children. */ - public function loadRecent($number = 10); + public function getChildCids(array $comments); /** - * Retrieves comments for a thread. + * Retrieves comments for a thread, sorted in order suitable for display: most + * recent comments first. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity whose comment(s) needs rendering. @@ -69,102 +74,44 @@ public function loadRecent($number = 10); * @param int $mode * The comment display mode; COMMENT_MODE_FLAT or COMMENT_MODE_THREADED. * @param int $comments_per_page - * The amount of comments to display per page. + * (optional) The amount of comments to display per page. + * Defaults to 0, which means show all comments. * @param int $pager_id * (optional) Pager id to use in case of multiple pagers on the one page. - * Defaults to 0. - * - * @return mixed An array of the commment objects. - */ - public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page, $pager_id); - - /** - * Retrieves CIDs of comments, that were created by a user. - * - * @param \Drupal\Core\Entity\EntityInterface $account - * User object. + * Defaults to 0; is only used when $comments_per_page is greater than zero. * * @return array - * Array of user's comment ids. + * Ordered array of comment objects. */ - public function loadUsersComments(EntityInterface $account); + public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0); /** * Retrieves UIDs of users that commented on a given node. * * @param \Drupal\Core\Entity\EntityInterface $node * User object. - * @param string $entity_type - * Entity type to query against. * - * @return array + * @return int[] * Array of user ids. */ - public function loadCommentingUsers(EntityInterface $node, $entity_type = 'node'); + public function getCommentingUserIds(EntityInterface $node); /** - * Retrieves globally highest comment count (across all nodes). + * Gets the page number (location) of the first unread comment, if displaying + * as a threaded list. * - * @return int - * Number of comment on a node with highest comment count. - */ - public function getHighestCommentCount(); - - /** - * Gets the display ordinal for a comment, starting from 0. - * - * Count the number of comments which appear before the comment we want to - * display, taking into account display settings and threading. - * - * @param int $cid - * The comment ID. - * @param array $instance - * Field instance as returned from field_info_instance(). - * - * @return - * The display ordinal for the comment. - */ - public function getCommentDisplayOrdinal($cid, $instance); - - /** - * Get page of first unread comment in threaded list. - * - * @param EntityInterface $node + * @param \Drupal\Core\Entity\EntityInterface $node * Node object. * @param int $new_replies * Number of new replies. * @param int $comments_per_page - * Number of comments per page.. + * Number of comments per page. * @param string $field_name - * The field name on the entity to which comments are attached to. + * The field name on the entity to which comments are attached. * * @return int - * "page=X" if the page number is greater than zero; empty string otherwise. + * The page number (0-based). */ - public function getThreadedNewCommentPage(EntityInterface $node, $new_replies, $comments_per_page, $field_name); + public function getThreadedNewCommentPageNr(EntityInterface $node, $new_replies, $comments_per_page, $field_name); - /** - * Returns nodes along with their comment count, ordered by created date. - * - * @param array $nodes - * Array of node IDs that we limit to. - * @return array - * Array of objects as loaded from DB. - */ - public function getLatestNodesWithStats($nodes); - - /** - * Returns data needed for building comment overview page. - * - * @param array $headers - * Overview table headers. - * @param $status - * Comment status to filter on (approved or unapproved). - * @param int $limit - * Number of items per page (defaults to 50). - * @return array - * An associative array of comments (keyed by cid), or an empty array if - * there is no result set. - */ - public function getCommentOverview($headers, $status, $limit = 50); } diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index 9b0c9ad..809aa5d 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -137,7 +137,9 @@ public function viewElements(FieldItemListInterface $items) { $this->currentUser->hasPermission('administer comments'))) { $mode = $comment_settings['default_mode']; $comments_per_page = $comment_settings['per_page']; - if ($comments = comment_get_thread($entity, $field_name, $mode, $comments_per_page, $this->getSetting('pager_id'))) { + $comments = \Drupal::entityManager()->getStorage('comment') + ->loadThread($entity, $field_name, $mode, $comments_per_page, $this->getSetting('pager_id')); + if ($comments) { comment_prepare_thread($comments); $build = $this->viewBuilder->viewMultiple($comments); $build['pager']['#theme'] = 'pager'; diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Menu/LocalTask/UnapprovedComments.php b/core/modules/comment/lib/Drupal/comment/Plugin/Menu/LocalTask/UnapprovedComments.php index c7a1ff7..6063fa6 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Menu/LocalTask/UnapprovedComments.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Menu/LocalTask/UnapprovedComments.php @@ -7,6 +7,7 @@ namespace Drupal\comment\Plugin\Menu\LocalTask; +use Drupal\comment\CommentInterface; use Drupal\Core\Menu\LocalTaskDefault; /** @@ -18,7 +19,11 @@ class UnapprovedComments extends LocalTaskDefault { * {@inheritdoc} */ public function getTitle() { - return comment_count_unpublished(); + $count = \Drupal::entityQuery('comment') + ->condition('status', CommentInterface::NOT_PUBLISHED) + ->count() + ->execute(); + return t('Unapproved comments (@count)', array('@count' => $count)); } } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php index 139bf73..4c6cdb9 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php @@ -116,16 +116,13 @@ function testCommentLanguage() { $this->drupalPostForm(NULL, $edit, t('Save')); // Check that comment language matches the current content language. - $cid = db_select('comment', 'c') - ->fields('c', array('cid')) - ->condition('entity_id', $node->id()) - ->condition('entity_type', 'node') + $cids = \Drupal::entityQuery('comment') + ->condition('entity_id', (int) $node->id()) ->condition('field_id', 'node__comment') - ->orderBy('cid', 'DESC') + ->sort('cid', 'DESC') ->range(0, 1) - ->execute() - ->fetchField(); - $comment = comment_load($cid); + ->execute(); + $comment = comment_load(reset($cids)); $args = array('%node_language' => $node_langcode, '%comment_language' => $comment->langcode->value, '%langcode' => $langcode); $this->assertEqual($comment->langcode->value, $langcode, format_string('The comment posted with content language %langcode and belonging to the node with language %node_language has language %comment_language', $args)); $this->assertEqual($comment->comment_body->value, $comment_values[$node_langcode][$langcode], 'Comment body correctly stored.'); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php index cf7af82..a5c5048 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php @@ -159,7 +159,7 @@ function setEnvironment(array $info) { $this->comment = $comment; } else { - $cids = db_query("SELECT cid FROM {comment}")->fetchCol(); + $cids = \Drupal::entityQuery('comment')->execute(); entity_delete_multiple('comment', $cids); unset($this->comment); } diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module index 007970b..bb93d27 100644 --- a/core/modules/tracker/tracker.module +++ b/core/modules/tracker/tracker.module @@ -38,6 +38,8 @@ function tracker_help($path, $arg) { * 'tracker.index_nid' is set to ((the last node ID that was indexed) - 1) and * used to select the nodes to be processed. If there are no remaining nodes to * process, 'tracker.index_nid' will be 0. + * This process does not run regularly on live sites, rather it updates tracking + * info once on an existing site just after the tracker module was installed. */ function tracker_cron() { $state = \Drupal::state(); @@ -82,8 +84,8 @@ function tracker_cron() { )) ->execute(); - $node = \Drupal::entityManager()->getStorageController('node')->load($row->nid); - $uids = \Drupal::entityManager()->getStorageController('comment')->loadCommentingUsers($node); + $node = \Drupal::entityManager()->getStorage('node')->load($row->nid); + $uids = \Drupal::entityManager()->getStorage('comment')->getCommentingUserIds($node); // Insert the user-level data for the commenters (except if a commenter // is the node's author). @@ -296,7 +298,7 @@ function _tracker_calculate_changed($nid) { $latest_comment_cid = reset($latest_comment_cid); if ($latest_comment_cid) { - $latest_comment = \Drupal::entityManager()->getStorageController('comment')->load($latest_comment_cid); + $latest_comment = \Drupal::entityManager()->getStorage('comment')->load($latest_comment_cid); if ($latest_comment && $latest_comment->getChangedTime() > $changed) { $changed = $latest_comment->getChangedTime(); } diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc index 6927b9c..85fa119 100644 --- a/core/modules/tracker/tracker.pages.inc +++ b/core/modules/tracker/tracker.pages.inc @@ -45,7 +45,23 @@ function tracker_page($account = NULL) { if (!empty($tracker_data)) { $nids = array_keys($tracker_data); $nodes = node_load_multiple($nids); - $result = \Drupal::entityManager()->getStorageController('comment')->getLatestNodesWithStats(array_keys($nodes)); + // @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' => 'slave'))->fetchAllKeyed(); foreach ($result as $nid => $comment_count) { $nodes[$nid]->last_activity = $tracker_data[$nid]->changed; $nodes[$nid]->comment_count = $comment_count;