diff --git a/actions/emailsettings.php b/actions/emailsettings.php new file mode 100644 index 0000000000..4fb1c17099 --- /dev/null +++ b/actions/emailsettings.php @@ -0,0 +1,241 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/lib/settingsaction.php'); + +class ImsettingsAction extends SettingsAction { + + function get_instructions() { + return _('Manage how you get email from %%site.name%%.'); + } + + function show_form($msg=NULL, $success=false) { + $user = common_current_user(); + $this->form_header(_('Email Settings'), $msg, $success); + common_element_start('form', array('method' => 'post', + 'id' => 'emailsettings', + 'action' => + common_local_url('emailsettings'))); + + common_element('h2', NULL, _('Address')); + + if ($user->email) { + common_element_start('p'); + common_element('span', 'address confirmed', $user->email); + common_element('span', 'input_instructions', + _('Current confirmed email address.')); + common_hidden('email', $user->email); + common_element_end('p'); + common_submit('remove', _('Remove')); + } else { + $confirm = $this->get_confirmation(); + if ($confirm) { + common_element_start('p'); + common_element('span', 'address unconfirmed', $confirm->address); + common_element('span', 'input_instructions', + _('Awaiting confirmation on this address. Check your inbox (and spam box!) for a message with further instructions.')); + common_hidden('email', $confirm->address); + common_element_end('p'); + common_submit('cancel', _('Cancel')); + } else { + common_input('email', _('Email Address'), + ($this->arg('email')) ? $this->arg('email') : NULL, + _('Email address, like "UserName@example.org"')); + common_submit('add', _('Add')); + } + } + + common_element('h2', NULL, _('Preferences')); + + common_checkbox('emailnotifysub', + _('Send me notices of new subscriptions through email.'), + $user->emailnotifysub); + + common_submit('save', _('Save')); + + common_element_end('form'); + common_show_footer(); + } + + function get_confirmation() { + $user = common_current_user(); + $confirm = new Confirm_address(); + $confirm->user_id = $user->id; + $confirm->address_type = 'email'; + if ($confirm->find(TRUE)) { + return $confirm; + } else { + return NULL; + } + } + + function handle_post() { + + if ($this->arg('save')) { + $this->save_preferences(); + } else if ($this->arg('add')) { + $this->add_address(); + } else if ($this->arg('cancel')) { + $this->cancel_confirmation(); + } else if ($this->arg('remove')) { + $this->remove_address(); + } else { + $this->show_form(_('Unexpected form submission.')); + } + } + + function save_preferences() { + + $emailnotifysub = $this->boolean('emailnotifysub'); + + $user = common_current_user(); + + assert(!is_null($user)); # should already be checked + + $user->query('BEGIN'); + + $original = clone($user); + + $user->emailnotifysub = $emailnotifysub; + + $result = $user->update($original); + + if ($result === FALSE) { + common_log_db_error($user, 'UPDATE', __FILE__); + common_server_error(_('Couldn\'t update user.')); + return; + } + + $user->query('COMMIT'); + + $this->show_form(_('Preferences saved.'), true); + } + + function add_address() { + + $user = common_current_user(); + + $email = $this->trimmed('email'); + + # Some validation + + if (!$email) { + $this->show_form(_('No email address.')); + return; + } + + $email = common_normalize_email($email); + + if (!$email) { + $this->show_form(_('Cannot normalize that email address')); + return; + } + if (!Validate::email($email, true)) { + $this->show_form(_('Not a valid email address')); + return; + } else if ($user->email == $email) { + $this->show_form(_('That is already your email address.')); + return; + } else if ($this->email_exists($email)) { + $this->show_form(_('That email address already belongs to another user.')); + return; + } + + $confirm = new Confirm_address(); + $confirm->address = $email; + $confirm->address_type = 'email'; + $confirm->user_id = $user->id; + $confirm->code = common_confirmation_code(64); + + $result = $confirm->insert(); + + if ($result === FALSE) { + common_log_db_error($confirm, 'INSERT', __FILE__); + common_server_error(_('Couldn\'t insert confirmation code.')); + return; + } + + $msg = _('A confirmation code was sent to the email address you added. Check your inbox (and spam box!) for the code and instructions on how to use it.'); + + $this->show_form($msg, TRUE); + } + + function cancel_confirmation() { + $email = $this->arg('email'); + $confirm = $this->get_confirmation(); + if (!$confirm) { + $this->show_form(_('No pending confirmation to cancel.')); + return; + } + if ($confirm->address != $email) { + $this->show_form(_('That is the wrong IM address.')); + return; + } + + $result = $confirm->delete(); + + if (!$result) { + common_log_db_error($confirm, 'DELETE', __FILE__); + $this->server_error(_('Couldn\'t delete email confirmation.')); + return; + } + + $this->show_form(_('Confirmation cancelled.'), TRUE); + } + + function remove_address() { + + $user = common_current_user(); + $email = $this->arg('email'); + + # Maybe an old tab open...? + + if ($user->email != $email) { + $this->show_form(_('That is not your email address.')); + return; + } + + $user->query('BEGIN'); + $original = clone($user); + $user->email = NULL; + $result = $user->updateKeys($original); + if (!$result) { + common_log_db_error($user, 'UPDATE', __FILE__); + common_server_error(_('Couldn\'t update user.')); + return; + } + $user->query('COMMIT'); + + # XXX: unsubscribe to the old address + + $this->show_form(_('The address was removed.'), TRUE); + } + + function email_exists($email) { + $user = common_current_user(); + $other = User::staticGet('email', $email); + if (!$other) { + return false; + } else { + return $other->id != $user->id; + } + } +} diff --git a/actions/subscribe.php b/actions/subscribe.php index 6499705ec8..43506a593d 100644 --- a/actions/subscribe.php +++ b/actions/subscribe.php @@ -73,7 +73,7 @@ class SubscribeAction extends Action { } function notify_email($listenee, $listener) { - if ($listenee->email) { + if ($listenee->email && $listenee->emailnotifysub) { $profile = $listenee->getProfile(); $other = $listener->getProfile(); $name = $profile->getBestName(); diff --git a/classes/User.php b/classes/User.php index e5046a394f..da70a24f0b 100644 --- a/classes/User.php +++ b/classes/User.php @@ -34,6 +34,7 @@ class User extends DB_DataObject public $nickname; // varchar(64) unique_key public $password; // varchar(255) public $email; // varchar(255) unique_key + public $emailnotifysub; // tinyint(1) unique_key default_1 public $jabber; // varchar(255) unique_key public $jabbernotify; // tinyint(1) public $jabberreplies; // tinyint(1) diff --git a/classes/stoica.ini b/classes/stoica.ini index 8b1708afbc..3a468989a4 100644 --- a/classes/stoica.ini +++ b/classes/stoica.ini @@ -157,6 +157,7 @@ id = 129 nickname = 2 password = 2 email = 2 +emailnotifysub = 17 jabber = 2 jabbernotify = 17 jabberreplies = 17 @@ -172,6 +173,7 @@ modified = 384 id = K nickname = U email = U +emailnotifysub = U jabber = U sms = U uri = U diff --git a/db/laconica.sql b/db/laconica.sql index 4115b84ec5..e906b05fe0 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -45,6 +45,7 @@ create table user ( nickname varchar(64) unique key comment 'nickname or username, duped in profile', password varchar(255) comment 'salted password, can be null for OpenID users', email varchar(255) unique key comment 'email address for password recovery etc.', + emailnotifysub tinyint default 1 unique key comment 'Notify by email of subscriptions', jabber varchar(255) unique key comment 'jabber ID for notices', jabbernotify tinyint default 0 comment 'whether to send notices to jabber', jabberreplies tinyint default 0 comment 'whether to send notices to jabber on replies', diff --git a/htaccess.sample b/htaccess.sample index c0ba80f5d1..cbd485cd14 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -32,6 +32,7 @@ RewriteRule ^settings/password$ index.php?action=password [L,QSA] RewriteRule ^settings/profile$ index.php?action=profilesettings [L,QSA] RewriteRule ^settings/openid$ index.php?action=openidsettings [L,QSA] RewriteRule ^settings/im$ index.php?action=imsettings [L,QSA] +RewriteRule ^settings/email$ index.php?action=emailsettings [L,QSA] RewriteRule ^search/people$ index.php?action=peoplesearch [L,QSA] RewriteRule ^search/notice$ index.php?action=noticesearch [L,QSA] diff --git a/lib/settingsaction.php b/lib/settingsaction.php index fe0f48a7a2..14e89c2e4d 100644 --- a/lib/settingsaction.php +++ b/lib/settingsaction.php @@ -83,6 +83,9 @@ class SettingsAction extends Action { array('profilesettings' => array('Profile', 'Change your profile settings'), + 'emailsettings' => + array('Email', + 'Change email handling'), 'avatar' => array('Avatar', 'Upload a new profile image'), diff --git a/lib/util.php b/lib/util.php index 9d66c1ca13..97a36296cf 100644 --- a/lib/util.php +++ b/lib/util.php @@ -724,6 +724,8 @@ function common_fancy_url($action, $args=NULL) { return common_path('settings/'.$action); case 'profilesettings': return common_path('settings/profile'); + case 'emailsettings': + return common_path('settings/email'); case 'openidsettings': return common_path('settings/openid'); case 'newnotice':