diff --git a/actions/finishaddopenid.php b/actions/finishaddopenid.php index 708e8d4bfb..8f10505cff 100644 --- a/actions/finishaddopenid.php +++ b/actions/finishaddopenid.php @@ -1,9 +1,12 @@ . + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} -require_once(INSTALLDIR.'/lib/openid.php'); +require_once INSTALLDIR.'/lib/openid.php'; + +/** + * Complete adding an OpenID + * + * Handle the return from an OpenID verification + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ class FinishaddopenidAction extends Action { + var $msg = null; + + /** + * Handle the redirect back from OpenID confirmation + * + * Check to see if the user's logged in, and then try + * to use the OpenID login system. + * + * @param array $args $_REQUEST arguments + * + * @return void + */ function handle($args) { @@ -30,13 +66,20 @@ class FinishaddopenidAction extends Action if (!common_logged_in()) { $this->clientError(_('Not logged in.')); } else { - $this->try_login(); + $this->tryLogin(); } } - - function try_login() - { + /** + * Try to log in using OpenID + * + * Check the OpenID for validity; potentially store it. + * + * @return void + */ + + function tryLogin() + { $consumer =& oid_consumer(); $response = $consumer->complete(common_local_url('finishaddopenid')); @@ -46,10 +89,11 @@ class FinishaddopenidAction extends Action return; } else if ($response->status == Auth_OpenID_FAILURE) { // Authentication failed; display the error message. - $this->message(sprintf(_('OpenID authentication failed: %s'), $response->message)); + $this->message(sprintf(_('OpenID authentication failed: %s'), + $response->message)); } else if ($response->status == Auth_OpenID_SUCCESS) { - $display = $response->getDisplayIdentifier(); + $display = $response->getDisplayIdentifier(); $canonical = ($response->endpoint && $response->endpoint->canonicalID) ? $response->endpoint->canonicalID : $display; @@ -60,6 +104,7 @@ class FinishaddopenidAction extends Action } $cur =& common_current_user(); + $other = oid_get_user($canonical); if ($other) { @@ -71,7 +116,7 @@ class FinishaddopenidAction extends Action return; } - # start a transaction + // start a transaction $cur->query('BEGIN'); @@ -88,7 +133,7 @@ class FinishaddopenidAction extends Action } } - # success! + // success! $cur->query('COMMIT'); @@ -98,10 +143,43 @@ class FinishaddopenidAction extends Action } } + /** + * Show a failure message + * + * Something went wrong. Save the message, and show the page. + * + * @param string $msg Error message to show + * + * @return void + */ + function message($msg) { - common_show_header(_('OpenID Login')); - $this->element('p', null, $msg); - common_show_footer(); + $this->message = $msg; + $this->showPage(); + } + + /** + * Title of the page + * + * @return string title + */ + + function title() + { + return _('OpenID Login'); + } + + /** + * Show error message + * + * @return void + */ + + function showPageNotice() + { + if ($this->message) { + $this->element('p', 'error', $this->message); + } } } diff --git a/actions/imsettings.php b/actions/imsettings.php index 14df3451a8..3e578b307d 100644 --- a/actions/imsettings.php +++ b/actions/imsettings.php @@ -1,9 +1,12 @@ . + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} -require_once(INSTALLDIR.'/lib/settingsaction.php'); -require_once(INSTALLDIR.'/lib/jabber.php'); +require_once INSTALLDIR.'/lib/settingsaction.php'; +require_once INSTALLDIR.'/lib/jabber.php'; + +/** + * Settings for Jabber/XMPP integration + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see SettingsAction + */ class ImsettingsAction extends SettingsAction { + /** + * Title of the page + * + * @return string Title of the page + */ - function get_instructions() + function title() { - return _('You can send and receive notices through Jabber/GTalk [instant messages](%%doc.im%%). Configure your address and settings below.'); + return _('IM Settings'); } - function show_form($msg=null, $success=false) + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() + { + return _('You can send and receive notices through '. + 'Jabber/GTalk [instant messages](%%doc.im%%). '. + 'Configure your address and settings below.'); + } + + /** + * Content area of the page + * + * We make different sections of the form for the different kinds of + * functions, and have submit buttons with different names. These + * are muxed by handlePost() to see what the user really wants to do. + * + * @return void + */ + + function showContent() { $user = common_current_user(); - $this->form_header(_('IM Settings'), $msg, $success); $this->elementStart('form', array('method' => 'post', - 'id' => 'imsettings', - 'action' => - common_local_url('imsettings'))); + 'id' => 'imsettings', + 'action' => + common_local_url('imsettings'))); $this->hidden('token', common_session_token()); $this->element('h2', null, _('Address')); @@ -51,19 +102,27 @@ class ImsettingsAction extends SettingsAction $this->elementEnd('p'); $this->submit('remove', _('Remove')); } else { - $confirm = $this->get_confirmation(); + $confirm = $this->getConfirmation(); if ($confirm) { $this->elementStart('p'); $this->element('span', 'address unconfirmed', $confirm->address); $this->element('span', 'input_instructions', - sprintf(_('Awaiting confirmation on this address. Check your Jabber/GTalk account for a message with further instructions. (Did you add %s to your buddy list?)'), jabber_daemon_address())); + sprintf(_('Awaiting confirmation on this address. '. + 'Check your Jabber/GTalk account for a '. + 'message with further instructions. '. + '(Did you add %s to your buddy list?)'), + jabber_daemon_address())); $this->hidden('jabber', $confirm->address); $this->elementEnd('p'); $this->submit('cancel', _('Cancel')); } else { $this->input('jabber', _('IM Address'), ($this->arg('jabber')) ? $this->arg('jabber') : null, - sprintf(_('Jabber or GTalk address, like "UserName@example.org". First, make sure to add %s to your buddy list in your IM client or on GTalk.'), jabber_daemon_address())); + sprintf(_('Jabber or GTalk address, '. + 'like "UserName@example.org". '. + 'First, make sure to add %s to your '. + 'buddy list in your IM client or on GTalk.'), + jabber_daemon_address())); $this->submit('add', _('Add')); } } @@ -77,7 +136,8 @@ class ImsettingsAction extends SettingsAction _('Post a notice when my Jabber/GTalk status changes.'), $user->updatefrompresence); $this->checkbox('jabberreplies', - _('Send me replies through Jabber/GTalk from people I\'m not subscribed to.'), + _('Send me replies through Jabber/GTalk '. + 'from people I\'m not subscribed to.'), $user->jabberreplies); $this->checkbox('jabbermicroid', _('Publish a MicroID for my Jabber/GTalk address.'), @@ -85,15 +145,23 @@ class ImsettingsAction extends SettingsAction $this->submit('save', _('Save')); $this->elementEnd('form'); - common_show_footer(); } - function get_confirmation() + /** + * Get a confirmation code for this user + * + * @return Confirm_address address object for this user + */ + + function getConfirmation() { $user = common_current_user(); + $confirm = new Confirm_address(); - $confirm->user_id = $user->id; + + $confirm->user_id = $user->id; $confirm->address_type = 'jabber'; + if ($confirm->find(true)) { return $confirm; } else { @@ -101,49 +169,69 @@ class ImsettingsAction extends SettingsAction } } - function handle_post() - { + /** + * Handle posts to this form + * + * Based on the button that was pressed, muxes out to other functions + * to do the actual task requested. + * + * All sub-functions reload the form with a message -- success or failure. + * + * @return void + */ - # CSRF protection + function handlePost() + { + // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->show_form(_('There was a problem with your session token. Try again, please.')); + $this->showForm(_('There was a problem with your session token. '. + 'Try again, please.')); return; } if ($this->arg('save')) { - $this->save_preferences(); + $this->savePreferences(); } else if ($this->arg('add')) { - $this->add_address(); + $this->addAddress(); } else if ($this->arg('cancel')) { - $this->cancel_confirmation(); + $this->cancelConfirmation(); } else if ($this->arg('remove')) { - $this->remove_address(); + $this->removeAddress(); } else { - $this->show_form(_('Unexpected form submission.')); + $this->showForm(_('Unexpected form submission.')); } } - function save_preferences() + /** + * Save user's Jabber preferences + * + * These are the checkboxes at the bottom of the page. They're used to + * set different settings + * + * @return void + */ + + function savePreferences() { - $jabbernotify = $this->boolean('jabbernotify'); + $jabbernotify = $this->boolean('jabbernotify'); $updatefrompresence = $this->boolean('updatefrompresence'); - $jabberreplies = $this->boolean('jabberreplies'); - $jabbermicroid = $this->boolean('jabbermicroid'); + $jabberreplies = $this->boolean('jabberreplies'); + $jabbermicroid = $this->boolean('jabbermicroid'); $user = common_current_user(); - assert(!is_null($user)); # should already be checked + assert(!is_null($user)); // should already be checked $user->query('BEGIN'); $original = clone($user); - $user->jabbernotify = $jabbernotify; + $user->jabbernotify = $jabbernotify; $user->updatefrompresence = $updatefrompresence; - $user->jabberreplies = $jabberreplies; - $user->jabbermicroid = $jabbermicroid; + $user->jabberreplies = $jabberreplies; + $user->jabbermicroid = $jabbermicroid; $result = $user->update($original); @@ -155,45 +243,54 @@ class ImsettingsAction extends SettingsAction $user->query('COMMIT'); - $this->show_form(_('Preferences saved.'), true); + $this->showForm(_('Preferences saved.'), true); } - function add_address() - { + /** + * Sends a confirmation to the address given + * + * Stores a confirmation record and sends out a + * Jabber message with the confirmation info. + * + * @return void + */ + function addAddress() + { $user = common_current_user(); $jabber = $this->trimmed('jabber'); - # Some validation + // Some validation if (!$jabber) { - $this->show_form(_('No Jabber ID.')); + $this->showForm(_('No Jabber ID.')); return; } $jabber = jabber_normalize_jid($jabber); if (!$jabber) { - $this->show_form(_('Cannot normalize that Jabber ID')); + $this->showForm(_('Cannot normalize that Jabber ID')); return; } if (!jabber_valid_base_jid($jabber)) { - $this->show_form(_('Not a valid Jabber ID')); + $this->showForm(_('Not a valid Jabber ID')); return; } else if ($user->jabber == $jabber) { - $this->show_form(_('That is already your Jabber ID.')); + $this->showForm(_('That is already your Jabber ID.')); return; - } else if ($this->jabber_exists($jabber)) { - $this->show_form(_('Jabber ID already belongs to another user.')); + } else if ($this->jabberExists($jabber)) { + $this->showForm(_('Jabber ID already belongs to another user.')); return; } - $confirm = new Confirm_address(); - $confirm->address = $jabber; - $confirm->address_type = 'jabber'; - $confirm->user_id = $user->id; - $confirm->code = common_confirmation_code(64); + $confirm = new Confirm_address(); + + $confirm->address = $jabber; + $confirm->address_type = 'jabber'; + $confirm->user_id = $user->id; + $confirm->code = common_confirmation_code(64); $result = $confirm->insert(); @@ -209,21 +306,35 @@ class ImsettingsAction extends SettingsAction $jabber); } - $msg = sprintf(_('A confirmation code was sent to the IM address you added. You must approve %s for sending messages to you.'), jabber_daemon_address()); + $msg = sprintf(_('A confirmation code was sent '. + 'to the IM address you added. '. + 'You must approve %s for '. + 'sending messages to you.'), + jabber_daemon_address()); - $this->show_form($msg, true); + $this->showForm($msg, true); } - function cancel_confirmation() + /** + * Cancel a confirmation + * + * If a confirmation exists, cancel it. + * + * @return void + */ + + function cancelConfirmation() { $jabber = $this->arg('jabber'); - $confirm = $this->get_confirmation(); + + $confirm = $this->getConfirmation(); + if (!$confirm) { - $this->show_form(_('No pending confirmation to cancel.')); + $this->showForm(_('No pending confirmation to cancel.')); return; } if ($confirm->address != $jabber) { - $this->show_form(_('That is the wrong IM address.')); + $this->showForm(_('That is the wrong IM address.')); return; } @@ -235,26 +346,38 @@ class ImsettingsAction extends SettingsAction return; } - $this->show_form(_('Confirmation cancelled.'), true); + $this->showForm(_('Confirmation cancelled.'), true); } - function remove_address() - { + /** + * Remove an address + * + * If the user has a confirmed address, remove it. + * + * @return void + */ + function removeAddress() + { $user = common_current_user(); + $jabber = $this->arg('jabber'); - # Maybe an old tab open...? + // Maybe an old tab open...? if ($user->jabber != $jabber) { - $this->show_form(_('That is not your Jabber ID.')); + $this->showForm(_('That is not your Jabber ID.')); return; } $user->query('BEGIN'); + $original = clone($user); + $user->jabber = null; + $result = $user->updateKeys($original); + if (!$result) { common_log_db_error($user, 'UPDATE', __FILE__); $this->serverError(_('Couldn\'t update user.')); @@ -262,15 +385,27 @@ class ImsettingsAction extends SettingsAction } $user->query('COMMIT'); - # XXX: unsubscribe to the old address + // XXX: unsubscribe to the old address - $this->show_form(_('The address was removed.'), true); + $this->showForm(_('The address was removed.'), true); } - function jabber_exists($jabber) + /** + * Does this Jabber ID exist? + * + * Checks if we already have another user with this address. + * + * @param string $jabber Address to check + * + * @return boolean whether the Jabber ID exists + */ + + function jabberExists($jabber) { $user = common_current_user(); + $other = User::staticGet('jabber', $jabber); + if (!$other) { return false; } else { diff --git a/actions/openidsettings.php b/actions/openidsettings.php index 9265b5ea62..a21a9869e3 100644 --- a/actions/openidsettings.php +++ b/actions/openidsettings.php @@ -1,9 +1,12 @@ . + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} -require_once(INSTALLDIR.'/lib/settingsaction.php'); -require_once(INSTALLDIR.'/lib/openid.php'); +require_once INSTALLDIR.'/lib/settingsaction.php'; +require_once INSTALLDIR.'/lib/openid.php'; + +/** + * Settings for OpenID + * + * Lets users add, edit and delete OpenIDs from their account + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ class OpenidsettingsAction extends SettingsAction { + /** + * Title of the page + * + * @return string Page title + */ - function get_instructions() + function title() { - return _('[OpenID](%%doc.openid%%) lets you log into many sites ' . - ' with the same user account. '. - ' Manage your associated OpenIDs from here.'); + return _('OpenID settings'); } - function show_form($msg=null, $success=false) - { + /** + * Instructions for use + * + * @return string Instructions for use + */ + function getInstructions() + { + return _('[OpenID](%%doc.openid%%) lets you log into many sites ' . + ' with the same user account. '. + ' Manage your associated OpenIDs from here.'); + } + + /** + * Show the form for OpenID management + * + * We have one form with a few different submit buttons to do different things. + * + * @return void + */ + + function showContent() + { $user = common_current_user(); - $this->form_header(_('OpenID settings'), $msg, $success); - $this->elementStart('form', array('method' => 'post', - 'id' => 'openidadd', - 'action' => - common_local_url('openidsettings'))); + 'id' => 'openidadd', + 'action' => + common_local_url('openidsettings'))); $this->hidden('token', common_session_token()); $this->element('h2', null, _('Add OpenID')); $this->element('p', null, _('If you want to add an OpenID to your account, ' . - 'enter it in the box below and click "Add".')); + 'enter it in the box below and click "Add".')); $this->elementStart('p'); $this->element('label', array('for' => 'openid_url'), _('OpenID URL')); @@ -63,6 +108,7 @@ class OpenidsettingsAction extends SettingsAction $this->elementEnd('form'); $oid = new User_openid(); + $oid->user_id = $user->id; $cnt = $oid->find(); @@ -74,8 +120,10 @@ class OpenidsettingsAction extends SettingsAction if ($cnt == 1 && !$user->password) { $this->element('p', null, - _('Removing your only OpenID would make it impossible to log in! ' . - 'If you need to remove it, add another OpenID first.')); + _('Removing your only OpenID '. + 'would make it impossible to log in! ' . + 'If you need to remove it, '. + 'add another OpenID first.')); if ($oid->fetch()) { $this->elementStart('p'); @@ -88,14 +136,15 @@ class OpenidsettingsAction extends SettingsAction $this->element('p', null, _('You can remove an OpenID from your account '. - 'by clicking the button marked "Remove".')); + 'by clicking the button marked "Remove".')); $idx = 0; while ($oid->fetch()) { - $this->elementStart('form', array('method' => 'POST', - 'id' => 'openiddelete' . $idx, - 'action' => - common_local_url('openidsettings'))); + $this->elementStart('form', + array('method' => 'POST', + 'id' => 'openiddelete' . $idx, + 'action' => + common_local_url('openidsettings'))); $this->elementStart('p'); $this->hidden('token', common_session_token()); $this->element('a', array('href' => $oid->canonical), @@ -115,47 +164,65 @@ class OpenidsettingsAction extends SettingsAction } } } - - common_show_footer(); } - function handle_post() + /** + * Handle a POST request + * + * Muxes to different sub-functions based on which button was pushed + * + * @return void + */ + + function handlePost() { - # CSRF protection + // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->show_form(_('There was a problem with your session token. Try again, please.')); + $this->showForm(_('There was a problem with your session token. '. + 'Try again, please.')); return; } if ($this->arg('add')) { - $result = oid_authenticate($this->trimmed('openid_url'), 'finishaddopenid'); - if (is_string($result)) { # error message - $this->show_form($result); + $result = oid_authenticate($this->trimmed('openid_url'), + 'finishaddopenid'); + if (is_string($result)) { // error message + $this->showForm($result); } } else if ($this->arg('remove')) { - $this->remove_openid(); + $this->removeOpenid(); } else { - $this->show_form(_('Something weird happened.')); + $this->showForm(_('Something weird happened.')); } } - function remove_openid() - { + /** + * Handles a request to remove an OpenID from the user's account + * + * Validates input and, if everything is OK, deletes the OpenID. + * Reloads the form with a success or error notification. + * + * @return void + */ + function removeOpenid() + { $openid_url = $this->trimmed('openid_url'); + $oid = User_openid::staticGet('canonical', $openid_url); + if (!$oid) { - $this->show_form(_('No such OpenID.')); + $this->showForm(_('No such OpenID.')); return; } $cur = common_current_user(); if (!$cur || $oid->user_id != $cur->id) { - $this->show_form(_('That OpenID does not belong to you.')); + $this->showForm(_('That OpenID does not belong to you.')); return; } $oid->delete(); - $this->show_form(_('OpenID removed.'), true); + $this->showForm(_('OpenID removed.'), true); return; } } diff --git a/actions/smssettings.php b/actions/smssettings.php index c5879e4d95..f214997ec6 100644 --- a/actions/smssettings.php +++ b/actions/smssettings.php @@ -1,9 +1,12 @@ . + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} -require_once(INSTALLDIR.'/lib/settingsaction.php'); -require_once(INSTALLDIR.'/actions/emailsettings.php'); +require_once INSTALLDIR.'/lib/settingsaction.php'; -class SmssettingsAction extends EmailsettingsAction +/** + * Settings for SMS + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see SettingsAction + */ + +class SmssettingsAction extends SettingsAction { + /** + * Title of the page + * + * @return string Title of the page + */ - function get_instructions() + function title() + { + return _('SMS Settings'); + } + + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() { return _('You can receive SMS messages through email from %%site.name%%.'); } - function show_form($msg=null, $success=false) + /** + * Content area of the page + * + * Shows a form for adding and removing SMS phone numbers and setting + * SMS preferences. + * + * @return void + */ + + function showContent() { $user = common_current_user(); - $this->form_header(_('SMS Settings'), $msg, $success); + $this->elementStart('form', array('method' => 'post', - 'id' => 'smssettings', - 'action' => - common_local_url('smssettings'))); + 'id' => 'smssettings', + 'action' => + common_local_url('smssettings'))); + $this->hidden('token', common_session_token()); $this->element('h2', null, _('Address')); if ($user->sms) { $this->elementStart('p'); $carrier = $user->getCarrier(); - $this->element('span', 'address confirmed', $user->sms . ' (' . $carrier->name . ')'); + $this->element('span', 'address confirmed', + $user->sms . ' (' . $carrier->name . ')'); $this->element('span', 'input_instructions', _('Current confirmed SMS-enabled phone number.')); $this->hidden('sms', $user->sms); @@ -52,11 +102,12 @@ class SmssettingsAction extends EmailsettingsAction $this->elementEnd('p'); $this->submit('remove', _('Remove')); } else { - $confirm = $this->get_confirmation(); + $confirm = $this->getConfirmation(); if ($confirm) { $carrier = Sms_carrier::staticGet($confirm->address_extra); $this->elementStart('p'); - $this->element('span', 'address unconfirmed', $confirm->address . ' (' . $carrier->name . ')'); + $this->element('span', 'address unconfirmed', + $confirm->address . ' (' . $carrier->name . ')'); $this->element('span', 'input_instructions', _('Awaiting confirmation on this phone number.')); $this->hidden('sms', $confirm->address); @@ -69,15 +120,16 @@ class SmssettingsAction extends EmailsettingsAction } else { $this->input('sms', _('SMS Phone number'), ($this->arg('sms')) ? $this->arg('sms') : null, - _('Phone number, no punctuation or spaces, with area code')); - $this->carrier_select(); + _('Phone number, no punctuation or spaces, '. + 'with area code')); + $this->carrierSelect(); $this->submit('add', _('Add')); } } if ($user->sms) { $this->element('h2', null, _('Incoming email')); - + if ($user->incomingemail) { $this->elementStart('p'); $this->element('span', 'address', $user->incomingemail); @@ -86,32 +138,45 @@ class SmssettingsAction extends EmailsettingsAction $this->elementEnd('p'); $this->submit('removeincoming', _('Remove')); } - + $this->elementStart('p'); $this->element('span', 'input_instructions', - _('Make a new email address for posting to; cancels the old one.')); + _('Make a new email address for posting to; '. + 'cancels the old one.')); $this->elementEnd('p'); $this->submit('newincoming', _('New')); } - + $this->element('h2', null, _('Preferences')); - + $this->checkbox('smsnotify', - _('Send me notices through SMS; I understand I may incur exorbitant charges from my carrier.'), + _('Send me notices through SMS; '. + 'I understand I may incur '. + 'exorbitant charges from my carrier.'), $user->smsnotify); - + $this->submit('save', _('Save')); - + $this->elementEnd('form'); - common_show_footer(); } - function get_confirmation() + /** + * Get a pending confirmation, if any, for this user + * + * @return void + * + * @todo very similar to EmailsettingsAction::getConfirmation(); refactor? + */ + + function getConfirmation() { $user = common_current_user(); + $confirm = new Confirm_address(); - $confirm->user_id = $user->id; + + $confirm->user_id = $user->id; $confirm->address_type = 'sms'; + if ($confirm->find(true)) { return $confirm; } else { @@ -119,44 +184,62 @@ class SmssettingsAction extends EmailsettingsAction } } - function handle_post() - { + /** + * Handle posts to this form + * + * Based on the button that was pressed, muxes out to other functions + * to do the actual task requested. + * + * All sub-functions reload the form with a message -- success or failure. + * + * @return void + */ - # CSRF protection + function handlePost() + { + // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->show_form(_('There was a problem with your session token. Try again, please.')); + $this->showForm(_('There was a problem with your session token. '. + 'Try again, please.')); return; } if ($this->arg('save')) { - $this->save_preferences(); + $this->savePreferences(); } else if ($this->arg('add')) { - $this->add_address(); + $this->addAddress(); } else if ($this->arg('cancel')) { - $this->cancel_confirmation(); + $this->cancelConfirmation(); } else if ($this->arg('remove')) { - $this->remove_address(); + $this->removeAddress(); } else if ($this->arg('removeincoming')) { - $this->remove_incoming(); + $this->removeIncoming(); } else if ($this->arg('newincoming')) { - $this->new_incoming(); + $this->newIncoming(); } else if ($this->arg('confirm')) { - $this->confirm_code(); + $this->confirmCode(); } else { - $this->show_form(_('Unexpected form submission.')); + $this->showForm(_('Unexpected form submission.')); } } - function save_preferences() - { + /** + * Handle a request to save preferences + * + * Sets the user's SMS preferences in the DB. + * + * @return void + */ + function savePreferences() + { $smsnotify = $this->boolean('smsnotify'); - + $user = common_current_user(); - assert(!is_null($user)); # should already be checked + assert(!is_null($user)); // should already be checked $user->query('BEGIN'); @@ -174,45 +257,54 @@ class SmssettingsAction extends EmailsettingsAction $user->query('COMMIT'); - $this->show_form(_('Preferences saved.'), true); + $this->showForm(_('Preferences saved.'), true); } - function add_address() - { + /** + * Add a new SMS number for confirmation + * + * When the user requests a new SMS number, sends a confirmation + * message. + * + * @return void + */ + function addAddress() + { $user = common_current_user(); - $sms = $this->trimmed('sms'); + $sms = $this->trimmed('sms'); $carrier_id = $this->trimmed('carrier'); - - # Some validation + + // Some validation if (!$sms) { - $this->show_form(_('No phone number.')); + $this->showForm(_('No phone number.')); return; } if (!$carrier_id) { - $this->show_form(_('No carrier selected.')); - return; - } - - $sms = common_canonical_sms($sms); - - if ($user->sms == $sms) { - $this->show_form(_('That is already your phone number.')); - return; - } else if ($this->sms_exists($sms)) { - $this->show_form(_('That phone number already belongs to another user.')); + $this->showForm(_('No carrier selected.')); return; } - $confirm = new Confirm_address(); - $confirm->address = $sms; - $confirm->address_extra = $carrier_id; - $confirm->address_type = 'sms'; - $confirm->user_id = $user->id; - $confirm->code = common_confirmation_code(40); + $sms = common_canonical_sms($sms); + + if ($user->sms == $sms) { + $this->showForm(_('That is already your phone number.')); + return; + } else if ($this->smsExists($sms)) { + $this->showForm(_('That phone number already belongs to another user.')); + return; + } + + $confirm = new Confirm_address(); + + $confirm->address = $sms; + $confirm->address_extra = $carrier_id; + $confirm->address_type = 'sms'; + $confirm->user_id = $user->id; + $confirm->code = common_confirmation_code(40); $result = $confirm->insert(); @@ -223,30 +315,39 @@ class SmssettingsAction extends EmailsettingsAction } $carrier = Sms_carrier::staticGet($carrier_id); - + mail_confirm_sms($confirm->code, $user->nickname, $carrier->toEmailAddress($sms)); - $msg = _('A confirmation code was sent to the phone number you added. Check your inbox (and spam box!) for the code and instructions on how to use it.'); + $msg = _('A confirmation code was sent to the phone number you added. '. + 'Check your phone for the code and instructions '. + 'on how to use it.'); - $this->show_form($msg, true); + $this->showForm($msg, true); } - function cancel_confirmation() + /** + * Cancel a pending confirmation + * + * Cancels the confirmation. + * + * @return void + */ + + function cancelConfirmation() { - - $sms = $this->trimmed('sms'); + $sms = $this->trimmed('sms'); $carrier = $this->trimmed('carrier'); - - $confirm = $this->get_confirmation(); - + + $confirm = $this->getConfirmation(); + if (!$confirm) { - $this->show_form(_('No pending confirmation to cancel.')); + $this->showForm(_('No pending confirmation to cancel.')); return; } if ($confirm->address != $sms) { - $this->show_form(_('That is the wrong confirmation number.')); + $this->showForm(_('That is the wrong confirmation number.')); return; } @@ -258,28 +359,37 @@ class SmssettingsAction extends EmailsettingsAction return; } - $this->show_form(_('Confirmation cancelled.'), true); + $this->showForm(_('Confirmation cancelled.'), true); } - function remove_address() - { + /** + * Remove a phone number from the user's account + * + * @return void + */ + function removeAddress() + { $user = common_current_user(); - $sms = $this->arg('sms'); + + $sms = $this->arg('sms'); $carrier = $this->arg('carrier'); - - # Maybe an old tab open...? + + // Maybe an old tab open...? if ($user->sms != $sms) { - $this->show_form(_('That is not your phone number.')); + $this->showForm(_('That is not your phone number.')); return; } $user->query('BEGIN'); + $original = clone($user); - $user->sms = null; - $user->carrier = null; - $user->smsemail = null; + + $user->sms = null; + $user->carrier = null; + $user->smsemail = null; + $result = $user->updateKeys($original); if (!$result) { common_log_db_error($user, 'UPDATE', __FILE__); @@ -288,13 +398,25 @@ class SmssettingsAction extends EmailsettingsAction } $user->query('COMMIT'); - $this->show_form(_('The address was removed.'), true); + $this->showForm(_('The address was removed.'), true); } - - function sms_exists($sms) + + /** + * Does this sms number exist in our database? + * + * Also checks if it belongs to someone else + * + * @param string $sms phone number to check + * + * @return boolean does the number exist + */ + + function smsExists($sms) { $user = common_current_user(); + $other = User::staticGet('sms', $sms); + if (!$other) { return false; } else { @@ -302,15 +424,22 @@ class SmssettingsAction extends EmailsettingsAction } } - function carrier_select() + /** + * Show a drop-down box with all the SMS carriers in the DB + * + * @return void + */ + + function carrierSelect() { $carrier = new Sms_carrier(); + $cnt = $carrier->find(); $this->elementStart('p'); $this->element('label', array('for' => 'carrier')); $this->elementStart('select', array('name' => 'carrier', - 'id' => 'carrier')); + 'id' => 'carrier')); $this->element('option', array('value' => 0), _('Select a carrier')); while ($carrier->fetch()) { @@ -321,23 +450,30 @@ class SmssettingsAction extends EmailsettingsAction $this->elementEnd('p'); $this->element('span', 'input_instructions', sprintf(_('Mobile carrier for your phone. '. - 'If you know a carrier that accepts ' . + 'If you know a carrier that accepts ' . 'SMS over email but isn\'t listed here, ' . 'send email to let us know at %s.'), common_config('site', 'email'))); } - function confirm_code() + /** + * Confirm an SMS confirmation code + * + * Redirects to the confirmaddress page for this code + * + * @return void + */ + + function confirmCode() { - $code = $this->trimmed('code'); - + if (!$code) { - $this->show_form(_('No code entered')); + $this->showForm(_('No code entered')); return; } - - common_redirect(common_local_url('confirmaddress', + + common_redirect(common_local_url('confirmaddress', array('code' => $code))); } } diff --git a/actions/twittersettings.php b/actions/twittersettings.php index d6d31c4838..5492dd9958 100644 --- a/actions/twittersettings.php +++ b/actions/twittersettings.php @@ -1,9 +1,12 @@ . + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} -require_once(INSTALLDIR.'/lib/settingsaction.php'); +require_once INSTALLDIR.'/lib/settingsaction.php'; define('SUBSCRIPTIONS', 80); +/** + * Settings for Twitter integration + * + * @category Settings + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see SettingsAction + */ + class TwittersettingsAction extends SettingsAction { + /** + * Title of the page + * + * @return string Title of the page + */ - function get_instructions() + function title() { - return _('Add your Twitter account to automatically send your notices to Twitter, ' . - 'and subscribe to Twitter friends already here.'); + _('Twitter settings'); } - function show_form($msg=null, $success=false) + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() + { + return _('Add your Twitter account to automatically send '. + ' your notices to Twitter, ' . + 'and subscribe to Twitter friends already here.'); + } + + /** + * Content area of the page + * + * Shows a form for associating a Twitter account with this + * Laconica account. Also lets the user set preferences. + * + * @return void + */ + + function showContent() { $user = common_current_user(); + $profile = $user->getProfile(); + $fuser = null; + $flink = Foreign_link::getByUserID($user->id, 1); // 1 == Twitter if ($flink) { $fuser = $flink->getForeignUser(); } - $this->form_header(_('Twitter settings'), $msg, $success); $this->elementStart('form', array('method' => 'post', - 'id' => 'twittersettings', - 'action' => - common_local_url('twittersettings'))); + 'id' => 'twittersettings', + 'action' => + common_local_url('twittersettings'))); $this->hidden('token', common_session_token()); $this->element('h2', null, _('Twitter Account')); @@ -56,7 +108,7 @@ class TwittersettingsAction extends SettingsAction $this->elementStart('p'); $this->element('span', 'twitter_user', $fuser->nickname); - $this->element('a', array('href' => $fuser->uri), $fuser->uri); + $this->element('a', array('href' => $fuser->uri), $fuser->uri); $this->element('span', 'input_instructions', _('Current verified Twitter account.')); $this->hidden('flink_foreign_id', $flink->foreign_id); @@ -64,7 +116,9 @@ class TwittersettingsAction extends SettingsAction $this->submit('remove', _('Remove')); } else { $this->input('twitter_username', _('Twitter user name'), - ($this->arg('twitter_username')) ? $this->arg('twitter_username') : $profile->nickname, + ($this->arg('twitter_username')) ? + $this->arg('twitter_username') : + $profile->nickname, _('No spaces, please.')); // hey, it's what Twitter says $this->password('twitter_password', _('Twitter password')); @@ -72,14 +126,23 @@ class TwittersettingsAction extends SettingsAction $this->element('h2', null, _('Preferences')); - $this->checkbox('noticesync', _('Automatically send my notices to Twitter.'), - ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND) : true); + $this->checkbox('noticesync', + _('Automatically send my notices to Twitter.'), + ($flink) ? + ($flink->noticesync & FOREIGN_NOTICE_SEND) : + true); - $this->checkbox('replysync', _('Send local "@" replies to Twitter.'), - ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : true); + $this->checkbox('replysync', + _('Send local "@" replies to Twitter.'), + ($flink) ? + ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : + true); - $this->checkbox('friendsync', _('Subscribe to my Twitter friends here.'), - ($flink) ? ($flink->friendsync & FOREIGN_FRIEND_RECV) : false); + $this->checkbox('friendsync', + _('Subscribe to my Twitter friends here.'), + ($flink) ? + ($flink->friendsync & FOREIGN_FRIEND_RECV) : + false); if ($flink) { $this->submit('save', _('Save')); @@ -87,24 +150,31 @@ class TwittersettingsAction extends SettingsAction $this->submit('add', _('Add')); } - $this->show_twitter_subscriptions(); + $this->showTwitterSubscriptions(); $this->elementEnd('form'); - - common_show_footer(); } - function subscribed_twitter_users() + /** + * Gets some of the user's Twitter friends + * + * Gets the number of Twitter friends that are on this + * instance of Laconica. + * + * @return array array of User objects + */ + + function subscribedTwitterUsers() { $current_user = common_current_user(); $qry = 'SELECT user.* ' . - 'FROM subscription ' . - 'JOIN user ON subscription.subscribed = user.id ' . - 'JOIN foreign_link ON foreign_link.user_id = user.id ' . - 'WHERE subscriber = %d ' . - 'ORDER BY user.nickname'; + 'FROM subscription ' . + 'JOIN user ON subscription.subscribed = user.id ' . + 'JOIN foreign_link ON foreign_link.user_id = user.id ' . + 'WHERE subscriber = %d ' . + 'ORDER BY user.nickname'; $user = new User(); @@ -123,10 +193,20 @@ class TwittersettingsAction extends SettingsAction return $users; } - function show_twitter_subscriptions() + /** + * Show user's Twitter friends + * + * Gets the number of Twitter friends that are on this + * instance of Laconica, and shows their mini-avatars. + * + * @return void + */ + + function showTwitterSubscriptions() { - $friends = $this->subscribed_twitter_users(); + $friends = $this->subscribedTwitterUsers(); + $friends_count = count($friends); if ($friends_count > 0) { @@ -146,13 +226,19 @@ class TwittersettingsAction extends SettingsAction $this->elementStart('li'); $this->elementStart('a', array('title' => ($other->fullname) ? - $other->fullname : - $other->nickname, - 'href' => $other->profileurl, - 'rel' => 'contact', - 'class' => 'subscription')); + $other->fullname : + $other->nickname, + 'href' => $other->profileurl, + 'rel' => 'contact', + 'class' => 'subscription')); + $avatar = $other->getAvatar(AVATAR_MINI_SIZE); - $this->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)), + + $avatar_url = ($avatar) ? + common_avatar_display_url($avatar) : + common_default_avatar(AVATAR_MINI_SIZE); + + $this->element('img', array('src' => $avatar_url, 'width' => AVATAR_MINI_SIZE, 'height' => AVATAR_MINI_SIZE, 'class' => 'avatar mini', @@ -168,88 +254,96 @@ class TwittersettingsAction extends SettingsAction $this->elementEnd('div'); } - - // XXX Figure out a way to show all Twitter friends... ? - - /* - if ($subs_count > SUBSCRIPTIONS) { - $this->elementStart('p', array('id' => 'subscriptions_viewall')); - - $this->element('a', array('href' => common_local_url('subscriptions', - array('nickname' => $profile->nickname)), - 'class' => 'moresubscriptions'), - _('All subscriptions')); - $this->elementEnd('p'); - } - */ - } - function handle_post() + /** + * Handle posts to this form + * + * Based on the button that was pressed, muxes out to other functions + * to do the actual task requested. + * + * All sub-functions reload the form with a message -- success or failure. + * + * @return void + */ + + function handlePost() { - # CSRF protection + // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { - $this->show_form(_('There was a problem with your session token. Try again, please.')); + $this->showForm(_('There was a problem with your session token. '. + 'Try again, please.')); return; } if ($this->arg('save')) { - $this->save_preferences(); + $this->savePreferences(); } else if ($this->arg('add')) { - $this->add_twitter_acct(); + $this->addTwitterAccount(); } else if ($this->arg('remove')) { - $this->remove_twitter_acct(); + $this->removeTwitterAccount(); } else { - $this->show_form(_('Unexpected form submission.')); + $this->showForm(_('Unexpected form submission.')); } } - function add_twitter_acct() - { + /** + * Associate a Twitter account with the user's account + * + * Validates post input; verifies it against Twitter; and if + * successful stores in the database. + * + * @return void + */ + function addTwitterAccount() + { $screen_name = $this->trimmed('twitter_username'); - $password = $this->trimmed('twitter_password'); - $noticesync = $this->boolean('noticesync'); - $replysync = $this->boolean('replysync'); - $friendsync = $this->boolean('friendsync'); + $password = $this->trimmed('twitter_password'); + $noticesync = $this->boolean('noticesync'); + $replysync = $this->boolean('replysync'); + $friendsync = $this->boolean('friendsync'); if (!Validate::string($screen_name, - array( 'min_length' => 1, - 'max_length' => 15, - 'format' => VALIDATE_NUM . VALIDATE_ALPHA . '_'))) { - $this->show_form( - _('Username must have only numbers, upper- and lowercase letters, and underscore (_). 15 chars max.')); + array('min_length' => 1, + 'max_length' => 15, + 'format' => VALIDATE_NUM.VALIDATE_ALPHA.'_'))) { + $this->showForm(_('Username must have only numbers, '. + 'upper- and lowercase letters, '. + 'and underscore (_). 15 chars max.')); return; } - if (!$this->verify_credentials($screen_name, $password)) { - $this->show_form(_('Could not verify your Twitter credentials!')); + if (!$this->verifyCredentials($screen_name, $password)) { + $this->showForm(_('Could not verify your Twitter credentials!')); return; } $twit_user = twitter_user_info($screen_name, $password); if (!$twit_user) { - $this->show_form(sprintf(_('Unable to retrieve account information for "%s" from Twitter.'), - $screen_name)); + $this->showForm(sprintf(_('Unable to retrieve account information '. + 'For "%s" from Twitter.'), + $screen_name)); return; } if (!save_twitter_user($twit_user->id, $screen_name)) { - $this->show_form(_('Unable to save your Twitter settings!')); + $this->showForm(_('Unable to save your Twitter settings!')); return; } $user = common_current_user(); - $flink = DB_DataObject::factory('foreign_link'); - $flink->user_id = $user->id; - $flink->foreign_id = $twit_user->id; - $flink->service = 1; // Twitter + $flink = new Foreign_link(); + + $flink->user_id = $user->id; + $flink->foreign_id = $twit_user->id; + $flink->service = 1; // Twitter $flink->credentials = $password; - $flink->created = common_sql_now(); + $flink->created = common_sql_now(); $flink->set_flags($noticesync, $replysync, $friendsync); @@ -257,7 +351,7 @@ class TwittersettingsAction extends SettingsAction if (!$flink_id) { common_log_db_error($flink, 'INSERT', __FILE__); - $this->show_form(_('Unable to save your Twitter settings!')); + $this->showForm(_('Unable to save your Twitter settings!')); return; } @@ -265,19 +359,26 @@ class TwittersettingsAction extends SettingsAction save_twitter_friends($user, $twit_user->id, $screen_name, $password); } - $this->show_form(_('Twitter settings saved.'), true); + $this->showForm(_('Twitter settings saved.'), true); } - function remove_twitter_acct() - { + /** + * Disassociate an existing Twitter account from this account + * + * @return void + */ + function removeTwitterAccount() + { $user = common_current_user(); + $flink = Foreign_link::getByUserID($user->id, 1); + $flink_foreign_id = $this->arg('flink_foreign_id'); - # Maybe an old tab open...? + // Maybe an old tab open...? if ($flink->foreign_id != $flink_foreign_id) { - $this->show_form(_('That is not your Twitter account.')); + $this->showForm(_('That is not your Twitter account.')); return; } @@ -289,15 +390,20 @@ class TwittersettingsAction extends SettingsAction return; } - $this->show_form(_('Twitter account removed.'), true); + $this->showForm(_('Twitter account removed.'), true); } - function save_preferences() - { + /** + * Save user's Twitter-bridging preferences + * + * @return void + */ + function savePreferences() + { $noticesync = $this->boolean('noticesync'); $friendsync = $this->boolean('friendsync'); - $replysync = $this->boolean('replysync'); + $replysync = $this->boolean('replysync'); $user = common_current_user(); @@ -305,30 +411,32 @@ class TwittersettingsAction extends SettingsAction if (!$flink) { common_log_db_error($flink, 'SELECT', __FILE__); - $this->show_form(_('Couldn\'t save Twitter preferences.')); + $this->showForm(_('Couldn\'t save Twitter preferences.')); return; } $twitter_id = $flink->foreign_id; - $password = $flink->credentials; + $password = $flink->credentials; $fuser = $flink->getForeignUser(); if (!$fuser) { common_log_db_error($fuser, 'SELECT', __FILE__); - $this->show_form(_('Couldn\'t save Twitter preferences.')); + $this->showForm(_('Couldn\'t save Twitter preferences.')); return; } $screen_name = $fuser->nickname; $original = clone($flink); + $flink->set_flags($noticesync, $replysync, $friendsync); + $result = $flink->update($original); if ($result === false) { common_log_db_error($flink, 'UPDATE', __FILE__); - $this->show_form(_('Couldn\'t save Twitter preferences.')); + $this->showForm(_('Couldn\'t save Twitter preferences.')); return; } @@ -336,12 +444,22 @@ class TwittersettingsAction extends SettingsAction save_twitter_friends($user, $flink->foreign_id, $screen_name, $password); } - $this->show_form(_('Twitter preferences saved.'), true); + $this->showForm(_('Twitter preferences saved.'), true); } - function verify_credentials($screen_name, $password) + /** + * Verifies a username and password against Twitter's API + * + * @param string $screen_name Twitter user name + * @param string $password Twitter password + * + * @return boolean success flag + */ + + function verifyCredentials($screen_name, $password) { - $uri = 'http://twitter.com/account/verify_credentials.json'; + $uri = 'http://twitter.com/account/verifyCredentials.json'; + $data = get_twitter_data($uri, $screen_name, $password); if (!$data) { @@ -354,7 +472,7 @@ class TwittersettingsAction extends SettingsAction return false; } - $twitter_id = $user->id; + $twitter_id = $user->id; if ($twitter_id) { return $twitter_id; @@ -363,5 +481,4 @@ class TwittersettingsAction extends SettingsAction return false; } - } \ No newline at end of file