updates for invitations
Add the code to registration to handle invitation codes. Some edge cases on invitations: is the user already subbed to this person? Tell them. Is the person already on the system? Sub the user to them, then, and tell the user. Add some code to User to auto-sub invitees whenever the email address changes. Call it from a new registration with an invite code, and also from confirmaddress. Some whitespace cleanup in the files touched. darcs-hash:20080827001927-84dde-b50e5d921ca3f2fb894821730ff93cac09d2ba66.gz
This commit is contained in:
parent
c2839a80f0
commit
e248066b74
|
@ -73,6 +73,10 @@ class ConfirmaddressAction extends Action {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($type == 'email') {
|
||||||
|
$cur->emailChanged();
|
||||||
|
}
|
||||||
|
|
||||||
$result = $confirm->delete();
|
$result = $confirm->delete();
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
|
|
|
@ -32,13 +32,13 @@ class InviteAction extends Action {
|
||||||
common_config('site', 'name')));
|
common_config('site', 'name')));
|
||||||
return;
|
return;
|
||||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
$this->send_invitation();
|
$this->send_invitations();
|
||||||
} else {
|
} else {
|
||||||
$this->show_form();
|
$this->show_form();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_invitation() {
|
function send_invitations() {
|
||||||
|
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
$profile = $user->getProfile();
|
$profile = $user->getProfile();
|
||||||
|
@ -50,49 +50,58 @@ class InviteAction extends Action {
|
||||||
$addresses = explode("\n", $this->trimmed('addresses'));
|
$addresses = explode("\n", $this->trimmed('addresses'));
|
||||||
|
|
||||||
foreach ($addresses as $email) {
|
foreach ($addresses as $email) {
|
||||||
|
|
||||||
$email = trim($email);
|
$email = trim($email);
|
||||||
|
|
||||||
if (!Validate::email($email, true)) {
|
if (!Validate::email($email, true)) {
|
||||||
$this->show_form(sprintf(_('Invalid email address: %s'), $email));
|
$this->show_form(sprintf(_('Invalid email address: %s'), $email));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$already = array();
|
||||||
|
$subbed = array();
|
||||||
|
|
||||||
foreach ($addresses as $email) {
|
foreach ($addresses as $email) {
|
||||||
|
$email = common_canonical_email($email);
|
||||||
$email = trim($email);
|
$other = User::staticGet('email', $email);
|
||||||
|
if ($other) {
|
||||||
$recipients = array($email);
|
if ($user->isSubscribed($other)) {
|
||||||
|
$already[] = $other;
|
||||||
$headers['From'] = mail_notify_from();
|
} else {
|
||||||
$headers['To'] = $email;
|
subs_subscribe_to($user, $other);
|
||||||
$headers['Subject'] = sprintf(_('%1s has invited you to join them on %2s'), $bestname, $sitename);
|
$subbed[] = $other;
|
||||||
|
}
|
||||||
$body = sprintf(_("%1s has invited you to join them on %2s (%3s).\n\n".
|
} else {
|
||||||
"%4s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
|
$sent[] = $email;
|
||||||
"You can also share news about yourself, your thoughts, or your life online with people who know about you.\n\n".
|
$this->send_invitation($email, $user);
|
||||||
"%5s said:\n\n%6s\n\n".
|
}
|
||||||
"You can see %7s's profile page on %8s here:\n\n".
|
|
||||||
"%9s\n\n".
|
|
||||||
"If you'd like to try the service, click on the link below to accept the invitation.\n\n".
|
|
||||||
"%10s\n\n".
|
|
||||||
"If not, you can ignore this message. Thanks for your patience and your time.\n\n".
|
|
||||||
"Sincerely, %11s\n"),
|
|
||||||
$bestname, $sitename, common_root_url(),
|
|
||||||
$sitename,
|
|
||||||
$bestname, $personal,
|
|
||||||
$bestname, $sitename,
|
|
||||||
common_local_url('showstream', array('nickname' => $user->nickname)),
|
|
||||||
common_local_url('register', array('code' => $invite->code)),
|
|
||||||
$sitename);
|
|
||||||
|
|
||||||
mail_send($recipients, $headers, $body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
common_show_header(_('Invitation(s) sent'));
|
common_show_header(_('Invitation(s) sent'));
|
||||||
common_element('p', NULL, _('Invitation(s) sent. You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
|
if ($already) {
|
||||||
|
common_element('p', NULL, _('You are already subscribed to these users:'));
|
||||||
|
common_element_start('ul');
|
||||||
|
foreach ($already as $other) {
|
||||||
|
common_element('li', NULL, sprintf(_('%s (%s)'), $other->nickname, $other->email));
|
||||||
|
}
|
||||||
|
common_element_end('ul');
|
||||||
|
}
|
||||||
|
if ($subbed) {
|
||||||
|
common_element('p', NULL, _('These people are already users and you were automatically subscribed to them:'));
|
||||||
|
common_element_start('ul');
|
||||||
|
foreach ($subbed as $other) {
|
||||||
|
common_element('li', NULL, sprintf(_('%s (%s)'), $other->nickname, $other->email));
|
||||||
|
}
|
||||||
|
common_element_end('ul');
|
||||||
|
}
|
||||||
|
if ($sent) {
|
||||||
|
common_element('p', NULL, _('Invitation(s) sent to the following people:'));
|
||||||
|
common_element_start('ul');
|
||||||
|
foreach ($sent as $other) {
|
||||||
|
common_element('li', NULL, $sent);
|
||||||
|
}
|
||||||
|
common_element_end('ul');
|
||||||
|
common_element('p', NULL, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
|
||||||
|
}
|
||||||
common_show_footer();
|
common_show_footer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,4 +140,48 @@ class InviteAction extends Action {
|
||||||
|
|
||||||
common_show_footer();
|
common_show_footer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function send_invitation($email, $user) {
|
||||||
|
|
||||||
|
$email = trim($email);
|
||||||
|
|
||||||
|
$invite = new Invitation();
|
||||||
|
|
||||||
|
$invite->address = $email;
|
||||||
|
$invite->type = 'email';
|
||||||
|
$invite->user_id = $user->id;
|
||||||
|
$invite->created = common_sql_now();
|
||||||
|
|
||||||
|
if (!$invite->insert()) {
|
||||||
|
common_log_db_error($invite, 'INSERT', __FILE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$recipients = array($email);
|
||||||
|
|
||||||
|
$headers['From'] = mail_notify_from();
|
||||||
|
$headers['To'] = $email;
|
||||||
|
$headers['Subject'] = sprintf(_('%1s has invited you to join them on %2s'), $bestname, $sitename);
|
||||||
|
|
||||||
|
$body = sprintf(_("%1s has invited you to join them on %2s (%3s).\n\n".
|
||||||
|
"%4s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
|
||||||
|
"You can also share news about yourself, your thoughts, or your life online with people who know about you.\n\n".
|
||||||
|
"%5s said:\n\n%6s\n\n".
|
||||||
|
"You can see %7s's profile page on %8s here:\n\n".
|
||||||
|
"%9s\n\n".
|
||||||
|
"If you'd like to try the service, click on the link below to accept the invitation.\n\n".
|
||||||
|
"%10s\n\n".
|
||||||
|
"If not, you can ignore this message. Thanks for your patience and your time.\n\n".
|
||||||
|
"Sincerely, %11s\n"),
|
||||||
|
$bestname, $sitename, common_root_url(),
|
||||||
|
$sitename,
|
||||||
|
$bestname, $personal,
|
||||||
|
$bestname, $sitename,
|
||||||
|
common_local_url('showstream', array('nickname' => $user->nickname)),
|
||||||
|
common_local_url('register', array('code' => $invite->code)),
|
||||||
|
$sitename);
|
||||||
|
|
||||||
|
mail_send($recipients, $headers, $body);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,10 @@ class RegisterAction extends Action {
|
||||||
$password = $this->arg('password');
|
$password = $this->arg('password');
|
||||||
$confirm = $this->arg('confirm');
|
$confirm = $this->arg('confirm');
|
||||||
|
|
||||||
|
# invitation code, if any
|
||||||
|
|
||||||
|
$code = $this->trimmed('code');
|
||||||
|
|
||||||
# Input scrubbing
|
# Input scrubbing
|
||||||
|
|
||||||
$nickname = common_canonical_nickname($nickname);
|
$nickname = common_canonical_nickname($nickname);
|
||||||
|
@ -94,7 +98,7 @@ class RegisterAction extends Action {
|
||||||
$this->show_form(_('Passwords don\'t match.'));
|
$this->show_form(_('Passwords don\'t match.'));
|
||||||
} else if ($user = User::register(array('nickname' => $nickname, 'password' => $password, 'email' => $email,
|
} else if ($user = User::register(array('nickname' => $nickname, 'password' => $password, 'email' => $email,
|
||||||
'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio,
|
'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio,
|
||||||
'location' => $location))) {
|
'location' => $location, 'code' => $code))) {
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
$this->show_form(_('Invalid username or password.'));
|
$this->show_form(_('Invalid username or password.'));
|
||||||
return;
|
return;
|
||||||
|
@ -149,15 +153,19 @@ class RegisterAction extends Action {
|
||||||
common_element_start('form', array('method' => 'post',
|
common_element_start('form', array('method' => 'post',
|
||||||
'id' => 'login',
|
'id' => 'login',
|
||||||
'action' => common_local_url('register')));
|
'action' => common_local_url('register')));
|
||||||
common_hidden('token', common_session_token());
|
|
||||||
common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
|
common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
|
||||||
_('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
|
_('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
|
||||||
common_password('password', _('Password'),
|
common_password('password', _('Password'),
|
||||||
_('6 or more characters. Required.'));
|
_('6 or more characters. Required.'));
|
||||||
common_password('confirm', _('Confirm'),
|
common_password('confirm', _('Confirm'),
|
||||||
_('Same as password above. Required.'));
|
_('Same as password above. Required.'));
|
||||||
|
if ($invite && $invite->address_type == 'email') {
|
||||||
|
common_input('email', _('Email'), $invite->address,
|
||||||
|
_('Used only for updates, announcements, and password recovery'));
|
||||||
|
} else {
|
||||||
common_input('email', _('Email'), $this->trimmed('email'),
|
common_input('email', _('Email'), $this->trimmed('email'),
|
||||||
_('Used only for updates, announcements, and password recovery'));
|
_('Used only for updates, announcements, and password recovery'));
|
||||||
|
}
|
||||||
common_input('fullname', _('Full name'),
|
common_input('fullname', _('Full name'),
|
||||||
$this->trimmed('fullname'),
|
$this->trimmed('fullname'),
|
||||||
_('Longer name, preferably your "real" name'));
|
_('Longer name, preferably your "real" name'));
|
||||||
|
|
|
@ -131,7 +131,7 @@ class User extends DB_DataObject
|
||||||
$sub->subscriber = $this->id;
|
$sub->subscriber = $this->id;
|
||||||
$sub->subscribed = $other->id;
|
$sub->subscribed = $other->id;
|
||||||
|
|
||||||
$sub->created = DB_DataObject_Cast::dateTime(); # current time
|
$sub->created = common_sql_now(); # current time
|
||||||
|
|
||||||
if (!$sub->insert()) {
|
if (!$sub->insert()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -142,16 +142,6 @@ class User extends DB_DataObject
|
||||||
|
|
||||||
function noticesWithFriends($offset=0, $limit=20) {
|
function noticesWithFriends($offset=0, $limit=20) {
|
||||||
|
|
||||||
# We clearly need a more elegant way to make this work.
|
|
||||||
|
|
||||||
if (common_config('memcached', 'enabled')) {
|
|
||||||
if ($offset + $limit <= WITHFRIENDS_CACHE_WINDOW) {
|
|
||||||
$cached = $this->noticesWithFriendsWindow();
|
|
||||||
$wrapper = new NoticeWrapper(array_slice($cached, $offset, $limit));
|
|
||||||
return $wrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
|
|
||||||
$notice->query('SELECT notice.* ' .
|
$notice->query('SELECT notice.* ' .
|
||||||
|
@ -163,39 +153,6 @@ class User extends DB_DataObject
|
||||||
return $notice;
|
return $notice;
|
||||||
}
|
}
|
||||||
|
|
||||||
function noticesWithFriendsWindow() {
|
|
||||||
|
|
||||||
$cache = new Memcache();
|
|
||||||
$res = $cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'));
|
|
||||||
|
|
||||||
if (!$res) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notices = $cache->get(common_cache_key('user:notices_with_friends:' . $this->id));
|
|
||||||
|
|
||||||
if ($notices) {
|
|
||||||
return $notices;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notice = new Notice();
|
|
||||||
|
|
||||||
$notice->query('SELECT notice.* ' .
|
|
||||||
'FROM notice JOIN subscription on notice.profile_id = subscription.subscribed ' .
|
|
||||||
'WHERE subscription.subscriber = ' . $this->id . ' ' .
|
|
||||||
'ORDER BY created DESC, notice.id DESC ' .
|
|
||||||
'LIMIT 0, ' . WITHFRIENDS_CACHE_WINDOW);
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
$cache->set(common_cache_key('user:notices_with_friends:' . $this->id), $notices);
|
|
||||||
return $notices;
|
|
||||||
}
|
|
||||||
|
|
||||||
static function register($fields) {
|
static function register($fields) {
|
||||||
|
|
||||||
# MAGICALLY put fields into current scope
|
# MAGICALLY put fields into current scope
|
||||||
|
@ -240,6 +197,15 @@ class User extends DB_DataObject
|
||||||
$user->password = common_munge_password($password, $id);
|
$user->password = common_munge_password($password, $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Users who respond to invite email have proven their ownership of that address
|
||||||
|
|
||||||
|
if ($code) {
|
||||||
|
$invite = Invite::staticGet($code);
|
||||||
|
if ($invite && $invite->address && $invite->address_type == 'email') {
|
||||||
|
$user->email = $invite->address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$user->created = common_sql_now();
|
$user->created = common_sql_now();
|
||||||
$user->uri = common_user_uri($user);
|
$user->uri = common_user_uri($user);
|
||||||
|
|
||||||
|
@ -264,7 +230,7 @@ class User extends DB_DataObject
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($email) {
|
if ($email && !$code) {
|
||||||
|
|
||||||
$confirm = new Confirm_address();
|
$confirm = new Confirm_address();
|
||||||
$confirm->code = common_confirmation_code(128);
|
$confirm->code = common_confirmation_code(128);
|
||||||
|
@ -279,9 +245,13 @@ class User extends DB_DataObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($code && $user->email) {
|
||||||
|
$user->emailChanged();
|
||||||
|
}
|
||||||
|
|
||||||
$profile->query('COMMIT');
|
$profile->query('COMMIT');
|
||||||
|
|
||||||
if ($email) {
|
if ($email && !$code) {
|
||||||
mail_confirm_address($confirm->code,
|
mail_confirm_address($confirm->code,
|
||||||
$profile->nickname,
|
$profile->nickname,
|
||||||
$email);
|
$email);
|
||||||
|
@ -289,4 +259,20 @@ class User extends DB_DataObject
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Things we do when the email changes
|
||||||
|
|
||||||
|
function emailChanged() {
|
||||||
|
|
||||||
|
$invites = new Invitation();
|
||||||
|
$invites->address = $user->email;
|
||||||
|
$invites->address_type = 'email';
|
||||||
|
|
||||||
|
if ($invites->find()) {
|
||||||
|
while ($invites->fetch()) {
|
||||||
|
$other = User::staticGet($invites->user_id);
|
||||||
|
subs_subscribe_to($other, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ RewriteRule ^doc/source$ index.php?action=doc&title=source [L,QSA]
|
||||||
|
|
||||||
RewriteRule ^main/login$ index.php?action=login [L,QSA]
|
RewriteRule ^main/login$ index.php?action=login [L,QSA]
|
||||||
RewriteRule ^main/logout$ index.php?action=logout [L,QSA]
|
RewriteRule ^main/logout$ index.php?action=logout [L,QSA]
|
||||||
|
RewriteRule ^main/register/(.*)$ index.php?action=register&code=$1 [L,QSA]
|
||||||
RewriteRule ^main/register$ index.php?action=register [L,QSA]
|
RewriteRule ^main/register$ index.php?action=register [L,QSA]
|
||||||
RewriteRule ^main/openid$ index.php?action=openidlogin [L,QSA]
|
RewriteRule ^main/openid$ index.php?action=openidlogin [L,QSA]
|
||||||
RewriteRule ^main/remote$ index.php?action=remotesubscribe [L,QSA]
|
RewriteRule ^main/remote$ index.php?action=remotesubscribe [L,QSA]
|
||||||
|
|
|
@ -816,11 +816,16 @@ function common_fancy_url($action, $args=NULL) {
|
||||||
return common_path('doc/'.$args['title']);
|
return common_path('doc/'.$args['title']);
|
||||||
case 'login':
|
case 'login':
|
||||||
case 'logout':
|
case 'logout':
|
||||||
case 'register':
|
|
||||||
case 'subscribe':
|
case 'subscribe':
|
||||||
case 'unsubscribe':
|
case 'unsubscribe':
|
||||||
case 'invite':
|
case 'invite':
|
||||||
return common_path('main/'.$action);
|
return common_path('main/'.$action);
|
||||||
|
case 'register':
|
||||||
|
if ($args && $args['code']) {
|
||||||
|
return common_path('main/register/'.$args['code']);
|
||||||
|
} else {
|
||||||
|
return common_path('main/register');
|
||||||
|
}
|
||||||
case 'remotesubscribe':
|
case 'remotesubscribe':
|
||||||
if ($args && $args['nickname']) {
|
if ($args && $args['nickname']) {
|
||||||
return common_path('main/remote?nickname=' . $args['nickname']);
|
return common_path('main/remote?nickname=' . $args['nickname']);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user