<?php

/**
 * @file
 * Enables password creation on registration form.
 */

/**
 * No verification email is sent.
 */
define('USER_REGISTRATIONPASS_NO_VERIFICATION', 0);

/**
 * Verification email is sent before password is set.
 */
define('USER_REGISTRATIONPASS_VERIFICATION_DEFAULT', 1);

/**
 * Verification email is sent after password is set.
 */
define('USER_REGISTRATIONPASS_VERIFICATION_PASS', 2);

/**
 * Implements hook_menu().
 */
function user_registrationpassword_menu() {
  $items['user/registrationpassword/%/%/%'] = array(
    'title' => 'Confirm account',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_registrationpassword_confirm_account', 2, 3, 4),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
    'file' => 'user_registrationpassword.pages.inc',
  );
  return $items;
}

/**
 * Implements hook_form_FORM_ID_alter() for the user administration form.
 */
function user_registrationpassword_form_user_admin_settings_alter(&$form, &$form_state) {
  $form['registration_cancellation']['user_registrationpassword_registration'] = array(
    '#type' => 'radios',
    '#title' => t('Require e-mail verification when a visitor creates an account'),
    '#description' => t('Choose whether new users will be required to validate their e-mail address prior to logging into the site, and will be assigned a system-generated password, or if they can set their password directly on the registration form. With this setting disabled, users will be logged in immediately upon registering, and may select their own passwords during registration.'),
    '#weight' => 0,
    '#options' => array(
      USER_REGISTRATIONPASS_NO_VERIFICATION => t('Do not require a verification e-mail, and let users set their password on the registration form.'),
      USER_REGISTRATIONPASS_VERIFICATION_DEFAULT => t('Require a verification e-mail, but wait for the approval e-mail to let users set their password.'),
      USER_REGISTRATIONPASS_VERIFICATION_PASS => t('Require a verification e-mail, but let users set their password directly on the registration form.'),
    ),
    '#default_value' => variable_get('user_registrationpassword_registration', USER_REGISTRATIONPASS_VERIFICATION_PASS),
  );

  $form['registration_cancellation']['user_email_verification']['#access'] = FALSE;
  $email_token_help = t('Available variables are: [site:name], [site:url], [user:name], [user:mail], [site:login-url], [site:url-brief], [user:edit-url], [user:one-time-login-url], [user:cancel-url].');

  $form['email_user_registrationpassword'] = array(
    '#type' => 'fieldset',
    '#title' => t('Welcome (no approval required, password is set)'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#description' => t('Edit the welcome e-mail messages sent to new members upon registering, when no administrator approval is required and password has already been set.') . ' ' . $email_token_help,
    '#group' => 'email',
  );
  $form['email_user_registrationpassword']['user_registrationpassword_register_subject'] = array(
    '#type' => 'textfield',
    '#title' => t('Subject'),
    '#default_value' => _user_registrationpassword_mail_text('register_subject', NULL, array(), FALSE),
    '#maxlength' => 180,
  );
  $form['email_user_registrationpassword']['user_registrationpassword_register_body'] = array(
    '#type' => 'textarea',
    '#title' => t('Body'),
    '#default_value' => _user_registrationpassword_mail_text('register_body', NULL, array(), FALSE),
    '#rows' => 15,
  );
  // Overwrite the default activation e-mail template with our own.
  $form['email_activated']['settings']['user_mail_status_activated_subject'] = array(
    '#type' => 'textfield',
    '#title' => t('Subject'),
    '#default_value' => variable_get('user_mail_status_activated_subject', _user_registrationpassword_mail_text('status_activated_subject', NULL, array(), FALSE)),
    '#maxlength' => 180,
  );
  $form['email_activated']['settings']['user_mail_status_activated_body'] = array(
    '#type' => 'textarea',
    '#title' => t('Body'),
    '#default_value' => variable_get('user_mail_status_activated_body', _user_registrationpassword_mail_text('status_activated_body', NULL, array(), FALSE)),
    '#rows' => 15,
  );

  $form['#submit'][] = 'user_registrationpassword_admin_settings_submit';
}

/**
 * Submit handler for the user admin form.
 */
function user_registrationpassword_admin_settings_submit(&$form, &$form_state) {
  $value = $form_state['values']['user_registrationpassword_registration'];
  if ($value == USER_REGISTRATIONPASS_VERIFICATION_PASS) {
    variable_set('user_email_verification', 0);
    // Prevent standard notification email to administrators and to user.
    variable_set('user_mail_register_pending_approval_notify', 0);
  }
  else {
    variable_set('user_email_verification', (int) $value);
    // Let default value.
    // @see _user_mail_notify()
    variable_del('user_mail_register_pending_approval_notify');
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for the user registration form.
 */
function user_registrationpassword_form_user_register_form_alter(&$form, &$form_state) {
  // Prevent this from being run if approval with password on registration
  // form is set and the user is an anonymous user registering to the site.
  // When admin users create a user, this does not need to be executed.
  // And when this also does not need to be executed 'user_register' is not set as 
  // 'Visitors can create accounts and no administrator approval is required.'
  // (user registers, recieves user_registrationpass email, would not make sense.)
  // (cause that will unblock the user Without the admin 'approving'.)
  global $user;
  if (variable_get('user_register', 0) == 1 && variable_get('user_registrationpassword_registration', USER_REGISTRATIONPASS_VERIFICATION_PASS) == USER_REGISTRATIONPASS_VERIFICATION_PASS && $user->uid < 1) {
    $form['account']['status']['#default_value'] = 0;
    $form['account']['notify']['#default_value'] = 0;
    $form['#submit'][] = 'user_registrationpassword_form_user_register_submit';
  }
}

/**
 * Submit handler for the user registration form.
 */
function user_registrationpassword_form_user_register_submit(&$form, &$form_state) {
  // Remove the message sent by default.
  $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 e-mail address.');
  $position = array_search($message, $_SESSION['messages']['status']);
  if ($position !== FALSE) {
    unset($_SESSION['messages']['status'][$position]);
  }
  $_SESSION['messages']['status'] = array_values($_SESSION['messages']['status']);
  // Notify the user.
  $account = $form_state['user'];
  $params['account'] = $account;
  $mail = drupal_mail('user_registrationpassword', 'register', $account->mail, user_preferred_language($account), $params);

  drupal_set_message(t('A welcome message with further instructions has been sent to your e-mail address.'));
}

/**
 * Implements hook_mail().
 */
function user_registrationpassword_mail($key, &$message, $params) {
  $language = $message['language'];
  $variables = array('user' => $params['account']);
  $message['subject'] .= _user_registrationpassword_mail_text($key . '_subject', $language, $variables);
  $message['body'][] = _user_registrationpassword_mail_text($key . '_body', $language, $variables);
}

/**
 * Returns a mail string for a variable name.
 *
 * Used by user_registrationpassword_mail() and the settings forms to retrieve strings.
 */
function _user_registrationpassword_mail_text($key, $language = NULL, $variables = array(), $replace = TRUE) {
  $langcode = isset($language) ? $language->language : NULL;

  if ($admin_setting = variable_get('user_registrationpassword_' . $key, FALSE)) {
    // An admin setting overrides the default string.
    $text = $admin_setting;
  }
  else {
    // No override, return default string.
    switch ($key) {
      case 'register_subject':
        $text = t('Account details for [user:name] at [site:name]', array(), array('langcode' => $langcode));
        break;
      case 'register_body':
        $text = t("[user:name],

Thank you for registering at [site:name]. You may now log in and verify your account by clicking this link or copying and pasting it to your browser:

[user:registrationpassword-url]

This link can only be used once. You will be able to log in at [site:login-url] in the future using:

username: [user:name]
password: Your password

--  [site:name] team", array(), array('langcode' => $langcode));
        break;
      case 'status_activated_subject':
        $text = t('Account details for !username at !site', array(), array('langcode' => $langcode));
        break;
      case 'status_activated_body':
        $text = t("!username,

Your account at !site has been activated.

You will be able to log in to !login_uri in the future using:

username: !username
password: your password.

--  !site team", array(), array('langcode' => $langcode));
        break;
    }
  }

  if ($replace) {
    // We do not sanitize the token replacement, since the output of this
    // replacement is intended for an e-mail message, not a web browser.
    return token_replace($text, $variables, array('language' => $language, 'callback' => 'user_registrationpassword_mail_tokens', 'sanitize' => FALSE));
  }

  return $text;
}

/**
 * Token callback to add unsafe tokens for user mails.
 *
 * @see user_mail_tokens()
 * @see user_registrationpassword_mail()
 */
function user_registrationpassword_mail_tokens(&$replacements, $data, $options) {
  user_mail_tokens($replacements, $data, $options);
  if (isset($data['user'])) {
    $replacements['[user:registrationpassword-url]'] = user_registrationpassword_confirmation_url($data['user']);
  }
}

/**
 * Generates a unique URL for a user to login with their password already set.
 *
 * @param object $account
 *   An object containing the user account.
 *
 * @return
 *   A unique URL that provides a one-time log in for the user, from which
 *   they can change their password.
 */
function user_registrationpassword_confirmation_url($account) {
  $timestamp = REQUEST_TIME;
  return url("user/registrationpassword/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE));
}

/**
 * Implements hook_mailkeys().
 *
 * @return array
 */
function user_registrationpassword_mailkeys() {
  return array(
    'register' => t('Welcome message when user self-registers and sets password during registration'),
  );
}

/**
 * Implements hook_mail_edit_text().
 *
 * @param string $mailkey
 * @param object $language
 *
 * @return array
 */
function user_registrationpassword_mail_edit_text($mailkey, $language) {
  $return = array();
  $return['subject'] = _user_registrationpassword_mail_text($mailkey . '_subject', $language, array(), FALSE);
  $return['body'] = _user_registrationpassword_mail_text($mailkey . '_body', $language, array(), FALSE);
  return $return;
}

/**
 * Implements hook_mail_edit_token_types().
 *
 * @param string $mailkey
 *
 * @return array
 */
function user_registrationpassword_mail_edit_token_types($mailkey) {
  return array('user');
}

/**
 * Implements hook_variable_info().
 *
 * @see variable.module.
 */
function user_registrationpassword_variable_info($options) {
  $variables['user_registrationpassword_register_[mail_part]'] = array(
    'type' => 'user_mail',
    'title' => t('Welcome, no approval, password is already set', array(), $options),
    'description' => t('Customize welcome e-mail messages sent to new members when password is already set .', array(), $options),
    'group' => 'user_mails',
  );
  return $variables;
}
