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.