You are here

social_auth_extra.module in Open Social 8.4

File

modules/custom/social_auth_extra/social_auth_extra.module
View source
<?php

/**
 * @file
 * Contains social_auth_extra.module.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\social_api\Plugin\NetworkBase;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\bootstrap\Utility\Unicode;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_auth_extra_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($social_buttons = _social_auth_extra_get_buttons('register')) {
    $form += $social_buttons;
  }
  $request = \Drupal::request();
  if ($provider = $request
    ->get('provider')) {
    $network_manager = \Drupal::service('plugin.network.manager');
    $networks = $network_manager
      ->getDefinitions();
    foreach ($networks as $network) {
      $instance = $network_manager
        ->createInstance($network['id']);
      if ($instance
        ->isActive() && $instance
        ->getSocialNetworkKey() == $provider) {
        $form_state
          ->set('network_instance', $instance);
        $data_handler = $instance
          ->getDataHandler();

        // Get the username from social network if it possible.
        if (($sdk = $network_manager
          ->createInstance($network['id'])
          ->getSdk()) && ($access_token = $instance
          ->getDataHandler()
          ->get('access_token'))) {
          $auth_manager = \Drupal::service($network['id'] . '.auth_manager');
          $auth_manager
            ->setSdk($sdk);
          $auth_manager
            ->setAccessToken($access_token);
          $name = $auth_manager
            ->getUsername();
        }

        // If username is not given from social network, generate it based on
        // first name and last name.
        if (empty($name)) {

          // Translate to lowercase and remove unnecessary symbols.
          $name = Unicode::strtolower($data_handler
            ->get('name'));
          $name = \Drupal::transliteration()
            ->transliterate($name);
          $name = str_replace('  ', ' ', $name);
          $name = preg_replace('/[^0-9a-z]/si', '_', $name);
        }

        // The user already selected an authentication method and there
        // will be a drupal_set_message informing the user.
        unset($form['social_auth_extra']);
        unset($form['account']['title']);
        $form['account']['mail']['#default_value'] = $data_handler
          ->get('mail');
        $form['account']['name']['#default_value'] = $name;
        $form['actions']['submit']['#submit'] = [
          'social_auth_extra_form_user_register_form_submit',
        ];
        break;
      }
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_auth_extra_form_social_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($social_buttons = _social_auth_extra_get_buttons('login')) {
    $form += $social_buttons;
  }
}

/**
 * Returns form array with social network auth buttons.
 */
function _social_auth_extra_get_buttons($type = 'login') {
  $form = [];
  $network_manager = \Drupal::service('plugin.network.manager');
  $networks = $network_manager
    ->getDefinitions();
  $provider = \Drupal::request()
    ->get('provider');
  if (!empty($networks)) {
    $sign_up = new TranslatableMarkup('Sign up');
    $login = new TranslatableMarkup('Log in');
    $form['social_auth_extra'] = [
      '#type' => 'fieldset',
      '#attributes' => [
        'class' => [
          'social-auth-buttons',
        ],
      ],
      '#title' => new TranslatableMarkup('@action with <b>Social Accounts</b>', [
        '@action' => $type === 'register' ? $sign_up : $login,
      ]),
      '#weight' => -100,
      '#attached' => [
        'library' => [
          'socialbase/form--social-auth-buttons',
        ],
      ],
    ];

    // If there's a help text for social signup/login we display it to the user.
    $help_key = $type === 'login' ? 'social_login_help' : 'social_signup_help';
    $help_text = \Drupal::config('social_auth_extra.settings')
      ->get($help_key);
    if (!empty($help_text)) {
      $form['social_auth_extra']['#description'] = $help_text;
    }
    foreach ($networks as $key => $network) {
      $instance = $network_manager
        ->createInstance($network['id']);
      $status = \Drupal::config("{$key}.settings")
        ->get('status');
      $network_btnlabel = strtolower('btn--' . $network['social_network']);
      $btn_attributes = [
        'class' => [
          'btn',
          'btn--with-bgicon',
          $network_btnlabel,
        ],
      ];
      if ($provider && $provider != $instance
        ->getSocialNetworkKey()) {
        $btn_attributes['disabled'] = 'disabled';
      }
      if ($status) {
        $form['social_auth_extra'][$key] = [
          '#type' => 'link',
          '#title' => $network['social_network'],
          '#url' => Url::fromRoute("{$key}.user_{$type}"),
          '#attributes' => $btn_attributes,
        ];
      }
    }

    // If there are no any active network, hide fieldset.
    if (empty(array_intersect_key($networks, $form['social_auth_extra']))) {
      unset($form['social_auth_extra']);
    }
  }
  return $form;
}

/**
 * Custom submit function for user_register_form.
 *
 * This function is using for registration via social network.
 */
function social_auth_extra_form_user_register_form_submit($form, FormStateInterface $form_state) {

  /* @var $instance NetworkBase */
  if (($instance = $form_state
    ->get('network_instance')) && $instance instanceof NetworkBase) {
    $id = $instance
      ->getPluginId();
    $user_manager = \Drupal::service($id . '.user_manager');
    $account = $user_manager
      ->createAccount([
      'name' => $form_state
        ->getValue('name'),
      'mail' => $form_state
        ->getValue('mail'),
      'init' => $form_state
        ->getValue('mail'),
      'status' => $form_state
        ->getValue('status'),
      'preferred_langcode' => $form_state
        ->getValue('preferred_langcode'),
    ]);
    try {
      $network_manager = \Drupal::service('plugin.network.manager');
      if (($sdk = $network_manager
        ->createInstance($id)
        ->getSdk()) && ($access_token = $instance
        ->getDataHandler()
        ->get('access_token'))) {
        $auth_manager = \Drupal::service($id . '.auth_manager');
        $auth_manager
          ->setSdk($sdk);
        $auth_manager
          ->setAccessToken($access_token);
        if ($auth_manager
          ->getProfile()) {

          /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
          $module_handler = \Drupal::service('module_handler');

          // Set id of social profile to account and save.
          $account_id = $auth_manager
            ->getAccountId();
          $user_manager
            ->setAccountId($account_id);
          $module_handler
            ->invokeAll('social_auth_extra_user_presave', [
            $account,
            $auth_manager,
            $user_manager,
          ]);
          $account
            ->save();
          $form_state
            ->getFormObject()
            ->setEntity($account);
          if ($module_handler
            ->moduleExists('profile')) {

            // Create profile if it doesn't exists.

            /** @var \Drupal\profile\ProfileStorageInterface $profile_storage */
            $profile_storage = \Drupal::entityTypeManager()
              ->getStorage('profile');
            if (!($profile = $profile_storage
              ->loadByUser($account, 'profile', TRUE))) {
              $profile = $user_manager
                ->createProfile();
            }
            else {
              $user_manager
                ->setProfile($profile);
            }
            $module_handler
              ->invokeAll('social_auth_extra_profile_presave', [
              $account,
              $profile,
              $auth_manager,
              $user_manager,
            ]);
            $profile
              ->save();

            // Redirect to profile.
            $form_state
              ->setRedirect('entity.profile.type.user_profile_form', [
              'user' => $account
                ->id(),
              'profile_type' => 'profile',
              [],
            ]);
          }
          else {

            // If the profile module does not exist redirect to account form.
            $form_state
              ->setRedirect('entity.user.edit_form', [
              'user' => $account
                ->id(),
            ]);
          }
        }
      }
      if (!$account
        ->id()) {
        $module_handler
          ->invokeAll('social_auth_extra_user_presave', [
          $account,
          $auth_manager,
          $user_manager,
        ]);
        $account
          ->save();
        $form_state
          ->getFormObject()
          ->setEntity($account);
      }
      if ($account
        ->get('status')->value === 0) {
        _user_mail_notify('register_pending_approval', $account);
        drupal_set_message(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, a welcome message with further instructions has been sent to your email address.'));
        $form_state
          ->setRedirect('<front>');
      }
      else {
        user_login_finalize($account);
        drupal_set_message(t('Your account is created. We have sent an email with your account details. You can now start exploring @community_name.', [
          '@community_name' => \Drupal::config('system.site')
            ->get('name'),
        ]));

        // Send email notification.
        $params['account'] = $account;
        $langcode = $account
          ->getPreferredLangcode();
        $site_mail = \Drupal::config('system.site')
          ->get('mail_notification');
        if (empty($site_mail)) {
          $site_mail = \Drupal::config('system.site')
            ->get('mail');
        }
        if (empty($site_mail)) {
          $site_mail = ini_get('sendmail_from');
        }
        \Drupal::service('plugin.manager.mail')
          ->mail('social_auth_extra', 'email_social_login', $account
          ->getEmail(), $langcode, $params, $site_mail);
      }

      // Save user consent.
      if (\Drupal::hasService('data_policy.manager')) {

        /** @var \Drupal\data_policy\DataPolicyManagerInterface $data_policy_manager */
        $data_policy_manager = \Drupal::service('data_policy.manager');
        if ($data_policy_manager
          ->isDataPolicy() && !empty($form_state
          ->getValue('data_policy'))) {
          $data_policy_manager
            ->saveConsent($account
            ->id(), TRUE);
        }
      }
    } catch (EntityStorageException $e) {
      drupal_set_message(t('Creation of user account failed. Please contact site administrator.'), 'error');
      $logger_factory = \Drupal::service('logger.fatory');
      $logger_factory
        ->get($id)
        ->error('Could not create new user. Exception: @message', [
        '@message' => $e
          ->getMessage(),
      ]);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for user_form().
 */
function social_auth_extra_form_user_form_alter(&$form, FormStateInterface $form_state) {
  $account = $form_state
    ->getFormObject()
    ->getEntity();
  $network_manager = \Drupal::service('plugin.network.manager');
  $networks = $network_manager
    ->getDefinitions();
  if ($account
    ->id()) {
    if ($networks) {
      $form['social_login_connections'] = [
        '#type' => 'fieldset',
        '#title' => t('Social Log in Connections'),
      ];
      foreach ($networks as $network) {
        $instance = $network_manager
          ->createInstance($network['id']);
        if (!$instance
          ->isActive()) {
          continue;
        }
        $user_manager = \Drupal::service($network['id'] . '.user_manager');
        $user_manager
          ->setAccount($account);
        $form['social_login_connections'][$network['id']] = [
          '#type' => 'item',
          '#social_linkitem' => TRUE,
          '#title' => $network['social_network'],
        ];
        if ($user_manager
          ->getAccountId()) {
          $form['social_login_connections'][$network['id']]['link'] = [
            '#type' => 'link',
            '#title' => t('Unlink'),
            '#attributes' => [
              'class' => [
                'btn btn-default btn-social-linking',
              ],
            ],
            '#url' => Url::fromRoute($network['id'] . '.user_unlink'),
          ];
        }
        else {
          $form['social_login_connections'][$network['id']]['link'] = [
            '#type' => 'link',
            '#title' => t('Link'),
            '#attributes' => [
              'class' => [
                'btn btn-flat btn-social-linking',
              ],
            ],
            '#url' => Url::fromRoute($network['id'] . '.user_link'),
          ];
        }
      }

      // If there are no any active network, hide fieldset.
      if (empty(array_intersect_key($networks, $form['social_login_connections']))) {
        unset($form['social_login_connections']);
      }
    }
    if (!$account
      ->get('pass')->value) {
      $form['account']['current_pass']['#access'] = FALSE;
      $form_state
        ->set('user_pass_reset', TRUE);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for user_admin_settings().
 */
function social_auth_extra_form_user_admin_settings_alter(&$form, FormStateInterface $form_state, $form_id) {
  _social_auth_extra_email_config_form($form, $form_state);
  _social_auth_extra_help_text_config_form($form, $form_state);
  $form['#submit'][] = 'social_auth_extra_form_user_admin_settings_submit';
}

/**
 * Adds form fields for the social login notification emails.
 */
function _social_auth_extra_email_config_form(&$form, FormStateInterface $form_state) {
  $config = \Drupal::config('social_auth_extra.mail');
  $form['email_social_login'] = [
    '#type' => 'details',
    '#title' => t('Welcome (registration with social network)'),
    '#description' => t('This message will be sent to users when users will be registered with a social network account.'),
    '#group' => 'email',
    '#tree' => TRUE,
    '#weight' => -10,
  ];
  $form['email_social_login']['subject'] = [
    '#type' => 'textfield',
    '#title' => t('Subject'),
    '#maxlength' => 180,
    '#default_value' => $config
      ->get('email_social_login.subject'),
  ];
  $form['email_social_login']['body'] = [
    '#type' => 'textarea',
    '#title' => t('Body'),
    '#rows' => 8,
    '#default_value' => $config
      ->get('email_social_login.body'),
  ];
}

/**
 * Adds the form fields to configure the social signup/login user help texts.
 */
function _social_auth_extra_help_text_config_form(&$form, FormStateInterface $form_state) {
  $config = \Drupal::config('social_auth_extra.settings');
  $fieldset = social_user_ensure_help_text_fieldset($form);
  $form[$fieldset]['social_signup_help'] = [
    '#type' => 'textarea',
    '#title' => new TranslatableMarkup('Social Sign Up'),
    '#description' => new TranslatableMarkup("Displayed in the social user sign-up card."),
    "#default_value" => $config
      ->get('social_signup_help'),
    '#weight' => 100,
  ];
  $form[$fieldset]['social_login_help'] = [
    '#type' => 'textarea',
    '#title' => new TranslatableMarkup('Social Log In'),
    '#description' => new TranslatableMarkup("Displayed in the social user log in card."),
    "#default_value" => $config
      ->get('social_login_help'),
    '#weight' => 110,
  ];
}

/**
 * Custom submit function for user_admin_settings().
 */
function social_auth_extra_form_user_admin_settings_submit($form, FormStateInterface $form_state) {
  _social_auth_extra_email_config_submit($form, $form_state);
  _social_auth_extra_help_text_config_submit($form, $form_state);
}

/**
 * Stores the configuration for the social_auth_extra registration emails.
 */
function _social_auth_extra_email_config_submit($form, FormStateInterface $form_state) {
  $config = \Drupal::service('config.factory')
    ->getEditable('social_auth_extra.mail');
  $config
    ->set('email_social_login', $form_state
    ->getValue('email_social_login'));
  $config
    ->save();
}

/**
 * Stores the help texts for the social_auth_extra module.
 */
function _social_auth_extra_help_text_config_submit($form, FormStateInterface $form_state) {
  $config = \Drupal::configFactory()
    ->getEditable('social_auth_extra.settings');
  $config
    ->set('social_signup_help', $form_state
    ->getValue("social_signup_help"));
  $config
    ->set('social_login_help', $form_state
    ->getValue("social_login_help"));
  $config
    ->save();
}

/**
 * Implements hook_mail().
 */
function social_auth_extra_mail($key, &$message, $params) {
  $token_service = \Drupal::token();
  $language_manager = \Drupal::languageManager();
  $langcode = $message['langcode'];
  $variables = [
    'user' => $params['account'],
  ];
  $language = \Drupal::languageManager()
    ->getLanguage($params['account']
    ->getPreferredLangcode());
  $original_language = $language_manager
    ->getConfigOverrideLanguage();
  $language_manager
    ->setConfigOverrideLanguage($language);
  $mail_config = \Drupal::config('social_auth_extra.mail');
  $token_options = [
    'langcode' => $langcode,
    'callback' => 'user_mail_tokens',
    'clear' => TRUE,
  ];
  $message['subject'] .= PlainTextOutput::renderFromHtml($token_service
    ->replace($mail_config
    ->get($key . '.subject'), $variables, $token_options));
  $message['body'][] = $token_service
    ->replace($mail_config
    ->get($key . '.body'), $variables, $token_options);
  $language_manager
    ->setConfigOverrideLanguage($original_language);
}

Functions

Namesort descending Description
social_auth_extra_form_social_user_login_form_alter Implements hook_form_FORM_ID_alter().
social_auth_extra_form_user_admin_settings_alter Implements hook_form_FORM_ID_alter() for user_admin_settings().
social_auth_extra_form_user_admin_settings_submit Custom submit function for user_admin_settings().
social_auth_extra_form_user_form_alter Implements hook_form_FORM_ID_alter() for user_form().
social_auth_extra_form_user_register_form_alter Implements hook_form_FORM_ID_alter().
social_auth_extra_form_user_register_form_submit Custom submit function for user_register_form.
social_auth_extra_mail Implements hook_mail().
_social_auth_extra_email_config_form Adds form fields for the social login notification emails.
_social_auth_extra_email_config_submit Stores the configuration for the social_auth_extra registration emails.
_social_auth_extra_get_buttons Returns form array with social network auth buttons.
_social_auth_extra_help_text_config_form Adds the form fields to configure the social signup/login user help texts.
_social_auth_extra_help_text_config_submit Stores the help texts for the social_auth_extra module.