diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml index 7c31ccbba9..b866db5eb3 100644 --- a/core/modules/comment/config/schema/comment.schema.yml +++ b/core/modules/comment/config/schema/comment.schema.yml @@ -17,6 +17,12 @@ field.formatter.settings.comment_default: pager_id: type: integer label: 'Pager ID' + language_filter: + type: sequence + label: 'Filter comments by language' + sequence: + type: string + label: 'Language' field.widget.settings.comment_default: type: mapping diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php index 2334e59220..6e10f91b1a 100644 --- a/core/modules/comment/src/CommentStorage.php +++ b/core/modules/comment/src/CommentStorage.php @@ -271,7 +271,7 @@ public function getChildCids(array $comments) { * spoil the reverse ordering, "ORDER BY thread ASC" -- here, we do not need * to consider the trailing "/" so we use a substring only. */ - public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0) { + public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0, array $langcodes = []) { $data_table = $this->getDataTable(); $query = $this->database->select($data_table, 'c'); $query->addField('c', 'cid'); @@ -308,6 +308,13 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment $query->setCountQuery($count_query); } + if (!empty($langcodes)) { + $query->condition('c.langcode', $langcodes, 'IN'); + if ($comments_per_page) { + $count_query->condition('c.langcode', $langcodes, 'IN'); + } + } + if (!$this->currentUser->hasPermission('administer comments')) { $query->condition('c.status', CommentInterface::PUBLISHED); if ($comments_per_page) { diff --git a/core/modules/comment/src/CommentStorageInterface.php b/core/modules/comment/src/CommentStorageInterface.php index 592b1ea921..4d6b8db654 100644 --- a/core/modules/comment/src/CommentStorageInterface.php +++ b/core/modules/comment/src/CommentStorageInterface.php @@ -97,11 +97,13 @@ public function getChildCids(array $comments); * @param int $pager_id * (optional) Pager id to use in case of multiple pagers on the one page. * Defaults to 0; is only used when $comments_per_page is greater than zero. + * @param array $langcodes + * (optional) Only fetch comments in the specified languages. * * @return array * Ordered array of comment objects, keyed by comment id. */ - public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0); + public function loadThread(EntityInterface $entity, $field_name, $mode, $comments_per_page = 0, $pager_id = 0, array $langcodes = []); /** * Returns the number of unapproved comments. diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index 35ce99b7eb..ec8a737d00 100644 --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -9,6 +9,8 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Language\LanguageInterface; +use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FormatterBase; @@ -39,6 +41,7 @@ public static function defaultSettings() { return [ 'view_mode' => 'default', 'pager_id' => 0, + 'language_filter' => [], ] + parent::defaultSettings(); } @@ -82,6 +85,20 @@ public static function defaultSettings() { */ protected $routeMatch; + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * Stores the language options for the language filter setting. + * + * @var array + */ + protected $languageOptions; + /** * {@inheritdoc} */ @@ -98,6 +115,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('entity.form_builder'), $container->get('current_route_match'), + $container->get('language_manager'), $container->get('entity_display.repository') ); } @@ -127,16 +145,19 @@ public static function create(ContainerInterface $container, array $configuratio * The entity form builder. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match object. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager object. * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository * The entity display repository. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, EntityFormBuilderInterface $entity_form_builder, RouteMatchInterface $route_match, EntityDisplayRepositoryInterface $entity_display_repository) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, EntityFormBuilderInterface $entity_form_builder, RouteMatchInterface $route_match, LanguageManagerInterface $language_manager, EntityDisplayRepositoryInterface $entity_display_repository) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); $this->viewBuilder = $entity_type_manager->getViewBuilder('comment'); $this->storage = $entity_type_manager->getStorage('comment'); $this->currentUser = $current_user; $this->entityFormBuilder = $entity_form_builder; $this->routeMatch = $route_match; + $this->languageManager = $language_manager; $this->entityDisplayRepository = $entity_display_repository; } @@ -170,7 +191,23 @@ public function viewElements(FieldItemListInterface $items, $langcode) { if ($entity->get($field_name)->comment_count || $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')); + + $langcodes = []; + $language_ids = $this->getSetting('language_filter'); + if (!empty($language_ids)) { + foreach ($language_ids as $language_id) { + if (!$language_id) { + continue; + } + // Use the interface language for filtering. + if ($language_id === LanguageInterface::TYPE_INTERFACE) { + $language_id = $langcode; + } + $langcodes[] = $language_id; + } + } + + $comments = $this->storage->loadThread($entity, $field_name, $mode, $comments_per_page, $this->getSetting('pager_id'), $langcodes); if ($comments) { $build = $this->viewBuilder->viewMultiple($comments, $this->getSetting('view_mode')); $build['pager']['#type'] = 'pager'; @@ -242,6 +279,13 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#default_value' => $this->getSetting('pager_id'), '#description' => $this->t("Unless you're experiencing problems with pagers related to this field, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."), ]; + $element['language_filter'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('Filter by language'), + '#options' => $this->getLanguageOptions(), + '#default_value' => $this->getSetting('language_filter'), + '#description' => $this->t('Show comments in the selected languages. If none selected, all comments will be showed.'), + ]; return $element; } @@ -256,9 +300,30 @@ public function settingsSummary() { if ($pager_id = $this->getSetting('pager_id')) { $summary[] = $this->t('Pager ID: @id', ['@id' => $pager_id]); } + if (!empty($this->getSetting('language_filter'))) { + $language_filter = array_intersect_key($this->getLanguageOptions(), array_flip($this->getSetting('language_filter'))); + $summary[] = $this->t('Show comments in the following languages: @languages', ['@languages' => implode(', ', $language_filter)]); + } return $summary; } + /** + * Get a list of language options for the language_filter setting. + * + * @return array + * All available language options. + */ + protected function getLanguageOptions() { + if (!isset($this->languageOptions)) { + $this->languageOptions[LanguageInterface::TYPE_INTERFACE] = $this->t('Interface text language selected for page'); + $languages = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL); + foreach ($languages as $langcode => $language) { + $this->languageOptions[$langcode] = $language->getName(); + } + } + return $this->languageOptions; + } + /** * {@inheritdoc} */