Commit 7f8e1c93 authored by alexpott's avatar alexpott

Issue #2627678 by claudiu.cristea, larowlan, jonathanjfshaw, alexpott, catch:...

Issue #2627678 by claudiu.cristea, larowlan, jonathanjfshaw, alexpott, catch: Specify view mode to be used by comment formatter
parent 4a95e650
......@@ -6,6 +6,8 @@
*/
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\field\Entity\FieldStorageConfig;
/**
......@@ -134,3 +136,46 @@ function comment_update_8001() {
function comment_update_8002() {
// Empty update to cause a cache flush.
}
/**
* @addtogroup updates-8.2.x
* @{
*/
/**
* Add the 'view_mode' setting to displays having 'comment_default' formatter.
*/
function comment_update_8200() {
$config_factory = \Drupal::configFactory();
$displays = [];
// Iterate on all entity view displays.
foreach ($config_factory->listAll('core.entity_view_display.') as $name) {
$changed = FALSE;
$display = $config_factory->getEditable($name);
$components = $display->get('content') ?: [];
foreach ($components as $field_name => $component) {
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');
$displays[] = $display->get('id');
$changed = TRUE;
}
}
}
if ($changed) {
$display->save(TRUE);
}
}
if ($displays) {
return new PluralTranslatableMarkup(count($displays), '1 entity display updated: @displays.', '@count entity displays updated: @displays.', ['@displays' => implode(', ', $displays)]);
}
else {
return new TranslatableMarkup('No entity view display updated.');
}
}
/**
* @} End of "addtogroup updates-8.2.x".
*/
......@@ -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,43 @@ 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 it is using the comment view display '@display' (@mode) that was just disabled.", $arguments);
$changed = TRUE;
}
}
}
if ($changed) {
$view_display->save();
}
}
}
......@@ -4,6 +4,9 @@ field.formatter.settings.comment_default:
type: mapping
label: 'Comment display format settings'
mapping:
view_mode:
type: string
label: 'The comment entity view mode to be used in this formatter'
pager_id:
type: integer
label: 'Pager ID'
......
......@@ -3,6 +3,7 @@
namespace Drupal\comment\Plugin\Field\FieldFormatter;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityFormBuilderInterface;
use Drupal\Core\Field\FieldItemListInterface;
......@@ -36,6 +37,7 @@ class CommentDefaultFormatter extends FormatterBase implements ContainerFactoryP
*/
public static function defaultSettings() {
return array(
'view_mode' => 'default',
'pager_id' => 0,
) + parent::defaultSettings();
}
......@@ -167,7 +169,7 @@ 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);
$build = $this->viewBuilder->viewMultiple($comments, $this->getSetting('view_mode'));
$build['pager']['#type'] = 'pager';
// CommentController::commentPermalink() calculates the page number
// where a specific comment appears and does a subrequest pointing to
......@@ -217,6 +219,16 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element = array();
$view_modes = $this->getViewModes();
$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,
// Only show the select element when there are more than one options.
'#access' => count($view_modes) > 1,
];
$element['pager_id'] = array(
'#type' => 'select',
'#title' => $this->t('Pager ID'),
......@@ -231,13 +243,41 @@ 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'),
)));
$view_mode = $this->getSetting('view_mode');
$view_modes = $this->getViewModes();
$view_mode_label = isset($view_modes[$view_mode]) ? $view_modes[$view_mode] : 'default';
$summary = [$this->t('Comment view mode: @mode', ['@mode' => $view_mode_label])];
if ($pager_id = $this->getSetting('pager_id')) {
$summary[] = $this->t('Pager ID: @id', ['@id' => $pager_id]);
}
return $summary;
}
/**
* {@inheritdoc}
*/
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 */
if ($display = EntityViewDisplay::load("comment.$bundle.$mode")) {
$dependencies[$display->getConfigDependencyKey()][] = $display->getConfigDependencyName();
}
}
}
return array();
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'));
}
}
......@@ -5,6 +5,9 @@
use Drupal\comment\CommentManagerInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Entity\Comment;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\user\RoleInterface;
use Drupal\filter\Entity\FilterFormat;
......@@ -292,4 +295,53 @@ public function testAutoFilledHtmlSubject() {
$this->assertEqual('(No subject)', Comment::load(2)->getSubject());
}
/**
* Tests the comment formatter configured with a custom comment view mode.
*/
public function testViewMode() {
$this->drupalLogin($this->webUser);
$this->drupalGet($this->node->toUrl());
$comment_text = $this->randomMachineName();
// Post a comment.
$this->postComment($this->node, $comment_text);
// Comment displayed in 'default' display mode found and has body text.
$comment_element = $this->cssSelect('.comment-wrapper');
$this->assertTrue(!empty($comment_element));
$this->assertRaw('<p>' . $comment_text . '</p>');
// Create a new comment entity view mode.
$mode = Unicode::strtolower($this->randomMachineName());
EntityViewMode::create([
'targetEntityType' => 'comment',
'id' => "comment.$mode",
])->save();
// Create the corresponding entity view display for article node-type. Note
// that this new view display mode doesn't contain the comment body.
EntityViewDisplay::create([
'targetEntityType' => 'comment',
'bundle' => 'comment',
'mode' => $mode,
])->setStatus(TRUE)->save();
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $node_display */
$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.
$formatter['settings']['view_mode'] = $mode;
$node_display
->setComponent('comment', $formatter)
->save();
// Reloading the node page to show the same node with its same comment but
// with a different display mode.
$this->drupalGet($this->node->toUrl());
// The comment should exist but without the body text because we used $mode
// mode this time.
$comment_element = $this->cssSelect('.comment-wrapper');
$this->assertTrue(!empty($comment_element));
$this->assertNoRaw('<p>' . $comment_text . '</p>');
}
}
......@@ -283,6 +283,7 @@ function testTwoPagers() {
'weight' => 30,
'settings' => array(
'pager_id' => 1,
'view_mode' => 'default',
)
))
->save();
......
......@@ -29,8 +29,11 @@ trait CommentTestTrait {
* CommentItemInterface::OPEN.
* @param string $comment_type_id
* (optional) ID of comment type to use. Defaults to 'comment'.
* @param string $comment_view_mode
* (optional) The comment view mode to be used in comment field formatter.
* Defaults to 'full'.
*/
public function addDefaultCommentField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN, $comment_type_id = 'comment') {
public function addDefaultCommentField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN, $comment_type_id = 'comment', $comment_view_mode = 'full') {
$entity_manager = \Drupal::entityManager();
// Create the comment type if needed.
$comment_type_storage = $entity_manager->getStorage('comment_type');
......@@ -106,6 +109,7 @@ public function addDefaultCommentField($entity_type, $bundle, $field_name = 'com
'label' => 'above',
'type' => 'comment_default',
'weight' => 20,
'settings' => array('view_mode' => $comment_view_mode),
))
->save();
foreach ($entity_manager->getViewModes($entity_type) as $id => $view_mode) {
......
<?php
namespace Drupal\comment\Tests\Update;
use Drupal\system\Tests\Update\UpdatePathTestBase;
/**
* Tests that comment settings are properly updated during database updates.
*
* @group comment
*/
class CommentUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz',
];
}
/**
* Tests comment_update_8200().
*
* @see comment_update_8200()
*/
public function testCommentUpdate8101() {
// Load the 'node.article.default' entity view display config, and check
// that component 'comment' does not contain the 'view_mode' setting.
$config = $this->config('core.entity_view_display.node.article.default');
$this->assertNull($config->get('content.comment.settings.view_mode'));
// Load the 'node.forum.default' entity view display config, and check that
// component 'comment_forum' does not contain the 'view_mode' setting.
$config = $this->config('core.entity_view_display.node.forum.default');
$this->assertNull($config->get('content.comment_forum.settings.view_mode'));
// Run updates.
$this->runUpdates();
// Check that 'node.article.default' entity view display setting 'view_mode'
// has the value 'default'.
$config = $this->config('core.entity_view_display.node.article.default');
$this->assertIdentical($config->get('content.comment.settings.view_mode'), 'default');
// Check that 'node.forum.default' entity view display setting 'view_mode'
// has the value 'default'.
$config = $this->config('core.entity_view_display.node.forum.default');
$this->assertIdentical($config->get('content.comment_forum.settings.view_mode'), 'default');
}
}
<?php
namespace Drupal\Tests\comment\Kernel;
use Drupal\comment\Entity\CommentType;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Database\Database;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests integration of comment with other components.
*
* @group comment
*/
class CommentIntegrationTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['comment', 'field', 'entity_test', 'user', 'system', 'dblog'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->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 it is using the comment view display '@display' (@mode) that was just disabled.")
->condition('variables', serialize($arguments))
->execute()
->fetchField();
$this->assertTrue($logged);
// 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]);
}
}
......@@ -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
......@@ -26,6 +27,7 @@ content:
type: comment_default
weight: 20
settings:
view_mode: default
pager_id: 0
third_party_settings: { }
links:
......
......@@ -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
......@@ -25,10 +26,11 @@ content:
third_party_settings: { }
label: hidden
comment:
label: above
type: comment_default
weight: 20
weight: 110
label: above
settings:
view_mode: default
pager_id: 0
third_party_settings: { }
field_image:
......@@ -46,13 +48,6 @@ content:
settings:
link: true
third_party_settings: { }
comment:
label: above
type: comment_default
weight: 110
settings:
pager_id: 0
third_party_settings: { }
links:
weight: 100
hidden:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment