You are here

public function AjaxCommentsController::save in AJAX Comments 8

Submit handler for the comment reply and edit forms.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The current request object.

\Drupal\comment\CommentInterface $comment: The comment entity.

Return value

\Drupal\Core\Ajax\AjaxResponse The Ajax response.

1 call to AjaxCommentsController::save()
AjaxCommentsController::saveReply in src/Controller/AjaxCommentsController.php
Builds ajax response to save a submitted reply to another comment.
1 string reference to 'AjaxCommentsController::save'
ajax_comments.routing.yml in ./ajax_comments.routing.yml
ajax_comments.routing.yml

File

src/Controller/AjaxCommentsController.php, line 372

Class

AjaxCommentsController
Controller routines for AJAX comments routes.

Namespace

Drupal\ajax_comments\Controller

Code

public function save(Request $request, CommentInterface $comment) {
  $response = new AjaxResponse();

  // Store the selectors from the incoming request, if applicable.
  // If the selectors are not in the request, the stored ones will
  // not be overwritten.
  $this->tempStore
    ->getSelectors($request, $overwrite = TRUE);

  // Rebuild the form to trigger form submission.
  $form = $this
    ->entityFormBuilder()
    ->getForm($comment, 'default', [
    'editing' => TRUE,
  ]);

  // Check for errors.
  if (empty($this->messenger
    ->messagesByType('error'))) {
    $errors = FALSE;

    // If there are no errors, set the ajax-updated
    // selector value for the form.
    $this->tempStore
      ->setSelector('form_html_id', $form['#attributes']['id']);

    // Build the updated comment field and insert into a replaceWith
    // response. Also prepend any status messages in the response.
    $response = $this
      ->buildCommentFieldResponse($request, $response, $comment
      ->getCommentedEntity(), $comment
      ->get('field_name')->value);
  }
  else {
    $errors = TRUE;

    // Retrieve the selector values for use in building the response.
    $selectors = $this->tempStore
      ->getSelectors($request, $overwrite = TRUE);
    $wrapper_html_id = $selectors['wrapper_html_id'];
    $form_html_id = $selectors['form_html_id'];

    // If there are errors, remove old messages and reload the form.
    $response
      ->addCommand(new RemoveCommand($wrapper_html_id . ' .js-ajax-comments-messages'));
    $response
      ->addCommand(new ReplaceCommand($form_html_id, $form));
  }

  // If this is a new comment being added from this method, it is being
  // inserted as a reply to another comment, and there is no $comment->id()
  // yet. Insert the message after the parent comment instead.
  if ($comment
    ->isNew()) {

    // Retrieve the comment id of the new comment, which was saved in
    // AjaxCommentsForm::save() during the previous HTTP request.
    $cid = $this->tempStore
      ->getCid();

    // Try to insert the message above the new comment.
    if (!empty($cid) && !$errors && \Drupal::currentUser()
      ->hasPermission('skip comment approval')) {
      $selector = static::getCommentSelectorPrefix() . $cid;
      $response = $this
        ->addMessages($request, $response, $selector, 'before');
    }
    else {
      $response = $this
        ->addMessages($request, $response, static::getCommentSelectorPrefix() . $comment
        ->get('pid')->target_id, 'after');
    }
  }
  else {
    $response = $this
      ->addMessages($request, $response, static::getCommentSelectorPrefix() . $comment
      ->id(), 'before');
  }

  // Clear out the tempStore variables.
  $this->tempStore
    ->deleteAll();

  // Remove the libraries from the response, otherwise when
  // core/misc/drupal.js is reinserted into the DOM, the following line of
  // code will execute, causing Drupal.attachBehaviors() to run on the entire
  // document, and reattach behaviors to DOM elements that already have them:
  // @code
  // // Attach all behaviors.
  // domready(function () { Drupal.attachBehaviors(document, drupalSettings); });
  // @endcode
  $attachments = $response
    ->getAttachments();

  // Need to have only 'core/drupalSettings' in the asset library list.
  // If neither 'core/drupalSettings', nor a library with a dependency on it,
  // is in the list of libraries, drupalSettings will be stripped out of the
  // ajax response by \Drupal\Core\Asset\AssetResolver::getJsAssets().
  $attachments['library'] = [
    'core/drupalSettings',
  ];

  // We need to keep the drupalSettings in the response, otherwise the
  // #ajax properties in the form definition won't be properly attached to
  // the rebuilt comment field returned in the ajax response, and subsequent
  // ajax interactions will be broken.
  $response
    ->setAttachments($attachments);
  return $response;
}