You are here

comment_perm_search.module in Comment Permissions 8

Comment permissions search functionality.

File

modules/comment_perm_search/comment_perm_search.module
View source
<?php

/**
 * @file
 * Comment permissions search functionality.
 */
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user\RoleInterface;

/**
 * Implements hook_search_plugin_alter().
 */
function comment_perm_search_search_plugin_alter(array &$definitions) {
  if (isset($definitions['node_search'])) {
    $definitions['node_search']['class'] = 'Drupal\\comment_perm_search\\Plugin\\Search\\NodeSearch';
  }
}

/**
 * Implements hook_node_update_index().
 */
function comment_perm_search_node_update_index(EntityInterface $node) {
  $index_comments =& drupal_static(__FUNCTION__);
  if ($index_comments === NULL) {

    // Do not index in the following three cases:
    // 1. 'Authenticated user' can search content but can't access comments.
    // 2. 'Anonymous user' can search content but can't access comments.
    // 3. Any role can search content but can't access comments and access
    // comments is not granted by the 'authenticated user' role. In this case
    // all users might have both permissions from various roles but it is also
    // possible to set up a user to have only search content and so a user
    // edit could change the security situation so it is not safe to index the
    // comments.
    $index_comments = TRUE;
    foreach (\Drupal::service('comment.manager')
      ->getFields('node') as $field_name => $info) {

      // Skip fields that entity does not have.
      if (!$node
        ->hasField($field_name)) {
        continue;
      }
      $comment_type = $node
        ->getFieldDefinition($field_name)
        ->getSetting('comment_type');
      $roles = \Drupal::entityTypeManager()
        ->getStorage('user_role')
        ->loadMultiple();
      $authenticated_can_access = $roles[RoleInterface::AUTHENTICATED_ID]
        ->hasPermission("access {$comment_type} comments");
      foreach ($roles as $rid => $role) {
        if ($role
          ->hasPermission('search content') && !$role
          ->hasPermission("access {$comment_type} comments")) {
          if ($rid == RoleInterface::AUTHENTICATED_ID || $rid == RoleInterface::ANONYMOUS_ID || !$authenticated_can_access) {
            $index_comments = FALSE;
            break;
          }
        }
      }
    }
  }
  $index_comments = true;
  $build = [];
  if ($index_comments) {
    foreach (\Drupal::service('comment.manager')
      ->getFields('node') as $field_name => $info) {

      // Skip fields that entity does not have.
      if (!$node
        ->hasField($field_name)) {
        continue;
      }
      $field_definition = $node
        ->getFieldDefinition($field_name);
      $mode = $field_definition
        ->getSetting('default_mode');
      $comments_per_page = $field_definition
        ->getSetting('per_page');
      if ($node
        ->get($field_name)->status) {
        $comments = \Drupal::entityTypeManager()
          ->getStorage('comment')
          ->loadThread($node, $field_name, $mode, $comments_per_page);
        if ($comments) {
          $build[] = \Drupal::entityTypeManager()
            ->getViewBuilder('comment')
            ->viewMultiple($comments);
        }
      }
    }
  }
  return \Drupal::service('renderer')
    ->renderPlain($build);
}

/**
 * Implements hook_node_search_result().
 *
 * Formats a comment count string and returns it, for display with search
 * results.
 */
function comment_perm_search_node_search_result(EntityInterface $node) {
  $comment_fields = \Drupal::service('comment.manager')
    ->getFields('node');
  $comments = 0;
  $open = FALSE;
  foreach ($comment_fields as $field_name => $info) {

    // Skip fields that entity does not have.
    if (!$node
      ->hasField($field_name)) {
      continue;
    }

    // Do not make a string if comments are hidden.
    $status = $node
      ->get($field_name)->status;
    $comment_type = $node
      ->getFieldDefinition($field_name)
      ->getSetting('comment_type');
    if (\Drupal::currentUser()
      ->hasPermission("access {$comment_type} comments") && $status != CommentItemInterface::HIDDEN) {
      if ($status == CommentItemInterface::OPEN) {

        // At least one comment field is open.
        $open = TRUE;
      }
      $comments += $node
        ->get($field_name)->comment_count;
    }
  }

  // Do not make a string if there are no comment fields, or no comments exist
  // or all comment fields are hidden.
  if ($comments > 0 || $open) {
    return [
      'comment' => \Drupal::translation()
        ->formatPlural($comments, '1 comment', '@count comments'),
    ];
  }
}