]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/smssettings.php
Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x
[quix0rs-gnu-social.git] / actions / smssettings.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Settings for SMS
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
36 /**
37  * Settings for SMS
38  *
39  * @category Settings
40  * @package  StatusNet
41  * @author   Evan Prodromou <evan@status.net>
42  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
43  * @link     http://status.net/
44  *
45  * @see      SettingsAction
46  */
47
48 class SmssettingsAction extends ConnectSettingsAction
49 {
50     /**
51      * Title of the page
52      *
53      * @return string Title of the page
54      */
55
56     function title()
57     {
58         return _('SMS settings');
59     }
60
61     /**
62      * Instructions for use
63      *
64      * @return instructions for use
65      */
66
67     function getInstructions()
68     {
69         return _('You can receive SMS messages through email from %%site.name%%.');
70     }
71
72     function showScripts()
73     {
74         parent::showScripts();
75         $this->autofocus('sms');
76     }
77
78     /**
79      * Content area of the page
80      *
81      * Shows a form for adding and removing SMS phone numbers and setting
82      * SMS preferences.
83      *
84      * @return void
85      */
86
87     function showContent()
88     {
89         if (!common_config('sms', 'enabled')) {
90             $this->element('div', array('class' => 'error'),
91                            _('SMS is not available.'));
92             return;
93         }
94
95         $user = common_current_user();
96
97         $this->elementStart('form', array('method' => 'post',
98                                           'id' => 'form_settings_sms',
99                                           'class' => 'form_settings',
100                                           'action' =>
101                                           common_local_url('smssettings')));
102
103         $this->elementStart('fieldset', array('id' => 'settings_sms_address'));
104         $this->element('legend', null, _('Address'));
105         $this->hidden('token', common_session_token());
106
107         if ($user->sms) {
108             $carrier = $user->getCarrier();
109             $this->element('p', 'form_confirmed',
110                            $user->sms . ' (' . $carrier->name . ')');
111             $this->element('p', 'form_guide',
112                            _('Current confirmed SMS-enabled phone number.'));
113             $this->hidden('sms', $user->sms);
114             $this->hidden('carrier', $user->carrier);
115             $this->submit('remove', _('Remove'));
116         } else {
117             $confirm = $this->getConfirmation();
118             if ($confirm) {
119                 $carrier = Sms_carrier::staticGet($confirm->address_extra);
120                 $this->element('p', 'form_unconfirmed',
121                                $confirm->address . ' (' . $carrier->name . ')');
122                 $this->element('p', 'form_guide',
123                                _('Awaiting confirmation on this phone number.'));
124                 $this->hidden('sms', $confirm->address);
125                 $this->hidden('carrier', $confirm->address_extra);
126                 $this->submit('cancel', _('Cancel'));
127
128                 $this->elementStart('ul', 'form_data');
129                 $this->elementStart('li');
130                 $this->input('code', _('Confirmation code'), null,
131                              _('Enter the code you received on your phone.'));
132                 $this->elementEnd('li');
133                 $this->elementEnd('ul');
134                 $this->submit('confirm', _('Confirm'));
135             } else {
136                 $this->elementStart('ul', 'form_data');
137                 $this->elementStart('li');
138                 $this->input('sms', _('SMS phone number'),
139                              ($this->arg('sms')) ? $this->arg('sms') : null,
140                              _('Phone number, no punctuation or spaces, '.
141                                'with area code'));
142                 $this->elementEnd('li');
143                 $this->elementEnd('ul');
144                 $this->carrierSelect();
145                 $this->submit('add', _('Add'));
146             }
147         }
148         $this->elementEnd('fieldset');
149
150         if ($user->sms) {
151         $this->elementStart('fieldset', array('id' => 'settings_sms_incoming_email'));
152             $this->element('legend', null, _('Incoming email'));
153
154             if ($user->incomingemail) {
155                 $this->element('p', 'form_unconfirmed', $user->incomingemail);
156                 $this->element('p', 'form_note',
157                                _('Send email to this address to post new notices.'));
158                 $this->submit('removeincoming', _('Remove'));
159             }
160
161             $this->element('p', 'form_guide',
162                            _('Make a new email address for posting to; '.
163                              'cancels the old one.'));
164             $this->submit('newincoming', _('New'));
165             $this->elementEnd('fieldset');
166         }
167
168         $this->elementStart('fieldset', array('id' => 'settings_sms_preferences'));
169         $this->element('legend', null, _('Preferences'));
170
171         $this->elementStart('ul', 'form_data');
172         $this->elementStart('li');
173         $this->checkbox('smsnotify',
174                         _('Send me notices through SMS; '.
175                           'I understand I may incur '.
176                           'exorbitant charges from my carrier.'),
177                         $user->smsnotify);
178         $this->elementEnd('li');
179         $this->elementEnd('ul');
180
181         $this->submit('save', _('Save'));
182
183         $this->elementEnd('fieldset');
184         $this->elementEnd('form');
185     }
186
187     /**
188      * Get a pending confirmation, if any, for this user
189      *
190      * @return void
191      *
192      * @todo very similar to EmailsettingsAction::getConfirmation(); refactor?
193      */
194
195     function getConfirmation()
196     {
197         $user = common_current_user();
198
199         $confirm = new Confirm_address();
200
201         $confirm->user_id      = $user->id;
202         $confirm->address_type = 'sms';
203
204         if ($confirm->find(true)) {
205             return $confirm;
206         } else {
207             return null;
208         }
209     }
210
211     /**
212      * Handle posts to this form
213      *
214      * Based on the button that was pressed, muxes out to other functions
215      * to do the actual task requested.
216      *
217      * All sub-functions reload the form with a message -- success or failure.
218      *
219      * @return void
220      */
221
222     function handlePost()
223     {
224         // CSRF protection
225
226         $token = $this->trimmed('token');
227         if (!$token || $token != common_session_token()) {
228             $this->showForm(_('There was a problem with your session token. '.
229                               'Try again, please.'));
230             return;
231         }
232
233         if ($this->arg('save')) {
234             $this->savePreferences();
235         } else if ($this->arg('add')) {
236             $this->addAddress();
237         } else if ($this->arg('cancel')) {
238             $this->cancelConfirmation();
239         } else if ($this->arg('remove')) {
240             $this->removeAddress();
241         } else if ($this->arg('removeincoming')) {
242             $this->removeIncoming();
243         } else if ($this->arg('newincoming')) {
244             $this->newIncoming();
245         } else if ($this->arg('confirm')) {
246             $this->confirmCode();
247         } else {
248             $this->showForm(_('Unexpected form submission.'));
249         }
250     }
251
252     /**
253      * Handle a request to save preferences
254      *
255      * Sets the user's SMS preferences in the DB.
256      *
257      * @return void
258      */
259
260     function savePreferences()
261     {
262         $smsnotify = $this->boolean('smsnotify');
263
264         $user = common_current_user();
265
266         assert(!is_null($user)); // should already be checked
267
268         $user->query('BEGIN');
269
270         $original = clone($user);
271
272         $user->smsnotify = $smsnotify;
273
274         $result = $user->update($original);
275
276         if ($result === false) {
277             common_log_db_error($user, 'UPDATE', __FILE__);
278             $this->serverError(_('Couldn\'t update user.'));
279             return;
280         }
281
282         $user->query('COMMIT');
283
284         $this->showForm(_('Preferences saved.'), true);
285     }
286
287     /**
288      * Add a new SMS number for confirmation
289      *
290      * When the user requests a new SMS number, sends a confirmation
291      * message.
292      *
293      * @return void
294      */
295
296     function addAddress()
297     {
298         $user = common_current_user();
299
300         $sms        = $this->trimmed('sms');
301         $carrier_id = $this->trimmed('carrier');
302
303         // Some validation
304
305         if (!$sms) {
306             $this->showForm(_('No phone number.'));
307             return;
308         }
309
310         if (!$carrier_id) {
311             $this->showForm(_('No carrier selected.'));
312             return;
313         }
314
315         $sms = common_canonical_sms($sms);
316
317         if ($user->sms == $sms) {
318             $this->showForm(_('That is already your phone number.'));
319             return;
320         } else if ($this->smsExists($sms)) {
321             $this->showForm(_('That phone number already belongs to another user.'));
322             return;
323         }
324
325         $confirm = new Confirm_address();
326
327         $confirm->address       = $sms;
328         $confirm->address_extra = $carrier_id;
329         $confirm->address_type  = 'sms';
330         $confirm->user_id       = $user->id;
331         $confirm->code          = common_confirmation_code(40);
332
333         $result = $confirm->insert();
334
335         if ($result === false) {
336             common_log_db_error($confirm, 'INSERT', __FILE__);
337             $this->serverError(_('Couldn\'t insert confirmation code.'));
338             return;
339         }
340
341         $carrier = Sms_carrier::staticGet($carrier_id);
342
343         mail_confirm_sms($confirm->code,
344                          $user->nickname,
345                          $carrier->toEmailAddress($sms));
346
347         $msg = _('A confirmation code was sent to the phone number you added. '.
348                  'Check your phone for the code and instructions '.
349                  'on how to use it.');
350
351         $this->showForm($msg, true);
352     }
353
354     /**
355      * Cancel a pending confirmation
356      *
357      * Cancels the confirmation.
358      *
359      * @return void
360      */
361
362     function cancelConfirmation()
363     {
364         $sms     = $this->trimmed('sms');
365         $carrier = $this->trimmed('carrier');
366
367         $confirm = $this->getConfirmation();
368
369         if (!$confirm) {
370             $this->showForm(_('No pending confirmation to cancel.'));
371             return;
372         }
373         if ($confirm->address != $sms) {
374             $this->showForm(_('That is the wrong confirmation number.'));
375             return;
376         }
377
378         $result = $confirm->delete();
379
380         if (!$result) {
381             common_log_db_error($confirm, 'DELETE', __FILE__);
382             $this->serverError(_('Couldn\'t delete email confirmation.'));
383             return;
384         }
385
386         $this->showForm(_('Confirmation cancelled.'), true);
387     }
388
389     /**
390      * Remove a phone number from the user's account
391      *
392      * @return void
393      */
394
395     function removeAddress()
396     {
397         $user = common_current_user();
398
399         $sms     = $this->arg('sms');
400         $carrier = $this->arg('carrier');
401
402         // Maybe an old tab open...?
403
404         if ($user->sms != $sms) {
405             $this->showForm(_('That is not your phone number.'));
406             return;
407         }
408
409         $user->query('BEGIN');
410
411         $original = clone($user);
412
413         $user->sms      = null;
414         $user->carrier  = null;
415         $user->smsemail = null;
416
417         $result = $user->updateKeys($original);
418         if (!$result) {
419             common_log_db_error($user, 'UPDATE', __FILE__);
420             $this->serverError(_('Couldn\'t update user.'));
421             return;
422         }
423         $user->query('COMMIT');
424
425         $this->showForm(_('The address was removed.'), true);
426     }
427
428     /**
429      * Does this sms number exist in our database?
430      *
431      * Also checks if it belongs to someone else
432      *
433      * @param string $sms phone number to check
434      *
435      * @return boolean does the number exist
436      */
437
438     function smsExists($sms)
439     {
440         $user = common_current_user();
441
442         $other = User::staticGet('sms', $sms);
443
444         if (!$other) {
445             return false;
446         } else {
447             return $other->id != $user->id;
448         }
449     }
450
451     /**
452      * Show a drop-down box with all the SMS carriers in the DB
453      *
454      * @return void
455      */
456
457     function carrierSelect()
458     {
459         $carrier = new Sms_carrier();
460
461         $cnt = $carrier->find();
462
463         $this->elementStart('ul', 'form_data');
464         $this->elementStart('li');
465         $this->element('label', array('for' => 'carrier'), _('Mobile carrier'));
466         $this->elementStart('select', array('name' => 'carrier',
467                                             'id' => 'carrier'));
468         $this->element('option', array('value' => 0),
469                        _('Select a carrier'));
470         while ($carrier->fetch()) {
471             $this->element('option', array('value' => $carrier->id),
472                            $carrier->name);
473         }
474         $this->elementEnd('select');
475         $this->element('p', 'form_guide',
476                        sprintf(_('Mobile carrier for your phone. '.
477                                  'If you know a carrier that accepts ' .
478                                  'SMS over email but isn\'t listed here, ' .
479                                  'send email to let us know at %s.'),
480                                common_config('site', 'email')));
481         $this->elementEnd('li');
482         $this->elementEnd('ul');
483     }
484
485     /**
486      * Confirm an SMS confirmation code
487      *
488      * Redirects to the confirmaddress page for this code
489      *
490      * @return void
491      */
492
493     function confirmCode()
494     {
495         $code = $this->trimmed('code');
496
497         if (!$code) {
498             $this->showForm(_('No code entered'));
499             return;
500         }
501
502         common_redirect(common_local_url('confirmaddress',
503                                          array('code' => $code)),
504                         303);
505     }
506
507     /**
508      * Handle a request to remove an incoming email address
509      *
510      * @return void
511      */
512
513     function removeIncoming()
514     {
515         $user = common_current_user();
516
517         if (!$user->incomingemail) {
518             $this->showForm(_('No incoming email address.'));
519             return;
520         }
521
522         $orig = clone($user);
523
524         $user->incomingemail = null;
525
526         if (!$user->updateKeys($orig)) {
527             common_log_db_error($user, 'UPDATE', __FILE__);
528             $this->serverError(_("Couldn't update user record."));
529         }
530
531         $this->showForm(_('Incoming email address removed.'), true);
532     }
533
534     /**
535      * Generate a new incoming email address
536      *
537      * @return void
538      *
539      * @see Emailsettings::newIncoming
540      */
541
542     function newIncoming()
543     {
544         $user = common_current_user();
545
546         $orig = clone($user);
547
548         $user->incomingemail = mail_new_incoming_address();
549
550         if (!$user->updateKeys($orig)) {
551             common_log_db_error($user, 'UPDATE', __FILE__);
552             $this->serverError(_("Couldn't update user record."));
553         }
554
555         $this->showForm(_('New incoming email address added.'), true);
556     }
557 }