diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml index a90f410..c793cf4 100644 --- a/core/modules/comment/comment.routing.yml +++ b/core/modules/comment/comment.routing.yml @@ -2,7 +2,7 @@ comment.admin: path: '/admin/content/comment' defaults: _title: 'Comments' - _controller: '\Drupal\comment\Controller\AdminController::adminPage' + _form: 'Drupal\comment\Form\CommentAdminOverview' type: 'new' requirements: _permission: 'administer comments' @@ -11,7 +11,7 @@ comment.admin_approval: path: '/admin/content/comment/approval' defaults: _title: 'Unapproved comments' - _controller: '\Drupal\comment\Controller\AdminController::adminPage' + _form: 'Drupal\comment\Form\CommentAdminOverview' type: 'approval' requirements: _permission: 'administer comments' @@ -50,6 +50,14 @@ entity.comment.delete_form: requirements: _entity_access: 'comment.delete' +comment.multiple_delete_confirm: + path: '/admin/content/comment/delete' + defaults: + _title: 'Delete' + _form: '\Drupal\comment\Form\ConfirmDeleteMultiple' + requirements: + _permission: 'administer comments' + comment.reply: path: '/comment/reply/{entity_type}/{entity}/{field_name}/{pid}' defaults: diff --git a/core/modules/comment/config/install/system.action.comment_delete_action.yml b/core/modules/comment/config/install/system.action.comment_delete_action.yml new file mode 100644 index 0000000..5034172 --- /dev/null +++ b/core/modules/comment/config/install/system.action.comment_delete_action.yml @@ -0,0 +1,7 @@ +id: comment_delete_action +label: 'Delete comment' +status: true +langcode: en +type: comment +plugin: comment_delete_action +configuration: { } diff --git a/core/modules/comment/config/install/views.view.comment.yml b/core/modules/comment/config/install/views.view.comment.yml new file mode 100644 index 0000000..945d07c --- /dev/null +++ b/core/modules/comment/config/install/views.view.comment.yml @@ -0,0 +1,419 @@ +langcode: en +status: true +dependencies: + module: + - comment + - user +id: comment +label: Comments +module: comment +description: 'Find and manage comments.' +tag: '' +base_table: comment +base_field: cid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 1 + display_options: + access: + type: perm + options: + perm: 'administer comments' + cache: + type: none + query: + type: views_query + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 50 + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + comment_bulk_form: comment_bulk_form + subject: subject + name: name + title: title + changed: changed + edit_comment: edit_comment + delete_comment: delete_comment + dropbutton: dropbutton + info: + comment_bulk_form: + align: '' + separator: '' + empty_column: false + responsive: '' + subject: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + name: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: priority-medium + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: priority-low + edit_comment: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + delete_comment: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + dropbutton: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: changed + empty_table: false + row: + type: fields + fields: + comment_bulk_form: + id: comment_bulk_form + table: comment + field: comment_bulk_form + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + action_title: 'Update Options' + include_exclude: include + selected_actions: + - comment_delete_action + - comment_unpublish_action + plugin_id: comment_bulk_form + entity_type: comment + subject: + id: subject + table: comment_field_data + field: subject + group_type: group + admin_label: '' + label: Title + exclude: false + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_comment: true + link_to_entity: false + entity_type: comment + entity_field: subject + plugin_id: comment + name: + id: name + table: comment_field_data + field: name + group_type: group + admin_label: '' + label: Author + exclude: false + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_user: true + entity_type: comment + entity_field: name + plugin_id: comment_username + changed: + id: changed + table: comment_field_data + field: changed + group_type: group + admin_label: '' + label: Updated + exclude: false + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: fallback + custom_date_format: '' + timezone: '' + entity_type: comment + entity_field: changed + plugin_id: date + edit_comment: + id: edit_comment + table: comment + field: edit_comment + group_type: group + admin_label: '' + label: '' + exclude: true + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + text: edit + link_to_entity: false + destination: false + plugin_id: comment_link_edit + entity_type: comment + delete_comment: + id: delete_comment + table: comment + field: delete_comment + group_type: group + admin_label: '' + label: '' + exclude: true + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + text: delete + link_to_entity: false + plugin_id: comment_link_delete + entity_type: comment + dropbutton: + id: dropbutton + table: views + field: dropbutton + group_type: group + admin_label: '' + label: Operations + exclude: false + alter: + alter_text: false + element_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + fields: + edit_comment: edit_comment + delete_comment: delete_comment + action_bulk_form: '0' + subject: '0' + name: '0' + changed: '0' + destination: true + plugin_id: dropbutton + entity_type: comment + filters: + status: + id: status + table: comment_field_data + field: status + group_type: group + admin_label: '' + operator: '=' + value: true + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: comment + entity_field: status + plugin_id: boolean + sorts: + changed: + id: changed + table: comment_field_data + field: changed + group_type: group + admin_label: '' + order: DESC + exposed: false + expose: + label: '' + granularity: second + entity_type: comment + entity_field: changed + plugin_id: date + title: Comments + header: { } + footer: { } + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + empty: true + content: 'No comments available.' + plugin_id: text_custom + arguments: { } + display_extenders: { } + field_langcode: '***LANGUAGE_language_content***' + field_langcode_add_to_query: null + page_1: + display_plugin: page + id: page_1 + display_title: 'Published Comments' + position: 1 + display_options: + path: admin/content/comment + menu: + type: tab + title: Comments + description: 'Comments published' + weight: 0 + context: '0' + menu_name: admin + display_description: '' + display_extenders: { } + field_langcode: '***LANGUAGE_language_content***' + field_langcode_add_to_query: null + page_2: + display_plugin: page + id: page_2 + display_title: 'Unapproved Comments' + position: 2 + display_options: + path: admin/content/comment/approval + menu: + type: tab + title: 'Unapproved comments' + description: 'Comments unapproved' + weight: 1 + menu_name: admin + context: '0' + display_description: '' + filters: + status: + id: status + table: comment_field_data + field: status + group_type: group + admin_label: '' + operator: '=' + value: false + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: comment + entity_field: status + plugin_id: boolean + defaults: + filters: false + filter_groups: false + fields: true + filter_groups: + operator: AND + groups: + 1: AND + display_extenders: { } + field_langcode: '***LANGUAGE_language_content***' + field_langcode_add_to_query: null diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml index 9dd0aa5..8cafba3 100644 --- a/core/modules/comment/config/schema/comment.schema.yml +++ b/core/modules/comment/config/schema/comment.schema.yml @@ -102,3 +102,7 @@ field.field_settings.comment: preview: type: integer label: 'Preview comment' + +action.configuration.comment_delete_action: + type: action_configuration_default + label: 'Delete comment configuration' diff --git a/core/modules/comment/config/schema/comment.views.schema.yml b/core/modules/comment/config/schema/comment.views.schema.yml index 51953ad..bfd62de 100644 --- a/core/modules/comment/config/schema/comment.views.schema.yml +++ b/core/modules/comment/config/schema/comment.views.schema.yml @@ -27,6 +27,10 @@ views.field.comment_entity_link: type: boolean label: 'Show teaser-style link' +views.field.comment_bulk_form: + type: views_field_bulk_form + label: 'Comment bulk form' + views.field.comment_last_timestamp: type: views.field.date label: 'Last comment date' @@ -36,10 +40,10 @@ views.field.comment_link: label: 'Comment link' mapping: text: - type: views_field + type: label label: 'Text to display' link_to_entity: - type: views_field + type: boolean label: 'Link field to the entity if there is no comment' views.field.comment_link_approve: diff --git a/core/modules/comment/src/CommentViewsData.php b/core/modules/comment/src/CommentViewsData.php index 2a7083c..968b462 100644 --- a/core/modules/comment/src/CommentViewsData.php +++ b/core/modules/comment/src/CommentViewsData.php @@ -148,6 +148,14 @@ public function getViewsData() { ), ); + $data['comment']['comment_bulk_form'] = array( + 'title' => t('Comment operations bulk form'), + 'help' => t('Add a form element that lets you run operations on multiple comments.'), + 'field' => array( + 'id' => 'comment_bulk_form', + ), + ); + $data['comment_field_data']['thread']['field'] = array( 'title' => t('Depth'), 'help' => t('Display the depth of the comment if it is threaded.'), diff --git a/core/modules/comment/src/Controller/AdminController.php b/core/modules/comment/src/Controller/AdminController.php index 4c1592f..76becb8 100644 --- a/core/modules/comment/src/Controller/AdminController.php +++ b/core/modules/comment/src/Controller/AdminController.php @@ -10,6 +10,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; +use Drupal\comment\CommentManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -18,32 +19,29 @@ class AdminController extends ControllerBase { /** - * The form builder. + * Constructs an AdminController object. * - * @var \Drupal\Core\Form\FormBuilderInterface + * @param \Drupal\comment\CommentManagerInterface $comment_manager + * The comment manager service. + * @param \Drupal\Core\Form\FormBuilderInterface $form_builder + * The form builder. */ - protected $formBuilder; + public function __construct(CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) { + $this->commentManager = $comment_manager; + $this->formBuilder = $form_builder; + } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( + $container->get('comment.manager'), $container->get('form_builder') ); } /** - * Constructs an AdminController object. - * - * @param \Drupal\Core\Form\FormBuilderInterface $form_builder - * The form builder. - */ - public function __construct(FormBuilderInterface $form_builder) { - $this->formBuilder = $form_builder; - } - - /** * Presents an administrative comment listing. * * @param \Symfony\Component\HttpFoundation\Request $request diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php index 4abff68..fb6fbb2 100644 --- a/core/modules/comment/src/Form/CommentAdminOverview.php +++ b/core/modules/comment/src/Form/CommentAdminOverview.php @@ -9,6 +9,8 @@ use Drupal\comment\CommentInterface; use Drupal\comment\CommentStorageInterface; +use Drupal\Core\Cache\Cache; +use Drupal\user\TempStoreFactory; use Drupal\Component\Utility\Unicode; use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Entity\EntityManagerInterface; @@ -52,6 +54,13 @@ class CommentAdminOverview extends FormBase { protected $moduleHandler; /** + * The tempstore factory. + * + * @var \Drupal\user\TempStoreFactory + */ + protected $tempStoreFactory; + + /** * Creates a CommentAdminOverview form. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager @@ -62,12 +71,15 @@ class CommentAdminOverview extends FormBase { * The date formatter service. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. + * @param \Drupal\user\TempStoreFactory $temp_store_factory + * The tempstore factory. */ - public function __construct(EntityManagerInterface $entity_manager, CommentStorageInterface $comment_storage, DateFormatter $date_formatter, ModuleHandlerInterface $module_handler) { + public function __construct(EntityManagerInterface $entity_manager, CommentStorageInterface $comment_storage, DateFormatter $date_formatter, ModuleHandlerInterface $module_handler, TempStoreFactory $temp_store_factory) { $this->entityManager = $entity_manager; $this->commentStorage = $comment_storage; $this->dateFormatter = $date_formatter; $this->moduleHandler = $module_handler; + $this->tempStoreFactory = $temp_store_factory; } /** @@ -78,7 +90,8 @@ public static function create(ContainerInterface $container) { $container->get('entity.manager'), $container->get('entity.manager')->getStorage('comment'), $container->get('date.formatter'), - $container->get('module_handler') + $container->get('module_handler'), + $container->get('user.tempstore') ); } @@ -262,23 +275,33 @@ public function validateForm(array &$form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { $operation = $form_state->getValue('operation'); $cids = $form_state->getValue('comments'); - - foreach ($cids as $cid) { - // Delete operation handled in \Drupal\comment\Form\ConfirmDeleteMultiple - // see \Drupal\comment\Controller\AdminController::adminPage(). - if ($operation == 'unpublish') { - $comment = $this->commentStorage->load($cid); - $comment->setPublished(FALSE); - $comment->save(); - } - elseif ($operation == 'publish') { - $comment = $this->commentStorage->load($cid); - $comment->setPublished(TRUE); - $comment->save(); + if ($operation != 'delete') { + foreach ($cids as $cid) { + // Delete operation handled in + // \Drupal\comment\Form\ConfirmDeleteMultiple + // @see \Drupal\comment\Controller\AdminController::adminPage(). + if ($operation == 'unpublish') { + $comment = $this->commentStorage->load($cid); + $comment->setPublished(FALSE); + $comment->save(); + } + elseif ($operation == 'publish') { + $comment = $this->commentStorage->load($cid); + $comment->setPublished(TRUE); + $comment->save(); + } } + drupal_set_message($this->t('The update has been performed.')); + $form_state->setRedirect('comment.admin'); + Cache::invalidateTags(['content']); + } + else { + $this->tempStoreFactory + ->get('comment_multiple_delete_confirm') + ->set($this->currentUser()->id(), + $this->commentStorage->loadMultiple($cids)); + $form_state->setRedirect('comment.multiple_delete_confirm'); } - drupal_set_message($this->t('The update has been performed.')); - $form_state->setRedirect('comment.admin'); } } diff --git a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php index f6c8a6e..fcbb886 100644 --- a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php +++ b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php @@ -8,10 +8,12 @@ namespace Drupal\comment\Form; use Drupal\comment\CommentStorageInterface; +use Drupal\user\TempStoreFactory; use Drupal\Component\Utility\String; use Drupal\Core\Form\ConfirmFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -20,6 +22,13 @@ class ConfirmDeleteMultiple extends ConfirmFormBase { /** + * The tempstore factory. + * + * @var \Drupal\user\TempStoreFactory + */ + protected $tempStoreFactory; + + /** * The comment storage. * * @var \Drupal\comment\CommentStorageInterface @@ -38,9 +47,12 @@ class ConfirmDeleteMultiple extends ConfirmFormBase { * * @param \Drupal\comment\CommentStorageInterface $comment_storage * The comment storage. + * @param \Drupal\user\TempStoreFactory $temp_store_factory + * The tempstore factory. */ - public function __construct(CommentStorageInterface $comment_storage) { + public function __construct(CommentStorageInterface $comment_storage, TempStoreFactory $temp_store_factory) { $this->commentStorage = $comment_storage; + $this->tempStoreFactory = $temp_store_factory; } /** @@ -48,7 +60,8 @@ public function __construct(CommentStorageInterface $comment_storage) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('entity.manager')->getStorage('comment') + $container->get('entity.manager')->getStorage('comment'), + $container->get('user.tempstore') ); } @@ -63,7 +76,7 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to delete these comments and all their children?'); + return $this->formatPlural(count($this->comments), 'Are you sure you want to delete this comment and all its children?', 'Are you sure you want to delete these comments and all their children?'); } /** @@ -77,23 +90,24 @@ public function getCancelUrl() { * {@inheritdoc} */ public function getConfirmText() { - return $this->t('Delete comments'); + return $this->t('Delete'); } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $edit = $form_state->getUserInput(); + $this->comments = $this->tempStoreFactory->get('comment_multiple_delete_confirm')->get($this->currentUser()->id()); + if (empty($this->comments)) { + return $this->redirect('comment.admin'); + } $form['comments'] = array( '#prefix' => '