diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index d875009..3fe147e 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -140,7 +140,7 @@ function comment_update_8101() { $display = $config_factory->getEditable($name); $components = $display->get('content') ?: []; foreach ($components as $field_name => $component) { - if (isset($component['type']) && ($component['type'] == 'comment_default')) { + if (isset($component['type']) && ($component['type'] === 'comment_default')) { if (empty($display->get("content.{$field_name}.settings.view_mode"))) { $display->set("content.{$field_name}.settings.view_mode", 'default'); $changed = TRUE; diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index e333b56..d07c256 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -14,6 +14,7 @@ use Drupal\comment\Entity\CommentType; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Core\Entity\Entity\EntityViewMode; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; @@ -756,3 +757,44 @@ function comment_preprocess_field(&$variables) { function comment_ranking() { return \Drupal::service('comment.statistics')->getRankingInfo(); } + +/** + * Implements hook_ENTITY_TYPE_presave() for entity_view_display entities. + */ +function comment_entity_view_display_presave(EntityViewDisplayInterface $display) { + // Act only on comment view displays being disabled. + if ($display->isNew() || $display->getTargetEntityTypeId() != 'comment' || $display->status()) { + return; + } + $storage = \Drupal::entityTypeManager()->getStorage('entity_view_display'); + if (!$storage->loadUnchanged($display->getOriginalId())->status()) { + return; + } + + // Disable the comment field formatter when the used view display is disabled. + foreach ($storage->loadMultiple() as $id => $view_display) { + $changed = FALSE; + /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */ + foreach ($view_display->getComponents() as $field => $component) { + if (isset($component['type']) && ($component['type'] == 'comment_default')) { + if ($component['settings']['view_mode'] == $display->getMode()) { + $view_display->removeComponent($field); + /** @var \Drupal\Core\Entity\EntityViewModeInterface $mode */ + $mode = EntityViewMode::load($display->getTargetEntityTypeId() . '.' . $display->getMode()); + $arguments = [ + '@id' => $view_display->id(), + '@name' => $field, + '@display' => $mode->label(), + '@mode' => $display->getMode(), + ]; + \Drupal::logger('system') + ->warning("View display '@id': Comment field formatter '@name' was disabled because is using the comment view display '@display' (@mode) that was just disabled.", $arguments); + $changed = TRUE; + } + } + } + if ($changed) { + $view_display->save(); + } + } +} diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml index 652ba99..a55488a 100644 --- a/core/modules/comment/config/schema/comment.schema.yml +++ b/core/modules/comment/config/schema/comment.schema.yml @@ -6,7 +6,7 @@ field.formatter.settings.comment_default: mapping: view_mode: type: string - label: 'The comment entity view mode to be used in this formatter ' + label: 'The comment entity view mode to be used in this formatter' pager_id: type: integer label: 'Pager ID' diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index 884e34e..80f6d1f 100644 --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -164,7 +164,12 @@ public function viewElements(FieldItemListInterface $items, $langcode) { $comments_per_page = $comment_settings['per_page']; $comments = $this->storage->loadThread($entity, $field_name, $mode, $comments_per_page, $this->getSetting('pager_id')); if ($comments) { - $build = $this->viewBuilder->viewMultiple($comments, $this->getSetting('view_mode')); + if (($view_mode = $this->getSetting('view_mode')) === 'default') { + $build = $this->viewBuilder->viewMultiple($comments); + } + else { + $build = $this->viewBuilder->viewMultiple($comments, $view_mode); + } $build['pager']['#type'] = 'pager'; if ($this->getSetting('pager_id')) { $build['pager']['#element'] = $this->getSetting('pager_id'); @@ -208,13 +213,23 @@ public function viewElements(FieldItemListInterface $items, $langcode) { */ public function settingsForm(array $form, FormStateInterface $form_state) { $element = array(); - $element['view_mode'] = array( - '#type' => 'select', - '#title' => $this->t('Comments view mode'), - '#description' => $this->t('Select the view mode used to show the list of comments.'), - '#default_value' => $this->getSetting('view_mode'), - '#options' => $this->entityManager->getViewModeOptionsByBundle('comment', $this->getFieldSetting('comment_type')), - ); + $view_modes = $this->getViewModes(); + // Only show the select element when there are more than one options. + if (count($view_modes) > 1) { + $element['view_mode'] = [ + '#type' => 'select', + '#title' => $this->t('Comments view mode'), + '#description' => $this->t('Select the view mode used to show the list of comments.'), + '#default_value' => $this->getSetting('view_mode'), + '#options' => $view_modes, + ]; + } + else { + $element['view_mode'] = [ + '#type' => 'value', + '#value' => 'default', + ]; + } $element['pager_id'] = array( '#type' => 'select', '#title' => $this->t('Pager ID'), @@ -229,13 +244,14 @@ 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. - if ($this->getSetting('pager_id')) { - return array($this->t('Pager ID: @id', array( - '@id' => $this->getSetting('pager_id'), - ))); + $summary = []; + if (($mode = $this->getSetting('view_mode')) !== 'default') { + $summary[] = $this->t('Comment view mode: @mode', ['@mode' => $this->getViewModes()[$mode]]); + } + if ($pager_id = $this->getSetting('pager_id')) { + $summary[] = $this->t('Pager ID: @id', ['@id' => $pager_id]); } - return array(); + return $summary; } /** @@ -243,7 +259,6 @@ public function settingsSummary() { */ public function calculateDependencies() { $dependencies = parent::calculateDependencies(); - if ($mode = $this->getSetting('view_mode')) { if ($bundle = $this->getFieldSetting('comment_type')) { /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */ @@ -252,8 +267,19 @@ public function calculateDependencies() { } } } - return $dependencies; } + /** + * Provides a list of comment view modes for the configured comment type. + * + * @return array + * Associative array keyed by view mode key and having the view mode label + * as value. + */ + protected function getViewModes() { + return $this->entityManager + ->getViewModeOptionsByBundle('comment', $this->getFieldSetting('comment_type')); + } + } diff --git a/core/modules/comment/src/Tests/CommentInterfaceTest.php b/core/modules/comment/src/Tests/CommentInterfaceTest.php index c547772..bea911f 100644 --- a/core/modules/comment/src/Tests/CommentInterfaceTest.php +++ b/core/modules/comment/src/Tests/CommentInterfaceTest.php @@ -325,7 +325,7 @@ public function testViewMode() { ])->setStatus(TRUE)->save(); /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $node_display */ - $node_display = EntityViewDisplay::load("node.article.default"); + $node_display = EntityViewDisplay::load('node.article.default'); $formatter = $node_display->getComponent('comment'); // Change the node comment field formatter to use $mode mode instead of // 'default' mode. diff --git a/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php b/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php new file mode 100644 index 0000000..efde8dd --- /dev/null +++ b/core/modules/comment/tests/src/Kernel/CommentIntegrationTest.php @@ -0,0 +1,142 @@ +installEntitySchema('entity_test'); + $this->installEntitySchema('user'); + $this->installEntitySchema('comment'); + $this->installSchema('dblog', ['watchdog']); + + // Create a new 'comment' comment-type. + CommentType::create([ + 'id' => 'comment', + 'label' => $this->randomString(), + ])->save(); + } + + /** + * Tests view mode setting integration. + * + * @see comment_entity_view_display_presave() + * @see CommentDefaultFormatter::calculateDependencies() + */ + public function testViewMode() { + $mode = Unicode::strtolower($this->randomMachineName()); + // Create a new comment view mode and a view display entity. + EntityViewMode::create([ + 'id' => "comment.$mode", + 'targetEntityType' => 'comment', + 'settings' => ['comment_type' => 'comment'], + ])->save(); + EntityViewDisplay::create([ + 'targetEntityType' => 'comment', + 'bundle' => 'comment', + 'mode' => $mode, + ])->setStatus(TRUE)->save(); + + // Create a comment field attached to a host 'entity_test' entity. + FieldStorageConfig::create([ + 'entity_type' => 'entity_test', + 'type' => 'comment', + 'field_name' => $field_name = Unicode::strtolower($this->randomMachineName()), + 'settings' => [ + 'comment_type' => 'comment', + ], + ])->save(); + FieldConfig::create([ + 'entity_type' => 'entity_test', + 'bundle' => 'entity_test', + 'field_name' => $field_name, + ])->save(); + + $component = [ + 'type' => 'comment_default', + 'settings' => ['view_mode' => $mode, 'pager_id' => 0], + ]; + // Create a new 'entity_test' view display on host entity that uses the + // custom comment display in field formatter to show the field. + EntityViewDisplay::create([ + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default' + ])->setComponent($field_name, $component)->setStatus(TRUE)->save(); + + $host_display_id = 'entity_test.entity_test.default'; + $comment_display_id = "comment.comment.$mode"; + + // Disable the "comment.comment.$mode" display. + EntityViewDisplay::load($comment_display_id)->setStatus(FALSE)->save(); + + /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $host_display */ + $host_display = EntityViewDisplay::load($host_display_id); + + // Check that the field formatter has been disabled on host view display. + $this->assertNull($host_display->getComponent($field_name)); + $this->assertTrue($host_display->get('hidden')[$field_name]); + + // Check that the proper warning has been logged. + $arguments = [ + '@id' => $host_display_id, + '@name' => $field_name, + '@display' => EntityViewMode::load("comment.$mode")->label(), + '@mode' => $mode, + ]; + $logged = (bool) Database::getConnection()->select('watchdog') + ->fields('watchdog', ['wid']) + ->condition('type', 'system') + ->condition('message', "View display '@id': Comment field formatter '@name' was disabled because is using the comment view display '@display' (@mode) that was just disabled.") + ->condition('variables', serialize($arguments)) + ->execute() + ->fetchField(); + + // Re-enable the comment view display. + EntityViewDisplay::load($comment_display_id)->setStatus(TRUE)->save(); + // Re-enable the comment field formatter on host entity view display. + EntityViewDisplay::load($host_display_id)->setComponent($field_name, $component)->save(); + + // Delete the "comment.$mode" view mode. + EntityViewMode::load("comment.$mode")->delete(); + + // Check that the comment view display entity has been deleted too. + $this->assertNull(EntityViewDisplay::load($comment_display_id)); + + /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */ + $host_display = EntityViewDisplay::load($host_display_id); + + // Check that the field formatter has been disabled on host view display. + $this->assertNull($host_display->getComponent($field_name)); + $this->assertTrue($host_display->get('hidden')[$field_name]); + } + +} diff --git a/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml b/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml index e9cc71d..b157c83 100644 --- a/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml +++ b/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml @@ -2,6 +2,7 @@ langcode: en status: true dependencies: config: + - core.entity_view_display.comment.comment_forum.default - field.field.node.forum.body - field.field.node.forum.comment_forum - field.field.node.forum.taxonomy_forums diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml index 605f494..ca59894 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml @@ -2,6 +2,7 @@ langcode: en status: true dependencies: config: + - core.entity_view_display.comment.comment.default - field.field.node.article.body - field.field.node.article.comment - field.field.node.article.field_image @@ -23,6 +24,14 @@ content: settings: { } third_party_settings: { } label: hidden + comment: + type: comment_default + weight: 110 + label: above + settings: + view_mode: default + pager_id: 0 + third_party_settings: { } field_image: type: image weight: -1 @@ -38,14 +47,6 @@ content: settings: link: true third_party_settings: { } - comment: - label: above - type: comment_default - weight: 110 - settings: - view_mode: default - pager_id: 0 - third_party_settings: { } links: weight: 100 hidden: