You are here

social_user.module in Open Social 8

The social user module alterations.

File

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

/**
 * @file
 * The social user module alterations.
 */
use Drupal\block\Entity\Block;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\profile\Entity\ProfileInterface;
use Drupal\social_user\Plugin\Action\SocialBlockUser;
use Drupal\user\Plugin\Action\BlockUser;

/**
 * Implements hook_action_info_alter().
 *
 * @see hook_action_info_alter()
 */
function social_user_action_info_alter(&$definitions) {

  // Swaps stadard block user action with our implementation.
  // If another module has already swapped out those classes,
  // though, we'll be polite and do nothing.
  if (isset($definitions['user_block_user_action']['class']) && $definitions['user_block_user_action']['class'] == BlockUser::class) {
    $definitions['user_block_user_action']['class'] = SocialBlockUser::class;
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * @see \Drupal\user\RegisterForm
 */
function social_user_form_user_register_form_alter(&$form, FormStateInterface $form_state) {

  // By default notify the user of the new account.
  if (isset($form['account']['notify']) && $form['account']['notify']['#access'] === TRUE) {
    $form['account']['notify']['#default_value'] = 1;
  }

  // Add an extra validation option, to check for existing data.
  $form['#validate'][] = 'social_user_register_validate';
}

/**
 * Validate function for the user register form.
 */
function social_user_register_validate(&$form, FormStateInterface $form_state) {

  // Fetch input.
  $input = $form_state
    ->getValues();

  // Check if mail or username already exist.
  if (user_load_by_mail($input['mail']) || user_load_by_name($input['name'])) {

    // If either the username or mail already exists in the DB, we clear ALL
    // existing messages, making sure nothing about this is being disclosed.
    $form_state
      ->clearErrors();

    // Set a new more general error.
    $form_state
      ->setErrorByName('mail', t('Due to privacy concerns, the policy of this web site is not to disclose the existence of registered email addresses or usernames. However, if you entered an email address or username that already exists, you will not be able to continue.
    Please try again, or request a new password. Contact the site administrator if there are any problems.'));
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * @see \Drupal\user\AccountForm
 */
function social_user_form_user_form_alter(&$form, FormStateInterface $form_state) {

  // Add forcing of changing password, message to user
  // if they logged in via a one-time login link.
  // See AccountForm.php this is where user_pass_reset gets set. Only when user
  // uses a one time login link it's true.
  if ($form_state
    ->get('user_pass_reset')) {
    $form['#attached']['library'][] = 'social_user/user_form_protection';

    // We prepend it because a user first has to be saved :) and the profile
    // user save needs to fire first!
    $form['actions']['submit']['#submit'][] = '_social_user_pass_reset_submit';

    // We have to pass some values, because at this point the user is still
    // unsaved and the createdTime and the changedTime are still the same!
    // So it's actually the first time the user logs in and we can do our
    // redirect.
    $user = \Drupal::routeMatch()
      ->getParameter('user');
    $storage = \Drupal::entityTypeManager()
      ->getStorage('profile');

    /** @var \Drupal\profile\Entity\ProfileInterface $profile */
    $profile = $storage
      ->loadByUser($user, 'profile');
    if (!$profile instanceof ProfileInterface) {
      $profile =& $user;
    }
    if ($profile
      ->getCreatedTime() == $profile
      ->getChangedTime()) {

      // Remove unwanted message.
      $message = 'You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.';
      if (isset($_SESSION['messages'])) {
        foreach ($_SESSION['messages'] as $type => $messages) {
          if ($type == 'status') {
            $key = array_search($message, $messages);
            if ($key !== FALSE) {
              unset($_SESSION['messages'][$type][$key]);
            }
          }
        }
        if (empty($_SESSION['messages']['status'])) {
          unset($_SESSION['messages']['status']);
        }
      }
      $form_state
        ->set('first_time_login', TRUE);
    }
  }
}

/**
 * Submit function for resetting password form.
 */
function _social_user_pass_reset_submit($form, FormStateInterface $form_state) {
  $storage = $form_state
    ->getValues();
  $submitted_user_id = isset($storage['uid']) ? $storage['uid'] : '';

  // Only when there is actual user, and the actual user is changing his own
  // account we redirect. When you're editing others you don't want this.
  if (!empty($submitted_user_id) && \Drupal::currentUser()
    ->id() == $submitted_user_id) {
    $first_time_login = $form_state
      ->get('first_time_login');

    // If created & changed user time are the same, the user has never submitted
    // the user save form before. Which means we can redirect to user profile.
    if ($first_time_login) {
      $form_state
        ->setRedirect('entity.profile.type.user_profile_form', [
        'user' => $submitted_user_id,
        'profile_type' => 'profile',
        [],
      ]);
      $form_state
        ->set('first_time_login', FALSE);
    }
    else {

      // We redirect them to the home page stream.
      $form_state
        ->setRedirect('social_core.homepage');
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_user_form_views_form_user_admin_people_page_1_alter(&$form, FormStateInterface $form_state) {
  if (!empty($form['header']['user_bulk_form']['action']['#options'])) {
    $actions = $form['header']['user_bulk_form']['action']['#options'];
    $block_action = [
      'user_block_user_action' => $actions['user_block_user_action'],
    ];
    $current_user = \Drupal::currentUser();
    if (!$current_user
      ->hasPermission('administer users')) {
      $actions = [];
    }
    if (empty($actions) && $current_user
      ->hasPermission('block users')) {
      $actions = $block_action;
    }
    $form['header']['user_bulk_form']['action']['#options'] = $actions;
  }
}

/**
 * Check if an users with the input field for name or mail field is blocked.
 *
 * @param string $name_or_mail
 *   Username or email address.
 *
 * @return bool
 *   TRUE if blocked FALSE if not blocked
 */
function social_user_is_blocked($name_or_mail) {
  $is_blocked_name = (bool) \Drupal::entityQuery('user')
    ->condition('name', $name_or_mail)
    ->condition('status', 0)
    ->execute();
  $is_blocked_mail = (bool) \Drupal::entityQuery('user')
    ->condition('mail', $name_or_mail)
    ->condition('status', 0)
    ->execute();
  if ($is_blocked_name || $is_blocked_mail) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implements hook_entity_base_field_info_alter().
 */
function social_user_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {

  // Add the custom Social username constraint.
  if ($entity_type
    ->id() == 'user' && isset($fields['name'])) {
    $fields['name']
      ->addConstraint('SocialUserName');
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_user_form_user_cancel_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Fetch the current user.
  $account = \Drupal::currentUser();

  // Check if the user has permissions.
  if ($account
    ->hasPermission('administer account settings') === FALSE) {

    // Remove the option to cancel account and delete all related content.
    unset($form['user_cancel_method']['#options']['user_cancel_delete']);
  }
}

/**
 * Implements hook_theme().
 */
function social_user_theme() {
  return [
    'account_header_links' => [
      'variables' => [
        'links' => NULL,
      ],
    ],
  ];
}

/**
 * Prepares variables for the account header links.
 *
 * Default template: account-header-links.html.twig.
 *
 * @param array $variables
 *   An associative array containing:
 *    - links.
 */
function template_preprocess_account_header_links(array &$variables) {

  // Add the search content block to account_header_links.
  $block = Block::load('search_content_block_header');
  if (!empty($block)) {
    $block_output = \Drupal::entityManager()
      ->getViewBuilder('block')
      ->view($block);
    $variables['links']['search_block'] = $block_output;
  }
}

/**
 * Implements hook_block_view_BASE_BLOCK_ID_alter().
 */
function social_user_block_view_search_content_block_alter(array &$build, BlockPluginInterface $block) {

  // Add pre render to search content block in the header.
  $build['#pre_render'][] = '_social_user_search_content_pre_render';
}

/**
 * Pre render for the search content in the header. This will add javascript.
 *
 * @param array $build
 *   The render build array.
 *
 * @return array
 *   Attached array with javascript.
 */
function _social_user_search_content_pre_render(array $build) {

  // Attach the social_search library defined in social_search.libraries.yml.
  $build['#attached'] = [
    'library' => [
      'social_search/navbar-search',
    ],
  ];
  return $build;
}

/**
 * Implements hook_user_format_name_alter().
 *
 * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
 */
function social_user_user_format_name_alter(&$name, $account) {

  /** @var \Drupal\Core\Session\AccountInterface $account */
  $accountname = '';
  $storage = \Drupal::entityTypeManager()
    ->getStorage('profile');
  if (!empty($storage)) {

    // Returns false.
    if ($user_profile = $storage
      ->loadByUser($account, 'profile', TRUE)) {
      $accountname = $user_profile
        ->get('field_profile_first_name')->value . " " . $user_profile
        ->get('field_profile_last_name')->value;
      $accountname = trim($accountname);
    }
  }
  $name = $accountname !== '' ? $accountname : $name;
}

/**
 * Implements hook_menu_local_tasks_alter().
 */
function social_user_menu_local_tasks_alter(&$data, $route_name) {

  // Change the default 'View' tab title.
  if (isset($data['tabs'][0]['entity.user.canonical']['#link'])) {
    $data['tabs'][0]['entity.user.canonical']['#link']['title'] = t('Stream');
  }

  // Remove Edit tab. Edit will always go through Floating Edit Button.
  if (isset($data['tabs'][0]['entity.user.edit_form'])) {
    unset($data['tabs'][0]['entity.user.edit_form']);
  }

  // Keep consistent sorting of 2nd navbar items.
  if (isset($data['tabs'][0]['social_user.events'])) {
    $data['tabs'][0]['social_user.events']['#weight'] = -2;
  }
  if (isset($data['tabs'][0]['social_user.topics'])) {
    $data['tabs'][0]['social_user.topics']['#weight'] = -1;
  }
}

/**
 * Implements hook_tokens_alter().
 *
 * This is a fallback for when the user object is empty and the display name and
 * URL tokens are not filled in by the other token replacements.
 * In cases like this the account is cancelled, but the message remains behind.
 */
function social_user_tokens_alter(&$replacements, $context, $bubbleable_metadata) {

  // Change the display name to that of the Anonymous user when the display name
  // token was not replaced.
  if (isset($context['tokens']['display-name']) && empty($replacements[$context['tokens']['display-name']]) && (array_key_exists('user', $context['data']) && $context['data']['user'] === NULL)) {
    $replacements[$context['tokens']['display-name']] = \Drupal::configFactory()
      ->get('user.settings')
      ->get('anonymous');
  }

  // Empty the URL so it doesn't break rendering when the URL token was not
  // replaced.
  if (isset($context['tokens']['url:absolute']) && empty($replacements[$context['tokens']['url:absolute']]) && (array_key_exists('user', $context['data']) && $context['data']['user'] === NULL)) {
    $replacements[$context['tokens']['url:absolute']] = NULL;
  }
}