Allow comment submission status messages and log messages to be overridden more easily in subclasses of CommentForm

Created on 15 July 2016, almost 8 years ago
Updated 30 January 2023, over 1 year ago

Problem/Motivation

It would be really nice if the logger messages and messages passed to drupal_set_message() in the \Drupal\comment\CommentForm::save() method were easier to override in classes that extend CommentForm.

For example, in \Drupal\comment\Form\DeleteForm, there are standalone methods in that form class, and in its parent classes, to return status messages and to insert messages into the logs:

  • ::getQuestion()
  • ::getDescription()
  • ::getDeletionMessage()
  • ::logDeletionMessage()

These helper methods are then used where needed in the form constructor and form submit handlers.

Example from \Drupal\Core\Entity\ContentEntityConfirmFormBase (a parent class of \Drupal\comment\Form\DeleteForm), which uses ::getQuestion() and ::getDescription():

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);

    $form['#title'] = $this->getQuestion();

    $form['#attributes']['class'][] = 'confirmation';
    $form['description'] = array('#markup' => $this->getDescription());
    $form[$this->getFormName()] = array('#type' => 'hidden', '#value' => 1);

    // By default, render the form using theme_confirm_form().
    if (!isset($form['#theme'])) {
      $form['#theme'] = 'confirm_form';
    }
    return $form;
  }

Example from \Drupal\Core\Entity\ContentEntityDeleteForm (a parent class of \Drupal\comment\Form\DeleteForm), which uses ::getDeletionMessage() and ::logDeletionMessage():

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $entity = $this->getEntity();

    // Make sure that deleting a translation does not delete the whole entity.
    if (!$entity->isDefaultTranslation()) {
      $untranslated_entity = $entity->getUntranslated();
      $untranslated_entity->removeTranslation($entity->language()->getId());
      $untranslated_entity->save();
      $form_state->setRedirectUrl($untranslated_entity->urlInfo('canonical'));
    }
    else {
      $entity->delete();
      $form_state->setRedirectUrl($this->getRedirectUrl());
    }

    drupal_set_message($this->getDeletionMessage());
    $this->logDeletionMessage();
  }

This approach makes it easy to extend the form class and just override the message text without having to duplicate the code of the entire submit handler method.

For the sake of completeness, here is how the custom child form class would be set as the handler for the comment entity type:

/**
 * Implements hook_entity_type_alter().
 */
function my_custom_comments_entity_type_alter(array &$entity_types) {
  $entity_types['comment']->setFormClass('delete', 'Drupal\my_custom_comments\Form\DeleteForm');
}

As it stands right now, the ::save() method on the default CommentForm doesn't make it easy to override the confirmation messages without reimplementing the whole method in a child class:

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $comment = $this->entity;
    $entity = $comment->getCommentedEntity();
    $field_name = $comment->getFieldName();
    $uri = $entity->urlInfo();
    $logger = $this->logger('content');

    if ($this->currentUser->hasPermission('post comments') && ($this->currentUser->hasPermission('administer comments') || $entity->{$field_name}->status == CommentItemInterface::OPEN)) {
      $comment->save();
      $form_state->setValue('cid', $comment->id());

      // Add a log entry.
      $logger->notice('Comment posted: %subject.', array(
          '%subject' => $comment->getSubject(),
          'link' => $this->l(t('View'), $comment->urlInfo()->setOption('fragment', 'comment-' . $comment->id()))
        ));

      // Explain the approval queue if necessary.
      if (!$comment->isPublished()) {
        if (!$this->currentUser->hasPermission('administer comments')) {
          drupal_set_message($this->t('Your comment has been queued for review by site administrators and will be published after approval.'));
        }
      }
      else {
        drupal_set_message($this->t('Your comment has been posted.'));
      }
      $query = array();
      // Find the current display page for this comment.
      $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$field_name];
      $page = $this->entityManager->getStorage('comment')->getDisplayOrdinal($comment, $field_definition->getSetting('default_mode'), $field_definition->getSetting('per_page'));
      if ($page > 0) {
        $query['page'] = $page;
      }
      // Redirect to the newly posted comment.
      $uri->setOption('query', $query);
      $uri->setOption('fragment', 'comment-' . $comment->id());
    }
    else {
      $logger->warning('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->getSubject()));
      drupal_set_message($this->t('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->getSubject())), 'error');
      // Redirect the user to the entity they are commenting on.
    }
    $form_state->setRedirectUrl($uri);
  }

Proposed resolution

Patch file attached that adds helper methods that supply the content for status messages and that write messages to the logs.

Remaining tasks

Needs community review and feedback.

User interface changes

None.

API changes

Exposes additional helper methods in the CommentForm class that child classes can override.

Data model changes

None.

✨ Feature request
Status

Needs work

Version

10.1 ✨

Component
CommentΒ  β†’

Last updated 2 days ago

Created by

πŸ‡ΊπŸ‡ΈUnited States danmuzyka

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • The Needs Review Queue Bot β†’ tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

    Consult the Drupal Contributor Guide β†’ to find step-by-step guides for working with issues.

Production build 0.69.0 2024