You are here

public function CommentLinkBuilder::buildCommentedEntityLinks in Comment Permissions 8

Builds links for the given entity.

Parameters

\Drupal\Core\Entity\FieldableEntityInterface $entity: Entity for which the links are being built.

array $context: Array of context passed from the entity view builder.

Return value

array Array of entity links.

Overrides CommentLinkBuilder::buildCommentedEntityLinks

File

src/CommentLinkBuilder.php, line 21

Class

CommentLinkBuilder
Overrides Comment link builder class.

Namespace

Drupal\comment_perm

Code

public function buildCommentedEntityLinks(FieldableEntityInterface $entity, array &$context) {
  $entity_links = [];
  $view_mode = $context['view_mode'];
  $comment_type = $entity
    ->bundle();
  if ($view_mode == 'search_index' || $view_mode == 'search_result' || $view_mode == 'print' || $view_mode == 'rss') {

    // Do not add any links if the entity is displayed for:
    // - search indexing.
    // - constructing a search result excerpt.
    // - print.
    // - rss.
    return [];
  }
  $fields = $this->commentManager
    ->getFields($entity
    ->getEntityTypeId());
  foreach ($fields as $field_name => $detail) {

    // Skip fields that the entity does not have.
    if (!$entity
      ->hasField($field_name)) {
      continue;
    }
    $links = [];
    $commenting_status = $entity
      ->get($field_name)->status;
    if ($commenting_status != CommentItemInterface::HIDDEN) {

      // Entity has commenting status open or closed.
      $field_definition = $entity
        ->getFieldDefinition($field_name);
      if ($view_mode == 'teaser') {

        // Teaser view: display the number of comments that have been posted,
        // or a link to add new comments if the user has permission, the
        // entity is open to new comments, and there currently are none.
        if ($this
          ->accessComment($this->currentUser, $comment_type)) {
          if (!empty($entity
            ->get($field_name)->comment_count)) {
            $links['comment-comments'] = [
              'title' => $this
                ->formatPlural($entity
                ->get($field_name)->comment_count, '1 comment', '@count comments'),
              'attributes' => [
                'title' => $this
                  ->t('Jump to the first comment.'),
              ],
              'fragment' => 'comments',
              'url' => $entity
                ->toUrl(),
            ];
            if ($this->moduleHandler
              ->moduleExists('history')) {
              $links['comment-new-comments'] = [
                'title' => '',
                'url' => Url::fromRoute('<current>'),
                'attributes' => [
                  'class' => 'hidden',
                  'title' => $this
                    ->t('Jump to the first new comment.'),
                  'data-history-node-last-comment-timestamp' => $entity
                    ->get($field_name)->last_comment_timestamp,
                  'data-history-node-field-name' => $field_name,
                ],
              ];
            }
          }
        }

        // Provide a link to new comment form.
        if ($commenting_status == CommentItemInterface::OPEN) {
          $comment_form_location = $field_definition
            ->getSetting('form_location');
          if ($this
            ->accessPostComment($this->currentUser, $comment_type)) {
            $links['comment-add'] = [
              'title' => $this
                ->t('Add new comment'),
              'language' => $entity
                ->language(),
              'attributes' => [
                'title' => $this
                  ->t('Share your thoughts and opinions.'),
              ],
              'fragment' => 'comment-form',
            ];
            if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
              $links['comment-add']['url'] = Url::fromRoute('comment.reply', [
                'entity_type' => $entity
                  ->getEntityTypeId(),
                'entity' => $entity
                  ->id(),
                'field_name' => $field_name,
              ]);
            }
            else {
              $links['comment-add'] += [
                'url' => $entity
                  ->toUrl(),
              ];
            }
          }
          elseif ($this->currentUser
            ->isAnonymous()) {
            $links['comment-forbidden'] = [
              'title' => $this->commentManager
                ->forbiddenMessage($entity, $field_name),
            ];
          }
        }
      }
      else {

        // Entity in other view modes: add a "post comment" link if the user
        // is allowed to post comments and if this entity is allowing new
        // comments.
        if ($commenting_status == CommentItemInterface::OPEN) {
          $comment_form_location = $field_definition
            ->getSetting('form_location');
          if ($this
            ->accessPostComment($this->currentUser, $comment_type)) {

            // Show the "post comment" link if the form is on another page, or
            // if there are existing comments that the link will skip past.
            if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || !empty($entity
              ->get($field_name)->comment_count) && $this
              ->accessComment($this->currentUser, $comment_type)) {
              $links['comment-add'] = [
                'title' => $this
                  ->t('Add new comment'),
                'attributes' => [
                  'title' => $this
                    ->t('Share your thoughts and opinions.'),
                ],
                'fragment' => 'comment-form',
              ];
              if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
                $links['comment-add']['url'] = Url::fromRoute('comment.reply', [
                  'entity_type' => $entity
                    ->getEntityTypeId(),
                  'entity' => $entity
                    ->id(),
                  'field_name' => $field_name,
                ]);
              }
              else {
                $links['comment-add']['url'] = $entity
                  ->toUrl();
              }
            }
          }
          elseif ($this->currentUser
            ->isAnonymous()) {
            $links['comment-forbidden'] = [
              'title' => $this->commentManager
                ->forbiddenMessage($entity, $field_name),
            ];
          }
        }
      }
    }
    if (!empty($links)) {
      $entity_links['comment__' . $field_name] = [
        '#theme' => 'links__entity__comment__' . $field_name,
        '#links' => $links,
        '#attributes' => [
          'class' => [
            'links',
            'inline',
          ],
        ],
      ];
      if ($view_mode == 'teaser' && $this->moduleHandler
        ->moduleExists('history') && $this->currentUser
        ->isAuthenticated()) {
        $entity_links['comment__' . $field_name]['#cache']['contexts'][] = 'user';
        $entity_links['comment__' . $field_name]['#attached']['library'][] = 'comment/drupal.node-new-comments-link';

        // Embed the metadata for the "X new comments" link (if any) on this
        // entity.
        $entity_links['comment__' . $field_name]['#attached']['drupalSettings']['history']['lastReadTimestamps'][$entity
          ->id()] = (int) history_read($entity
          ->id());
        $new_comments = $this->commentManager
          ->getCountNewComments($entity);
        if ($new_comments > 0) {
          $page_number = $this->entityTypeManager
            ->getStorage('comment')
            ->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new_comments, $entity, $field_name);
          $query = $page_number ? [
            'page' => $page_number,
          ] : NULL;
          $value = [
            'new_comment_count' => (int) $new_comments,
            'first_new_comment_link' => $entity
              ->toUrl('canonical', [
              'query' => $query,
              'fragment' => 'new',
            ])
              ->toString(),
          ];
          $parents = [
            'comment',
            'newCommentsLinks',
            $entity
              ->getEntityTypeId(),
            $field_name,
            $entity
              ->id(),
          ];
          NestedArray::setValue($entity_links['comment__' . $field_name]['#attached']['drupalSettings'], $parents, $value);
        }
      }
    }
  }
  return $entity_links;
}