diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 1ddc527..d7e5338 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -223,8 +223,6 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array // 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; @@ -480,12 +478,11 @@ function comment_node_update_index(EntityInterface $node, $langcode) { 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) { + $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, $display_settings['settings']['default_mode'], $display_settings['settings']['per_page']); if ($comments) { comment_prepare_thread($comments); $build[] = \Drupal::entityManager()->getViewBuilder('comment')->viewMultiple($comments); 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/src/CommentLinkBuilder.php b/core/modules/comment/src/CommentLinkBuilder.php index b1864da..8c074da 100644 --- a/core/modules/comment/src/CommentLinkBuilder.php +++ b/core/modules/comment/src/CommentLinkBuilder.php @@ -9,6 +9,7 @@ use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -31,6 +32,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 +64,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; @@ -87,7 +96,22 @@ public function buildCommentedEntityLinks(ContentEntityInterface $entity, 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); + + // Get formatter settings through EntityViewDisplay (logic copied from + // entity_get_display()). + $display = $this->entityManager->getStorage('entity_view_display') + ->load($entity->getEntityTypeId() . '.' . $entity->bundle() . '.' . $view_mode); + if (!$display) { + $display = $this->entityManager->getStorage('entity_view_display') + ->create(array( + 'targetEntityType' => $entity->getEntityTypeId(), + 'bundle' => $entity->bundle(), + 'mode' => $view_mode, + 'status' => TRUE, + )); + } + $display_settings = $display->getComponent($field_name); + if ($view_mode == 'rss') { // Add a comments RSS element which is a URL to the comments of this // entity. @@ -127,7 +151,8 @@ public function buildCommentedEntityLinks(ContentEntityInterface $entity, array } // Provide a link to new comment form. if ($commenting_status == CommentItemInterface::OPEN) { - $comment_form_location = $field_definition->getSetting('form_location'); + $comment_form_location = $display_settings['settings']['form_location']; + if ($this->currentUser->hasPermission('post comments')) { $links['comment-add'] = array( 'title' => $this->t('Add new comment'), @@ -160,7 +185,7 @@ public function buildCommentedEntityLinks(ContentEntityInterface $entity, array // 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'); + $comment_form_location = $display_settings['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. @@ -212,6 +237,8 @@ public function buildCommentedEntityLinks(ContentEntityInterface $entity, array 'entity_type' => $entity->getEntityTypeId(), 'entity_id' => $entity->id(), 'field_name' => $field_name, + 'default_mode' => $display_settings['settings']['default_mode'], + 'per_page' =>$display_settings['settings']['per_page'], ), ); } diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index 3346cc2..009b294 100644 --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -345,13 +345,12 @@ protected function buildLinks(FieldItemListInterface $items) { $field_name = $this->fieldDefinition->getName(); $entity = $items->getEntity(); $commenting_status = $items->status; - if ($commenting_status) { - $field_definition = $this->fieldDefinition; + if ($commenting_status != CommentItemInterface::HIDDEN) { + // Entity has commenting status open or closed. $link_style = $this->getSetting('show_links'); - // Node has commenting open or closed. if ($link_style == static::LINKS_RSS) { // Add a comments RSS element which is a URL to the comments of this - // node. + // entity. $options = array( 'fragment' => 'comments', 'absolute' => TRUE, @@ -363,7 +362,7 @@ protected function buildLinks(FieldItemListInterface $items) { } elseif ($link_style == static::LINKS_PAGE) { // Default links: display the number of comments that have been posted, - // or a link to add new comments if the user has permission, the node + // 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($items->comment_count)) { @@ -371,7 +370,6 @@ protected function buildLinks(FieldItemListInterface $items) { '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', - 'html' => TRUE, ) + $entity->urlInfo()->toArray(); if ($this->moduleHandler->moduleExists('history')) { $links['comment-new-comments'] = array( @@ -385,7 +383,6 @@ protected function buildLinks(FieldItemListInterface $items) { 'data-comment-per-page' => $this->getSetting('per_page'), 'data-comment-default-mode' => $this->getSetting('default_mode'), ), - 'html' => TRUE, ); } } @@ -400,7 +397,7 @@ protected function buildLinks(FieldItemListInterface $items) { 'attributes' => array('title' => t('Add a new comment to this page.')), 'fragment' => 'comment-form', ); - if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE) { + 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(), @@ -429,13 +426,13 @@ protected function buildLinks(FieldItemListInterface $items) { 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 == COMMENT_FORM_SEPARATE_PAGE || (!empty($items->comment_count) && $this->currentUser->hasPermission('access comments'))) { + if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || (!empty($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 == COMMENT_FORM_SEPARATE_PAGE) { + 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(), diff --git a/core/modules/comment/src/Tests/CommentLinksTest.php b/core/modules/comment/src/Tests/CommentLinksTest.php index 97c2d6f..e4a4304 100644 --- a/core/modules/comment/src/Tests/CommentLinksTest.php +++ b/core/modules/comment/src/Tests/CommentLinksTest.php @@ -12,7 +12,6 @@ use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\Core\Language\LanguageInterface; -use Drupal\entity\Entity\EntityViewDisplay; /** * Basic comment links tests to ensure markup present. diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php index 76c1137..ef3dfe9 100644 --- a/core/modules/comment/src/Tests/CommentTestBase.php +++ b/core/modules/comment/src/Tests/CommentTestBase.php @@ -82,12 +82,12 @@ protected function setUp() { $this->container->get('comment.manager')->addDefaultField('node', 'article'); // Set some display options for search results and print pages. - if (module_exists('book')) { + if ($this->container->get('module_handler')->moduleExists('book')) { $display = entity_get_display('node', 'article', 'print'); $display->removeComponent('comment'); $display->save(); } - if (module_exists('search')) { + 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'); @@ -281,7 +281,7 @@ public function setCommentPreview($mode, $field_name = 'comment') { * Defaults to 'comment'. */ public function setCommentForm($enabled, $field_name = 'comment') { - $this->setCommentFormatterSettings('form_location', ($enabled ? CommentItemInterface::FORM_BELOW : CommentItemInterface::COMMENT_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); } /** diff --git a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php index 2993f28..92b56ed 100644 --- a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php +++ b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php @@ -8,6 +8,7 @@ namespace Drupal\Tests\comment\Unit; use Drupal\comment\CommentLinkBuilder; +use Drupal\comment\CommentManagerInterface; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\node\NodeInterface; use Drupal\simpletest\TestBase; @@ -20,6 +21,27 @@ class CommentLinkBuilderTest extends UnitTestCase { /** + * Entity manager mock. + * + * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entityManager; + + /** + * Entity storage mock. + * + * @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entityStorage; + + /** + * Entity view display mock. + * + * @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $entityViewDisplay; + + /** * Comment manager mock. * * @var \Drupal\comment\CommentManagerInterface|\PHPUnit_Framework_MockObject_MockObject @@ -63,11 +85,18 @@ 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->entityViewDisplay = $this->getMock('Drupal\Core\Entity\Display\EntityViewDisplayInterface'); $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->entityManager->expects($this->any()) + ->method('getStorage') + ->with('entity_view_display') + ->willReturn($this->entityStorage); $this->commentManager->expects($this->any()) ->method('getFields') ->with('node') @@ -97,6 +126,8 @@ 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 array $expected * Array of expected links keyed by link ID. Can be either string (link * title) or array of link properties. @@ -105,7 +136,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, $expected) { $this->moduleHandler->expects($this->any()) ->method('moduleExists') ->with('history') @@ -122,6 +153,19 @@ 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() . '.' . $context['view_mode']) + ->willReturn($this->entityViewDisplay); + $this->entityViewDisplay->expects($this->any()) + ->method('getComponent') + ->willReturn(array('settings' => array( + 'form_location' => $form_location, + // These settings influence the page argument to the 'new comments' url, + // which we're not testing, so return static values. + 'default_mode' => CommentManagerInterface::COMMENT_MODE_THREADED, + 'per_page' => 50 + ))); $links = $this->commentLinkBuilder->buildCommentedEntityLinks($node, $context); if (!empty($expected)) { if (!empty($links)) { @@ -166,23 +210,25 @@ 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, CommentItemInterface::OPEN, 1), array('view_mode' => 'teaser'), TRUE, TRUE, TRUE, TRUE, + CommentItemInterface::FORM_BELOW, array(), ); foreach (array('search_result', 'search_index', 'print') as $view_mode) { // Nothing should be output in these view modes. $cases[] = array( - $this->getMockNode(TRUE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1), + $this->getMockNode(TRUE, CommentItemInterface::OPEN, 1), array('view_mode' => $view_mode), TRUE, TRUE, TRUE, TRUE, + CommentItemInterface::FORM_BELOW, array(), ); } @@ -206,12 +252,13 @@ public function getLinkCombinations() { $permutations = TestBase::generatePermutations($combinations); foreach ($permutations as $combination) { $case = array( - $this->getMockNode(TRUE, $combination['comments'], $combination['form_location'], $combination['comment_count']), + $this->getMockNode(TRUE, $combination['comments'], $combination['comment_count']), array('view_mode' => $combination['view_mode']), $combination['has_access_comments'], $combination['history_exists'], $combination['has_post_comments'], $combination['is_anonymous'], + $combination['form_location'], ); $expected = array(); // When comments are enabled in teaser mode, and comments exist, and the @@ -265,15 +312,13 @@ public function getLinkCombinations() { * 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, $comment_status, $comment_count) { $node = $this->getMock('\Drupal\node\NodeInterface'); $node->expects($this->once()) ->method('hasField') @@ -293,10 +338,6 @@ protected function getMockNode($has_field, $comment_status, $form_location, $com ->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 +352,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/profiles/standard/standard.install b/core/profiles/standard/standard.install index 647a406..0e55bc4 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -4,6 +4,7 @@ * Install, update and uninstall functions for the standard installation profile. */ +use Drupal\comment\CommentManagerInterface; use Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; @@ -40,8 +41,8 @@ function standard_install() { 'weight' => 20, 'settings' => array( 'per_page' => 50, - 'default_mode' => COMMENT_MODE_THREADED, - 'form_location' => COMMENT_FORM_BELOW, + 'default_mode' => CommentManagerInterface::COMMENT_MODE_THREADED, + 'form_location' => CommentItemInterface::FORM_BELOW, 'show_links' => CommentDefaultFormatter::LINKS_TEASER, ), ))