You are here

public static function Utility::getWrapperIdFromEntity in AJAX Comments 8

Given an entity and the name of a comment field, return the wrapper id.

Using an entity with a comment field, and the machine name of the comment field, return the id attribute value of the wrapper element around the comment field, for use in ajax responses.

Parameters

\Drupal\Core\Entity\ContentEntityInterface $commented_entity: The entity that has the comment field being updated.

string $field_name: The machine name of the comment field.

Return value

string The value of the id attribute of the comment field wrapper element.

2 calls to Utility::getWrapperIdFromEntity()
AjaxCommentsForm::buildForm in src/Form/AjaxCommentsForm.php
Form constructor.
ajax_comments_comment_links_alter in ./ajax_comments.module
Implements hook_comment_links_alter().

File

src/Utility.php, line 96

Class

Utility
Provides various helper methods for Ajax Comments.

Namespace

Drupal\ajax_comments

Code

public static function getWrapperIdFromEntity(ContentEntityInterface $commented_entity, $field_name) {

  // Load the early-stage render array for the commented entity.
  $build = \Drupal::entityTypeManager()
    ->getViewBuilder($commented_entity
    ->getEntityTypeId())
    ->view($commented_entity, 'full');

  // First, attempt to retrieve the cached markup for the commented entity
  // and use a regular expression to get the id attribute value of the
  // wrapper element. This approach is necessary because Drupal will first
  // attempt to load the rendered field markup from cache and ignore any
  // render arrays generated during this HTTP response, so if markup is
  // returned from cache, the wrapper id will need to match the id attribute
  // in the returned markup.
  //
  // The following code block is adapted from
  // \Drupal\Core\Render\Renderer::doRender(). The code for loading the
  // markup from cache is not structured in a way that it can be called
  // independently, and attempting to call Renderer::doRender() directly
  // from this context results in an infinite loop, so the code needs to be
  // duplicated here.
  //
  // Try to fetch the prerendered element from cache,
  // replace any placeholders and return the final markup.
  if (isset($build['#cache']['keys'])) {
    $required_cache_contexts = \Drupal::getContainer()
      ->getParameter('renderer.config')['required_cache_contexts'];
    if (isset($build['#cache']['contexts'])) {
      $build['#cache']['contexts'] = Cache::mergeContexts($build['#cache']['contexts'], $required_cache_contexts);
    }
    else {
      $build['#cache']['contexts'] = $required_cache_contexts;
    }
    $cached_element = \Drupal::service('render_cache')
      ->get($build);
    if ($cached_element !== FALSE) {
      $build = $cached_element;

      // Mark the element markup as safe if is it a string.
      if (is_string($build['#markup'])) {
        $build['#markup'] = Markup::create($build['#markup']);
      }
    }
  }
  $matches = [];

  // If the cache returned markup, attempt to find the wrapper element id
  // attribute using a regular expression.
  if (isset($build['#markup'])) {

    // Generate the known, unchanging portion of the wrapper element id.
    $wrapper_html_id_prefix = Html::getId($commented_entity
      ->getEntityTypeId() . '-' . $commented_entity
      ->bundle() . '-' . $field_name);

    // Use regex to get the full wrapper id, using the known part of the id.
    preg_match('/\\sid="(' . $wrapper_html_id_prefix . '[^"]*)"/', $build['#markup']
      ->__toString(), $matches);
  }
  if (!empty($matches[1])) {
    $wrapper_html_id = $matches[1];
  }
  else {

    // If the field markup cannot be retrieved from cache, attempt to
    // retrieve the render array from the static variable on this class
    // or from the cache set by this class (both approaches are tried
    // in the method static::getEntityRenderArray()).
    $render_array = static::getEntityRenderArray($commented_entity, 'full');
    if (isset($render_array[$field_name])) {
      $wrapper_html_id = $render_array[$field_name]['#attributes']['id'];
    }
    else {

      // If the render array cannot be retrieved from the static variable or
      // the cache, generate it now and get the wrapper id from it.
      $render_array = $commented_entity
        ->get($field_name)
        ->view();
      $wrapper_html_id = $render_array['#attributes']['id'];
    }
  }
  return $wrapper_html_id;
}