diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install
index 64aa6bd..0df2dcc 100644
--- a/core/modules/comment/comment.install
+++ b/core/modules/comment/comment.install
@@ -32,6 +32,32 @@ function comment_install() {
}
/**
+ * Implements hook_modules_installed().
+ */
+function comment_modules_installed($modules) {
+ // Book is being enabled.
+ if (in_array('book', $modules)) {
+ // Disable comments in print view mode.
+ foreach (\Drupal::service('comment.manager')->getFields('node') as $field_name => $detail) {
+ foreach ($detail['bundles'] as $bundle) {
+ $display = entity_get_display('node', $bundle, 'print');
+ $display->removeComponent($field_name)->save();
+ }
+ }
+ }
+ // Comment is being enabled, check if book exists.
+ if (in_array('comment', $modules) && \Drupal::moduleHandler()->moduleExists('book')) {
+ // Disable comments in print view mode.
+ foreach (\Drupal::service('comment.manager')->getFields('node') as $field_name => $detail) {
+ foreach ($detail['bundles'] as $bundle) {
+ $display = entity_get_display('node', $bundle, 'print');
+ $display->removeComponent($field_name)->save();
+ }
+ }
+ }
+}
+
+/**
* Implements hook_schema().
*/
function comment_schema() {
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 4231ee5..c5241a7 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -12,7 +12,6 @@
use Drupal\comment\CommentInterface;
use Drupal\comment\Entity\Comment;
-use Drupal\comment\CommentManagerInterface;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Component\Utility\String;
@@ -217,14 +216,12 @@ function comment_entity_build_defaults_alter(array &$build, EntityInterface $ent
}
/**
- * Implements hook_node_links_alter().
+ * Implements hook_preprocess_hook() for theme_node().
*/
function comment_node_links_alter(array &$node_links, NodeInterface $node, array &$context) {
// Comment links are only added to node entity type for backwards
// compatibility. Should you require comment links for other entity types you
// can do so by implementing a new field formatter.
- // @todo Make this configurable from the formatter see
- // http://drupal.org/node/1901110
$links = \Drupal::service('comment.link_builder')->buildCommentedEntityLinks($node, $context);
$node_links += $links;
@@ -475,17 +472,18 @@ function comment_node_update_index(EntityInterface $node, $langcode) {
$build = array();
if ($index_comments) {
+ $node_base_defs = \Drupal::entityManager()->getFieldStorageDefinitions($node->getEntityTypeId());
foreach (\Drupal::service('comment.manager')->getFields('node') as $field_name => $info) {
// Skip fields that entity does not have.
if (!$node->hasField($field_name)) {
continue;
}
- $field_definition = $node->getFieldDefinition($field_name);
- $mode = $field_definition->getSetting('default_mode');
- $comments_per_page = $field_definition->getSetting('per_page');
if ($node->get($field_name)->status) {
+ $comment_type = CommentType::load($node_base_defs[$field_name]->getSetting('comment_type'));
+ $display_settings = entity_get_display($node->getEntityTypeId(), $node->bundle(), 'default')
+ ->getComponent($field_name);
$comments = \Drupal::entityManager()->getStorage('comment')
- ->loadThread($node, $field_name, $mode, $comments_per_page);
+ ->loadThread($node, $field_name, $comment_type->getThreadingMode(), $display_settings['settings']['per_page']);
if ($comments) {
comment_prepare_thread($comments);
$build[] = \Drupal::entityManager()->getViewBuilder('comment')->viewMultiple($comments);
@@ -833,7 +831,7 @@ function comment_preprocess_field(&$variables) {
$element = $variables['element'];
if ($element['#field_type'] == 'comment') {
// Provide contextual information.
- $variables['comment_display_mode'] = $element[0]['#comment_display_mode'];
+ $variables['comment_threading_mode'] = $element[0]['#comment_threading_mode'];
$variables['comment_type'] = $element[0]['#comment_type'];
// Adjust a comment field's attributes.
diff --git a/core/modules/comment/comment.services.yml b/core/modules/comment/comment.services.yml
index 239cdb2..b67b08f 100644
--- a/core/modules/comment/comment.services.yml
+++ b/core/modules/comment/comment.services.yml
@@ -20,4 +20,4 @@ services:
comment.link_builder:
class: Drupal\comment\CommentLinkBuilder
- arguments: ['@current_user', '@comment.manager', '@module_handler', '@string_translation']
+ arguments: ['@current_user', '@entity.manager', '@comment.manager', '@module_handler', '@string_translation']
diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml
index b5bcd86..36bea18 100644
--- a/core/modules/comment/config/schema/comment.schema.yml
+++ b/core/modules/comment/config/schema/comment.schema.yml
@@ -59,6 +59,9 @@ comment.type.*:
description:
type: text
label: 'Description'
+ threading_mode:
+ type: integer
+ label: 'Threading'
field.comment.storage_settings:
type: sequence
@@ -97,18 +100,9 @@ field.comment.field_settings:
type: mapping
label: 'Comment settings'
mapping:
- default_mode:
- type: integer
- label: 'Threading'
- per_page:
- type: integer
- label: 'Comments per page'
anonymous:
type: integer
label: 'Mode'
- form_location:
- type: boolean
- label: ' Allow comment title'
preview:
type: integer
label: 'Preview comment'
diff --git a/core/modules/comment/js/node-new-comments-link.js b/core/modules/comment/js/node-new-comments-link.js
index e1e10b2..9b72498 100644
--- a/core/modules/comment/js/node-new-comments-link.js
+++ b/core/modules/comment/js/node-new-comments-link.js
@@ -40,9 +40,12 @@
return;
}
+ var perPage = $placeholder.closest('[data-comment-per-page]').attr('data-comment-per-page');
+ var threadingMode = $placeholder.closest('[data-comment-threading-mode]').attr('data-comment-threading-mode');
+
// Perform an AJAX request to retrieve node read timestamps.
Drupal.history.fetchTimestamps(nodeIDs, function () {
- processNodeNewCommentLinks($placeholders);
+ processNodeNewCommentLinks($placeholders, perPage, threadingMode);
});
}
};
@@ -71,7 +74,7 @@
.end().show();
}
- function processNodeNewCommentLinks($placeholders) {
+ function processNodeNewCommentLinks($placeholders, perPage, threadingMode) {
// Figure out which placeholders need the "x new comments" links.
var $placeholdersToUpdate = {};
var fieldName = 'comment';
@@ -121,7 +124,7 @@
$.ajax({
url: Drupal.url('comments/render_new_comments_node_links'),
type: 'POST',
- data: { 'node_ids[]': nodeIDs, 'field_name': fieldName },
+ data: { 'node_ids[]': nodeIDs, 'field_name': fieldName, 'per_page': perPage, 'threading_mode': threadingMode },
dataType: 'json',
success: render
});
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index 84f1dce..c9c0183 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -384,10 +384,13 @@ public function save(array $form, FormStateInterface $form_state) {
else {
drupal_set_message($this->t('Your comment has been posted.'));
}
- $query = array();
// Find the current display page for this comment.
- $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$field_name];
- $page = $this->entityManager->getStorage('comment')->getDisplayOrdinal($comment, $field_definition->getSetting('default_mode'), $field_definition->getSetting('per_page'));
+ $display_settings = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'default')
+ ->getComponent($field_name);
+ $field_definition = $this->entityManager->getFieldStorageDefinitions($entity->getEntityTypeId())[$field_name];
+ $comment_type = $this->entityManager->getStorage('comment_type')->load($field_definition->getSetting('comment_type'));
+ $page = $this->entityManager->getStorage('comment')->getDisplayOrdinal($comment, $comment_type->getThreadingMode(), $display_settings['settings']['per_page']);
+ $query = array();
if ($page > 0) {
$query['page'] = $page;
}
diff --git a/core/modules/comment/src/CommentLinkBuilder.php b/core/modules/comment/src/CommentLinkBuilder.php
index b1864da..a7dc9e8 100644
--- a/core/modules/comment/src/CommentLinkBuilder.php
+++ b/core/modules/comment/src/CommentLinkBuilder.php
@@ -7,8 +7,11 @@
namespace Drupal\comment;
+use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -31,6 +34,13 @@ class CommentLinkBuilder implements CommentLinkBuilderInterface {
protected $currentUser;
/**
+ * Entity manager.
+ *
+ * @var \Drupal\Core\Entity\EntityManagerInterface
+ */
+ protected $entityManager;
+
+ /**
* Comment manager service.
*
* @var \Drupal\comment\CommentManagerInterface
@@ -56,8 +66,9 @@ class CommentLinkBuilder implements CommentLinkBuilderInterface {
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* String translation service.
*/
- public function __construct(AccountInterface $current_user, CommentManagerInterface $comment_manager, ModuleHandlerInterface $module_handler, TranslationInterface $string_translation) {
+ public function __construct(AccountInterface $current_user, EntityManagerInterface $entity_manager, CommentManagerInterface $comment_manager, ModuleHandlerInterface $module_handler, TranslationInterface $string_translation) {
$this->currentUser = $current_user;
+ $this->entityManager = $entity_manager;
$this->commentManager = $comment_manager;
$this->moduleHandler = $module_handler;
$this->stringTranslation = $string_translation;
@@ -83,141 +94,186 @@ public function buildCommentedEntityLinks(ContentEntityInterface $entity, array
if (!$entity->hasField($field_name)) {
continue;
}
- $links = array();
- $commenting_status = $entity->get($field_name)->status;
- if ($commenting_status != CommentItemInterface::HIDDEN) {
- // Entity has commenting status open or closed.
- $field_definition = $entity->getFieldDefinition($field_name);
- if ($view_mode == 'rss') {
- // Add a comments RSS element which is a URL to the comments of this
- // entity.
- $options = array(
+
+ // Get the field formatter, via the entity display.
+ $display = $this->entityManager->getStorage('entity_view_display')
+ ->load($entity->getEntityTypeId() . '.' . $entity->bundle() . '.' . $view_mode);
+ if (!$display) {
+ $display = $this->entityManager->getStorage('entity_view_display')
+ ->load($entity->getEntityTypeId() . '.' . $entity->bundle() . '.default');
+ }
+ if ($display) {
+ $formatter_options = $display->getComponent($field_name);
+ }
+// else {
+// // Even the default display mode does not exist.
+// // @todo: get defaultSettings from CommentedDefaultFormatter?
+// }
+ $items = $entity->get($field_name);
+ if ($items) {
+ $links = $this->buildCommentedEntityFieldLinks($field_name, $items, $formatter_options['settings']);
+ if (!empty($links)) {
+ $entity_links['comment__' . $field_name] = $links;
+ }
+ }
+ }
+ return $entity_links;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildCommentedEntityFieldLinks($field_name, FieldItemListInterface $items, array $display_settings) {
+ $build = array();
+
+ $commenting_status = $items->status;
+ if ($commenting_status == CommentItemInterface::HIDDEN) {
+ return $build;
+ }
+ // Entity has commenting status open or closed.
+
+ $link_style = $display_settings['show_links'];
+ if ($link_style == CommentDefaultFormatter::LINKS_NONE) {
+ return $build;
+ }
+
+ $field_definition = $items->getFieldDefinition()->getFieldStorageDefinition();
+ $comment_type = $this->entityManager->getStorage('comment_type')->load($field_definition->getSetting('comment_type'));
+ $entity = $items->getEntity();
+ if ($link_style == CommentDefaultFormatter::LINKS_RSS) {
+ // Add a comments RSS element which is a URL to the comments of this
+ // entity.
+ $options = array(
+ 'fragment' => 'comments',
+ 'absolute' => TRUE,
+ );
+ $entity->rss_elements[] = array(
+ 'key' => 'comments',
+ 'value' => $entity->url('canonical', $options),
+ );
+ }
+ elseif ($link_style == CommentDefaultFormatter::LINKS_TEASER) {
+ // Teaser style links: display the number of comments that have been posted,
+ // or a link to add new comments if the user has permission, the entity
+ // is open to new comments, and there currently are none.
+ if ($this->currentUser->hasPermission('access comments')) {
+ if ($items->comment_count) {
+ $links['comment-comments'] = array(
+ 'title' => $this->formatPlural($items->comment_count, '1 comment', '@count comments'),
+ 'attributes' => array('title' => $this->t('Jump to the first comment of this posting.')),
'fragment' => 'comments',
- 'absolute' => TRUE,
+ ) + $entity->urlInfo()->toArray();
+ if ($this->moduleHandler->moduleExists('history')) {
+ $links['comment-new-comments'] = array(
+ 'title' => '',
+ 'href' => '',
+ 'attributes' => array(
+ 'class' => 'hidden',
+ 'title' => t('Jump to the first new comment of this posting.'),
+ 'data-history-node-last-comment-timestamp' => $items->last_comment_timestamp,
+ 'data-history-node-field-name' => $field_name,
+ 'data-comment-threading-mode' => $comment_type->getThreadingMode(),
+ 'data-comment-per-page' => $display_settings['per_page'],
+ ),
+ );
+ }
+ }
+ }
+ // Provide a link to new comment form.
+ if ($commenting_status == CommentItemInterface::OPEN) {
+ $comment_form_location = $display_settings['form_location'];
+ if ($this->currentUser->hasPermission('post comments')) {
+ $links['comment-add'] = array(
+ 'title' => t('Add new comment'),
+ 'language' => $entity->language(),
+ 'attributes' => array('title' => t('Add a new comment to this page.')),
+ 'fragment' => 'comment-form',
);
- $entity->rss_elements[] = array(
- 'key' => 'comments',
- 'value' => $entity->url('canonical', $options),
+ if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
+ $links['comment-add']['route_name'] = 'comment.reply';
+ $links['comment-add']['route_parameters'] = array(
+ 'entity_type' => $entity->getEntityTypeId(),
+ 'entity_id' => $entity->id(),
+ 'field_name' => $field_name,
+ );
+ }
+ else {
+ $links['comment-add'] += $entity->urlInfo()->toArray();
+ }
+ }
+ elseif ($this->currentUser->isAnonymous()) {
+ $links['comment-forbidden'] = array(
+ 'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
+ 'html' => TRUE,
);
}
- elseif ($view_mode == 'teaser') {
- // Teaser view: display the number of comments that have been posted,
- // or a link to add new comments if the user has permission, the
- // entity is open to new comments, and there currently are none.
- if ($this->currentUser->hasPermission('access comments')) {
- if (!empty($entity->get($field_name)->comment_count)) {
- $links['comment-comments'] = array(
- 'title' => $this->formatPlural($entity->get($field_name)->comment_count, '1 comment', '@count comments'),
- 'attributes' => array('title' => $this->t('Jump to the first comment of this posting.')),
- 'fragment' => 'comments',
- ) + $entity->urlInfo()->toArray();
- if ($this->moduleHandler->moduleExists('history')) {
- $links['comment-new-comments'] = array(
- 'title' => '',
- 'href' => '',
- 'attributes' => array(
- 'class' => 'hidden',
- 'title' => $this->t('Jump to the first new comment of this posting.'),
- 'data-history-node-last-comment-timestamp' => $entity->get($field_name)->last_comment_timestamp,
- 'data-history-node-field-name' => $field_name,
- ),
- );
- }
- }
- }
- // Provide a link to new comment form.
- if ($commenting_status == CommentItemInterface::OPEN) {
- $comment_form_location = $field_definition->getSetting('form_location');
- if ($this->currentUser->hasPermission('post comments')) {
- $links['comment-add'] = array(
- 'title' => $this->t('Add new comment'),
- 'language' => $entity->language(),
- 'attributes' => array('title' => $this->t('Add a new comment to this page.')),
- 'fragment' => 'comment-form',
+ }
+ }
+ else {
+ // Default links: add a "post comment" link if the user is allowed to
+ // post comments and if this node is allowing new comments.
+ if ($commenting_status == CommentItemInterface::OPEN) {
+ $comment_form_location = $display_settings['form_location'];
+ if ($this->currentUser->hasPermission('post comments')) {
+ // Show the "post comment" link if the form is on another page, or
+ // if there are existing comments that the link will skip past.
+ if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || ($items->comment_count && $this->currentUser->hasPermission('access comments'))) {
+ $links['comment-add'] = array(
+ 'title' => t('Add new comment'),
+ 'attributes' => array('title' => t('Share your thoughts and opinions related to this posting.')),
+ 'fragment' => 'comment-form',
+ );
+ if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
+ $links['comment-add']['route_name'] = 'comment.reply';
+ $links['comment-add']['route_parameters'] = array(
+ 'entity_type' => $entity->getEntityTypeId(),
+ 'entity_id' => $entity->id(),
+ 'field_name' => $field_name,
);
- if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
- $links['comment-add']['route_name'] = 'comment.reply';
- $links['comment-add']['route_parameters'] = array(
- 'entity_type' => $entity->getEntityTypeId(),
- 'entity' => $entity->id(),
- 'field_name' => $field_name,
- );
- }
- else {
- $links['comment-add'] += $entity->urlInfo()->toArray();
- }
}
- elseif ($this->currentUser->isAnonymous()) {
- $links['comment-forbidden'] = array(
- 'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
- 'html' => TRUE,
- );
+ else {
+ $links['comment-add'] += $entity->urlInfo()->toArray();
}
}
}
- else {
- // Entity in other view modes: add a "post comment" link if the user
- // is allowed to post comments and if this entity is allowing new
- // comments.
- if ($commenting_status == CommentItemInterface::OPEN) {
- $comment_form_location = $field_definition->getSetting('form_location');
- if ($this->currentUser->hasPermission('post comments')) {
- // Show the "post comment" link if the form is on another page, or
- // if there are existing comments that the link will skip past.
- if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || (!empty($entity->get($field_name)->comment_count) && $this->currentUser->hasPermission('access comments'))) {
- $links['comment-add'] = array(
- 'title' => $this->t('Add new comment'),
- 'attributes' => array('title' => $this->t('Share your thoughts and opinions related to this posting.')),
- 'fragment' => 'comment-form',
- );
- if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
- $links['comment-add']['route_name'] = 'comment.reply';
- $links['comment-add']['route_parameters'] = array(
- 'entity_type' => $entity->getEntityTypeId(),
- 'entity' => $entity->id(),
- 'field_name' => $field_name,
- );
- }
- else {
- $links['comment-add'] += $entity->urlInfo()->toArray();
- }
- }
- }
- elseif ($this->currentUser->isAnonymous()) {
- $links['comment-forbidden'] = array(
- 'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
- 'html' => TRUE,
- );
- }
- }
+ elseif ($this->currentUser->isAnonymous()) {
+ $links['comment-forbidden'] = array(
+ 'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
+ 'html' => TRUE,
+ );
}
}
+ }
- if (!empty($links)) {
- $entity_links['comment__' . $field_name] = array(
- '#theme' => 'links__entity__comment__' . $field_name,
- '#links' => $links,
- '#attributes' => array('class' => array('links', 'inline')),
- );
- if ($view_mode == 'teaser' && $this->moduleHandler->moduleExists('history') && $this->currentUser->isAuthenticated()) {
- $entity_links['comment__' . $field_name]['#attached']['library'][] = 'comment/drupal.node-new-comments-link';
+ if (!empty($links)) {
+ $build = array(
+ '#theme' => 'links__entity__comment__' . $field_name,
+ '#links' => $links,
+ '#attributes' => array('class' => array('links', 'inline')),
+ );
+ if ($link_style == CommentDefaultFormatter::LINKS_TEASER && $this->moduleHandler->moduleExists('history') && $this->currentUser->isAuthenticated()
+ // @todo revisit this condition when history.module is generalized;
+ // see https://www.drupal.org/node/2081585.
+ && $entity->getEntityTypeId() == 'node') {
+ $build['#attached']['library'][] = 'comment/drupal.node-new-comments-link';
- // Embed the metadata for the "X new comments" link (if any) on this
- // entity.
- $entity_links['comment__' . $field_name]['#post_render_cache']['history_attach_timestamp'] = array(
- array('node_id' => $entity->id()),
- );
- $entity_links['comment__' . $field_name]['#post_render_cache']['Drupal\comment\CommentViewBuilder::attachNewCommentsLinkMetadata'] = array(
- array(
- 'entity_type' => $entity->getEntityTypeId(),
- 'entity_id' => $entity->id(),
- 'field_name' => $field_name,
- ),
- );
- }
+ // Embed the metadata for the "X new comments" link (if any) on this
+ // node.
+ $build['#post_render_cache']['history_attach_timestamp'] = array(
+ array($entity->getEntityTypeId() . '_id' => $entity->id()),
+ );
+ $build['#post_render_cache']['Drupal\comment\CommentViewBuilder::attachNewCommentsLinkMetadata'] = array(
+ array(
+ 'entity_type' => $entity->getEntityTypeId(),
+ 'entity_id' => $entity->id(),
+ 'field_name' => $field_name,
+ 'threading_mode' => $comment_type->getThreadingMode(),
+ 'per_page' => $display_settings['per_page'],
+ ),
+ );
}
}
- return $entity_links;
+ return $build;
}
}
diff --git a/core/modules/comment/src/CommentLinkBuilderInterface.php b/core/modules/comment/src/CommentLinkBuilderInterface.php
index 995efcf..97f3193 100644
--- a/core/modules/comment/src/CommentLinkBuilderInterface.php
+++ b/core/modules/comment/src/CommentLinkBuilderInterface.php
@@ -8,6 +8,7 @@
namespace Drupal\comment;
use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Field\FieldItemListInterface;
/**
* Defines an interface for building comment links on a commented entity.
@@ -25,8 +26,24 @@
* Array of context passed from the entity view builder.
*
* @return array
- * Array of entity links.
+ * Array of entity links (separately grouped per comment field).
*/
public function buildCommentedEntityLinks(ContentEntityInterface $entity, array &$context);
+ /**
+ * Builds links for one comment field on an entity.
+ *
+ * @param string $field_name
+ * Machine name of the comment field
+ * @param FieldItemListInterface $items
+ * Value of the comment field
+ * @param array $display_settings
+ * The formatter settings for the comment field in the desired view mode.
+ * (That is: the 'settings' sub-array of the field's display options.)
+ *
+ * @return array
+ * A render array of entity links for one field.
+ */
+ public function buildCommentedEntityFieldLinks($field_name, FieldItemListInterface $items, array $display_settings);
+
}
diff --git a/core/modules/comment/src/CommentManager.php b/core/modules/comment/src/CommentManager.php
index f331f13..d1db72b 100644
--- a/core/modules/comment/src/CommentManager.php
+++ b/core/modules/comment/src/CommentManager.php
@@ -7,6 +7,7 @@
namespace Drupal\comment;
+use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
@@ -130,6 +131,8 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment',
'%entity_type' => $entity_type,
)));
}
+ $comment_type->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
+ $comment_type->save();
}
else {
// Silently create the comment-type for the calling code.
@@ -138,6 +141,7 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment',
'label' => Unicode::ucfirst($comment_type_id),
'target_entity_type_id' => $entity_type,
'description' => 'Default comment field',
+ 'threading_mode' => CommentTypeInterface::THREADING_MODE_THREADED,
))->save();
}
// Make sure the field doesn't already exist.
@@ -198,6 +202,11 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment',
'label' => 'above',
'type' => 'comment_default',
'weight' => 20,
+ 'settings' => array(
+ 'per_page' => 50,
+ 'form_location' => CommentItemInterface::FORM_BELOW,
+ 'show_links' => CommentDefaultFormatter::LINKS_PAGE,
+ )
))
->save();
// The comment field should be hidden in all other view displays.
diff --git a/core/modules/comment/src/CommentManagerInterface.php b/core/modules/comment/src/CommentManagerInterface.php
index 0f00351..8e9f782 100644
--- a/core/modules/comment/src/CommentManagerInterface.php
+++ b/core/modules/comment/src/CommentManagerInterface.php
@@ -17,16 +17,6 @@
interface CommentManagerInterface {
/**
- * Comments are displayed in a flat list - expanded.
- */
- const COMMENT_MODE_FLAT = 0;
-
- /**
- * Comments are displayed as a threaded list - expanded.
- */
- const COMMENT_MODE_THREADED = 1;
-
- /**
* Utility function to return an array of comment fields.
*
* @param string $entity_type_id
diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php
index 28422e2..d33065c 100644
--- a/core/modules/comment/src/CommentStorage.php
+++ b/core/modules/comment/src/CommentStorage.php
@@ -107,7 +107,7 @@ public function getDisplayOrdinal(CommentInterface $comment, $comment_mode, $div
$query->condition('c1.status', CommentInterface::PUBLISHED);
}
- if ($comment_mode == CommentManagerInterface::COMMENT_MODE_FLAT) {
+ if ($comment_mode == CommentTypeInterface::THREADING_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.
@@ -131,15 +131,13 @@ public function getDisplayOrdinal(CommentInterface $comment, $comment_mode, $div
/**
* {@inheritdoc}
*/
- public function getNewCommentPageNumber($total_comments, $new_comments, ContentEntityInterface $entity, $field_name = 'comment') {
- $field = $entity->getFieldDefinition($field_name);
- $comments_per_page = $field->getSetting('per_page');
+ public function getNewCommentPageNumber($total_comments, $new_comments, ContentEntityInterface $entity, $mode = CommentTypeInterface::THREADING_MODE_THREADED, $comments_per_page = 50, $field_name = 'comment') {
if ($total_comments <= $comments_per_page) {
// Only one page of comments.
$count = 0;
}
- elseif ($field->getSetting('default_mode') == CommentManagerInterface::COMMENT_MODE_FLAT) {
+ elseif ($mode == CommentTypeInterface::THREADING_MODE_FLAT) {
// Flat comments.
$count = $total_comments - $new_comments;
}
@@ -296,7 +294,7 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment
$query->condition('c.status', CommentInterface::PUBLISHED);
$count_query->condition('c.status', CommentInterface::PUBLISHED);
}
- if ($mode == CommentManagerInterface::COMMENT_MODE_FLAT) {
+ if ($mode == CommentTypeInterface::THREADING_MODE_FLAT) {
$query->orderBy('c.cid', 'ASC');
}
else {
diff --git a/core/modules/comment/src/CommentStorageInterface.php b/core/modules/comment/src/CommentStorageInterface.php
index d3f15a9..6d52d1d 100644
--- a/core/modules/comment/src/CommentStorageInterface.php
+++ b/core/modules/comment/src/CommentStorageInterface.php
@@ -48,13 +48,18 @@ public function getMaxThreadPerThread(CommentInterface $comment);
* The number of new comments that the entity has.
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity to which the comments belong.
+ * @param int $mode
+ * (optional) The threading mode: CommentTypeInterface::THREADING_MODE_FLAT
+ * or CommentTypeInterface::THREADING_MODE_THREADED (the default).
+ * @param int $comments_per_page
+ * (optional) The amount of comments to display per page. Defaults to 50.
* @param string $field_name
* The field name on the entity to which comments are attached.
*
* @return array|null
* The page number where first new comment appears. (First page returns 0.)
*/
- public function getNewCommentPageNumber($total_comments, $new_comments, ContentEntityInterface $entity, $field_name = 'comment');
+ public function getNewCommentPageNumber($total_comments, $new_comments, ContentEntityInterface $entity, $mode = CommentTypeInterface::THREADING_MODE_THREADED, $comments_per_page = 50, $field_name = 'comment');
/**
* Gets the display ordinal or page number for a comment.
@@ -62,8 +67,8 @@ public function getNewCommentPageNumber($total_comments, $new_comments, ContentE
* @param \Drupal\comment\CommentInterface $comment
* The comment to use as a reference point.
* @param int $comment_mode
- * The comment display mode: CommentManagerInterface::COMMENT_MODE_FLAT or
- * CommentManagerInterface::COMMENT_MODE_THREADED.
+ * The threading mode: CommentTypeInterface::THREADING_MODE_FLAT or
+ * CommentTypeInterface::THREADING_MODE_THREADED.
* @param int $divisor
* Defaults to 1, which returns the display ordinal for a comment. If the
* number of comments per page is provided, the returned value will be the
@@ -93,8 +98,8 @@ public function getChildCids(array $comments);
* @param string $field_name
* The field_name whose comment(s) needs rendering.
* @param int $mode
- * The comment display mode: CommentManagerInterface::COMMENT_MODE_FLAT or
- * CommentManagerInterface::COMMENT_MODE_THREADED.
+ * The threading mode: CommentTypeInterface::THREADING_MODE_FLAT or
+ * CommentTypeInterface::THREADING_MODE_THREADED.
* @param int $comments_per_page
* (optional) The amount of comments to display per page.
* Defaults to 0, which means show all comments.
diff --git a/core/modules/comment/src/CommentTypeForm.php b/core/modules/comment/src/CommentTypeForm.php
index 8e73652..b06b888 100644
--- a/core/modules/comment/src/CommentTypeForm.php
+++ b/core/modules/comment/src/CommentTypeForm.php
@@ -63,6 +63,7 @@ public function __construct(EntityManagerInterface $entity_manager, LoggerInterf
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
+ /** @var $comment_type CommentTypeInterface */
$comment_type = $this->entity;
$form['label'] = array(
@@ -114,6 +115,13 @@ public function form(array $form, FormStateInterface $form_state) {
);
}
+ $form['threading_mode'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Threading'),
+ '#default_value' => $comment_type->getThreadingMode(),
+ '#description' => t('Show comment replies in a threaded list.'),
+ );
+
if ($this->moduleHandler->moduleExists('content_translation')) {
$form['language'] = array(
'#type' => 'details',
diff --git a/core/modules/comment/src/CommentTypeInterface.php b/core/modules/comment/src/CommentTypeInterface.php
index 2ccc0c1..b7015a7 100644
--- a/core/modules/comment/src/CommentTypeInterface.php
+++ b/core/modules/comment/src/CommentTypeInterface.php
@@ -15,6 +15,16 @@
interface CommentTypeInterface extends ConfigEntityInterface {
/**
+ * Comments are displayed as a flat list.
+ */
+ const THREADING_MODE_FLAT = 0;
+
+ /**
+ * Comments are displayed as a threaded list.
+ */
+ const THREADING_MODE_THREADED = 1;
+
+ /**
* Returns the comment type description.
*
* @return string
@@ -40,4 +50,23 @@ public function setDescription($description);
*/
public function getTargetEntityTypeId();
+ /**
+ * Gets the threading mode for this comment type.
+ *
+ * @return int
+ * The comment threading mode (CommentTypeInterface::THREADING_MODE_FLAT or
+ * CommentTypeInterface::THREADING_MODE_THREADED)
+ */
+ public function getThreadingMode();
+
+ /**
+ * Sets the threading mode for this comment type.
+ *
+ * @param int $mode
+ * The threading mode.
+ *
+ * @return $this
+ */
+ public function setThreadingMode($mode);
+
}
diff --git a/core/modules/comment/src/CommentViewBuilder.php b/core/modules/comment/src/CommentViewBuilder.php
index 524349d..9e07531 100644
--- a/core/modules/comment/src/CommentViewBuilder.php
+++ b/core/modules/comment/src/CommentViewBuilder.php
@@ -15,7 +15,6 @@
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityViewBuilder;
-use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Language\LanguageManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -73,9 +72,13 @@ public function __construct(EntityTypeInterface $entity_type, EntityManagerInter
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
$build = parent::getBuildDefaults($entity, $view_mode, $langcode);
+ // Threading mode setting is stored in comment_type config; the name of the
+ // specific comment type is stored in our field definition.
+ $field_definition = $this->entityManager->getFieldStorageDefinitions($entity->getCommentedEntity()->getEntityTypeId())[$entity->getFieldName()];
+ $comment_type = $this->entityManager->getStorage('comment_type')->load($field_definition->getSetting('comment_type'));
// If threading is enabled, don't render cache individual comments, but do
// keep the cache tags, so they can bubble up.
- if ($entity->getCommentedEntity()->getFieldDefinition($entity->getFieldName())->getSetting('default_mode') === CommentManagerInterface::COMMENT_MODE_THREADED) {
+ if ($comment_type->getThreadingMode() === CommentTypeInterface::THREADING_MODE_THREADED) {
$cache_tags = $build['#cache']['tags'];
$build['#cache'] = [];
$build['#cache']['tags'] = $cache_tags;
@@ -305,9 +308,10 @@ protected function alterBuild(array &$build, EntityInterface $comment, EntityVie
if (empty($comment->in_preview)) {
$prefix = '';
$commented_entity = $comment->getCommentedEntity();
- $field_definition = $this->entityManager->getFieldDefinitions($commented_entity->getEntityTypeId(), $commented_entity->bundle())[$comment->getFieldName()];
+ $field_definition = $this->entityManager->getFieldStorageDefinitions($commented_entity->getEntityTypeId())[$comment->getFieldName()];
+ $comment_type = $this->entityManager->getStorage('comment_type')->load($field_definition->getSetting('comment_type'));
$is_threaded = isset($comment->divs)
- && $field_definition->getSetting('default_mode') == CommentManagerInterface::COMMENT_MODE_THREADED;
+ && $comment_type->getThreadingMode() == CommentTypeInterface::THREADING_MODE_THREADED;
// Add indentation div or close open divs as needed.
if ($is_threaded) {
@@ -356,7 +360,7 @@ public static function attachNewCommentsLinkMetadata(array $element, array $cont
$field_name = $context['field_name'];
$page_number = \Drupal::entityManager()
->getStorage('comment')
- ->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new, $entity);
+ ->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new, $entity, $context['threading_mode'], $context['per_page']);
$query = $page_number ? array('page' => $page_number) : NULL;
// Attach metadata.
diff --git a/core/modules/comment/src/Controller/CommentController.php b/core/modules/comment/src/Controller/CommentController.php
index af415d0..d2e0023 100644
--- a/core/modules/comment/src/Controller/CommentController.php
+++ b/core/modules/comment/src/Controller/CommentController.php
@@ -9,9 +9,11 @@
use Drupal\comment\CommentInterface;
use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityInterface;
+use Drupal\node\Entity\Node;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -111,10 +113,12 @@ public function commentPermalink(Request $request, CommentInterface $comment) {
if (!$entity->access('view')) {
throw new AccessDeniedHttpException();
}
- $field_definition = $this->entityManager()->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()];
-
+ $field_definition = $this->entityManager()->getFieldStorageDefinitions($entity->getEntityTypeId())[$comment->getFieldName()];
+ $comment_type = $this->entityManager()->getStorage('comment_type')->load($field_definition->getSetting('comment_type'));
+ $display_settings = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'default')
+ ->getComponent($comment->getFieldName());
// Find the current display page for this comment.
- $page = $this->entityManager()->getStorage('comment')->getDisplayOrdinal($comment, $field_definition->getSetting('default_mode'), $field_definition->getSetting('per_page'));
+ $page = $this->entityManager()->getStorage('comment')->getDisplayOrdinal($comment, $comment_type->getThreadingMode(), $display_settings['settings']['per_page']);
// @todo: Cleaner sub request handling.
$redirect_request = Request::create($entity->getSystemPath(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all());
$redirect_request->query->set('page', $page);
@@ -277,18 +281,20 @@ public function renderNewCommentsNodeLinks(Request $request) {
$nids = $request->request->get('node_ids');
$field_name = $request->request->get('field_name');
- if (!isset($nids)) {
+ $per_page = $request->request->get('per_page');
+ $threading_mode = $request->request->get('threading_mode');
+ if (!isset($nids) || !in_array($threading_mode, array(CommentTypeInterface::THREADING_MODE_THREADED, CommentTypeInterface::THREADING_MODE_FLAT))) {
throw new NotFoundHttpException();
}
// Only handle up to 100 nodes.
$nids = array_slice($nids, 0, 100);
$links = array();
- foreach ($nids as $nid) {
- $node = node_load($nid);
+ $nodes = Node::loadMultiple($nids);
+ foreach ($nodes as $nid => $node) {
$new = $this->commentManager->getCountNewComments($node);
$page_number = $this->entityManager()->getStorage('comment')
- ->getNewCommentPageNumber($node->{$field_name}->comment_count, $new, $node);
+ ->getNewCommentPageNumber($node->{$field_name}->comment_count, $new, $node, $threading_mode, $per_page);
$query = $page_number ? array('page' => $page_number) : NULL;
$links[$nid] = array(
'new_comment_count' => (int) $new,
diff --git a/core/modules/comment/src/Entity/CommentType.php b/core/modules/comment/src/Entity/CommentType.php
index 3a1b3a8..d32ed36 100644
--- a/core/modules/comment/src/Entity/CommentType.php
+++ b/core/modules/comment/src/Entity/CommentType.php
@@ -71,6 +71,13 @@ class CommentType extends ConfigEntityBundleBase implements CommentTypeInterface
protected $target_entity_type_id;
/**
+ * The comment threading mode (flat or threaded).
+ *
+ * @var int
+ */
+ protected $threading_mode;
+
+ /**
* {@inheritdoc}
*/
public function getDescription() {
@@ -95,6 +102,22 @@ public function getTargetEntityTypeId() {
/**
* {@inheritdoc}
*/
+ public function getThreadingMode() {
+ return isset($this->threading_mode) ? $this->threading_mode :
+ CommentTypeInterface::THREADING_MODE_THREADED;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setThreadingMode($mode) {
+ $this->threading_mode = $mode;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
if (!$update && !$this->isSyncing()) {
diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
index aa41d12..10539b9 100644
--- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
+++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
@@ -7,17 +7,20 @@
namespace Drupal\comment\Plugin\Field\FieldFormatter;
+use Drupal\comment\CommentLinkBuilderInterface;
use Drupal\comment\CommentManagerInterface;
use Drupal\comment\CommentStorageInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityViewBuilderInterface;
use Drupal\Core\Entity\EntityFormBuilderInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldItemListInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -38,11 +41,34 @@
class CommentDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
/**
+ * Display no links.
+ */
+ const LINKS_NONE = 0;
+
+ /**
+ * Display default 'add new comment' and 'x comments' links seen on page view.
+ */
+ const LINKS_PAGE = 1;
+
+ /**
+ * Display RSS style links.
+ */
+ const LINKS_RSS = 2;
+
+ /**
+ * Display teaser style links.
+ */
+ const LINKS_TEASER = 3;
+
+ /**
* {@inheritdoc}
*/
public static function defaultSettings() {
return array(
'pager_id' => 0,
+ 'show_links' => static::LINKS_NONE,
+ 'per_page' => 50,
+ 'form_location' => CommentItemInterface::FORM_BELOW,
) + parent::defaultSettings();
}
@@ -61,6 +87,13 @@ public static function defaultSettings() {
protected $currentUser;
/**
+ * The entity manager.
+ *
+ * @var \Drupal\Core\Entity\EntityManagerInterface
+ */
+ protected $entityManager;
+
+ /**
* The comment render controller.
*
* @var \Drupal\Core\Entity\EntityViewBuilderInterface
@@ -75,6 +108,27 @@ public static function defaultSettings() {
protected $entityFormBuilder;
/**
+ * The module handler service.
+ *
+ * @var \Drupal\Core\Extension\ModuleHandlerInterface
+ */
+ protected $moduleHandler;
+
+ /**
+ * The comment manager service.
+ *
+ * @var \Drupal\comment\CommentManagerInterface
+ */
+ protected $commentManager;
+
+ /**
+ * The link builder service.
+ *
+ * @var \Drupal\comment\CommentLinkBuilderInterface
+ */
+ protected $commentLinkBuilder;
+
+ /**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
@@ -89,7 +143,11 @@ public static function create(ContainerInterface $container, array $configuratio
$container->get('current_user'),
$container->get('entity.manager')->getStorage('comment'),
$container->get('entity.manager')->getViewBuilder('comment'),
- $container->get('entity.form_builder')
+ $container->get('entity.form_builder'),
+ $container->get('module_handler'),
+ $container->get('comment.manager'),
+ $container->get('comment.link_builder'),
+ $container->get('entity.manager')
);
}
@@ -118,13 +176,25 @@ public static function create(ContainerInterface $container, array $configuratio
* The comment view builder.
* @param \Drupal\Core\Entity\EntityFormBuilderInterface $entity_form_builder
* The entity form builder.
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+ * The module handler service.
+ * @param \Drupal\comment\CommentManagerInterface $comment_manager
+ * The comment manager service.
+ * @param \Drupal\comment\CommentLinkBuilderInterface $comment_link_builder
+ * The link builder service.
+ * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+ * The entity manager.
*/
- public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, CommentStorageInterface $comment_storage, EntityViewBuilderInterface $comment_view_builder, EntityFormBuilderInterface $entity_form_builder) {
+ public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, CommentStorageInterface $comment_storage, EntityViewBuilderInterface $comment_view_builder, EntityFormBuilderInterface $entity_form_builder, ModuleHandlerInterface $module_handler, CommentManagerInterface $comment_manager, CommentLinkBuilderInterface $comment_link_builder, EntityManagerInterface $entity_manager) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
+ $this->entityManager = $entity_manager;
$this->viewBuilder = $comment_view_builder;
$this->storage = $comment_storage;
$this->currentUser = $current_user;
$this->entityFormBuilder = $entity_form_builder;
+ $this->moduleHandler = $module_handler;
+ $this->commentManager = $comment_manager;
+ $this->commentLinkBuilder = $comment_link_builder;
}
/**
@@ -144,7 +214,8 @@ public function viewElements(FieldItemListInterface $items) {
// comment_node_update_index() instead of by this formatter, so don't
// return anything if the view mode is search_index or search_result.
!in_array($this->viewMode, array('search_result', 'search_index'))) {
- $comment_settings = $this->getFieldSettings();
+
+ $comment_type = $this->entityManager->getStorage('comment_type')->load($this->getFieldSetting('comment_type'));
// Only attempt to render comments if the entity has visible comments.
// Unpublished comments are not included in
@@ -152,9 +223,7 @@ public function viewElements(FieldItemListInterface $items) {
// should display if the user is an administrator.
if ((($entity->get($field_name)->comment_count && $this->currentUser->hasPermission('access comments')) ||
$this->currentUser->hasPermission('administer comments'))) {
- $mode = $comment_settings['default_mode'];
- $comments_per_page = $comment_settings['per_page'];
- $comments = $this->storage->loadThread($entity, $field_name, $mode, $comments_per_page, $this->getSetting('pager_id'));
+ $comments = $this->storage->loadThread($entity, $field_name, $comment_type->getThreadingMode(), $this->getSetting('per_page'), $this->getSetting('pager_id'));
if ($comments) {
comment_prepare_thread($comments);
$build = $this->viewBuilder->viewMultiple($comments);
@@ -168,7 +237,7 @@ public function viewElements(FieldItemListInterface $items) {
// Append comment form if the comments are open and the form is set to
// display below the entity. Do not show the form for the print view mode.
- if ($status == CommentItemInterface::OPEN && $comment_settings['form_location'] == CommentItemInterface::FORM_BELOW && $this->viewMode != 'print') {
+ if ($status == CommentItemInterface::OPEN && $this->getSetting('form_location') == CommentItemInterface::FORM_BELOW && $this->viewMode != 'print') {
// Only show the add comment form if the user has permission.
if ($this->currentUser->hasPermission('post comments')) {
// All users in the "anonymous" role can use the same form: it is fine
@@ -205,11 +274,16 @@ public function viewElements(FieldItemListInterface $items) {
}
}
+ $links = $this->commentLinkBuilder->buildCommentedEntityFieldLinks($field_name, $items, $this->getSettings());
+ if ($links) {
+ $links = array('comment__' . $field_name => $links);
+ }
$elements[] = $output + array(
'#comment_type' => $this->getFieldSetting('comment_type'),
- '#comment_display_mode' => $this->getFieldSetting('default_mode'),
+ '#comment_threading_mode' => $comment_type->getThreadingMode(),
'comments' => array(),
'comment_form' => array(),
+ 'links' => $links,
);
}
@@ -221,6 +295,32 @@ public function viewElements(FieldItemListInterface $items) {
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element = array();
+ $element['show_links'] = array(
+ '#type' => 'select',
+ '#title' => t('Show links'),
+ '#default_value' => $this->getSetting('show_links'),
+ '#description' => t('Show comment links.'),
+ '#options' => array(
+ static::LINKS_NONE => $this->t('None'),
+ static::LINKS_PAGE => $this->t('Default links'),
+ static::LINKS_RSS => $this->t('RSS links'),
+ static::LINKS_TEASER => $this->t('Teaser links'),
+ ),
+ );
+ $element['per_page'] = array(
+ '#type' => 'number',
+ '#title' => t('Comments per page'),
+ '#default_value' => $this->getSetting('per_page'),
+ '#required' => TRUE,
+ '#min' => 10,
+ '#max' => 1000,
+ '#step' => 10,
+ );
+ $element['form_location'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Show reply form on the same page as comments'),
+ '#default_value' => $this->getSetting('form_location'),
+ );
$element['pager_id'] = array(
'#type' => 'select',
'#title' => $this->t('Pager ID'),
@@ -235,13 +335,24 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function settingsSummary() {
- // Only show a summary if we're using a non-standard pager id.
+ $links_map = array(
+ static::LINKS_NONE => $this->t('without links'),
+ static::LINKS_RSS => $this->t('RSS style links'),
+ static::LINKS_PAGE => $this->t('with full-page style links'),
+ static::LINKS_TEASER => $this->t('with teaser style links'),
+ );
+ $variables = array(
+ '@id' => $this->getSetting('pager_id'),
+ '@form' => $this->getSetting('form_location') ? $this->t('inline form') : $this->t('form on separate page'),
+ '@per_page' => $this->getSetting('per_page'),
+ '@links' => $links_map[$this->getSetting('show_links')],
+ );
if ($this->getSetting('pager_id')) {
- return array($this->t('Pager ID: @id', array(
- '@id' => $this->getSetting('pager_id'),
- )));
+ // Only include pager details in summary if we're using a non-standard
+ // pager id.
+ return array($this->t('Showing @per_page comments with @form, using pager ID @id and @links', $variables));
}
- return array();
+ return array($this->t('Showing @per_page comments with @form and @links', $variables));
}
}
diff --git a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
index 0aa290f..46ed8d9 100644
--- a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
+++ b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
@@ -42,9 +42,6 @@ public static function defaultStorageSettings() {
*/
public static function defaultFieldSettings() {
return array(
- 'default_mode' => CommentManagerInterface::COMMENT_MODE_THREADED,
- 'per_page' => 50,
- 'form_location' => CommentItemInterface::FORM_BELOW,
'anonymous' => COMMENT_ANONYMOUS_MAYNOT_CONTACT,
'preview' => DRUPAL_OPTIONAL,
) + parent::defaultFieldSettings();
@@ -114,21 +111,6 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
'library' => array('comment/drupal.comment'),
),
);
- $element['comment']['default_mode'] = array(
- '#type' => 'checkbox',
- '#title' => t('Threading'),
- '#default_value' => $settings['default_mode'],
- '#description' => t('Show comment replies in a threaded list.'),
- );
- $element['comment']['per_page'] = array(
- '#type' => 'number',
- '#title' => t('Comments per page'),
- '#default_value' => $settings['per_page'],
- '#required' => TRUE,
- '#min' => 10,
- '#max' => 1000,
- '#step' => 10,
- );
$element['comment']['anonymous'] = array(
'#type' => 'select',
'#title' => t('Anonymous commenting'),
@@ -140,11 +122,6 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
),
'#access' => $anonymous_user->hasPermission('post comments'),
);
- $element['comment']['form_location'] = array(
- '#type' => 'checkbox',
- '#title' => t('Show reply form on the same page as comments'),
- '#default_value' => $settings['form_location'],
- );
$element['comment']['preview'] = array(
'#type' => 'radios',
'#title' => t('Preview comment'),
diff --git a/core/modules/comment/src/Plugin/views/field/NodeNewComments.php b/core/modules/comment/src/Plugin/views/field/NodeNewComments.php
index 6bf1607..51c1cd4 100644
--- a/core/modules/comment/src/Plugin/views/field/NodeNewComments.php
+++ b/core/modules/comment/src/Plugin/views/field/NodeNewComments.php
@@ -90,6 +90,21 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
'#type' => 'checkbox',
'#default_value' => $this->options['link_to_comment'],
);
+ $form['threading_mode'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Threading'),
+ '#default_value' => $this->options['threading_mode'],
+ '#description' => t('Comment replies use a threaded list.'),
+ );
+ $element['per_page'] = array(
+ '#type' => 'number',
+ '#title' => t('Comments per page'),
+ '#default_value' => $this->options['per_page'],
+ '#required' => TRUE,
+ '#min' => 10,
+ '#max' => 1000,
+ '#step' => 10,
+ );
parent::buildOptionsForm($form, $form_state);
}
@@ -153,7 +168,7 @@ protected function renderLink($data, ResultRow $values) {
'type' => $this->getValue($values, 'type'),
));
$page_number = \Drupal::entityManager()->getStorage('comment')
- ->getNewCommentPageNumber($this->getValue($values, 'comment_count'), $this->getValue($values), $node);
+ ->getNewCommentPageNumber($this->getValue($values, 'comment_count'), $this->getValue($values), $node, $this->options['threading_mode'], $this->options['per_page']);
$this->options['alter']['make_link'] = TRUE;
$this->options['alter']['path'] = 'node/' . $node->id();
$this->options['alter']['query'] = $page_number ? array('page' => $page_number) : NULL;
diff --git a/core/modules/comment/src/Tests/CommentCacheTagsTest.php b/core/modules/comment/src/Tests/CommentCacheTagsTest.php
index 921f6ca..18f1a05 100644
--- a/core/modules/comment/src/Tests/CommentCacheTagsTest.php
+++ b/core/modules/comment/src/Tests/CommentCacheTagsTest.php
@@ -7,9 +7,9 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
+use Drupal\comment\Entity\CommentType;
use Drupal\Core\Entity\EntityInterface;
-use Drupal\field\Entity\FieldConfig;
use Drupal\system\Tests\Entity\EntityWithUriCacheTagsTestBase;
/**
@@ -49,9 +49,9 @@ protected function createEntity() {
\Drupal::service('comment.manager')->addDefaultField('entity_test', 'bar', 'comment');
// Display comments in a flat list; threaded comments are not render cached.
- $field = FieldConfig::loadByName('entity_test', 'bar', 'comment');
- $field->settings['default_mode'] = CommentManagerInterface::COMMENT_MODE_FLAT;
- $field->save();
+ $comment_type = CommentType::load('comment');
+ $comment_type->setThreadingMode(CommentTypeInterface::THREADING_MODE_FLAT);
+ $comment_type->save();
// Create a "Camelids" test entity.
$entity_test = entity_create('entity_test', array(
diff --git a/core/modules/comment/src/Tests/CommentInterfaceTest.php b/core/modules/comment/src/Tests/CommentInterfaceTest.php
index b174492..e107aee 100644
--- a/core/modules/comment/src/Tests/CommentInterfaceTest.php
+++ b/core/modules/comment/src/Tests/CommentInterfaceTest.php
@@ -7,7 +7,7 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Entity\Comment;
@@ -27,7 +27,7 @@ function testCommentInterface() {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(FALSE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
$this->drupalLogout();
// Post comment #1 without subject or preview.
diff --git a/core/modules/comment/src/Tests/CommentLinksTest.php b/core/modules/comment/src/Tests/CommentLinksTest.php
index 34b8b41..6d0176a 100644
--- a/core/modules/comment/src/Tests/CommentLinksTest.php
+++ b/core/modules/comment/src/Tests/CommentLinksTest.php
@@ -7,10 +7,11 @@
namespace Drupal\comment\Tests;
+use Drupal\comment\CommentInterface;
+use Drupal\comment\CommentTypeInterface;
+use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Language\LanguageInterface;
-use Drupal\comment\CommentInterface;
-use Drupal\entity\Entity\EntityViewDisplay;
/**
* Basic comment links tests to ensure markup present.
@@ -43,6 +44,28 @@ class CommentLinksTest extends CommentTestBase {
public static $modules = array('views');
/**
+ * {@inheritdoc}
+ */
+ public function setUp() {
+ parent::setUp();
+ // Set comment field to use the link formatter on article teasers.
+ entity_get_display('node', 'article', 'teaser')
+ ->setComponent('comment', array(
+ 'label' => 'hidden',
+ 'type' => 'comment_links',
+ 'weight' => 20,
+ 'settings' => array(
+ 'per_page' => 50,
+ 'default_mode' => CommentTypeInterface::THREADING_MODE_THREADED,
+ 'form_location' => CommentItemInterface::FORM_BELOW,
+ 'show_links' => CommentDefaultFormatter::LINKS_TEASER,
+ ),
+ ))
+ ->save();
+ }
+
+
+ /**
* Tests that comment links are output and can be hidden.
*/
public function testCommentLinks() {
@@ -76,7 +99,7 @@ public function testCommentLinks() {
$this->comment = $comment;
// Change comment settings.
- $this->setCommentSettings('form_location', CommentItemInterface::FORM_BELOW, 'Set comment form location');
+ $this->setCommentFormatterSettings('form_location', CommentItemInterface::FORM_BELOW, 'Set comment form location');
$this->setCommentAnonymous(TRUE);
$this->node->comment = CommentItemInterface::OPEN;
$this->node->save();
diff --git a/core/modules/comment/src/Tests/CommentNewIndicatorTest.php b/core/modules/comment/src/Tests/CommentNewIndicatorTest.php
index d057415..0be4f01 100644
--- a/core/modules/comment/src/Tests/CommentNewIndicatorTest.php
+++ b/core/modules/comment/src/Tests/CommentNewIndicatorTest.php
@@ -109,6 +109,8 @@ public function testCommentNewCommentsIndicator() {
// perform an HTTP request to render the "new comments" node link.
$this->assertIdentical(1, count($this->xpath('//*[@data-history-node-last-comment-timestamp="' . $comment->getChangedTime() . '"]')), 'data-history-node-last-comment-timestamp attribute is set to the correct value.');
$this->assertIdentical(1, count($this->xpath('//*[@data-history-node-field-name="comment"]')), 'data-history-node-field-name attribute is set to the correct value.');
+ $this->assertIdentical(1, count($this->xpath('//*[@data-comment-per-page="50"]')), 'data-comment-per-page attribute is set to the correct value.');
+ $this->assertIdentical(1, count($this->xpath('//*[@data-comment-threading-mode="1"]')), 'data-comment-threading-mode is set to the correct value.');
$response = $this->renderNewCommentsNodeLinks(array($this->node->id()));
$this->assertResponse(200);
$json = Json::decode($response);
diff --git a/core/modules/comment/src/Tests/CommentNodeAccessTest.php b/core/modules/comment/src/Tests/CommentNodeAccessTest.php
index 4c50180..b49e08f 100644
--- a/core/modules/comment/src/Tests/CommentNodeAccessTest.php
+++ b/core/modules/comment/src/Tests/CommentNodeAccessTest.php
@@ -7,7 +7,7 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
/**
* Tests comments with node access.
@@ -54,7 +54,7 @@ function testThreadedCommentView() {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
+ $this->setCommentFormatterSettings('default_mode', CommentTypeInterface::THREADING_MODE_THREADED, 'Comment paging changed.');
$this->drupalLogout();
// Post comment.
diff --git a/core/modules/comment/src/Tests/CommentPagerTest.php b/core/modules/comment/src/Tests/CommentPagerTest.php
index 3ebfbab..42af43a 100644
--- a/core/modules/comment/src/Tests/CommentPagerTest.php
+++ b/core/modules/comment/src/Tests/CommentPagerTest.php
@@ -7,7 +7,7 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
use Drupal\Component\Utility\String;
/**
@@ -34,7 +34,7 @@ function testCommentPaging() {
$comments[] = $this->postComment($node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
$comments[] = $this->postComment($node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_FLAT, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_FLAT);
// Set comments to one per page so that we are able to test paging without
// needing to insert large numbers of comments.
@@ -74,7 +74,7 @@ function testCommentPaging() {
// If we switch to threaded mode, the replies on the oldest comment
// should be bumped to the first page and comment 6 should be bumped
// to the second page.
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Switched to threaded mode.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED, 'Switched to threaded mode.');
$this->drupalGet('node/' . $node->id(), array('query' => array('page' => 0)));
$this->assertTrue($this->commentExists($reply, TRUE), 'In threaded mode, reply appears on page 1.');
$this->assertFalse($this->commentExists($comments[1]), 'In threaded mode, comment 2 has been bumped off of page 1.');
@@ -134,7 +134,7 @@ function testCommentOrderingThreading() {
// - 2
// - 5
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_FLAT, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_FLAT);
$expected_order = array(
0,
@@ -148,7 +148,7 @@ function testCommentOrderingThreading() {
$this->drupalGet('node/' . $node->id());
$this->assertCommentOrder($comments, $expected_order);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Switched to threaded mode.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED, 'Switched to threaded mode.');
$expected_order = array(
0,
@@ -229,7 +229,7 @@ function testCommentNewPageIndicator() {
// - 2
// - 5
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_FLAT, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_FLAT);
$expected_pages = array(
1 => 5, // Page of comment 5
@@ -243,11 +243,11 @@ function testCommentNewPageIndicator() {
$node = node_load($node->id());
foreach ($expected_pages as $new_replies => $expected_page) {
$returned_page = \Drupal::entityManager()->getStorage('comment')
- ->getNewCommentPageNumber($node->get('comment')->comment_count, $new_replies, $node);
+ ->getNewCommentPageNumber($node->get('comment')->comment_count, $new_replies, $node, CommentTypeInterface::THREADING_MODE_FLAT, 1);
$this->assertIdentical($expected_page, $returned_page, format_string('Flat mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
}
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Switched to threaded mode.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED, 'Switched to threaded mode.');
$expected_pages = array(
1 => 5, // Page of comment 5
@@ -262,7 +262,7 @@ function testCommentNewPageIndicator() {
$node = node_load($node->id());
foreach ($expected_pages as $new_replies => $expected_page) {
$returned_page = \Drupal::entityManager()->getStorage('comment')
- ->getNewCommentPageNumber($node->get('comment')->comment_count, $new_replies, $node);
+ ->getNewCommentPageNumber($node->get('comment')->comment_count, $new_replies, $node, CommentTypeInterface::THREADING_MODE_THREADED, 1);
$this->assertEqual($expected_page, $returned_page, format_string('Threaded mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page)));
}
}
@@ -309,7 +309,7 @@ function testTwoPagers() {
foreach (array('comment', 'comment_2') as $field_name) {
$this->setCommentForm(TRUE, $field_name);
$this->setCommentPreview(DRUPAL_OPTIONAL, $field_name);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_FLAT, 'Comment paging changed.', $field_name);
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_FLAT);
// Set comments to one per page so that we are able to test paging without
// needing to insert large numbers of comments.
diff --git a/core/modules/comment/src/Tests/CommentPreviewTest.php b/core/modules/comment/src/Tests/CommentPreviewTest.php
index 8d188c3..80f652a 100644
--- a/core/modules/comment/src/Tests/CommentPreviewTest.php
+++ b/core/modules/comment/src/Tests/CommentPreviewTest.php
@@ -7,7 +7,7 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\comment\Entity\Comment;
@@ -36,7 +36,7 @@ function testCommentPreview() {
$this->setCommentPreview(DRUPAL_OPTIONAL);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
$this->drupalLogout();
// Login as web user and add a signature and a user picture.
@@ -79,7 +79,7 @@ function testCommentEditPreviewSave() {
$this->setCommentPreview(DRUPAL_OPTIONAL);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
$edit = array();
$date = new DrupalDateTime('2008-03-02 17:23');
diff --git a/core/modules/comment/src/Tests/CommentStatisticsTest.php b/core/modules/comment/src/Tests/CommentStatisticsTest.php
index 6b7bf01..8c19182 100644
--- a/core/modules/comment/src/Tests/CommentStatisticsTest.php
+++ b/core/modules/comment/src/Tests/CommentStatisticsTest.php
@@ -7,7 +7,7 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
use Drupal\comment\Entity\Comment;
/**
@@ -41,7 +41,7 @@ function testCommentNodeCommentStatistics() {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(FALSE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
$this->drupalLogout();
// Checks the initial values of node comment statistics with no comment.
diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php
index d86e3d4..9d23d7f 100644
--- a/core/modules/comment/src/Tests/CommentTestBase.php
+++ b/core/modules/comment/src/Tests/CommentTestBase.php
@@ -81,6 +81,20 @@ protected function setUp() {
// Create comment field on article.
$this->container->get('comment.manager')->addDefaultField('node', 'article');
+ // Set some display options for search results and print pages.
+ if ($this->container->get('module_handler')->moduleExists('book')) {
+ $display = entity_get_display('node', 'article', 'print');
+ $display->removeComponent('comment');
+ $display->save();
+ }
+ if ($this->container->get('module_handler')->moduleExists('search')) {
+ foreach (array('search_result', 'search_index') as $view_mode) {
+ $display = entity_get_display('node', 'article', $view_mode);
+ $display->removeComponent('comment');
+ $display->save();
+ }
+ }
+
// Create a test node authored by the web user.
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->id()));
}
@@ -267,7 +281,7 @@ public function setCommentPreview($mode, $field_name = 'comment') {
* Defaults to 'comment'.
*/
public function setCommentForm($enabled, $field_name = 'comment') {
- $this->setCommentSettings('form_location', ($enabled ? CommentItemInterface::FORM_BELOW : CommentItemInterface::FORM_SEPARATE_PAGE), 'Comment controls ' . ($enabled ? 'enabled' : 'disabled') . '.', $field_name);
+ $this->setCommentFormatterSettings('form_location', ($enabled ? CommentItemInterface::FORM_BELOW : CommentItemInterface::FORM_SEPARATE_PAGE), 'Comment controls ' . ($enabled ? 'enabled' : 'disabled') . '.', $field_name);
}
/**
@@ -293,11 +307,27 @@ function setCommentAnonymous($level) {
* Defaults to 'comment'.
*/
public function setCommentsPerPage($number, $field_name = 'comment') {
- $this->setCommentSettings('per_page', $number, format_string('Number of comments per page set to @number.', array('@number' => $number)), $field_name);
+ $this->setCommentFormatterSettings('per_page', $number, format_string('Number of comments per page set to @number.', array('@number' => $number)), $field_name);
+ }
+
+ /**
+ * Sets the threading mode for this comment type.
+ *
+ * @param int $mode
+ * The threading mode.
+ * @param string $message
+ * (optional) Status message to display. Defaults to 'Comment threading
+ * changed.'
+ */
+ public function setThreadingMode($mode, $message = 'Comment threading changed.') {
+ $comment_type = CommentType::load('article');
+ $comment_type->setThreadingMode($mode);
+ $comment_type->save();
+ $this->pass($message);
}
/**
- * Sets a comment settings variable for the article content type.
+ * Sets a comment field settings variable for the article content type.
*
* @param string $name
* Name of variable.
@@ -318,6 +348,29 @@ public function setCommentSettings($name, $value, $message, $field_name = 'comme
}
/**
+ * Sets a display formatter settings variable for the article content type.
+ *
+ * @param string $name
+ * Name of variable.
+ * @param string $value
+ * Value of variable.
+ * @param string $message
+ * Status message to display.
+ * @param string $field_name
+ * (optional) Field name through which the comment should be posted.
+ * Defaults to 'comment'.
+ */
+ public function setCommentFormatterSettings($name, $value, $message, $field_name = 'comment') {
+ $display = entity_get_display('node', 'article', 'full');
+ $component = $display->getComponent($field_name);
+ $component['settings'][$name] = $value;
+ $display->setComponent($field_name, $component);
+ $display->save();
+ // Display status message.
+ $this->pass($message);
+ }
+
+ /**
* Checks whether the commenter's contact information is displayed.
*
* @return boolean
diff --git a/core/modules/comment/src/Tests/CommentThreadingTest.php b/core/modules/comment/src/Tests/CommentThreadingTest.php
index 6fa1197..848ba2c 100644
--- a/core/modules/comment/src/Tests/CommentThreadingTest.php
+++ b/core/modules/comment/src/Tests/CommentThreadingTest.php
@@ -7,7 +7,7 @@
namespace Drupal\comment\Tests;
-use Drupal\comment\CommentManagerInterface;
+use Drupal\comment\CommentTypeInterface;
/**
* Tests to make sure the comment number increments properly.
@@ -24,7 +24,7 @@ function testCommentThreading() {
$this->setCommentPreview(DRUPAL_DISABLED);
$this->setCommentForm(TRUE);
$this->setCommentSubject(TRUE);
- $this->setCommentSettings('default_mode', CommentManagerInterface::COMMENT_MODE_THREADED, 'Comment paging changed.');
+ $this->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
$this->drupalLogout();
// Create a node.
diff --git a/core/modules/comment/templates/field--comment.html.twig b/core/modules/comment/templates/field--comment.html.twig
index 9aae572..9691012 100644
--- a/core/modules/comment/templates/field--comment.html.twig
+++ b/core/modules/comment/templates/field--comment.html.twig
@@ -15,7 +15,7 @@
* - comments: List of comments rendered through comment.html.twig.
* - content_attributes: HTML attributes for the form title.
* - comment_form: The 'Add new comment' form.
- * - comment_display_mode: Is the comments are threaded.
+ * - comment_threading_mode: Is non-zero if the comments are threaded.
* - comment_type: The comment type bundle ID for the comment field.
*
* @see template_preprocess_field()
diff --git a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php
index 2993f28..89d5cbc 100644
--- a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php
+++ b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php
@@ -8,6 +8,8 @@
namespace Drupal\Tests\comment\Unit;
use Drupal\comment\CommentLinkBuilder;
+use Drupal\comment\CommentTypeInterface;
+use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\node\NodeInterface;
use Drupal\simpletest\TestBase;
@@ -20,6 +22,62 @@
class CommentLinkBuilderTest extends UnitTestCase {
/**
+ * Entity manager mock.
+ *
+ * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $entityManager;
+
+ /**
+ * Entity storage mock which knows entity_view_display load method/argument.
+ *
+ * @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $entityStorage;
+
+ /**
+ * Entity storage mock which knows comment_type load method/argument.
+ *
+ * @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $commentTypeStorage;
+
+ /**
+ * Entity view display mock.
+ *
+ * @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $entityViewDisplay;
+
+ /**
+ * Comment type mock.
+ *
+ * @var \Drupal\comment\CommentTypeInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $commentType;
+
+ /**
+ * Field item list(value) mock.
+ *
+ * @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $fieldItem;
+
+ /**
+ * Field definition mock.
+ *
+ * @var \Drupal\Core\Field\FieldDefinitionInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $fieldDefinition;
+
+ /**
+ * Field definition mock.
+ *
+ * @var \Drupal\Core\Field\FieldStorageDefinitionInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $fieldStorageDefinition;
+
+ /**
* Comment manager mock.
*
* @var \Drupal\comment\CommentManagerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -63,11 +121,38 @@ class CommentLinkBuilderTest extends UnitTestCase {
* Prepares mocks for the test.
*/
protected function setUp() {
+ $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
+ $this->entityStorage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface');
+ $this->commentTypeStorage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface');
+ $this->commentType = $this->getMock('\Drupal\comment\CommentTypeInterface');
+ $this->entityViewDisplay = $this->getMock('Drupal\Core\Entity\Display\EntityViewDisplayInterface');
+ $this->fieldItem = $this->getMock('\Drupal\Core\Field\FieldItemListInterface');
+ $this->fieldDefinition = $this->getMock('\Drupal\Core\Field\FieldDefinitionInterface');
+ $this->fieldStorageDefinition = $this->getMock('\Drupal\Core\Field\FieldStorageDefinitionInterface');
$this->commentManager = $this->getMock('\Drupal\comment\CommentManagerInterface');
$this->stringTranslation = $this->getStringTranslationStub();
$this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
$this->currentUser = $this->getMock('\Drupal\Core\Session\AccountProxyInterface');
- $this->commentLinkBuilder = new CommentLinkBuilder($this->currentUser, $this->commentManager, $this->moduleHandler, $this->stringTranslation);
+ $this->commentLinkBuilder = new CommentLinkBuilder($this->currentUser, $this->entityManager, $this->commentManager, $this->moduleHandler, $this->stringTranslation);
+ $this->fieldItem->expects($this->any())
+ ->method('getFieldDefinition')
+ ->willReturn($this->fieldDefinition);
+ $this->fieldDefinition->expects($this->any())
+ ->method('getFieldStorageDefinition')
+ ->willReturn($this->fieldStorageDefinition);
+ $this->fieldStorageDefinition->expects($this->any())
+ ->method('getSetting')
+ ->with('comment_type')
+ ->willReturn('comment');
+ $this->entityManager->expects($this->any())
+ ->method('getStorage')
+ ->will($this->returnValueMap(array(
+ array('entity_view_display', $this->entityStorage),
+ array('comment_type', $this->commentTypeStorage),
+ )));
+ $this->commentTypeStorage->expects($this->any())
+ ->method('load')
+ ->willReturn($this->commentType);
$this->commentManager->expects($this->any())
->method('getFields')
->with('node')
@@ -97,6 +182,14 @@ protected function setUp() {
* TRUE if the use has 'post comments' permission.
* @param bool $is_anonymous
* TRUE if the user is anonymous.
+ * @param int $form_location
+ * One of CommentItemInterface::FORM_BELOW|FORM_SEPARATE_PAGE
+ * @param int $link_style
+ * CommentDefaultFormatter::LINKS_NONE|LINKS_PAGE|LINKS_RSS|LINKS_TEASER
+ * @param int $comment_status
+ * One of CommentItemInterface::OPEN|HIDDEN|CLOSED
+ * @param int $comment_count
+ * Number of comments against the field.
* @param array $expected
* Array of expected links keyed by link ID. Can be either string (link
* title) or array of link properties.
@@ -105,7 +198,7 @@ protected function setUp() {
*
* @covers ::buildCommentedEntityLinks()
*/
- public function testCommentLinkBuilder(NodeInterface $node, $context, $has_access_comments, $history_exists, $has_post_comments, $is_anonymous, $expected) {
+ public function testCommentLinkBuilder(NodeInterface $node, $context, $has_access_comments, $history_exists, $has_post_comments, $is_anonymous, $form_location, $link_style, $comment_status, $comment_count, $expected) {
$this->moduleHandler->expects($this->any())
->method('moduleExists')
->with('history')
@@ -122,6 +215,44 @@ public function testCommentLinkBuilder(NodeInterface $node, $context, $has_acces
$this->currentUser->expects($this->any())
->method('isAnonymous')
->willReturn($is_anonymous);
+
+ $this->entityStorage->expects($this->any())
+ ->method('load')
+ ->with($node->getEntityTypeId() . '.' . $node->bundle() . '.teaser')
+ ->willReturn($this->entityViewDisplay);
+ $this->entityViewDisplay->expects($this->any())
+ ->method('getComponent')
+ ->willReturn(array('settings' => array(
+ 'form_location' => $form_location,
+ 'show_links' => $link_style,
+ // This setting influences the page argument to the 'new comments' url,
+ // which we're not testing, so return static values.
+ 'per_page' => 50
+ )));
+ // This setting influences the page argument to the 'new comments' url,
+ // which we're not testing, so return static values.
+ $this->commentType->expects($this->any())
+ ->method('getThreadingMode')
+ ->willReturn(CommentTypeInterface::THREADING_MODE_THREADED);
+
+ if (empty($this->timestamp)) {
+ $this->timestamp = time();
+ }
+ $this->fieldItem->expects($this->any())
+ ->method('getEntity')
+ ->willReturn($node);
+ $this->fieldItem->expects($this->any())
+ ->method('__get')
+ ->will($this->returnValueMap(array(
+ array('status', $comment_status),
+ array('comment_count', $comment_count),
+ array('last_comment_timestamp', $this->timestamp),
+ )));
+ $node->expects($this->any())
+ ->method('get')
+ ->with('comment')
+ ->willReturn($this->fieldItem);
+
$links = $this->commentLinkBuilder->buildCommentedEntityLinks($node, $context);
if (!empty($expected)) {
if (!empty($links)) {
@@ -145,14 +276,12 @@ public function testCommentLinkBuilder(NodeInterface $node, $context, $has_acces
else {
$this->assertSame($links, $expected);
}
- if ($context['view_mode'] == 'rss' && $node->get('comment')->status) {
+ if ($link_style == CommentDefaultFormatter::LINKS_RSS && $node->get('comment')->status) {
$found = FALSE;
- if ($node->get('comment')->status) {
- foreach ($node->rss_elements as $element) {
- if ($element['key'] == 'comments') {
- $found = TRUE;
- break;
- }
+ foreach ($node->rss_elements as $element) {
+ if ($element['key'] == 'comments') {
+ $found = TRUE;
+ break;
}
}
$this->assertTrue($found);
@@ -166,23 +295,33 @@ public function getLinkCombinations() {
$cases = array();
// No links should be created if the entity doesn't have the field.
$cases[] = array(
- $this->getMockNode(FALSE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1),
+ $this->getMockNode(FALSE),
array('view_mode' => 'teaser'),
TRUE,
TRUE,
TRUE,
TRUE,
+ CommentItemInterface::FORM_BELOW,
+ CommentDefaultFormatter::LINKS_TEASER,
+ CommentItemInterface::OPEN,
+ 1,
array(),
);
foreach (array('search_result', 'search_index', 'print') as $view_mode) {
// Nothing should be output in these view modes.
+ // (Other view modes do not influence link display; they're only used for
+ // loading display settings. So we arbitrarily use 'teaser'.)
$cases[] = array(
- $this->getMockNode(TRUE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1),
+ $this->getMockNode(TRUE),
array('view_mode' => $view_mode),
TRUE,
TRUE,
TRUE,
TRUE,
+ CommentItemInterface::FORM_BELOW,
+ CommentDefaultFormatter::LINKS_TEASER,
+ CommentItemInterface::OPEN,
+ 1,
array(),
);
}
@@ -199,39 +338,52 @@ public function getLinkCombinations() {
CommentItemInterface::CLOSED,
CommentItemInterface::HIDDEN,
),
- 'view_mode' => array(
- 'teaser', 'rss', 'full',
+ 'link_style' => array(
+ CommentDefaultFormatter::LINKS_NONE,
+ CommentDefaultFormatter::LINKS_PAGE,
+ CommentDefaultFormatter::LINKS_RSS,
+ CommentDefaultFormatter::LINKS_TEASER,
),
);
$permutations = TestBase::generatePermutations($combinations);
foreach ($permutations as $combination) {
$case = array(
- $this->getMockNode(TRUE, $combination['comments'], $combination['form_location'], $combination['comment_count']),
- array('view_mode' => $combination['view_mode']),
+ $this->getMockNode(TRUE),
+ array('view_mode' => 'teaser'),
$combination['has_access_comments'],
$combination['history_exists'],
$combination['has_post_comments'],
$combination['is_anonymous'],
+ $combination['form_location'],
+ $combination['link_style'],
+ $combination['comments'],
+ $combination['comment_count'],
);
$expected = array();
- // When comments are enabled in teaser mode, and comments exist, and the
- // user has access - we can output the comment count.
- if ($combination['comments'] && $combination['view_mode'] == 'teaser' && $combination['comment_count'] && $combination['has_access_comments']) {
+ // When comments are enabled with teaser links, and comments exist, and
+ // the user has access - we can output the comment count.
+ if ($combination['comments'] != CommentItemInterface::HIDDEN
+ && $combination['link_style'] == CommentDefaultFormatter::LINKS_TEASER
+ && $combination['comment_count']
+ && $combination['has_access_comments']) {
$expected['comment-comments'] = '1 comment';
// And if history module exists, we can show a 'new comments' link.
if ($combination['history_exists']) {
$expected['comment-new-comments'] = '';
}
}
- // All view modes other than RSS.
- if ($combination['view_mode'] != 'rss') {
+ // All link styles other than RSS.
+ if ($combination['link_style'] != CommentDefaultFormatter::LINKS_RSS
+ && $combination['link_style'] != CommentDefaultFormatter::LINKS_NONE) {
// Where commenting is open.
if ($combination['comments'] == CommentItemInterface::OPEN) {
// And the user has post-comments permission.
if ($combination['has_post_comments']) {
- // If the view mode is teaser, or the user can access comments and
+ // If the link style is teaser, or the user can access comments and
// comments exist or the form is on a separate page.
- if ($combination['view_mode'] == 'teaser' || ($combination['has_access_comments'] && $combination['comment_count']) || $combination['form_location'] == CommentItemInterface::FORM_SEPARATE_PAGE) {
+ if ($combination['link_style'] == CommentDefaultFormatter::LINKS_TEASER
+ || ($combination['has_access_comments'] && $combination['comment_count'])
+ || $combination['form_location'] == CommentItemInterface::FORM_SEPARATE_PAGE) {
// There should be a add comment link.
$expected['comment-add'] = array('title' => 'Add new comment');
if ($combination['form_location'] == CommentItemInterface::FORM_BELOW) {
@@ -263,40 +415,17 @@ public function getLinkCombinations() {
*
* @param bool $has_field
* TRUE if the node has the 'comment' field.
- * @param int $comment_status
- * One of CommentItemInterface::OPEN|HIDDEN|CLOSED
- * @param int $form_location
- * One of CommentItemInterface::FORM_BELOW|FORM_SEPARATE_PAGE
- * @param int $comment_count
- * Number of comments against the field.
*
* @return \Drupal\node\NodeInterface|\PHPUnit_Framework_MockObject_MockObject
* Mock node for testing.
*/
- protected function getMockNode($has_field, $comment_status, $form_location, $comment_count) {
+ protected function getMockNode($has_field) {
$node = $this->getMock('\Drupal\node\NodeInterface');
$node->expects($this->once())
->method('hasField')
->willReturn($has_field);
- if (empty($this->timestamp)) {
- $this->timestamp = time();
- }
- $field_item = (object) array(
- 'status' => $comment_status,
- 'comment_count' => $comment_count,
- 'last_comment_timestamp' => $this->timestamp,
- );
- $node->expects($this->any())
- ->method('get')
- ->with('comment')
- ->willReturn($field_item);
-
$field_definition = $this->getMock('\Drupal\Core\Field\FieldDefinitionInterface');
- $field_definition->expects($this->any())
- ->method('getSetting')
- ->with('form_location')
- ->willReturn($form_location);
$node->expects($this->any())
->method('getFieldDefinition')
->with('comment')
@@ -311,6 +440,10 @@ protected function getMockNode($has_field, $comment_status, $form_location, $com
->willReturn('node');
$node->expects($this->any())
+ ->method('bundle')
+ ->willReturn('article');
+
+ $node->expects($this->any())
->method('id')
->willReturn(1);
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 6605c1d..3ab6db8 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -5,10 +5,11 @@
* Install, update, and uninstall functions for the Forum module.
*/
+use Drupal\comment\CommentTypeInterface;
+use Drupal\comment\Entity\CommentType;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\comment\CommentManagerInterface;
/**
* Implements hook_install().
@@ -91,9 +92,9 @@ function forum_install() {
Drupal::service('comment.manager')->addDefaultField('node', 'forum', 'comment_forum', CommentItemInterface::OPEN, 'comment_forum');
// Add here because we don't have param in addDefaultField function.
- $field = FieldConfig::loadByName('node', 'forum', 'comment_forum');
- $field->settings['default_mode'] = CommentManagerInterface::COMMENT_MODE_FLAT;
- $field->save();
+ $comment_type = CommentType::load('comment_forum');
+ $comment_type->setThreadingMode(CommentTypeInterface::THREADING_MODE_FLAT);
+ $comment_type->save();
// Hide label for comment field.
entity_get_display('node', 'forum', 'default')
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index f81f6a8..107678c 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -494,6 +494,10 @@ function forum_theme_suggestions_forums(array $variables) {
*/
function template_preprocess_forums(&$variables) {
$variables['tid'] = $variables['term']->id();
+ $display = entity_get_display('node', 'forum', 'full');
+ $settings = $display->getComponent('comment_forum')['settings'];
+ $field_definition = \Drupal::entityManager()->getFieldStorageDefinitions('node')['comment_forum'];
+ $comment_type = CommentType::load($field_definition->getSetting('comment_type'));
if ($variables['forums_defined'] = count($variables['forums']) || count($variables['parents'])) {
if (!empty($variables['forums'])) {
$variables['forums'] = array(
@@ -560,7 +564,7 @@ function template_preprocess_forums(&$variables) {
if ($topic->new_replies) {
$page_number = \Drupal::entityManager()->getStorage('comment')
- ->getNewCommentPageNumber($topic->comment_count, $topic->new_replies, $topic, 'comment_forum');
+ ->getNewCommentPageNumber($topic->comment_count, $topic->new_replies, $topic, $comment_type->getThreadingMode(), $settings['per_page'], 'comment_forum');
$query = $page_number ? array('page' => $page_number) : NULL;
$variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post in topic %title', '@count new posts in topic %title', array('%title' => $variables['topics'][$id]->label()));
$variables['topics'][$id]->new_url = \Drupal::url('entity.node.canonical', ['node' => $topic->id()], ['query' => $query, 'fragment' => 'new']);
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index c2b5582..489afca 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -4,6 +4,9 @@
* Install, update and uninstall functions for the standard installation profile.
*/
+use Drupal\comment\CommentTypeInterface;
+use Drupal\comment\Entity\CommentType;
+use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
/**
@@ -25,6 +28,28 @@ function standard_install() {
// Add comment field to article node type.
\Drupal::service('comment.manager')->addDefaultField('node', 'article', 'comment', CommentItemInterface::OPEN);
+ $comment_type = CommentType::load('comment');
+ $comment_type->setThreadingMode(CommentTypeInterface::THREADING_MODE_THREADED);
+ $comment_type->save();
+ // Set some display options for comments in search results.
+ foreach (array('search_result', 'search_index') as $view_mode) {
+ $display = entity_get_display('node', 'article', $view_mode);
+ $display->removeComponent('comment');
+ $display->save();
+ }
+ // Set comment field to use the link formatter on article teasers.
+ entity_get_display('node', 'article', 'teaser')
+ ->setComponent('comment', array(
+ 'label' => 'hidden',
+ 'type' => 'comment_links',
+ 'weight' => 20,
+ 'settings' => array(
+ 'per_page' => 50,
+ 'form_location' => CommentItemInterface::FORM_BELOW,
+ 'show_links' => CommentDefaultFormatter::LINKS_TEASER,
+ ),
+ ))
+ ->save();
// Hide the comment field in the rss view mode.
entity_get_display('node', 'article', 'rss')