You are here

social_group_secret.module in Open Social 10.3.x

The Social group secret module.

File

modules/social_features/social_group/modules/social_group_secret/social_group_secret.module
View source
<?php

/**
 * @file
 * The Social group secret module.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\group\Entity\Group;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\Plugin\views\row\EntityRow;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_group_secret_form_social_group_add_alter(&$form, FormStateInterface $form_state, $form_id) {
  $items =& $form['group_settings']['group_type']['#options'];
  if (isset($items['secret_group'])) {
    $item = $items['secret_group'];
    unset($items['secret_group']);
    $items['secret_group'] = $item;
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Prohibit changing group type.
 */
function social_group_secret_form_group_secret_group_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['group_type']['widget']['#description'] = t('It is not possible to change the group type of a secret group.');
  foreach (array_keys($form['group_type']['widget']['#options']) as $type) {
    $form['group_type']['widget'][$type] = [
      '#disabled' => TRUE,
    ];
  }
  unset($form['group_type']['#ajax']);
  $id = array_search('_social_group_type_edit_submit', $form['actions']['submit']['#submit']);
  unset($form['actions']['submit']['#submit'][$id]);
}

/**
 * Implements hook_views_query_alter().
 *
 * Hide secret groups everywhere when the current user is not a member.
 */
function social_group_secret_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if (empty($view->rowPlugin) || !$view->rowPlugin instanceof EntityRow || $view->rowPlugin
    ->getEntityTypeId() !== 'group') {
    return;
  }
  $account = \Drupal::currentUser();
  if (social_group_secret_can_view_secret_groups($account)) {
    return;
  }

  /** @var \Drupal\group\GroupMembershipLoaderInterface $service */
  $service = \Drupal::service('group.membership_loader');

  // Define the list of the secret groups where the current user is a member.
  // It's needed because the user should see only secret groups where it is a
  // member.
  $ids = [];

  /** @var \Drupal\group\GroupMembership $membership */
  foreach ($service
    ->loadByUser($account) as $membership) {
    if ($membership
      ->getGroup()
      ->bundle() === 'secret_group') {
      $ids[] = $membership
        ->getGroup()
        ->id();
    }
  }

  /** @var \Drupal\views\Plugin\views\query\Sql $query */
  $group = count($query->where);
  while (isset($query->where[$group])) {
    $group++;
  }
  if ($ids) {
    $ids = \Drupal::entityTypeManager()
      ->getStorage('group')
      ->getQuery()
      ->condition('type', 'secret_group')
      ->condition('id', $ids, 'NOT IN')
      ->execute();
    if ($ids) {
      $query
        ->addWhere($group, 'groups_field_data.id', $ids, 'NOT IN');
    }
  }
  else {

    // Add context so for AN it will have a different cache.
    $view->element['#cache']['contexts'][] = 'user.roles:anonymous';
    $query
      ->addWhere($group, 'groups_field_data.type', [
      'secret_group',
    ], 'NOT IN');
  }
}

/**
 * Determine whether a user can see secret groups as outsider.
 *
 * @param \Drupal\Core\Session\AccountInterface $account
 *   The user to check for.
 *
 * @return bool
 *   Whether the user is allowed to view secret groups.
 */
function social_group_secret_can_view_secret_groups(AccountInterface $account) : bool {
  return social_group_can_view_groups_of_type('secret_group', $account);
}

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

  /** @var \Drupal\group\Entity\GroupInterface $group */
  $group = $variables['group'];
  if ($group
    ->getGroupType()
    ->id() === 'secret_group') {
    $variables['secret_group_shield'] = TRUE;
  }
}

/**
 * Implements hook_social_group_types_alter().
 */
function social_group_secret_social_group_types_alter(array &$social_group_types) {
  $social_group_types[] = 'secret_group';
}

/**
 * Implements hook_social_group_default_visibility_alter().
 */
function social_group_secret_social_group_default_visibility_alter(&$visibility, $group_type_id) {
  if ($group_type_id === 'secret_group') {
    $visibility = 'group';
  }
}

/**
 * Implements hook_social_group_allowed_visibilities_alter().
 */
function social_group_secret_social_group_allowed_visibilities_alter(array &$visibilities, $group_type_id) {
  if ($group_type_id === 'secret_group') {
    foreach ($visibilities as $visibility_name => &$is_visible) {
      $is_visible = $visibility_name === 'group';
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Hides secret groups for users that are not a member unless the content is
 * already in the group.
 */
function social_group_secret_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // The is_new field may not be set for new entities.
  $editing = isset($form['is_new']) && !$form['is_new']['#value'];
  if (!$editing) {
    return;
  }
  $user = \Drupal::currentUser();
  if (!empty($form["groups"]["widget"]['#default_value'])) {
    $current_group = $form["groups"]["widget"]['#default_value'][0];
  }
  $secret_group = t('Secret group')
    ->__toString();

  // The options are either a list of group ids when there is only a single
  // group type or they're nested per group type.
  if (isset($form["groups"]["widget"]["#options"][$secret_group])) {
    $group_ids = array_keys($form["groups"]["widget"]["#options"][$secret_group]);
    $groups = Group::loadMultiple($group_ids);

    /** @var \Drupal\group\Entity\Group $group */
    foreach ($groups as $group) {
      if (isset($current_group) && $group
        ->id() === $current_group) {
        continue;
      }
      if (!$group
        ->hasPermission('view group', $user)) {
        unset($form["groups"]["widget"]["#options"][$secret_group][$group
          ->id()]);
      }
    }
    if (empty($form["groups"]["widget"]["#options"][$secret_group])) {
      unset($form["groups"]["widget"]["#options"][$secret_group]);
    }
  }
  else {
    $group_ids = array_filter(array_keys($form["groups"]["widget"]["#options"]), 'is_numeric');
    $groups = Group::loadMultiple($group_ids);

    /** @var \Drupal\group\Entity\Group $group */
    foreach ($groups as $group) {

      // If this is a list of one group type and it's not a secret group then
      // we're done.
      if ($group
        ->bundle() !== 'secret_group') {
        break;
      }
      if (isset($current_group) && $group
        ->id() === $current_group) {
        continue;
      }
      if (!$group
        ->hasPermission('view group', $user)) {
        unset($form["groups"]["widget"]["#options"][$group
          ->id()]);
      }
    }
  }
}