]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/imsettings.php
Merge branch 'master' into 0.9.x
[quix0rs-gnu-social.git] / actions / imsettings.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Settings for Jabber/XMPP integration
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Settings
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @copyright 2008-2009 StatusNet, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET') && !defined('LACONICA')) {
31     exit(1);
32 }
33
34 require_once INSTALLDIR.'/lib/connectsettingsaction.php';
35 require_once INSTALLDIR.'/lib/jabber.php';
36
37 /**
38  * Settings for Jabber/XMPP integration
39  *
40  * @category Settings
41  * @package  StatusNet
42  * @author   Evan Prodromou <evan@status.net>
43  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
44  * @link     http://status.net/
45  *
46  * @see      SettingsAction
47  */
48 class ImsettingsAction extends ConnectSettingsAction
49 {
50     /**
51      * Title of the page
52      *
53      * @return string Title of the page
54      */
55     function title()
56     {
57         // TRANS: Title for instance messaging settings.
58         return _('IM settings');
59     }
60
61     /**
62      * Instructions for use
63      *
64      * @return instructions for use
65      */
66     function getInstructions()
67     {
68         // TRANS: Instant messaging settings page instructions.
69         // TRANS: [instant messages] is link text, "(%%doc.im%%)" is the link.
70         // TRANS: the order and formatting of link text and link should remain unchanged.
71         return _('You can send and receive notices through '.
72                  'Jabber/GTalk [instant messages](%%doc.im%%). '.
73                  'Configure your address and settings below.');
74     }
75
76     /**
77      * Content area of the page
78      *
79      * We make different sections of the form for the different kinds of
80      * functions, and have submit buttons with different names. These
81      * are muxed by handlePost() to see what the user really wants to do.
82      *
83      * @return void
84      */
85     function showContent()
86     {
87         if (!common_config('xmpp', 'enabled')) {
88             $this->element('div', array('class' => 'error'),
89                            // TRANS: Message given in the IM settings if XMPP is not enabled on the site.
90                            _('IM is not available.'));
91             return;
92         }
93
94         $user = common_current_user();
95         $this->elementStart('form', array('method' => 'post',
96                                           'id' => 'form_settings_im',
97                                           'class' => 'form_settings',
98                                           'action' =>
99                                           common_local_url('imsettings')));
100         $this->elementStart('fieldset', array('id' => 'settings_im_address'));
101         // TRANS: Form legend for IM settings form.
102         $this->element('legend', null, _('IM address'));
103         $this->hidden('token', common_session_token());
104
105         if ($user->jabber) {
106             $this->element('p', 'form_confirmed', $user->jabber);
107             // TRANS: Form note in IM settings form.
108             $this->element('p', 'form_note',
109                            _('Current confirmed Jabber/GTalk address.'));
110             $this->hidden('jabber', $user->jabber);
111             // TRANS: Button label to remove a confirmed IM address.
112             $this->submit('remove', _m('BUTTON','Remove'));
113         } else {
114             $confirm = $this->getConfirmation();
115             if ($confirm) {
116                 $this->element('p', 'form_unconfirmed', $confirm->address);
117                 $this->element('p', 'form_note',
118                                // TRANS: Form note in IM settings form.
119                                // TRANS: %s is the IM address set for the site.
120                                sprintf(_('Awaiting confirmation on this address. '.
121                                          'Check your Jabber/GTalk account for a '.
122                                          'message with further instructions. '.
123                                          '(Did you add %s to your buddy list?)'),
124                                        jabber_daemon_address()));
125                 $this->hidden('jabber', $confirm->address);
126                 // TRANS: Button label to cancel an IM address confirmation procedure.
127                 $this->submit('cancel', _m('BUTTON','Cancel'));
128             } else {
129                 $this->elementStart('ul', 'form_data');
130                 $this->elementStart('li');
131                 // TRANS: Field label for IM address input in IM settings form.
132                 $this->input('jabber', _('IM address'),
133                              ($this->arg('jabber')) ? $this->arg('jabber') : null,
134                              // TRANS: IM address input field instructions in IM settings form.
135                              // TRANS: %s is the IM address set for the site.
136                              // TRANS: Do not translate "example.org". It is one of the domain names reserved for use in examples by
137                              // TRANS: http://www.rfc-editor.org/rfc/rfc2606.txt. Any other domain may be owned by a legitimate
138                              // TRANS: person or organization.
139                              sprintf(_('Jabber or GTalk address, '.
140                                        'like "UserName@example.org". '.
141                                        'First, make sure to add %s to your '.
142                                        'buddy list in your IM client or on GTalk.'),
143                                      jabber_daemon_address()));
144                 $this->elementEnd('li');
145                 $this->elementEnd('ul');
146                 // TRANS: Button label for adding an IM address in IM settings form.
147                 $this->submit('add', _m('BUTTON','Add'));
148             }
149         }
150         $this->elementEnd('fieldset');
151
152         $this->elementStart('fieldset', array('id' => 'settings_im_preferences'));
153         // TRANS: Form legend for IM preferences form.
154         $this->element('legend', null, _('IM preferences'));
155         $this->elementStart('ul', 'form_data');
156         $this->elementStart('li');
157         $this->checkbox('jabbernotify',
158                         // TRANS: Checkbox label in IM preferences form.
159                         _('Send me notices through Jabber/GTalk.'),
160                         $user->jabbernotify);
161         $this->elementEnd('li');
162         $this->elementStart('li');
163         $this->checkbox('updatefrompresence',
164                         // TRANS: Checkbox label in IM preferences form.
165                         _('Post a notice when my Jabber/GTalk status changes.'),
166                         $user->updatefrompresence);
167         $this->elementEnd('li');
168         $this->elementStart('li');
169         $this->checkbox('jabberreplies',
170                         // TRANS: Checkbox label in IM preferences form.
171                         _('Send me replies through Jabber/GTalk '.
172                           'from people I\'m not subscribed to.'),
173                         $user->jabberreplies);
174         $this->elementEnd('li');
175         $this->elementStart('li');
176         $this->checkbox('jabbermicroid',
177                         // TRANS: Checkbox label in IM preferences form.
178                         _('Publish a MicroID for my Jabber/GTalk address.'),
179                         $user->jabbermicroid);
180         $this->elementEnd('li');
181         $this->elementEnd('ul');
182         // TRANS: Button label to save IM preferences.
183         $this->submit('save', _m('BUTTON','Save'));
184         $this->elementEnd('fieldset');
185         $this->elementEnd('form');
186     }
187
188     /**
189      * Get a confirmation code for this user
190      *
191      * @return Confirm_address address object for this user
192      */
193     function getConfirmation()
194     {
195         $user = common_current_user();
196
197         $confirm = new Confirm_address();
198
199         $confirm->user_id      = $user->id;
200         $confirm->address_type = 'jabber';
201
202         if ($confirm->find(true)) {
203             return $confirm;
204         } else {
205             return null;
206         }
207     }
208
209     /**
210      * Handle posts to this form
211      *
212      * Based on the button that was pressed, muxes out to other functions
213      * to do the actual task requested.
214      *
215      * All sub-functions reload the form with a message -- success or failure.
216      *
217      * @return void
218      */
219     function handlePost()
220     {
221         // CSRF protection
222         $token = $this->trimmed('token');
223         if (!$token || $token != common_session_token()) {
224             $this->showForm(_('There was a problem with your session token. '.
225                               'Try again, please.'));
226             return;
227         }
228
229         if ($this->arg('save')) {
230             $this->savePreferences();
231         } else if ($this->arg('add')) {
232             $this->addAddress();
233         } else if ($this->arg('cancel')) {
234             $this->cancelConfirmation();
235         } else if ($this->arg('remove')) {
236             $this->removeAddress();
237         } else {
238             // TRANS: Message given submitting a form with an unknown action in IM settings.
239             $this->showForm(_('Unexpected form submission.'));
240         }
241     }
242
243     /**
244      * Save user's Jabber preferences
245      *
246      * These are the checkboxes at the bottom of the page. They're used to
247      * set different settings
248      *
249      * @return void
250      */
251     function savePreferences()
252     {
253         $jabbernotify       = $this->boolean('jabbernotify');
254         $updatefrompresence = $this->boolean('updatefrompresence');
255         $jabberreplies      = $this->boolean('jabberreplies');
256         $jabbermicroid      = $this->boolean('jabbermicroid');
257
258         $user = common_current_user();
259
260         assert(!is_null($user)); // should already be checked
261
262         $user->query('BEGIN');
263
264         $original = clone($user);
265
266         $user->jabbernotify       = $jabbernotify;
267         $user->updatefrompresence = $updatefrompresence;
268         $user->jabberreplies      = $jabberreplies;
269         $user->jabbermicroid      = $jabbermicroid;
270
271         $result = $user->update($original);
272
273         if ($result === false) {
274             common_log_db_error($user, 'UPDATE', __FILE__);
275             // TRANS: Server error thrown on database error updating IM preferences.
276             $this->serverError(_('Could not update user.'));
277             return;
278         }
279
280         $user->query('COMMIT');
281
282         // TRANS: Confirmation message for successful IM preferences save.
283         $this->showForm(_('Preferences saved.'), true);
284     }
285
286     /**
287      * Sends a confirmation to the address given
288      *
289      * Stores a confirmation record and sends out a
290      * Jabber message with the confirmation info.
291      *
292      * @return void
293      */
294     function addAddress()
295     {
296         $user = common_current_user();
297
298         $jabber = $this->trimmed('jabber');
299
300         // Some validation
301
302         if (!$jabber) {
303             // TRANS: Message given saving IM address without having provided one.
304             $this->showForm(_('No Jabber ID.'));
305             return;
306         }
307
308         $jabber = jabber_normalize_jid($jabber);
309
310         if (!$jabber) {
311             // TRANS: Message given saving IM address that cannot be normalised.
312             $this->showForm(_('Cannot normalize that Jabber ID'));
313             return;
314         }
315         if (!jabber_valid_base_jid($jabber, common_config('email', 'domain_check'))) {
316             // TRANS: Message given saving IM address that not valid.
317             $this->showForm(_('Not a valid Jabber ID'));
318             return;
319         } else if ($user->jabber == $jabber) {
320             // TRANS: Message given saving IM address that is already set.
321             $this->showForm(_('That is already your Jabber ID.'));
322             return;
323         } else if ($this->jabberExists($jabber)) {
324             // TRANS: Message given saving IM address that is already set for another user.
325             $this->showForm(_('Jabber ID already belongs to another user.'));
326             return;
327         }
328
329         $confirm = new Confirm_address();
330
331         $confirm->address      = $jabber;
332         $confirm->address_type = 'jabber';
333         $confirm->user_id      = $user->id;
334         $confirm->code         = common_confirmation_code(64);
335         $confirm->sent         = common_sql_now();
336         $confirm->claimed      = common_sql_now();
337
338         $result = $confirm->insert();
339
340         if ($result === false) {
341             common_log_db_error($confirm, 'INSERT', __FILE__);
342             // TRANS: Server error thrown on database error adding IM confirmation code.
343             $this->serverError(_('Could not insert confirmation code.'));
344             return;
345         }
346
347         jabber_confirm_address($confirm->code,
348                                $user->nickname,
349                                $jabber);
350
351         // TRANS: Message given saving valid IM address that is to be confirmed.
352         // TRANS: %s is the IM address set for the site.
353         $msg = sprintf(_('A confirmation code was sent '.
354                          'to the IM address you added. '.
355                          'You must approve %s for '.
356                          'sending messages to you.'),
357                        jabber_daemon_address());
358
359         $this->showForm($msg, true);
360     }
361
362     /**
363      * Cancel a confirmation
364      *
365      * If a confirmation exists, cancel it.
366      *
367      * @return void
368      */
369     function cancelConfirmation()
370     {
371         $jabber = $this->arg('jabber');
372
373         $confirm = $this->getConfirmation();
374
375         if (!$confirm) {
376             // TRANS: Message given canceling IM address confirmation that is not pending.
377             $this->showForm(_('No pending confirmation to cancel.'));
378             return;
379         }
380         if ($confirm->address != $jabber) {
381             // TRANS: Message given canceling IM address confirmation for the wrong IM address.
382             $this->showForm(_('That is the wrong IM address.'));
383             return;
384         }
385
386         $result = $confirm->delete();
387
388         if (!$result) {
389             common_log_db_error($confirm, 'DELETE', __FILE__);
390             // TRANS: Server error thrown on database error canceling IM address confirmation.
391             $this->serverError(_('Could not delete IM confirmation.'));
392             return;
393         }
394
395         // TRANS: Message given after successfully canceling IM address confirmation.
396         $this->showForm(_('IM confirmation cancelled.'), true);
397     }
398
399     /**
400      * Remove an address
401      *
402      * If the user has a confirmed address, remove it.
403      *
404      * @return void
405      */
406     function removeAddress()
407     {
408         $user = common_current_user();
409
410         $jabber = $this->arg('jabber');
411
412         // Maybe an old tab open...?
413
414         if ($user->jabber != $jabber) {
415             // TRANS: Message given trying to remove an IM address that is not
416             // TRANS: registered for the active user.
417             $this->showForm(_('That is not your Jabber ID.'));
418             return;
419         }
420
421         $user->query('BEGIN');
422
423         $original = clone($user);
424
425         $user->jabber = null;
426
427         $result = $user->updateKeys($original);
428
429         if (!$result) {
430             common_log_db_error($user, 'UPDATE', __FILE__);
431             // TRANS: Server error thrown on database error removing a registered IM address.
432             $this->serverError(_('Could not update user.'));
433             return;
434         }
435         $user->query('COMMIT');
436
437         // XXX: unsubscribe to the old address
438
439         // TRANS: Message given after successfully removing a registered IM address.
440         $this->showForm(_('The IM address was removed.'), true);
441     }
442
443     /**
444      * Does this Jabber ID exist?
445      *
446      * Checks if we already have another user with this address.
447      *
448      * @param string $jabber Address to check
449      *
450      * @return boolean whether the Jabber ID exists
451      */
452     function jabberExists($jabber)
453     {
454         $user = common_current_user();
455
456         $other = User::staticGet('jabber', $jabber);
457
458         if (!$other) {
459             return false;
460         } else {
461             return $other->id != $user->id;
462         }
463     }
464 }