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