diff --git a/actions/all.php b/actions/all.php index 8c22e6f5f0..a977fce954 100644 --- a/actions/all.php +++ b/actions/all.php @@ -61,7 +61,7 @@ class AllAction extends ProfileAction if ($this->page > 1 && $this->notice->N == 0) { // TRANS: Server error when page not found (404) - $this->serverError(_('No such page'), $code = 404); + $this->serverError(_('No such page.'), $code = 404); } return true; diff --git a/actions/allrss.php b/actions/allrss.php index 01e737ad7b..7df0b1ef7c 100644 --- a/actions/allrss.php +++ b/actions/allrss.php @@ -112,10 +112,12 @@ class AllrssAction extends Rss10Action $c = array('url' => common_local_url('allrss', array('nickname' => $user->nickname)), + // TRANS: Message is used as link title. %s is a user nickname. 'title' => sprintf(_('%s and friends'), $user->nickname), 'link' => common_local_url('all', array('nickname' => $user->nickname)), + // TRANS: Message is used as link description. %1$s is a username, %2$s is a site name. 'description' => sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, common_config('site', 'name'))); return $c; diff --git a/actions/apiaccountupdatedeliverydevice.php b/actions/apiaccountupdatedeliverydevice.php index 4bd6c326f8..d42d25a618 100644 --- a/actions/apiaccountupdatedeliverydevice.php +++ b/actions/apiaccountupdatedeliverydevice.php @@ -103,7 +103,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction $this->clientError( _( 'You must specify a parameter named ' . - '\'device\' with a value of one of: sms, im, none' + '\'device\' with a value of one of: sms, im, none.' ) ); return; diff --git a/actions/apigroupcreate.php b/actions/apigroupcreate.php index 145806356c..3eb3ae5fcc 100644 --- a/actions/apigroupcreate.php +++ b/actions/apigroupcreate.php @@ -263,7 +263,7 @@ class ApiGroupCreateAction extends ApiAuthAction if (!$valid) { $this->clientError( - sprintf(_('Invalid alias: "%s"'), $alias), + sprintf(_('Invalid alias: "%s".'), $alias), 403, $this->format ); diff --git a/actions/apigroupismember.php b/actions/apigroupismember.php index 97f8435614..f51c747dfb 100644 --- a/actions/apigroupismember.php +++ b/actions/apigroupismember.php @@ -92,7 +92,7 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction } if (empty($this->group)) { - $this->clientError(_('Group not found!'), 404, $this->format); + $this->clientError(_('Group not found.'), 404, $this->format); return false; } diff --git a/actions/apigroupjoin.php b/actions/apigroupjoin.php index 374cf83df0..28df72fa9a 100644 --- a/actions/apigroupjoin.php +++ b/actions/apigroupjoin.php @@ -101,7 +101,7 @@ class ApiGroupJoinAction extends ApiAuthAction } if (empty($this->group)) { - $this->clientError(_('Group not found!'), 404, $this->format); + $this->clientError(_('Group not found.'), 404, $this->format); return false; } diff --git a/actions/apigroupleave.php b/actions/apigroupleave.php index 9848ece053..f6e52b26e8 100644 --- a/actions/apigroupleave.php +++ b/actions/apigroupleave.php @@ -101,7 +101,7 @@ class ApiGroupLeaveAction extends ApiAuthAction } if (empty($this->group)) { - $this->clientError(_('Group not found!'), 404, $this->format); + $this->clientError(_('Group not found.'), 404, $this->format); return false; } diff --git a/actions/apigrouplistall.php b/actions/apigrouplistall.php index f7677970f8..bd05fa3ea8 100644 --- a/actions/apigrouplistall.php +++ b/actions/apigrouplistall.php @@ -87,6 +87,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction parent::handle($args); $sitename = common_config('site', 'name'); + // TRANS: Message is used as a title. %s is a site name. $title = sprintf(_("%s groups"), $sitename); $taguribase = TagURI::base(); $id = "tag:$taguribase:Groups"; diff --git a/actions/apigroupmembership.php b/actions/apigroupmembership.php index 9f72b527cf..c97b27fac4 100644 --- a/actions/apigroupmembership.php +++ b/actions/apigroupmembership.php @@ -88,7 +88,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction parent::handle($args); if (empty($this->group)) { - $this->clientError(_('Group not found!'), 404, $this->format); + $this->clientError(_('Group not found.'), 404, $this->format); return false; } diff --git a/actions/apigroupshow.php b/actions/apigroupshow.php index 5745a81f41..8e471689a8 100644 --- a/actions/apigroupshow.php +++ b/actions/apigroupshow.php @@ -79,7 +79,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction common_redirect(common_local_url('ApiGroupShow', $args), 301); } else { $this->clientError( - _('Group not found!'), + _('Group not found.'), 404, $this->format ); diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index 1956c85863..d4ef6b550d 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -199,7 +199,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction $reply_to = $this->in_reply_to_status_id; } else { $this->clientError( - _('Not found'), + _('Not found.'), $code = 404, $this->format ); diff --git a/actions/apitimelinefriends.php b/actions/apitimelinefriends.php index ac350ab1b7..7f80f252e7 100644 --- a/actions/apitimelinefriends.php +++ b/actions/apitimelinefriends.php @@ -116,6 +116,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction $id = "tag:$taguribase:FriendsTimeline:" . $this->user->id; $subtitle = sprintf( + // TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name. _('Updates from %1$s and friends on %2$s!'), $this->user->nickname, $sitename diff --git a/actions/apitimelinegroup.php b/actions/apitimelinegroup.php index da816c40a9..56d1de094c 100644 --- a/actions/apitimelinegroup.php +++ b/actions/apitimelinegroup.php @@ -88,7 +88,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction parent::handle($args); if (empty($this->group)) { - $this->clientError(_('Group not found!'), 404, $this->format); + $this->clientError(_('Group not found.'), 404, $this->format); return false; } diff --git a/actions/apitimelinehome.php b/actions/apitimelinehome.php index 1618c9923c..43a13dcda9 100644 --- a/actions/apitimelinehome.php +++ b/actions/apitimelinehome.php @@ -117,6 +117,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction $id = "tag:$taguribase:HomeTimeline:" . $this->user->id; $subtitle = sprintf( + // TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name. _('Updates from %1$s and friends on %2$s!'), $this->user->nickname, $sitename ); diff --git a/actions/apitimelineretweetedbyme.php b/actions/apitimelineretweetedbyme.php index 564e98619a..af05623cdf 100644 --- a/actions/apitimelineretweetedbyme.php +++ b/actions/apitimelineretweetedbyme.php @@ -69,7 +69,7 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction { parent::prepare($args); - $this->serverError('Unimplemented', 503); + $this->serverError('Unimplemented.', 503); return false; } diff --git a/actions/avatarsettings.php b/actions/avatarsettings.php index d4ea11cb7e..52dc2e4249 100644 --- a/actions/avatarsettings.php +++ b/actions/avatarsettings.php @@ -103,7 +103,7 @@ class AvatarsettingsAction extends AccountSettingsAction if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); - $this->serverError(_('User without matching profile')); + $this->serverError(_('User without matching profile.')); return; } @@ -182,7 +182,7 @@ class AvatarsettingsAction extends AccountSettingsAction if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); - $this->serverError(_('User without matching profile')); + $this->serverError(_('User without matching profile.')); return; } diff --git a/actions/block.php b/actions/block.php index fe4ec00881..11565e20c5 100644 --- a/actions/block.php +++ b/actions/block.php @@ -66,7 +66,7 @@ class BlockAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if ($cur->hasBlocked($this->profile)) { - $this->clientError(_("You already blocked that user.")); + $this->clientError(_('You already blocked that user.')); return false; } @@ -140,8 +140,20 @@ class BlockAction extends ProfileFormAction $this->hidden($k, $v); } } - $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user")); - $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user')); + $this->submit('form_action-no', + // TRANS: Button label on the user block form. + _m('BUTTON','No'), + 'submit form_action-primary', + 'no', + // TRANS: Submit button title for 'No' when blocking a user. + _('Do not block this user')); + $this->submit('form_action-yes', + // TRANS: Button label on the user block form. + _m('BUTTON','Yes'), + 'submit form_action-secondary', + 'yes', + // TRANS: Submit button title for 'Yes' when blocking a user. + _('Block this user')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/bookmarklet.php b/actions/bookmarklet.php index 0603a74561..041c2e8947 100644 --- a/actions/bookmarklet.php +++ b/actions/bookmarklet.php @@ -47,7 +47,8 @@ class BookmarkletAction extends NewnoticeAction { function showTitle() { - $this->element('title', null, _('Post to ').common_config('site', 'name')); + // TRANS: Title for mini-posting window loaded from bookmarklet. + $this->element('title', null, sprintf(_('Post to %s'), common_config('site', 'name'))); } function showHeader() diff --git a/actions/confirmaddress.php b/actions/confirmaddress.php index eaf1c91c1a..f92db3ec45 100644 --- a/actions/confirmaddress.php +++ b/actions/confirmaddress.php @@ -89,6 +89,7 @@ class ConfirmaddressAction extends Action $transports = array(); Event::handle('GetImTransports', array(&$transports)); if (!in_array($type, array('email', 'sms')) && !in_array($type, array_keys($transports))) { + // TRANS: Server error for an unknown address type, which can be 'email', 'sms', or the name of an IM network (such as 'xmpp' or 'aim') $this->serverError(sprintf(_('Unrecognized address type %s'), $type)); return; } diff --git a/actions/deleteapplication.php b/actions/deleteapplication.php index 17526e1118..806de0be6e 100644 --- a/actions/deleteapplication.php +++ b/actions/deleteapplication.php @@ -150,13 +150,17 @@ class DeleteapplicationAction extends Action 'This will clear all data about the application from the '. 'database, including all existing user connections.')); $this->submit('form_action-no', - _('No'), + // TRANS: Button label on the delete application form. + _m('BUTTON','No'), 'submit form_action-primary', 'no', - _("Do not delete this application")); + // TRANS: Submit button title for 'No' when deleting an application. + _('Do not delete this application')); $this->submit('form_action-yes', - _('Yes'), + // TRANS: Button label on the delete application form. + _m('BUTTON','Yes'), 'submit form_action-secondary', + // TRANS: Submit button title for 'Yes' when deleting an application. 'yes', _('Delete this application')); $this->elementEnd('fieldset'); $this->elementEnd('form'); diff --git a/actions/deletenotice.php b/actions/deletenotice.php index 69cb1ebe87..f8010a814a 100644 --- a/actions/deletenotice.php +++ b/actions/deletenotice.php @@ -142,8 +142,20 @@ class DeletenoticeAction extends Action $this->hidden('token', common_session_token()); $this->hidden('notice', $this->trimmed('notice')); $this->element('p', null, _('Are you sure you want to delete this notice?')); - $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not delete this notice")); - $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this notice')); + $this->submit('form_action-no', + // TRANS: Button label on the delete notice form. + _m('BUTTON','No'), + 'submit form_action-primary', + 'no', + // TRANS: Submit button title for 'No' when deleting a notice. + _("Do not delete this notice")); + $this->submit('form_action-yes', + // TRANS: Button label on the delete notice form. + _m('BUTTON','Yes'), + 'submit form_action-secondary', + 'yes', + // TRANS: Submit button title for 'Yes' when deleting a notice. + _('Delete this notice')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/deleteuser.php b/actions/deleteuser.php index 4e6b273953..1c1f19b0e6 100644 --- a/actions/deleteuser.php +++ b/actions/deleteuser.php @@ -64,14 +64,14 @@ class DeleteuserAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::DELETEUSER)) { - $this->clientError(_("You cannot delete users.")); + $this->clientError(_('You cannot delete users.')); return false; } $this->user = User::staticGet('id', $this->profile->id); if (empty($this->user)) { - $this->clientError(_("You can only delete local users.")); + $this->clientError(_('You can only delete local users.')); return false; } @@ -147,8 +147,20 @@ class DeleteuserAction extends ProfileFormAction } Event::handle('EndDeleteUserForm', array($this, $this->user)); } - $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user")); - $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this user')); + $this->submit('form_action-no', + // TRANS: Button label on the delete user form. + _m('BUTTON','No'), + 'submit form_action-primary', + 'no', + // TRANS: Submit button title for 'No' when deleting a user. + _('Do not block this user')); + $this->submit('form_action-yes', + // TRANS: Button label on the delete user form. + _m('BUTTON','Yes'), + 'submit form_action-secondary', + 'yes', + // TRANS: Submit button title for 'Yes' when deleting a user. + _('Delete this user')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/designadminpanel.php b/actions/designadminpanel.php index 30e8bde1a4..8c08581b5d 100644 --- a/actions/designadminpanel.php +++ b/actions/designadminpanel.php @@ -59,6 +59,7 @@ class DesignadminpanelAction extends AdminPanelAction function title() { + // TRANS: Message used as title for design settings for the site. return _('Design'); } @@ -272,11 +273,11 @@ class DesignadminpanelAction extends AdminPanelAction { if (!empty($values['logo']) && !Validate::uri($values['logo'], array('allowed_schemes' => array('http', 'https')))) { - $this->clientError(_("Invalid logo URL.")); + $this->clientError(_('Invalid logo URL.')); } if (!in_array($values['theme'], Theme::listAvailable())) { - $this->clientError(sprintf(_("Theme not available: %s"), $values['theme'])); + $this->clientError(sprintf(_("Theme not available: %s."), $values['theme'])); } } @@ -454,6 +455,7 @@ class DesignAdminPanelForm extends AdminForm $this->out->element('label', array('for' => 'design_background-image_on', 'class' => 'radio'), + // TRANS: Used as radio button label to add a background image. _('On')); $attrs = array('name' => 'design_background-image_onoff', @@ -470,6 +472,7 @@ class DesignAdminPanelForm extends AdminForm $this->out->element('label', array('for' => 'design_background-image_off', 'class' => 'radio'), + // TRANS: Used as radio button label to not add a background image. _('Off')); $this->out->element('p', 'form_guide', _('Turn background image on or off.')); $this->unli(); diff --git a/actions/disfavor.php b/actions/disfavor.php index 6269f1bd25..3ccdd69af2 100644 --- a/actions/disfavor.php +++ b/actions/disfavor.php @@ -71,7 +71,7 @@ class DisfavorAction extends Action $notice = Notice::staticGet($id); $token = $this->trimmed('token-'.$notice->id); if (!$token || $token != common_session_token()) { - $this->clientError(_("There was a problem with your session token. Try again, please.")); + $this->clientError(_('There was a problem with your session token. Try again, please.')); return; } $fave = new Fave(); diff --git a/actions/emailsettings.php b/actions/emailsettings.php index 08608348cd..6138a88f90 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -57,6 +57,7 @@ class EmailsettingsAction extends AccountSettingsAction function title() { + // TRANS: Title for e-mail settings. return _('Email settings'); } @@ -68,6 +69,10 @@ class EmailsettingsAction extends AccountSettingsAction function getInstructions() { + // XXX: For consistency of parameters in messages, this should be a + // regular parameters, replaced with sprintf(). + // TRANS: E-mail settings page instructions. + // TRANS: %%site.name%% is the name of the site. return _('Manage how you get email from %%site.name%%.'); } @@ -97,102 +102,126 @@ class EmailsettingsAction extends AccountSettingsAction common_local_url('emailsettings'))); $this->elementStart('fieldset'); $this->elementStart('fieldset', array('id' => 'settings_email_address')); - $this->element('legend', null, _('Address')); + // TRANS: Form legend for e-mail settings form. + $this->element('legend', null, _('Email address')); $this->hidden('token', common_session_token()); if ($user->email) { $this->element('p', array('id' => 'form_confirmed'), $user->email); + // TRANS: Form note in e-mail settings form. $this->element('p', array('class' => 'form_note'), _('Current confirmed email address.')); $this->hidden('email', $user->email); - $this->submit('remove', _('Remove')); + // TRANS: Button label to remove a confirmed e-mail address. + $this->submit('remove', _m('BUTTON','Remove')); } else { $confirm = $this->getConfirmation(); if ($confirm) { $this->element('p', array('id' => 'form_unconfirmed'), $confirm->address); + // TRANS: Form note in e-mail settings form. $this->element('p', array('class' => 'form_note'), _('Awaiting confirmation on this address. '. 'Check your inbox (and spam box!) for a message '. 'with further instructions.')); $this->hidden('email', $confirm->address); - $this->submit('cancel', _('Cancel')); + // TRANS: Button label to cancel an e-mail address confirmation procedure. + $this->submit('cancel', _m('BUTTON','Cancel')); } else { $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label for e-mail address input in e-mail settings form. $this->input('email', _('Email address'), ($this->arg('email')) ? $this->arg('email') : null, + // TRANS: Instructions for e-mail address input form. _('Email address, like "UserName@example.org"')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('add', _('Add')); + // TRANS: Button label for adding an e-mail address in e-mail settings form. + $this->submit('add', _m('BUTTON','Add')); } } $this->elementEnd('fieldset'); if (common_config('emailpost', 'enabled') && $user->email) { $this->elementStart('fieldset', array('id' => 'settings_email_incoming')); + // TRANS: Form legend for incoming e-mail settings form. $this->element('legend', null, _('Incoming email')); if ($user->incomingemail) { $this->elementStart('p'); $this->element('span', 'address', $user->incomingemail); + // XXX: Looks a little awkward in the UI. + // Something like "xxxx@identi.ca Send email ..". Needs improvement. $this->element('span', 'input_instructions', + // TRANS: Form instructions for incoming e-mail form in e-mail settings. _('Send email to this address to post new notices.')); $this->elementEnd('p'); - $this->submit('removeincoming', _('Remove')); + // TRANS: Button label for removing a set sender e-mail address to post notices from. + $this->submit('removeincoming', _m('BUTTON','Remove')); } $this->elementStart('p'); $this->element('span', 'input_instructions', + // TRANS: Instructions for incoming e-mail address input form. _('Make a new email address for posting to; '. 'cancels the old one.')); $this->elementEnd('p'); - $this->submit('newincoming', _('New')); + // TRANS: Button label for adding an e-mail address to send notices from. + $this->submit('newincoming', _m('BUTTON','New')); $this->elementEnd('fieldset'); } $this->elementStart('fieldset', array('id' => 'settings_email_preferences')); - $this->element('legend', null, _('Preferences')); + // TRANS: Form legend for e-mail preferences form. + $this->element('legend', null, _('Email preferences')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->checkbox('emailnotifysub', + // TRANS: Checkbox label in e-mail preferences form. _('Send me notices of new subscriptions through email.'), $user->emailnotifysub); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('emailnotifyfav', + // TRANS: Checkbox label in e-mail preferences form. _('Send me email when someone '. 'adds my notice as a favorite.'), $user->emailnotifyfav); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('emailnotifymsg', + // TRANS: Checkbox label in e-mail preferences form. _('Send me email when someone sends me a private message.'), $user->emailnotifymsg); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('emailnotifyattn', + // TRANS: Checkbox label in e-mail preferences form. _('Send me email when someone sends me an "@-reply".'), $user->emailnotifyattn); $this->elementEnd('li'); $this->elementStart('li'); $this->checkbox('emailnotifynudge', + // TRANS: Checkbox label in e-mail preferences form. _('Allow friends to nudge me and send me an email.'), $user->emailnotifynudge); $this->elementEnd('li'); if (common_config('emailpost', 'enabled')) { $this->elementStart('li'); $this->checkbox('emailpost', + // TRANS: Checkbox label in e-mail preferences form. _('I want to post notices by email.'), $user->emailpost); $this->elementEnd('li'); } $this->elementStart('li'); $this->checkbox('emailmicroid', + // TRANS: Checkbox label in e-mail preferences form. _('Publish a MicroID for my email address.'), $user->emailmicroid); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('save', _('Save')); + // TRANS: Button label to save e-mail preferences. + $this->submit('save', _m('BUTTON','Save')); $this->elementEnd('fieldset'); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -253,6 +282,7 @@ class EmailsettingsAction extends AccountSettingsAction } else if ($this->arg('newincoming')) { $this->newIncoming(); } else { + // TRANS: Message given submitting a form with an unknown action in e-mail settings. $this->showForm(_('Unexpected form submission.')); } } @@ -293,13 +323,15 @@ class EmailsettingsAction extends AccountSettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error updating e-mail preferences. $this->serverError(_('Couldn\'t update user.')); return; } $user->query('COMMIT'); - $this->showForm(_('Preferences saved.'), true); + // TRANS: Confirmation message for successful e-mail preferences save. + $this->showForm(_('Email preferences saved.'), true); } /** @@ -317,6 +349,7 @@ class EmailsettingsAction extends AccountSettingsAction // Some validation if (!$email) { + // TRANS: Message given saving e-mail address without having provided one. $this->showForm(_('No email address.')); return; } @@ -324,16 +357,20 @@ class EmailsettingsAction extends AccountSettingsAction $email = common_canonical_email($email); if (!$email) { + // TRANS: Message given saving e-mail address that cannot be normalised. $this->showForm(_('Cannot normalize that email address')); return; } if (!Validate::email($email, common_config('email', 'check_domain'))) { + // TRANS: Message given saving e-mail address that not valid. $this->showForm(_('Not a valid email address.')); return; } else if ($user->email == $email) { + // TRANS: Message given saving e-mail address that is already set. $this->showForm(_('That is already your email address.')); return; } else if ($this->emailExists($email)) { + // TRANS: Message given saving e-mail address that is already set for another user. $this->showForm(_('That email address already belongs '. 'to another user.')); return; @@ -350,12 +387,14 @@ class EmailsettingsAction extends AccountSettingsAction if ($result === false) { common_log_db_error($confirm, 'INSERT', __FILE__); + // TRANS: Server error thrown on database error adding e-mail confirmation code. $this->serverError(_('Couldn\'t insert confirmation code.')); return; } mail_confirm_address($user, $confirm->code, $user->nickname, $email); + // TRANS: Message given saving valid e-mail address that is to be confirmed. $msg = _('A confirmation code was sent to the email address you added. '. 'Check your inbox (and spam box!) for the code and instructions '. 'on how to use it.'); @@ -376,11 +415,13 @@ class EmailsettingsAction extends AccountSettingsAction $confirm = $this->getConfirmation(); if (!$confirm) { + // TRANS: Message given canceling e-mail address confirmation that is not pending. $this->showForm(_('No pending confirmation to cancel.')); return; } if ($confirm->address != $email) { - $this->showForm(_('That is the wrong IM address.')); + // TRANS: Message given canceling e-mail address confirmation for the wrong e-mail address. + $this->showForm(_('That is the wrong email address.')); return; } @@ -388,11 +429,13 @@ class EmailsettingsAction extends AccountSettingsAction if (!$result) { common_log_db_error($confirm, 'DELETE', __FILE__); + // TRANS: Server error thrown on database error canceling e-mail address confirmation. $this->serverError(_('Couldn\'t delete email confirmation.')); return; } - $this->showForm(_('Confirmation cancelled.'), true); + // TRANS: Message given after successfully canceling e-mail address confirmation. + $this->showForm(_('Email confirmation cancelled.'), true); } /** @@ -410,6 +453,8 @@ class EmailsettingsAction extends AccountSettingsAction // Maybe an old tab open...? if ($user->email != $email) { + // TRANS: Message given trying to remove an e-mail address that is not + // TRANS: registered for the active user. $this->showForm(_('That is not your email address.')); return; } @@ -424,12 +469,14 @@ class EmailsettingsAction extends AccountSettingsAction if (!$result) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error removing a registered e-mail address. $this->serverError(_('Couldn\'t update user.')); return; } $user->query('COMMIT'); - $this->showForm(_('The address was removed.'), true); + // TRANS: Message given after successfully removing a registered e-mail address. + $this->showForm(_('The email address was removed.'), true); } /** @@ -453,9 +500,11 @@ class EmailsettingsAction extends AccountSettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error removing incoming e-mail address. $this->serverError(_("Couldn't update user record.")); } + // TRANS: Message given after successfully removing an incoming e-mail address. $this->showForm(_('Incoming email address removed.'), true); } @@ -475,9 +524,11 @@ class EmailsettingsAction extends AccountSettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error adding incoming e-mail address. $this->serverError(_("Couldn't update user record.")); } + // TRANS: Message given after successfully adding an incoming e-mail address. $this->showForm(_('New incoming email address added.'), true); } diff --git a/actions/favor.php b/actions/favor.php index afca9768ae..475912fd0b 100644 --- a/actions/favor.php +++ b/actions/favor.php @@ -72,7 +72,7 @@ class FavorAction extends Action $notice = Notice::staticGet($id); $token = $this->trimmed('token-'.$notice->id); if (!$token || $token != common_session_token()) { - $this->clientError(_("There was a problem with your session token. Try again, please.")); + $this->clientError(_('There was a problem with your session token. Try again, please.')); return; } if ($user->hasFave($notice)) { diff --git a/actions/finishremotesubscribe.php b/actions/finishremotesubscribe.php index deee70f360..ac51ddec3f 100644 --- a/actions/finishremotesubscribe.php +++ b/actions/finishremotesubscribe.php @@ -135,7 +135,7 @@ class FinishremotesubscribeAction extends Action $service->getServiceURI(OMB_ENDPOINT_UPDATEPROFILE); if (!$remote->update($orig_remote)) { - $this->serverError(_('Error updating remote profile')); + $this->serverError(_('Error updating remote profile.')); return; } diff --git a/actions/foafgroup.php b/actions/foafgroup.php index d685554ac4..4db40c28be 100644 --- a/actions/foafgroup.php +++ b/actions/foafgroup.php @@ -56,7 +56,7 @@ class FoafGroupAction extends Action return false; } - $local = Local_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $this->nickname); if (!$local) { $this->clientError(_('No such group.'), 404); @@ -126,7 +126,8 @@ class FoafGroupAction extends Action while ($members->fetch()) { $member_uri = common_local_url('userbyid', array('id'=>$members->id)); $member_details[$member_uri] = array( - 'nickname' => $members->nickname + 'nickname' => $members->nickname, + 'is_admin' => false, ); $this->element('member', array('rdf:resource' => $member_uri)); } diff --git a/actions/grantrole.php b/actions/grantrole.php index cd6bd4d79a..b8b23d02e9 100644 --- a/actions/grantrole.php +++ b/actions/grantrole.php @@ -59,11 +59,11 @@ class GrantRoleAction extends ProfileFormAction $this->role = $this->arg('role'); if (!Profile_role::isValid($this->role)) { - $this->clientError(_("Invalid role.")); + $this->clientError(_('Invalid role.')); return false; } if (!Profile_role::isSettable($this->role)) { - $this->clientError(_("This role is reserved and cannot be set.")); + $this->clientError(_('This role is reserved and cannot be set.')); return false; } @@ -72,14 +72,14 @@ class GrantRoleAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::GRANTROLE)) { - $this->clientError(_("You cannot grant user roles on this site.")); + $this->clientError(_('You cannot grant user roles on this site.')); return false; } assert(!empty($this->profile)); // checked by parent if ($this->profile->hasRole($this->role)) { - $this->clientError(_("User already has this role.")); + $this->clientError(_('User already has this role.')); return false; } diff --git a/actions/groupblock.php b/actions/groupblock.php index 88d7634a28..e52db6e111 100644 --- a/actions/groupblock.php +++ b/actions/groupblock.php @@ -41,7 +41,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @link http://status.net/ */ -class GroupblockAction extends Action +class GroupblockAction extends RedirectingAction { var $profile = null; var $group = null; @@ -117,9 +117,7 @@ class GroupblockAction extends Action parent::handle($args); if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($this->arg('no')) { - common_redirect(common_local_url('groupmembers', - array('nickname' => $this->group->nickname)), - 303); + $this->returnToArgs(); } elseif ($this->arg('yes')) { $this->blockProfile(); } elseif ($this->arg('blockto')) { @@ -175,8 +173,20 @@ class GroupblockAction extends Action $this->hidden($k, $v); } } - $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group")); - $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group')); + $this->submit('form_action-no', + // TRANS: Button label on the form to block a user from a group. + _m('BUTTON','No'), + 'submit form_action-primary', + 'no', + // TRANS: Submit button title for 'No' when blocking a user from a group. + _('Do not block this user from this group')); + $this->submit('form_action-yes', + // TRANS: Button label on the form to block a user from a group. + _m('BUTTON','Yes'), + 'submit form_action-secondary', + 'yes', + // TRANS: Submit button title for 'Yes' when blocking a user from a group. + _('Block this user from this group')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -196,23 +206,20 @@ class GroupblockAction extends Action $this->serverError(_("Database error blocking user from group.")); return false; } + + $this->returnToArgs(); + } - // Now, gotta figure where we go back to - foreach ($this->args as $k => $v) { - if ($k == 'returnto-action') { - $action = $v; - } elseif (substr($k, 0, 9) == 'returnto-') { - $args[substr($k, 9)] = $v; - } - } - - if ($action) { - common_redirect(common_local_url($action, $args), 303); - } else { - common_redirect(common_local_url('groupmembers', - array('nickname' => $this->group->nickname)), - 303); - } + /** + * If we reached this form without returnto arguments, default to + * the top of the group's member list. + * + * @return string URL + */ + function defaultReturnTo() + { + return common_local_url('groupmembers', + array('nickname' => $this->group->nickname)); } function showScripts() diff --git a/actions/groupmembers.php b/actions/groupmembers.php index fb4e46dbc0..54f1d8dcda 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -205,8 +205,7 @@ class GroupMemberListItem extends ProfileListItem !$this->profile->isAdmin($this->group)) { $this->out->elementStart('li', 'entity_make_admin'); $maf = new MakeAdminForm($this->out, $this->profile, $this->group, - array('action' => 'groupmembers', - 'nickname' => $this->group->nickname)); + $this->returnToArgs()); $maf->show(); $this->out->elementEnd('li'); } @@ -220,8 +219,7 @@ class GroupMemberListItem extends ProfileListItem if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) { $this->out->elementStart('li', 'entity_block'); $bf = new GroupBlockForm($this->out, $this->profile, $this->group, - array('action' => 'groupmembers', - 'nickname' => $this->group->nickname)); + $this->returnToArgs()); $bf->show(); $this->out->elementEnd('li'); } @@ -240,9 +238,30 @@ class GroupMemberListItem extends ProfileListItem function homepageAttributes() { + $aAttrs = parent::linkAttributes(); + if (common_config('nofollow', 'members')) { $aAttrs['rel'] = 'nofollow'; } + + return $aAttrs; + } + + /** + * Fetch necessary return-to arguments for the profile forms + * to return to this list when they're done. + * + * @return array + */ + protected function returnToArgs() + { + $args = array('action' => 'groupmembers', + 'nickname' => $this->group->nickname); + $page = $this->out->arg('page'); + if ($page) { + $args['param-page'] = $page; + } + return $args; } } diff --git a/actions/grouprss.php b/actions/grouprss.php index 490f6f945c..98fdea38de 100644 --- a/actions/grouprss.php +++ b/actions/grouprss.php @@ -135,8 +135,10 @@ class groupRssAction extends Rss10Action $c = array('url' => common_local_url('grouprss', array('nickname' => $group->nickname)), + // TRANS: Message is used as link title. %s is a user nickname. 'title' => sprintf(_('%s timeline'), $group->nickname), 'link' => common_local_url('showgroup', array('nickname' => $group->nickname)), + // TRANS: Message is used as link description. %1$s is a username, %2$s is a site name. 'description' => sprintf(_('Updates from members of %1$s on %2$s!'), $group->nickname, common_config('site', 'name'))); return $c; diff --git a/actions/imsettings.php b/actions/imsettings.php index fe1864f0d1..2c2606b76c 100644 --- a/actions/imsettings.php +++ b/actions/imsettings.php @@ -53,6 +53,7 @@ class ImsettingsAction extends ConnectSettingsAction function title() { + // TRANS: Title for instance messaging settings. return _('IM settings'); } @@ -64,6 +65,9 @@ class ImsettingsAction extends ConnectSettingsAction function getInstructions() { + // TRANS: Instant messaging settings page instructions. + // TRANS: [instant messages] is link text, "(%%doc.im%%)" is the link. + // TRANS: the order and formatting of link text and link should remain unchanged. return _('You can send and receive notices through '. 'instant messaging [instant messages](%%doc.im%%). '. 'Configure your addresses and settings below.'); @@ -85,6 +89,7 @@ class ImsettingsAction extends ConnectSettingsAction Event::handle('GetImTransports', array(&$transports)); if (! $transports) { $this->element('div', array('class' => 'error'), + // TRANS: Message given in the IM settings if IM is not enabled on the site. _('IM is not available.')); return; } @@ -101,6 +106,7 @@ class ImsettingsAction extends ConnectSettingsAction 'action' => common_local_url('imsettings'))); $this->elementStart('fieldset', array('id' => 'settings_im_address')); + // TRANS: Form legend for IM settings form. $this->element('legend', null, $transport_info['display']); $this->hidden('token', common_session_token()); $this->hidden('transport', $transport); @@ -108,21 +114,30 @@ class ImsettingsAction extends ConnectSettingsAction if ($user_im_prefs = User_im_prefs::pkeyGet( array('transport' => $transport, 'user_id' => $user->id) )) { $user_im_prefs_by_transport[$transport] = $user_im_prefs; $this->element('p', 'form_confirmed', $user_im_prefs->screenname); + // TRANS: Form note in IM settings form. $this->element('p', 'form_note', sprintf(_('Current confirmed %s address.'),$transport_info['display'])); $this->hidden('screenname', $user_im_prefs->screenname); - $this->submit('remove', _('Remove')); + // TRANS: Button label to remove a confirmed IM address. + $this->submit('remove', _m('BUTTON','Remove')); } else { $confirm = $this->getConfirmation($transport); if ($confirm) { $this->element('p', 'form_unconfirmed', $confirm->address); + // TRANS: Form note in IM settings form. $this->element('p', 'form_note', + // TRANS: Form note in IM settings form. + // TRANS: %s is the IM address set for the site. sprintf(_('Awaiting confirmation on this address. '. 'Check your %s account for a '. - 'message with further instructions.'), - $transport_info['display'])); + 'message with further instructions. '. + '(Did you add %s to your buddy list?)'), + $transport_info['display'], + $transport_info['daemon_screenname'], + jabber_daemon_address())); $this->hidden('screenname', $confirm->address); - $this->submit('cancel', _('Cancel')); + // TRANS: Button label to cancel an IM address confirmation procedure. + $this->submit('cancel', _m('BUTTON','Cancel')); } else { $this->elementStart('ul', 'form_data'); $this->elementStart('li'); @@ -132,7 +147,8 @@ class ImsettingsAction extends ConnectSettingsAction $transport_info['display'])); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('add', _('Add')); + // TRANS: Button label for adding an IM address in IM settings form. + $this->submit('add', _m('BUTTON','Add')); } } $this->elementEnd('fieldset'); @@ -151,17 +167,22 @@ class ImsettingsAction extends ConnectSettingsAction $this->hidden('token', common_session_token()); $this->elementStart('table'); $this->elementStart('tr'); - $this->element('th', null, _('Preferences')); + // TRANS: Header for IM preferences form. + $this->element('th', null, _('IM Preferences')); foreach($user_im_prefs_by_transport as $transport=>$user_im_prefs) { $this->element('th', null, $transports[$transport]['display']); } $this->elementEnd('tr'); $preferences = array( + // TRANS: Checkbox label in IM preferences form. array('name'=>'notify', 'description'=>_('Send me notices')), + // TRANS: Checkbox label in IM preferences form. array('name'=>'updatefrompresence', 'description'=>_('Post a notice when my status changes.')), + // TRANS: Checkbox label in IM preferences form. array('name'=>'replies', 'description'=>_('Send me replies '. 'from people I\'m not subscribed to.')), + // TRANS: Checkbox label in IM preferences form. array('name'=>'microid', 'description'=>_('Publish a MicroID')) ); foreach($preferences as $preference) @@ -179,7 +200,8 @@ class ImsettingsAction extends ConnectSettingsAction $this->elementEnd('tr'); } $this->elementEnd('table'); - $this->submit('save', _('Save')); + // TRANS: Button label to save IM preferences. + $this->submit('save', _m('BUTTON','Save')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -237,6 +259,7 @@ class ImsettingsAction extends ConnectSettingsAction } else if ($this->arg('remove')) { $this->removeAddress(); } else { + // TRANS: Message given submitting a form with an unknown action in IM settings. $this->showForm(_('Unexpected form submission.')); } } @@ -271,12 +294,14 @@ class ImsettingsAction extends ConnectSettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error updating IM preferences. $this->serverError(_('Couldn\'t update IM preferences.')); return; } }while($user_im_prefs->fetch()); $user_im_prefs->query('COMMIT'); } + // TRANS: Confirmation message for successful IM preferences save. $this->showForm(_('Preferences saved.'), true); } @@ -299,6 +324,7 @@ class ImsettingsAction extends ConnectSettingsAction // Some validation if (!$screenname) { + // TRANS: Message given saving IM address without having provided one. $this->showForm(_('No screenname.')); return; } @@ -311,15 +337,18 @@ class ImsettingsAction extends ConnectSettingsAction Event::handle('NormalizeImScreenname', array($transport, &$screenname)); if (!$screenname) { + // TRANS: Message given saving IM address that cannot be normalised. $this->showForm(_('Cannot normalize that screenname')); return; } $valid = false; Event::handle('ValidateImScreenname', array($transport, $screenname, &$valid)); if (!$valid) { + // TRANS: Message given saving IM address that not valid. $this->showForm(_('Not a valid screenname')); return; } else if ($this->screennameExists($transport, $screenname)) { + // TRANS: Message given saving IM address that is already set for another user. $this->showForm(_('Screenname already belongs to another user.')); return; } @@ -337,12 +366,14 @@ class ImsettingsAction extends ConnectSettingsAction if ($result === false) { common_log_db_error($confirm, 'INSERT', __FILE__); + // TRANS: Server error thrown on database error adding IM confirmation code. $this->serverError(_('Couldn\'t insert confirmation code.')); return; } Event::handle('SendImConfirmationCode', array($transport, $screenname, $confirm->code, $user)); + // TRANS: Message given saving valid IM address that is to be confirmed. $msg = _('A confirmation code was sent '. 'to the IM address you added.'); @@ -365,10 +396,12 @@ class ImsettingsAction extends ConnectSettingsAction $confirm = $this->getConfirmation($transport); if (!$confirm) { + // TRANS: Message given canceling IM address confirmation that is not pending. $this->showForm(_('No pending confirmation to cancel.')); return; } if ($confirm->address != $screenname) { + // TRANS: Message given canceling IM address confirmation for the wrong IM address. $this->showForm(_('That is the wrong IM address.')); return; } @@ -377,11 +410,13 @@ class ImsettingsAction extends ConnectSettingsAction if (!$result) { common_log_db_error($confirm, 'DELETE', __FILE__); + // TRANS: Server error thrown on database error canceling IM address confirmation. $this->serverError(_('Couldn\'t delete confirmation.')); return; } - $this->showForm(_('Confirmation cancelled.'), true); + // TRANS: Message given after successfully canceling IM address confirmation. + $this->showForm(_('IM confirmation cancelled.'), true); } /** @@ -404,6 +439,8 @@ class ImsettingsAction extends ConnectSettingsAction $user_im_prefs = new User_im_prefs(); $user_im_prefs->user_id = $user->id; if(! ($user_im_prefs->find() && $user_im_prefs->fetch())) { + // TRANS: Message given trying to remove an IM address that is not + // TRANS: registered for the active user. $this->showForm(_('That is not your screenname.')); return; } @@ -412,13 +449,16 @@ class ImsettingsAction extends ConnectSettingsAction if (!$result) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error removing a registered IM address. $this->serverError(_('Couldn\'t update user im prefs.')); + $this->serverError(_('Couldn\'t update user.')); return; } // XXX: unsubscribe to the old address - $this->showForm(_('The address was removed.'), true); + // TRANS: Message given after successfully removing a registered IM address. + $this->showForm(_('The IM address was removed.'), true); } /** diff --git a/actions/invite.php b/actions/invite.php index 54b2de62ac..4bba8893d6 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -38,7 +38,7 @@ class InviteAction extends CurrentUserDesignAction if (!common_config('invite', 'enabled')) { $this->clientError(_('Invites have been disabled.')); } else if (!common_logged_in()) { - $this->clientError(sprintf(_('You must be logged in to invite other users to use %s'), + $this->clientError(sprintf(_('You must be logged in to invite other users to use %s.'), common_config('site', 'name'))); return; } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { @@ -224,8 +224,10 @@ 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. $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. $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 f19348648d..9ccb442308 100644 --- a/actions/makeadmin.php +++ b/actions/makeadmin.php @@ -41,7 +41,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @link http://status.net/ */ -class MakeadminAction extends Action +class MakeadminAction extends RedirectingAction { var $profile = null; var $group = null; @@ -148,20 +148,19 @@ class MakeadminAction extends Action $this->group->getBestName()); } - foreach ($this->args as $k => $v) { - if ($k == 'returnto-action') { - $action = $v; - } else if (substr($k, 0, 9) == 'returnto-') { - $args[substr($k, 9)] = $v; - } - } - - if ($action) { - common_redirect(common_local_url($action, $args), 303); - } else { - common_redirect(common_local_url('groupmembers', - array('nickname' => $this->group->nickname)), - 303); - } + $this->returnToArgs(); } + + /** + * If we reached this form without returnto arguments, default to + * the top of the group's member list. + * + * @return string URL + */ + function defaultReturnTo() + { + return common_local_url('groupmembers', + array('nickname' => $this->group->nickname)); + } + } diff --git a/actions/microsummary.php b/actions/microsummary.php index 5c761e8bb6..d145dc3bc7 100644 --- a/actions/microsummary.php +++ b/actions/microsummary.php @@ -66,7 +66,7 @@ class MicrosummaryAction extends Action $notice = $user->getCurrentNotice(); if (!$notice) { - $this->clientError(_('No current status'), 404); + $this->clientError(_('No current status.'), 404); } header('Content-Type: text/plain'); diff --git a/actions/oauthconnectionssettings.php b/actions/oauthconnectionssettings.php index f125f4c631..8a206d7101 100644 --- a/actions/oauthconnectionssettings.php +++ b/actions/oauthconnectionssettings.php @@ -183,7 +183,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction if (!$result) { common_log_db_error($orig, 'DELETE', __FILE__); - $this->clientError(_('Unable to revoke access for app: ' . $app->id)); + $this->clientError(sprintf(_('Unable to revoke access for app: %s.'), $app->id)); return false; } @@ -195,7 +195,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function showEmptyListMessage() { - $message = sprintf(_('You have not authorized any applications to use your account.')); + $message = _('You have not authorized any applications to use your account.'); $this->elementStart('div', 'guide'); $this->raw(common_markup_to_html($message)); diff --git a/actions/oembed.php b/actions/oembed.php index e287b6ae2a..1503aa9c2b 100644 --- a/actions/oembed.php +++ b/actions/oembed.php @@ -60,7 +60,7 @@ class OembedAction extends Action $proxy_args = $r->map($path); if (!$proxy_args) { - $this->serverError(_("$path not found"), 404); + $this->serverError(_("$path not found."), 404); } $oembed=array(); $oembed['version']='1.0'; @@ -72,11 +72,11 @@ class OembedAction extends Action $id = $proxy_args['notice']; $notice = Notice::staticGet($id); if(empty($notice)){ - $this->serverError(_("notice $id not found"), 404); + $this->serverError(_("Notice $id not found."), 404); } $profile = $notice->getProfile(); if (empty($profile)) { - $this->serverError(_('Notice has no profile'), 500); + $this->serverError(_('Notice has no profile.'), 500); } if (!empty($profile->fullname)) { $authorname = $profile->fullname . ' (' . $profile->nickname . ')'; @@ -95,7 +95,7 @@ class OembedAction extends Action $id = $proxy_args['attachment']; $attachment = File::staticGet($id); if(empty($attachment)){ - $this->serverError(_("attachment $id not found"), 404); + $this->serverError(_("Attachment $id not found."), 404); } if(empty($attachment->filename) && $file_oembed = File_oembed::staticGet('file_id', $attachment->id)){ // Proxy the existing oembed information @@ -123,7 +123,7 @@ class OembedAction extends Action if($attachment->title) $oembed['title']=$attachment->title; break; default: - $this->serverError(_("$path not supported for oembed requests"), 501); + $this->serverError(_("$path not supported for oembed requests."), 501); } switch($args['format']){ case 'xml': @@ -154,10 +154,12 @@ class OembedAction extends Action $this->end_document('json'); break; default: - $this->serverError(_('content type ' . $apidata['content-type'] . ' not supported'), 501); + // TRANS: Error message displaying attachments. %s is a raw MIME type (eg 'image/png') + $this->serverError(sprintf(_('Content type %s not supported.'), $apidata['content-type']), 501); } }else{ - $this->serverError(_('Only ' . common_root_url() . ' urls over plain http please'), 404); + // TRANS: Error message displaying attachments. %s is the site's base URL. + $this->serverError(sprintf(_('Only %s URLs over plain HTTP please.'), common_root_url()), 404); } } diff --git a/actions/pathsadminpanel.php b/actions/pathsadminpanel.php index 9155a7e428..7ff3c2583a 100644 --- a/actions/pathsadminpanel.php +++ b/actions/pathsadminpanel.php @@ -154,19 +154,19 @@ class PathsadminpanelAction extends AdminPanelAction // Validate theme dir if (!empty($values['theme']['dir']) && !is_readable($values['theme']['dir'])) { - $this->clientError(sprintf(_("Theme directory not readable: %s"), $values['theme']['dir'])); + $this->clientError(sprintf(_("Theme directory not readable: %s."), $values['theme']['dir'])); } // Validate avatar dir if (empty($values['avatar']['dir']) || !is_writable($values['avatar']['dir'])) { - $this->clientError(sprintf(_("Avatar directory not writable: %s"), $values['avatar']['dir'])); + $this->clientError(sprintf(_("Avatar directory not writable: %s."), $values['avatar']['dir'])); } // Validate background dir if (empty($values['background']['dir']) || !is_writable($values['background']['dir'])) { - $this->clientError(sprintf(_("Background directory not writable: %s"), $values['background']['dir'])); + $this->clientError(sprintf(_("Background directory not writable: %s."), $values['background']['dir'])); } // Validate locales dir @@ -174,13 +174,13 @@ 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'])) { - $this->clientError(sprintf(_("Locales directory not readable: %s"), $values['site']['locale_path'])); + $this->clientError(sprintf(_("Locales directory not readable: %s."), $values['site']['locale_path'])); } // Validate SSL setup if (mb_strlen($values['site']['sslserver']) > 255) { - $this->clientError(_("Invalid SSL server. The maximum length is 255 characters.")); + $this->clientError(_('Invalid SSL server. The maximum length is 255 characters.')); } } diff --git a/actions/peopletag.php b/actions/peopletag.php index 456cc21c4c..7287cfbf99 100644 --- a/actions/peopletag.php +++ b/actions/peopletag.php @@ -65,7 +65,7 @@ class PeopletagAction extends Action $this->tag = $this->trimmed('tag'); if (!common_valid_profile_tag($this->tag)) { - $this->clientError(sprintf(_('Not a valid people tag: %s'), + $this->clientError(sprintf(_('Not a valid people tag: %s.'), $this->tag)); return; } @@ -168,9 +168,13 @@ class PeopleTagListItem extends ProfileListItem function homepageAttributes() { + $aAttrs = parent::linkAttributes(); + if (common_config('nofollow', 'peopletag')) { $aAttrs['rel'] = 'nofollow'; } + + return $aAttrs; } } diff --git a/actions/postnotice.php b/actions/postnotice.php index b2f6f1bb95..694c7808d9 100644 --- a/actions/postnotice.php +++ b/actions/postnotice.php @@ -92,7 +92,7 @@ class PostnoticeAction extends Action { $content = common_shorten_links($_POST['omb_notice_content']); if (Notice::contentTooLong($content)) { - $this->clientError(_('Invalid notice content'), 400); + $this->clientError(_('Invalid notice content.'), 400); return false; } $license = $_POST['omb_notice_license']; diff --git a/actions/public.php b/actions/public.php index 0b3b5fde84..5fc547feaf 100644 --- a/actions/public.php +++ b/actions/public.php @@ -80,7 +80,7 @@ class PublicAction extends Action $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; if ($this->page > MAX_PUBLIC_PAGE) { - $this->clientError(sprintf(_("Beyond the page limit (%s)"), MAX_PUBLIC_PAGE)); + $this->clientError(sprintf(_("Beyond the page limit (%s)."), MAX_PUBLIC_PAGE)); } common_set_returnto($this->selfUrl()); @@ -95,7 +95,7 @@ class PublicAction extends Action if($this->page > 1 && $this->notice->N == 0){ // TRANS: Server error when page not found (404) - $this->serverError(_('No such page'),$code=404); + $this->serverError(_('No such page.'),$code=404); } return true; diff --git a/actions/register.php b/actions/register.php index ccab76cf01..d1bc381fbc 100644 --- a/actions/register.php +++ b/actions/register.php @@ -341,7 +341,7 @@ class RegisterAction extends Action } else { $instr = common_markup_to_html(_('With this form you can create '. - ' a new account. ' . + 'a new account. ' . 'You can then post notices and '. 'link up to friends and colleagues. ')); @@ -491,11 +491,15 @@ class RegisterAction extends Action $this->elementStart('li'); $this->element('input', $attrs); $this->elementStart('label', array('class' => 'checkbox', 'for' => 'license')); - $this->text(_('My text and files are available under ')); - $this->element('a', array('href' => common_config('license', 'url')), - common_config('license', 'title'), _("Creative Commons Attribution 3.0")); - $this->text(_(' except this private data: password, '. - 'email address, IM address, and phone number.')); + $message = _('My text and files are available under %s ' . + 'except this private data: password, ' . + 'email address, IM address, and phone number.'); + $link = '' . + htmlspecialchars(common_config('license', 'title')) . + ''; + $this->raw(sprintf(htmlspecialchars($message), $link)); $this->elementEnd('label'); $this->elementEnd('li'); } diff --git a/actions/remotesubscribe.php b/actions/remotesubscribe.php index c723d53a1c..9fc235e743 100644 --- a/actions/remotesubscribe.php +++ b/actions/remotesubscribe.php @@ -188,7 +188,7 @@ class RemotesubscribeAction extends Action $profile = $user->getProfile(); if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); - $this->serverError(_('User without matching profile')); + $this->serverError(_('User without matching profile.')); return; } diff --git a/actions/repeat.php b/actions/repeat.php index e112496bc1..893cae4ffd 100644 --- a/actions/repeat.php +++ b/actions/repeat.php @@ -54,21 +54,21 @@ class RepeatAction extends Action $this->user = common_current_user(); if (empty($this->user)) { - $this->clientError(_("Only logged-in users can repeat notices.")); + $this->clientError(_('Only logged-in users can repeat notices.')); return false; } $id = $this->trimmed('notice'); if (empty($id)) { - $this->clientError(_("No notice specified.")); + $this->clientError(_('No notice specified.')); return false; } $this->notice = Notice::staticGet('id', $id); if (empty($this->notice)) { - $this->clientError(_("No notice specified.")); + $this->clientError(_('No notice specified.')); return false; } @@ -80,14 +80,14 @@ class RepeatAction extends Action $token = $this->trimmed('token-'.$id); if (empty($token) || $token != common_session_token()) { - $this->clientError(_("There was a problem with your session token. Try again, please.")); + $this->clientError(_('There was a problem with your session token. Try again, please.')); return false; } $profile = $this->user->getProfile(); if ($profile->hasRepeated($id)) { - $this->clientError(_("You already repeated that notice.")); + $this->clientError(_('You already repeated that notice.')); return false; } diff --git a/actions/replies.php b/actions/replies.php index 4ff1b7a8d2..608f71d6e0 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -90,7 +90,7 @@ class RepliesAction extends OwnerDesignAction if($this->page > 1 && $this->notice->N == 0){ // TRANS: Server error when page not found (404) - $this->serverError(_('No such page'),$code=404); + $this->serverError(_('No such page.'),$code=404); } return true; diff --git a/actions/revokerole.php b/actions/revokerole.php index b78c1c25a4..c67b70fdaf 100644 --- a/actions/revokerole.php +++ b/actions/revokerole.php @@ -59,11 +59,11 @@ class RevokeRoleAction extends ProfileFormAction $this->role = $this->arg('role'); if (!Profile_role::isValid($this->role)) { - $this->clientError(_("Invalid role.")); + $this->clientError(_('Invalid role.')); return false; } if (!Profile_role::isSettable($this->role)) { - $this->clientError(_("This role is reserved and cannot be set.")); + $this->clientError(_('This role is reserved and cannot be set.')); return false; } @@ -72,7 +72,7 @@ class RevokeRoleAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::REVOKEROLE)) { - $this->clientError(_("You cannot revoke user roles on this site.")); + $this->clientError(_('You cannot revoke user roles on this site.')); return false; } diff --git a/actions/sandbox.php b/actions/sandbox.php index 5b034ff078..d1ef4c86b2 100644 --- a/actions/sandbox.php +++ b/actions/sandbox.php @@ -62,14 +62,14 @@ class SandboxAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::SANDBOXUSER)) { - $this->clientError(_("You cannot sandbox users on this site.")); + $this->clientError(_('You cannot sandbox users on this site.')); return false; } assert(!empty($this->profile)); // checked by parent if ($this->profile->isSandboxed()) { - $this->clientError(_("User is already sandboxed.")); + $this->clientError(_('User is already sandboxed.')); return false; } diff --git a/actions/showfavorites.php b/actions/showfavorites.php index 5b85de6835..4d776ef04c 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -135,7 +135,7 @@ class ShowfavoritesAction extends OwnerDesignAction if($this->page > 1 && $this->notice->N == 0){ // TRANS: Server error when page not found (404) - $this->serverError(_('No such page'),$code=404); + $this->serverError(_('No such page.'),$code=404); } return true; diff --git a/actions/shownotice.php b/actions/shownotice.php index 12e1d77f80..77ba2ce9fd 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -97,7 +97,7 @@ class ShownoticeAction extends OwnerDesignAction $this->profile = $this->notice->getProfile(); if (empty($this->profile)) { - $this->serverError(_('Notice has no profile'), 500); + $this->serverError(_('Notice has no profile.'), 500); return false; } diff --git a/actions/silence.php b/actions/silence.php index 206e5ba878..09cc480d9e 100644 --- a/actions/silence.php +++ b/actions/silence.php @@ -62,14 +62,14 @@ class SilenceAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::SILENCEUSER)) { - $this->clientError(_("You cannot silence users on this site.")); + $this->clientError(_('You cannot silence users on this site.')); return false; } assert(!empty($this->profile)); // checked by parent if ($this->profile->isSilenced()) { - $this->clientError(_("User is already silenced.")); + $this->clientError(_('User is already silenced.')); return false; } diff --git a/actions/siteadminpanel.php b/actions/siteadminpanel.php index e5482987fb..4238b3e85a 100644 --- a/actions/siteadminpanel.php +++ b/actions/siteadminpanel.php @@ -130,7 +130,7 @@ class SiteadminpanelAction extends AdminPanelAction // Validate site name if (empty($values['site']['name'])) { - $this->clientError(_("Site name must have non-zero length.")); + $this->clientError(_('Site name must have non-zero length.')); } // Validate email @@ -168,7 +168,7 @@ class SiteadminpanelAction extends AdminPanelAction // Validate dupe limit if (!Validate::number($values['site']['dupelimit'], array('min' => 1))) { - $this->clientError(_("Dupe limit must 1 or more seconds.")); + $this->clientError(_("Dupe limit must be one or more seconds.")); } } diff --git a/actions/sitenoticeadminpanel.php b/actions/sitenoticeadminpanel.php index a68cc699ca..bdcaa23557 100644 --- a/actions/sitenoticeadminpanel.php +++ b/actions/sitenoticeadminpanel.php @@ -110,7 +110,7 @@ class SitenoticeadminpanelAction extends AdminPanelAction if (mb_strlen($siteNotice) > 255) { $this->clientError( - _('Max length for the site-wide notice is 255 chars') + _('Max length for the site-wide notice is 255 chars.') ); } diff --git a/actions/smssettings.php b/actions/smssettings.php index 751495d57a..6af1872a0e 100644 --- a/actions/smssettings.php +++ b/actions/smssettings.php @@ -55,6 +55,7 @@ class SmssettingsAction extends ConnectSettingsAction function title() { + // TRANS: Title for SMS settings. return _('SMS settings'); } @@ -66,6 +67,10 @@ class SmssettingsAction extends ConnectSettingsAction function getInstructions() { + // XXX: For consistency of parameters in messages, this should be a + // regular parameters, replaced with sprintf(). + // TRANS: SMS settings page instructions. + // TRANS: %%site.name%% is the name of the site. return _('You can receive SMS messages through email from %%site.name%%.'); } @@ -88,6 +93,7 @@ class SmssettingsAction extends ConnectSettingsAction { if (!common_config('sms', 'enabled')) { $this->element('div', array('class' => 'error'), + // TRANS: Message given in the SMS settings if SMS is not enabled on the site. _('SMS is not available.')); return; } @@ -101,7 +107,8 @@ class SmssettingsAction extends ConnectSettingsAction common_local_url('smssettings'))); $this->elementStart('fieldset', array('id' => 'settings_sms_address')); - $this->element('legend', null, _('Address')); + // TRANS: Form legend for SMS settings form. + $this->element('legend', null, _('SMS address')); $this->hidden('token', common_session_token()); if ($user->sms) { @@ -109,10 +116,12 @@ class SmssettingsAction extends ConnectSettingsAction $this->element('p', 'form_confirmed', $user->sms . ' (' . $carrier->name . ')'); $this->element('p', 'form_guide', + // TRANS: Form guide in SMS settings form. _('Current confirmed SMS-enabled phone number.')); $this->hidden('sms', $user->sms); $this->hidden('carrier', $user->carrier); - $this->submit('remove', _('Remove')); + // TRANS: Button label to remove a confirmed SMS address. + $this->submit('remove', _m('BUTTON','Remove')); } else { $confirm = $this->getConfirmation(); if ($confirm) { @@ -120,57 +129,75 @@ class SmssettingsAction extends ConnectSettingsAction $this->element('p', 'form_unconfirmed', $confirm->address . ' (' . $carrier->name . ')'); $this->element('p', 'form_guide', + // TRANS: Form guide in IM settings form. _('Awaiting confirmation on this phone number.')); $this->hidden('sms', $confirm->address); $this->hidden('carrier', $confirm->address_extra); - $this->submit('cancel', _('Cancel')); + // TRANS: Button label to cancel a SMS address confirmation procedure. + $this->submit('cancel', _m('BUTTON','Cancel')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label for SMS address input in SMS settings form. $this->input('code', _('Confirmation code'), null, + // TRANS: Form field instructions in SMS settings form. _('Enter the code you received on your phone.')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('confirm', _('Confirm')); + // TRANS: Button label to confirm SMS confirmation code in SMS settings. + $this->submit('confirm', _m('BUTTON','Confirm')); } else { $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label for SMS phone number input in SMS settings form. $this->input('sms', _('SMS phone number'), ($this->arg('sms')) ? $this->arg('sms') : null, + // TRANS: SMS phone number input field instructions in SMS settings form. _('Phone number, no punctuation or spaces, '. 'with area code')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->carrierSelect(); - $this->submit('add', _('Add')); + // TRANS: Button label for adding a SMS phone number in SMS settings form. + $this->submit('add', _m('BUTTON','Add')); } } $this->elementEnd('fieldset'); if ($user->sms) { $this->elementStart('fieldset', array('id' => 'settings_sms_incoming_email')); + // XXX: Confused! This is about SMS. Should this message be updated? + // TRANS: Form legend for incoming SMS settings form. $this->element('legend', null, _('Incoming email')); if ($user->incomingemail) { $this->element('p', 'form_unconfirmed', $user->incomingemail); $this->element('p', 'form_note', + // XXX: Confused! This is about SMS. Should this message be updated? + // TRANS: Form instructions for incoming SMS e-mail address form in SMS settings. _('Send email to this address to post new notices.')); - $this->submit('removeincoming', _('Remove')); + // TRANS: Button label for removing a set sender SMS e-mail address to post notices from. + $this->submit('removeincoming', _m('BUTTON','Remove')); } $this->element('p', 'form_guide', + // XXX: Confused! This is about SMS. Should this message be updated? + // TRANS: Instructions for incoming SMS e-mail address input form. _('Make a new email address for posting to; '. 'cancels the old one.')); - $this->submit('newincoming', _('New')); + // TRANS: Button label for adding an SMS e-mail address to send notices from. + $this->submit('newincoming', _m('BUTTON','New')); $this->elementEnd('fieldset'); } $this->elementStart('fieldset', array('id' => 'settings_sms_preferences')); - $this->element('legend', null, _('Preferences')); + // TRANS: Form legend for SMS preferences form. + $this->element('legend', null, _('SMS preferences')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->checkbox('smsnotify', + // TRANS: Checkbox label in SMS preferences form. _('Send me notices through SMS; '. 'I understand I may incur '. 'exorbitant charges from my carrier.'), @@ -178,7 +205,8 @@ class SmssettingsAction extends ConnectSettingsAction $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('save', _('Save')); + // TRANS: Button label to save SMS preferences. + $this->submit('save', _m('BUTTON','Save')); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -245,6 +273,7 @@ class SmssettingsAction extends ConnectSettingsAction } else if ($this->arg('confirm')) { $this->confirmCode(); } else { + // TRANS: Message given submitting a form with an unknown action in SMS settings. $this->showForm(_('Unexpected form submission.')); } } @@ -275,13 +304,15 @@ class SmssettingsAction extends ConnectSettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error updating SMS preferences. $this->serverError(_('Couldn\'t update user.')); return; } $user->query('COMMIT'); - $this->showForm(_('Preferences saved.'), true); + // TRANS: Confirmation message for successful SMS preferences save. + $this->showForm(_('SMS preferences saved.'), true); } /** @@ -303,11 +334,13 @@ class SmssettingsAction extends ConnectSettingsAction // Some validation if (!$sms) { + // TRANS: Message given saving SMS phone number without having provided one. $this->showForm(_('No phone number.')); return; } if (!$carrier_id) { + // TRANS: Message given saving SMS phone number without having selected a carrier. $this->showForm(_('No carrier selected.')); return; } @@ -315,9 +348,11 @@ class SmssettingsAction extends ConnectSettingsAction $sms = common_canonical_sms($sms); if ($user->sms == $sms) { + // TRANS: Message given saving SMS phone number that is already set. $this->showForm(_('That is already your phone number.')); return; } else if ($this->smsExists($sms)) { + // TRANS: Message given saving SMS phone number that is already set for another user. $this->showForm(_('That phone number already belongs to another user.')); return; } @@ -334,6 +369,7 @@ class SmssettingsAction extends ConnectSettingsAction if ($result === false) { common_log_db_error($confirm, 'INSERT', __FILE__); + // TRANS: Server error thrown on database error adding SMS confirmation code. $this->serverError(_('Couldn\'t insert confirmation code.')); return; } @@ -344,6 +380,7 @@ class SmssettingsAction extends ConnectSettingsAction $user->nickname, $carrier->toEmailAddress($sms)); + // TRANS: Message given saving valid SMS phone number that is to be confirmed. $msg = _('A confirmation code was sent to the phone number you added. '. 'Check your phone for the code and instructions '. 'on how to use it.'); @@ -367,10 +404,12 @@ class SmssettingsAction extends ConnectSettingsAction $confirm = $this->getConfirmation(); if (!$confirm) { + // TRANS: Message given canceling SMS phone number confirmation that is not pending. $this->showForm(_('No pending confirmation to cancel.')); return; } if ($confirm->address != $sms) { + // TRANS: Message given canceling SMS phone number confirmation for the wrong phone number. $this->showForm(_('That is the wrong confirmation number.')); return; } @@ -379,11 +418,13 @@ class SmssettingsAction extends ConnectSettingsAction if (!$result) { common_log_db_error($confirm, 'DELETE', __FILE__); + // TRANS: Server error thrown on database error canceling SMS phone number confirmation. $this->serverError(_('Couldn\'t delete email confirmation.')); return; } - $this->showForm(_('Confirmation cancelled.'), true); + // TRANS: Message given after successfully canceling SMS phone number confirmation. + $this->showForm(_('SMS confirmation cancelled.'), true); } /** @@ -402,6 +443,8 @@ class SmssettingsAction extends ConnectSettingsAction // Maybe an old tab open...? if ($user->sms != $sms) { + // TRANS: Message given trying to remove an SMS phone number that is not + // TRANS: registered for the active user. $this->showForm(_('That is not your phone number.')); return; } @@ -417,12 +460,14 @@ class SmssettingsAction extends ConnectSettingsAction $result = $user->updateKeys($original); if (!$result) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error thrown on database error removing a registered SMS phone number. $this->serverError(_('Couldn\'t update user.')); return; } $user->query('COMMIT'); - $this->showForm(_('The address was removed.'), true); + // TRANS: Message given after successfully removing a registered SMS phone number. + $this->showForm(_('The SMS phone number was removed.'), true); } /** @@ -462,10 +507,12 @@ class SmssettingsAction extends ConnectSettingsAction $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Label for mobile carrier dropdown menu in SMS settings. $this->element('label', array('for' => 'carrier'), _('Mobile carrier')); $this->elementStart('select', array('name' => 'carrier', 'id' => 'carrier')); $this->element('option', array('value' => 0), + // TRANS: Default option for mobile carrier dropdown menu in SMS settings. _('Select a carrier')); while ($carrier->fetch()) { $this->element('option', array('value' => $carrier->id), @@ -473,6 +520,8 @@ class SmssettingsAction extends ConnectSettingsAction } $this->elementEnd('select'); $this->element('p', 'form_guide', + // TRANS: Form instructions for mobile carrier dropdown menu in SMS settings. + // TRANS: %s is an administrative contact's e-mail address. sprintf(_('Mobile carrier for your phone. '. 'If you know a carrier that accepts ' . 'SMS over email but isn\'t listed here, ' . @@ -495,6 +544,7 @@ class SmssettingsAction extends ConnectSettingsAction $code = $this->trimmed('code'); if (!$code) { + // TRANS: Message given saving SMS phone number confirmation code without having provided one. $this->showForm(_('No code entered')); return; } diff --git a/actions/snapshotadminpanel.php b/actions/snapshotadminpanel.php index a0c2315bc1..be0a793e51 100644 --- a/actions/snapshotadminpanel.php +++ b/actions/snapshotadminpanel.php @@ -124,13 +124,13 @@ class SnapshotadminpanelAction extends AdminPanelAction // Validate snapshot run value if (!in_array($values['snapshot']['run'], array('web', 'cron', 'never'))) { - $this->clientError(_("Invalid snapshot run value.")); + $this->clientError(_('Invalid snapshot run value.')); } // Validate snapshot frequency value if (!Validate::number($values['snapshot']['frequency'])) { - $this->clientError(_("Snapshot frequency must be a number.")); + $this->clientError(_('Snapshot frequency must be a number.')); } // Validate report URL @@ -141,7 +141,7 @@ class SnapshotadminpanelAction extends AdminPanelAction array('allowed_schemes' => array('http', 'https') ) )) { - $this->clientError(_("Invalid snapshot report URL.")); + $this->clientError(_('Invalid snapshot report URL.')); } } } @@ -197,7 +197,7 @@ class SnapshotAdminPanelForm extends AdminForm $this->out->elementStart('ul', 'form_data'); $this->li(); $snapshot = array( - 'web' => _('Randomly during Web hit'), + 'web' => _('Randomly during web hit'), 'cron' => _('In a scheduled job'), 'never' => _('Never') ); diff --git a/actions/subscribers.php b/actions/subscribers.php index 6dda7312d6..2845a498e9 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -157,9 +157,13 @@ class SubscribersListItem extends SubscriptionListItem $user = common_current_user(); if (!empty($user) && $this->owner->id == $user->id) { - $bf = new BlockForm($this->out, $this->profile, - array('action' => 'subscribers', - 'nickname' => $this->owner->nickname)); + $returnto = array('action' => 'subscribers', + 'nickname' => $this->owner->nickname); + $page = $this->out->arg('page'); + if ($page) { + $returnto['param-page'] = $page; + } + $bf = new BlockForm($this->out, $this->profile, $returnto); $bf->show(); } } @@ -177,8 +181,12 @@ class SubscribersListItem extends SubscriptionListItem function homepageAttributes() { + $aAttrs = parent::linkAttributes(); + if (common_config('nofollow', 'subscribers')) { $aAttrs['rel'] = 'nofollow'; } + + return $aAttrs; } } diff --git a/actions/tag.php b/actions/tag.php index 512dac63a4..7c6f99d92b 100644 --- a/actions/tag.php +++ b/actions/tag.php @@ -49,7 +49,7 @@ class TagAction extends Action if($this->page > 1 && $this->notice->N == 0){ // TRANS: Server error when page not found (404) - $this->serverError(_('No such page'),$code=404); + $this->serverError(_('No such page.'),$code=404); } return true; diff --git a/actions/unsandbox.php b/actions/unsandbox.php index 22f4d8e766..d50b5072ee 100644 --- a/actions/unsandbox.php +++ b/actions/unsandbox.php @@ -62,14 +62,14 @@ class UnsandboxAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::SANDBOXUSER)) { - $this->clientError(_("You cannot sandbox users on this site.")); + $this->clientError(_('You cannot sandbox users on this site.')); return false; } assert(!empty($this->profile)); // checked by parent if (!$this->profile->isSandboxed()) { - $this->clientError(_("User is not sandboxed.")); + $this->clientError(_('User is not sandboxed.')); return false; } diff --git a/actions/unsilence.php b/actions/unsilence.php index 9ff1b828b0..7d282c3661 100644 --- a/actions/unsilence.php +++ b/actions/unsilence.php @@ -62,14 +62,14 @@ class UnsilenceAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::SILENCEUSER)) { - $this->clientError(_("You cannot silence users on this site.")); + $this->clientError(_('You cannot silence users on this site.')); return false; } assert(!empty($this->profile)); // checked by parent if (!$this->profile->isSilenced()) { - $this->clientError(_("User is not silenced.")); + $this->clientError(_('User is not silenced.')); return false; } diff --git a/actions/unsubscribe.php b/actions/unsubscribe.php index 6bb10d448b..57ca15d687 100644 --- a/actions/unsubscribe.php +++ b/actions/unsubscribe.php @@ -74,7 +74,7 @@ class UnsubscribeAction extends Action $other_id = $this->arg('unsubscribeto'); if (!$other_id) { - $this->clientError(_('No profile id in request.')); + $this->clientError(_('No profile ID in request.')); return; } diff --git a/actions/userauthorization.php b/actions/userauthorization.php index 7f71c60dbe..e896ff96ca 100644 --- a/actions/userauthorization.php +++ b/actions/userauthorization.php @@ -69,7 +69,7 @@ class UserauthorizationAction extends Action $profile = $user->getProfile(); if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); - $this->serverError(_('User without matching profile')); + $this->serverError(_('User without matching profile.')); return; } diff --git a/actions/usergroups.php b/actions/usergroups.php index 29bda0a765..6606e76cdb 100644 --- a/actions/usergroups.php +++ b/actions/usergroups.php @@ -59,8 +59,10 @@ class UsergroupsAction extends OwnerDesignAction function title() { if ($this->page == 1) { + // TRANS: Message is used as a page title. %s is a nick name. return sprintf(_('%s groups'), $this->user->nickname); } else { + // TRANS: Message is used as a page title. %1$s is a nick name, %2$d is a page number. return sprintf(_('%1$s groups, page %2$d'), $this->user->nickname, $this->page); diff --git a/actions/userrss.php b/actions/userrss.php index e03eb93566..b7078fcaf8 100644 --- a/actions/userrss.php +++ b/actions/userrss.php @@ -72,7 +72,7 @@ class UserrssAction extends Rss10Action { $notice = $this->user->getNotices( 0, - ($limit == 0) ? NOTICES_PER_PAGE : $limit + ($this->limit == 0) ? NOTICES_PER_PAGE : $this->limit ); $notices = array(); @@ -90,8 +90,10 @@ class UserrssAction extends Rss10Action $c = array('url' => common_local_url('userrss', array('nickname' => $user->nickname)), + // TRANS: Message is used as link title. %s is a user nickname. 'title' => sprintf(_('%s timeline'), $user->nickname), 'link' => $profile->profileurl, + // TRANS: Message is used as link description. %1$s is a username, %2$s is a site name. 'description' => sprintf(_('Updates from %1$s on %2$s!'), $user->nickname, common_config('site', 'name'))); return $c; @@ -103,7 +105,7 @@ class UserrssAction extends Rss10Action $profile = $user->getProfile(); if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); - $this->serverError(_('User without matching profile')); + $this->serverError(_('User without matching profile.')); return null; } $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); diff --git a/classes/Notice.php b/classes/Notice.php index be3e9ca2a6..d65f0da9a9 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -148,11 +148,11 @@ class Notice extends Memcached_DataObject //turn each into their canonical tag //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag for($i=0; $isaveTag($hashtag); self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, $hashtag); } @@ -172,7 +172,8 @@ class Notice extends Memcached_DataObject $id = $tag->insert(); if (!$id) { - throw new ServerException(sprintf(_('DB error inserting hashtag: %s'), + // TRANS: Server exception. %s are the error details. + throw new ServerException(sprintf(_('Database error inserting hashtag: %s'), $last_error->message)); return; } @@ -373,18 +374,20 @@ class Notice extends Memcached_DataObject $notice->saveReplies(); } - if (isset($groups)) { - $notice->saveKnownGroups($groups); - } else { - $notice->saveGroups(); - } - if (isset($tags)) { $notice->saveKnownTags($tags); } else { $notice->saveTags(); } + // Note: groups may save tags, so must be run after tags are saved + // to avoid errors on duplicates. + if (isset($groups)) { + $notice->saveKnownGroups($groups); + } else { + $notice->saveGroups(); + } + if (isset($urls)) { $notice->saveKnownUrls($urls); } else { @@ -699,6 +702,27 @@ class Notice extends Memcached_DataObject return $ids; } + /** + * Is this notice part of an active conversation? + * + * @return boolean true if other messages exist in the same + * conversation, false if this is the only one + */ + function hasConversation() + { + if (!empty($this->conversation)) { + $conversation = Notice::conversationStream( + $this->conversation, + 1, + 1 + ); + if ($conversation->N > 0) { + return true; + } + } + return false; + } + /** * @param $groups array of Group *objects* * @param $recipients array of profile *ids* @@ -964,11 +988,19 @@ class Notice extends Memcached_DataObject */ function saveKnownReplies($uris) { + if (empty($uris)) { + return; + } + $sender = Profile::staticGet($this->profile_id); + foreach ($uris as $uri) { $user = User::staticGet('uri', $uri); if (!empty($user)) { + if ($user->hasBlocked($sender)) { + continue; + } $reply = new Reply(); @@ -1478,6 +1510,8 @@ class Notice extends Memcached_DataObject { $author = Profile::staticGet('id', $this->profile_id); + // TRANS: Message used to repeat a notice. RT is the abbreviation of 'retweet'. + // TRANS: %1$s is the repeated user's name, %2$s is the repeated notice. $content = sprintf(_('RT @%1$s %2$s'), $author->nickname, $this->content); diff --git a/classes/User.php b/classes/User.php index bec05f8cfc..4626a7ca1e 100644 --- a/classes/User.php +++ b/classes/User.php @@ -543,7 +543,10 @@ class User extends Memcached_DataObject return false; } - Subscription::cancel($other, $this->getProfile()); + $self = $this->getProfile(); + if (Subscription::exists($other, $self)) { + Subscription::cancel($other, $self); + } $block->query('COMMIT'); diff --git a/index.php b/index.php index 6bfbc11da8..66a9838d65 100644 --- a/index.php +++ b/index.php @@ -37,8 +37,6 @@ define('INSTALLDIR', dirname(__FILE__)); define('STATUSNET', true); define('LACONICA', true); // compatibility -require_once INSTALLDIR . '/lib/common.php'; - $user = null; $action = null; @@ -68,52 +66,69 @@ function getPath($req) */ function handleError($error) { - if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { - return; - } + try { - $logmsg = "PEAR error: " . $error->getMessage(); - if (common_config('site', 'logdebug')) { - $logmsg .= " : ". $error->getDebugInfo(); - } - // DB queries often end up with a lot of newlines; merge to a single line - // for easier grepability... - $logmsg = str_replace("\n", " ", $logmsg); - common_log(LOG_ERR, $logmsg); - - // @fixme backtrace output should be consistent with exception handling - if (common_config('site', 'logdebug')) { - $bt = $error->getBacktrace(); - foreach ($bt as $n => $line) { - common_log(LOG_ERR, formatBacktraceLine($n, $line)); + if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { + return; } - } - if ($error instanceof DB_DataObject_Error - || $error instanceof DB_Error - ) { - $msg = sprintf( - _( - 'The database for %s isn\'t responding correctly, '. - 'so the site won\'t work properly. '. - 'The site admins probably know about the problem, '. - 'but you can contact them at %s to make sure. '. - 'Otherwise, wait a few minutes and try again.' - ), - common_config('site', 'name'), - common_config('site', 'email') - ); - } else { - $msg = _( - 'An important error occured, probably related to email setup. '. - 'Check logfiles for more info..' - ); - } - $dac = new DBErrorAction($msg, 500); - $dac->showPage(); + $logmsg = "PEAR error: " . $error->getMessage(); + if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) { + $logmsg .= " : ". $error->toText(); + } + // DB queries often end up with a lot of newlines; merge to a single line + // for easier grepability... + $logmsg = str_replace("\n", " ", $logmsg); + common_log(LOG_ERR, $logmsg); + + // @fixme backtrace output should be consistent with exception handling + if (common_config('site', 'logdebug')) { + $bt = $error->getTrace(); + foreach ($bt as $n => $line) { + common_log(LOG_ERR, formatBacktraceLine($n, $line)); + } + } + if ($error instanceof DB_DataObject_Error + || $error instanceof DB_Error + || ($error instanceof PEAR_Exception && $error->getCode() == -24) + ) { + //If we run into a DB error, assume we can't connect to the DB at all + //so set the current user to null, so we don't try to access the DB + //while rendering the error page. + global $_cur; + $_cur = null; + + $msg = sprintf( + _( + 'The database for %s isn\'t responding correctly, '. + 'so the site won\'t work properly. '. + 'The site admins probably know about the problem, '. + 'but you can contact them at %s to make sure. '. + 'Otherwise, wait a few minutes and try again.' + ), + common_config('site', 'name'), + common_config('site', 'email') + ); + } else { + $msg = _( + 'An important error occured, probably related to email setup. '. + 'Check logfiles for more info..' + ); + } + + $dac = new DBErrorAction($msg, 500); + $dac->showPage(); + + } catch (Exception $e) { + echo _('An error occurred.'); + } exit(-1); } +set_exception_handler('handleError'); + +require_once INSTALLDIR . '/lib/common.php'; + /** * Format a backtrace line for debug output roughly like debug_print_backtrace() does. * Exceptions already have this built in, but PEAR error objects just give us the array. @@ -238,10 +253,6 @@ function main() return; } - // For database errors - - PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError'); - // Make sure RW database is setup setupRW(); diff --git a/install.php b/install.php index 8a299f8975..08555d19b9 100644 --- a/install.php +++ b/install.php @@ -1,8 +1,7 @@ - 'gettext', - 'url'=>'http://us.php.net/manual/en/book.gettext.php', - 'check_function'=>'gettext' - ), - array( - 'name'=>'PEAR', - 'url'=>'http://pear.php.net/', - 'deb'=>'php-pear', - 'include'=>'PEAR.php', - 'check_class'=>'PEAR' - ), - array( - 'name'=>'DB', - 'pear'=>'DB', - 'url'=>'http://pear.php.net/package/DB', - 'deb'=>'php-db', - 'include'=>'DB/common.php', - 'check_class'=>'DB_common' - ), - array( - 'name'=>'DB_DataObject', - 'pear'=>'DB_DataObject', - 'url'=>'http://pear.php.net/package/DB_DataObject', - 'include'=>'DB/DataObject.php', - 'check_class'=>'DB_DataObject' - ), - array( - 'name'=>'Console_Getopt', - 'pear'=>'Console_Getopt', - 'url'=>'http://pear.php.net/package/Console_Getopt', - 'include'=>'Console/Getopt.php', - 'check_class'=>'Console_Getopt' - ), - array( - 'name'=>'Facebook API', - 'url'=>'http://developers.facebook.com/', - 'include'=>'facebook/facebook.php', - 'check_class'=>'Facebook' - ), - array( - 'name'=>'htmLawed', - 'url'=>'http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed', - 'include'=>'htmLawed/htmLawed.php', - 'check_function'=>'htmLawed' - ), - array( - 'name'=>'HTTP_Request', - 'pear'=>'HTTP_Request', - 'url'=>'http://pear.php.net/package/HTTP_Request', - 'deb'=>'php-http-request', - 'include'=>'HTTP/Request.php', - 'check_class'=>'HTTP_Request' - ), - array( - 'name'=>'HTTP_Request2', - 'pear'=>'HTTP_Request2', - 'url'=>'http://pear.php.net/package/HTTP_Request2', - 'include'=>'HTTP/Request2.php', - 'check_class'=>'HTTP_Request2' - ), - array( - 'name'=>'Mail', - 'pear'=>'Mail', - 'url'=>'http://pear.php.net/package/Mail', - 'deb'=>'php-mail', - 'include'=>'Mail.php', - 'check_class'=>'Mail' - ), - array( - 'name'=>'Mail_mimeDecode', - 'pear'=>'Mail_mimeDecode', - 'url'=>'http://pear.php.net/package/Mail_mimeDecode', - 'deb'=>'php-mail-mimedecode', - 'include'=>'Mail/mimeDecode.php', - 'check_class'=>'Mail_mimeDecode' - ), - array( - 'name'=>'Mime_Type', - 'pear'=>'Mime_Type', - 'url'=>'http://pear.php.net/package/Mime_Type', - 'include'=>'MIME/Type.php', - 'check_class'=>'Mime_Type' - ), - array( - 'name'=>'Net_URL_Mapper', - 'pear'=>'Net_URL_Mapper', - 'url'=>'http://pear.php.net/package/Net_URL_Mapper', - 'include'=>'Net/URL/Mapper.php', - 'check_class'=>'Net_URL_Mapper' - ), - array( - 'name'=>'Net_LDAP2', - 'pear'=>'Net_LDAP2', - 'url'=>'http://pear.php.net/package/Net_LDAP2', - 'deb'=>'php-net-ldap2', - 'include'=>'Net/LDAP2.php', - 'check_class'=>'Net_LDAP2' - ), - array( - 'name'=>'Net_Socket', - 'pear'=>'Net_Socket', - 'url'=>'http://pear.php.net/package/Net_Socket', - 'deb'=>'php-net-socket', - 'include'=>'Net/Socket.php', - 'check_class'=>'Net_Socket' - ), - array( - 'name'=>'Net_SMTP', - 'pear'=>'Net_SMTP', - 'url'=>'http://pear.php.net/package/Net_SMTP', - 'deb'=>'php-net-smtp', - 'include'=>'Net/SMTP.php', - 'check_class'=>'Net_SMTP' - ), - array( - 'name'=>'Net_URL', - 'pear'=>'Net_URL', - 'url'=>'http://pear.php.net/package/Net_URL', - 'deb'=>'php-net-url', - 'include'=>'Net/URL.php', - 'check_class'=>'Net_URL' - ), - array( - 'name'=>'Net_URL2', - 'pear'=>'Net_URL2', - 'url'=>'http://pear.php.net/package/Net_URL2', - 'include'=>'Net/URL2.php', - 'check_class'=>'Net_URL2' - ), - array( - 'name'=>'Services_oEmbed', - 'pear'=>'Services_oEmbed', - 'url'=>'http://pear.php.net/package/Services_oEmbed', - 'include'=>'Services/oEmbed.php', - 'check_class'=>'Services_oEmbed' - ), - array( - 'name'=>'Stomp', - 'url'=>'http://stomp.codehaus.org/PHP', - 'include'=>'Stomp.php', - 'check_class'=>'Stomp' - ), - array( - 'name'=>'System_Command', - 'pear'=>'System_Command', - 'url'=>'http://pear.php.net/package/System_Command', - 'include'=>'System/Command.php', - 'check_class'=>'System_Command' - ), - array( - 'name'=>'XMPPHP', - 'url'=>'http://code.google.com/p/xmpphp', - 'include'=>'XMPPHP/XMPP.php', - 'check_class'=>'XMPPHP_XMPP' - ), - array( - 'name'=>'PHP Markdown', - 'url'=>'http://www.michelf.com/projects/php-markdown/', - 'include'=>'markdown.php', - 'check_class'=>'Markdown_Parser' - ), - array( - 'name'=>'OAuth', - 'url'=>'http://code.google.com/p/oauth-php', - 'include'=>'OAuth.php', - 'check_class'=>'OAuthRequest' - ), - array( - 'name'=>'Validate', - 'pear'=>'Validate', - 'url'=>'http://pear.php.net/package/Validate', - 'include'=>'Validate.php', - 'check_class'=>'Validate' - ) -); -$dbModules = array( - 'mysql' => array( - 'name' => 'MySQL', - 'check_module' => 'mysql', // mysqli? - 'installer' => 'mysql_db_installer', - ), - 'pgsql' => array( - 'name' => 'PostgreSQL', - 'check_module' => 'pgsql', - 'installer' => 'pgsql_db_installer', - ), -); - -/** - * the actual installation. - * If call libraries are present, then install - * - * @return void - */ -function main() -{ - if (!checkPrereqs()) { - return; - } - - if (!empty($_GET['checklibs'])) { - showLibs(); - } else { - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - handlePost(); - } else { - showForm(); - } - } -} - -/** - * checks if an external libary is present - * - * @param string $external_library Name of library - * - * @return boolean indicates if library present - */ -function haveExternalLibrary($external_library) -{ - if (isset($external_library['include']) && !haveIncludeFile($external_library['include'])) { - return false; - } - if (isset($external_library['check_function']) && ! function_exists($external_library['check_function'])) { - return false; - } - if (isset($external_library['check_class']) && ! class_exists($external_library['check_class'])) { - return false; - } - return true; -} - -// Attempt to include a PHP file and report if it worked, while -// suppressing the annoying warning messages on failure. -function haveIncludeFile($filename) { - $old = error_reporting(error_reporting() & ~E_WARNING); - $ok = include_once($filename); - error_reporting($old); - return $ok; -} - -/** - * Check if all is ready for installation - * - * @return void - */ -function checkPrereqs() -{ - $pass = true; - - if (file_exists(INSTALLDIR.'/config.php')) { - printf('

Config file "config.php" already exists.

'); - $pass = false; - } - - if (version_compare(PHP_VERSION, '5.2.3', '<')) { - printf('

Require PHP version 5.2.3 or greater.

'); - $pass = false; - } - - // Look for known library bugs - $str = "abcdefghijklmnopqrstuvwxyz"; - $replaced = preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str); - if ($str != $replaced) { - printf('

PHP is linked to a version of the PCRE library ' . - 'that does not support Unicode properties. ' . - 'If you are running Red Hat Enterprise Linux / ' . - 'CentOS 5.4 or earlier, see our documentation page on fixing this.

'); - $pass = false; - } - - $reqs = array('gd', 'curl', - 'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml'); - - foreach ($reqs as $req) { - if (!checkExtension($req)) { - printf('

Cannot load required extension: %s

', $req); - $pass = false; - } - } - // Make sure we have at least one database module available - global $dbModules; - $missingExtensions = array(); - foreach ($dbModules as $type => $info) { - if (!checkExtension($info['check_module'])) { - $missingExtensions[] = $info['check_module']; - } - } - - if (count($missingExtensions) == count($dbModules)) { - $req = implode(', ', $missingExtensions); - printf('

Cannot find mysql or pgsql extension. You need one or the other.'); - $pass = false; - } - - if (!is_writable(INSTALLDIR)) { - printf('

Cannot write config file to: %s

', INSTALLDIR); - printf('

On your server, try this command: chmod a+w %s', INSTALLDIR); - $pass = false; - } - - // Check the subdirs used for file uploads - $fileSubdirs = array('avatar', 'background', 'file'); - foreach ($fileSubdirs as $fileSubdir) { - $fileFullPath = INSTALLDIR."/$fileSubdir/"; - if (!is_writable($fileFullPath)) { - printf('

Cannot write to %s directory: %s

', $fileSubdir, $fileFullPath); - printf('

On your server, try this command: chmod a+w %s

', $fileFullPath); - $pass = false; - } - } - - return $pass; -} - -/** - * Checks if a php extension is both installed and loaded - * - * @param string $name of extension to check - * - * @return boolean whether extension is installed and loaded - */ -function checkExtension($name) -{ - if (extension_loaded($name)) { - return true; - } elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) { - // dl will throw a fatal error if it's disabled or we're in safe mode. - // More fun, it may not even exist under some SAPIs in 5.3.0 or later... - $soname = $name . '.' . PHP_SHLIB_SUFFIX; - if (PHP_SHLIB_SUFFIX == 'dll') { - $soname = "php_" . $soname; - } - return @dl($soname); - } else { - return false; - } -} - -/** - * Show list of libraries - * - * @return void - */ -function showLibs() -{ - global $external_libraries; - $present_libraries=array(); - $absent_libraries=array(); - foreach ($external_libraries as $external_library) { - if (haveExternalLibrary($external_library)) { - $present_libraries[]=$external_library; - } else { - $absent_libraries[]=$external_library; - } - } - echo<< -

StatusNet comes bundled with a number of libraries required for the application to work. However, it is best that you use PEAR or you distribution to manage - libraries instead, as they tend to provide security updates faster, and may offer improved performance.

-

On Debian based distributions, such as Ubuntu, use a package manager (such as "aptitude", "apt-get", and "synaptic") to install the package listed.

-

On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as "yum", "apt-rpm", and "up2date") to install the package listed.

-

On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run "pear install <name>".

- -

Absent Libraries

-