View source
<?php
define('INVITE_SESSION', 'invite_code');
define('INVITE_ADMIN_SESSION', 'invite_admin_filter');
define('INVITE_UNLIMITED', -1);
require_once drupal_get_path('module', 'invite') . '/invite_token.inc';
function invite_help($path, $arg) {
switch ($path) {
case 'admin/help#invite':
return _invite_module_help();
case 'user/%/invites':
case 'user/%/invites/accepted':
$output = '<p>' . t("The invitations shown on this page have been used to join the site. Clicking on an e-mail address takes you to the user's profile page.");
break;
case 'user/%/invites/pending':
$output = '<p>' . t("The invitations shown on this page haven't been accepted yet.");
break;
case 'user/%/invites/expired':
$output = '<p>' . t('The invitations shown on this page have not been used to register on the site within the expiration period of @count days.', array(
'@count' => variable_get('invite_expiry', 30),
));
break;
default:
return;
}
$output .= ' ' . t('The status <em>deleted</em> means the user account has been terminated.') . '</p>';
if (!user_access('withdraw accepted invitations')) {
$output .= '<p>' . t("At any time, you may withdraw either pending or expired invitations. Accepted invitations can't be withdrawn and count permanently toward your invitation allotment.") . '</p>';
}
return $output;
}
function _invite_module_help() {
$file = drupal_get_path('module', 'invite') . '/README.txt';
if (file_exists($file)) {
return _filter_autop(check_plain(file_get_contents($file)));
}
}
function invite_theme() {
return array(
'invite_form' => array(
'arguments' => array(
'form' => NULL,
),
),
'invite_user_overview' => array(
'arguments' => array(
'items' => NULL,
),
'file' => 'invite_admin.inc',
),
'invite_token_help' => array(
'arguments' => array(
'type' => NULL,
'prefix' => NULL,
'suffix' => NULL,
),
'file' => 'invite_token.inc',
),
);
}
function invite_perm() {
return array(
'administer invitations',
'send invitations',
'send mass invitations',
'track invitations',
'withdraw accepted invitations',
);
}
function invite_init() {
global $user;
if (!empty($user->invite_sent) && !module_invoke('throttle', 'status')) {
invite_notify($user->uid);
}
}
function invite_menu() {
$items['admin/user/invite'] = array(
'title' => 'Invites',
'page callback' => 'invite_admin_overview',
'access arguments' => array(
'administer invitations',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'invite_admin.inc',
);
$items['admin/user/invite/list'] = array(
'title' => 'Inviters',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/user/invite/settings'] = array(
'title' => 'Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'invite_settings',
),
'access arguments' => array(
'administer invitations',
),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
'file' => 'invite_admin.inc',
);
$items['admin/user/invite/details/%user'] = array(
'title callback' => 'invite_admin_details_page_title',
'title arguments' => array(
4,
),
'page callback' => 'invite_admin_details',
'page arguments' => array(
4,
),
'access arguments' => array(
'administer invitations',
),
'type' => MENU_LOCAL_TASK,
'file' => 'invite_admin.inc',
);
$items['invite'] = array(
'title' => 'Invite a friend',
'title callback' => 'invite_page_title',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'invite_form',
'page',
array(),
),
'access arguments' => array(
'send invitations',
),
'type' => MENU_NORMAL_ITEM,
);
$items['invite/accept/%invite'] = array(
'page callback' => 'invite_accept',
'page arguments' => array(
2,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['invite/withdraw/%invite'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'invite_cancel',
2,
),
'access arguments' => array(
'track invitations',
),
'type' => MENU_CALLBACK,
);
$items['invite/resend/%invite'] = array(
'title' => 'Resend invitation',
'page callback' => 'invite_resend',
'page arguments' => array(
2,
),
'access arguments' => array(
'send invitations',
),
'type' => MENU_CALLBACK,
);
$items['user/%user/invites'] = array(
'title' => 'Invitations',
'page callback' => 'invite_user_overview',
'access callback' => 'invite_user_access',
'access arguments' => array(
'track invitations',
1,
),
'type' => MENU_LOCAL_TASK,
'file' => 'invite_admin.inc',
);
$items['user/%user/invites/accepted'] = array(
'title' => 'Accepted',
'page callback' => 'invite_user_overview',
'page arguments' => array(
'accepted',
),
'access callback' => 'invite_user_access',
'access arguments' => array(
'track invitations',
1,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -5,
'file' => 'invite_admin.inc',
);
$items['user/%user/invites/pending'] = array(
'title' => 'Pending',
'page callback' => 'invite_user_overview',
'page arguments' => array(
'pending',
),
'access callback' => 'invite_user_access',
'access arguments' => array(
'track invitations',
1,
),
'type' => MENU_LOCAL_TASK,
'file' => 'invite_admin.inc',
);
$items['user/%user/invites/expired'] = array(
'title' => 'Expired',
'page callback' => 'invite_user_overview',
'page arguments' => array(
'expired',
),
'access callback' => 'invite_user_access',
'access arguments' => array(
'track invitations',
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
'file' => 'invite_admin.inc',
);
$items['user/%user/invites/new'] = array(
'title' => 'New invitation',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'invite_form',
'page',
array(),
),
'access callback' => 'invite_user_access',
'access arguments' => array(
'send invitations',
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
);
return $items;
}
function invite_menu_alter(&$items) {
if (invite_user_registration_by_invite_only()) {
$items['user/register']['access callback'] = 'invite_user_register_access';
}
}
function invite_user_registration_by_invite_only() {
return variable_get('user_register', 1) === '1-inviteonly';
}
function invite_user_register_access() {
$invite = invite_load_from_session();
if (!$invite && ($code = arg(2))) {
if ($invite = invite_load($code)) {
if (invite_validate($invite)) {
$_SESSION[INVITE_SESSION] = $invite->reg_code;
}
}
}
if (!$invite && !user_access('administer users')) {
if (arg(1) == 'register') {
drupal_set_message(t('Sorry, new user registration by invitation only.'));
}
return FALSE;
}
return user_register_access();
}
function invite_page_title($title) {
return variable_get('invite_page_title', $title);
}
function invite_admin_details_page_title($account) {
return t('Invitees of @name', array(
'@name' => $account->name,
));
}
function invite_user_access($permission, $account) {
return $account->uid == $GLOBALS['user']->uid && user_access($permission);
}
function invite_notify($uid) {
$result = db_query('SELECT invitee FROM {invite_notifications} WHERE uid = %d', $uid);
while ($row = db_fetch_object($result)) {
$account = user_load(array(
'uid' => $row->invitee,
'status' => 1,
));
if ($account) {
drupal_set_message(t('!user (@email) has joined @site-name!', array(
'!user' => theme('username', $account),
'@email' => $account->mail,
'@site-name' => variable_get('site_name', t('Drupal')),
)));
db_query("DELETE FROM {invite_notifications} WHERE uid = %d AND invitee = %d", $uid, $row->invitee);
}
}
}
function invite_accept($invite) {
global $user;
if (!$user->uid && invite_validate($invite)) {
$_SESSION[INVITE_SESSION] = $invite->reg_code;
drupal_goto(variable_get('invite_registration_path', 'user/register'));
}
drupal_goto();
}
function invite_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'user_admin_settings':
$item = menu_get_item('user/register');
if (in_array($item['access_callback'], array(
'user_register_access',
'invite_user_register_access',
))) {
$form['registration']['user_register']['#options']['1-inviteonly'] = t('New user registration by invitation only.');
}
$form['#submit'][] = 'menu_rebuild';
break;
case 'user_register':
$GLOBALS['conf']['cache'] = CACHE_DISABLED;
$invite = invite_load_from_session();
if (!$invite && ($code = arg(2))) {
if ($invite = invite_load($code)) {
if (invite_validate($invite)) {
$_SESSION[INVITE_SESSION] = $invite->reg_code;
}
}
}
if ($invite) {
if (isset($form['account'])) {
$field =& $form['account'];
}
else {
$field =& $form;
}
if (isset($field['mail'])) {
$field['mail']['#default_value'] = $invite->email;
}
}
break;
case 'user_login_block':
if (invite_user_registration_by_invite_only()) {
$new_items = array();
$new_items[] = l(t('Request new password'), 'user/password', array(
'attributes' => array(
'title' => t('Request new password via e-mail.'),
),
));
$form['links']['#value'] = theme('item_list', $new_items);
}
break;
}
}
function invite_load($code) {
$result = db_query("SELECT * FROM {invite} WHERE reg_code = '%s' AND canceled = 0", $code);
if ($invite = db_fetch_object($result)) {
$invite->inviter = user_load(array(
'uid' => $invite->uid,
));
$invite->data = (array) unserialize($invite->data);
}
return $invite;
}
function invite_load_from_session() {
if (isset($_SESSION[INVITE_SESSION])) {
return invite_load($_SESSION[INVITE_SESSION]);
}
return FALSE;
}
function invite_validate($invite) {
if (!$invite || !$invite->inviter) {
drupal_set_message(t('This invitation has been withdrawn.'));
drupal_goto();
}
elseif ($invite->joined != 0) {
drupal_set_message(t('This invitation has already been used. Please login now with your username and password.'));
drupal_goto('user');
}
elseif ($invite->expiry < time()) {
drupal_set_message(t('Sorry, this invitation has expired.'));
drupal_goto();
}
else {
return TRUE;
}
}
function invite_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'insert':
$invite = invite_load_from_session();
if (!$invite) {
$code = db_result(db_query("SELECT reg_code FROM {invite} WHERE email = '%s'", $account->mail));
if ($code) {
$invite = invite_load($code);
}
}
if ($invite) {
$roles = invite_process($invite, $account);
if ($roles) {
if (!isset($edit['roles']) || !is_array($edit['roles'])) {
$edit['roles'] = array();
}
$edit['roles'] += $roles;
user_module_invoke('update', $edit, $account);
}
if ($invite->inviter->uid) {
user_save($invite->inviter, array(
'invite_sent' => TRUE,
));
}
unset($_SESSION[INVITE_SESSION]);
}
break;
case 'delete':
invite_delete($account->uid);
break;
}
}
function invite_process($invite, $account) {
db_query("UPDATE {invite} SET email = '%s', invitee = %d, joined = %d WHERE reg_code = '%s'", $account->mail, $account->uid, time(), $invite->reg_code);
db_query("DELETE FROM {invite} WHERE (email = '%s' OR email = '%s') AND reg_code <> '%s'", $invite->email, $account->mail, $invite->reg_code);
db_query("INSERT INTO {invite_notifications} (uid, invitee) SELECT uid, %d from {invite} WHERE (email = '%s' OR email = '%s') AND canceled = 0", $account->uid, $invite->email, $account->mail);
db_query("UPDATE {users} SET status = 1 WHERE uid = %d", $account->uid);
$roles = invite_target_roles($invite);
$args = array(
'invitee' => $account,
'inviter' => $invite->inviter,
'roles' => &$roles,
);
module_invoke_all('invite', 'escalate', $args);
return $roles;
}
function invite_target_roles($invite) {
$targets = array();
$roles = array(
'default' => 'default',
);
if ($invite->inviter) {
$roles = array_merge($roles, array_intersect($invite->inviter->roles, user_roles(FALSE, 'send invitations')));
}
foreach ($roles as $rid => $role) {
$target = variable_get('invite_target_role_' . $rid, DRUPAL_AUTHENTICATED_RID);
if ($target != DRUPAL_AUTHENTICATED_RID) {
$targets[$target] = $target;
}
}
return $targets;
}
function invite_delete($uid) {
$origin = db_result(db_query("SELECT uid FROM {invite} WHERE invitee = %d", $uid));
if ($origin && ($inviter = user_load(array(
'uid' => $origin,
)))) {
if (user_access('withdraw accepted invitations', $inviter)) {
db_query("DELETE FROM {invite} WHERE invitee = %d", $uid);
}
}
db_query("DELETE FROM {invite} WHERE uid = %d", $uid);
db_query("DELETE FROM {invite_notifications} WHERE uid = %d OR invitee = %d", $uid, $uid);
}
function invite_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks[0] = array(
'info' => t('Invite a friend'),
'cache' => BLOCK_CACHE_PER_ROLE,
);
return $blocks;
}
elseif ($op == 'view') {
$block = array();
switch ($delta) {
case 0:
if (user_access('send invitations')) {
$block = array(
'subject' => t('Invite a friend'),
'content' => drupal_get_form('invite_form', 'block'),
);
}
break;
}
return $block;
}
}
function invite_form(&$form_state, $op = 'page', $edit = array()) {
global $user;
if (!is_array($edit)) {
$edit = (array) $edit;
}
$remaining_invites = invite_get_remaining_invites($user);
if ($remaining_invites == 0) {
if ($op == 'block') {
$form['#access'] = FALSE;
return $form;
}
elseif (!$edit) {
drupal_set_message(t("Sorry, you've reached the maximum number of invitations."), 'error');
drupal_goto(referer_uri());
}
}
$form['resent'] = array(
'#type' => 'value',
'#value' => $edit ? $edit['resent'] + 1 : 0,
);
$form['reg_code'] = array(
'#type' => 'value',
'#value' => $edit ? $edit['reg_code'] : NULL,
);
if ($remaining_invites != INVITE_UNLIMITED) {
$form['remaining_invites'] = array(
'#type' => 'value',
'#value' => $remaining_invites,
);
}
switch ($op) {
case 'page':
default:
$form += invite_page_form($remaining_invites, $edit);
break;
case 'block':
$form += invite_block_form($remaining_invites);
break;
}
return $form;
}
function invite_get_remaining_invites($account) {
if ($account->uid == 1) {
return INVITE_UNLIMITED;
}
$data = unserialize($account->data);
if (isset($data['invites'])) {
$remaining = $data['invites'];
}
else {
$remaining = invite_get_role_limit($account);
if ($remaining > 0) {
$sent = db_result(db_query("SELECT COUNT(*) FROM {invite} WHERE uid = %d", $account->uid));
$remaining = max($remaining - $sent, 0);
if ($sent > 0) {
user_save($account, array(
'invites' => $remaining,
));
}
}
}
return $remaining;
}
function invite_get_role_limit($account) {
if (!isset($account->roles)) {
$account = user_load(array(
'uid' => $account->uid,
));
}
$role_limit = 0;
foreach (user_roles(FALSE, 'send invitations') as $rid => $role) {
if (array_key_exists($rid, $account->roles)) {
$role_max = variable_get('invite_maxnum_' . $rid, INVITE_UNLIMITED);
if ($role_max == INVITE_UNLIMITED) {
return INVITE_UNLIMITED;
}
$role_limit = max($role_max, $role_limit);
}
}
return $role_limit;
}
function invite_page_form($remaining_invites, $edit = array()) {
global $user;
if ($remaining_invites != INVITE_UNLIMITED) {
$form['remaining_invites_markup']['#value'] = format_plural($remaining_invites, 'You have 1 invite remaining.', 'You have @count invites remaining.');
}
if ($user->uid && variable_get('invite_use_users_email', 0)) {
$from = $user->mail;
}
else {
$from = variable_get('site_mail', ini_get('sendmail_from'));
}
if (module_exists('pmail')) {
$from = personalize_email($from);
}
$form['from'] = array(
'#type' => 'item',
'#title' => t('From'),
'#value' => check_plain($from),
);
if (!$edit) {
$failed_emails = '';
$allow_multiple = user_access('send mass invitations');
if (isset($_SESSION['invite_failed_emails'])) {
$failed_emails = implode("\n", (array) unserialize($_SESSION['invite_failed_emails']));
unset($_SESSION['invite_failed_emails']);
}
$form['email'] = array(
'#title' => t('To'),
'#default_value' => $failed_emails,
'#description' => format_plural($allow_multiple ? 99 : 1, 'Enter the e-mail address of the person you would like to invite.', 'Enter the e-mail addresses of the persons you would like to invite. To specify multiple recipients, enter one e-mail address per line or separate each address with a comma.'),
'#required' => TRUE,
);
if ($allow_multiple) {
$form['email']['#type'] = 'textarea';
$form['email']['#rows'] = 3;
}
else {
$form['email']['#type'] = 'textfield';
$form['email']['#maxlength'] = 64;
}
if ($failed_emails) {
$form['email']['#attributes']['class'] = 'error';
}
}
else {
$allow_multiple = FALSE;
$form['email_markup'] = array(
'#type' => 'item',
'#title' => t('To'),
'#value' => check_plain($edit['email']),
);
$form['email'] = array(
'#type' => 'value',
'#value' => $edit['email'],
);
}
if ($edit && !empty($edit['data']['subject'])) {
$subject = $edit['data']['subject'];
}
else {
$subject = invite_get_subject();
}
$prefix = t('Re:');
if ($edit && drupal_substr($subject, 0, strlen($prefix)) != $prefix) {
$subject = $prefix . ' ' . $subject;
}
if (variable_get('invite_subject_editable', FALSE)) {
$form['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#default_value' => $subject,
'#description' => t('Type the subject of the invitation e-mail.'),
'#required' => TRUE,
);
}
else {
$form['subject'] = array(
'#type' => 'item',
'#title' => t('Subject'),
'#value' => check_plain($subject),
);
}
$form['body'] = array(
'#type' => 'item',
'#title' => t('Message'),
);
$form['message'] = array(
'#type' => 'textarea',
'#default_value' => $edit && !empty($edit['data']['message']) ? $edit['data']['message'] : '',
'#description' => format_plural($allow_multiple ? 1 : 99, 'This message will be added to the mail sent to the persons you are inviting.', 'This message will be added to the mail sent to the person you are inviting.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send invite'),
);
return $form;
}
function invite_block_form($remaining_invites) {
global $user;
$form['#action'] = url('invite');
$form['invite'] = array(
'#value' => t('Recommend @site-name to:', array(
'@site-name' => variable_get('site_name', t('Drupal')),
)),
);
$description = '';
if ($remaining_invites != INVITE_UNLIMITED) {
$description = format_plural($remaining_invites, '1 invite remaining', '@count invites remaining');
}
$form['email'] = array(
'#type' => 'textfield',
'#size' => 20,
'#maxlength' => 64,
'#description' => $description,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send invite'),
);
$form['link'] = array(
'#prefix' => '<div><small>',
'#value' => l(t('View your invites'), "user/{$user->uid}/invites"),
'#suffix' => '</small></div>',
'#access' => user_access('track invitations') && $user->uid,
);
return $form;
}
function theme_invite_form($form) {
$output = '';
$op = $form['#parameters'][2];
if ($op == 'page') {
$output .= drupal_render($form['remaining_invites_markup']);
$output .= drupal_render($form['remaining_invites']);
$output .= drupal_render($form['from']);
if (isset($form['email_markup'])) {
$output .= drupal_render($form['email_markup']);
}
$output .= drupal_render($form['email']);
$output .= drupal_render($form['subject']);
$output .= drupal_render($form['body']);
$output .= '<div class="invite-message"><div class="opening">';
$message_form = "</p></div>\n" . drupal_render($form['message']) . "\n" . '<div class="closing"><p>';
$body = _filter_autop(t(_invite_get_mail_template()));
$types = _invite_token_types(array(
'data' => array(
'message' => $message_form,
),
));
$output .= token_replace_multiple($body, $types);
$output .= "</div></div>\n";
}
$output .= drupal_render($form);
return $output;
}
function invite_form_validate($form, &$form_state) {
global $user;
$emails = _invite_get_emails($form_state['values']['email']);
if (!$form_state['values']['resent']) {
if (count($emails) > 0) {
$failed_emails = _invite_validate_emails("SELECT mail AS email FROM {users} WHERE mail IN (" . db_placeholders($emails, 'varchar') . ")", $emails);
if (count($failed_emails)) {
$error = format_plural(count($failed_emails), 'The following recipient is already a member:', 'The following recipients are already members:') . '<br />';
foreach ($failed_emails as $key => $email) {
$account = user_load(array(
'mail' => $email,
));
$failed_emails[$key] = theme('username', $account) . ' (' . check_plain($email) . ')';
}
$error .= implode(', ', $failed_emails);
drupal_set_message($error, 'error');
}
}
if (!empty($emails)) {
$failed_emails = _invite_validate_emails("SELECT email FROM {invite} WHERE email IN (" . db_placeholders($emails, 'varchar') . ") AND uid = %d AND canceled = 0", $emails, $user->uid);
if (count($failed_emails)) {
$error = format_plural(count($failed_emails), 'You have already invited the following recipient:', 'You have already invited the following recipients:') . '<br />';
$error .= implode(', ', array_map('check_plain', $failed_emails));
drupal_set_message($error, 'error');
}
}
if (count($emails) == 0) {
form_set_error('email', t('Please enter valid e-mail addresses.'));
return;
}
if (isset($form_state['values']['remaining_invites']) && count($emails) > $form_state['values']['remaining_invites']) {
form_set_error('email', format_plural($form_state['values']['remaining_invites'], 'You have only 1 invite left.', 'You have only @count invites left.'));
return;
}
if (!user_access('send mass invitations') && count($emails) > 1) {
form_set_error('email', t('You cannot send more than one invitation.'));
return;
}
}
$form_state['values']['valid_emails'] = $emails;
}
function _invite_get_emails($string) {
$valid_emails = $failed_emails = array();
$user = '[a-zA-Z0-9_\\-\\.\\+\\^!#\\$%&*+\\/\\=\\?\\`\\|\\{\\}~\']+';
$domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.?)+';
$ipv4 = '[0-9]{1,3}(\\.[0-9]{1,3}){3}';
$ipv6 = '[0-9a-fA-F]{1,4}(\\:[0-9a-fA-F]{1,4}){7}';
$rx = "/({$user}@({$domain}|(\\[({$ipv4}|{$ipv6})\\])))>?\$/";
$emails = array_unique(split("[,\n\r]", drupal_strtolower($string)));
foreach ($emails as $email) {
$email = preg_replace('/^.*<(.*)>$/', '${1}', trim($email));
if ($email) {
if (preg_match($rx, $email, $match)) {
$valid_emails[] = $match[1];
}
else {
$failed_emails[] = $email;
}
}
}
if (count($failed_emails)) {
$_SESSION['invite_failed_emails'] = serialize($failed_emails);
}
return $valid_emails;
}
function _invite_validate_emails($sql, &$emails) {
$failed_emails = array();
$args = func_get_args();
$args = array_merge($emails, array_slice($args, 2));
$result = db_query($sql, $args);
while ($row = db_fetch_object($result)) {
$failed_emails[] = $row->email;
}
$emails = array_diff($emails, $failed_emails);
return $failed_emails;
}
function invite_form_submit($form, &$form_state) {
global $user, $language;
$form_state['redirect'] = 'invite';
$failed_emails = array();
$num_failed = $num_succeeded = 0;
if (isset($_SESSION['invite_failed_emails'])) {
$failed_emails = (array) unserialize($_SESSION['invite_failed_emails']);
$num_failed = count($failed_emails);
}
$subject = isset($form_state['values']['subject']) ? trim($form_state['values']['subject']) : invite_get_subject();
$message = isset($form_state['values']['message']) ? trim($form_state['values']['message']) : NULL;
if (!variable_get('invite_use_users_email', 0)) {
$from = variable_get('invite_manual_from', '');
}
elseif ($user->uid) {
$from = $user->mail;
}
if (!$from) {
$from = NULL;
}
foreach ($form_state['values']['valid_emails'] as $email) {
$code = $form_state['values']['reg_code'] ? $form_state['values']['reg_code'] : invite_generate_code();
$invite = _invite_substitutions(array(
'email' => $email,
'code' => $code,
'resent' => $form_state['values']['resent'],
'data' => array(
'subject' => $subject,
'message' => $message,
),
));
$params = array(
'invite' => $invite,
);
$result = drupal_mail('invite', 'invite', $email, $language, $params, $from, TRUE);
if ($result['result']) {
invite_save($invite);
if (!$form_state['values']['resent']) {
$args = array(
'inviter' => $invite->inviter,
'email' => $invite->email,
'code' => $invite->code,
);
module_invoke_all('invite', 'invite', $args);
}
$num_succeeded++;
}
else {
$failed_emails[] = $email;
}
}
if ($failed_emails) {
$_SESSION['invite_failed_emails'] = serialize($failed_emails);
}
if ($num_succeeded) {
if (isset($form_state['values']['remaining_invites'])) {
user_save($user, array(
'invites' => $form_state['values']['remaining_invites'] - $num_succeeded,
));
}
$message = format_plural($num_succeeded, 'Your invitation has been successfully sent. You will be notified when the invitee joins the site.', '@count invitations have been successfully sent. You will be notified when any invitee joins the site.');
drupal_set_message($message);
}
if ($num_failed) {
$message = format_plural($num_failed, 'The entered e-mail address is invalid. Please correct it.', '@count entered e-mail addresses are invalid. Please correct them.');
drupal_set_message($message, 'error');
}
elseif (user_access('track invitations') && $user->uid) {
$form_state['redirect'] = "user/{$user->uid}/invites/pending";
}
}
function invite_link_alter(&$links, $node, $comment = NULL) {
if (isset($links['comment_forbidden'])) {
if (invite_user_registration_by_invite_only()) {
if (variable_get('comment_form_location_' . $node->type, COMMENT_FORM_SEPARATE_PAGE) == COMMENT_FORM_SEPARATE_PAGE) {
$destination = 'destination=' . rawurlencode("comment/reply/{$node->nid}#comment-form");
}
else {
$destination = 'destination=' . rawurlencode("node/{$node->nid}#comment-form");
}
$link = t('<a href="@login">Login</a> to post comments', array(
'@login' => url('user/login', array(
'query' => $destination,
)),
));
$links['comment_forbidden']['title'] = $link;
}
}
}
function invite_get_subject($substitutions = array()) {
$subject = t(variable_get('invite_subject', t('[inviter-raw] has sent you an invite!')));
return token_replace_multiple($subject, _invite_token_types($substitutions));
}
function invite_generate_code() {
do {
$reg_code = user_password(8);
$result = db_query("SELECT COUNT(*) FROM {invite} WHERE reg_code = '%s'", $reg_code);
} while (db_result($result));
return $reg_code;
}
function invite_mail($key, &$message, $params) {
global $user;
$invite = $params['invite'];
if (!variable_get('invite_use_users_email_replyto', 0)) {
$reply_to = variable_get('invite_manual_reply_to', '');
}
elseif ($user->uid) {
$reply_to = $user->mail;
}
if ($reply_to) {
$message['headers']['Reply-To'] = $reply_to;
}
$message['subject'] = $invite->data['subject'];
$template = t(_invite_get_mail_template());
$tokens = _invite_token_types($invite);
$message['body'][] = token_replace_multiple($template, $tokens);
}
function invite_save($edit) {
$edit = (array) $edit;
$data = serialize($edit['data']);
$now = time();
$expiry = $now + variable_get('invite_expiry', 30) * 60 * 60 * 24;
if ($edit['resent']) {
$result = db_query("UPDATE {invite} SET expiry = %d, resent = %d, data = '%s' WHERE reg_code = '%s' AND uid = %d", $expiry, $edit['resent'], $data, $edit['code'], $edit['inviter']->uid);
}
else {
$result = db_query("INSERT INTO {invite} (reg_code, email, uid, created, expiry, data) VALUES ('%s', '%s', %d, %d, %d, '%s')", $edit['code'], $edit['email'], $edit['inviter']->uid, $now, $expiry, $data);
}
return $result;
}
function invite_cancel(&$form_state, $invite) {
global $user;
if ($invite->inviter->uid == $user->uid) {
if (!$invite->joined || user_access('withdraw accepted invitations')) {
$form['invite'] = array(
'#type' => 'value',
'#value' => $invite,
);
$description = !$invite->joined && $invite->expiry > time() ? t("The invitee won't be able to register any more using this invitation.") : '';
return confirm_form($form, t('Are you sure you want to withdraw the invitation to %email?', array(
'%email' => $invite->email,
)), $_REQUEST['destination'], $description . ' ' . t('This action cannot be undone.'), t('Withdraw'), t('Cancel'));
}
else {
drupal_set_message(t('Invitations to registered users cannot be withdrawn.'), 'error');
}
}
else {
watchdog('invite', 'Detected malicious attempt to delete an invitation.', array(), WATCHDOG_WARNING, l(t('view'), 'user/' . $user->uid));
return drupal_access_denied();
}
drupal_goto();
}
function invite_cancel_submit($form, &$form_state) {
$invite = $form_state['values']['invite'];
db_query("UPDATE {invite} SET canceled = 1 WHERE reg_code = '%s'", $invite->reg_code);
drupal_set_message(t('Invitation to %email has been withdrawn.', array(
'%email' => $invite->email,
)));
$args = array(
'inviter' => $invite->inviter,
'email' => $invite->email,
'code' => $invite->reg_code,
);
module_invoke_all('invite', 'cancel', $args);
}
function invite_resend($invite) {
global $user;
if ($invite->uid == $user->uid && $invite->expiry < time()) {
return drupal_get_form('invite_form', 'page', $invite);
}
return drupal_access_denied();
}
function invite_count($uid, $op) {
switch ($op) {
case 'accepted':
return db_result(db_query("SELECT COUNT(*) FROM {invite} WHERE uid = %d AND joined <> 0", $uid));
case 'pending':
return db_result(db_query("SELECT COUNT(*) FROM {invite} WHERE uid = %d AND joined = 0 AND expiry >= %d", $uid, time()));
case 'expired':
return db_result(db_query("SELECT COUNT(*) FROM {invite} WHERE uid = %d AND joined = 0 AND expiry < %d", $uid, time()));
}
}
function invite_disable() {
if (invite_user_registration_by_invite_only()) {
variable_set('user_register', 1);
drupal_set_message(t('User registration option reset to %no_approval.', array(
'%no_approval' => t('Visitors can create accounts and no administrator approval is required.'),
)));
}
}
function _invite_get_mail_template() {
$template = t("Your friend, [inviter-raw], has invited you to join [site-name] at [site-url].\n\nTo become a member of [site-name], click the link below or paste it into the address bar of your browser.\n\n[join-link]\n\n----------\n[invite-message-raw]");
return variable_get('invite_default_mail_template', $template);
}
function _invite_token_types($args = array()) {
global $user;
if (!is_array($args)) {
$args = (array) $args;
}
$invite = _invite_substitutions($args);
return array(
'user' => $user,
'profile' => $user,
'invite' => $invite,
);
}
function _invite_substitutions($args = array()) {
global $user;
$defaults = array(
'inviter' => $user,
'email' => t('--recipient-email--'),
'code' => t('--invite-code--'),
'resent' => 0,
'data' => array(
'subject' => NULL,
'message' => NULL,
),
);
return (object) array_merge($defaults, $args);
}