You are here

public function AjaxCommentsController::add in AJAX Comments 8

Builds ajax response for adding a new comment without a parent comment.

Parameters

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

\Drupal\Core\Entity\EntityInterface $entity: The entity this comment belongs to.

string $field_name: The field_name to which the comment belongs.

int $pid: (optional) Some comments are replies to other comments. In those cases, $pid is the parent comment's comment ID. Defaults to NULL.

Return value

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

See also

\Drupal\comment\Controller\CommentController::getReplyForm()

1 string reference to 'AjaxCommentsController::add'
ajax_comments.routing.yml in ./ajax_comments.routing.yml
ajax_comments.routing.yml

File

src/Controller/AjaxCommentsController.php, line 582

Class

AjaxCommentsController
Controller routines for AJAX comments routes.

Namespace

Drupal\ajax_comments\Controller

Code

public function add(Request $request, EntityInterface $entity, $field_name, $pid = NULL) {
  $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);

  // Check the user's access to reply.
  // The user should not have made it this far without proper permission,
  // but adding this access check as a fallback.
  $this
    ->replyAccess($request, $response, $entity, $field_name, $pid);

  // If $this->replyAccess() added any commands to the AjaxResponse,
  // it means that access was denied, so we should NOT submit the form
  // and rebuild the comment field. Just return the response with the
  // error message.
  if (!empty($response
    ->getCommands())) {
    return $response;
  }

  // Build the comment entity form.
  // This approach is very similar to the one taken in
  // \Drupal\comment\CommentLazyBuilders::renderForm().
  $comment = $this
    ->entityTypeManager()
    ->getStorage('comment')
    ->create([
    'entity_id' => $entity
      ->id(),
    'pid' => $pid,
    'entity_type' => $entity
      ->getEntityTypeId(),
    'field_name' => $field_name,
  ]);

  // Rebuild the form to trigger form submission.
  $form = $this
    ->entityFormBuilder()
    ->getForm($comment);

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

    // 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.
    $response = $this
      ->buildCommentFieldResponse($request, $response, $entity, $field_name);
  }
  else {

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

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

  // The form_html_id should have been updated by the form constructor when
  // $this->buildCommentFieldResponse() was called, so retrieve the updated
  // selector values for use in building the response.
  $selectors = $this->tempStore
    ->getSelectors($request);
  $form_html_id = $selectors['form_html_id'];

  // Prepend any status messages in the response.
  $response = $this
    ->addMessages($request, $response, $form_html_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;
}