]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
updates for invitations
authorEvan Prodromou <evan@prodromou.name>
Wed, 27 Aug 2008 00:19:27 +0000 (20:19 -0400)
committerEvan Prodromou <evan@prodromou.name>
Wed, 27 Aug 2008 00:19:27 +0000 (20:19 -0400)
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

actions/confirmaddress.php
actions/invite.php
actions/register.php
classes/User.php
htaccess.sample
lib/util.php

index 3cffda8710b59c15efa87ca347c22e087df3e073..44280e08a7543cf15dc373244042c5a489b63ec0 100644 (file)
@@ -73,6 +73,10 @@ class ConfirmaddressAction extends Action {
             return;
         }
 
+               if ($type == 'email') {
+                   $cur->emailChanged();
+               }
+
         $result = $confirm->delete();
 
         if (!$result) {
index e230ec6eea7373f1ec0cbd712f5035c5aaaac48a..3a68a60de93708eb85b66b6655f1960d768d6454 100644 (file)
 if (!defined('LACONICA')) { exit(1); }
 
 class InviteAction extends Action {
-       
-       function is_readonly() {                                
+
+       function is_readonly() {
                return false;
        }
-       
+
     function handle($args) {
         parent::handle($args);
                if (!common_logged_in()) {
@@ -32,70 +32,79 @@ class InviteAction extends Action {
                                                                                common_config('site', 'name')));
                        return;
                } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->send_invitation();
+                       $this->send_invitations();
                } else {
                        $this->show_form();
                }
        }
-       
-       function send_invitation() {
-               
+
+       function send_invitations() {
+
                $user = common_current_user();
                $profile = $user->getProfile();
-               
+
                $bestname = $profile->getBestName();
                $sitename = common_config('site', 'name');
                $personal = $this->trimmed('personal');
 
                $addresses = explode("\n", $this->trimmed('addresses'));
-               
+
                foreach ($addresses as $email) {
-                       
                        $email = trim($email);
-                       
                        if (!Validate::email($email, true)) {
                                $this->show_form(sprintf(_('Invalid email address: %s'), $email));
                                return;
                        }
                }
-               
+
+               $already = array();
+               $subbed = array();
+
                foreach ($addresses as $email) {
-                       
-                       $email = trim($email);
-                       
-                       $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);
+                       $email = common_canonical_email($email);
+                       $other = User::staticGet('email', $email);
+                       if ($other) {
+                               if ($user->isSubscribed($other)) {
+                                       $already[] = $other;
+                               } else {
+                                       subs_subscribe_to($user, $other);
+                                       $subbed[] = $other;
+                               }
+                       } else {
+                               $sent[] = $email;
+                               $this->send_invitation($email, $user);
+                       }
                }
-               
 
                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();
        }
-       
+
        function show_top($error=NULL) {
                if ($error) {
                        common_element('p', 'error', $error);
@@ -108,7 +117,7 @@ class InviteAction extends Action {
        }
 
        function show_form($error=NULL) {
-               
+
                global $config;
 
                common_show_header(_('Invite new users'), NULL, $error, array($this, 'show_top'));
@@ -120,15 +129,59 @@ class InviteAction extends Action {
                common_textarea('addresses', _('Email addresses'),
                                                $this->trimmed('addresses'),
                                                _('Addresses of friends to invite (one per line)'));
-               
+
                common_textarea('personal', _('Personal message'),
                                                $this->trimmed('personal'),
                                                _('Optionally add a personal message to the invitation.'));
-               
+
                common_submit('preview', _('Preview'));
 
                common_element_end('form');
-               
+
                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);
+       }
+
 }
index f366bd3e0015a1ac38151d00254c22c0c065da15..9a871dd53f58539f1b29b472ebcc25ca0fcf862e 100644 (file)
@@ -55,6 +55,10 @@ class RegisterAction extends Action {
                $password = $this->arg('password');
                $confirm = $this->arg('confirm');
 
+               # invitation code, if any
+
+               $code = $this->trimmed('code');
+
                # Input scrubbing
 
                $nickname = common_canonical_nickname($nickname);
@@ -93,8 +97,8 @@ class RegisterAction extends Action {
                } else if ($password != $confirm) {
                        $this->show_form(_('Passwords don\'t match.'));
                } else if ($user = User::register(array('nickname' => $nickname, 'password' => $password, 'email' => $email,
-                                                                                               'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio, 
-                                                                                               'location' => $location))) {
+                                                                                               'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio,
+                                                                                               'location' => $location, 'code' => $code))) {
                        if (!$user) {
                                $this->show_form(_('Invalid username or password.'));
                                return;
@@ -149,15 +153,19 @@ class RegisterAction extends Action {
                common_element_start('form', array('method' => 'post',
                                                                                   'id' => 'login',
                                                                                   'action' => common_local_url('register')));
-               common_hidden('token', common_session_token());
                common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
                                         _('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
                common_password('password', _('Password'),
                                                _('6 or more characters. Required.'));
                common_password('confirm', _('Confirm'),
                                                _('Same as password above. Required.'));
-               common_input('email', _('Email'), $this->trimmed('email'),
+               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'),
+                                                _('Used only for updates, announcements, and password recovery'));
+               }
                common_input('fullname', _('Full name'),
                                         $this->trimmed('fullname'),
                                          _('Longer name, preferably your "real" name'));
@@ -170,7 +178,7 @@ class RegisterAction extends Action {
                common_input('location', _('Location'),
                                         $this->trimmed('location'),
                                         _('Where you are, like "City, State (or Region), Country"'));
-               common_checkbox('rememberme', _('Remember me'), 
+               common_checkbox('rememberme', _('Remember me'),
                                                $this->boolean('rememberme'),
                                _('Automatically login in the future; not for shared computers!'));
                common_element_start('p');
@@ -191,7 +199,7 @@ class RegisterAction extends Action {
                common_element_end('form');
                common_show_footer();
        }
-                                               
+
        function show_success() {
                $nickname = $this->arg('nickname');
                common_show_header(_('Registration successful'));
@@ -214,5 +222,5 @@ class RegisterAction extends Action {
                common_element_end('div');
                common_show_footer();
        }
-                                               
+
 }
index 62f38ebffb62117cc10a2bcbf063cbd4b17aa716..cdb6568f0cb7060f10e69174d74e7043a08cdbec 100644 (file)
@@ -121,94 +121,51 @@ class User extends DB_DataObject
                }
                return $profile->getCurrentNotice($dt);
        }
-       
+
        function getCarrier() {
                return Sms_carrier::staticGet($this->carrier);
        }
-       
+
        function subscribeTo($other) {
                $sub = new Subscription();
                $sub->subscriber = $this->id;
                $sub->subscribed = $other->id;
 
-               $sub->created = DB_DataObject_Cast::dateTime(); # current time
+               $sub->created = common_sql_now(); # current time
 
                if (!$sub->insert()) {
                        return false;
                }
-               
+
                return true;
        }
 
        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->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 ' . $offset . ', ' . $limit);
-               
-               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);
-               }
+                                          'LIMIT ' . $offset . ', ' . $limit);
 
-               $cache->set(common_cache_key('user:notices_with_friends:' . $this->id), $notices);
-               return $notices;
+               return $notice;
        }
        
        static function register($fields) {
 
                # MAGICALLY put fields into current scope
-               
+
                extract($fields);
-               
+
                $profile = new Profile();
 
                $profile->query('BEGIN');
 
                $profile->nickname = $nickname;
                $profile->profileurl = common_profile_url($nickname);
-               
+
                if ($fullname) {
                        $profile->fullname = $fullname;
                }
@@ -221,25 +178,34 @@ class User extends DB_DataObject
                if ($location) {
                        $profile->location = $location;
                }
-               
+
                $profile->created = common_sql_now();
-               
+
                $id = $profile->insert();
 
                if (!$id) {
                        common_log_db_error($profile, 'INSERT', __FILE__);
                    return FALSE;
                }
-               
+
                $user = new User();
-               
+
                $user->id = $id;
                $user->nickname = $nickname;
 
                if ($password) { # may not have a password for OpenID users
                        $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->uri = common_user_uri($user);
 
@@ -256,15 +222,15 @@ class User extends DB_DataObject
                $subscription->subscriber = $user->id;
                $subscription->subscribed = $user->id;
                $subscription->created = $user->created;
-               
+
                $result = $subscription->insert();
-               
+
                if (!$result) {
                        common_log_db_error($subscription, 'INSERT', __FILE__);
                        return FALSE;
                }
-               
-               if ($email) {
+
+               if ($email && !$code) {
 
                        $confirm = new Confirm_address();
                        $confirm->code = common_confirmation_code(128);
@@ -279,9 +245,13 @@ class User extends DB_DataObject
                        }
                }
 
+               if ($code && $user->email) {
+                       $user->emailChanged();
+               }
+
                $profile->query('COMMIT');
 
-               if ($email) {
+               if ($email && !$code) {
                        mail_confirm_address($confirm->code,
                                                                 $profile->nickname,
                                                                 $email);
@@ -289,4 +259,20 @@ class User extends DB_DataObject
 
                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);
+                       }
+               }
+       }
 }
index db8c43e743b0c53f8ffa356b84110ccd1e3ed851..982b605786326d20488fcbb3a4a3034a59aeed8f 100644 (file)
@@ -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/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/openid$ index.php?action=openidlogin [L,QSA]
 RewriteRule ^main/remote$ index.php?action=remotesubscribe [L,QSA]
index 0b463b211cd609a2b5b3a133d6a931460a2a2f56..eeb2d7f6412f90d7528a0575230e5c3091ff8f37 100644 (file)
@@ -136,7 +136,7 @@ function common_init_language() {
        $language = common_language();
        # So we don't have to make people install the gettext locales
        putenv('LANGUAGE='.$language);
-       putenv('LANG='.$language);      
+       putenv('LANG='.$language);
        $locale_set = setlocale(LC_ALL, $language . ".utf8",
                                                        $language . ".UTF8",
                                                        $language . ".utf-8",
@@ -816,11 +816,16 @@ function common_fancy_url($action, $args=NULL) {
                return common_path('doc/'.$args['title']);
         case 'login':
         case 'logout':
-        case 'register':
         case 'subscribe':
         case 'unsubscribe':
         case 'invite':
                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':
                if ($args && $args['nickname']) {
                        return common_path('main/remote?nickname=' . $args['nickname']);