You are here

ulogin.module in uLogin (advanced version) 7

Same filename and directory in other branches
  1. 8 ulogin.module
  2. 6 ulogin.module

Main file for the uLogin module.

File

ulogin.module
View source
<?php

/**
 * @file
 * Main file for the uLogin module.
 */

/**
 * Implements hook_hook_info().
 */
function ulogin_hook_info() {
  $hooks = array(
    'ulogin_username_alter',
  );
  return array_fill_keys($hooks, array(
    'group' => 'ulogin',
  ));
}

/**
 * Implements hook_permission().
 */
function ulogin_permission() {
  return array(
    'use ulogin' => array(
      'title' => t('Login using uLogin'),
      'description' => t('Allows users to login through different authentication providers using uLogin.'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function ulogin_menu() {
  $items = array();
  $items['admin/config/people/ulogin'] = array(
    'title' => 'uLogin',
    'description' => 'Manage uLogin social sign-on settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'ulogin_settings_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'ulogin.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/reports/ulogin'] = array(
    'title' => 'uLogin identities',
    'description' => 'View uLogin identities counts grouped by authentication provider.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'ulogin_report',
    ),
    'access arguments' => array(
      'access site reports',
    ),
    'file' => 'ulogin.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['ulogin'] = array(
    'page callback' => 'ulogin_callback',
    'access arguments' => array(
      'use ulogin',
    ),
    'file' => 'ulogin.pages.inc',
    'type' => MENU_CALLBACK,
  );
  $items['user/%user/ulogin'] = array(
    'title' => 'uLogin identities',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'ulogin_user_identity',
      1,
    ),
    'access callback' => 'user_edit_access',
    'access arguments' => array(
      1,
    ),
    'file' => 'ulogin.pages.inc',
    'type' => MENU_LOCAL_TASK,
  );
  $items['user/%user/ulogin/delete'] = array(
    'title' => 'Delete uLogin identity',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'ulogin_user_identity_delete',
      1,
      4,
    ),
    'access callback' => 'user_edit_access',
    'access arguments' => array(
      1,
    ),
    'file' => 'ulogin.pages.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_menu_site_status_alter().
 */
function ulogin_menu_site_status_alter(&$menu_site_status, $path) {

  // Allow access to ulogin path even if site is in offline mode.
  if ($menu_site_status == MENU_SITE_OFFLINE && user_is_anonymous() && $path == 'ulogin') {
    $menu_site_status = MENU_SITE_ONLINE;
  }
}

/**
 * Implements hook_block_info().
 */
function ulogin_block_info() {
  $blocks['ulogin'] = array(
    'info' => t('User login - uLogin widget only'),
    'cache' => DRUPAL_CACHE_GLOBAL,
  );
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function ulogin_block_view($delta = '') {
  if ($delta == 'ulogin' && !user_is_logged_in() && user_access('use ulogin')) {
    $block = array();
    $block['subject'] = t('User login');
    $block['content'] = array(
      'ulogin' => array(
        '#type' => 'ulogin_widget',
      ),
    );
    return $block;
  }
}

/**
 * Implements hook_user_presave().
 */
function ulogin_user_presave(&$edit, $account, $category) {
  global $ulogin_data;
  if (empty($account->uid) && !empty($ulogin_data)) {

    // the user is being created
    $edit['data']['ulogin'] = $ulogin_data;
    if (!empty($ulogin_data['email'])) {

      //email_confirm: if email was manually entered - set temporary email
      if (!empty($ulogin_data['manual']) && in_array('email', explode(',', $ulogin_data['manual'])) && variable_get('ulogin_email_confirm', 0) && module_exists('email_confirm')) {
        $edit['mail'] = preg_replace('/^(.+)@/', '$1+not_confirmed@', $ulogin_data['email']);
      }
      else {
        $edit['mail'] = $ulogin_data['email'];
      }
    }
  }
}

/**
 * Implements hook_user_delete().
 */
function ulogin_user_delete($account) {
  _ulogin_identity_delete_by_uid($account->uid);
}

/**
 * Implements hook_user_cancel().
 */

/*function ulogin_user_cancel($edit, $account, $method) {
  if (in_array($method, array('user_cancel_reassign', 'user_cancel_delete'))) {
    _ulogin_identity_delete_by_uid($account->uid);
  }
}*/

/**
 * Implements hook_form_alter().
 */
function ulogin_form_alter(&$form, &$form_state, $form_id) {
  _ulogin_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function ulogin_form_comment_form_alter(&$form, &$form_state, $form_id) {
  _ulogin_form_alter($form, $form_state, 'comment_form');
}
function _ulogin_form_alter(&$form, &$form_state, $form_id) {
  if (user_access('use ulogin') && user_is_anonymous() && in_array($form_id, array_filter(variable_get('ulogin_forms', array(
    'user_login',
    'user_login_block',
  ))))) {
    $form['ulogin'] = array(
      '#type' => 'ulogin_widget',
    );
  }
}

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

  //global $user;
  if ($form['#user_category'] == 'account' && !empty($form['#user']->data['ulogin'])) {
    if ($form['account']['name']['#access'] && variable_get('ulogin_disable_username_change', 1)) {
      $form['account']['name']['#access'] = FALSE;
    }
    if (variable_get('ulogin_remove_password_fields', 1)) {
      $form['#validate'] = array_filter($form['#validate'], 'ulogin_user_profile_form_validate_filter');
      unset($form['account']['pass']);
      unset($form['account']['current_pass']);
      unset($form['account']['current_pass_required_values']);
    }
  }
}
function ulogin_user_profile_form_validate_filter($value) {
  return !($value == 'user_validate_current_pass');
}

/**
 * Implements hook_element_info().
 */
function ulogin_element_info() {
  $types = array();
  $enabled_providers = array_filter(variable_get('ulogin_providers_enabled', drupal_map_assoc(array(
    'vkontakte',
    'odnoklassniki',
    'mailru',
    'facebook',
    'twitter',
    'google',
    'yandex',
    'livejournal',
    'openid',
  ))));
  $main_providers = array_filter(variable_get('ulogin_providers_main', drupal_map_assoc(array(
    'vkontakte',
    'odnoklassniki',
    'mailru',
    'facebook',
  ))));
  $required_fields = array_filter(variable_get('ulogin_fields_required', drupal_map_assoc(array(
    'first_name',
    'last_name',
    'email',
    'nickname',
    'bdate',
    'sex',
    'photo',
    'photo_big',
    'country',
    'city',
  ))));
  $optional_fields = array_filter(variable_get('ulogin_fields_optional', drupal_map_assoc(array(
    'phone',
  ))));
  $types['ulogin_widget'] = array(
    '#input' => FALSE,
    '#pre_render' => array(
      'ulogin_widget_pre_render',
    ),
    '#theme' => 'ulogin_widget',
    '#theme_wrappers' => array(
      'form_element',
    ),
    '#ulogin_id' => 'ulogin',
    '#ulogin_widget_id' => variable_get('ulogin_widget_id', ''),
    '#title' => variable_get('ulogin_widget_title', ''),
    '#weight' => variable_get('ulogin_widget_weight', -100),
    '#ulogin_display' => variable_get('ulogin_display', 'panel'),
    '#ulogin_fields_required' => implode(',', $required_fields),
    '#ulogin_fields_optional' => implode(',', $optional_fields),
    '#ulogin_providers' => implode(',', array_intersect_assoc($main_providers, $enabled_providers)),
    '#ulogin_hidden' => implode(',', array_diff_assoc($enabled_providers, $main_providers)),
    '#ulogin_destination' => variable_get('ulogin_destination', ''),
    '#ulogin_redirect' => variable_get('ulogin_redirect', 0),
    '#ulogin_icons_path' => variable_get('ulogin_icons_path', ''),
    '#ulogin_icons' => array(),
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'ulogin') . '/js/ulogin.async.js' => array(
          'type' => 'file',
        ),
      ),
    ),
  );
  return $types;
}

/**
 * Pre-render callback for the 'ulogin_widget' element.
 */
function ulogin_widget_pre_render($element) {
  $element['#ulogin_id'] = drupal_html_id($element['#ulogin_id']);
  $element['#attached']['js'][] = array(
    'type' => 'setting',
    'data' => array(
      'ulogin' => array(
        $element['#ulogin_id'],
      ),
    ),
  );
  if ($element['#ulogin_widget_id']) {
    $element['#theme'] = 'ulogin_widget_id';
    return $element;
  }
  if ($element['#ulogin_redirect']) {
    $callback = 'Drupalulogintoken';
    $redirect = '';
    $element['#attached']['js'][drupal_get_path('module', 'ulogin') . '/js/ulogin.js'] = array(
      'type' => 'file',
    );
  }
  else {
    $callback = '';
    $redirect = _ulogin_token_url($element['#ulogin_destination']);
  }
  $element['#ulogin_data'] = 'display=' . $element['#ulogin_display'] . ';fields=' . $element['#ulogin_fields_required'] . ';optional=' . $element['#ulogin_fields_optional'] . ';callback=' . $callback . ';redirect_uri=' . $redirect;
  if ($element['#ulogin_display'] == 'window') {
    $element['#theme'] = 'ulogin_widget_window';
    return $element;
  }
  if ($element['#ulogin_display'] == 'buttons') {
    $element['#theme'] = 'ulogin_widget_buttons';
    $icons = array();
    if (!empty($element['#ulogin_icons_path'])) {
      foreach (file_scan_directory($element['#ulogin_icons_path'], '//') as $icon) {
        $icons[$icon->name] = $icon->uri;
      }
    }
    if (empty($icons)) {
      $icons = $element['#ulogin_icons'];
    }
    $element['icons'] = array();
    foreach ($icons as $key => $value) {
      $image_info = image_get_info($value);
      $element['icons'][] = array(
        '#theme' => 'image',
        '#path' => $value,
        '#alt' => $key,
        '#title' => $key,
        '#width' => $image_info['width'],
        '#height' => $image_info['height'],
        '#attributes' => array(
          'data-uloginbutton' => $key,
          'class' => 'ulogin-icon-' . $key,
        ),
      );
    }
    return $element;
  }
  $element['#ulogin_data'] .= ';providers=' . $element['#ulogin_providers'] . ';hidden=' . $element['#ulogin_hidden'];
  return $element;
}

/**
 * Implements hook_theme().
 */
function ulogin_theme($existing, $type, $theme, $path) {
  return array(
    'ulogin_widget' => array(
      'render element' => 'element',
      'template' => 'templates/ulogin_widget',
    ),
    'ulogin_widget_id' => array(
      'render element' => 'element',
      'template' => 'templates/ulogin_widget_id',
    ),
    'ulogin_widget_window' => array(
      'render element' => 'element',
      'template' => 'templates/ulogin_widget_window',
    ),
    'ulogin_widget_buttons' => array(
      'render element' => 'element',
      'template' => 'templates/ulogin_widget_buttons',
    ),
  );
}

/**
 * Implements hook_username_alter().
 */
function ulogin_username_alter(&$name, $account) {

  // Don't alter anonymous users or objects that do not have any user ID.
  if (empty($account->uid)) {
    return;
  }
  $ulogin_pattern = variable_get('ulogin_display_name', '[user:ulogin:first_name] [user:ulogin:last_name]');
  if (!empty($ulogin_pattern) && !module_exists('realname')) {
    $account2 = user_load($account->uid);
    if (!empty($account2->data['ulogin'])) {
      $pattern = str_replace('[user:name]', $account2->name, $ulogin_pattern);
      $ulogin_name = token_replace($pattern, array(
        'user' => $account2,
      ), array(
        'clear' => TRUE,
      ));
      $name = trim(strip_tags($ulogin_name));
    }
  }
}

/**
 * Implements hook_realname_alter().
 */
function ulogin_realname_alter(&$realname, $account) {
  if (!empty($account->data['ulogin']) && variable_get('ulogin_override_realname', 0)) {
    $ulogin_pattern = variable_get('ulogin_display_name', '[user:ulogin:first_name] [user:ulogin:last_name]');
    $pattern = str_replace('[user:name]', $realname, $ulogin_pattern);
    $ulogin_name = token_replace($pattern, array(
      'user' => $account,
    ), array(
      'clear' => TRUE,
    ));
    $realname = trim(strip_tags($ulogin_name));
  }
}

/**
 * Implements hook_email_registration_name().
 */
function ulogin_email_registration_name($edit, $account) {
  global $ulogin_data;
  if (!empty($ulogin_data) || !empty($account->data['ulogin'])) {
    return $account->name;
  }
  return NULL;
}

/**
 * Implements hook_exit().
 * Intercepts drupal_goto() calls from Legal legal_user_login().
 */
function ulogin_exit($destination = NULL) {
  global $ulogin_data;
  if (!empty($ulogin_data) && preg_match('/\\/legal_accept\\/([\\d]*)\\//', $destination, $matches) && !_ulogin_identity_load($ulogin_data)) {
    $uid = $matches[1];
    _ulogin_user_save($ulogin_data, $uid);
  }
}

/**
 * Internal functions.
 */
function _ulogin_providers_list() {
  return array(
    'vkontakte' => t('VKontakte'),
    'twitter' => t('Twitter'),
    'mailru' => t('Mail.ru'),
    'facebook' => t('Facebook'),
    'odnoklassniki' => t('Odnoklassniki'),
    'yandex' => t('Yandex'),
    'google' => t('Google'),
    'steam' => t('Steam'),
    'soundcloud' => t('SoundCloud'),
    'lastfm' => t('Last.fm'),
    'linkedin' => t('LinkedIn'),
    'liveid' => t('Live ID'),
    'flickr' => t('Flickr'),
    'uid' => t('uID'),
    'livejournal' => t('Live Journal'),
    'openid' => t('OpenID'),
    'webmoney' => t('WebMoney'),
    'youtube' => t('YouTube'),
    'foursquare' => t('foursquare'),
    'tumblr' => t('tumblr'),
    'googleplus' => t('Google+'),
    'dudu' => t('dudu'),
    'vimeo' => t('Vimeo'),
    'instagram' => t('Instagram'),
    'wargaming' => t('Wargaming.net'),
  );
}
function _ulogin_fields_list() {
  return array(
    'first_name' => t('First name'),
    'last_name' => t('Last name'),
    'email' => t('Email address'),
    'nickname' => t('Nickname'),
    'bdate' => t('Birthday'),
    'sex' => t('Gender'),
    'phone' => t('Phone number'),
    'photo' => t('Photo'),
    'photo_big' => t('Big photo'),
    'city' => t('City'),
    'country' => t('Country'),
  );
}
function _ulogin_token_url($destination = NULL) {
  if (empty($destination)) {
    $destination = drupal_get_destination();
  }
  elseif ($destination == '[HTTP_REFERER]' && isset($_SERVER['HTTP_REFERER'])) {
    $destination = array(
      'destination' => $_SERVER['HTTP_REFERER'],
    );
  }
  else {
    $destination = array(
      'destination' => $destination,
    );
  }
  $token_url = url('ulogin', array(
    'absolute' => TRUE,
    'query' => $destination,
  ));
  return urlencode($token_url);
}
function _ulogin_make_username($data) {
  $pattern = variable_get('ulogin_username', 'ulogin_[user:ulogin:network]_[user:ulogin:uid]');
  $account = new stdClass();
  $account->data = array(
    'ulogin' => $data,
  );
  $ulogin_name = $desired_name = token_replace($pattern, array(
    'user' => $account,
  ), array(
    'clear' => TRUE,
    'sanitize' => FALSE,
  ));
  $counter = 0;
  while (user_load_by_name($ulogin_name)) {
    $counter++;
    $ulogin_name = $desired_name . ' ' . $counter;
  }
  $name = $ulogin_name;
  drupal_alter('ulogin_username', $name, $data);

  // Check that the altered username is unique.
  if ($name == $ulogin_name || user_load_by_name($name)) {
    return $ulogin_name;
  }
  else {
    return $name;
  }
}
function _ulogin_user_is_blocked_by_uid($uid) {
  return db_select('users')
    ->fields('users', array(
    'name',
  ))
    ->condition('uid', $uid)
    ->condition('status', 0)
    ->execute()
    ->fetchObject();
}
function _ulogin_identity_save($data, $uid = NULL) {
  global $user;
  if (!$uid) {
    $uid = $user->uid;
  }
  db_merge('ulogin_identity')
    ->key(array(
    'uid' => $uid,
    'network' => $data['network'],
    'ulogin_uid' => $data['uid'],
  ))
    ->fields(array(
    'data' => serialize($data),
  ))
    ->execute();
}
function _ulogin_identity_load($data) {
  $result = db_select('ulogin_identity', 'ul_id')
    ->fields('ul_id')
    ->condition('network', $data['network'], '=')
    ->condition('ulogin_uid', $data['uid'], '=')
    ->execute()
    ->fetchAssoc();
  return $result;
}
function _ulogin_identity_load_by_uid($uid) {
  $result = db_select('ulogin_identity', 'ul_id')
    ->fields('ul_id')
    ->condition('uid', $uid, '=')
    ->execute()
    ->fetchAllAssoc('id', PDO::FETCH_ASSOC);
  return $result;
}
function _ulogin_identity_load_by_id($id) {
  $result = db_select('ulogin_identity', 'ul_id')
    ->fields('ul_id')
    ->condition('id', $id, '=')
    ->execute()
    ->fetchAssoc();
  return $result;
}
function _ulogin_identity_delete_by_uid($uid) {
  $result = db_delete('ulogin_identity')
    ->condition('uid', $uid, '=')
    ->execute();
  return $result;
}
function _ulogin_identity_delete_by_id($id) {
  $result = db_delete('ulogin_identity')
    ->condition('id', $id, '=')
    ->execute();
  return $result;
}
function _ulogin_user_save($data, $uid = NULL) {
  global $user;
  if ($uid) {
    $account = user_load($uid);
  }
  else {
    $account = $user;
  }
  _ulogin_identity_save($data, $uid);
  $user_save_trigger = FALSE;
  $edit = array();

  //save user picture
  if (variable_get('user_pictures', 0) && variable_get('ulogin_pictures', 1)) {
    $photo_url = '';
    if (!empty($data['photo_big']) && $data['photo_big'] != 'http://ulogin.ru/img/photo_big.png') {
      $photo_url = $data['photo_big'];
    }
    elseif (!empty($data['photo']) && $data['photo'] != 'http://ulogin.ru/img/photo.png') {
      $photo_url = $data['photo'];
    }
    if ($photo_url) {
      $photo = drupal_http_request($photo_url);
      $file = file_save_data($photo->data);
      $file->status = 0;

      //to make user_save() to process the file and move it
      $edit['picture'] = $file;
      $user_save_trigger = TRUE;
    }
  }

  //email_confirm: if email was manually entered - trigger email change confirmation
  if (!empty($data['email']) && !empty($data['manual']) && in_array('email', explode(',', $data['manual'])) && variable_get('ulogin_email_confirm', 0) && module_exists('email_confirm')) {
    $edit['mail'] = $data['email'];
    $user_save_trigger = TRUE;
    if ($uid) {

      //backup original user
      $user_backup = $user;

      //replace user with fake one so that email_confirm module works without notices
      $user = $account;
    }
  }
  if ($user_save_trigger) {

    //hack to remove one notice from Legal module
    if (module_exists('legal')) {
      $edit['legal_accept'] = NULL;
    }
    user_save($account, $edit);
  }

  //return original user back
  if (isset($user_backup)) {
    $user = $user_backup;
  }
}