You are here

opigno_forum.module in Opigno forum 8

Same filename and directory in other branches
  1. 3.x opigno_forum.module

File

opigno_forum.module
View source
<?php

/**
 * @file
 * Contains opigno_forum.module.
 */
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\group\Entity\Group;
use Drupal\node\NodeInterface;
use Drupal\opigno_forum\ForumTopicHandler;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\TermInterface;
use Drupal\user\Entity\User;

/**
 * Implements hook_entity_presave().
 */
function opigno_forum_entity_presave(EntityInterface $entity) {
  if ($entity
    ->getEntityTypeId() === 'group' && $entity
    ->bundle() === 'learning_path') {

    /** @var \Drupal\group\Entity\Group $entity */

    // Create a forum for the training
    // if it is enabled and not already exists.
    $enable_forum = $entity
      ->get('field_learning_path_enable_forum')
      ->getValue()[0]['value'];
    $has_forum = !$entity
      ->get('field_learning_path_forum')
      ->isEmpty();
    if ($enable_forum && !$has_forum) {
      $forum = Term::create([
        'vid' => 'forums',
        'name' => $entity
          ->label(),
        'parent' => 0,
      ]);
      $forum
        ->save();
      $entity
        ->set('field_learning_path_forum', [
        'target_id' => $forum
          ->id(),
      ]);
    }
  }

  // Update forum new learning path title.
  if ($entity
    ->getEntityTypeId() === 'group' && $entity
    ->bundle() === 'learning_path' && !$entity
    ->isNew() && !$entity
    ->get('field_learning_path_forum')
    ->isEmpty()) {
    $forum = $entity
      ->get('field_learning_path_forum')->target_id;
    $forum = Term::load($forum);
    if ($forum instanceof TermInterface) {
      $new_name = $entity
        ->label();
      $forum
        ->setName($new_name);
      $forum
        ->save();
    }
  }

  // Add notification about new post in a training forum.
  if ($entity
    ->getEntityTypeId() === 'comment' && $entity
    ->bundle() === 'comment_forum') {

    // If new post.
    if ($entity
      ->isNew()) {

      // Get post topic.
      $topic = $entity
        ->getCommentedEntity();
      if ($topic && !empty($topic->forum_tid)) {

        // Get training id of the forum.
        $db_connection = \Drupal::service('database');
        $group_id = $db_connection
          ->select('group__field_learning_path_forum', 'lpf')
          ->fields('lpf', [
          'entity_id',
        ])
          ->condition('field_learning_path_forum_target_id', $topic->forum_tid)
          ->execute()
          ->fetchField();
        if ($group_id) {
          $group = Group::load($group_id);
          if ($group) {

            // Get training members ids except current user.
            $user = \Drupal::currentUser();
            $uids = $db_connection
              ->select('group_content_field_data', 'gc')
              ->fields('gc', [
              'entity_id',
            ])
              ->condition('type', 'learning_path-group_membership')
              ->condition('gid', $group_id)
              ->condition('entity_id', $user
              ->id(), '!=')
              ->execute()
              ->fetchCol();
            if ($uids) {
              $message = t('New forum post in training "@name"', [
                '@name' => $group
                  ->label(),
              ]);
              $url = Url::fromRoute('entity.group.canonical', [
                'group' => $group
                  ->id(),
              ])
                ->toString();
              foreach ($uids as $uid) {
                $account = User::load($uid);

                // Check user access to forum.
                if ($account && _opigno_forum_access($topic->forum_tid, $account)) {

                  // Add notification about new post.
                  opigno_set_message($uid, $message, $url);
                }
              }
            }
          }
        }
      }
    }
  }
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function opigno_forum_node_insert(NodeInterface $node) {
  ForumTopicHandler::get()
    ->onNodeInsert($node);
}

/**
 * Checks user access to the forum.
 *
 * @param int $tid
 *   Forum tid.
 * @param \Drupal\Core\Session\AccountInterface $account
 *   User to check.
 *
 * @return bool
 *   Forum access.
 */
function _opigno_forum_access($tid, AccountInterface $account) {
  if ($account
    ->hasPermission('manage group content in any group') || $account
    ->hasPermission('manage group members in any group')) {

    // Allow access if user is admin or platform-level manager.
    return TRUE;
  }

  // Get user groups.
  $membership_service = \Drupal::service('group.membership_loader');
  $memberships = $membership_service
    ->loadByUser($account);

  /** @var \Drupal\group\Entity\GroupInterface[] $groups */
  $groups = array_map(function ($membership) {

    /** @var \Drupal\group\GroupMembership $membership */
    return $membership
      ->getGroup();
  }, $memberships);

  // Allow access to the forum if it is attached to the group
  // that user belongs to.
  foreach ($groups as $group) {
    if ($group
      ->hasField('field_learning_path_enable_forum') && $group
      ->hasField('field_learning_path_forum')) {
      $enable_forum_field = $group
        ->get('field_learning_path_enable_forum')
        ->getValue();
      $forum_field = $group
        ->get('field_learning_path_forum')
        ->getValue();
      if (!empty($enable_forum_field) && !empty($forum_field)) {
        $is_forum_enabled = $enable_forum_field[0]['value'];
        $forum_tids = array_map(function ($item) {
          return $item['target_id'];
        }, $forum_field);
        if ($is_forum_enabled && in_array($tid, $forum_tids)) {
          return TRUE;
        }
      }
    }
  }
  return FALSE;
}

/**
 * Implements hook_ENTITY_TYPE_access().
 */
function opigno_forum_taxonomy_term_access(TermInterface $entity, $operation, AccountInterface $account) {
  if ($entity
    ->bundle() === 'forums') {

    // Check current user access to the forum taxonomy term.
    $tid = $entity
      ->id();
    return AccessResult::forbiddenIf(!_opigno_forum_access($tid, $account));
  }
  return AccessResult::neutral();
}

/**
 * Implements hook_node_access().
 */
function opigno_forum_node_access(NodeInterface $node, $op, AccountInterface $account) {
  if ($node
    ->bundle() === 'forum' && $node
    ->hasField('taxonomy_forums')) {

    // Check current user access to the forum topic node.
    $tid = $node
      ->get('taxonomy_forums')
      ->getValue()[0]['target_id'];
    return AccessResult::forbiddenIf(!_opigno_forum_access($tid, $account));
  }
  return AccessResult::neutral();
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function opigno_forum_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (isset($form['taxonomy_forums'])) {

    // Hide forums that current user can't access from the forum fields.
    $account = \Drupal::currentUser();
    $widget =& $form['taxonomy_forums']['widget'];
    $options = $widget['#options'];
    foreach ($options as $tid => $title) {
      if (!is_numeric($tid)) {
        continue;
      }
      if (!_opigno_forum_access($tid, $account)) {
        unset($widget['#options'][$tid]);
      }
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function opigno_forum_preprocess_forum_list(&$variables) {

  // Hide forums that current user can't access from the forum listings.
  $account = \Drupal::currentUser();
  $forums = $variables['forums'];
  foreach ($forums as $tid => $forum) {
    if (!_opigno_forum_access($tid, $account)) {
      unset($variables['forums'][$tid]);
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function opigno_forum_preprocess_node(&$variables) {
  if ($variables['node']
    ->getType() == 'forum' && $variables['view_mode'] == 'full') {
    $node = $variables['node'];
    $topics_list_link = $node->taxonomy_forums
      ->getValue();
    if (!empty($topics_list_link)) {
      $variables['topics_list_link'] = Link::createFromRoute(t('To the topics list'), 'forum.page', [
        'taxonomy_term' => $topics_list_link['0']['target_id'],
      ], [
        'attributes' => [
          'class' => 'btn btn-success color-white text-uppercase btn-back',
        ],
      ]);
    }
  }
}