]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/invite.php
Merge remote-tracking branch 'upstream/master' into social-master
[quix0rs-gnu-social.git] / actions / invite.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2008-2011, StatusNet, Inc.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 if (!defined('GNUSOCIAL')) { exit(1); }
21
22 // @todo XXX: Add documentation.
23 class InviteAction extends Action
24 {
25     var $mode = null;
26     var $error = null;
27     var $already = null;
28     var $subbed = null;
29     var $sent = null;
30
31     function showNoticeForm()
32     {
33         return;
34     }
35
36     function isReadOnly(array $args=array())
37     {
38         return false;
39     }
40
41     function handle(array $args=array())
42     {
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')));
52             return;
53         } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
54             $this->sendInvitations();
55         } else {
56             $this->showForm();
57         }
58     }
59
60     function sendInvitations()
61     {
62         if (Event::handle('StartSendInvitations', array(&$this))) {
63             // CSRF protection
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.'));
68                 return;
69             }
70
71             $user = common_current_user();
72             $profile = $user->getProfile();
73
74             $bestname = $profile->getBestName();
75             $sitename = common_config('site', 'name');
76             $personal = $this->trimmed('personal');
77             $language = $this->trimmed('language');
78
79             $addresses = explode("\n", $this->trimmed('addresses'));
80             foreach ($addresses as $email) {
81                 $email = trim($email);
82                 $valid = null;
83
84                 try {
85
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));
89                     }
90
91                     if ($valid) {
92                         if (Event::handle('StartValidateEmailInvite', array($user, $email, &$valid))) {
93                             $valid = true;
94                             Event::handle('EndValidateEmailInvite', array($user, $email, &$valid));
95                         }
96                     }
97
98                     if (!$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));
102                         return;
103                     }
104                 } catch (ClientException $e) {
105                     $this->showForm($e->getMessage());
106                     return;
107                 }
108             }
109
110             $this->already = array();
111             $this->subbed = array();
112
113             foreach ($addresses as $email) {
114                 $email = common_canonical_email($email);
115                 try {
116                     // If this user is already registered, subscribe to it!
117                     $other = Profile::getByEmail($email);
118                     if ($user->isSubscribed($other)) {
119                         $this->already[] = $other;
120                     } else {
121                         try {
122                             Subscription::ensureStart($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());
127                         }
128                     }
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);
133                 }
134             }
135
136             $this->mode = 'sent';
137
138             $this->showPage();
139             Event::handle('EndSendInvitations', array($this));
140         }
141     }
142
143     function showScripts()
144     {
145         parent::showScripts();
146         $this->autofocus('addresses');
147     }
148
149     function title()
150     {
151         if ($this->mode == 'sent') {
152             // TRANS: Page title when invitations have been sent.
153             return _('Invitations sent');
154         } else {
155             // TRANS: Page title when inviting potential users.
156             return _('Invite new users');
157         }
158     }
159
160     function showContent()
161     {
162         if ($this->mode == 'sent') {
163             $this->showInvitationSuccess();
164         } else {
165             $this->showInviteForm();
166         }
167     }
168
169     function showInvitationSuccess()
170     {
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));
184                 }
185                 $this->elementEnd('ul');
186             }
187             if ($this->subbed) {
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));
198                 }
199                 $this->elementEnd('ul');
200             }
201             if ($this->sent) {
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);
211                 }
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!'));
216             }
217             Event::handle('EndShowInvitationSuccess', array($this));
218         }
219     }
220
221     function showPageNotice()
222     {
223         if ($this->mode != 'sent') {
224             if ($this->error) {
225                 $this->element('p', 'error', $this->error);
226             } else {
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');
232             }
233         }
234     }
235
236     function showForm($error=null)
237     {
238         $this->mode = 'form';
239         $this->error = $error;
240         $this->showPage();
241     }
242
243     function showInviteForm()
244     {
245         if (Event::handle('StartShowInviteForm', array($this))) {
246             $form = new InviteForm($this);
247             $form->show();
248             Event::handle('EndShowInviteForm', array($this));
249         }
250     }
251
252     function sendInvitation($email, $user, $personal, $language)
253     {
254         $profile = $user->getProfile();
255         $bestname = $profile->getBestName();
256
257         $sitename = common_config('site', 'name');
258
259         $invite = new Invitation();
260
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();
266
267         if (!$invite->insert()) {
268             common_log_db_error($invite, 'INSERT', __FILE__);
269             return false;
270         }
271
272         $confirmUrl = common_local_url('register', array('code' => $invite->code));
273
274         $recipients = array($email);
275
276         $headers['From'] = mail_notify_from();
277         $headers['To'] = trim($email);
278         $headers['Content-Type'] = 'text/html; charset=UTF-8';
279
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);
284
285         $title = (empty($personal)) ? 'invite' : 'invitepersonal';
286
287         // @todo FIXME: i18n issue.
288         $inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths(), $language);
289
290         $body = $inviteTemplate->toHTML(array('inviter' => $bestname,
291                                               'inviterurl' => $profile->profileurl,
292                                               'confirmurl' => $confirmUrl,
293                                               'personal' => $personal));
294
295         common_debug('Confirm URL is ' . common_local_url('register', array('code' => $invite->code)));
296
297         mail_send($recipients, $headers, $body);
298     }
299 }