diff options
Diffstat (limited to 'actions')
37 files changed, 1040 insertions, 391 deletions
diff --git a/actions/all.php b/actions/all.php index 6c14d2f13..b65335abc 100644 --- a/actions/all.php +++ b/actions/all.php @@ -89,7 +89,7 @@ class AllAction extends ProfileAction // TRANS: Page title. %1$s is user nickname, %2$d is page number return sprintf(_('%1$s and friends, page %2$d'), $this->user->nickname, $this->page); } else { - // TRANS: Page title. %1$s is user nickname + // TRANS: Page title. %s is user nickname return sprintf(_("%s and friends"), $this->user->nickname); } } @@ -103,7 +103,7 @@ class AllAction extends ProfileAction 'nickname' => $this->user->nickname) ), - // TRANS: %1$s is user nickname + // TRANS: %s is user nickname sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)), new Feed(Feed::RSS2, common_local_url( @@ -112,7 +112,7 @@ class AllAction extends ProfileAction 'id' => $this->user->nickname ) ), - // TRANS: %1$s is user nickname + // TRANS: %s is user nickname sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)), new Feed(Feed::ATOM, common_local_url( @@ -121,7 +121,7 @@ class AllAction extends ProfileAction 'id' => $this->user->nickname ) ), - // TRANS: %1$s is user nickname + // TRANS: %s is user nickname sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname)) ); } @@ -134,18 +134,23 @@ class AllAction extends ProfileAction function showEmptyListMessage() { - // TRANS: %1$s is user nickname + // TRANS: %s is user nickname $message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->user->nickname) . ' '; if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { + // TRANS: Encouragement displayed on logged in user's empty timeline. + // TRANS: This message contains Markdown links. Keep "](" together. $message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.'); } else { // TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@" + // TRANS: This message contains Markdown links. Keep "](" together. $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } } else { + // TRANS: Encoutagement displayed on empty timeline user pages for anonymous users. + // TRANS: %s is a user nickname. This message contains Markdown links. Keep "](" together. $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->user->nickname); } @@ -181,7 +186,7 @@ class AllAction extends ProfileAction // TRANS: H1 text $this->element('h1', null, _("You and friends")); } else { - // TRANS: H1 text. %1$s is user nickname + // TRANS: H1 text. %s is a user nickname $this->element('h1', null, sprintf(_('%s and friends'), $this->user->nickname)); } } diff --git a/actions/apiaccountupdatedeliverydevice.php b/actions/apiaccountupdatedeliverydevice.php index 2d903cb46..a7342a94f 100644 --- a/actions/apiaccountupdatedeliverydevice.php +++ b/actions/apiaccountupdatedeliverydevice.php @@ -45,7 +45,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction { /** @@ -56,7 +55,6 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -76,7 +74,6 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -92,6 +89,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction if (!in_array($this->format, array('xml', 'json'))) { $this->clientError( + // TRANS: Client error displayed handling a non-existing API method. _('API method not found.'), 404, $this->format @@ -102,16 +100,14 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction // Note: Twitter no longer supports IM if (!in_array(strtolower($this->device), array('sms', 'im', 'none'))) { - $this->clientError( - _( - 'You must specify a parameter named ' . - '\'device\' with a value of one of: sms, im, none.' - ) - ); + // TRANS: Client error displayed when no valid device parameter is provided for a user's delivery device setting. + $this->clientError(_( 'You must specify a parameter named ' . + '\'device\' with a value of one of: sms, im, none.' )); return; } if (empty($this->user)) { + // TRANS: Client error displayed when no existing user is provided for a user's delivery device setting. $this->clientError(_('No such user.'), 404, $this->format); return; } @@ -131,6 +127,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction if ($result === false) { common_log_db_error($this->user, 'UPDATE', __FILE__); + // TRANS: Server error displayed when a user's delivery device cannot be updated. $this->serverError(_('Could not update user.')); return; } @@ -155,5 +152,4 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction $this->endDocument('json'); } } - } diff --git a/actions/apiaccountupdateprofile.php b/actions/apiaccountupdateprofile.php index 92d0f6b77..aea10e33e 100644 --- a/actions/apiaccountupdateprofile.php +++ b/actions/apiaccountupdateprofile.php @@ -43,10 +43,8 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiAccountUpdateProfileAction extends ApiAuthAction { - /** * Take arguments for running * @@ -55,7 +53,6 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -79,7 +76,6 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -103,6 +99,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction } if (empty($this->user)) { + // TRANS: Client error displayed if a user could not be found. $this->clientError(_('No such user.'), 404, $this->format); return; } @@ -110,6 +107,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction $profile = $this->user->getProfile(); if (empty($profile)) { + // TRANS: Client error displayed if a user profile could not be found. $this->clientError(_('User has no profile.')); return; } @@ -145,6 +143,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction if (!$result) { common_log_db_error($profile, 'UPDATE', __FILE__); + // TRANS: Server error displayed if a user profile could not be saved. $this->serverError(_('Could not save profile.')); return; } @@ -163,5 +162,4 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction $this->endDocument('json'); } } - } diff --git a/actions/apiaccountupdateprofilebackgroundimage.php b/actions/apiaccountupdateprofilebackgroundimage.php index 923fb1d11..87af962d2 100644 --- a/actions/apiaccountupdateprofilebackgroundimage.php +++ b/actions/apiaccountupdateprofilebackgroundimage.php @@ -42,10 +42,8 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction { - var $tile = false; /** @@ -56,7 +54,6 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -76,7 +73,6 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -92,6 +88,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction if (!in_array($this->format, array('xml', 'json'))) { $this->clientError( + // TRANS: Client error displayed when trying to handle an unknown API method. _('API method not found.'), 404, $this->format @@ -106,8 +103,11 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; @@ -125,7 +125,6 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction // is part of the img filename. if (empty($design)) { - $this->user->query('BEGIN'); // save new design @@ -134,6 +133,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction if (empty($id)) { common_log_db_error($id, 'INSERT', __FILE__); + // TRANS: Client error displayed when saving design settings fails because of an empty id. $this->clientError(_('Unable to save your design settings.')); return; } @@ -144,6 +144,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction if (empty($result)) { common_log_db_error($original, 'UPDATE', __FILE__); + // TRANS: Client error displayed when saving design settings fails because of an empty result. $this->clientError(_('Unable to save your design settings.')); $this->user->query('ROLLBACK'); return; @@ -185,6 +186,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction if ($result === false) { common_log_db_error($design, 'UPDATE', __FILE__); + // TRANS: Error displayed when updating design settings fails. $this->showForm(_('Could not update your design.')); return; } @@ -192,6 +194,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction $profile = $this->user->getProfile(); if (empty($profile)) { + // TRANS: Client error displayed when a user has no profile. $this->clientError(_('User has no profile.')); return; } @@ -208,5 +211,4 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction $this->endDocument('json'); } } - } diff --git a/actions/apiaccountupdateprofileimage.php b/actions/apiaccountupdateprofileimage.php index 7f868a6eb..1f38bd220 100644 --- a/actions/apiaccountupdateprofileimage.php +++ b/actions/apiaccountupdateprofileimage.php @@ -95,9 +95,11 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); - + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } diff --git a/actions/apiblockcreate.php b/actions/apiblockcreate.php index 53844cd2f..a9f31e791 100644 --- a/actions/apiblockcreate.php +++ b/actions/apiblockcreate.php @@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiBlockCreateAction extends ApiAuthAction { var $other = null; @@ -59,7 +58,6 @@ class ApiBlockCreateAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -79,7 +77,6 @@ class ApiBlockCreateAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -103,6 +100,7 @@ class ApiBlockCreateAction extends ApiAuthAction if ($this->user->id == $this->other->id) { $this->clientError( + // TRANS: Client error displayed when users try to block themselves. _("You cannot block yourself!"), 403, $this->format @@ -124,10 +122,8 @@ class ApiBlockCreateAction extends ApiAuthAction $this->showProfile($this->other, $this->format); $this->endDocument($this->format); } else { + // TRANS: Server error displayed when blocking a user has failed. $this->serverError(_('Block user failed.'), 500, $this->format); } - } - } - diff --git a/actions/apiblockdestroy.php b/actions/apiblockdestroy.php index 871ce66c7..b69907784 100644 --- a/actions/apiblockdestroy.php +++ b/actions/apiblockdestroy.php @@ -45,7 +45,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiBlockDestroyAction extends ApiAuthAction { var $other = null; @@ -58,7 +57,6 @@ class ApiBlockDestroyAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -78,7 +76,6 @@ class ApiBlockDestroyAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -112,10 +109,8 @@ class ApiBlockDestroyAction extends ApiAuthAction $this->showProfile($this->other, $this->format); $this->endDocument($this->format); } else { + // TRANS: Server error displayed when unblocking a user has failed. $this->serverError(_('Unblock user failed.')); } - } - } - diff --git a/actions/apidirectmessagenew.php b/actions/apidirectmessagenew.php index c126cd312..ccef57b3f 100644 --- a/actions/apidirectmessagenew.php +++ b/actions/apidirectmessagenew.php @@ -121,9 +121,9 @@ class ApiDirectMessageNewAction extends ApiAuthAction } else { $content_shortened = common_shorten_links($this->content); if (Message::contentTooLong($content_shortened)) { - // TRANS: Client error displayed when message content is too long. - // TRANS: %d is the maximum number of characters for a message. $this->clientError( + // TRANS: Client error displayed when message content is too long. + // TRANS: %d is the maximum number of characters for a message. sprintf(_m('That\'s too long. Maximum message size is %d character.', 'That\'s too long. Maximum message size is %d characters.', Message::maxContent()), Message::maxContent() ), diff --git a/actions/apifavoritecreate.php b/actions/apifavoritecreate.php index 15da01013..90a29d228 100644 --- a/actions/apifavoritecreate.php +++ b/actions/apifavoritecreate.php @@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiFavoriteCreateAction extends ApiAuthAction { var $notice = null; @@ -61,7 +60,6 @@ class ApiFavoriteCreateAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -81,7 +79,6 @@ class ApiFavoriteCreateAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -107,6 +104,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction if (empty($this->notice)) { $this->clientError( + // TRANS: Client error displayed when requesting a status with a non-existing ID. _('No status found with that ID.'), 404, $this->format @@ -118,6 +116,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction if ($this->user->hasFave($this->notice)) { $this->clientError( + // TRANS: Client error displayed when trying to mark a notice favourite that already is a favourite. _('This status is already a favorite.'), 403, $this->format @@ -129,6 +128,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction if (empty($fave)) { $this->clientError( + // TRANS: Client error displayed when marking a notice as favourite fails. _('Could not create favorite.'), 403, $this->format @@ -166,5 +166,4 @@ class ApiFavoriteCreateAction extends ApiAuthAction // XXX: notify by SMS } } - } diff --git a/actions/apigroupcreate.php b/actions/apigroupcreate.php index fa443573d..1608e030b 100644 --- a/actions/apigroupcreate.php +++ b/actions/apigroupcreate.php @@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiGroupCreateAction extends ApiAuthAction { var $group = null; @@ -95,7 +94,6 @@ class ApiGroupCreateAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -111,6 +109,7 @@ class ApiGroupCreateAction extends ApiAuthAction } if (empty($this->user)) { + // TRANS: Client error given when a user was not found (404). $this->clientError(_('No such user.'), 404, $this->format); return; } @@ -137,13 +136,13 @@ class ApiGroupCreateAction extends ApiAuthAction break; default: $this->clientError( + // TRANS: Client error given when an API method was not found (404). _('API method not found.'), 404, $this->format ); break; } - } /** @@ -164,6 +163,7 @@ class ApiGroupCreateAction extends ApiAuthAction if (!$valid) { $this->clientError( + // TRANS: Validation error in form for group creation. _( 'Nickname must have only lowercase letters ' . 'and numbers and no spaces.' @@ -174,6 +174,7 @@ class ApiGroupCreateAction extends ApiAuthAction return false; } elseif ($this->groupNicknameExists($this->nickname)) { $this->clientError( + // TRANS: Client error trying to create a group with a nickname this is already in use. _('Nickname already in use. Try another one.'), 403, $this->format @@ -181,6 +182,7 @@ class ApiGroupCreateAction extends ApiAuthAction return false; } else if (!User_group::allowedNickname($this->nickname)) { $this->clientError( + // TRANS: Client error in form for group creation. _('Not a valid nickname.'), 403, $this->format @@ -197,6 +199,7 @@ class ApiGroupCreateAction extends ApiAuthAction ) )) { $this->clientError( + // TRANS: Client error in form for group creation. _('Homepage is not a valid URL.'), 403, $this->format @@ -206,7 +209,8 @@ class ApiGroupCreateAction extends ApiAuthAction !is_null($this->fullname) && mb_strlen($this->fullname) > 255) { $this->clientError( - _('Full name is too long (max 255 chars).'), + // TRANS: Client error in form for group creation. + _('Full name is too long (maximum 255 characters).'), 403, $this->format ); @@ -225,7 +229,7 @@ class ApiGroupCreateAction extends ApiAuthAction !is_null($this->location) && mb_strlen($this->location) > 255) { $this->clientError( - _('Location is too long (max 255 chars).'), + _('Location is too long (maximum 255 characters).'), 403, $this->format ); diff --git a/actions/apimediaupload.php b/actions/apimediaupload.php index 54d7fda68..a33771cae 100644 --- a/actions/apimediaupload.php +++ b/actions/apimediaupload.php @@ -78,9 +78,11 @@ class ApiMediaUploadAction extends ApiAuthAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); - + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } diff --git a/actions/apioauthaccesstoken.php b/actions/apioauthaccesstoken.php index 663a7a2bb..f66e4af1e 100644 --- a/actions/apioauthaccesstoken.php +++ b/actions/apioauthaccesstoken.php @@ -44,7 +44,6 @@ require_once INSTALLDIR . '/lib/apioauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiOauthAccessTokenAction extends ApiOauthAction { protected $reqToken = null; @@ -67,21 +66,21 @@ class ApiOauthAccessTokenAction extends ApiOauthAction $server->add_signature_method($hmac_method); - $atok = null; + $atok = $app = null; // XXX: Insist that oauth_token and oauth_verifier be populated? // Spec doesn't say they MUST be. try { - $req = OAuthRequest::from_request(); $this->reqToken = $req->get_parameter('oauth_token'); $this->verifier = $req->get_parameter('oauth_verifier'); + $app = $datastore->getAppByRequestToken($this->reqToken); $atok = $server->fetch_access_token($req); - } catch (OAuthException $e) { + } catch (Exception $e) { common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage()); common_debug(var_export($req, true)); $code = $e->getCode(); @@ -92,22 +91,27 @@ class ApiOauthAccessTokenAction extends ApiOauthAction // Token exchange failed -- log it - list($proxy, $ip) = common_client_ip(); - $msg = sprintf( - 'API OAuth - Failure exchanging request token for access token, ' - . 'request token = %s, verifier = %s, IP = %s, proxy = %s', + 'API OAuth - Failure exchanging OAuth request token for access token, ' + . 'request token = %s, verifier = %s', $this->reqToken, - $this->verifier, - $ip, - $proxy + $this->verifier ); common_log(LOG_WARNING, $msg); - + // TRANS: Client error given from the OAuth API when the request token or verifier is invalid. $this->clientError(_("Invalid request token or verifier.", 400, 'text')); } else { + common_log( + LOG_INFO, + sprintf( + "Issued access token '%s' for application %d (%s).", + $atok->key, + $app->id, + $app->name + ) + ); $this->showAccessToken($atok); } } diff --git a/actions/apioauthauthorize.php b/actions/apioauthauthorize.php index ea5c30c2a..e0c9ff244 100644 --- a/actions/apioauthauthorize.php +++ b/actions/apioauthauthorize.php @@ -35,7 +35,7 @@ require_once INSTALLDIR . '/lib/apioauth.php'; require_once INSTALLDIR . '/lib/info.php'; /** - * Authorize an OAuth request token + * Authorize an Oputh request token * * @category API * @package StatusNet @@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/info.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiOauthAuthorizeAction extends Action { var $oauthTokenParam; @@ -69,11 +68,11 @@ class ApiOauthAuthorizeAction extends Action { parent::prepare($args); - $this->nickname = $this->trimmed('nickname'); - $this->password = $this->arg('password'); - $this->oauthTokenParam = $this->arg('oauth_token'); - $this->callback = $this->arg('oauth_callback'); - $this->store = new ApiStatusNetOAuthDataStore(); + $this->nickname = $this->trimmed('nickname'); + $this->password = $this->arg('password'); + $this->oauthTokenParam = $this->arg('oauth_token'); + $this->mode = $this->arg('mode'); + $this->store = new ApiStatusNetOAuthDataStore(); try { $this->app = $this->store->getAppByRequestToken($this->oauthTokenParam); @@ -93,7 +92,6 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -106,6 +104,7 @@ class ApiOauthAuthorizeAction extends Action // Make sure a oauth_token parameter was provided if (empty($this->oauthTokenParam)) { + // TRANS: Client error given when no oauth_token was passed to the OAuth API. $this->clientError(_('No oauth_token parameter provided.')); } else { @@ -113,20 +112,21 @@ class ApiOauthAuthorizeAction extends Action $this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam); if (empty($this->reqToken)) { - $this->serverError( - _('Invalid request token.') - ); + // TRANS: Client error given when an invalid request token was passed to the OAuth API. + $this->clientError(_('Invalid request token.')); } else { // Check to make sure we haven't already authorized the token if ($this->reqToken->state != 0) { - $this->clientError("Invalid request token."); + // TRANS: Client error given when an invalid request token was passed to the OAuth API. + $this->clientError(_('Request token already authorized.')); } } } // make sure there's an app associated with this token if (empty($this->app)) { + // TRANS: Client error given when an invalid request token was passed to the OAuth API. $this->clientError(_('Invalid request token.')); } @@ -156,10 +156,15 @@ class ApiOauthAuthorizeAction extends Action // XXX Force credentials check? - // XXX OpenID + // @fixme this should probably use a unified login form handler + $user = null; + if (Event::handle('StartOAuthLoginCheck', array($this, &$user))) { + $user = common_check_user($this->nickname, $this->password); + } + Event::handle('EndOAuthLoginCheck', array($this, &$user)); - $user = common_check_user($this->nickname, $this->password); if (empty($user)) { + // TRANS: Form validation error given when an invalid username and/or password was passed to the OAuth API. $this->showForm(_("Invalid nickname / password!")); return; } @@ -167,10 +172,11 @@ class ApiOauthAuthorizeAction extends Action $user = common_current_user(); } - if ($this->arg('allow')) { + // fetch the token + $this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam); + assert(!empty($this->reqToken)); - // fetch the token - $this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam); + if ($this->arg('allow')) { // mark the req token as authorized try { @@ -179,73 +185,66 @@ class ApiOauthAuthorizeAction extends Action $this->serverError($e->getMessage()); } - // Check to see if there was a previous token associated - // with this user/app and kill it. If the user is doing this she - // probably doesn't want any old tokens anyway. - - $appUser = Oauth_application_user::getByKeys($user, $this->app); - - if (!empty($appUser)) { - $result = $appUser->delete(); - - if (!$result) { - common_log_db_error($appUser, 'DELETE', __FILE__); - $this->serverError(_('Database error deleting OAuth application user.')); - } - } - - // associated the authorized req token with the user and the app - - $appUser = new Oauth_application_user(); + common_log( + LOG_INFO, + sprintf( + "API OAuth - User %d (%s) has authorized request token %s for OAuth application %d (%s).", + $user->id, + $user->nickname, + $this->reqToken->tok, + $this->app->id, + $this->app->name + ) + ); - $appUser->profile_id = $user->id; - $appUser->application_id = $this->app->id; + // XXX: Make sure we have a oauth_token_association table. The table + // is now in the main schema, but because it is being added with + // a point release, it's unlikely to be there. This code can be + // removed as of 1.0. + $this->ensureOauthTokenAssociationTable(); - // Note: do not copy the access type from the application. - // The access type should always be 0 when the OAuth app - // user record has a request token associated with it. - // Access type gets assigned once an access token has been - // granted. The OAuth app user record then gets updated - // with the new access token and access type. + $tokenAssoc = new Oauth_token_association(); - $appUser->token = $this->oauthTokenParam; - $appUser->created = common_sql_now(); + $tokenAssoc->profile_id = $user->id; + $tokenAssoc->application_id = $this->app->id; + $tokenAssoc->token = $this->oauthTokenParam; + $tokenAssoc->created = common_sql_now(); - $result = $appUser->insert(); + $result = $tokenAssoc->insert(); if (!$result) { - common_log_db_error($appUser, 'INSERT', __FILE__); - $this->serverError(_('Database error inserting OAuth application user.')); + common_log_db_error($tokenAssoc, 'INSERT', __FILE__); + // TRANS: Server error displayed when a database action fails. + $this->serverError(_('Database error inserting oauth_token_association.')); } - // If we have a callback redirect and provide the token - - // Note: A callback specified in the app setup overrides whatever - // is passed in with the request. - - if (!empty($this->app->callback_url)) { - $this->callback = $this->app->callback_url; - } + $callback = $this->getCallback(); - if (!empty($this->callback)) { - - $targetUrl = $this->getCallback( - $this->callback, + if (!empty($callback) && $this->reqToken->verified_callback != 'oob') { + $targetUrl = $this->buildCallbackUrl( + $callback, array( 'oauth_token' => $this->oauthTokenParam, 'oauth_verifier' => $this->reqToken->verifier // 1.0a ) ); + common_log(LOG_INFO, "Redirecting to callback: $targetUrl"); + // Redirect the user to the provided OAuth callback common_redirect($targetUrl, 303); - } else { + } elseif ($this->app->type == 2) { + // Strangely, a web application seems to want to do the OOB + // workflow. Because no callback was specified anywhere. common_log( - LOG_INFO, - "No oauth_callback parameter provided for application ID " - . $this->app->id - . " when authorizing request token." + LOG_WARNING, + sprintf( + "API OAuth - No callback provided for OAuth web client ID %s (%s) " + . "during authorization step. Falling back to OOB workflow.", + $this->app->id, + $this->app->name + ) ); } @@ -254,18 +253,118 @@ class ApiOauthAuthorizeAction extends Action } else if ($this->arg('cancel')) { + common_log( + LOG_INFO, + sprintf( + "API OAuth - User %d (%s) refused to authorize request token %s for OAuth application %d (%s).", + $user->id, + $user->nickname, + $this->reqToken->tok, + $this->app->id, + $this->app->name + ) + ); + try { $this->store->revoke_token($this->oauthTokenParam, 0); - $this->showCanceled(); } catch (Exception $e) { $this->ServerError($e->getMessage()); } + $callback = $this->getCallback(); + + // If there's a callback available, inform the consumer the user + // has refused authorization + if (!empty($callback) && $this->reqToken->verified_callback != 'oob') { + $targetUrl = $this->buildCallbackUrl( + $callback, + array( + 'oauth_problem' => 'user_refused', + ) + ); + + common_log(LOG_INFO, "Redirecting to callback: $targetUrl"); + + // Redirect the user to the provided OAuth callback + common_redirect($targetUrl, 303); + } + + // otherwise inform the user that authorization for the rt was declined + $this->showCanceled(); + } else { + // TRANS: Client error given on when invalid data was passed through a form in the OAuth API. $this->clientError(_('Unexpected form submission.')); } } + // XXX Remove this function when we hit 1.0 + function ensureOauthTokenAssociationTable() + { + $schema = Schema::get(); + + $reqTokenCols = array( + new ColumnDef('profile_id', 'integer', null, true, 'PRI'), + new ColumnDef('application_id', 'integer', null, true, 'PRI'), + new ColumnDef('token', 'varchar', 255, true, 'PRI'), + new ColumnDef('created', 'datetime', null, false), + new ColumnDef( + 'modified', + 'timestamp', + null, + false, + null, + 'CURRENT_TIMESTAMP', + 'on update CURRENT_TIMESTAMP' + ) + ); + + $schema->ensureTable('oauth_token_association', $reqTokenCols); + } + + /** + * Show body - override to add a special CSS class for the authorize + * page's "desktop mode" (minimal display) + * + * Calls template methods + * + * @return nothing + */ + function showBody() + { + $bodyClasses = array(); + + if ($this->desktopMode()) { + $bodyClasses[] = 'oauth-desktop-mode'; + } + + if (common_current_user()) { + $bodyClasses[] = 'user_in'; + } + + $attrs = array('id' => strtolower($this->trimmed('action'))); + + if (!empty($bodyClasses)) { + $attrs['class'] = implode(' ', $bodyClasses); + } + + $this->elementStart('body', $attrs); + + $this->elementStart('div', array('id' => 'wrap')); + if (Event::handle('StartShowHeader', array($this))) { + $this->showHeader(); + Event::handle('EndShowHeader', array($this)); + } + $this->showCore(); + if (Event::handle('StartShowFooter', array($this))) { + $this->showFooter(); + Event::handle('EndShowFooter', array($this)); + } + $this->elementEnd('div'); + $this->showScripts(); + $this->elementEnd('body'); + } + function showForm($error=null) { $this->error = $error; @@ -285,9 +384,9 @@ class ApiOauthAuthorizeAction extends Action * * @return string title of the page */ - function title() { + // TRANS: Title for a page where a user can confirm/deny account access by an external application. return _('An application would like to connect to your account'); } @@ -296,7 +395,6 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function showContent() { $this->elementStart('form', array('method' => 'post', @@ -305,27 +403,40 @@ class ApiOauthAuthorizeAction extends Action 'action' => common_local_url('ApiOauthAuthorize'))); $this->elementStart('fieldset'); $this->element('legend', array('id' => 'apioauthauthorize_allowdeny'), + // TRANS: Fieldset legend. _('Allow or deny access')); $this->hidden('token', common_session_token()); + $this->hidden('mode', $this->mode); $this->hidden('oauth_token', $this->oauthTokenParam); $this->hidden('oauth_callback', $this->callback); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->elementStart('p'); - if (!empty($this->app->icon)) { + if (!empty($this->app->icon) && $this->app->name != 'anonymous') { $this->element('img', array('src' => $this->app->icon)); } $access = ($this->app->access_type & Oauth_application::$writeAccess) ? 'access and update' : 'access'; - $msg = _('The application <strong>%1$s</strong> by ' . - '<strong>%2$s</strong> would like the ability ' . + // TRANS: User notification of external application requesting account access. + // TRANS: %1$s is the application name requesting access, %2$s is the organisation behind the application, + // TRANS: %3$s is the access type requested, %4$s is the StatusNet sitename. + if ($this->app->name == 'anonymous') { + // Special message for the anonymous app and consumer + $msg = _('An application would like the ability ' . 'to <strong>%3$s</strong> your %4$s account data. ' . 'You should only give access to your %4$s account ' . 'to third parties you trust.'); + } else { + $msg = _('The application <strong>%1$s</strong> by ' . + '<strong>%2$s</strong> would like the ability ' . + 'to <strong>%3$s</strong> your %4$s account data. ' . + 'You should only give access to your %4$s account ' . + 'to third parties you trust.'); + } $this->raw(sprintf($msg, $this->app->name, @@ -336,34 +447,43 @@ class ApiOauthAuthorizeAction extends Action $this->elementEnd('li'); $this->elementEnd('ul'); + // quickie hack + $button = false; if (!common_logged_in()) { - - $this->elementStart('fieldset'); - $this->element('legend', null, _('Account')); - $this->elementStart('ul', 'form_data'); - $this->elementStart('li'); - $this->input('nickname', _('Nickname')); - $this->elementEnd('li'); - $this->elementStart('li'); - $this->password('password', _('Password')); - $this->elementEnd('li'); - $this->elementEnd('ul'); - - $this->elementEnd('fieldset'); - + if (Event::handle('StartOAuthLoginForm', array($this, &$button))) { + $this->elementStart('fieldset'); + // TRANS: Fieldset legend. + $this->element('legend', null, _m('LEGEND','Account')); + $this->elementStart('ul', 'form_data'); + $this->elementStart('li'); + // TRANS: Field label on OAuth API authorisation form. + $this->input('nickname', _('Nickname')); + $this->elementEnd('li'); + $this->elementStart('li'); + // TRANS: Field label on OAuth API authorisation form. + $this->password('password', _('Password')); + $this->elementEnd('li'); + $this->elementEnd('ul'); + + $this->elementEnd('fieldset'); + } + Event::handle('EndOAuthLoginForm', array($this, &$button)); } $this->element('input', array('id' => 'cancel_submit', 'class' => 'submit submit form_action-primary', 'name' => 'cancel', 'type' => 'submit', - 'value' => _('Cancel'))); + // TRANS: Button text that when clicked will cancel the process of allowing access to an account + // TRANS: by an external application. + 'value' => _m('BUTTON','Cancel'))); $this->element('input', array('id' => 'allow_submit', 'class' => 'submit submit form_action-secondary', 'name' => 'allow', 'type' => 'submit', - 'value' => _('Allow'))); + // TRANS: Button text that when clicked will allow access to an account by an external application. + 'value' => $button ? $button : _m('BUTTON','Allow'))); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -377,9 +497,9 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function getInstructions() { + // TRANS: Form instructions. return _('Authorize access to your account information.'); } @@ -390,18 +510,61 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function showLocalNav() { // NOP } + /* + * Checks to see if a the "mode" parameter is present in the request + * and set to "desktop". If it is, the page is meant to be displayed in + * a small frame of another application, and we should suppress the + * header, aside, and footer. + */ + function desktopMode() + { + if (isset($this->mode) && $this->mode == 'desktop') { + return true; + } else { + return false; + } + } + + /* + * Override - suppress output in "desktop" mode + */ + function showHeader() + { + if ($this->desktopMode() == false) { + parent::showHeader(); + } + } + + /* + * Override - suppress output in "desktop" mode + */ + function showAside() + { + if ($this->desktopMode() == false) { + parent::showAside(); + } + } + + /* + * Override - suppress output in "desktop" mode + */ + function showFooter() + { + if ($this->desktopMode() == false) { + parent::showFooter(); + } + } + /** * Show site notice. * * @return nothing */ - function showSiteNotice() { // NOP @@ -414,7 +577,6 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showNoticeForm() { // NOP @@ -426,14 +588,16 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showCanceled() { $info = new InfoAction( + // TRANS: Header for user notification after revoking OAuth access to an application. _('Authorization canceled.'), sprintf( + // TRANS: User notification after revoking OAuth access to an application. + // TRANS: %s is an OAuth token. _('The request token %s has been revoked.'), - $this->oauthTokenParm + $this->oauthTokenParam ) ); @@ -446,21 +610,46 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showAuthorized() { - $title = sprintf( - _("You have successfully authorized %s."), - $this->app->name - ); + $title = null; + $msg = null; - $msg = sprintf( - _('Please return to %s and enter the following security code to complete the process.'), - $this->app->name - ); + if ($this->app->name == 'anonymous') { + + $title = + // TRANS: Title of the page notifying the user that an anonymous client application was successfully authorized to access the user's account with OAuth. + _('You have successfully authorized the application'); + + $msg = + // TRANS: Message notifying the user that an anonymous client application was successfully authorized to access the user's account with OAuth. + _('Please return to the application and enter the following security code to complete the process.'); + + } else { + + $title = sprintf( + // TRANS: Title of the page notifying the user that the client application was successfully authorized to access the user's account with OAuth. + // TRANS: %s is the authorised application name. + _('You have successfully authorized %s'), + $this->app->name + ); + + $msg = sprintf( + // TRANS: Message notifying the user that the client application was successfully authorized to access the user's account with OAuth. + // TRANS: %s is the authorised application name. + _('Please return to %s and enter the following security code to complete the process.'), + $this->app->name + ); + + } if ($this->reqToken->verified_callback == 'oob') { - $pin = new ApiOauthPinAction($title, $msg, $this->reqToken->verifier); + $pin = new ApiOauthPinAction( + $title, + $msg, + $this->reqToken->verifier, + $this->desktopMode() + ); $pin->showPage(); } else { @@ -481,6 +670,36 @@ class ApiOauthAuthorizeAction extends Action } /* + * Figure out what the callback should be + */ + function getCallback() + { + $callback = null; + + // Return the verified callback if we have one + if ($this->reqToken->verified_callback != 'oob') { + + $callback = $this->reqToken->verified_callback; + + // Otherwise return the callback that was provided when + // registering the app + if (empty($callback)) { + + common_debug( + "No verified callback found for request token, using application callback: " + . $this->app->callback_url, + __FILE__ + ); + + $callback = $this->app->callback_url; + } + + } + + return $callback; + } + + /* * Properly format the callback URL and parameters so it's * suitable for a redirect in the OAuth dance * @@ -489,8 +708,7 @@ class ApiOauthAuthorizeAction extends Action * * @return string $url a URL to use for redirecting to */ - - function getCallback($url, $params) + function buildCallbackUrl($url, $params) { foreach ($params as $k => $v) { $url = $this->appendQueryVar( @@ -513,7 +731,6 @@ class ApiOauthAuthorizeAction extends Action * * @return string $url the new URL with added parameter */ - function appendQueryVar($url, $k, $v) { $url = preg_replace('/(.*)(\?|&)' . $k . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&'); $url = substr($url, 0, -1); diff --git a/actions/apioauthpin.php b/actions/apioauthpin.php index 5e6713a54..a0d98e543 100644 --- a/actions/apioauthpin.php +++ b/actions/apioauthpin.php @@ -31,8 +31,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once INSTALLDIR . '/lib/info.php'; - /** * Class for displaying an OAuth verifier pin * @@ -47,14 +45,122 @@ require_once INSTALLDIR . '/lib/info.php'; class ApiOauthPinAction extends InfoAction { - function __construct($title, $message, $verifier) + function __construct($title, $message, $verifier, $desktopMode = false) { - $this->verifier = $verifier; - $this->title = $title; + $this->verifier = $verifier; + $this->title = $title; + $this->desktopMode = $desktopMode; parent::__construct($title, $message); } /** + * Show body - override to add a special CSS class for the pin pages's + * "desktop mode" (minimal display) + * + * Calls template methods + * + * @return nothing + */ + function showBody() + { + $bodyClasses = array(); + + if ($this->desktopMode) { + $bodyClasses[] = 'oauth-desktop-mode'; + } + + if (common_current_user()) { + $bodyClasses[] = 'user_in'; + } + + $attrs = array('id' => strtolower($this->trimmed('action'))); + + if (!empty($bodyClasses)) { + $attrs['class'] = implode(' ', $bodyClasses); + } + + $this->elementStart('body', $attrs); + + $this->elementStart('div', array('id' => 'wrap')); + if (Event::handle('StartShowHeader', array($this))) { + $this->showHeader(); + Event::handle('EndShowHeader', array($this)); + } + $this->showCore(); + if (Event::handle('StartShowFooter', array($this))) { + $this->showFooter(); + Event::handle('EndShowFooter', array($this)); + } + $this->elementEnd('div'); + $this->showScripts(); + $this->elementEnd('body'); + } + + /** + * A local menu + * + * Shows different login/register actions. + * + * @return void + */ + function showLocalNav() + { + // NOP + } + + /* + * Override - suppress output in "desktop" mode + */ + function showHeader() + { + if ($this->desktopMode == false) { + parent::showHeader(); + } + } + + /* + * Override - suppress output in "desktop" mode + */ + function showAside() + { + if ($this->desktopMode == false) { + parent::showAside(); + } + } + + /* + * Override - suppress output in "desktop" mode + */ + function showFooter() + { + if ($this->desktopMode == false) { + parent::showFooter(); + } + } + + /** + * Show site notice. + * + * @return nothing + */ + function showSiteNotice() + { + // NOP + } + + /** + * Show notice form. + * + * Show the form for posting a new notice + * + * @return nothing + */ + function showNoticeForm() + { + // NOP + } + + /** * Display content. * * @return nothing diff --git a/actions/apioauthrequesttoken.php b/actions/apioauthrequesttoken.php index 478d2dbfc..376567125 100644 --- a/actions/apioauthrequesttoken.php +++ b/actions/apioauthrequesttoken.php @@ -146,7 +146,7 @@ class ApiOauthRequestTokenAction extends ApiOauthAction function verifyCallback($callback) { if ($callback == "oob") { - common_debug("OAuth request token requested for out of bounds client."); + common_debug("OAuth request token requested for out of band client."); // XXX: Should we throw an error if a client is registered as a // web application but requests the pin based workflow? For now I'm @@ -154,10 +154,7 @@ class ApiOauthRequestTokenAction extends ApiOauthAction return true; } else { - return Validate::uri( - $callback, - array('allowed_schemes' => array('http', 'https')) - ); + return Validate::uri($callback); } } diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index 4715f7002..822ebacbd 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -147,10 +147,8 @@ require_once INSTALLDIR . '/lib/mediafile.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiStatusesUpdateAction extends ApiAuthAction { - var $source = null; var $status = null; var $in_reply_to_status_id = null; var $lat = null; @@ -164,7 +162,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -188,7 +185,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -210,8 +206,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; @@ -219,6 +218,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction if (empty($this->status)) { $this->clientError( + // TRANS: Client error displayed when the parameter "status" is missing. _('Client must provide a \'status\' parameter with a value.'), 400, $this->format @@ -240,7 +240,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction $this->clientError( sprintf( - _('That\'s too long. Max notice size is %d chars.'), + // TRANS: Client error displayed when the parameter "status" is missing. + // TRANS: %d is the maximum number of character for a notice. + _m('That\'s too long. Maximum notice size is %d character.', + 'That\'s too long. Maximum notice size is %d characters.', + Notice::maxContent()), Notice::maxContent() ), 406, @@ -256,7 +260,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction $cmd = $inter->handle_command($this->auth_user, $status_shortened); if ($cmd) { - if ($this->supported($cmd)) { $cmd->execute(new Channel()); } @@ -266,13 +269,10 @@ class ApiStatusesUpdateAction extends ApiAuthAction // or not! $this->notice = $this->auth_user->getCurrentNotice(); - } else { - $reply_to = null; if (!empty($this->in_reply_to_status_id)) { - // Check whether notice actually exists $reply = Notice::staticGet($this->in_reply_to_status_id); @@ -281,7 +281,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction $reply_to = $this->in_reply_to_status_id; } else { $this->clientError( - _('Not found.'), + // TRANS: Client error displayed when replying to a non-existing notice. + _('Parent notice not found.'), $code = 404, $this->format ); @@ -303,10 +304,9 @@ class ApiStatusesUpdateAction extends ApiAuthAction if (Notice::contentTooLong($status_shortened)) { $upload->delete(); - $msg = _( - 'Max notice size is %d chars, ' . - 'including attachment URL.' - ); + $msg = _m('Maximum notice size is %d character, including attachment URL.', + 'Maximum notice size is %d characters, including attachment URL.', + Notice::maxContent()); $this->clientError( sprintf($msg, Notice::maxContent()), 400, @@ -345,7 +345,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction if (isset($upload)) { $upload->attachToNotice($this->notice); } - } $this->showNotice(); @@ -356,7 +355,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * * @return void */ - function showNotice() { if (!empty($this->notice)) { @@ -375,7 +373,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * * @return boolean true or false */ - function supported($cmd) { static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', @@ -387,5 +384,4 @@ class ApiStatusesUpdateAction extends ApiAuthAction return false; } - } diff --git a/actions/avatarsettings.php b/actions/avatarsettings.php index 52dc2e424..9d4040e75 100644 --- a/actions/avatarsettings.php +++ b/actions/avatarsettings.php @@ -254,9 +254,11 @@ class AvatarsettingsAction extends AccountSettingsAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); - + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } diff --git a/actions/deletegroup.php b/actions/deletegroup.php index acb309e1d..62fff00c4 100644 --- a/actions/deletegroup.php +++ b/actions/deletegroup.php @@ -45,7 +45,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @link http://status.net/ * @fixme merge more of this code with related variants */ - class DeletegroupAction extends RedirectingAction { var $group = null; @@ -56,12 +55,12 @@ class DeletegroupAction extends RedirectingAction * @fixme merge common setup code with other group actions * @fixme allow group admins to delete their own groups */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error when trying to delete group while not logged in. $this->clientError(_('You must be logged in to delete a group.')); return false; } @@ -84,23 +83,27 @@ class DeletegroupAction extends RedirectingAction $local = Local_group::staticGet('nickname', $nickname); if (!$local) { + // TRANS: Client error when trying to delete a non-local group. $this->clientError(_('No such group.'), 404); return false; } $this->group = User_group::staticGet('id', $local->group_id); } else { + // TRANS: Client error when trying to delete a group without providing a nickname or ID for the group. $this->clientError(_('No nickname or ID.'), 404); return false; } if (!$this->group) { + // TRANS: Client error when trying to delete a non-existing group. $this->clientError(_('No such group.'), 404); return false; } $cur = common_current_user(); if (!$cur->hasRight(Right::DELETEGROUP)) { + // TRANS: Client error when trying to delete a group without having the rights to delete it. $this->clientError(_('You are not allowed to delete this group.'), 403); return false; } @@ -117,7 +120,6 @@ class DeletegroupAction extends RedirectingAction * * @return void */ - function handle($args) { parent::handle($args); @@ -143,14 +145,18 @@ class DeletegroupAction extends RedirectingAction Event::handle('EndDeleteGroup', array($this->group)); } } catch (Exception $e) { - $this->serverError(sprintf(_('Could not delete group %2$s.'), + // TRANS: Server error displayed if a group could not be deleted. + // TRANS: %s is the name of the group that could not be deleted. + $this->serverError(sprintf(_('Could not delete group %s.'), $this->group->nickname)); } if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); - $this->element('title', null, sprintf(_('Deleted group %2$s'), + // TRANS: Message given after deleting a group. + // TRANS: %s is the deleted group's name. + $this->element('title', null, sprintf(_('Deleted group %s'), $this->group->nickname)); $this->elementEnd('head'); $this->elementStart('body'); @@ -166,6 +172,7 @@ class DeletegroupAction extends RedirectingAction } function title() { + // TRANS: Title. return _('Delete group'); } @@ -191,8 +198,10 @@ class DeletegroupAction extends RedirectingAction 'action' => common_local_url('deletegroup', array('id' => $this->group->id)))); $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); + // TRANS: Form legend for deleting a group. $this->element('legend', _('Delete group')); if (Event::handle('StartDeleteGroupForm', array($this, $this->group))) { + // TRANS: Warning in form for deleleting a group. $this->element('p', null, _('Are you sure you want to delete this group? '. 'This will clear all data about the group from the '. @@ -223,4 +232,4 @@ class DeletegroupAction extends RedirectingAction $this->elementEnd('fieldset'); $this->elementEnd('form'); } -}
\ No newline at end of file +} diff --git a/actions/designadminpanel.php b/actions/designadminpanel.php index 587333e06..321a8ee5e 100644 --- a/actions/designadminpanel.php +++ b/actions/designadminpanel.php @@ -120,8 +120,11 @@ class DesignadminpanelAction extends AdminPanelAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } @@ -258,8 +261,8 @@ class DesignadminpanelAction extends AdminPanelAction function saveBackgroundImage() { $filename = null; - - if ($_FILES['design_background-image_file']['error'] == + if (isset($_FILES['design_background-image_file']['error']) && + $_FILES['design_background-image_file']['error'] == UPLOAD_ERR_OK) { $filepath = null; diff --git a/actions/editapplication.php b/actions/editapplication.php index 477bcd6f0..d1c7a5c3d 100644 --- a/actions/editapplication.php +++ b/actions/editapplication.php @@ -42,7 +42,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class EditApplicationAction extends OwnerDesignAction { var $msg = null; @@ -51,18 +50,19 @@ class EditApplicationAction extends OwnerDesignAction function title() { - return _('Edit Application'); + // TRANS: Title for "Edit application" form. + return _('Edit application'); } /** * Prepare to run */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed trying to edit an application while not logged in. $this->clientError(_('You must be logged in to edit an application.')); return false; } @@ -74,10 +74,12 @@ class EditApplicationAction extends OwnerDesignAction $cur = common_current_user(); if ($cur->id != $this->owner->id) { + // TRANS: Client error displayed trying to edit an application while not being its owner. $this->clientError(_('You are not the owner of this application.'), 401); } if (!$this->app) { + // TRANS: Client error displayed trying to edit an application that does not exist. $this->clientError(_('No such application.')); return false; } @@ -94,7 +96,6 @@ class EditApplicationAction extends OwnerDesignAction * * @return void */ - function handle($args) { parent::handle($args); @@ -115,8 +116,11 @@ class EditApplicationAction extends OwnerDesignAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } @@ -136,6 +140,7 @@ class EditApplicationAction extends OwnerDesignAction } elseif ($this->arg('save')) { $this->trySave(); } else { + // TRANS: Client error displayed submitting invalid form data for edit application. $this->clientError(_('Unexpected form submission.')); } } @@ -158,6 +163,7 @@ class EditApplicationAction extends OwnerDesignAction $this->element('p', 'error', $this->msg); } else { $this->element('p', 'instructions', + // TRANS: Instructions for "Edit application" form. _('Use this form to edit your application.')); } } @@ -174,36 +180,47 @@ class EditApplicationAction extends OwnerDesignAction $access_type = $this->arg('default_access_type'); if (empty($name)) { + // TRANS: Validation error shown when not providing a name in the "Edit application" form. $this->showForm(_('Name is required.')); return; } elseif (mb_strlen($name) > 255) { - $this->showForm(_('Name is too long (max 255 chars).')); + // TRANS: Validation error shown when providing too long a name in the "Edit application" form. + $this->showForm(_('Name is too long (max 255 characters).')); return; } else if ($this->nameExists($name)) { + // TRANS: Validation error shown when providing a name for an application that already exists in the "Edit application" form. $this->showForm(_('Name already in use. Try another one.')); return; } elseif (empty($description)) { + // TRANS: Validation error shown when not providing a description in the "Edit application" form. $this->showForm(_('Description is required.')); return; } elseif (Oauth_application::descriptionTooLong($description)) { $this->showForm(sprintf( - _('Description is too long (max %d chars).'), + // TRANS: Validation error shown when providing too long a description in the "Edit application" form. + _m('Description is too long (maximum %d character).', + 'Description is too long (maximum %d characters).', + Oauth_application::maxDesc()), Oauth_application::maxDesc())); return; } elseif (mb_strlen($source_url) > 255) { + // TRANS: Validation error shown when providing too long a source URL in the "Edit application" form. $this->showForm(_('Source URL is too long.')); return; } elseif ((mb_strlen($source_url) > 0) && !Validate::uri($source_url, array('allowed_schemes' => array('http', 'https')))) { + // TRANS: Validation error shown when providing an invalid source URL in the "Edit application" form. $this->showForm(_('Source URL is not valid.')); return; } elseif (empty($organization)) { + // TRANS: Validation error shown when not providing an organisation in the "Edit application" form. $this->showForm(_('Organization is required.')); return; } elseif (mb_strlen($organization) > 255) { - $this->showForm(_('Organization is too long (max 255 chars).')); + // TRANS: Validation error shown when providing too long an arganisation name in the "Edit application" form. + $this->showForm(_('Organization is too long (maximum 255 characters).')); return; } elseif (empty($homepage)) { $this->showForm(_('Organization homepage is required.')); @@ -212,9 +229,11 @@ class EditApplicationAction extends OwnerDesignAction && !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { + // TRANS: Validation error shown when providing an invalid homepage URL in the "Edit application" form. $this->showForm(_('Homepage is not a valid URL.')); return; } elseif (mb_strlen($callback_url) > 255) { + // TRANS: Validation error shown when providing too long a callback URL in the "Edit application" form. $this->showForm(_('Callback is too long.')); return; } elseif (mb_strlen($callback_url) > 0 @@ -222,6 +241,7 @@ class EditApplicationAction extends OwnerDesignAction array('allowed_schemes' => array('http', 'https')) )) { + // TRANS: Validation error shown when providing an invalid callback URL in the "Edit application" form. $this->showForm(_('Callback URL is not valid.')); return; } @@ -258,6 +278,7 @@ class EditApplicationAction extends OwnerDesignAction // the next step. if ($result === false) { common_log_db_error($this->app, 'UPDATE', __FILE__); + // TRANS: Server error occuring when an application could not be updated from the "Edit application" form. $this->serverError(_('Could not update application.')); } @@ -276,7 +297,6 @@ class EditApplicationAction extends OwnerDesignAction * * @return boolean true if the name already exists */ - function nameExists($name) { $newapp = Oauth_application::staticGet('name', $name); @@ -286,6 +306,4 @@ class EditApplicationAction extends OwnerDesignAction return $newapp->id != $this->app->id; } } - } - diff --git a/actions/editgroup.php b/actions/editgroup.php index 4b596cade..eaadbabe4 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -199,13 +199,13 @@ class EditgroupAction extends GroupDesignAction $this->showForm(_('Homepage is not a valid URL.')); return; } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { - $this->showForm(_('Full name is too long (max 255 chars).')); + $this->showForm(_('Full name is too long (maximum 255 characters).')); return; } else if (User_group::descriptionTooLong($description)) { - $this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription())); + $this->showForm(sprintf(_('Description is too long (max %d chars).'), User_group::maxDescription())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { - $this->showForm(_('Location is too long (max 255 chars).')); + $this->showForm(_('Location is too long (maximum 255 characters).')); return; } diff --git a/actions/invite.php b/actions/invite.php index 4bba8893d..2779437e0 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -36,8 +36,11 @@ class InviteAction extends CurrentUserDesignAction { parent::handle($args); if (!common_config('invite', 'enabled')) { + // TRANS: Client error displayed when trying to sent invites while they have been disabled. $this->clientError(_('Invites have been disabled.')); } else if (!common_logged_in()) { + // TRANS: Client error displayed when trying to sent invites while not logged in. + // TRANS: %s is the StatusNet site name. $this->clientError(sprintf(_('You must be logged in to invite other users to use %s.'), common_config('site', 'name'))); return; @@ -69,7 +72,9 @@ class InviteAction extends CurrentUserDesignAction foreach ($addresses as $email) { $email = trim($email); if (!Validate::email($email, common_config('email', 'check_domain'))) { - $this->showForm(sprintf(_('Invalid email address: %s'), $email)); + // TRANS: Form validation message when providing an e-mail address that does not validate. + // TRANS: %s is an invalid e-mail address. + $this->showForm(sprintf(_('Invalid email address: %s.'), $email)); return; } } @@ -107,8 +112,10 @@ class InviteAction extends CurrentUserDesignAction function title() { if ($this->mode == 'sent') { - return _('Invitation(s) sent'); + // TRANS: Page title when invitations have been sent. + return _('Invitations sent'); } else { + // TRANS: Page title when inviting potential users. return _('Invite new users'); } } @@ -125,28 +132,48 @@ class InviteAction extends CurrentUserDesignAction function showInvitationSuccess() { if ($this->already) { - $this->element('p', null, _('You are already subscribed to these users:')); + // TRANS: Message displayed inviting users to use a StatusNet site while the inviting user + // TRANS: is already subscribed to one or more users with the given e-mail address(es). + // TRANS: Plural form is based on the number of reported already subscribed e-mail addresses. + // TRANS: Followed by a bullet list. + $this->element('p', null, _m('You are already subscribed to this user:', + 'You are already subscribed to these users:', + count($this->already))); $this->elementStart('ul'); foreach ($this->already as $other) { + // TRANS: Used as list item for already subscribed users (%1$s is nickname, %2$s is e-mail address). $this->element('li', null, sprintf(_('%1$s (%2$s)'), $other->nickname, $other->email)); } $this->elementEnd('ul'); } if ($this->subbed) { - $this->element('p', null, _('These people are already users and you were automatically subscribed to them:')); + // TRANS: Message displayed inviting users to use a StatusNet site while the invited user + // TRANS: already uses a this StatusNet site. Plural form is based on the number of + // TRANS: reported already present people. Followed by a bullet list. + $this->element('p', null, _m('This person is already a user and you were automatically subscribed:', + 'These people are already users and you were automatically subscribed to them:', + count($this->subbed))); $this->elementStart('ul'); foreach ($this->subbed as $other) { + // TRANS: Used as list item for already registered people (%1$s is nickname, %2$s is e-mail address). $this->element('li', null, sprintf(_('%1$s (%2$s)'), $other->nickname, $other->email)); } $this->elementEnd('ul'); } if ($this->sent) { - $this->element('p', null, _('Invitation(s) sent to the following people:')); + // TRANS: Message displayed inviting users to use a StatusNet site. Plural form is + // TRANS: based on the number of invitations sent. Followed by a bullet list of + // TRANS: e-mail addresses to which invitations were sent. + $this->element('p', null, _m('Invitation sent to the following person:', + 'Invitations sent to the following people:', + count($this->sent))); $this->elementStart('ul'); foreach ($this->sent as $other) { $this->element('li', null, $other); } $this->elementEnd('ul'); + // TRANS: Generic message displayed after sending out one or more invitations to + // TRANS: people to join a StatusNet site. $this->element('p', null, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!')); } } @@ -159,6 +186,7 @@ class InviteAction extends CurrentUserDesignAction } else { $this->elementStart('div', 'instructions'); $this->element('p', null, + // TRANS: Form instructions. _('Use this form to invite your friends and colleagues to use this service.')); $this->elementEnd('div'); } @@ -179,18 +207,23 @@ class InviteAction extends CurrentUserDesignAction 'class' => 'form_settings', 'action' => common_local_url('invite'))); $this->elementStart('fieldset'); + // TRANS: Form legend. $this->element('legend', null, 'Send an invitation'); $this->hidden('token', common_session_token()); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label for a list of e-mail addresses. $this->textarea('addresses', _('Email addresses'), $this->trimmed('addresses'), + // TRANS: Tooltip for field label for a list of e-mail addresses. _('Addresses of friends to invite (one per line)')); $this->elementEnd('li'); $this->elementStart('li'); + // TRANS: Field label for a personal message to send to invitees. $this->textarea('personal', _('Personal message'), $this->trimmed('personal'), + // TRANS: Tooltip for field label for a personal message to send to invitees. _('Optionally add a personal message to the invitation.')); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -224,10 +257,16 @@ class InviteAction extends CurrentUserDesignAction $headers['From'] = mail_notify_from(); $headers['To'] = trim($email); - // TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral singular 3rd-person pronoun in English. + // TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral + // TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, $2$s is + // TRANS: the StatusNet sitename. $headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename); - // TRANS: Body text for invitation email. Note that 'them' is correct as a gender-neutral singular 3rd-person pronoun in English. + // TRANS: Body text for invitation email. Note that 'them' is correct as a gender-neutral + // TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, %2$s is the + // TRANS: StatusNet sitename, %3$s is the site URL, %4$s is the personal message from the + // TRANS: inviting user, %s%5 a link to the timeline for the inviting user, %s$6 is a link + // TRANS: to register with the StatusNet site. $body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n". "%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n". "You can also share news about yourself, your thoughts, or your life online with people who know about you. ". diff --git a/actions/makeadmin.php b/actions/makeadmin.php index 9ccb44230..4e6e97a56 100644 --- a/actions/makeadmin.php +++ b/actions/makeadmin.php @@ -148,7 +148,7 @@ class MakeadminAction extends RedirectingAction $this->group->getBestName()); } - $this->returnToArgs(); + $this->returnToPrevious(); } /** diff --git a/actions/newapplication.php b/actions/newapplication.php index 8b150c315..033c0852d 100644 --- a/actions/newapplication.php +++ b/actions/newapplication.php @@ -42,14 +42,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class NewApplicationAction extends OwnerDesignAction { var $msg; function title() { - return _('New Application'); + // TRANS: This is the title of the form for adding a new application. + return _('New application'); } /** @@ -61,6 +61,7 @@ class NewApplicationAction extends OwnerDesignAction parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed trying to add a new application while not logged in. $this->clientError(_('You must be logged in to register an application.')); return false; } @@ -91,35 +92,38 @@ class NewApplicationAction extends OwnerDesignAction function handlePost($args) { - // Workaround for PHP returning empty $_POST and $_FILES when POST + // Workaround for PHP returning empty $_POST and $_FILES when POST // length > post_max_size in php.ini if (empty($_FILES) && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } - // CSRF protection - $token = $this->trimmed('token'); - if (!$token || $token != common_session_token()) { - $this->clientError(_('There was a problem with your session token.')); - return; - } + // CSRF protection + $token = $this->trimmed('token'); + if (!$token || $token != common_session_token()) { + $this->clientError(_('There was a problem with your session token.')); + return; + } - $cur = common_current_user(); + $cur = common_current_user(); - if ($this->arg('cancel')) { - common_redirect(common_local_url('oauthappssettings'), 303); - } elseif ($this->arg('save')) { - $this->trySave(); - } else { - $this->clientError(_('Unexpected form submission.')); - } + if ($this->arg('cancel')) { + common_redirect(common_local_url('oauthappssettings'), 303); + } elseif ($this->arg('save')) { + $this->trySave(); + } else { + $this->clientError(_('Unexpected form submission.')); + } } function showForm($msg=null) @@ -162,14 +166,18 @@ class NewApplicationAction extends OwnerDesignAction $this->showForm(_('Name already in use. Try another one.')); return; } elseif (mb_strlen($name) > 255) { - $this->showForm(_('Name is too long (max 255 chars).')); + $this->showForm(_('Name is too long (maximum 255 chars).')); return; } elseif (empty($description)) { $this->showForm(_('Description is required.')); return; } elseif (Oauth_application::descriptionTooLong($description)) { $this->showForm(sprintf( - _('Description is too long (max %d chars).'), + // TRANS: Form validation error in New application form. + // TRANS: %d is the maximum number of characters for the description. + _m('Description is too long (maximum %d character).', + 'Description is too long (maximum %d characters).', + Oauth_application::maxDesc()), Oauth_application::maxDesc())); return; } elseif (empty($source_url)) { @@ -188,7 +196,7 @@ class NewApplicationAction extends OwnerDesignAction $this->showForm(_('Organization is required.')); return; } elseif (mb_strlen($organization) > 255) { - $this->showForm(_('Organization is too long (max 255 chars).')); + $this->showForm(_('Organization is too long (maximum 255 chars).')); return; } elseif (empty($homepage)) { $this->showForm(_('Organization homepage is required.')); diff --git a/actions/newgroup.php b/actions/newgroup.php index 75bc293ec..ebfe9b599 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -139,13 +139,13 @@ class NewgroupAction extends Action $this->showForm(_('Homepage is not a valid URL.')); return; } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { - $this->showForm(_('Full name is too long (max 255 chars).')); + $this->showForm(_('Full name is too long (maximum 255 characters).')); return; } else if (User_group::descriptionTooLong($description)) { $this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { - $this->showForm(_('Location is too long (max 255 chars).')); + $this->showForm(_('Location is too long (maximum 255 characters).')); return; } diff --git a/actions/newmessage.php b/actions/newmessage.php index 25e58feab..c58ed3849 100644 --- a/actions/newmessage.php +++ b/actions/newmessage.php @@ -147,8 +147,11 @@ class NewmessageAction extends Action $content_shortened = common_shorten_links($this->content); if (Message::contentTooLong($content_shortened)) { - $this->showForm(sprintf(_('That\'s too long. ' . - 'Max message size is %d chars.'), + // TRANS: Form validation error displayed when message content is too long. + // TRANS: %d is the maximum number of characters for a message. + $this->showForm(sprintf(_m('That\'s too long. Maximum message size is %d character.', + 'That\'s too long. Maximum message size is %d characters.', + Message::maxContent()), Message::maxContent())); return; } diff --git a/actions/newnotice.php b/actions/newnotice.php index ea832cf4e..57cd847c6 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -82,7 +82,6 @@ class NewnoticeAction extends Action * * @return void */ - function handle($args) { if (!common_logged_in()) { @@ -91,9 +90,12 @@ class NewnoticeAction extends Action // check for this before token since all POST and FILES data // is losts when size is exceeded if (empty($_POST) && $_SERVER['CONTENT_LENGTH']) { - $this->clientError(sprintf(_('The server was unable to handle ' . - 'that much POST data (%s bytes) due to its current configuration.'), - $_SERVER['CONTENT_LENGTH'])); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); + $this->clientError(sprintf($msg,$_SERVER['CONTENT_LENGTH'])); } parent::handle($args); @@ -352,4 +354,3 @@ class NewnoticeAction extends Action $nli->show(); } } - diff --git a/actions/nudge.php b/actions/nudge.php index 32ae8587c..219a8c9ab 100644 --- a/actions/nudge.php +++ b/actions/nudge.php @@ -82,7 +82,7 @@ class NudgeAction extends Action } if (!$other->email || !$other->emailnotifynudge) { - $this->clientError(_('This user doesn\'t allow nudges or hasn\'t confirmed or set their email yet.')); + $this->clientError(_('This user doesn\'t allow nudges or hasn\'t confirmed or set their email address yet.')); return; } diff --git a/actions/oauthappssettings.php b/actions/oauthappssettings.php index 6c0670b17..c98c90dbf 100644 --- a/actions/oauthappssettings.php +++ b/actions/oauthappssettings.php @@ -56,6 +56,7 @@ class OauthappssettingsAction extends SettingsAction $this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1; if (!common_logged_in()) { + // TRANS: Message displayed to an anonymous user trying to view OAuth application list. $this->clientError(_('You must be logged in to list your applications.')); return false; } @@ -71,6 +72,7 @@ class OauthappssettingsAction extends SettingsAction function title() { + // TRANS: Page title for OAuth applications return _('OAuth applications'); } @@ -82,6 +84,7 @@ class OauthappssettingsAction extends SettingsAction function getInstructions() { + // TRANS: Page instructions for OAuth applications return _('Applications you have registered'); } @@ -100,6 +103,7 @@ class OauthappssettingsAction extends SettingsAction $application = new Oauth_application(); $application->owner = $user->id; + $application->whereAdd("name != 'anonymous'"); $application->limit($offset, $limit); $application->orderBy('created DESC'); $application->find(); @@ -119,6 +123,7 @@ class OauthappssettingsAction extends SettingsAction array('href' => common_local_url('newapplication'), 'class' => 'more' ), + // TRANS: Link description to add a new OAuth application. 'Register a new application'); $this->elementEnd('p'); @@ -132,6 +137,7 @@ class OauthappssettingsAction extends SettingsAction function showEmptyListMessage() { + // TRANS: Empty list message on page with OAuth applications. $message = sprintf(_('You have not registered any applications yet.')); $this->elementStart('div', 'guide'); @@ -162,5 +168,4 @@ class OauthappssettingsAction extends SettingsAction } } - } diff --git a/actions/oauthconnectionssettings.php b/actions/oauthconnectionssettings.php index 1fa70662f..9a7cda924 100644 --- a/actions/oauthconnectionssettings.php +++ b/actions/oauthconnectionssettings.php @@ -22,7 +22,7 @@ * @category Settings * @package StatusNet * @author Zach Copley <zach@status.net> - * @copyright 2008-2009 StatusNet, Inc. + * @copyright 2008-2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ @@ -46,17 +46,15 @@ require_once INSTALLDIR . '/lib/apioauthstore.php'; * * @see SettingsAction */ - class OauthconnectionssettingsAction extends ConnectSettingsAction { - - var $page = null; - var $id = null; + var $page = null; + var $oauth_token = null; function prepare($args) { parent::prepare($args); - $this->id = (int)$this->arg('id'); + $this->oauth_token = $this->arg('oauth_token'); $this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1; return true; } @@ -69,6 +67,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function title() { + // TRANS: Title for OAuth connection settings. return _('Connected applications'); } @@ -80,7 +79,8 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function getInstructions() { - return _('You have allowed the following applications to access your account.'); + // TRANS: Instructions for OAuth connection settings. + return _('The following connections exist for your account.'); } /** @@ -97,22 +97,26 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction $offset = ($this->page - 1) * APPS_PER_PAGE; $limit = APPS_PER_PAGE + 1; - $application = $profile->getApplications($offset, $limit); + $connection = $profile->getConnectedApps($offset, $limit); $cnt = 0; - if (!empty($application)) { - $al = new ApplicationList($application, $user, $this, true); - $cnt = $al->show(); + if (!empty($connection)) { + $cal = new ConnectedAppsList($connection, $user, $this); + $cnt = $cal->show(); } if ($cnt == 0) { $this->showEmptyListMessage(); } - $this->pagination($this->page > 1, $cnt > APPS_PER_PAGE, - $this->page, 'connectionssettings', - array('nickname' => $user->nickname)); + $this->pagination( + $this->page > 1, + $cnt > APPS_PER_PAGE, + $this->page, + 'connectionssettings', + array('nickname' => $user->nickname) + ); } /** @@ -125,7 +129,6 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction * * @return void */ - function handlePost() { // CSRF protection @@ -138,44 +141,36 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction } if ($this->arg('revoke')) { - $this->revokeAccess($this->id); - - // XXX: Show some indicator to the user of what's been done. - - $this->showPage(); + $this->revokeAccess($this->oauth_token); } else { + // TRANS: Client error when submitting a form with unexpected information. $this->clientError(_('Unexpected form submission.'), 401); return false; } } /** - * Revoke access to an authorized OAuth application + * Revoke an access token + * + * XXX: Confirm revoke before doing it * * @param int $appId the ID of the application * */ - - function revokeAccess($appId) + function revokeAccess($token) { $cur = common_current_user(); - $app = Oauth_application::staticGet('id', $appId); - - if (empty($app)) { - $this->clientError(_('No such application.'), 404); - return false; - } - - // XXX: Transaction here? - - $appUser = Oauth_application_user::getByKeys($cur, $app); + $appUser = Oauth_application_user::getByUserAndToken($cur, $token); if (empty($appUser)) { + // TRANS: Client error when trying to revoke access for an application while not being a user of it. $this->clientError(_('You are not a user of that application.'), 401); return false; } + $app = Oauth_application::staticGet('id', $appUser->application_id); + $datastore = new ApiStatusNetOAuthDataStore(); $datastore->revoke_token($appUser->token, 1); @@ -183,18 +178,38 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction if (!$result) { common_log_db_error($orig, 'DELETE', __FILE__); - $this->clientError(sprintf(_('Unable to revoke access for app: %s.'), $app->id)); + // TRANS: Client error when revoking access has failed for some reason. + // TRANS: %s is the application ID revoking access failed for. + $this->clientError(sprintf(_('Unable to revoke access for application: %s.'), $app->id)); return false; } - $msg = 'User %s (id: %d) revoked access to app %s (id: %d)'; - common_log(LOG_INFO, sprintf($msg, $cur->nickname, - $cur->id, $app->name, $app->id)); - + $msg = 'API OAuth - user %s (id: %d) revoked access token %s for app id %d'; + common_log( + LOG_INFO, + sprintf( + $msg, + $cur->nickname, + $cur->id, + $appUser->token, + $appUser->application_id + ) + ); + + $msg = sprintf( + // TRANS: Success message after revoking access for an application. + // TRANS: %1$s is the application name, %2$s is the first part of the user token. + _('You have successfully revoked access for %1$s and the access token starting with %2$s.'), + $app->name, + substr($appUser->token, 0, 7) + ); + + $this->showForm($msg, true); } function showEmptyListMessage() { + // TRANS: Empty list message when no applications have been authorised yet. $message = _('You have not authorized any applications to use your account.'); $this->elementStart('div', 'guide'); @@ -204,15 +219,26 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function showSections() { - $cur = common_current_user(); - - $this->element('h2', null, 'Developers'); - $this->elementStart('p'); - $this->raw(_('Developers can edit the registration settings for their applications ')); - $this->element('a', - array('href' => common_local_url('oauthappssettings')), - 'here.'); - $this->elementEnd('p'); - } + $cur = common_current_user(); + + $this->elementStart('div', array('id' => 'developer-help', 'class' => 'section')); + $this->element('h2', null, 'Developers'); + $this->elementStart('p'); + + $devMsg = sprintf( + // TRANS: Note for developers in the OAuth connection settings form. + // TRANS: This message contains a Markdown link. Do not separate "](". + // TRANS: %s is the URL to the OAuth settings. + _('Are you a developer? [Register an OAuth client application](%s) to use with this instance of StatusNet.'), + common_local_url('oauthappssettings') + ); + + $output = common_markup_to_html($devMsg); + + $this->raw($output); + $this->elementEnd('p'); + + $this->elementEnd('section'); + } } diff --git a/actions/pathsadminpanel.php b/actions/pathsadminpanel.php index e073b0a2a..dd65a7a13 100644 --- a/actions/pathsadminpanel.php +++ b/actions/pathsadminpanel.php @@ -44,10 +44,8 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class PathsadminpanelAction extends AdminPanelAction { - /** * Returns the page title * @@ -56,6 +54,7 @@ class PathsadminpanelAction extends AdminPanelAction function title() { + // TRANS: Title for Paths admin panel. return _('Paths'); } @@ -64,9 +63,9 @@ class PathsadminpanelAction extends AdminPanelAction * * @return string instructions */ - function getInstructions() { + // TRANS: Form instructions for Path admin panel. return _('Path and server settings for this StatusNet site'); } @@ -75,7 +74,6 @@ class PathsadminpanelAction extends AdminPanelAction * * @return void */ - function showForm() { $form = new PathsAdminPanelForm($this); @@ -88,7 +86,6 @@ class PathsadminpanelAction extends AdminPanelAction * * @return void */ - function saveSettings() { static $settings = array( @@ -148,25 +145,29 @@ class PathsadminpanelAction extends AdminPanelAction * * @return void */ - function validate(&$values) { - // Validate theme dir if (!empty($values['theme']['dir']) && !is_readable($values['theme']['dir'])) { + // TRANS: Client error in Paths admin panel. + // TRANS: %s is the directory that could not be read from. $this->clientError(sprintf(_("Theme directory not readable: %s."), $values['theme']['dir'])); } // Validate avatar dir if (empty($values['avatar']['dir']) || !is_writable($values['avatar']['dir'])) { + // TRANS: Client error in Paths admin panel. + // TRANS: %s is the avatar directory that could not be written to. $this->clientError(sprintf(_("Avatar directory not writable: %s."), $values['avatar']['dir'])); } // Validate background dir if (empty($values['background']['dir']) || !is_writable($values['background']['dir'])) { + // TRANS: Client error in Paths admin panel. + // TRANS: %s is the background directory that could not be written to. $this->clientError(sprintf(_("Background directory not writable: %s."), $values['background']['dir'])); } @@ -175,27 +176,28 @@ class PathsadminpanelAction extends AdminPanelAction // XXX: What else do we need to validate for lacales path here? --Z if (!empty($values['site']['locale_path']) && !is_readable($values['site']['locale_path'])) { + // TRANS: Client error in Paths admin panel. + // TRANS: %s is the locales directory that could not be read from. $this->clientError(sprintf(_("Locales directory not readable: %s."), $values['site']['locale_path'])); } // Validate SSL setup if (mb_strlen($values['site']['sslserver']) > 255) { + // TRANS: Client error in Paths admin panel. + // TRANS: %s is the SSL server URL that is too long. $this->clientError(_('Invalid SSL server. The maximum length is 255 characters.')); } } - } class PathsAdminPanelForm extends AdminForm { - /** * ID of the form * * @return int ID of the form */ - function id() { return 'form_paths_admin_panel'; @@ -206,7 +208,6 @@ class PathsAdminPanelForm extends AdminForm * * @return string class of the form */ - function formClass() { return 'form_settings'; @@ -217,7 +218,6 @@ class PathsAdminPanelForm extends AdminForm * * @return string URL of the action */ - function action() { return common_local_url('pathsadminpanel'); @@ -228,27 +228,39 @@ class PathsAdminPanelForm extends AdminForm * * @return void */ - function formData() { $this->out->elementStart('fieldset', array('id' => 'settings_paths_locale')); + // TRANS: Fieldset legend in Paths admin panel. $this->out->element('legend', null, _('Site'), 'site'); $this->out->elementStart('ul', 'form_data'); $this->li(); - $this->input('server', _('Server'), _('Site\'s server hostname.')); + $this->input('server', + // TRANS: Field label in Paths admin panel. + _('Server'), + _('Site\'s server hostname.')); $this->unli(); $this->li(); - $this->input('path', _('Path'), _('Site path')); + $this->input('path', + // TRANS: Field label in Paths admin panel. + _('Path'), + _('Site path.')); $this->unli(); $this->li(); - $this->input('locale_path', _('Locale Directory'), _('Directory path to locales'), 'site'); + $this->input('locale_path', + // TRANS: Field label in Paths admin panel. + _('Locale directory'), + _('Directory path to locales.'), + 'site'); $this->unli(); $this->li(); - $this->out->checkbox('fancy', _('Fancy URLs'), + $this->out->checkbox('fancy', + // TRANS: Checkbox label in Paths admin panel. + _('Fancy URLs'), (bool) $this->value('fancy'), _('Use fancy (more readable and memorable) URLs?')); $this->unli(); @@ -262,43 +274,84 @@ class PathsAdminPanelForm extends AdminForm $this->out->elementStart('ul', 'form_data'); $this->li(); - $this->input('server', _('Server'), _('Server for themes'), 'theme'); + $this->input('server', + // TRANS: Field label in Paths admin panel. + _('Server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server for themes.'), + 'theme'); $this->unli(); $this->li(); - $this->input('path', _('Path'), _('Web path to themes'), 'theme'); + $this->input('path', + // TRANS: Field label in Paths admin panel. + _('Path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Web path to themes.'), + 'theme'); $this->unli(); $this->li(); - $this->input('sslserver', _('SSL server'), _('SSL server for themes (default: SSL server)'), 'theme'); + $this->input('sslserver', + // TRANS: Field label in Paths admin panel. + _('SSL server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('SSL server for themes (default: SSL server).'), + 'theme'); $this->unli(); $this->li(); - $this->input('sslpath', _('SSL path'), _('SSL path to themes (default: /theme/)'), 'theme'); + $this->input('sslpath', + // TRANS: Field label in Paths admin panel. + _('SSL path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('SSL path to themes (default: /theme/).'), + 'theme'); $this->unli(); $this->li(); - $this->input('dir', _('Directory'), _('Directory where themes are located'), 'theme'); + $this->input('dir', + // TRANS: Field label in Paths admin panel. + _('Directory'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Directory where themes are located.'), + 'theme'); $this->unli(); $this->out->elementEnd('ul'); $this->out->elementEnd('fieldset'); $this->out->elementStart('fieldset', array('id' => 'settings_avatar-paths')); + // TRANS: Fieldset legend in Paths admin panel. $this->out->element('legend', null, _('Avatars')); $this->out->elementStart('ul', 'form_data'); $this->li(); - $this->input('server', _('Avatar server'), 'Server for avatars', 'avatar'); + $this->input('server', + // TRANS: Field label in Paths admin panel. + _('Avatar server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server for avatars.'), + 'avatar'); $this->unli(); $this->li(); - $this->input('path', _('Avatar path'), 'Web path to avatars', 'avatar'); + $this->input('path', + // TRANS: Field label in Paths admin panel. + _('Avatar path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Web path to avatars.'), + 'avatar'); $this->unli(); $this->li(); - $this->input('dir', _('Avatar directory'), 'Directory where avatars are located', 'avatar'); + $this->input('dir', + // TRANS: Field label in Paths admin panel. + _('Avatar directory'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Directory where avatars are located.'), + 'avatar'); $this->unli(); $this->out->elementEnd('ul'); @@ -307,27 +360,53 @@ class PathsAdminPanelForm extends AdminForm $this->out->elementStart('fieldset', array('id' => 'settings_design_background-paths')); + // TRANS: Fieldset legend in Paths admin panel. $this->out->element('legend', null, _('Backgrounds')); $this->out->elementStart('ul', 'form_data'); $this->li(); - $this->input('server', _('Server'), 'Server for backgrounds', 'background'); + $this->input('server', + // TRANS: Field label in Paths admin panel. + _('Server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server for backgrounds.'), + 'background'); $this->unli(); $this->li(); - $this->input('path', _('Path'), 'Web path to backgrounds', 'background'); + $this->input('path', + // TRANS: Field label in Paths admin panel. + _('Path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Web path to backgrounds.'), + 'background'); $this->unli(); $this->li(); - $this->input('sslserver', _('SSL server'), 'Server for backgrounds on SSL pages', 'background'); + $this->input('sslserver', + // TRANS: Field label in Paths admin panel. + _('SSL server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server for backgrounds on SSL pages.'), + 'background'); $this->unli(); $this->li(); - $this->input('sslpath', _('SSL path'), 'Web path to backgrounds on SSL pages', 'background'); + $this->input('sslpath', + // TRANS: Field label in Paths admin panel. + _('SSL path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Web path to backgrounds on SSL pages.'), + 'background'); $this->unli(); $this->li(); - $this->input('dir', _('Directory'), 'Directory where backgrounds are located', 'background'); + $this->input('dir', + // TRANS: Field label in Paths admin panel. + _('Directory'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Directory where backgrounds are located.'), + 'background'); $this->unli(); $this->out->elementEnd('ul'); @@ -336,53 +415,90 @@ class PathsAdminPanelForm extends AdminForm $this->out->elementStart('fieldset', array('id' => 'settings_design_attachments-paths')); + // TRANS: Fieldset legens in Paths admin panel. $this->out->element('legend', null, _('Attachments')); $this->out->elementStart('ul', 'form_data'); $this->li(); - $this->input('server', _('Server'), 'Server for attachments', 'attachments'); + $this->input('server', + // TRANS: Field label in Paths admin panel. + _('Server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server for attachments.'), + 'attachments'); $this->unli(); $this->li(); - $this->input('path', _('Path'), 'Web path to attachments', 'attachments'); + $this->input('path', + // TRANS: Field label in Paths admin panel. + _('Path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Web path to attachments.'), + 'attachments'); $this->unli(); $this->li(); - $this->input('sslserver', _('SSL server'), 'Server for attachments on SSL pages', 'attachments'); + $this->input('sslserver', + // TRANS: Field label in Paths admin panel. + _('SSL server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server for attachments on SSL pages.'), + 'attachments'); $this->unli(); $this->li(); - $this->input('sslpath', _('SSL path'), 'Web path to attachments on SSL pages', 'attachments'); + $this->input('sslpath', + // TRANS: Field label in Paths admin panel. + _('SSL path'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Web path to attachments on SSL pages.'), + 'attachments'); $this->unli(); $this->li(); - $this->input('dir', _('Directory'), 'Directory where attachments are located', 'attachments'); + $this->input('dir', + // TRANS: Field label in Paths admin panel. + _('Directory'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Directory where attachments are located.'), + 'attachments'); $this->unli(); $this->out->elementEnd('ul'); $this->out->elementEnd('fieldset'); $this->out->elementStart('fieldset', array('id' => 'settings_admin_ssl')); + // TRANS: Fieldset legend in Paths admin panel. $this->out->element('legend', null, _('SSL')); $this->out->elementStart('ul', 'form_data'); $this->li(); + // TRANS: Drop down option in Paths admin panel (option for "When to use SSL"). $ssl = array('never' => _('Never'), + // TRANS: Drop down option in Paths admin panel (option for "When to use SSL"). 'sometimes' => _('Sometimes'), + // TRANS: Drop down option in Paths admin panel (option for "When to use SSL"). 'always' => _('Always')); - $this->out->dropdown('site-ssl', _('Use SSL'), - $ssl, _('When to use SSL'), - false, $this->value('ssl', 'site')); + // TRANS: Drop down label in Paths admin panel. + $this->out->dropdown('site-ssl', + _('Use SSL'), + // TRANS: Tooltip for field label in Paths admin panel. + $ssl, _('When to use SSL.'), + false, + $this->value('ssl', 'site')); $this->unli(); $this->li(); - $this->input('sslserver', _('SSL server'), - _('Server to direct SSL requests to'), 'site'); + $this->input('sslserver', + // TRANS: Field label in Paths admin panel. + _('SSL server'), + // TRANS: Tooltip for field label in Paths admin panel. + _('Server to direct SSL requests to.'), + 'site'); $this->unli(); $this->out->elementEnd('ul'); $this->out->elementEnd('fieldset'); - } /** @@ -390,10 +506,11 @@ class PathsAdminPanelForm extends AdminForm * * @return void */ - function formActions() { - $this->out->submit('save', _('Save'), 'submit', + // TRANS: Button text to store form data in the Paths admin panel. + $this->out->submit('save', _m('BUTTON','Save'), 'submit', + // TRANS: Button title text to store form data in the Paths admin panel. 'save', _('Save paths')); } @@ -410,7 +527,6 @@ class PathsAdminPanelForm extends AdminForm * * @return void */ - function input($setting, $title, $instructions, $section='site') { $this->out->input("$section-$setting", $title, $this->value($setting, $section), $instructions); diff --git a/actions/profilesettings.php b/actions/profilesettings.php index 161e35b11..e1a0f8b6d 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -57,6 +57,7 @@ class ProfilesettingsAction extends AccountSettingsAction function title() { + // TRANS: Page title for profile settings. return _('Profile settings'); } @@ -68,6 +69,7 @@ class ProfilesettingsAction extends AccountSettingsAction function getInstructions() { + // TRANS: Usage instructions for profile settings. return _('You can update your personal profile info here '. 'so people know more about you.'); } @@ -96,6 +98,7 @@ class ProfilesettingsAction extends AccountSettingsAction 'class' => 'form_settings', 'action' => common_local_url('profilesettings'))); $this->elementStart('fieldset'); + // TRANS: Profile settings form legend. $this->element('legend', null, _('Profile information')); $this->hidden('token', common_session_token()); @@ -103,38 +106,54 @@ class ProfilesettingsAction extends AccountSettingsAction $this->elementStart('ul', 'form_data'); if (Event::handle('StartProfileFormData', array($this))) { $this->elementStart('li'); + // TRANS: Field label in form for profile settings. $this->input('nickname', _('Nickname'), ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname, - _('1-64 lowercase letters or numbers, no punctuation or spaces')); + // TRANS: Tooltip for field label in form for profile settings. + _('1-64 lowercase letters or numbers, no punctuation or spaces.')); $this->elementEnd('li'); $this->elementStart('li'); + // TRANS: Field label in form for profile settings. $this->input('fullname', _('Full name'), ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname); $this->elementEnd('li'); $this->elementStart('li'); + // TRANS: Field label in form for profile settings. $this->input('homepage', _('Homepage'), ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage, - _('URL of your homepage, blog, or profile on another site')); + // TRANS: Tooltip for field label in form for profile settings. + _('URL of your homepage, blog, or profile on another site.')); $this->elementEnd('li'); $this->elementStart('li'); $maxBio = Profile::maxBio(); if ($maxBio > 0) { - $bioInstr = sprintf(_('Describe yourself and your interests in %d chars'), + // TRANS: Tooltip for field label in form for profile settings. Plural + // TRANS: is decided by the number of characters available for the + // TRANS: biography (%d). + $bioInstr = sprintf(_m('Describe yourself and your interests in %d character', + 'Describe yourself and your interests in %d characters', + $maxBio), $maxBio); } else { + // TRANS: Tooltip for field label in form for profile settings. $bioInstr = _('Describe yourself and your interests'); } + // TRANS: Text area label in form for profile settings where users can provide. + // TRANS: their biography. $this->textarea('bio', _('Bio'), ($this->arg('bio')) ? $this->arg('bio') : $profile->bio, $bioInstr); $this->elementEnd('li'); $this->elementStart('li'); + // TRANS: Field label in form for profile settings. $this->input('location', _('Location'), ($this->arg('location')) ? $this->arg('location') : $profile->location, + // TRANS: Tooltip for field label in form for profile settings. _('Where you are, like "City, State (or Region), Country"')); $this->elementEnd('li'); if (common_config('location', 'share') == 'user') { $this->elementStart('li'); + // TRANS: Checkbox label in form for profile settings. $this->checkbox('sharelocation', _('Share my current location when posting notices'), ($this->arg('sharelocation')) ? $this->arg('sharelocation') : $user->shareLocation()); @@ -142,13 +161,17 @@ class ProfilesettingsAction extends AccountSettingsAction } Event::handle('EndProfileFormData', array($this)); $this->elementStart('li'); + // TRANS: Field label in form for profile settings. $this->input('tags', _('Tags'), ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()), + // TRANS: Tooltip for field label in form for profile settings. _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated')); $this->elementEnd('li'); $this->elementStart('li'); $language = common_language(); + // TRANS: Dropdownlist label in form for profile settings. $this->dropdown('language', _('Language'), + // TRANS: Tooltip for dropdown list label in form for profile settings. get_nice_language_list(), _('Preferred language'), false, $language); $this->elementEnd('li'); @@ -158,12 +181,15 @@ class ProfilesettingsAction extends AccountSettingsAction $timezones[$v] = $v; } $this->elementStart('li'); + // TRANS: Dropdownlist label in form for profile settings. $this->dropdown('timezone', _('Timezone'), + // TRANS: Tooltip for dropdown list label in form for profile settings. $timezones, _('What timezone are you normally in?'), true, $timezone); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('autosubscribe', + // TRANS: Checkbox label in form for profile settings. _('Automatically subscribe to whoever '. 'subscribes to me (best for non-humans)'), ($this->arg('autosubscribe')) ? @@ -171,7 +197,8 @@ class ProfilesettingsAction extends AccountSettingsAction $this->elementEnd('li'); } $this->elementEnd('ul'); - $this->submit('save', _('Save')); + // TRANS: Button to save input in profile settings. + $this->submit('save', _m('BUTTON','Save')); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -212,33 +239,46 @@ class ProfilesettingsAction extends AccountSettingsAction if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => NICKNAME_FMT))) { + // TRANS: Validation error in form for profile settings. $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); return; } else if (!User::allowed_nickname($nickname)) { + // TRANS: Validation error in form for profile settings. $this->showForm(_('Not a valid nickname.')); return; } else if (!is_null($homepage) && (strlen($homepage) > 0) && !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { + // TRANS: Validation error in form for profile settings. $this->showForm(_('Homepage is not a valid URL.')); return; } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { - $this->showForm(_('Full name is too long (max 255 chars).')); + // TRANS: Validation error in form for profile settings. + $this->showForm(_('Full name is too long (maximum 255 characters).')); return; } else if (Profile::bioTooLong($bio)) { - $this->showForm(sprintf(_('Bio is too long (max %d chars).'), + // TRANS: Validation error in form for profile settings. + // TRANS: Plural form is used based on the maximum number of allowed + // TRANS: characters for the biography (%d). + $this->showForm(sprintf(_m('Bio is too long (maximum %d character).', + 'Bio is too long (maximum %d characters).', + Profile::maxBio()), Profile::maxBio())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { - $this->showForm(_('Location is too long (max 255 chars).')); + // TRANS: Validation error in form for profile settings. + $this->showForm(_('Location is too long (maximum 255 characters).')); return; } else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) { + // TRANS: Validation error in form for profile settings. $this->showForm(_('Timezone not selected.')); return; } else if ($this->nicknameExists($nickname)) { + // TRANS: Validation error in form for profile settings. $this->showForm(_('Nickname already in use. Try another one.')); return; } else if (!is_null($language) && strlen($language) > 50) { - $this->showForm(_('Language is too long (max 50 chars).')); + // TRANS: Validation error in form for profile settings. + $this->showForm(_('Language is too long (maximum 50 characters).')); return; } @@ -250,6 +290,8 @@ class ProfilesettingsAction extends AccountSettingsAction foreach ($tags as $tag) { if (!common_valid_profile_tag($tag)) { + // TRANS: Validation error in form for profile settings. + // TRANS: %s is an invalid tag. $this->showForm(sprintf(_('Invalid tag: "%s"'), $tag)); return; } @@ -280,6 +322,7 @@ class ProfilesettingsAction extends AccountSettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown when user profile settings could not be updated. $this->serverError(_('Couldn\'t update user.')); return; } else { @@ -303,6 +346,8 @@ class ProfilesettingsAction extends AccountSettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown when user profile settings could not be updated to + // TRANS: automatically subscribe to any subscriber. $this->serverError(_('Couldn\'t update user for autosubscribe.')); return; } @@ -360,6 +405,7 @@ class ProfilesettingsAction extends AccountSettingsAction if ($result === false) { common_log_db_error($prefs, ($exists) ? 'UPDATE' : 'INSERT', __FILE__); + // TRANS: Server error thrown when user profile location preference settings could not be updated. $this->serverError(_('Couldn\'t save location prefs.')); return; } @@ -372,6 +418,7 @@ class ProfilesettingsAction extends AccountSettingsAction if ($result === false) { common_log_db_error($profile, 'UPDATE', __FILE__); + // TRANS: Server error thrown when user profile settings could not be saved. $this->serverError(_('Couldn\'t save profile.')); return; } @@ -380,6 +427,7 @@ class ProfilesettingsAction extends AccountSettingsAction $result = $user->setSelfTags($tags); if (!$result) { + // TRANS: Server error thrown when user profile settings tags could not be saved. $this->serverError(_('Couldn\'t save tags.')); return; } @@ -388,6 +436,7 @@ class ProfilesettingsAction extends AccountSettingsAction Event::handle('EndProfileSaveForm', array($this)); common_broadcast_profile($profile); + // TRANS: Confirmation shown when user profile settings are saved. $this->showForm(_('Settings saved.'), true); } diff --git a/actions/publictagcloud.php b/actions/publictagcloud.php index 70c356659..57821d428 100644 --- a/actions/publictagcloud.php +++ b/actions/publictagcloud.php @@ -44,7 +44,6 @@ define('TAGS_PER_PAGE', 100); * @copyright 2008-2009 StatusNet, Inc. * @link http://status.net/ */ - class PublictagcloudAction extends Action { function isReadOnly($args) @@ -54,24 +53,37 @@ class PublictagcloudAction extends Action function title() { + // TRANS: Title for public tag cloud. return _('Public tag cloud'); } function showPageNotice() { $this->element('p', 'instructions', - sprintf(_('These are most popular recent tags on %s '), + // TRANS: Instructions (more used like an explanation/header). + // TRANS: %s is the StatusNet sitename. + sprintf(_('These are most popular recent tags on %s'), common_config('site', 'name'))); } function showEmptyList() { + // TRANS: This message contains a Markdown URL. The link description is between + // TRANS: square brackets, and the link between parentheses. Do not separate "](" + // TRANS: and do not change the URL part. $message = _('No one has posted a notice with a [hashtag](%%doc.tags%%) yet.') . ' '; if (common_logged_in()) { + // TRANS: Message shown to a logged in user for the public tag cloud + // TRANS: while no tags exist yet. "One" refers to the non-existing hashtag. $message .= _('Be the first to post one!'); } else { + // TRANS: Message shown to a anonymous user for the public tag cloud + // TRANS: while no tags exist yet. "One" refers to the non-existing hashtag. + // TRANS: This message contains a Markdown URL. The link description is between + // TRANS: square brackets, and the link between parentheses. Do not separate "](" + // TRANS: and do not change the URL part. $message .= _('Why not [register an account](%%action.register%%) and be the first to post one!'); } diff --git a/actions/register.php b/actions/register.php index 7307bc689..3ae3f56f6 100644 --- a/actions/register.php +++ b/actions/register.php @@ -224,14 +224,16 @@ class RegisterAction extends Action $this->showForm(_('Homepage is not a valid URL.')); return; } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { - $this->showForm(_('Full name is too long (max 255 chars).')); + $this->showForm(_('Full name is too long (maximum 255 characters).')); return; } else if (Profile::bioTooLong($bio)) { - $this->showForm(sprintf(_('Bio is too long (max %d chars).'), + $this->showForm(sprintf(_m('Bio is too long (maximum %d character).', + 'Bio is too long (maximum %d characters).', + Profile::maxBio()), Profile::maxBio())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { - $this->showForm(_('Location is too long (max 255 chars).')); + $this->showForm(_('Location is too long (maximum 255 characters).')); return; } else if (strlen($password) < 6) { $this->showForm(_('Password must be 6 or more characters.')); @@ -465,7 +467,12 @@ class RegisterAction extends Action $this->elementStart('li'); $maxBio = Profile::maxBio(); if ($maxBio > 0) { - $bioInstr = sprintf(_('Describe yourself and your interests in %d chars'), + // TRANS: Tooltip for field label in form for profile settings. Plural + // TRANS: is decided by the number of characters available for the + // TRANS: biography (%d). + $bioInstr = sprintf(_m('Describe yourself and your interests in %d character', + 'Describe yourself and your interests in %d characters', + $maxBio), $maxBio); } else { $bioInstr = _('Describe yourself and your interests'); diff --git a/actions/showstream.php b/actions/showstream.php index be61a7ce0..fb5b061fb 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -54,7 +54,6 @@ require_once INSTALLDIR.'/lib/feedlist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ShowstreamAction extends ProfileAction { function isReadOnly($args) @@ -84,7 +83,6 @@ class ShowstreamAction extends ProfileAction function handle($args) { - // Looks like we're good; start output // For YADIS discovery, we also have a <meta> tag @@ -186,7 +184,6 @@ class ShowstreamAction extends ProfileAction $this->element('link', array('rel' => 'EditURI', 'type' => 'application/rsd+xml', 'href' => $rsd)); - } function showProfile() diff --git a/actions/subscribers.php b/actions/subscribers.php index 2845a498e..2862f35c6 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -41,14 +41,17 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class SubscribersAction extends GalleryAction { function title() { if ($this->page == 1) { + // TRANS: Header for list of subscribers for a user (first page). + // TRANS: %s is the user's nickname. return sprintf(_('%s subscribers'), $this->user->nickname); } else { + // TRANS: Header for list of subscribers for a user (not first page). + // TRANS: %1$s is the user's nickname, $2$d is the page number. return sprintf(_('%1$s subscribers, page %2$d'), $this->user->nickname, $this->page); @@ -60,10 +63,14 @@ class SubscribersAction extends GalleryAction $user = common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, + // TRANS: Page notice for page with an overview of all subscribers + // TRANS: of the logged in user's own profile. _('These are the people who listen to '. 'your notices.')); } else { $this->element('p', null, + // TRANS: Page notice for page with an overview of all subscribers of a user other + // TRANS: than the logged in user. %s is the user nickname. sprintf(_('These are the people who '. 'listen to %s\'s notices.'), $this->profile->nickname)); @@ -105,12 +112,20 @@ class SubscribersAction extends GalleryAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message = _('You have no subscribers. Try subscribing to people you know and they might return the favor'); + // TRANS: Subscriber list text when the logged in user has no subscribers. + $message = _('You have no subscribers. Try subscribing to people you know and they might return the favor.'); } else { + // TRANS: Subscriber list text when looking at the subscribers for a of a user other + // TRANS: than the logged in user that has no subscribers. %s is the user nickname. $message = sprintf(_('%s has no subscribers. Want to be the first?'), $this->user->nickname); } } else { + // TRANS: Subscriber list text when looking at the subscribers for a of a user that has none + // TRANS: as an anonymous user. %s is the user nickname. + // TRANS: This message contains a Markdown URL. The link description is between + // TRANS: square brackets, and the link between parentheses. Do not separate "](" + // TRANS: and do not change the URL part. $message = sprintf(_('%s has no subscribers. Why not [register an account](%%%%action.register%%%%) and be the first?'), $this->user->nickname); } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index 7b10b3425..ba2f67f2d 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -41,16 +41,17 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } - class SubscriptionsAction extends GalleryAction { function title() { if ($this->page == 1) { + // TRANS: Header for subscriptions overview for a user (first page). + // TRANS: %s is a user nickname. return sprintf(_('%s subscriptions'), $this->user->nickname); } else { + // TRANS: Header for subscriptions overview for a user (not first page). + // TRANS: %1$s is a user nickname, %2$d is the page number. return sprintf(_('%1$s subscriptions, page %2$d'), $this->user->nickname, $this->page); @@ -62,10 +63,14 @@ class SubscriptionsAction extends GalleryAction $user = common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, + // TRANS: Page notice for page with an overview of all subscriptions + // TRANS: of the logged in user's own profile. _('These are the people whose notices '. 'you listen to.')); } else { $this->element('p', null, + // TRANS: Page notice for page with an overview of all subscriptions of a user other + // TRANS: than the logged in user. %s is the user nickname. sprintf(_('These are the people whose '. 'notices %s listens to.'), $this->profile->nickname)); @@ -123,12 +128,24 @@ class SubscriptionsAction extends GalleryAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message = _('You\'re not listening to anyone\'s notices right now, try subscribing to people you know. Try [people search](%%action.peoplesearch%%), look for members in groups you\'re interested in and in our [featured users](%%action.featured%%). If you\'re a [Twitter user](%%action.twittersettings%%), you can automatically subscribe to people you already follow there.'); + // TRANS: Subscription list text when the logged in user has no subscriptions. + // TRANS: This message contains Markdown URLs. The link description is between + // TRANS: square brackets, and the link between parentheses. Do not separate "](" + // TRANS: and do not change the URL part. + $message = _('You\'re not listening to anyone\'s notices right now, try subscribing to people you know. '. + 'Try [people search](%%action.peoplesearch%%), look for members in groups you\'re interested '. + 'in and in our [featured users](%%action.featured%%). '. + 'If you\'re a [Twitter user](%%action.twittersettings%%), you can automatically subscribe to '. + 'people you already follow there.'); } else { + // TRANS: Subscription list text when looking at the subscriptions for a of a user other + // TRANS: than the logged in user that has no subscriptions. %s is the user nickname. $message = sprintf(_('%s is not listening to anyone.'), $this->user->nickname); } } else { + // TRANS: Subscription list text when looking at the subscriptions for a of a user that has none + // TRANS: as an anonymous user. %s is the user nickname. $message = sprintf(_('%s is not listening to anyone.'), $this->user->nickname); } @@ -205,6 +222,7 @@ class SubscriptionsListItem extends SubscriptionListItem } $this->out->element('input', $attrs); + // TRANS: Checkbox label for enabling Jabber messages for a profile in a subscriptions list. $this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _('Jabber')); } else { $this->out->hidden('jabber', $sub->jabber); @@ -219,11 +237,13 @@ class SubscriptionsListItem extends SubscriptionListItem } $this->out->element('input', $attrs); + // TRANS: Checkbox label for enabling SMS messages for a profile in a subscriptions list. $this->out->element('label', array('for' => 'sms-'.$this->profile->id), _('SMS')); } else { $this->out->hidden('sms', $sub->sms); } - $this->out->submit('save', _('Save')); + // TRANS: Save button for settings for a profile in a subscriptions list. + $this->out->submit('save', _m('BUTTON','Save')); $this->out->elementEnd('form'); return; } |