3 namespace Drupal\comment\Form;
5 use Drupal\comment\CommentInterface;
6 use Drupal\Component\Utility\Unicode;
7 use Drupal\Core\Datetime\DateFormatterInterface;
8 use Drupal\Core\Entity\EntityTypeManagerInterface;
9 use Drupal\Core\Extension\ModuleHandlerInterface;
10 use Drupal\Core\Form\FormBase;
11 use Drupal\Core\Form\FormStateInterface;
12 use Drupal\Core\TempStore\PrivateTempStoreFactory;
13 use Symfony\Component\DependencyInjection\ContainerInterface;
16 * Provides the comments overview administration form.
20 class CommentAdminOverview extends FormBase {
23 * The entity type manager.
25 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
27 protected $entityTypeManager;
30 * The comment storage.
32 * @var \Drupal\comment\CommentStorageInterface
34 protected $commentStorage;
37 * The date formatter service.
39 * @var \Drupal\Core\Datetime\DateFormatterInterface
41 protected $dateFormatter;
46 * @var \Drupal\Core\Extension\ModuleHandlerInterface
48 protected $moduleHandler;
51 * The tempstore factory.
53 * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
55 protected $tempStoreFactory;
58 * Creates a CommentAdminOverview form.
60 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
61 * The entity manager service.
62 * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
63 * The date formatter service.
64 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
66 * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
67 * The tempstore factory.
69 public function __construct(EntityTypeManagerInterface $entity_type_manager, DateFormatterInterface $date_formatter, ModuleHandlerInterface $module_handler, PrivateTempStoreFactory $temp_store_factory) {
70 $this->entityTypeManager = $entity_type_manager;
71 $this->commentStorage = $entity_type_manager->getStorage('comment');
72 $this->dateFormatter = $date_formatter;
73 $this->moduleHandler = $module_handler;
74 $this->tempStoreFactory = $temp_store_factory;
80 public static function create(ContainerInterface $container) {
82 $container->get('entity_type.manager'),
83 $container->get('date.formatter'),
84 $container->get('module_handler'),
85 $container->get('tempstore.private')
92 public function getFormId() {
93 return 'comment_admin_overview';
97 * Form constructor for the comment overview administration form.
100 * An associative array containing the structure of the form.
101 * @param \Drupal\Core\Form\FormStateInterface $form_state
102 * The current state of the form.
103 * @param string $type
104 * The type of the overview form ('approval' or 'new').
107 * The form structure.
109 public function buildForm(array $form, FormStateInterface $form_state, $type = 'new') {
111 // Build an 'Update options' form.
113 '#type' => 'details',
114 '#title' => $this->t('Update options'),
116 '#attributes' => ['class' => ['container-inline']],
119 if ($type == 'approval') {
120 $options['publish'] = $this->t('Publish the selected comments');
123 $options['unpublish'] = $this->t('Unpublish the selected comments');
125 $options['delete'] = $this->t('Delete the selected comments');
127 $form['options']['operation'] = [
129 '#title' => $this->t('Action'),
130 '#title_display' => 'invisible',
131 '#options' => $options,
132 '#default_value' => 'publish',
134 $form['options']['submit'] = [
136 '#value' => $this->t('Update'),
139 // Load the comments that need to be displayed.
140 $status = ($type == 'approval') ? CommentInterface::NOT_PUBLISHED : CommentInterface::PUBLISHED;
143 'data' => $this->t('Subject'),
144 'specifier' => 'subject',
147 'data' => $this->t('Author'),
148 'specifier' => 'name',
149 'class' => [RESPONSIVE_PRIORITY_MEDIUM],
152 'data' => $this->t('Posted in'),
153 'class' => [RESPONSIVE_PRIORITY_LOW],
156 'data' => $this->t('Updated'),
157 'specifier' => 'changed',
159 'class' => [RESPONSIVE_PRIORITY_LOW],
161 'operations' => $this->t('Operations'),
163 $cids = $this->commentStorage->getQuery()
164 ->condition('status', $status)
169 /** @var $comments \Drupal\comment\CommentInterface[] */
170 $comments = $this->commentStorage->loadMultiple($cids);
172 // Build a table listing the appropriate comments.
174 $destination = $this->getDestinationArray();
176 $commented_entity_ids = [];
177 $commented_entities = [];
179 foreach ($comments as $comment) {
180 $commented_entity_ids[$comment->getCommentedEntityTypeId()][] = $comment->getCommentedEntityId();
183 foreach ($commented_entity_ids as $entity_type => $ids) {
184 $commented_entities[$entity_type] = $this->entityTypeManager
185 ->getStorage($entity_type)
186 ->loadMultiple($ids);
189 foreach ($comments as $comment) {
190 /** @var $commented_entity \Drupal\Core\Entity\EntityInterface */
191 $commented_entity = $commented_entities[$comment->getCommentedEntityTypeId()][$comment->getCommentedEntityId()];
192 $comment_permalink = $comment->permalink();
193 if ($comment->hasField('comment_body') && ($body = $comment->get('comment_body')->value)) {
194 $attributes = $comment_permalink->getOption('attributes') ?: [];
195 $attributes += ['title' => Unicode::truncate($body, 128)];
196 $comment_permalink->setOption('attributes', $attributes);
198 $options[$comment->id()] = [
199 'title' => ['data' => ['#title' => $comment->getSubject() ?: $comment->id()]],
203 '#title' => $comment->getSubject(),
204 '#url' => $comment_permalink,
209 '#theme' => 'username',
210 '#account' => $comment->getOwner(),
216 '#title' => $commented_entity->label(),
217 '#access' => $commented_entity->access('view'),
218 '#url' => $commented_entity->urlInfo(),
221 'changed' => $this->dateFormatter->format($comment->getChangedTimeAcrossTranslations(), 'short'),
223 $comment_uri_options = $comment->urlInfo()->getOptions() + ['query' => $destination];
226 'title' => $this->t('Edit'),
227 'url' => $comment->urlInfo('edit-form', $comment_uri_options),
229 if ($this->moduleHandler->moduleExists('content_translation') && $this->moduleHandler->invoke('content_translation', 'translate_access', [$comment])->isAllowed()) {
230 $links['translate'] = [
231 'title' => $this->t('Translate'),
232 'url' => $comment->urlInfo('drupal:content-translation-overview', $comment_uri_options),
235 $options[$comment->id()]['operations']['data'] = [
236 '#type' => 'operations',
241 $form['comments'] = [
242 '#type' => 'tableselect',
243 '#header' => $header,
244 '#options' => $options,
245 '#empty' => $this->t('No comments available.'),
248 $form['pager'] = ['#type' => 'pager'];
256 public function validateForm(array &$form, FormStateInterface $form_state) {
257 $form_state->setValue('comments', array_diff($form_state->getValue('comments'), [0]));
258 // We can't execute any 'Update options' if no comments were selected.
259 if (count($form_state->getValue('comments')) == 0) {
260 $form_state->setErrorByName('', $this->t('Select one or more comments to perform the update on.'));
267 public function submitForm(array &$form, FormStateInterface $form_state) {
268 $operation = $form_state->getValue('operation');
269 $cids = $form_state->getValue('comments');
270 /** @var \Drupal\comment\CommentInterface[] $comments */
271 $comments = $this->commentStorage->loadMultiple($cids);
272 if ($operation != 'delete') {
273 foreach ($comments as $comment) {
274 if ($operation == 'unpublish') {
275 $comment->setUnpublished();
277 elseif ($operation == 'publish') {
278 $comment->setPublished();
282 $this->messenger()->addStatus($this->t('The update has been performed.'));
283 $form_state->setRedirect('comment.admin');
287 /** @var \Drupal\comment\CommentInterface $comment */
288 foreach ($comments as $comment) {
289 $langcode = $comment->language()->getId();
290 $info[$comment->id()][$langcode] = $langcode;
292 $this->tempStoreFactory
293 ->get('entity_delete_multiple_confirm')
294 ->set($this->currentUser()->id() . ':comment', $info);
295 $form_state->setRedirect('entity.comment.delete_multiple_form');