3 * StatusNet - the distributed open-source microblogging tool
4 * Copyright (C) 2008-2011, StatusNet, Inc.
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 if (!defined('GNUSOCIAL')) { exit(1); }
22 // @todo XXX: Add documentation.
23 class InviteAction extends Action
31 function showNoticeForm()
36 function isReadOnly(array $args=array())
41 function handle(array $args=array())
43 parent::handle($args);
44 if (!common_config('invite', 'enabled')) {
45 // TRANS: Client error displayed when trying to sent invites while they have been disabled.
46 $this->clientError(_('Invites have been disabled.'));
47 } else if (!common_logged_in()) {
48 // TRANS: Client error displayed when trying to sent invites while not logged in.
49 // TRANS: %s is the StatusNet site name.
50 $this->clientError(sprintf(_('You must be logged in to invite other users to use %s.'),
51 common_config('site', 'name')));
53 } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
54 $this->sendInvitations();
60 function sendInvitations()
62 if (Event::handle('StartSendInvitations', array(&$this))) {
64 $token = $this->trimmed('token');
65 if (!$token || $token != common_session_token()) {
66 // TRANS: Client error displayed when the session token does not match or is not given.
67 $this->showForm(_('There was a problem with your session token. Try again, please.'));
71 $user = common_current_user();
72 $profile = $user->getProfile();
74 $bestname = $profile->getBestName();
75 $sitename = common_config('site', 'name');
76 $personal = $this->trimmed('personal');
77 $language = $this->trimmed('language');
79 $addresses = explode("\n", $this->trimmed('addresses'));
80 foreach ($addresses as $email) {
81 $email = trim($email);
86 if (Event::handle('StartValidateUserEmail', array(null, $email, &$valid))) {
87 $valid = Validate::email($email, common_config('email', 'check_domain'));
88 Event::handle('EndValidateUserEmail', array(null, $email, &$valid));
92 if (Event::handle('StartValidateEmailInvite', array($user, $email, &$valid))) {
94 Event::handle('EndValidateEmailInvite', array($user, $email, &$valid));
99 // TRANS: Form validation message when providing an e-mail address that does not validate.
100 // TRANS: %s is an invalid e-mail address.
101 $this->showForm(sprintf(_('Invalid email address: %s.'), $email));
104 } catch (ClientException $e) {
105 $this->showForm($e->getMessage());
110 $this->already = array();
111 $this->subbed = array();
113 foreach ($addresses as $email) {
114 $email = common_canonical_email($email);
116 // If this user is already registered, subscribe to it!
117 $other = Profile::getByEmail($email);
118 if ($user->isSubscribed($other)) {
119 $this->already[] = $other;
122 Subscription::start($profile, $other);
123 $this->subbed[] = $other;
124 } catch (Exception $e) {
125 // subscription failed, but keep working
126 common_debug('Invitation-based subscription failed: '.$e->getMessage());
129 } catch (NoSuchUserException $e) {
130 // If email was not known, let's send an invite!
131 $this->sent[] = $email;
132 $this->sendInvitation($email, $user, $personal, $language);
136 $this->mode = 'sent';
139 Event::handle('EndSendInvitations', array($this));
143 function showScripts()
145 parent::showScripts();
146 $this->autofocus('addresses');
151 if ($this->mode == 'sent') {
152 // TRANS: Page title when invitations have been sent.
153 return _('Invitations sent');
155 // TRANS: Page title when inviting potential users.
156 return _('Invite new users');
160 function showContent()
162 if ($this->mode == 'sent') {
163 $this->showInvitationSuccess();
165 $this->showInviteForm();
169 function showInvitationSuccess()
171 if (Event::handle('StartShowInvitationSuccess', array($this))) {
172 if ($this->already) {
173 // TRANS: Message displayed inviting users to use a StatusNet site while the inviting user
174 // TRANS: is already subscribed to one or more users with the given e-mail address(es).
175 // TRANS: Plural form is based on the number of reported already subscribed e-mail addresses.
176 // TRANS: Followed by a bullet list.
177 $this->element('p', null, _m('You are already subscribed to this user:',
178 'You are already subscribed to these users:',
179 count($this->already)));
180 $this->elementStart('ul');
181 foreach ($this->already as $other) {
182 // TRANS: Used as list item for already subscribed users (%1$s is nickname, %2$s is e-mail address).
183 $this->element('li', null, sprintf(_m('INVITE','%1$s (%2$s)'), $other->nickname, $other->email));
185 $this->elementEnd('ul');
188 // TRANS: Message displayed inviting users to use a StatusNet site while the invited user
189 // TRANS: already uses a this StatusNet site. Plural form is based on the number of
190 // TRANS: reported already present people. Followed by a bullet list.
191 $this->element('p', null, _m('This person is already a user and you were automatically subscribed:',
192 'These people are already users and you were automatically subscribed to them:',
193 count($this->subbed)));
194 $this->elementStart('ul');
195 foreach ($this->subbed as $other) {
196 // TRANS: Used as list item for already registered people (%1$s is nickname, %2$s is e-mail address).
197 $this->element('li', null, sprintf(_m('INVITE','%1$s (%2$s)'), $other->nickname, $other->email));
199 $this->elementEnd('ul');
202 // TRANS: Message displayed inviting users to use a StatusNet site. Plural form is
203 // TRANS: based on the number of invitations sent. Followed by a bullet list of
204 // TRANS: e-mail addresses to which invitations were sent.
205 $this->element('p', null, _m('Invitation sent to the following person:',
206 'Invitations sent to the following people:',
207 count($this->sent)));
208 $this->elementStart('ul');
209 foreach ($this->sent as $other) {
210 $this->element('li', null, $other);
212 $this->elementEnd('ul');
213 // TRANS: Generic message displayed after sending out one or more invitations to
214 // TRANS: people to join a StatusNet site.
215 $this->element('p', null, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
217 Event::handle('EndShowInvitationSuccess', array($this));
221 function showPageNotice()
223 if ($this->mode != 'sent') {
225 $this->element('p', 'error', $this->error);
227 $this->elementStart('div', 'instructions');
228 $this->element('p', null,
229 // TRANS: Form instructions.
230 _('Use this form to invite your friends and colleagues to use this service.'));
231 $this->elementEnd('div');
236 function showForm($error=null)
238 $this->mode = 'form';
239 $this->error = $error;
243 function showInviteForm()
245 if (Event::handle('StartShowInviteForm', array($this))) {
246 $form = new InviteForm($this);
248 Event::handle('EndShowInviteForm', array($this));
252 function sendInvitation($email, $user, $personal, $language)
254 $profile = $user->getProfile();
255 $bestname = $profile->getBestName();
257 $sitename = common_config('site', 'name');
259 $invite = new Invitation();
261 $invite->address = $email;
262 $invite->address_type = 'email';
263 $invite->code = common_confirmation_code(128);
264 $invite->user_id = $user->id;
265 $invite->created = common_sql_now();
267 if (!$invite->insert()) {
268 common_log_db_error($invite, 'INSERT', __FILE__);
272 $confirmUrl = common_local_url('register', array('code' => $invite->code));
274 $recipients = array($email);
276 $headers['From'] = mail_notify_from();
277 $headers['To'] = trim($email);
278 $headers['Content-Type'] = 'text/html; charset=UTF-8';
280 // TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral
281 // TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, $2$s is
282 // TRANS: the StatusNet sitename.
283 $headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename);
285 $title = (empty($personal)) ? 'invite' : 'invitepersonal';
287 // @todo FIXME: i18n issue.
288 $inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths(), $language);
290 $body = $inviteTemplate->toHTML(array('inviter' => $bestname,
291 'inviterurl' => $profile->profileurl,
292 'confirmurl' => $confirmUrl,
293 'personal' => $personal));
295 common_debug('Confirm URL is ' . common_local_url('register', array('code' => $invite->code)));
297 mail_send($recipients, $headers, $body);