You are here

social_comment.module in Open Social 8

The Social comment module.

File

modules/social_features/social_comment/social_comment.module
View source
<?php

/**
 * @file
 * The Social comment module.
 */
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\comment\CommentInterface;
use Drupal\group\Entity\GroupContent;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;

/**
 * @file
 * The Social comment module.
 */

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Enhance the comment form.
 */
function social_comment_form_comment_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Change value of 'Save' button.
  $form['actions']['submit']['#value'] = t('Comment', [], [
    'context' => 'Comment Button',
  ]);

  // Hide title of 'Comment' field.
  if (!empty($form['field_comment_body']['widget'][0]['value']['#title_display'])) {
    $form['field_comment_body']['widget'][0]['value']['#title_display'] = 'invisible';
  }

  // Validate replies to comments deeper than 1.
  $form['#validate'][] = 'social_comment_form_reply_validate';
  $route_name = \Drupal::routeMatch()
    ->getRouteName();
  switch ($route_name) {

    // Comment reply form.
    case 'comment.reply':
      $form['actions']['submit']['#attributes']['value'] = t('Reply');
      $form['actions']['submit']['#value'] = t('Reply');
      $form['field_comment_body']['widget'][0]['#placeholder'] = t('Add a reply');
      break;

    // Comment edit form.
    case 'entity.comment.edit_form':
      $form['actions']['submit']['#attributes']['value'] = t('Submit');
      $form['actions']['submit']['#value'] = t('Submit');
      break;
    default:

      // Redirect to the current url. We should not use this change for posts.
      // See social_post_form_comment_post_comment_form_alter for posts.
      if ($form_id !== 'comment_post_comment_form') {
        $form['#action'] = \Drupal::request()
          ->getRequestUri();
      }
      break;
  }
  $form['#attached']['library'][] = 'social_post/keycode-submit';
}

/**
 * Form validation handler for comment_form().
 *
 * Validate replies to comments deeper than 1.
 */
function social_comment_form_reply_validate($form, FormStateInterface $form_state) {

  // Get parrent comment ID.
  $pid = \Drupal::routeMatch()
    ->getParameter('pid');
  if ($pid) {
    $comment = \Drupal::entityTypeManager()
      ->getStorage('comment')
      ->load($pid);
    $bundle = $comment
      ->bundle();
    switch ($bundle) {
      default:
        if (!empty($comment
          ->getParentComment())) {
          $form_state
            ->setErrorByName('', t('Replies to comments deeper than 1 is not allowed'));
        }
        break;
      case "post_comment":
        $form_state
          ->setErrorByName('', t('Replies for comments on posts are not allowed'));
        break;
    }
  }
}

/**
 * Implements hook_comment_links_alter().
 *
 * Alter the links of a comment.
 */
function social_comment_comment_links_alter(array &$links, CommentInterface $entity, array &$context) {
  $bundle = $entity
    ->bundle();
  $commented_entity = $entity
    ->getCommentedEntity();
  $account = \Drupal::currentUser();
  switch ($bundle) {
    default:
      if (!empty($entity
        ->getParentComment()) || \Drupal::routeMatch()
        ->getRouteName() === 'comment.reply') {
        unset($links['comment']['#links']['comment-reply']);
      }
      else {
        $group_contents = GroupContent::loadByEntity($commented_entity);

        // Only react if it is actually posted inside a group.
        if (!empty($group_contents)) {
          foreach ($group_contents as $group_content) {
            $group = $group_content
              ->getGroup();

            // Remove comments from output if user don't have access.
            if (!$group
              ->hasPermission('post comments', $account)) {
              unset($links['comment']['#links']['comment-reply']);
            }
          }
        }
      }
      break;
    case "post_comment":
      unset($links['comment']['#links']['comment-reply']);
      break;
  }
}

/**
 * Implements hook_preprocess_comment().
 */
function social_comment_preprocess_comment(&$variables) {
  $comment = $variables['elements']['#comment'];

  // Display comment created date in format 'time ago'.
  $created_time_ago = \Drupal::service('date.formatter')
    ->formatTimeDiffSince($comment
    ->getCreatedTime(), [
    'granularity' => 1,
    'return_as_object' => TRUE,
  ]);
  $date = t('%time ago', [
    '%time' => $created_time_ago
      ->getString(),
  ]);
  $variables['submitted'] = Link::fromTextAndUrl($date, $comment
    ->urlInfo('canonical'));
  $variables['#cache']['max-age'] = $created_time_ago
    ->getMaxAge();
  $account = $comment
    ->getOwner();
  if ($account) {
    $storage = \Drupal::entityTypeManager()
      ->getStorage('profile');
    if (!empty($storage)) {
      $user_profile = $storage
        ->loadByUser($account, 'profile');
      if ($user_profile) {
        $content = \Drupal::entityTypeManager()
          ->getViewBuilder('profile')
          ->view($user_profile, 'compact');
        $variables['author_picture'] = $content;
      }
    }
  }

  // Add node ID attribute for comment "new" indicator.
  if (\Drupal::moduleHandler()
    ->moduleExists('history') && $comment
    ->getCommentedEntityTypeId() == 'node') {
    $variables['attributes']['data-history-node-id'] = $comment
      ->getCommentedEntityId();
  }
}

/**
 * Implements hook_ENTITY_TYPE_access().
 *
 * Allow users to delete their own comments.
 */
function social_comment_comment_access(EntityInterface $entity, $operation, AccountInterface $account) {
  if ($operation == 'delete') {
    if ($account
      ->hasPermission('administer comments', $account)) {
      return AccessResult::allowed()
        ->cachePerPermissions();
    }
    else {
      return AccessResult::allowedIf($account
        ->hasPermission('delete own comments', $account) && $account
        ->id() == $entity
        ->getOwnerId())
        ->cachePerPermissions()
        ->cachePerUser()
        ->addCacheableDependency($entity);
    }
  }
}

/**
 * Implements hook_entity_type_alter().
 */
function social_comment_entity_type_alter(array &$entity_types) {

  /* @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
  $entity_types['comment']
    ->setViewBuilderClass('Drupal\\social_comment\\SocialCommentViewBuilder');
}

/**
 * Implements hook_ENTITY_TYPE_view().
 */
function social_comment_comment_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($view_mode === 'activity') {
    $commented_entity = $entity
      ->getCommentedEntity();
    if (is_object($commented_entity)) {
      $commented_entity_type = $commented_entity
        ->getEntityTypeId();

      // Teaser of commented entity.
      $build['commented_entity'] = \Drupal::entityTypeManager()
        ->getViewBuilder($commented_entity_type)
        ->view($commented_entity, 'activity_comment');

      // Prepare the "Show all comments" link.
      if ($commented_entity_type === 'post') {
        $comment_field_name = 'field_post_comments';
      }
      elseif ($commented_entity_type === 'node') {
        $comment_field_name = 'field_' . $commented_entity
          ->bundle() . '_comments';

        // Prepare the "Comments" link.
        $link_options = [
          'fragment' => 'comment-form',
          'attributes' => [
            'class' => [
              'btn btn-block btn-link brand-text-primary',
            ],
          ],
        ];
        $commented_entity_url = $commented_entity
          ->toUrl('canonical', $link_options);
        $build['comment_link'] = Link::fromTextAndUrl(t('Comment'), $commented_entity_url)
          ->toRenderable();
      }
      $comment_count = $commented_entity->{$comment_field_name}->comment_count;
      $t_args = [
        ':num_comments' => $comment_count,
      ];
      if ($comment_count > 1) {
        $more_link = t('Show all :num_comments comments', $t_args);

        // Set link classes to be added to the button.
        $more_link_options = [
          'attributes' => [
            'class' => [
              'btn',
              'btn-flat',
              'brand-text-primary',
            ],
          ],
        ];

        // Set path to post node.
        $link_url = $commented_entity
          ->urlInfo('canonical');

        // Attach the attributes.
        $link_url
          ->setOptions($more_link_options);
        $more_button = Link::fromTextAndUrl($more_link, $link_url)
          ->toRenderable();
        $build['more_link'] = $more_button;
      }
    }

    // Comment.
    $build['comment'] = \Drupal::entityTypeManager()
      ->getViewBuilder($entity
      ->getEntityTypeId())
      ->view($entity, 'activity_comment');
  }
}

/**
 * Implements hook_field_info_alter().
 *
 * Change the default list_class for fields of type 'comment'.
 */
function social_comment_field_info_alter(&$info) {
  if (isset($info['comment'])) {
    $info['comment']['list_class'] = '\\Drupal\\social_comment\\SocialCommentFieldItemList';
  }
}