View source
<?php
define('INVITE_SESSION_NAME', 'invite_code');
define('INVITE_UNLIMITED_INVITES', -1);
function invite_help($section) {
if ($section == 'admin/help#invite') {
$file = drupal_get_path('module', 'invite') . '/README.txt';
if (file_exists($file)) {
return _filter_autop(file_get_contents($file));
}
return;
}
switch ($section) {
case 'invite/list':
case 'invite/list/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 'invite/list/pending':
$output = '<p>' . t("The invitations shown on this page haven't been accepted yet.");
break;
case 'invite/list/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_perm() {
return array(
'send invitations',
'send mass invitations',
'track invitations',
'withdraw accepted invitations',
);
}
function invite_menu($may_cache) {
global $user;
$items = array();
$send_access = user_access('send invitations');
$track_access = user_access('track invitations');
if ($may_cache) {
$items[] = array(
'path' => 'admin/user/invite',
'title' => 'Invite settings',
'description' => t('Manage Invite settings'),
'callback' => 'drupal_get_form',
'callback arguments' => 'invite_settings',
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'invite/accept',
'callback' => 'invite_action',
'access' => TRUE,
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'invite',
'title' => variable_get('invite_page_title', t('Invite your friends and colleagues')),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'invite_form',
'page',
),
'access' => $send_access,
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'invite/add',
'title' => t('New invitation'),
'access' => $send_access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -1,
);
$items[] = array(
'path' => 'invite/list',
'title' => t('Your invitations'),
'callback' => 'invite_overview',
'access' => $track_access,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'invite/list/accepted',
'title' => t('Accepted'),
'callback' => 'invite_overview',
'callback arguments' => array(
'accepted',
),
'access' => $track_access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -5,
);
$items[] = array(
'path' => 'invite/list/pending',
'title' => t('Pending'),
'callback' => 'invite_overview',
'callback arguments' => array(
'pending',
),
'access' => $track_access,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'invite/list/expired',
'title' => t('Expired'),
'callback' => 'invite_overview',
'callback arguments' => array(
'expired',
),
'access' => $track_access,
'type' => MENU_LOCAL_TASK,
'weight' => 5,
);
$items[] = array(
'path' => 'invite/withdraw',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'invite_delete',
),
'access' => $track_access,
'type' => MENU_CALLBACK,
);
}
else {
if ($user->uid && $send_access) {
_invite_check_messages($user->uid);
}
}
return $items;
}
function invite_form_alter($form_id, &$form) {
switch ($form_id) {
case 'user_admin_settings':
$form['registration']['user_register']['#options']['inviteonly'] = t('New user registration by invitation only.');
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_NAME] = $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;
}
}
else {
if (variable_get('user_register', 1) == 'inviteonly' && !user_access('administer users')) {
drupal_set_message(t('Sorry, new user registration by invitation only.'));
drupal_goto();
}
}
break;
case 'user_login_block':
if (variable_get('user_register', 1) == 'inviteonly') {
$new_items = array();
$new_items[] = l(t('Request new password'), 'user/password', array(
'title' => t('Request new password via e-mail.'),
));
$form['links']['#value'] = theme('item_list', $new_items);
}
break;
}
}
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'", $edit['mail']));
if ($code) {
$invite = invite_load($code);
}
}
if ($invite) {
_invite_set_accepted($edit['mail'], $account->uid, $invite->reg_code);
_invite_role_escalate($account);
_invite_unblock($account->uid);
unset($_SESSION[INVITE_SESSION_NAME]);
}
break;
case 'delete':
$delete_joined = user_access('withdraw accepted invitations');
if ($delete_joined) {
db_query("DELETE FROM {invite} WHERE mid = %d", $account->uid);
}
$sql = "DELETE FROM {invite} WHERE uid = %d";
if (!$delete_joined) {
$sql .= " AND timestamp != 0";
}
db_query($sql, $account->uid);
break;
}
}
function invite_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks[0] = array(
'info' => t('Invite a friend'),
);
return $blocks;
}
else {
if ($op == 'view') {
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_cron() {
}
function invite_disable() {
if (variable_get('user_register', 1) == 'inviteonly') {
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_settings() {
include drupal_get_path('module', 'invite') . '/invite_token.inc';
$roles = user_roles(0, 'send invitations');
if (count($roles) == 0) {
drupal_set_message(t('Please enable the <em>send invitations</em> permission for at least one role. This can be done on the <a href="!admin-user-access">Access control page</a>.', array(
'!admin-user-access' => url('admin/user/access'),
)));
}
$target_roles = user_roles(1);
$form['general'] = array(
'#type' => 'fieldset',
'#title' => t('General settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['general']['invite_target_role_default'] = array(
'#type' => 'select',
'#title' => t('Default target role'),
'#default_value' => variable_get('invite_target_role_default', DRUPAL_AUTHENTICATED_RID),
'#options' => $target_roles,
'#description' => t('Choose the default role that invited users will be added to when they register. For example, <em>authenticated user</em>.'),
'#required' => TRUE,
);
$form['general']['invite_expiry'] = array(
'#type' => 'select',
'#title' => t('Invitation expiry'),
'#default_value' => variable_get('invite_expiry', 30),
'#options' => drupal_map_assoc(array(
1,
3,
7,
14,
30,
60,
)),
'#description' => t('Set the expiry period for user invitations, in days.'),
'#multiple' => FALSE,
'#required' => TRUE,
);
$form['role'] = array(
'#type' => 'fieldset',
'#title' => t('Role settings'),
'#description' => t('Note: Permission related settings can be found at the <a href="!admin-user-access">Access control page</a>.', array(
'!admin-user-access' => url('admin/user/access'),
)),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
foreach ($roles as $role) {
$role_no_space = str_replace(' ', '_', $role);
$form['role'][$role_no_space] = array(
'#type' => 'fieldset',
'#title' => t('@role settings', array(
'@role' => ucfirst($role),
)),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['role'][$role_no_space]['invite_target_role_' . $role_no_space] = array(
'#type' => 'select',
'#title' => t('Target role'),
'#default_value' => variable_get('invite_target_role_' . $role_no_space, DRUPAL_AUTHENTICATED_RID),
'#options' => $target_roles,
'#description' => t('You may choose to add invited users to another role (in addition to the default role set in the general section) when they have been invited by a member of %role.', array(
'%role' => $role,
)),
'#required' => TRUE,
);
$form['role'][$role_no_space]['invite_maxnum_' . $role_no_space] = array(
'#type' => 'select',
'#title' => t('Invitation limit'),
'#default_value' => variable_get('invite_maxnum_' . $role_no_space, INVITE_UNLIMITED_INVITES),
'#options' => array(
5 => 5,
10 => 10,
20 => 20,
50 => 50,
100 => 100,
500 => 500,
1000 => 1000,
INVITE_UNLIMITED_INVITES => t('unlimited'),
),
'#description' => t('Allows to limit the total number of invitations members of %role can send.', array(
'%role' => $role,
)),
'#multiple' => FALSE,
'#required' => TRUE,
);
}
$form['email'] = array(
'#type' => 'fieldset',
'#title' => t('E-mail settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['email']['invite_subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#default_value' => variable_get('invite_subject', t('[inviter-raw] has sent you an invite!')),
'#size' => 30,
'#maxlength' => 64,
'#description' => t('Type the default subject of the invitation e-mail.') . ' ' . t('Use the syntax [token] if you want to insert a replacement pattern.'),
'#required' => TRUE,
);
$form['email']['invite_subject_editable'] = array(
'#type' => 'checkbox',
'#title' => t('Editable subject'),
'#description' => t('Choose whether users should be able to customize the subject.'),
'#default_value' => variable_get('invite_subject_editable', FALSE),
);
$form['email']['invite_default_mail_template'] = array(
'#type' => 'textarea',
'#title' => t('Mail template'),
'#default_value' => _invite_get_mail_template(),
'#required' => TRUE,
'#description' => t('Use the syntax [token] if you want to insert a replacement pattern.'),
);
$form['email']['token_help'] = array(
'#title' => t('Replacement patterns'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['email']['token_help']['help'] = array(
'#value' => theme('invite_token_help', array(
'user',
'profile',
'invite',
)),
);
$form['email']['invite_use_users_email'] = array(
'#type' => 'radios',
'#title' => t('<em>From</em> e-mail address'),
'#description' => t('Choose which e-mail address will be in the From: header for the invitation mails sent; <em>site</em> or <em>inviter</em>. <em>Site</em> will use the default e-mail address of the site, whereas <em>inviter</em> will use the e-mail address of the user who is sending the invitation. Alternatively, you can set this value manually by clicking on <em>advanced settings</em> below.'),
'#options' => array(
t('site'),
t('inviter'),
),
'#default_value' => variable_get('invite_use_users_email', 0),
);
$form['email']['invite_use_users_email_replyto'] = array(
'#type' => 'radios',
'#title' => t('<em>Reply-To</em> e-mail address'),
'#description' => t('Choose which e-mail address will be in the Reply-To: header for the invitation mails sent; <em>site</em> or <em>inviter</em>. <em>Site</em> will use the default e-mail address of the site, whereas <em>inviter</em> will use the e-mail address of the user who is sending the invitation. Alternatively, you can set this value manually by clicking on <em>advanced settings</em> below.'),
'#options' => array(
t('site'),
t('inviter'),
),
'#default_value' => variable_get('invite_use_users_email_replyto', 0),
);
$form['email']['advanced'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('<strong>Note:</strong> unless these fields are blank, they will override the radio button choices above.'),
);
$form['email']['advanced']['invite_manual_from'] = array(
'#type' => 'textfield',
'#title' => t('Manually override <em>From</em> e-mail address'),
'#default_value' => variable_get('invite_manual_from', NULL),
'#description' => t('The e-mail address the invitation e-mail is sent from.'),
);
$form['email']['advanced']['invite_manual_reply_to'] = array(
'#type' => 'textfield',
'#title' => t('Manually override <em>Reply-To</em> e-mail address'),
'#default_value' => variable_get('invite_manual_reply_to', NULL),
'#description' => t('The e-mail address you want recipients to reply to.'),
);
$form['custom'] = array(
'#type' => 'fieldset',
'#title' => t('Invite page customization'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['custom']['invite_page_title'] = array(
'#type' => 'textfield',
'#title' => t('Invite page title'),
'#default_value' => variable_get('invite_page_title', t('Invite your friends and colleagues')),
'#description' => t('The title of the page where users invite friends.'),
'#required' => TRUE,
);
return system_settings_form($form);
}
function invite_action() {
global $user;
if (!$user->uid) {
$invite = invite_load(arg(2));
if (_invite_validate($invite)) {
$_SESSION[INVITE_SESSION_NAME] = $invite->reg_code;
drupal_goto('user/register');
}
}
drupal_goto();
}
function invite_load($code) {
$result = db_query("SELECT * FROM {invite} WHERE reg_code = '%s'", $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_NAME])) {
return invite_load($_SESSION[INVITE_SESSION_NAME]);
}
return FALSE;
}
function invite_overview($page = 'accepted') {
global $user;
$rows = array();
$time = time();
$profile_access = user_access('access user profiles');
$allow_delete = user_access('withdraw accepted invitations');
switch ($page) {
case 'accepted':
default:
$sql = "SELECT i.*, u.uid FROM {invite} i LEFT JOIN {users} u ON u.uid = i.mid AND u.uid != 0 WHERE i.uid = %d AND i.timestamp > 0 ORDER BY u.uid DESC, i.expiry DESC";
break;
case 'pending':
$sql = "SELECT * FROM {invite} WHERE uid = %d AND timestamp = 0 AND expiry >= %d ORDER BY expiry DESC";
break;
case 'expired':
$sql = "SELECT * FROM {invite} WHERE uid = %d AND timestamp = 0 AND expiry < %d ORDER BY expiry DESC";
break;
}
$result = pager_query($sql, 50, 0, NULL, $user->uid, $time);
while ($invite = db_fetch_object($result)) {
$row = array();
switch ($page) {
case 'accepted':
default:
$account_exists = !is_null($invite->uid);
if ($profile_access) {
$row[] = $account_exists ? l($invite->email, 'user/' . $invite->mid, array(
'title' => t('View user profile.'),
)) : check_plain($invite->email);
}
else {
$row[] = check_plain($invite->email);
}
$row[] = $account_exists ? t('Accepted') : t('Deleted');
$row[] = $allow_delete ? l(t('Withdraw'), "invite/withdraw/{$page}/{$invite->reg_code}") : '';
break;
case 'pending':
case 'expired':
$expired = $invite->expiry < $time;
$row[] = check_plain($invite->email);
$row[] = $expired ? t('Expired') : t('Pending');
$row[] = l(t('Withdraw'), "invite/withdraw/{$page}/{$invite->reg_code}");
break;
}
$rows[] = $row;
}
return theme('invite_overview', $rows);
}
function theme_invite_overview($items) {
if (count($items) > 0) {
$headers = array(
t('E-mail'),
t('Status'),
'',
);
$output = theme('table', $headers, $items, array(
'id' => 'invites',
));
$output .= theme('pager', NULL, 50, 0);
}
else {
$output = t('No invitations available.');
}
return $output;
}
function invite_form($op = 'page') {
global $user;
$max_invites = invite_max_invites();
$allow_multiple = user_access('send mass invitations');
if ($max_invites != INVITE_UNLIMITED_INVITES) {
$invites_sent = db_result(db_query("SELECT COUNT(*) FROM {invite} WHERE uid = %d", $user->uid));
$invites_left = max($max_invites - $invites_sent, 0);
if ($invites_left == 0) {
if ($op == 'block') {
$form['#access'] = FALSE;
return $form;
}
else {
drupal_set_message(t('Sorry, you reached the maximum number (@max) of invitations.', array(
'@max' => $max_invites,
)), 'error');
drupal_goto(user_access('track invitations') ? 'invite/list' : '<front>');
}
}
}
else {
$invites_left = INVITE_UNLIMITED_INVITES;
}
$form['remaining_invites'] = array(
'#type' => 'value',
'#value' => $invites_left,
);
switch ($op) {
case 'block':
$form['#action'] = url('invite');
$form['invite'] = array(
'#value' => t('Recommend @site-name to:', array(
'@site-name' => variable_get('site_name', t('Drupal')),
)),
);
$description = '';
if ($max_invites != INVITE_UNLIMITED_INVITES) {
$description = format_plural($invites_left, '1 invite left', '@count invites left');
}
$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'), 'invite/list'),
'#suffix' => '</small></div>',
'#access' => user_access('track invitations'),
);
break;
case 'page':
default:
if ($max_invites != INVITE_UNLIMITED_INVITES) {
$form['remaining_invites_markup'] = array(
'#value' => format_plural($invites_left, 'You have 1 invite left.', 'You have @count invites left.'),
);
}
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),
);
$failed_emails = '';
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((int) $allow_multiple + 1, 'Type the e-mail address of the person you would like to invite.', 'Type the e-mail addresses of the persons you would like to invite. Addresses should be separated by newlines or commas.'),
'#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';
}
$subject = invite_get_subject();
if (variable_get('invite_subject_editable', FALSE)) {
$form['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#default_value' => $subject,
'#maxlength' => 64,
'#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',
'#description' => format_plural((int) $allow_multiple + 1, 'This message will be added to the mail sent to the person you are inviting.', 'This message will be added to the mail sent to the persons you are inviting.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
break;
}
return $form;
}
function theme_invite_form($form) {
$output = '';
$op = $form['#parameters'][1];
if ($op == 'page') {
$output .= drupal_render($form['remaining_invites_markup']);
$output .= drupal_render($form['remaining_invites']);
$output .= drupal_render($form['from']);
$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_id, &$edit) {
global $user;
$emails = _invite_get_emails($edit['email']);
if (count($emails) > 0) {
$failed_emails = _invite_validate_emails("SELECT mail AS email FROM {users} WHERE mail IN (%s)", $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');
}
$failed_emails = _invite_validate_emails("SELECT email FROM {invite} WHERE email IN (%s)", $emails);
if (count($failed_emails)) {
$error = format_plural(count($failed_emails), 'The following recipient has already been invited:', 'The following recipients have already been invited:') . '<br />';
$error .= implode(', ', array_map('check_plain', $failed_emails));
drupal_set_message($error, 'error');
}
if (count($emails) == 0) {
form_set_error('email');
return;
}
if ($edit['remaining_invites'] != INVITE_UNLIMITED_INVITES && count($emails) > $edit['remaining_invites']) {
form_set_error('email', format_plural($edit['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_set_value(array(
'#parents' => array(
'valid_emails',
),
), $emails);
}
function invite_form_submit($form_id, $edit) {
$failed_emails = array();
$count_failed = $count_success = 0;
if (isset($_SESSION['invite_failed_emails'])) {
$failed_emails = (array) unserialize($_SESSION['invite_failed_emails']);
$count_failed = count($failed_emails);
}
$subject = isset($edit['subject']) ? trim($edit['subject']) : invite_get_subject();
$message = isset($edit['message']) ? trim($edit['message']) : NULL;
foreach ($edit['valid_emails'] as $email) {
$invite = _invite_substitutions(array(
'email' => $email,
'code' => invite_regcode(),
'data' => array(
'subject' => $subject,
'message' => $message,
),
));
$body = token_replace_multiple(t(_invite_get_mail_template()), _invite_token_types($invite));
if (invite_send_invite($email, $subject, $body)) {
invite_save($invite);
$args = array(
'inviter' => $invite->inviter,
'code' => $invite->code,
);
module_invoke_all('invite', 'invite', $args);
$count_success++;
}
else {
$failed_emails[] = $email;
}
}
if ($failed_emails) {
$_SESSION['invite_failed_emails'] = serialize($failed_emails);
}
if ($count_success) {
$message = format_plural($count_success, '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 ($count_failed) {
$message = format_plural($count_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');
}
else {
if (user_access('track invitations')) {
return 'invite/list';
}
}
return 'invite';
}
function invite_max_invites($uid = NULL) {
global $user;
$account = is_null($uid) ? $user : user_load(array(
'uid' => $uid,
));
if ($account->uid == 1) {
return INVITE_UNLIMITED_INVITES;
}
$max = 0;
foreach (user_roles(0, 'send invitations') as $role) {
$role_no_space = str_replace(' ', '_', $role);
if (in_array($role, $account->roles)) {
$role_max = variable_get('invite_maxnum_' . $role_no_space, INVITE_UNLIMITED_INVITES);
if ($role_max == INVITE_UNLIMITED_INVITES) {
return INVITE_UNLIMITED_INVITES;
}
if ($role_max > $max) {
$max = $role_max;
}
}
}
return $max;
}
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_regcode() {
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_send_invite($recipient, $subject, $body) {
global $user;
$headers = array();
$from_site = variable_get('site_mail', ini_get('sendmail_from'));
if ($from_site) {
$headers['Sender'] = $headers['Return-Path'] = $headers['Errors-To'] = $from_site;
}
$from = variable_get('invite_manual_from', NULL);
$reply_to = variable_get('invite_manual_reply_to', NULL);
if (!$from) {
if ($user->uid && variable_get('invite_use_users_email', 0)) {
$from = $user->mail;
}
else {
if ($from_site) {
$from = $from_site;
}
}
}
if (!$reply_to) {
if ($user->uid && variable_get('invite_use_users_email_replyto', 0)) {
$reply_to = $user->mail;
}
else {
if ($from_site) {
$reply_to = $from_site;
}
}
}
if ($reply_to) {
$headers['Reply-To'] = $reply_to;
}
if (!($success = drupal_mail('invite-mail', $recipient, $subject, wordwrap($body, 72), $from, $headers))) {
static $error_shown = FALSE;
if (!$error_shown) {
drupal_set_message(t('Problems occurred while sending the invitation(s). Please contact the site administrator.'), 'error');
$error_shown = TRUE;
}
watchdog('invite', t('Failed sending invitation. To: @email From: @from', array(
'@email' => '<' . $recipient . '>',
'@from' => '<' . $from . '>',
)));
}
return $success;
}
function invite_save($edit) {
$edit = (array) $edit;
$expiry = time() + variable_get('invite_expiry', 30) * 60 * 60 * 24;
$data = serialize($edit['data']);
return db_query("INSERT INTO {invite} (email, reg_code, uid, expiry, data) VALUES ('%s', '%s', %d, %d, '%s')", $edit['email'], $edit['code'], $edit['inviter']->uid, $expiry, $data);
}
function invite_delete($origin, $code) {
global $user;
$invite = invite_load($code);
if ($invite->inviter->uid == $user->uid) {
if (!$invite->timestamp || user_access('withdraw accepted invitations')) {
$form['invite'] = array(
'#type' => 'value',
'#value' => $invite,
);
$description = !$invite->timestamp && $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,
)), "invite/list/{$origin}", $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', t('Detected malicious attempt to delete an invitation.'), WATCHDOG_WARNING, l(t('view'), 'user/' . $user->uid));
drupal_access_denied();
}
drupal_goto('invite/list');
}
function invite_delete_submit($form_id, $form_values) {
$invite = $form_values['invite'];
db_query("DELETE FROM {invite} 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,
);
module_invoke_all('invite', 'cancel', $args);
drupal_goto('invite/list');
}
function invite_token_values($type = 'all', $object = NULL) {
$values = array();
if ($type == 'invite' && is_object($object)) {
$values['inviter-raw'] = $object->inviter->name;
$values['invite-mail'] = $object->email;
$values['invite-message-raw'] = $object->data['message'];
$values['join-link'] = url('invite/accept/' . $object->code, NULL, NULL, TRUE);
}
return $values;
}
function invite_token_list($type = 'all') {
if ($type == 'invite' || $type == 'all') {
$tokens['invite']['inviter-raw'] = t("Inviter's name. WARNING - raw user input.");
$tokens['invite']['invite-mail'] = t('The e-mail address of the invited user.');
$tokens['invite']['invite-message-raw'] = t('The personal message for the invitee as unfiltered text. WARNING - raw user input.');
$tokens['invite']['join-link'] = t('The link to the registration page of the site.');
return $tokens;
}
}
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]", $string));
foreach ($emails as $email) {
$email = 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();
$emails_sql = "'" . implode("','", array_map('db_escape_string', $emails)) . "'";
$result = db_query(sprintf($sql, $emails_sql));
while ($row = db_fetch_object($result)) {
$failed_emails[] = $row->email;
}
$emails = array_diff($emails, $failed_emails);
return $failed_emails;
}
function _invite_validate($invite) {
if (!$invite || !$invite->inviter) {
drupal_set_message(t('This invitation has been withdrawn.'));
drupal_goto();
}
else {
if ($invite->timestamp != 0) {
drupal_set_message(t('This invitation has already been used. Please login now with your username and password.'));
drupal_goto('user');
}
else {
if ($invite->expiry < time()) {
drupal_set_message(t('Sorry, this invitation has expired.'));
drupal_goto();
}
else {
return TRUE;
}
}
}
}
function _invite_role_escalate($invitee) {
$roles = array(
'default',
);
$inviter_uid = db_result(db_query("SELECT uid FROM {invite} WHERE mid = %d", $invitee->uid));
if ($inviter_uid && ($inviter = user_load(array(
'uid' => $inviter_uid,
)))) {
$roles = array_merge($roles, array_intersect($inviter->roles, user_roles(0, 'send invitations')));
}
$targets = array();
foreach ($roles as $role) {
$role_no_space = str_replace(' ', '_', $role);
$target = variable_get('invite_target_role_' . $role_no_space, DRUPAL_AUTHENTICATED_RID);
if ($target != DRUPAL_AUTHENTICATED_RID) {
$targets[$target] = $target;
}
}
$edit = array(
'roles' => $targets,
);
user_module_invoke('update', $edit, $invitee);
foreach ($targets as $target) {
db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $invitee->uid, $target);
db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $invitee->uid, $target);
}
$args = array(
'invitee' => $invitee,
'inviter' => $inviter,
'roles' => $targets,
);
module_invoke_all('invite', 'escalate', $args);
}
function _invite_set_accepted($email, $uid, $code) {
db_query("UPDATE {invite} SET timestamp = %d, mid = %d, email = '%s' WHERE reg_code = '%s'", time(), $uid, $email, $code);
}
function _invite_check_messages($uid) {
$result = db_query('SELECT i.mid, i.email FROM {invite} i INNER JOIN {users} u ON u.uid = i.mid AND u.status = 1 WHERE i.uid = %d AND i.timestamp != 0 AND i.received = 0', $uid);
while ($invite = db_fetch_object($result)) {
$account = user_load(array(
'uid' => $invite->mid,
));
drupal_set_message(t('!user (@email) has joined @site-name!', array(
'!user' => theme('username', $account),
'@email' => $invite->email,
'@site-name' => variable_get('site_name', t('Drupal')),
)));
db_query("UPDATE {invite} SET received = 1 WHERE email = '%s'", $invite->email);
}
}
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' => '--recipient-email--',
'code' => '--invite-code--',
'data' => array(
'subject' => NULL,
'message' => NULL,
),
);
return (object) array_merge($defaults, $args);
}
function _invite_unblock($uid) {
db_query("UPDATE {users} SET status = 1 WHERE uid = %d", $uid);
}