diff --git a/EVENTS.txt b/EVENTS.txt index 1a329b9c0d..6cc1a7fe1c 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -1075,3 +1075,43 @@ StartCloseNoticeListItemElement: Before the closing of a notice list eleme EndCloseNoticeListItemElement: After the closing of a notice list element - $nli: The notice list item being shown + +StartGroupEditFormData: Beginning the group edit form entries +- $form: The form widget being shown + +EndGroupEditFormData: Ending the group edit form entries +- $form: The form widget being shown + +StartGroupSave: After initializing but before saving a group +- &$group: group about to be saved + +EndGroupSave: After saving a group, aliases, and first member +- $group: group that was saved + +StartInterpretCommand: Before running a command +- $cmd: First word in the string, 'foo' in 'foo argument' +- $arg: Argument, if any, like 'argument' in 'foo argument' +- $user: User who issued the command +- &$result: Resulting command; you can set this! + +EndInterpretCommand: Before running a command +- $cmd: First word in the string, 'foo' in 'foo argument' +- $arg: Argument, if any, like 'argument' in 'foo argument' +- $user: User who issued the command +- $result: Resulting command + +StartGroupActionsList: Start the list of actions on a group profile page (after , after last ) +- $action: action being executed (for output and params) +- $group: group for the page + +StartGroupProfileElements: Start showing stuff about the group on its profile page +- $action: action being executed (for output and params) +- $group: group for the page + +EndGroupProfileElements: Start showing stuff about the group on its profile page +- $action: action being executed (for output and params) +- $group: group for the page diff --git a/README b/README index a6db6d9c24..0dcbeea239 100644 --- a/README +++ b/README @@ -1283,7 +1283,7 @@ biolimit: max character length of bio; 0 means no limit; null means to use backup: whether users can backup their own profiles. Defaults to true. restore: whether users can restore their profiles from backup files. Defaults to true. -delete: whether users can delete their own accounts. Defaults to true. +delete: whether users can delete their own accounts. Defaults to false. move: whether users can move their accounts to another server. Defaults to true. @@ -1592,6 +1592,24 @@ proxy_user: Username to use for authenticating to the HTTP proxy. Default null. proxy_password: Password to use for authenticating to the HTTP proxy. Default null. proxy_auth_scheme: Scheme to use for authenticating to the HTTP proxy. Default null. +plugins +------- + +default: associative array mapping plugin name to array of arguments. To disable + a default plugin, unset its value in this array. +locale_path: path for finding plugin locale files. In the plugin's directory + by default. +server: Server to find static files for a plugin when the page is plain old HTTP. + Defaults to site/server (same as pages). Use this to move plugin CSS and + JS files to a CDN. +sslserver: Server to find static files for a plugin when the page is HTTPS. Defaults + to site/server (same as pages). Use this to move plugin CSS and JS files + to a CDN. +path: Path to the plugin files. defaults to site/path + '/plugins/'. Expects that + each plugin will have a subdirectory at plugins/NameOfPlugin. Change this + if you're using a CDN. +sslpath: Path to use on the SSL server. Same as plugins/path. + Plugins ======= diff --git a/actions/apiaccountupdatedeliverydevice.php b/actions/apiaccountupdatedeliverydevice.php index e7d44dc44d..a36806b216 100644 --- a/actions/apiaccountupdatedeliverydevice.php +++ b/actions/apiaccountupdatedeliverydevice.php @@ -149,7 +149,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction if ($this->format == 'xml') { $this->initDocument('xml'); - $this->showTwitterXmlUser($twitter_user); + $this->showTwitterXmlUser($twitter_user, 'user', true); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); diff --git a/actions/apiaccountupdateprofile.php b/actions/apiaccountupdateprofile.php index 163dac42d8..d0b9abe9b7 100644 --- a/actions/apiaccountupdateprofile.php +++ b/actions/apiaccountupdateprofile.php @@ -154,7 +154,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction if ($this->format == 'xml') { $this->initDocument('xml'); - $this->showTwitterXmlUser($twitter_user); + $this->showTwitterXmlUser($twitter_user, 'user', true); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); diff --git a/actions/apiaccountupdateprofilebackgroundimage.php b/actions/apiaccountupdateprofilebackgroundimage.php index badd8db002..f26c30198d 100644 --- a/actions/apiaccountupdateprofilebackgroundimage.php +++ b/actions/apiaccountupdateprofilebackgroundimage.php @@ -204,7 +204,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction if ($this->format == 'xml') { $this->initDocument('xml'); - $this->showTwitterXmlUser($twitter_user); + $this->showTwitterXmlUser($twitter_user, 'user', true); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); diff --git a/actions/apiaccountupdateprofilecolors.php b/actions/apiaccountupdateprofilecolors.php index 109fbf959e..4c102c4090 100644 --- a/actions/apiaccountupdateprofilecolors.php +++ b/actions/apiaccountupdateprofilecolors.php @@ -188,7 +188,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction if ($this->format == 'xml') { $this->initDocument('xml'); - $this->showTwitterXmlUser($twitter_user); + $this->showTwitterXmlUser($twitter_user, 'user', true); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); diff --git a/actions/apiaccountupdateprofileimage.php b/actions/apiaccountupdateprofileimage.php index f2886509d7..986a8f3f1e 100644 --- a/actions/apiaccountupdateprofileimage.php +++ b/actions/apiaccountupdateprofileimage.php @@ -112,16 +112,17 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction return; } + $type = $imagefile->preferredType(); $filename = Avatar::filename( $user->id, - image_type_to_extension($imagefile->type), + image_type_to_extension($type), null, 'tmp'.common_timestamp() ); $filepath = Avatar::path($filename); - move_uploaded_file($imagefile->filepath, $filepath); + $imagefile->copyTo($filepath); $profile = $this->user->getProfile(); @@ -139,7 +140,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction if ($this->format == 'xml') { $this->initDocument('xml'); - $this->showTwitterXmlUser($twitter_user); + $this->showTwitterXmlUser($twitter_user, 'user', true); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); diff --git a/actions/apiatomservice.php b/actions/apiatomservice.php index b60b312fc4..5d786723e9 100644 --- a/actions/apiatomservice.php +++ b/actions/apiatomservice.php @@ -39,7 +39,6 @@ require_once INSTALLDIR.'/lib/apibareauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 * @link http://status.net/ */ - class ApiAtomServiceAction extends ApiBareAuthAction { /** @@ -50,13 +49,13 @@ class ApiAtomServiceAction extends ApiBareAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); $this->user = $this->getTargetUser($this->arg('id')); if (empty($this->user)) { + // TRANS: Client error displayed when making an Atom API request for an unknown user. $this->clientError(_('No such user.'), 404, $this->format); return; } @@ -71,7 +70,6 @@ class ApiAtomServiceAction extends ApiBareAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -83,13 +81,15 @@ class ApiAtomServiceAction extends ApiBareAuthAction 'xmlns:atom' => 'http://www.w3.org/2005/Atom', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/')); $this->elementStart('workspace'); - $this->element('atom:title', null, _('Main')); + // TRANS: Title for Atom feed. + $this->element('atom:title', null, _m('ATOM','Main')); $this->elementStart('collection', array('href' => common_local_url('ApiTimelineUser', array('id' => $this->user->id, 'format' => 'atom')))); $this->element('atom:title', null, + // TRANS: Title for Atom feed. %s is a user nickname. sprintf(_("%s timeline"), $this->user->nickname)); $this->element('accept', null, 'application/atom+xml;type=entry'); @@ -100,6 +100,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction array('subscriber' => $this->user->id)))); $this->element('atom:title', null, + // TRANS: Title for Atom feed with a user's subscriptions. %s is a user nickname. sprintf(_("%s subscriptions"), $this->user->nickname)); $this->element('accept', null, 'application/atom+xml;type=entry'); @@ -110,6 +111,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction array('profile' => $this->user->id)))); $this->element('atom:title', null, + // TRANS: Title for Atom feed with a user's favorite notices. %s is a user nickname. sprintf(_("%s favorites"), $this->user->nickname)); $this->element('accept', null, 'application/atom+xml;type=entry'); @@ -120,6 +122,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction array('profile' => $this->user->id)))); $this->element('atom:title', null, + // TRANS: Title for Atom feed with a user's memberships. %s is a user nickname. sprintf(_("%s memberships"), $this->user->nickname)); $this->element('accept', null, 'application/atom+xml;type=entry'); diff --git a/actions/apiblockcreate.php b/actions/apiblockcreate.php index a9f31e791b..6942a53bb8 100644 --- a/actions/apiblockcreate.php +++ b/actions/apiblockcreate.php @@ -92,6 +92,7 @@ class ApiBlockCreateAction extends ApiAuthAction } if (empty($this->user) || empty($this->other)) { + // TRANS: Client error displayed when trying to block a non-existing user or a user from another site. $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apidirectmessagenew.php b/actions/apidirectmessagenew.php index 978c753532..e33077cdac 100644 --- a/actions/apidirectmessagenew.php +++ b/actions/apidirectmessagenew.php @@ -141,7 +141,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction } else if (!$this->user->mutuallySubscribed($this->other)) { $this->clientError( // TRANS: Client error displayed trying to direct message another user who's not a friend (403). - _('Can\'t send direct messages to users who aren\'t your friend.'), + _('Cannot send direct messages to users who aren\'t your friend.'), 403, $this->format ); diff --git a/actions/apigroupmembership.php b/actions/apigroupmembership.php index 99ac965fa1..939d22d757 100644 --- a/actions/apigroupmembership.php +++ b/actions/apigroupmembership.php @@ -66,6 +66,12 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction parent::prepare($args); $this->group = $this->getTargetGroup($this->arg('id')); + if (empty($this->group)) { + // TRANS: Client error displayed trying to show group membership on a non-existing group. + $this->clientError(_('Group not found.'), 404, $this->format); + return false; + } + $this->profiles = $this->getProfiles(); return true; @@ -84,12 +90,6 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction { parent::handle($args); - if (empty($this->group)) { - // TRANS: Client error displayed trying to show group membership on a non-existing group. - $this->clientError(_('Group not found.'), 404, $this->format); - return false; - } - // XXX: RSS and Atom switch($this->format) { diff --git a/actions/apioauthaccesstoken.php b/actions/apioauthaccesstoken.php index 064d05120f..76b06c28a2 100644 --- a/actions/apioauthaccesstoken.php +++ b/actions/apioauthaccesstoken.php @@ -84,6 +84,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction common_debug(var_export($req, true)); $code = $e->getCode(); $this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text'); + return; } if (empty($atok)) { @@ -98,7 +99,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction common_log(LOG_WARNING, $msg); // TRANS: Client error given from the OAuth API when the request token or verifier is invalid. - $this->clientError(_("Invalid request token or verifier.", 400, 'text')); + $this->clientError(_('Invalid request token or verifier.'), 400, 'text'); } else { common_log( LOG_INFO, diff --git a/actions/apistatusesshow.php b/actions/apistatusesshow.php index 80b0374a63..de4c4065c1 100644 --- a/actions/apistatusesshow.php +++ b/actions/apistatusesshow.php @@ -114,6 +114,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction $this->deleteNotice(); break; default: + // TRANS: Client error displayed calling an unsupported HTTP error in API status show. $this->clientError(_('HTTP method not supported.'), 405); return; } @@ -138,7 +139,9 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction $this->showSingleAtomStatus($this->notice); break; default: - throw new Exception(sprintf(_("Unsupported format: %s"), $this->format)); + // TRANS: Exception thrown requesting an unsupported notice output format. + // TRANS: %s is the requested output format. + throw new Exception(sprintf(_("Unsupported format: %s."), $this->format)); } } else { // XXX: Twitter just sets a 404 header and doens't bother @@ -171,7 +174,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction * * @return boolean true */ - + function isReadOnly($args) { return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD'); @@ -220,14 +223,16 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction function deleteNotice() { if ($this->format != 'atom') { - $this->clientError(_("Can only delete using the Atom format.")); + // TRANS: Client error displayed when trying to delete a notice not using the Atom format. + $this->clientError(_('Can only delete using the Atom format.')); return; } if (empty($this->auth_user) || ($this->notice->profile_id != $this->auth_user->id && !$this->auth_user->hasRight(Right::DELETEOTHERSNOTICE))) { - $this->clientError(_('Can\'t delete this notice.'), 403); + // TRANS: Client error displayed when a user has no rights to delete notices of other users. + $this->clientError(_('Cannot delete this notice.'), 403); return; } @@ -240,6 +245,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction header('HTTP/1.1 200 OK'); header('Content-Type: text/plain'); + // TRANS: Confirmation of notice deletion in API. %d is the ID (number) of the deleted notice. print(sprintf(_('Deleted notice %d'), $this->notice->id)); print("\n"); } diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index a8ec7f8bb9..5773bdc2e8 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -377,7 +377,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction function supported($cmd) { static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', - 'FavCommand', 'OnCommand', 'OffCommand'); + 'FavCommand', 'OnCommand', 'OffCommand', 'JoinCommand', 'LeaveCommand'); if (in_array(get_class($cmd), $cmdlist)) { return true; diff --git a/actions/apistatusnetconfig.php b/actions/apistatusnetconfig.php index 771a95baec..b34c6cc544 100644 --- a/actions/apistatusnetconfig.php +++ b/actions/apistatusnetconfig.php @@ -59,7 +59,8 @@ class ApiStatusnetConfigAction extends ApiAction 'notice' => array('contentlimit'), 'throttle' => array('enabled', 'count', 'timespan'), 'xmpp' => array('enabled', 'server', 'port', 'user'), - 'integration' => array('source') + 'integration' => array('source'), + 'attachments' => array('uploads', 'file_quota') ); /** @@ -96,7 +97,7 @@ class ApiStatusnetConfigAction extends ApiAction foreach ($this->keys as $section => $settings) { $this->elementStart($section); foreach ($settings as $setting) { - $value = common_config($section, $setting); + $value = $this->setting($section, $setting); if (is_array($value)) { $value = implode(',', $value); } else if ($value === false || $value == '0') { @@ -125,7 +126,7 @@ class ApiStatusnetConfigAction extends ApiAction $result[$section] = array(); foreach ($settings as $setting) { $result[$section][$setting] - = common_config($section, $setting); + = $this->setting($section, $setting); } } $this->initDocument('json'); @@ -143,6 +144,20 @@ class ApiStatusnetConfigAction extends ApiAction } } + function setting($section, $key) { + $result = common_config($section, $key); + if ($key == 'file_quota') { + // hack: adjust for the live upload limit + if (common_config($section, 'uploads')) { + $max = ImageFile::maxFileSizeInt(); + } else { + $max = 0; + } + return min($result, $max); + } + return $result; + } + /** * Return true if read only. * diff --git a/actions/apitimelinefavorites.php b/actions/apitimelinefavorites.php index c952c46238..36fc3089f5 100644 --- a/actions/apitimelinefavorites.php +++ b/actions/apitimelinefavorites.php @@ -169,6 +169,14 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link,'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); diff --git a/actions/apitimelinefriends.php b/actions/apitimelinefriends.php index 71049f6eb1..0e356bb18b 100644 --- a/actions/apitimelinefriends.php +++ b/actions/apitimelinefriends.php @@ -263,6 +263,14 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link,'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); diff --git a/actions/apitimelinegroup.php b/actions/apitimelinegroup.php index e1bc102e45..3fc930fa08 100644 --- a/actions/apitimelinegroup.php +++ b/actions/apitimelinegroup.php @@ -106,6 +106,11 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction $self = $this->getSelfUri(); + $link = common_local_url( + 'ApiTimelineGroup', + array('nickname' => $this->group->nickname) + ); + switch($this->format) { case 'xml': $this->showXmlTimeline($this->notices); @@ -123,24 +128,20 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction break; case 'atom': header('Content-Type: application/atom+xml; charset=utf-8'); - - try { $atom->addEntryFromNotices($this->notices); $this->raw($atom->getString()); - } catch (Atom10FeedException $e) { - $this->serverError( - // TRANS: Server error displayed when generating an Atom feed fails. - // TRANS: %s is the error. - sprintf(_('Could not generate feed for group - %s'),$e->getMessage()), - 400, - $this->format - ); - return; - } break; case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($atom->title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: $this->clientError( // TRANS: Client error displayed when trying to handle an unknown API method. diff --git a/actions/apitimelinehome.php b/actions/apitimelinehome.php index 75a9f72580..023c9698a1 100644 --- a/actions/apitimelinehome.php +++ b/actions/apitimelinehome.php @@ -168,6 +168,14 @@ class ApiTimelineHomeAction extends ApiBareAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); diff --git a/actions/apitimelinementions.php b/actions/apitimelinementions.php index a9b6d0b3df..2857bd41ea 100644 --- a/actions/apitimelinementions.php +++ b/actions/apitimelinementions.php @@ -169,6 +169,14 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); diff --git a/actions/apitimelinepublic.php b/actions/apitimelinepublic.php index 2745e5d3fe..353973b653 100644 --- a/actions/apitimelinepublic.php +++ b/actions/apitimelinepublic.php @@ -234,6 +234,14 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); diff --git a/actions/apitimelineretweetedtome.php b/actions/apitimelineretweetedtome.php index 6213a08eac..b9f9be1dda 100644 --- a/actions/apitimelineretweetedtome.php +++ b/actions/apitimelineretweetedtome.php @@ -92,6 +92,20 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction $offset = ($this->page-1) * $this->cnt; $limit = $this->cnt; + // TRANS: Title for Atom feed "repeated to me". %s is the user nickname. + $title = sprintf(_("Repeated to %s"), $this->auth_user->nickname); + $subtitle = sprintf( + _('%1$s notices that were to repeated to %2$s / %3$s.'), + $sitename, $this->user->nickname, $profile->getBestName() + ); + $taguribase = TagURI::base(); + $id = "tag:$taguribase:RepeatedToMe:" . $this->auth_user->id; + + $link = common_local_url( + 'all', + array('nickname' => $this->auth_user->nickname) + ); + $strm = $this->auth_user->repeatedToMe($offset, $limit, $this->since_id, $this->max_id); switch ($this->format) { @@ -102,16 +116,31 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction $this->showJsonTimeline($strm); break; case 'atom': - $profile = $this->auth_user->getProfile(); + header('Content-Type: application/atom+xml; charset=utf-8'); - // TRANS: Title for Atom feed "repeated to me". %s is the user nickname. - $title = sprintf(_("Repeated to %s"), $this->auth_user->nickname); - $taguribase = TagURI::base(); - $id = "tag:$taguribase:RepeatedToMe:" . $this->auth_user->id; - $link = common_local_url('all', - array('nickname' => $this->auth_user->nickname)); + $atom = new AtomNoticeFeed($this->auth_user); - $this->showAtomTimeline($strm, $title, $id, $link); + $atom->setId($id); + $atom->setTitle($title); + $atom->setSubtitle($subtitle); + $atom->setUpdated('now'); + $atom->addLink($link); + + $id = $this->arg('id'); + + $atom->setSelfLink($self); + $atom->addEntryFromNotices($strm); + + $this->raw($atom->getString()); + + break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($strm); + $this->raw($doc->asString()); break; default: // TRANS: Client error displayed when trying to handle an unknown API method. diff --git a/actions/apitimelineretweetsofme.php b/actions/apitimelineretweetsofme.php index 9cb277279f..aec6877f15 100644 --- a/actions/apitimelineretweetsofme.php +++ b/actions/apitimelineretweetsofme.php @@ -93,9 +93,27 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction $offset = ($this->page-1) * $this->cnt; $limit = $this->cnt; - $strm = $this->auth_user->repeatsOfMe($offset, $limit, $this->since_id, $this->max_id); + // TRANS: Title of list of repeated notices of the logged in user. + // TRANS: %s is the nickname of the logged in user. + $title = sprintf(_("Repeats of %s"), $this->auth_user->nickname); + $sitename = common_config('site', 'name'); - common_debug(var_export($strm, true)); + $profile = $this->auth_user->getProfile(); + + $subtitle = sprintf( + _('%1$s notices that %2$s / %3$s has repeated.'), + $sitename, $this->auth_user->nickname, $profile->getBestName() + ); + + $taguribase = TagURI::base(); + $id = "tag:$taguribase:RepeatsOfMe:" . $this->auth_user->id; + + $link = common_local_url( + 'all', + array('nickname' => $this->auth_user->nickname) + ); + + $strm = $this->auth_user->repeatsOfMe($offset, $limit, $this->since_id, $this->max_id); switch ($this->format) { case 'xml': @@ -105,49 +123,28 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction $this->showJsonTimeline($strm); break; case 'atom': - $profile = $this->auth_user->getProfile(); - - // TRANS: Title of list of repeated notices of the logged in user. - // TRANS: %s is the nickname of the logged in user. - $title = sprintf(_("Repeats of %s"), $this->auth_user->nickname); - $taguribase = TagURI::base(); - $id = "tag:$taguribase:RepeatsOfMe:" . $this->auth_user->id; - header('Content-Type: application/atom+xml; charset=utf-8'); - $atom = new AtomNoticeFeed($this->auth_user); - $atom->setId($id); $atom->setTitle($title); $atom->setSubtitle($subtitle); $atom->setUpdated('now'); - - $atom->addLink( - common_local_url( - 'showstream', - array('nickname' => $this->auth_user->nickname) - ) - ); - - $id = $this->arg('id'); - $aargs = array('format' => 'atom'); - if (!empty($id)) { - $aargs['id'] = $id; - } - - $atom->addLink( - $this->getSelfUri('ApiTimelineRetweetsOfMe', $aargs), - array('rel' => 'self', 'type' => 'application/atom+xml') - ); - + $atom->addLink($link); + $atom->setSelfLink($this->getSelfUri()); $atom->addEntryFromNotices($strm); - $this->raw($atom->getString()); - + break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($strm); + $this->raw($doc->asString()); break; default: // TRANS: Client error displayed when trying to handle an unknown API method. - $this->clientError(_('API method not found.'), $code = 404); + $this->clientError(_('API method not found.'), 404); break; } } diff --git a/actions/apitimelinetag.php b/actions/apitimelinetag.php index 4dbe1fc0db..5fa76d0cd0 100644 --- a/actions/apitimelinetag.php +++ b/actions/apitimelinetag.php @@ -107,7 +107,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction $sitename ); $taguribase = TagURI::base(); - $id = "tag:$taguribase:TagTimeline:".$tag; + $id = "tag:$taguribase:TagTimeline:".$this->tag; $link = common_local_url( 'tag', @@ -116,8 +116,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction $self = $this->getSelfUri(); - common_debug("self link is: $self"); - switch($this->format) { case 'xml': $this->showXmlTimeline($this->notices); @@ -154,6 +152,14 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); diff --git a/actions/apitimelineuser.php b/actions/apitimelineuser.php index 5809df3b5e..66984b5abd 100644 --- a/actions/apitimelineuser.php +++ b/actions/apitimelineuser.php @@ -201,6 +201,17 @@ class ApiTimelineUserAction extends ApiBareAuthAction case 'json': $this->showJsonTimeline($this->notices); break; + case 'as': + header('Content-Type: application/json; charset=utf-8'); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($atom->title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + + // XXX: Add paging extension? + + $this->raw($doc->asString()); + break; default: // TRANS: Client error displayed when trying to handle an unknown API method. $this->clientError(_('API method not found.'), $code = 404); @@ -241,7 +252,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction * * @return boolean true */ - + function isReadOnly($args) { return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD'); @@ -307,11 +318,13 @@ class ApiTimelineUserAction extends ApiBareAuthAction $xml = trim(file_get_contents('php://input')); if (empty($xml)) { + // TRANS: Client error displayed attempting to post an empty API notice. $this->clientError(_('Atom post must not be empty.')); } $dom = DOMDocument::loadXML($xml); if (!$dom) { + // TRANS: Client error displayed attempting to post an API that is not well-formed XML. $this->clientError(_('Atom post must be well-formed XML.')); } @@ -327,10 +340,8 @@ class ApiTimelineUserAction extends ApiBareAuthAction $saved = null; if (Event::handle('StartAtomPubNewActivity', array(&$activity, $this->user, &$saved))) { - if ($activity->verb != ActivityVerb::POST) { - // TRANS: Client error displayed when not using the POST verb. - // TRANS: Do not translate POST. + // TRANS: Client error displayed when not using the POST verb. Do not translate POST. $this->clientError(_('Can only handle POST activities.')); return; } @@ -375,6 +386,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction } else { // @fixme fetch from $sourceUrl? // TRANS: Client error displayed when posting a notice without content through the API. + // TRANS: %d is the notice ID (number). $this->clientError(sprintf(_('No content for notice %d.'), $note->id)); return; @@ -403,6 +415,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction if (!empty($notice)) { // TRANS: Client error displayed when using another format than AtomPub. + // TRANS: %s is the notice URI. $this->clientError(sprintf(_('Notice with URI "%s" already exists.'), $note->id)); return; @@ -427,14 +440,14 @@ class ApiTimelineUserAction extends ApiBareAuthAction $profile = Profile::fromURI($uri); if (!empty($profile)) { - $options['replies'] = $uri; + $options['replies'][] = $uri; } else { $group = User_group::staticGet('uri', $uri); if (!empty($group)) { - $options['groups'] = $uri; + $options['groups'][] = $uri; } else { // @fixme: hook for discovery here - common_log(LOG_WARNING, sprintf(_('AtomPub post with unknown attention URI %s'), $uri)); + common_log(LOG_WARNING, sprintf('AtomPub post with unknown attention URI %s', $uri)); } } } diff --git a/actions/atompubfavoritefeed.php b/actions/atompubfavoritefeed.php index 478a01b7c6..c31fcbd72a 100644 --- a/actions/atompubfavoritefeed.php +++ b/actions/atompubfavoritefeed.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Feed of ActivityStreams 'favorite' actions - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class AtompubfavoritefeedAction extends ApiAuthAction { private $_profile = null; @@ -59,7 +58,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -67,7 +65,8 @@ class AtompubfavoritefeedAction extends ApiAuthAction $this->_profile = Profile::staticGet('id', $this->trimmed('profile')); if (empty($this->_profile)) { - throw new ClientException(_('No such profile'), 404); + // TRANS: Client exception thrown when requesting a favorite feed for a non-existing profile. + throw new ClientException(_('No such profile.'), 404); } $offset = ($this->page-1) * $this->count; @@ -76,7 +75,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction $this->_faves = Fave::byProfile($this->_profile->id, $offset, $limit); - + return true; } @@ -87,7 +86,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -101,6 +99,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction $this->addFavorite(); break; default: + // TRANS: Client exception thrown when using an unsupported HTTP method. throw new ClientException(_('HTTP method not supported.'), 405); return; } @@ -113,7 +112,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return void */ - function showFeed() { header('Content-Type: application/atom+xml; charset=utf-8'); @@ -139,21 +137,25 @@ class AtompubfavoritefeedAction extends ApiAuthAction $feed->addAuthor($this->_profile->getBestName(), $this->_profile->getURI()); + // TRANS: Title for Atom favorites feed. + // TRANS: %s is a user nickname. $feed->setTitle(sprintf(_("%s favorites"), $this->_profile->getBestName())); - $feed->setSubtitle(sprintf(_("Notices %s has favorited to on %s"), + // TRANS: Subtitle for Atom favorites feed. + // TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename. + $feed->setSubtitle(sprintf(_('Notices %1$s has favorited on %2$s'), $this->_profile->getBestName(), common_config('site', 'name'))); $feed->addLink(common_local_url('showfavorites', - array('nickname' => + array('nickname' => $this->_profile->nickname))); $feed->addLink($url, array('rel' => 'self', 'type' => 'application/atom+xml')); - + // If there's more... if ($this->page > 1) { @@ -162,9 +164,9 @@ class AtompubfavoritefeedAction extends ApiAuthAction 'type' => 'application/atom+xml')); $feed->addLink(common_local_url('AtomPubFavoriteFeed', - array('profile' => + array('profile' => $this->_profile->id), - array('page' => + array('page' => $this->page - 1)), array('rel' => 'prev', 'type' => 'application/atom+xml')); @@ -205,17 +207,17 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return void */ - function addFavorite() { // XXX: Refactor this; all the same for atompub if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { - throw new ClientException(_("Can't add someone else's". - " subscription"), 403); + // TRANS: Client exception thrown when trying to set a favorite for another user. + throw new ClientException(_("Cannot add someone else's". + " subscription."), 403); } - + $xml = file_get_contents('php://input'); $dom = DOMDocument::loadXML($xml); @@ -234,9 +236,8 @@ class AtompubfavoritefeedAction extends ApiAuthAction if (Event::handle('StartAtomPubNewActivity', array(&$activity))) { if ($activity->verb != ActivityVerb::FAVORITE) { - // TRANS: Client error displayed when not using the POST verb. - // TRANS: Do not translate POST. - throw new ClientException(_('Can only handle Favorite activities.')); + // TRANS: Client exception thrown when trying use an incorrect activity verb for the Atom pub method. + throw new ClientException(_('Can only handle favorite activities.')); return; } @@ -245,6 +246,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction if (!in_array($note->type, array(ActivityObject::NOTE, ActivityObject::BLOGENTRY, ActivityObject::STATUS))) { + // TRANS: Client exception thrown when trying favorite an object that is not a notice. throw new ClientException(_('Can only fave notices.')); return; } @@ -253,6 +255,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction if (empty($notice)) { // XXX: import from listed URL or something + // TRANS: Client exception thrown when trying favorite a notice without content. throw new ClientException(_('Unknown note.')); } @@ -260,6 +263,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction 'notice_id' => $notice->id)); if (!empty($old)) { + // TRANS: Client exception thrown when trying favorite an already favorited notice. throw new ClientException(_('Already a favorite.')); } @@ -296,7 +300,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return boolean is read only action? */ - function isReadOnly($args) { if ($_SERVER['REQUEST_METHOD'] == 'GET' || @@ -328,7 +331,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return string etag http header */ - function etag() { return null; @@ -339,7 +341,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return boolean true if delete, else false */ - function requiresAuth() { if ($_SERVER['REQUEST_METHOD'] == 'GET' || @@ -359,7 +360,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction * * @return void */ - function notify($fave, $notice, $user) { $other = User::staticGet('id', $notice->profile_id); diff --git a/actions/atompubmembershipfeed.php b/actions/atompubmembershipfeed.php index 3002576c15..b52583314d 100644 --- a/actions/atompubmembershipfeed.php +++ b/actions/atompubmembershipfeed.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Feed of group memberships for a user, in ActivityStreams format - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class AtompubmembershipfeedAction extends ApiAuthAction { private $_profile = null; @@ -59,7 +58,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -67,8 +65,9 @@ class AtompubmembershipfeedAction extends ApiAuthAction $profileId = $this->trimmed('profile'); $this->_profile = Profile::staticGet('id', $profileId); - + if (empty($this->_profile)) { + // TRANS: Client exception. throw new ClientException(_('No such profile.'), 404); } @@ -78,7 +77,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction $this->_memberships = Group_member::byMember($this->_profile->id, $offset, $limit); - + return true; } @@ -89,7 +88,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -103,6 +101,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction $this->addMembership(); break; default: + // TRANS: Client exception thrown when using an unsupported HTTP method. throw new ClientException(_('HTTP method not supported.'), 405); return; } @@ -115,7 +114,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return void */ - function showFeed() { header('Content-Type: application/atom+xml; charset=utf-8'); @@ -141,21 +139,25 @@ class AtompubmembershipfeedAction extends ApiAuthAction $feed->addAuthor($this->_profile->getBestName(), $this->_profile->getURI()); + // TRANS: Title for group membership feed. + // TRANS: %s is a username. $feed->setTitle(sprintf(_("%s group memberships"), $this->_profile->getBestName())); - $feed->setSubtitle(sprintf(_("Groups %s is a member of on %s"), + // TRANS: Subtitle for group membership feed. + // TRANS: %1$s is a username, %2$s is the StatusNet sitename. + $feed->setSubtitle(sprintf(_('Groups %1$s is a member of on %2$s'), $this->_profile->getBestName(), common_config('site', 'name'))); $feed->addLink(common_local_url('usergroups', - array('nickname' => + array('nickname' => $this->_profile->nickname))); $feed->addLink($url, array('rel' => 'self', 'type' => 'application/atom+xml')); - + // If there's more... if ($this->page > 1) { @@ -164,9 +166,9 @@ class AtompubmembershipfeedAction extends ApiAuthAction 'type' => 'application/atom+xml')); $feed->addLink(common_local_url('AtomPubMembershipFeed', - array('profile' => + array('profile' => $this->_profile->id), - array('page' => + array('page' => $this->page - 1)), array('rel' => 'prev', 'type' => 'application/atom+xml')); @@ -207,17 +209,17 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return void */ - function addMembership() { // XXX: Refactor this; all the same for atompub if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { - throw new ClientException(_("Can't add someone else's". - " membership"), 403); + // TRANS: Client exception thrown when trying subscribe someone else to a group. + throw new ClientException(_("Cannot add someone else's". + " membership."), 403); } - + $xml = file_get_contents('php://input'); $dom = DOMDocument::loadXML($xml); @@ -234,25 +236,26 @@ class AtompubmembershipfeedAction extends ApiAuthAction $membership = null; if (Event::handle('StartAtomPubNewActivity', array(&$activity))) { - if ($activity->verb != ActivityVerb::JOIN) { // TRANS: Client error displayed when not using the POST verb. // TRANS: Do not translate POST. - throw new ClientException(_('Can only handle Join activities.')); + throw new ClientException(_('Can only handle join activities.')); return; } $groupObj = $activity->objects[0]; if ($groupObj->type != ActivityObject::GROUP) { + // TRANS: Client exception thrown when trying favorite an object that is not a notice. throw new ClientException(_('Can only fave notices.')); return; } $group = User_group::staticGet('uri', $groupObj->id); - + if (empty($group)) { // XXX: import from listed URL or something + // TRANS: Client exception thrown when trying to subscribe to a non-existing group. throw new ClientException(_('Unknown group.')); } @@ -260,6 +263,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction 'group_id' => $group->id)); if (!empty($old)) { + // TRANS: Client exception thrown when trying to subscribe to an already subscribed group. throw new ClientException(_('Already a member.')); } @@ -267,6 +271,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction if (Group_block::isBlocked($group, $profile)) { // XXX: import from listed URL or something + // TRANS: Client exception thrown when trying to subscribe to group while blocked from that group. throw new ClientException(_('Blocked by admin.')); } @@ -299,7 +304,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return boolean is read only action? */ - function isReadOnly($args) { if ($_SERVER['REQUEST_METHOD'] == 'GET' || @@ -331,7 +335,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return string etag http header */ - function etag() { return null; @@ -342,7 +345,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction * * @return boolean true if delete, else false */ - function requiresAuth() { if ($_SERVER['REQUEST_METHOD'] == 'GET' || diff --git a/actions/atompubshowfavorite.php b/actions/atompubshowfavorite.php index 5fe680bb7b..1727e0c3cf 100644 --- a/actions/atompubshowfavorite.php +++ b/actions/atompubshowfavorite.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Show a single favorite in Atom Activity Streams format - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class AtompubshowfavoriteAction extends ApiAuthAction { private $_profile = null; @@ -62,7 +61,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -73,12 +71,14 @@ class AtompubshowfavoriteAction extends ApiAuthAction $this->_profile = Profile::staticGet('id', $profileId); if (empty($this->_profile)) { + // TRANS: Client exception. throw new ClientException(_('No such profile.'), 404); } $this->_notice = Notice::staticGet('id', $noticeId); if (empty($this->_notice)) { + // TRANS: Client exception thrown when referencing a non-existing notice. throw new ClientException(_('No such notice.'), 404); } @@ -86,6 +86,7 @@ class AtompubshowfavoriteAction extends ApiAuthAction 'notice_id' => $noticeId)); if (empty($this->_fave)) { + // TRANS: Client exception thrown when referencing a non-existing favorite. throw new ClientException(_('No such favorite.'), 404); } @@ -99,7 +100,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -113,6 +113,7 @@ class AtompubshowfavoriteAction extends ApiAuthAction $this->deleteFave(); break; default: + // TRANS: Client exception thrown using an unsupported HTTP method. throw new ClientException(_('HTTP method not supported.'), 405); } @@ -121,10 +122,9 @@ class AtompubshowfavoriteAction extends ApiAuthAction /** * Show a single favorite, in ActivityStreams format - * + * * @return void */ - function showFave() { $activity = $this->_fave->asActivity(); @@ -140,16 +140,16 @@ class AtompubshowfavoriteAction extends ApiAuthAction /** * Delete the favorite - * + * * @return void */ - function deleteFave() { if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { - throw new ClientException(_("Can't delete someone else's". - " favorite"), 403); + // TRANS: Client exception thrown when trying to remove a favorite notice of another user. + throw new ClientException(_("Cannot delete someone else's". + " favorite."), 403); } $this->_fave->delete(); @@ -166,7 +166,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction * * @return boolean is read only action? */ - function isReadOnly($args) { if ($_SERVER['REQUEST_METHOD'] == 'GET' || @@ -184,7 +183,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction * * @return string last modified http header */ - function lastModified() { return max(strtotime($this->_profile->modified), @@ -199,7 +197,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction * * @return string etag http header */ - function etag() { $mtime = strtotime($this->_fave->modified); @@ -215,7 +212,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction * * @return boolean true if delete, else false */ - function requiresAuth() { if ($_SERVER['REQUEST_METHOD'] == 'GET' || diff --git a/actions/atompubshowmembership.php b/actions/atompubshowmembership.php index 6d848a2290..098cca8b3e 100644 --- a/actions/atompubshowmembership.php +++ b/actions/atompubshowmembership.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Show a single membership as an Activity Streams entry - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class AtompubshowmembershipAction extends ApiAuthAction { private $_profile = null; @@ -60,7 +59,6 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -68,8 +66,9 @@ class AtompubshowmembershipAction extends ApiAuthAction $profileId = $this->trimmed('profile'); $this->_profile = Profile::staticGet('id', $profileId); - + if (empty($this->_profile)) { + // TRANS: Client exception. throw new ClientException(_('No such profile.'), 404); } @@ -78,7 +77,8 @@ class AtompubshowmembershipAction extends ApiAuthAction $this->_group = User_group::staticGet('id', $groupId); if (empty($this->_group)) { - throw new ClientException(_('No such group'), 404); + // TRANS: Client exception thrown when referencing a non-existing group. + throw new ClientException(_('No such group.'), 404); } $kv = array('group_id' => $groupId, @@ -87,7 +87,8 @@ class AtompubshowmembershipAction extends ApiAuthAction $this->_membership = Group_member::pkeyGet($kv); if (empty($this->_membership)) { - throw new ClientException(_('Not a member'), 404); + // TRANS: Client exception thrown when trying to show membership of a non-subscribed group + throw new ClientException(_('Not a member.'), 404); } return true; @@ -100,7 +101,6 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return void */ - function handle($argarray=null) { switch ($_SERVER['REQUEST_METHOD']) { @@ -112,7 +112,8 @@ class AtompubshowmembershipAction extends ApiAuthAction $this->deleteMembership(); break; default: - throw new ClientException(_('Method not supported'), 405); + // TRANS: Client exception thrown when using an unsupported HTTP method. + throw new ClientException(_('HTTP method not supported.'), 405); break; } return; @@ -123,7 +124,6 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return void */ - function showMembership() { $activity = $this->_membership->asActivity(); @@ -142,13 +142,13 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return void */ - function deleteMembership() { if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { - throw new ClientException(_("Can't delete someone else's". - " membership"), 403); + // TRANS: Client exception thrown when deleting someone else's membership. + throw new ClientException(_("Cannot delete someone else's". + " membership."), 403); } if (Event::handle('StartLeaveGroup', array($this->_group, $this->auth_user))) { @@ -168,7 +168,6 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return boolean is read only action? */ - function isReadOnly($args) { if ($_SERVER['REQUEST_METHOD'] == 'GET' || @@ -203,7 +202,6 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return string etag http header */ - function etag() { $ctime = strtotime($this->_membership->created); @@ -222,7 +220,6 @@ class AtompubshowmembershipAction extends ApiAuthAction * * @return boolean true if delete, else false */ - function requiresAuth() { if ($_SERVER['REQUEST_METHOD'] == 'GET' || diff --git a/actions/atompubshowsubscription.php b/actions/atompubshowsubscription.php index 55ba68adc5..aeff0cbf2a 100644 --- a/actions/atompubshowsubscription.php +++ b/actions/atompubshowsubscription.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Single subscription - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -46,21 +46,19 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class AtompubshowsubscriptionAction extends ApiAuthAction { private $_subscriber = null; private $_subscribed = null; private $_subscription = null; - /** + /** * For initializing members of the class. * * @param array $argarray misc. arguments * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -69,7 +67,9 @@ class AtompubshowsubscriptionAction extends ApiAuthAction $this->_subscriber = Profile::staticGet('id', $subscriberId); if (empty($this->_subscriber)) { - throw new ClientException(sprintf(_('No such profile id: %d'), + // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. + // TRANS: %d is the non-existing profile ID number. + throw new ClientException(sprintf(_('No such profile id: %d.'), $subscriberId), 404); } @@ -78,16 +78,20 @@ class AtompubshowsubscriptionAction extends ApiAuthAction $this->_subscribed = Profile::staticGet('id', $subscribedId); if (empty($this->_subscribed)) { - throw new ClientException(sprintf(_('No such profile id: %d'), + // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. + // TRANS: %d is the non-existing profile ID number. + throw new ClientException(sprintf(_('No such profile id: %d.'), $subscribedId), 404); } - $this->_subscription = + $this->_subscription = Subscription::pkeyGet(array('subscriber' => $subscriberId, 'subscribed' => $subscribedId)); if (empty($this->_subscription)) { - $msg = sprintf(_('Profile %d not subscribed to profile %d'), + // TRANS: Client exception thrown when trying to display a subscription for a non-subscribed profile ID. + // TRANS: %1$d is the non-existing subscriber ID number, $2$d is the ID of the profile that was not subscribed to. + $msg = sprintf(_('Profile %1$d not subscribed to profile %2$d.'), $subscriberId, $subscribedId); throw new ClientException($msg, 404); } @@ -102,7 +106,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -115,6 +118,7 @@ class AtompubshowsubscriptionAction extends ApiAuthAction $this->deleteSubscription(); break; default: + // TRANS: Client error shown when using a non-supported HTTP method. $this->clientError(_('HTTP method not supported.'), 405); return; } @@ -127,7 +131,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return void */ - function showSubscription() { $activity = $this->_subscription->asActivity(); @@ -146,13 +149,13 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return void */ - function deleteSubscription() { if (empty($this->auth_user) || $this->auth_user->id != $this->_subscriber->id) { - throw new ClientException(_("Can't delete someone else's". - " subscription"), 403); + // TRANS: Client exception thrown when trying to delete a subscription of another user. + throw new ClientException(_("Cannot delete someone else's ". + "subscription."), 403); } Subscription::cancel($this->_subscriber, @@ -168,7 +171,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return boolean true */ - function isReadOnly($args) { if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { @@ -183,7 +185,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return string last modified http header */ - function lastModified() { return max(strtotime($this->_subscriber->modified), @@ -196,7 +197,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return string etag http header */ - function etag() { $mtime = strtotime($this->_subscription->modified); @@ -212,7 +212,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction * * @return boolean true if delete, else false */ - function requiresAuth() { if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { diff --git a/actions/atompubsubscriptionfeed.php b/actions/atompubsubscriptionfeed.php index 15ae79f6a6..26740da835 100644 --- a/actions/atompubsubscriptionfeed.php +++ b/actions/atompubsubscriptionfeed.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * AtomPub subscription feed - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -40,7 +40,7 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * Subscription feed class for AtomPub * * Generates a list of the user's subscriptions - * + * * @category AtomPub * @package StatusNet * @author Evan Prodromou @@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class AtompubsubscriptionfeedAction extends ApiAuthAction { private $_profile = null; @@ -61,17 +60,18 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); - + $subscriber = $this->trimmed('subscriber'); $this->_profile = Profile::staticGet('id', $subscriber); if (empty($this->_profile)) { - throw new ClientException(sprintf(_('No such profile id: %d'), + // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. + // TRANS: %d is the non-existing profile ID number. + throw new ClientException(sprintf(_('No such profile id: %d.'), $subscriber), 404); } @@ -93,7 +93,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -106,6 +105,7 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction $this->addSubscription(); break; default: + // TRANS: Client exception thrown when using an unsupported HTTP method. $this->clientError(_('HTTP method not supported.'), 405); return; } @@ -118,7 +118,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return void */ - function showFeed() { header('Content-Type: application/atom+xml; charset=utf-8'); @@ -144,21 +143,25 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction $feed->addAuthor($this->_profile->getBestName(), $this->_profile->getURI()); + // TRANS: Title for Atom subscription feed. + // TRANS: %s is a user nickname. $feed->setTitle(sprintf(_("%s subscriptions"), $this->_profile->getBestName())); - $feed->setSubtitle(sprintf(_("People %s has subscribed to on %s"), + // TRANS: Subtitle for Atom subscription feed. + // TRANS: %1$s is a user nickname, %s$s is the StatusNet sitename. + $feed->setSubtitle(sprintf(_("People %1\$s has subscribed to on %2\$s"), $this->_profile->getBestName(), common_config('site', 'name'))); $feed->addLink(common_local_url('subscriptions', - array('nickname' => + array('nickname' => $this->_profile->nickname))); $feed->addLink($url, array('rel' => 'self', 'type' => 'application/atom+xml')); - + // If there's more... if ($this->page > 1) { @@ -167,9 +170,9 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction 'type' => 'application/atom+xml')); $feed->addLink(common_local_url('AtomPubSubscriptionFeed', - array('subscriber' => + array('subscriber' => $this->_profile->id), - array('page' => + array('page' => $this->page - 1)), array('rel' => 'prev', 'type' => 'application/atom+xml')); @@ -214,15 +217,15 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return void */ - function addSubscription() { if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { - throw new ClientException(_("Can't add someone else's". - " subscription"), 403); + // TRANS: Client exception thrown when trying to subscribe another user. + throw new ClientException(_("Cannot add someone else's". + " subscription."), 403); } - + $xml = file_get_contents('php://input'); $dom = DOMDocument::loadXML($xml); @@ -241,8 +244,7 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction if (Event::handle('StartAtomPubNewActivity', array(&$activity))) { if ($activity->verb != ActivityVerb::FOLLOW) { - // TRANS: Client error displayed when not using the POST verb. - // TRANS: Do not translate POST. + // TRANS: Client error displayed when not using the follow verb. $this->clientError(_('Can only handle Follow activities.')); return; } @@ -250,6 +252,7 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction $person = $activity->objects[0]; if ($person->type != ActivityObject::PERSON) { + // TRANS: Client exception thrown when subscribing to an object that is not a person. $this->clientError(_('Can only follow people.')); return; } @@ -259,7 +262,19 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction $profile = Profile::fromURI($person->id); if (empty($profile)) { - $this->clientError(sprintf(_('Unknown profile %s'), $person->id)); + // TRANS: Client exception thrown when subscribing to a non-existing profile. + // TRANS: %s is the unknown profile ID. + $this->clientError(sprintf(_('Unknown profile %s.'), $person->id)); + return; + } + + if (Subscription::exists($this->_profile, $profile)) { + // 409 Conflict + // TRANS: Client error displayed trying to subscribe to an already subscribed profile. + // TRANS: %s is the profile the user already has a subscription on. + $this->clientError(sprintf(_('Already subscribed to %s.'), + $person->id), + 409); return; } @@ -290,7 +305,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return boolean is read only action? */ - function isReadOnly($args) { return $_SERVER['REQUEST_METHOD'] != 'POST'; @@ -301,7 +315,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return string last modified http header */ - function lastModified() { return null; @@ -312,7 +325,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return string etag http header */ - function etag() { return null; @@ -323,7 +335,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction * * @return boolean true if delete, else false */ - function requiresAuth() { if ($_SERVER['REQUEST_METHOD'] == 'POST') { diff --git a/actions/avatarsettings.php b/actions/avatarsettings.php index 7b671d9e32..d9542a39c8 100644 --- a/actions/avatarsettings.php +++ b/actions/avatarsettings.php @@ -157,13 +157,13 @@ class AvatarsettingsAction extends SettingsAction } $this->elementStart('li', array ('id' => 'settings_attach')); - $this->element('input', array('name' => 'avatarfile', - 'type' => 'file', - 'id' => 'avatarfile')); $this->element('input', array('name' => 'MAX_FILE_SIZE', 'type' => 'hidden', 'id' => 'MAX_FILE_SIZE', 'value' => ImageFile::maxFileSizeInt())); + $this->element('input', array('name' => 'avatarfile', + 'type' => 'file', + 'id' => 'avatarfile')); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -211,7 +211,7 @@ class AvatarsettingsAction extends SettingsAction array('id' => 'avatar_original', 'class' => 'avatar_view')); // TRANS: Header on avatar upload crop form for thumbnail of originally uploaded avatar (h2). - $this->element('h2', null, _("Original")); + $this->element('h2', null, _('Original')); $this->elementStart('div', array('id'=>'avatar_original_view')); $this->element('img', array('src' => Avatar::url($this->filedata['filename']), 'width' => $this->filedata['width'], @@ -224,7 +224,7 @@ class AvatarsettingsAction extends SettingsAction array('id' => 'avatar_preview', 'class' => 'avatar_view')); // TRANS: Header on avatar upload crop form for thumbnail of to be used rendition of uploaded avatar (h2). - $this->element('h2', null, _("Preview")); + $this->element('h2', null, _('Preview')); $this->elementStart('div', array('id'=>'avatar_preview_view')); $this->element('img', array('src' => Avatar::url($this->filedata['filename']), 'width' => AVATAR_PROFILE_SIZE, @@ -320,21 +320,20 @@ class AvatarsettingsAction extends SettingsAction } $cur = common_current_user(); - + $type = $imagefile->preferredType(); $filename = Avatar::filename($cur->id, - image_type_to_extension($imagefile->type), + image_type_to_extension($type), null, 'tmp'.common_timestamp()); $filepath = Avatar::path($filename); - - move_uploaded_file($imagefile->filepath, $filepath); + $imagefile->copyTo($filepath); $filedata = array('filename' => $filename, 'filepath' => $filepath, 'width' => $imagefile->width, 'height' => $imagefile->height, - 'type' => $imagefile->type); + 'type' => $type); $_SESSION['FILEDATA'] = $filedata; @@ -342,8 +341,8 @@ class AvatarsettingsAction extends SettingsAction $this->mode = 'crop'; - // TRANS: Avatar upload form unstruction after uploading a file. - $this->showForm(_('Pick a square area of the image to be your avatar'), + // TRANS: Avatar upload form instruction after uploading a file. + $this->showForm(_('Pick a square area of the image to be your avatar.'), true); } diff --git a/actions/backupaccount.php b/actions/backupaccount.php index 4f6fb936bd..8f642f3b77 100644 --- a/actions/backupaccount.php +++ b/actions/backupaccount.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Download a backup of your own account to the browser - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -48,18 +48,17 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class BackupaccountAction extends Action { /** * Returns the title of the page - * + * * @return string page title */ - function title() { - return _("Backup account"); + // TRANS: Title for backup account page. + return _('Backup account'); } /** @@ -69,7 +68,6 @@ class BackupaccountAction extends Action * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -77,10 +75,12 @@ class BackupaccountAction extends Action $cur = common_current_user(); if (empty($cur)) { + // TRANS: Client exception thrown when trying to backup an account while not logged in. throw new ClientException(_('Only logged-in users can backup their account.'), 403); } if (!$cur->hasRight(Right::BACKUPACCOUNT)) { + // TRANS: Client exception thrown when trying to backup an account without having backup rights. throw new ClientException(_('You may not backup your account.'), 403); } @@ -94,7 +94,6 @@ class BackupaccountAction extends Action * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -109,7 +108,7 @@ class BackupaccountAction extends Action /** * Send a feed of the user's activities to the browser - * + * * Uses the UserActivityStream class; may take a long time! * * @return void @@ -118,12 +117,14 @@ class BackupaccountAction extends Action function sendFeed() { $cur = common_current_user(); - - $stream = new UserActivityStream($cur); + + $stream = new UserActivityStream($cur, true, UserActivityStream::OUTPUT_RAW); header('Content-Disposition: attachment; filename='.$cur->nickname.'.atom'); header('Content-Type: application/atom+xml; charset=utf-8'); + // @fixme atom feed logic is in getString... + // but we just want it to output to the outputter. $this->raw($stream->getString()); } @@ -132,13 +133,13 @@ class BackupaccountAction extends Action * * @return void */ - + function showContent() { $form = new BackupAccountForm($this); $form->show(); } - + /** * Return true if read only. * @@ -148,10 +149,9 @@ class BackupaccountAction extends Action * * @return boolean is read only action? */ - function isReadOnly($args) { - return false; + return true; } /** @@ -161,7 +161,6 @@ class BackupaccountAction extends Action * * @return string last modified http header */ - function lastModified() { // For comparison with If-Last-Modified @@ -176,7 +175,6 @@ class BackupaccountAction extends Action * * @return string etag http header */ - function etag() { return null; @@ -193,7 +191,6 @@ class BackupaccountAction extends Action * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class BackupAccountForm extends Form { /** @@ -201,7 +198,6 @@ class BackupAccountForm extends Form * * @return string the form's class */ - function formClass() { return 'form_profile_backup'; @@ -212,7 +208,6 @@ class BackupAccountForm extends Form * * @return string the form's action URL */ - function action() { return common_local_url('backupaccount'); @@ -220,18 +215,18 @@ class BackupAccountForm extends Form /** * Output form data - * + * * Really, just instructions for doing a backup. * * @return void */ - function formData() { $msg = + // TRANS: Information displayed on the backup account page. _('You can backup your account data in '. 'Activity Streams '. - 'format. This is an experimental feature and provides an '. + 'format. This is an experimental feature and provides an '. 'incomplete backup; private account '. 'information like email and IM addresses is not backed up. '. 'Additionally, uploaded files and direct messages are not '. @@ -243,18 +238,19 @@ class BackupAccountForm extends Form /** * Buttons for the form - * + * * In this case, a single submit button * * @return void */ - function formActions() { $this->out->submit('submit', + // TRANS: Submit button to backup an account on the backup account page. _m('BUTTON', 'Backup'), 'submit', null, - _('Backup your account')); + // TRANS: Title for submit button to backup an account on the backup account page. + _('Backup your account.')); } } diff --git a/actions/block.php b/actions/block.php index e87353b4e1..f195fb5a88 100644 --- a/actions/block.php +++ b/actions/block.php @@ -155,14 +155,14 @@ class BlockAction extends ProfileFormAction 'submit form_action-primary', 'no', // TRANS: Submit button title for 'No' when blocking a user. - _('Do not block this 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')); + _('Block this user.')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/deleteaccount.php b/actions/deleteaccount.php index 9abe2fcdb6..614519d474 100644 --- a/actions/deleteaccount.php +++ b/actions/deleteaccount.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Delete your own account - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -36,7 +36,7 @@ if (!defined('STATUSNET')) { /** * Action to delete your own account - * + * * Note that this is distinct from DeleteuserAction, which see. I thought * that making that action do both things (delete another user and delete the * current user) would open a lot of holes. I'm open to refactoring, however. @@ -48,7 +48,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class DeleteaccountAction extends Action { private $_complete = false; @@ -61,19 +60,20 @@ class DeleteaccountAction extends Action * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); - + $cur = common_current_user(); if (empty($cur)) { + // TRANS: Client exception displayed trying to delete a user account while not logged in. throw new ClientException(_("Only logged-in users ". "can delete their account."), 403); } if (!$cur->hasRight(Right::DELETEACCOUNT)) { + // TRANS: Client exception displayed trying to delete a user account without have the rights to do that. throw new ClientException(_("You cannot delete your account."), 403); } @@ -87,7 +87,6 @@ class DeleteaccountAction extends Action * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -109,7 +108,6 @@ class DeleteaccountAction extends Action * * @return boolean is read only action? */ - function isReadOnly($args) { return false; @@ -122,7 +120,6 @@ class DeleteaccountAction extends Action * * @return string last modified http header */ - function lastModified() { // For comparison with If-Last-Modified @@ -137,7 +134,6 @@ class DeleteaccountAction extends Action * * @return string etag http header */ - function etag() { return null; @@ -145,7 +141,7 @@ class DeleteaccountAction extends Action /** * Delete the current user's account - * + * * Checks for the "I am sure." string to make sure the user really * wants to delete their account. * @@ -156,13 +152,16 @@ class DeleteaccountAction extends Action * * @return void */ - function deleteAccount() { $this->checkSessionToken(); - - if ($this->trimmed('iamsure') != _('I am sure.')) { - $this->_error = _('You must write "I am sure." exactly in the box.'); + // !!! If this string is changed, it also needs to be changed in DeleteAccountForm::formData() + // TRANS: Confirmation text for user deletion. The user has to type this exactly the same, including punctuation. + $iamsure = _('I am sure.'); + if ($this->trimmed('iamsure') != $iamsure ) { + // TRANS: Notification for user about the text that must be input to be able to delete a user account. + // TRANS: %s is the text that needs to be input. + $this->_error = sprintf(_('You must write "%s" exactly in the box.'), $iamsure); $this->showPage(); return; } @@ -191,7 +190,7 @@ class DeleteaccountAction extends Action /** * Shows the page content. - * + * * If the deletion is complete, just shows a completion message. * * Otherwise, shows the deletion form. @@ -199,11 +198,11 @@ class DeleteaccountAction extends Action * @return void * */ - function showContent() { if ($this->_complete) { - $this->element('p', 'confirmation', + $this->element('p', 'confirmation', + // TRANS: Confirmation that a user account has been deleted. _('Account deleted.')); return; } @@ -216,7 +215,7 @@ class DeleteaccountAction extends Action $form = new DeleteAccountForm($this); $form->show(); } - + /** * Show the title of the page * @@ -225,13 +224,14 @@ class DeleteaccountAction extends Action function title() { + // TRANS: Page title for page on which a user account can be deleted. return _('Delete account'); } } /** * Form for deleting your account - * + * * Note that this mostly is here to keep you from accidentally deleting your * account. * @@ -242,7 +242,6 @@ class DeleteaccountAction extends Action * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class DeleteAccountForm extends Form { /** @@ -250,7 +249,6 @@ class DeleteAccountForm extends Form * * @return string the form's class */ - function formClass() { return 'form_profile_delete'; @@ -261,7 +259,6 @@ class DeleteAccountForm extends Form * * @return string the form's action URL */ - function action() { return common_local_url('deleteaccount'); @@ -269,51 +266,60 @@ class DeleteAccountForm extends Form /** * Output form data - * + * * Instructions plus an 'i am sure' entry box. * * @return void */ - function formData() { $cur = common_current_user(); - $msg = _('

This will permanently delete '. - 'your account data from this server.

'); + // TRANS: Form text for user deletion form. + $msg = '

' . _('This will permanently delete '. + 'your account data from this server.') . '

'; if ($cur->hasRight(Right::BACKUPACCOUNT)) { - $msg .= sprintf(_('

You are strongly advised to '. + // TRANS: Additional form text for user deletion form shown if a user has account backup rights. + // TRANS: %s is a URL to the backup page. + $msg .= '

' . sprintf(_('You are strongly advised to '. 'back up your data'. - ' before deletion.

'), - common_local_url('backupaccount')); + ' before deletion.'), + common_local_url('backupaccount')) . '

'; } $this->out->elementStart('p'); $this->out->raw($msg); $this->out->elementEnd('p'); + // !!! If this string is changed, it also needs to be changed in class DeleteaccountAction. + // TRANS: Confirmation text for user deletion. The user has to type this exactly the same, including punctuation. + $iamsure = _("I am sure."); $this->out->input('iamsure', + // TRANS: Field label for delete account confirmation entry. _('Confirm'), null, - _('Enter "I am sure." to confirm that '. - 'you want to delete your account.')); + // TRANS: Input title for the delete account field. + // TRANS: %s is the text that needs to be input. + sprintf(_('Enter "%s" to confirm that '. + 'you want to delete your account.'),$iamsure )); } /** * Buttons for the form - * + * * In this case, a single submit button * * @return void */ - function formActions() { $this->out->submit('submit', + // TRANS: Button text for user account deletion. _m('BUTTON', 'Delete'), 'submit', null, - _('Permanently your account')); + // TRANS: Button title for user account deletion. + _('Permanently delete your account')); } } diff --git a/actions/deleteapplication.php b/actions/deleteapplication.php index 272a91762c..9f9ac18971 100644 --- a/actions/deleteapplication.php +++ b/actions/deleteapplication.php @@ -158,13 +158,13 @@ class DeleteapplicationAction extends Action 'submit form_action-primary', 'no', // TRANS: Submit button title for 'No' when deleting an application. - _('Do not delete this application')); + _('Do not delete this application.')); $this->submit('form_action-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')); + 'yes', _('Delete this application.')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/deletegroup.php b/actions/deletegroup.php index 4e9b9851f1..637a7cba73 100644 --- a/actions/deletegroup.php +++ b/actions/deletegroup.php @@ -221,14 +221,14 @@ class DeletegroupAction extends RedirectingAction 'submit form_action-primary', 'no', // TRANS: Submit button title for 'No' when deleting a group. - _('Do not delete this group')); + _('Do not delete this group.')); $this->submit('form_action-yes', // TRANS: Button label on the delete group form. _m('BUTTON','Yes'), 'submit form_action-secondary', 'yes', // TRANS: Submit button title for 'Yes' when deleting a group. - _('Delete this group')); + _('Delete this group.')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/deletenotice.php b/actions/deletenotice.php index a7ac28e19c..c997bb756a 100644 --- a/actions/deletenotice.php +++ b/actions/deletenotice.php @@ -75,7 +75,7 @@ class DeletenoticeAction extends Action if ($this->notice->profile_id != $this->user_profile->id && !$this->user->hasRight(Right::DELETEOTHERSNOTICE)) { // TRANS: Error message displayed trying to delete a notice that was not made by the current user. - common_user_error(_('Can\'t delete this notice.')); + common_user_error(_('Cannot delete this notice.')); exit; } // XXX: Ajax! @@ -156,14 +156,14 @@ class DeletenoticeAction extends Action 'submit form_action-primary', 'no', // TRANS: Submit button title for 'No' when deleting a notice. - _("Do not delete this 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')); + _('Delete this notice.')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/deleteuser.php b/actions/deleteuser.php index 02ded68b31..19b1e20e83 100644 --- a/actions/deleteuser.php +++ b/actions/deleteuser.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class DeleteuserAction extends ProfileFormAction { var $user = null; @@ -52,7 +51,6 @@ class DeleteuserAction extends ProfileFormAction * * @return boolean success flag */ - function prepare($args) { if (!parent::prepare($args)) { @@ -64,6 +62,7 @@ class DeleteuserAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::DELETEUSER)) { + // TRANS: Client error displayed when trying to delete a user without having the right to delete users. $this->clientError(_('You cannot delete users.')); return false; } @@ -71,6 +70,7 @@ class DeleteuserAction extends ProfileFormAction $this->user = User::staticGet('id', $this->profile->id); if (empty($this->user)) { + // TRANS: Client error displayed when trying to delete a non-local user. $this->clientError(_('You can only delete local users.')); return false; } @@ -87,7 +87,6 @@ class DeleteuserAction extends ProfileFormAction * * @return void */ - function handle($args) { if ($_SERVER['REQUEST_METHOD'] == 'POST') { @@ -107,7 +106,8 @@ class DeleteuserAction extends ProfileFormAction } function title() { - return _('Delete user'); + // TRANS: Title of delete user page. + return _m('TITLE','Delete user'); } function showNoticeForm() { @@ -130,9 +130,11 @@ class DeleteuserAction extends ProfileFormAction 'action' => common_local_url('deleteuser'))); $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); + // TRANS: Fieldset legend on delete user page. $this->element('legend', _('Delete user')); if (Event::handle('StartDeleteUserForm', array($this, $this->user))) { $this->element('p', null, + // TRANS: Information text to request if a user is certain that the described action has to be performed. _('Are you sure you want to delete this user? '. 'This will clear all data about the user from the '. 'database, without a backup.')); @@ -153,14 +155,14 @@ class DeleteuserAction extends ProfileFormAction 'submit form_action-primary', 'no', // TRANS: Submit button title for 'No' when deleting a user. - _('Do not block this user')); + _('Do not delete 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')); + _('Delete this user.')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -170,7 +172,6 @@ class DeleteuserAction extends ProfileFormAction * * @return void */ - function handlePost() { if (Event::handle('StartDeleteUser', array($this, $this->user))) { diff --git a/actions/designadminpanel.php b/actions/designadminpanel.php index 321a8ee5eb..a77b842fe3 100644 --- a/actions/designadminpanel.php +++ b/actions/designadminpanel.php @@ -44,10 +44,8 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class DesignadminpanelAction extends AdminPanelAction { - /* The default site design */ var $design = null; @@ -56,7 +54,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return string page title */ - function title() { // TRANS: Message used as title for design settings for the site. @@ -68,9 +65,9 @@ class DesignadminpanelAction extends AdminPanelAction * * @return string instructions */ - function getInstructions() { + // TRANS: Instructions for design adminsitration panel. return _('Design settings for this StatusNet site'); } @@ -79,7 +76,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return void */ - function showForm() { $this->design = Design::siteDesign(); @@ -93,7 +89,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return void */ - function saveSettings() { if ($this->arg('save')) { @@ -101,6 +96,7 @@ class DesignadminpanelAction extends AdminPanelAction } else if ($this->arg('defaults')) { $this->restoreDefaults(); } else { + // TRANS: Client error displayed when the submitted form contains unexpected data. $this->clientError(_('Unexpected form submission.')); } } @@ -110,7 +106,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return void */ - function saveDesignSettings() { // Workaround for PHP returning empty $_POST and $_FILES when POST @@ -225,11 +220,10 @@ class DesignadminpanelAction extends AdminPanelAction } /** - * Restore the default design - * - * @return void - */ - + * Restore the default design + * + * @return void + */ function restoreDefaults() { $this->deleteSetting('site', 'logo'); @@ -257,7 +251,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return string $filename the filename of the image */ - function saveBackgroundImage() { $filename = null; @@ -302,7 +295,6 @@ class DesignadminpanelAction extends AdminPanelAction * @throws ClientException for invalid theme archives * @throws ServerException if trouble saving the theme files */ - function saveCustomTheme() { if (common_config('theme_upload', 'enabled') && @@ -327,21 +319,24 @@ class DesignadminpanelAction extends AdminPanelAction * * @return void */ - function validate(&$values) { if (!empty($values['logo']) && !Validate::uri($values['logo'], array('allowed_schemes' => array('http', 'https')))) { + // TRANS: Client error displayed when a logo URL does is not valid. $this->clientError(_('Invalid logo URL.')); } if (!empty($values['ssllogo']) && !Validate::uri($values['ssllogo'], array('allowed_schemes' => array('https')))) { + // TRANS: Client error displayed when an SSL logo URL is invalid. $this->clientError(_('Invalid SSL logo URL.')); } if (!in_array($values['theme'], Theme::listAvailable())) { - $this->clientError(sprintf(_("Theme not available: %s."), $values['theme'])); + // TRANS: Client error displayed when a theme is submitted through the form that is not in the theme list. + // TRANS: %s is the chosen unavailable theme. + $this->clientError(sprintf(_('Theme not available: %s.'), $values['theme'])); } } @@ -350,7 +345,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return void */ - function showStylesheets() { parent::showStylesheets(); @@ -362,7 +356,6 @@ class DesignadminpanelAction extends AdminPanelAction * * @return void */ - function showScripts() { parent::showScripts(); @@ -383,7 +376,6 @@ class DesignAdminPanelForm extends AdminForm * * @return int ID of the form */ - function id() { return 'form_design_admin_panel'; @@ -394,7 +386,6 @@ class DesignAdminPanelForm extends AdminForm * * @return string class of the form */ - function formClass() { return 'form_settings'; @@ -408,7 +399,6 @@ class DesignAdminPanelForm extends AdminForm * * @return string the method to use for submitting */ - function method() { $this->enctype = 'multipart/form-data'; @@ -421,7 +411,6 @@ class DesignAdminPanelForm extends AdminForm * * @return string URL of the action */ - function action() { return common_local_url('designadminpanel'); @@ -432,7 +421,6 @@ class DesignAdminPanelForm extends AdminForm * * @return void */ - function formData() { $this->showLogo(); @@ -445,16 +433,25 @@ class DesignAdminPanelForm extends AdminForm function showLogo() { $this->out->elementStart('fieldset', array('id' => 'settings_design_logo')); + // TRANS: Fieldset legend for form to change logo. $this->out->element('legend', null, _('Change logo')); $this->out->elementStart('ul', 'form_data'); $this->li(); - $this->input('logo', _('Site logo'), 'Logo for the site (full URL)'); + $this->input('logo', + // TRANS: Field label for StatusNet site logo. + _('Site logo'), + // TRANS: Title for field label for StatusNet site logo. + 'Logo for the site (full URL).'); $this->unli(); $this->li(); - $this->input('ssllogo', _('SSL logo'), 'Logo to show on SSL pages'); + $this->input('ssllogo', + // TRANS: Field label for SSL StatusNet site logo. + _('SSL logo'), + // TRANS: Title for field label for SSL StatusNet site logo. + 'Logo to show on SSL pages.'); $this->unli(); $this->out->elementEnd('ul'); @@ -466,6 +463,7 @@ class DesignAdminPanelForm extends AdminForm function showTheme() { $this->out->elementStart('fieldset', array('id' => 'settings_design_theme')); + // TRANS: Fieldset legend for form change StatusNet site's theme. $this->out->element('legend', null, _('Change theme')); $this->out->elementStart('ul', 'form_data'); @@ -483,17 +481,21 @@ class DesignAdminPanelForm extends AdminForm $themes = array_combine($themes, $themes); $this->li(); + // TRANS: Field label for dropdown to choose site theme. $this->out->dropdown('theme', _('Site theme'), + // TRANS: Title for field label for dropdown to choose site theme. $themes, _('Theme for the site.'), false, $this->value('theme')); $this->unli(); if (common_config('theme_upload', 'enabled')) { $this->li(); + // TRANS: Field label for uploading a cutom theme. $this->out->element('label', array('for' => 'design_upload_theme'), _('Custom theme')); $this->out->element('input', array('id' => 'design_upload_theme', 'name' => 'design_upload_theme', 'type' => 'file')); + // TRANS: Form instructions for uploading a cutom StatusNet theme. $this->out->element('p', 'form_guide', _('You can upload a custom StatusNet theme as a .ZIP archive.')); $this->unli(); } @@ -509,22 +511,25 @@ class DesignAdminPanelForm extends AdminForm $this->out->elementStart('fieldset', array('id' => 'settings_design_background-image')); + // TRANS: Fieldset legend for theme background image. $this->out->element('legend', null, _('Change background image')); $this->out->elementStart('ul', 'form_data'); $this->li(); + $this->out->element('input', array('name' => 'MAX_FILE_SIZE', + 'type' => 'hidden', + 'id' => 'MAX_FILE_SIZE', + 'value' => ImageFile::maxFileSizeInt())); $this->out->element('label', array('for' => 'design_background-image_file'), + // TRANS: Field label for background image on theme designer page. _('Background')); $this->out->element('input', array('name' => 'design_background-image_file', 'type' => 'file', 'id' => 'design_background-image_file')); $this->out->element('p', 'form_guide', + // TRANS: Form guide for background image upload form on theme designer page. sprintf(_('You can upload a background image for the site. ' . 'The maximum file size is %1$s.'), ImageFile::maxFileSize())); - $this->out->element('input', array('name' => 'MAX_FILE_SIZE', - 'type' => 'hidden', - 'id' => 'MAX_FILE_SIZE', - 'value' => ImageFile::maxFileSizeInt())); $this->unli(); if (!empty($design->backgroundimage)) { @@ -568,11 +573,13 @@ class DesignAdminPanelForm extends AdminForm 'class' => 'radio'), // TRANS: Used as radio button label to not add a background image. _('Off')); + // TRANS: Form guide for turning background image on or off on theme designer page. $this->out->element('p', 'form_guide', _('Turn background image on or off.')); $this->unli(); $this->li(); $this->out->checkbox('design_background-image_repeat', + // TRANS: Checkbox label to title background image on theme designer page. _('Tile background image'), ($design->disposition & BACKGROUND_TILE) ? true : false); $this->unli(); @@ -587,7 +594,8 @@ class DesignAdminPanelForm extends AdminForm $design = $this->out->design; $this->out->elementStart('fieldset', array('id' => 'settings_design_color')); - $this->out->element('legend', null, _('Change colours')); + // TRANS: Fieldset legend for theme colors. + $this->out->element('legend', null, _('Change colors')); $this->out->elementStart('ul', 'form_data'); @@ -597,6 +605,7 @@ class DesignAdminPanelForm extends AdminForm $bgcolor = new WebColor($design->backgroundcolor); $this->li(); + // TRANS: Field label for background color selector. $this->out->element('label', array('for' => 'swatch-1'), _('Background')); $this->out->element('input', array('name' => 'design_background', 'type' => 'text', @@ -610,6 +619,7 @@ class DesignAdminPanelForm extends AdminForm $ccolor = new WebColor($design->contentcolor); $this->li(); + // TRANS: Field label for content color selector. $this->out->element('label', array('for' => 'swatch-2'), _('Content')); $this->out->element('input', array('name' => 'design_content', 'type' => 'text', @@ -623,6 +633,7 @@ class DesignAdminPanelForm extends AdminForm $sbcolor = new WebColor($design->sidebarcolor); $this->li(); + // TRANS: Field label for sidebar color selector. $this->out->element('label', array('for' => 'swatch-3'), _('Sidebar')); $this->out->element('input', array('name' => 'design_sidebar', 'type' => 'text', @@ -636,6 +647,7 @@ class DesignAdminPanelForm extends AdminForm $tcolor = new WebColor($design->textcolor); $this->li(); + // TRANS: Field label for text color selector. $this->out->element('label', array('for' => 'swatch-4'), _('Text')); $this->out->element('input', array('name' => 'design_text', 'type' => 'text', @@ -649,6 +661,7 @@ class DesignAdminPanelForm extends AdminForm $lcolor = new WebColor($design->linkcolor); $this->li(); + // TRANS: Field label for link color selector. $this->out->element('label', array('for' => 'swatch-5'), _('Links')); $this->out->element('input', array('name' => 'design_links', 'type' => 'text', @@ -674,10 +687,12 @@ class DesignAdminPanelForm extends AdminForm { if (common_config('custom_css', 'enabled')) { $this->out->elementStart('fieldset', array('id' => 'settings_design_advanced')); + // TRANS: Fieldset legend for advanced theme design settings. $this->out->element('legend', null, _('Advanced')); $this->out->elementStart('ul', 'form_data'); $this->li(); + // TRANS: Field label for custom CSS. $this->out->element('label', array('for' => 'css'), _('Custom CSS')); $this->out->element('textarea', array('name' => 'css', 'id' => 'css', @@ -699,17 +714,25 @@ class DesignAdminPanelForm extends AdminForm function formActions() { - $this->out->submit('defaults', _('Use defaults'), 'submit form_action-default', - 'defaults', _('Restore default designs')); + // TRANS: Button text for resetting theme settings. + $this->out->submit('defaults', _m('BUTTON','Use defaults'), 'submit form_action-default', + // TRANS: Title for button for resetting theme settings. + 'defaults', _('Restore default designs.')); $this->out->element('input', array('id' => 'settings_design_reset', 'type' => 'reset', + // TRANS: Button text for resetting theme settings. 'value' => 'Reset', 'class' => 'submit form_action-primary', - 'title' => _('Reset back to default'))); + // TRANS: Title for button for resetting theme settings. + 'title' => _('Reset back to default.'))); - $this->out->submit('save', _('Save'), 'submit form_action-secondary', - 'save', _('Save design')); + $this->out->submit('save', + // TRANS: Button text for saving theme settings. + _m('BUTTON','Save'), + 'submit form_action-secondary', + 'save', + // TRANS: Title for button for saving theme settings. + _('Save design.')); } - } diff --git a/actions/disfavor.php b/actions/disfavor.php index 3ccdd69af2..39598d60bf 100644 --- a/actions/disfavor.php +++ b/actions/disfavor.php @@ -1,5 +1,4 @@ clientError(_('Not logged in.')); return; } @@ -71,6 +71,7 @@ class DisfavorAction extends Action $notice = Notice::staticGet($id); $token = $this->trimmed('token-'.$notice->id); if (!$token || $token != common_session_token()) { + // TRANS: Client error displayed when the session token does not match or is not given. $this->clientError(_('There was a problem with your session token. Try again, please.')); return; } @@ -78,12 +79,14 @@ class DisfavorAction extends Action $fave->user_id = $user->id; $fave->notice_id = $notice->id; if (!$fave->find(true)) { + // TRANS: Client error displayed when trying to remove favorite status for a notice that is not a favorite. $this->clientError(_('This notice is not a favorite!')); return; } $result = $fave->delete(); if (!$result) { common_log_db_error($fave, 'DELETE', __FILE__); + // TRANS: Server error displayed when removing a favorite from the database fails. $this->serverError(_('Could not delete favorite.')); return; } @@ -91,6 +94,7 @@ class DisfavorAction extends Action if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); + // TRANS: Title for page on which favorites can be added. $this->element('title', null, _('Add to favorites')); $this->elementEnd('head'); $this->elementStart('body'); @@ -105,4 +109,3 @@ class DisfavorAction extends Action } } } - diff --git a/actions/doc.php b/actions/doc.php index f876fb8beb..20cf9e2810 100644 --- a/actions/doc.php +++ b/actions/doc.php @@ -1,5 +1,4 @@ element('h1', array('class' => 'entry-title'), $this->title()); @@ -96,7 +94,6 @@ class DocAction extends Action * * @return void. */ - function showContentBlock() { $this->elementStart('div', array('id' => 'content', 'class' => 'hentry')); @@ -117,7 +114,6 @@ class DocAction extends Action * * @return void */ - function showContent() { $this->raw($this->output); @@ -142,7 +138,6 @@ class DocAction extends Action * * @return boolean read-only flag (false) */ - function isReadOnly($args) { return true; @@ -155,7 +150,9 @@ class DocAction extends Action $this->filename = $this->getFilename(); if (empty($this->filename)) { - throw new ClientException(sprintf(_('No such document "%s"'), $this->title), 404); + // TRANS: Client exception thrown when requesting a document from the documentation that does not exist. + // TRANS: %s is the non-existing document. + throw new ClientException(sprintf(_('No such document "%s".'), $this->title), 404); } $c = file_get_contents($this->filename); diff --git a/actions/editapplication.php b/actions/editapplication.php index 760b1d284e..4e67d9e57b 100644 --- a/actions/editapplication.php +++ b/actions/editapplication.php @@ -198,6 +198,7 @@ class EditApplicationAction extends OwnerDesignAction } elseif (Oauth_application::descriptionTooLong($description)) { $this->showForm(sprintf( // TRANS: Validation error shown when providing too long a description in the "Edit application" form. + // TRANS: %d is the maximum number of allowed characters. _m('Description is too long (maximum %d character).', 'Description is too long (maximum %d characters).', Oauth_application::maxDesc()), @@ -223,6 +224,7 @@ class EditApplicationAction extends OwnerDesignAction $this->showForm(_('Organization is too long (maximum 255 characters).')); return; } elseif (empty($homepage)) { + // TRANS: Form validation error show when an organisation name has not been provided in the edit application form. $this->showForm(_('Organization homepage is required.')); return; } elseif ((mb_strlen($homepage) > 0) diff --git a/actions/editgroup.php b/actions/editgroup.php index ab4dbb2836..0e04170051 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -177,116 +177,121 @@ class EditgroupAction extends GroupDesignAction return; } - $nickname = Nickname::normalize($this->trimmed('nickname')); - $fullname = $this->trimmed('fullname'); - $homepage = $this->trimmed('homepage'); - $description = $this->trimmed('description'); - $location = $this->trimmed('location'); - $aliasstring = $this->trimmed('aliases'); + if (Event::handle('StartGroupSaveForm', array($this))) { - if ($this->nicknameExists($nickname)) { - // TRANS: Group edit form validation error. - $this->showForm(_('Nickname already in use. Try another one.')); - return; - } else if (!User_group::allowedNickname($nickname)) { - // TRANS: Group edit form validation error. - $this->showForm(_('Not a valid nickname.')); - return; - } else if (!is_null($homepage) && (strlen($homepage) > 0) && - !Validate::uri($homepage, - array('allowed_schemes' => - array('http', 'https')))) { - // TRANS: Group edit form validation error. - $this->showForm(_('Homepage is not a valid URL.')); - return; - } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { - // TRANS: Group edit form validation error. - $this->showForm(_('Full name is too long (maximum 255 characters).')); - return; - } else if (User_group::descriptionTooLong($description)) { - $this->showForm(sprintf( + $nickname = Nickname::normalize($this->trimmed('nickname')); + $fullname = $this->trimmed('fullname'); + $homepage = $this->trimmed('homepage'); + $description = $this->trimmed('description'); + $location = $this->trimmed('location'); + $aliasstring = $this->trimmed('aliases'); + + if ($this->nicknameExists($nickname)) { // TRANS: Group edit form validation error. - _m('Description is too long (maximum %d character).', - 'Description is too long (maximum %d characters).', - User_group::maxDescription()), + $this->showForm(_('Nickname already in use. Try another one.')); + return; + } else if (!User_group::allowedNickname($nickname)) { + // TRANS: Group edit form validation error. + $this->showForm(_('Not a valid nickname.')); + return; + } else if (!is_null($homepage) && (strlen($homepage) > 0) && + !Validate::uri($homepage, + array('allowed_schemes' => + array('http', 'https')))) { + // TRANS: Group edit form validation error. + $this->showForm(_('Homepage is not a valid URL.')); + return; + } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { + // TRANS: Group edit form validation error. + $this->showForm(_('Full name is too long (maximum 255 characters).')); + return; + } else if (User_group::descriptionTooLong($description)) { + $this->showForm(sprintf( + // TRANS: Group edit form validation error. + _m('Description is too long (maximum %d character).', + 'Description is too long (maximum %d characters).', + User_group::maxDescription()), User_group::maxDescription())); - return; - } else if (!is_null($location) && mb_strlen($location) > 255) { - // TRANS: Group edit form validation error. - $this->showForm(_('Location is too long (maximum 255 characters).')); - return; - } - - if (!empty($aliasstring)) { - $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring))); - } else { - $aliases = array(); - } - - if (count($aliases) > common_config('group', 'maxaliases')) { - // TRANS: Group edit form validation error. - // TRANS: %d is the maximum number of allowed aliases. - $this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.', - 'Too many aliases! Maximum %d allowed.', - common_config('group', 'maxaliases')), - common_config('group', 'maxaliases'))); - return; - } - - foreach ($aliases as $alias) { - if (!Nickname::isValid($alias)) { + return; + } else if (!is_null($location) && mb_strlen($location) > 255) { // TRANS: Group edit form validation error. - $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias)); + $this->showForm(_('Location is too long (maximum 255 characters).')); return; } - if ($this->nicknameExists($alias)) { + + if (!empty($aliasstring)) { + $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring))); + } else { + $aliases = array(); + } + + if (count($aliases) > common_config('group', 'maxaliases')) { // TRANS: Group edit form validation error. - $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'), - $alias)); + // TRANS: %d is the maximum number of allowed aliases. + $this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.', + 'Too many aliases! Maximum %d allowed.', + common_config('group', 'maxaliases')), + common_config('group', 'maxaliases'))); return; } - // XXX assumes alphanum nicknames - if (strcmp($alias, $nickname) == 0) { - // TRANS: Group edit form validation error. - $this->showForm(_('Alias can\'t be the same as nickname.')); - return; + + foreach ($aliases as $alias) { + if (!Nickname::isValid($alias)) { + // TRANS: Group edit form validation error. + $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias)); + return; + } + if ($this->nicknameExists($alias)) { + // TRANS: Group edit form validation error. + $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'), + $alias)); + return; + } + // XXX assumes alphanum nicknames + if (strcmp($alias, $nickname) == 0) { + // TRANS: Group edit form validation error. + $this->showForm(_('Alias can\'t be the same as nickname.')); + return; + } } + + $this->group->query('BEGIN'); + + $orig = clone($this->group); + + $this->group->nickname = $nickname; + $this->group->fullname = $fullname; + $this->group->homepage = $homepage; + $this->group->description = $description; + $this->group->location = $location; + $this->group->mainpage = common_local_url('showgroup', array('nickname' => $nickname)); + + $result = $this->group->update($orig); + + if (!$result) { + common_log_db_error($this->group, 'UPDATE', __FILE__); + // TRANS: Server error displayed when editing a group fails. + $this->serverError(_('Could not update group.')); + } + + $result = $this->group->setAliases($aliases); + + if (!$result) { + // TRANS: Server error displayed when group aliases could not be added. + $this->serverError(_('Could not create aliases.')); + } + + if ($nickname != $orig->nickname) { + common_log(LOG_INFO, "Saving local group info."); + $local = Local_group::staticGet('group_id', $this->group->id); + $local->setNickname($nickname); + } + + $this->group->query('COMMIT'); + + Event::handle('EndGroupSaveForm', array($this)); } - $this->group->query('BEGIN'); - - $orig = clone($this->group); - - $this->group->nickname = $nickname; - $this->group->fullname = $fullname; - $this->group->homepage = $homepage; - $this->group->description = $description; - $this->group->location = $location; - $this->group->mainpage = common_local_url('showgroup', array('nickname' => $nickname)); - - $result = $this->group->update($orig); - - if (!$result) { - common_log_db_error($this->group, 'UPDATE', __FILE__); - // TRANS: Server error displayed when editing a group fails. - $this->serverError(_('Could not update group.')); - } - - $result = $this->group->setAliases($aliases); - - if (!$result) { - // TRANS: Server error displayed when group aliases could not be added. - $this->serverError(_('Could not create aliases.')); - } - - if ($nickname != $orig->nickname) { - common_log(LOG_INFO, "Saving local group info."); - $local = Local_group::staticGet('group_id', $this->group->id); - $local->setNickname($nickname); - } - - $this->group->query('COMMIT'); - if ($this->group->nickname != $orig->nickname) { common_redirect(common_local_url('editgroup', array('nickname' => $nickname)), diff --git a/actions/emailsettings.php b/actions/emailsettings.php index 41c12f2a04..6780928157 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -54,7 +54,6 @@ class EmailsettingsAction extends SettingsAction * * @return string Title of the page */ - function title() { // TRANS: Title for e-mail settings. @@ -66,7 +65,6 @@ class EmailsettingsAction extends SettingsAction * * @return instructions for use */ - function getInstructions() { // XXX: For consistency of parameters in messages, this should be a @@ -91,7 +89,6 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function showContent() { $user = common_current_user(); @@ -118,8 +115,8 @@ class EmailsettingsAction extends SettingsAction $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'), + // TRANS: Form note in e-mail settings form. _('Awaiting confirmation on this address. '. 'Check your inbox (and spam box!) for a message '. 'with further instructions.')); @@ -173,7 +170,7 @@ class EmailsettingsAction extends SettingsAction if ($user->incomingemail) { $this->elementStart('p'); $this->element('span', 'address', $user->incomingemail); - // XXX: Looks a little awkward in the UI. + // @todo 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. @@ -208,7 +205,7 @@ class EmailsettingsAction extends SettingsAction $this->element('legend', null, _('Email preferences')); $this->elementStart('ul', 'form_data'); - + if (Event::handle('StartEmailFormData', array($this))) { $this->elementStart('li'); $this->checkbox('emailnotifysub', @@ -262,7 +259,6 @@ class EmailsettingsAction extends SettingsAction * * @return Confirm_address Email address confirmation for user, or null */ - function getConfirmation() { $user = common_current_user(); @@ -288,7 +284,6 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function handlePost() { // CSRF protection @@ -322,13 +317,12 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function savePreferences() { $user = common_current_user(); - + if (Event::handle('StartEmailSaveForm', array($this, &$user))) { - + $emailnotifysub = $this->boolean('emailnotifysub'); $emailnotifyfav = $this->boolean('emailnotifyfav'); $emailnotifymsg = $this->boolean('emailnotifymsg'); @@ -336,13 +330,13 @@ class EmailsettingsAction extends SettingsAction $emailnotifyattn = $this->boolean('emailnotifyattn'); $emailmicroid = $this->boolean('emailmicroid'); $emailpost = $this->boolean('emailpost'); - + assert(!is_null($user)); // should already be checked - + $user->query('BEGIN'); - + $original = clone($user); - + $user->emailnotifysub = $emailnotifysub; $user->emailnotifyfav = $emailnotifyfav; $user->emailnotifymsg = $emailnotifymsg; @@ -350,20 +344,20 @@ class EmailsettingsAction extends SettingsAction $user->emailnotifyattn = $emailnotifyattn; $user->emailmicroid = $emailmicroid; $user->emailpost = $emailpost; - + $result = $user->update($original); - + 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.')); + $this->serverError(_('Could not update user.')); return; } - + $user->query('COMMIT'); - + Event::handle('EndEmailSaveForm', array($this)); - + // TRANS: Confirmation message for successful e-mail preferences save. $this->showForm(_('Email preferences saved.'), true); } @@ -374,7 +368,6 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function addAddress() { $user = common_current_user(); @@ -393,7 +386,7 @@ class EmailsettingsAction extends SettingsAction if (!$email) { // TRANS: Message given saving e-mail address that cannot be normalised. - $this->showForm(_('Cannot normalize that email address')); + $this->showForm(_('Cannot normalize that email address.')); return; } if (!Validate::email($email, common_config('email', 'check_domain'))) { @@ -423,7 +416,7 @@ class EmailsettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not insert confirmation code.')); return; } @@ -442,7 +435,6 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function cancelConfirmation() { $email = $this->arg('email'); @@ -465,7 +457,7 @@ class EmailsettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not delete email confirmation.')); return; } @@ -478,7 +470,6 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function removeAddress() { $user = common_current_user(); @@ -505,7 +496,7 @@ class EmailsettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not update user.')); return; } $user->query('COMMIT'); @@ -519,12 +510,12 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function removeIncoming() { $user = common_current_user(); if (!$user->incomingemail) { + // TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set. $this->showForm(_('No incoming email address.')); return; } @@ -537,7 +528,7 @@ class EmailsettingsAction extends SettingsAction 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.")); + $this->serverError(_('Could not update user record.')); } // TRANS: Message given after successfully removing an incoming e-mail address. @@ -549,7 +540,6 @@ class EmailsettingsAction extends SettingsAction * * @return void */ - function newIncoming() { $user = common_current_user(); @@ -562,7 +552,7 @@ class EmailsettingsAction extends SettingsAction 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.")); + $this->serverError(_('Could not update user record.')); } // TRANS: Message given after successfully adding an incoming e-mail address. diff --git a/actions/favor.php b/actions/favor.php index 01976a38f5..61db235738 100644 --- a/actions/favor.php +++ b/actions/favor.php @@ -1,5 +1,4 @@ clientError(_('Not logged in.')); return; } @@ -76,11 +76,13 @@ class FavorAction extends Action return; } if ($user->hasFave($notice)) { + // TRANS: Client error displayed when trying to mark a notice as favorite that already is a favorite. $this->clientError(_('This notice is already a favorite!')); return; } $fave = Fave::addNew($user->getProfile(), $notice); if (!$fave) { + // TRANS: Server error displayed when trying to mark a notice as favorite fails in the database. $this->serverError(_('Could not create favorite.')); return; } @@ -89,7 +91,8 @@ class FavorAction extends Action if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); - $this->element('title', null, _('Disfavor favorite')); + // TRANS: Page title for page on which favorite notices can be unfavourited. + $this->element('title', null, _('Disfavor favorite.')); $this->elementEnd('head'); $this->elementStart('body'); $disfavor = new DisFavorForm($this, $notice); @@ -123,4 +126,3 @@ class FavorAction extends Action } } } - diff --git a/actions/favorited.php b/actions/favorited.php index 19d49feecf..c137cf424f 100644 --- a/actions/favorited.php +++ b/actions/favorited.php @@ -48,7 +48,6 @@ require_once INSTALLDIR.'/lib/noticelist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class FavoritedAction extends Action { var $page = null; @@ -62,8 +61,11 @@ class FavoritedAction extends Action function title() { if ($this->page == 1) { + // TRANS: Page title for first page of favorited notices. return _('Popular notices'); } else { + // TRANS: Page title for all but first page of favorited notices. + // TRANS: %d is the page number being displayed. return sprintf(_('Popular notices, page %d'), $this->page); } } @@ -73,9 +75,9 @@ class FavoritedAction extends Action * * @return instructions for use */ - function getInstructions() { + // TRANS: Description on page displaying favorited notices. return _('The most popular notices on the site right now.'); } @@ -84,7 +86,6 @@ class FavoritedAction extends Action * * @return boolean true */ - function isReadOnly($args) { return true; @@ -99,7 +100,6 @@ class FavoritedAction extends Action * * @todo move queries from showContent() to here */ - function prepare($args) { parent::prepare($args); @@ -119,7 +119,6 @@ class FavoritedAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -134,7 +133,6 @@ class FavoritedAction extends Action * * @return void */ - function showPageNotice() { $instr = $this->getInstructions(); @@ -147,12 +145,16 @@ class FavoritedAction extends Action function showEmptyList() { + // TRANS: Text displayed instead of a list when a site does not yet have any favourited notices. $message = _('Favorite notices appear on this page but no one has favorited one yet.') . ' '; if (common_logged_in()) { + // TRANS: Additional text displayed instead of a list when a site does not yet have any favourited notices for logged in users. $message .= _('Be the first to add a notice to your favorites by clicking the fave button next to any notice you like.'); } else { + // TRANS: Additional text displayed instead of a list when a site does not yet have any favourited notices for not logged in users. + // TRANS: %%action.register%% is a registration link. "[link text](link)" is Mark Down. Do not change the formatting. $message .= _('Why not [register an account](%%action.register%%) and be the first to add a notice to your favorites!'); } @@ -168,7 +170,6 @@ class FavoritedAction extends Action * * @return void */ - function showLocalNav() { $nav = new PublicGroupNav($this); @@ -182,7 +183,6 @@ class FavoritedAction extends Action * * @return void */ - function showContent() { $pop = new Popularity(); diff --git a/actions/favoritesrss.php b/actions/favoritesrss.php index 51c92af933..494327674d 100644 --- a/actions/favoritesrss.php +++ b/actions/favoritesrss.php @@ -1,5 +1,4 @@ user = User::staticGet('nickname', $nickname); if (!$this->user) { + // TRANS: Client error displayed when trying to get the RSS feed with favorites of a user that does not exist. $this->clientError(_('No such user.')); return false; } else { @@ -108,10 +106,14 @@ class FavoritesrssAction extends Rss10Action $c = array('url' => common_local_url('favoritesrss', array('nickname' => $user->nickname)), + // TRANS: Title of RSS feed with favourite notices of a user. + // TRANS: %s is a user's nickname. 'title' => sprintf(_("%s's favorite notices"), $user->nickname), 'link' => common_local_url('showfavorites', array('nickname' => $user->nickname)), + // TRANS: Desciption of RSS feed with favourite notices of a user. + // TRANS: %1$s is a user's nickname, %2$s is the name of the StatusNet site. 'description' => sprintf(_('Updates favored by %1$s on %2$s!'), $user->nickname, common_config('site', 'name'))); return $c; diff --git a/actions/featured.php b/actions/featured.php index dd1056dd58..9a7f128b57 100644 --- a/actions/featured.php +++ b/actions/featured.php @@ -45,7 +45,6 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class FeaturedAction extends Action { var $page = null; @@ -66,8 +65,11 @@ class FeaturedAction extends Action function title() { if ($this->page == 1) { + // TRANS: Page title for first page of featured users. return _('Featured users'); } else { + // TRANS: Page title for all but first page of featured users. + // TRANS: %d is the page number being displayed. return sprintf(_('Featured users, page %d'), $this->page); } } @@ -96,7 +98,8 @@ class FeaturedAction extends Action function getInstructions() { - return sprintf(_('A selection of some great users on %s'), + // TRANS: Description on page displaying featured users. + return sprintf(_('A selection of some great users on %s.'), common_config('site', 'name')); } diff --git a/actions/file.php b/actions/file.php index c6f7b998a2..49ed8af1d6 100644 --- a/actions/file.php +++ b/actions/file.php @@ -21,6 +21,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } require_once(INSTALLDIR.'/actions/shownotice.php'); +// @todo FIXME: Add documentation. class FileAction extends Action { var $id = null; @@ -31,14 +32,17 @@ class FileAction extends Action parent::prepare($args); $this->id = $this->trimmed('notice'); if (empty($this->id)) { + // TRANS: Client error displayed when no notice ID was given trying do display a file. $this->clientError(_('No notice ID.')); } $notice = Notice::staticGet('id', $this->id); if (empty($notice)) { + // TRANS: Client error displayed when an invalid notice ID was given trying do display a file. $this->clientError(_('No notice.')); } $atts = $notice->attachments(); if (empty($atts)) { + // TRANS: Client error displayed when trying do display a file for a notice without a file attachement. $this->clientError(_('No attachments.')); } foreach ($atts as $att) { @@ -48,6 +52,9 @@ class FileAction extends Action } } if (empty($this->filerec)) { + // XXX: Is this translation hint correct? If yes, please remove comment, if no, please correct and remove comment. + // TRANS: Client error displayed when trying do display a file for a notice with file attachements + // TRANS: that could not be found. $this->clientError(_('No uploaded attachments.')); } return true; @@ -62,11 +69,8 @@ class FileAction extends Action * * @return boolean true */ - function isReadOnly($args) { return true; } - } - diff --git a/actions/finishremotesubscribe.php b/actions/finishremotesubscribe.php index 0325f6adbb..59725af27f 100644 --- a/actions/finishremotesubscribe.php +++ b/actions/finishremotesubscribe.php @@ -48,7 +48,6 @@ require_once INSTALLDIR.'/lib/omb.php'; */ class FinishremotesubscribeAction extends Action { - /** * Class handler. * @@ -56,7 +55,7 @@ class FinishremotesubscribeAction extends Action * * @return nothing * - **/ + */ function handle($args) { parent::handle($args); @@ -66,6 +65,7 @@ class FinishremotesubscribeAction extends Action $service = unserialize($_SESSION['oauth_authorization_request']); if (!$service) { + // TRANS: Client error displayed when subscribing to a remote profile and an unexpected response is received. $this->clientError(_('Not expecting this response!')); return; } @@ -77,6 +77,7 @@ class FinishremotesubscribeAction extends Action $user = User::staticGet('uri', $service->getListeneeURI()); if (!$user) { + // TRANS: Client error displayed when subscribing to a remote profile that does not exist. $this->clientError(_('User being listened to does not exist.')); return; } @@ -84,6 +85,7 @@ class FinishremotesubscribeAction extends Action $other = User::staticGet('uri', $service->getListenerURI()); if ($other) { + // TRANS: Client error displayed when subscribing to a remote profile that is a local profile. $this->clientError(_('You can use the local subscription!')); return; } @@ -96,6 +98,7 @@ class FinishremotesubscribeAction extends Action $profile = Profile::staticGet($remote->id); if ($user->hasBlocked($profile)) { + // TRANS: Client error displayed when subscribing to a remote profile that is blocked form subscribing to. $this->clientError(_('That user has blocked you from subscribing.')); return; } @@ -107,14 +110,17 @@ class FinishremotesubscribeAction extends Action } catch (OAuthException $e) { if ($e->getMessage() == 'The authorized token does not equal the ' . 'submitted token.') { + // TRANS: Client error displayed when subscribing to a remote profile without providing an authorised token. $this->clientError(_('You are not authorized.')); return; } else { + // TRANS: Client error displayed when subscribing to a remote profile and conversion of the request token to access token fails. $this->clientError(_('Could not convert request token to ' . 'access token.')); return; } } catch (OMB_RemoteServiceException $e) { + // TRANS: Client error displayed when subscribing to a remote profile fails because of an unsupported version of the OMB protocol. $this->clientError(_('Remote service uses unknown version of ' . 'OMB protocol.')); return; @@ -135,6 +141,7 @@ class FinishremotesubscribeAction extends Action $service->getServiceURI(OMB_ENDPOINT_UPDATEPROFILE); if (!$remote->update($orig_remote)) { + // TRANS: Server error displayed when subscribing to a remote profile fails because the remote profile could not be updated. $this->serverError(_('Error updating remote profile.')); return; } diff --git a/actions/foaf.php b/actions/foaf.php index 09af7b5026..ceb575c736 100644 --- a/actions/foaf.php +++ b/actions/foaf.php @@ -23,6 +23,7 @@ define('LISTENER', 1); define('LISTENEE', -1); define('BOTH', 0); +// @todo XXX: Documentation missing. class FoafAction extends Action { function isReadOnly($args) @@ -37,6 +38,7 @@ class FoafAction extends Action $nickname_arg = $this->arg('nickname'); if (empty($nickname_arg)) { + // TRANS: Client error displayed when requesting Friends of a Friend feed without providing a user nickname. $this->clientError(_('No such user.'), 404); return false; } @@ -55,6 +57,7 @@ class FoafAction extends Action $this->user = User::staticGet('nickname', $this->nickname); if (!$this->user) { + // TRANS: Client error displayed when requesting Friends of a Friend feed for an object that is not a user. $this->clientError(_('No such user.'), 404); return false; } @@ -62,6 +65,7 @@ class FoafAction extends Action $this->profile = $this->user->getProfile(); if (!$this->profile) { + // TRANS: Server error displayed when requesting Friends of a Friend feed for a user for which the profile could not be found. $this->serverError(_('User has no profile.'), 500); return false; } @@ -110,7 +114,7 @@ class FoafAction extends Action if ($this->profile->bio) { $this->element('bio:olb', null, $this->profile->bio); } - + $location = $this->profile->getLocation(); if ($location) { $attr = array(); @@ -118,7 +122,7 @@ class FoafAction extends Action $attr['rdf:about'] = $location->getRdfURL(); } $location_name = $location->getName(); - + $this->elementStart('based_near'); $this->elementStart('geo:SpatialThing', $attr); if ($location_name) { @@ -193,7 +197,7 @@ class FoafAction extends Action $this->element('knows', array('rdf:resource' => $uri)); } } - + $this->elementEnd('Agent'); @@ -239,18 +243,17 @@ class FoafAction extends Action /** * Output FOAF bit for the given profile. - * + * * @param Profile $profile * @param mixed $service Root URL of this StatusNet instance for a local * user, otherwise null. * @param mixed $useruri URI string for the referenced profile.. * @param boolean $fetchSubscriptions Should we load and list all their subscriptions? * @param boolean $isSubscriber if not fetching subs, we can still mark the user as following the current page. - * + * * @return array if $fetchSubscribers is set, return a list of info on those * subscriptions. */ - function showMicrobloggingAccount($profile, $service=null, $useruri=null, $fetchSubscriptions=false, $isSubscriber=false) { $attr = array(); diff --git a/actions/foafgroup.php b/actions/foafgroup.php index 4db40c28be..9638ea0f34 100644 --- a/actions/foafgroup.php +++ b/actions/foafgroup.php @@ -27,6 +27,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +// @todo XXX: Documentation missing. class FoafGroupAction extends Action { function isReadOnly($args) @@ -41,6 +42,7 @@ class FoafGroupAction extends Action $nickname_arg = $this->arg('nickname'); if (empty($nickname_arg)) { + // TRANS: Client error displayed when requesting Friends of a Friend feed without providing a group nickname. $this->clientError(_('No such group.'), 404); return false; } @@ -59,6 +61,7 @@ class FoafGroupAction extends Action $local = Local_group::staticGet('nickname', $this->nickname); if (!$local) { + // TRANS: Client error displayed when requesting Friends of a Friend feed for a non-local group. $this->clientError(_('No such group.'), 404); return false; } @@ -66,6 +69,7 @@ class FoafGroupAction extends Action $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { + // TRANS: Client error displayed when requesting Friends of a Friend feed for a nickname that is not a group. $this->clientError(_('No such group.'), 404); return false; } diff --git a/actions/geocode.php b/actions/geocode.php index d934930608..123a839f56 100644 --- a/actions/geocode.php +++ b/actions/geocode.php @@ -68,7 +68,7 @@ class GeocodeAction extends Action * * @return nothing * - **/ + */ function handle($args) { header('Content-Type: application/json; charset=utf-8'); @@ -89,7 +89,6 @@ class GeocodeAction extends Action * * @return boolean true */ - function isReadOnly($args) { return true; diff --git a/actions/getfile.php b/actions/getfile.php index a45506ce2a..4b57a05cd6 100644 --- a/actions/getfile.php +++ b/actions/getfile.php @@ -47,13 +47,11 @@ require_once 'MIME/Type.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class GetfileAction extends Action { /** * Path of file to return */ - var $path = null; /** @@ -63,7 +61,6 @@ class GetfileAction extends Action * * @return success flag */ - function prepare($args) { parent::prepare($args); @@ -76,10 +73,12 @@ class GetfileAction extends Action } if (empty($path) or !file_exists($path)) { + // TRANS: Client error displayed when requesting a non-existent file. $this->clientError(_('No such file.'), 404); return false; } if (!is_readable($path)) { + // TRANS: Client error displayed when requesting a file without having read access to it. $this->clientError(_('Cannot read file.'), 403); return false; } @@ -93,7 +92,6 @@ class GetfileAction extends Action * * @return boolean true */ - function isReadOnly($args) { return true; @@ -104,7 +102,6 @@ class GetfileAction extends Action * * @return int last-modified date as unix timestamp */ - function lastModified() { if (common_config('site', 'use_x_sendfile')) { @@ -122,7 +119,6 @@ class GetfileAction extends Action * * @return string etag http header */ - function etag() { if (common_config('site', 'use_x_sendfile')) { @@ -151,7 +147,6 @@ class GetfileAction extends Action * * @return void */ - function handle($args) { // undo headers set by PHP sessions diff --git a/actions/grantrole.php b/actions/grantrole.php index b8b23d02e9..36369a8600 100644 --- a/actions/grantrole.php +++ b/actions/grantrole.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * Action class to sandbox an abusive user + * Action class to grant user roles. * * PHP version 5 * @@ -32,7 +32,7 @@ if (!defined('STATUSNET')) { } /** - * Sandbox a user. + * Assign role to user. * * @category Action * @package StatusNet @@ -40,7 +40,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class GrantRoleAction extends ProfileFormAction { /** @@ -50,19 +49,20 @@ class GrantRoleAction extends ProfileFormAction * * @return boolean success flag */ - function prepare($args) { if (!parent::prepare($args)) { return false; } - + $this->role = $this->arg('role'); if (!Profile_role::isValid($this->role)) { + // TRANS: Client error displayed when trying to assign an invalid role to a user. $this->clientError(_('Invalid role.')); return false; } if (!Profile_role::isSettable($this->role)) { + // TRANS: Client error displayed when trying to assign an reserved role to a user. $this->clientError(_('This role is reserved and cannot be set.')); return false; } @@ -72,6 +72,7 @@ class GrantRoleAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasRight(Right::GRANTROLE)) { + // TRANS: Client error displayed when trying to assign a role to a user while not being allowed to set roles. $this->clientError(_('You cannot grant user roles on this site.')); return false; } @@ -79,6 +80,7 @@ class GrantRoleAction extends ProfileFormAction assert(!empty($this->profile)); // checked by parent if ($this->profile->hasRole($this->role)) { + // TRANS: Client error displayed when trying to assign a role to a user that already has that role. $this->clientError(_('User already has this role.')); return false; } @@ -91,7 +93,6 @@ class GrantRoleAction extends ProfileFormAction * * @return void */ - function handlePost() { $this->profile->grantRole($this->role); diff --git a/actions/groupblock.php b/actions/groupblock.php index 39f783397a..d426563d8c 100644 --- a/actions/groupblock.php +++ b/actions/groupblock.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class GroupblockAction extends RedirectingAction { var $profile = null; @@ -53,11 +52,11 @@ class GroupblockAction extends RedirectingAction * * @return boolean success flag */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed trying to block a user from a group while not logged in. $this->clientError(_('Not logged in.')); return false; } @@ -68,35 +67,42 @@ class GroupblockAction extends RedirectingAction } $id = $this->trimmed('blockto'); if (empty($id)) { + // TRANS: Client error displayed trying to block a user from a group while not specifying a to be blocked user profile. $this->clientError(_('No profile specified.')); return false; } $this->profile = Profile::staticGet('id', $id); if (empty($this->profile)) { + // TRANS: Client error displayed trying to block a user from a group while specifying a non-existing profile. $this->clientError(_('No profile with that ID.')); return false; } $group_id = $this->trimmed('blockgroup'); if (empty($group_id)) { + // TRANS: Client error displayed trying to block a user from a group while not specifying a group to block a profile from. $this->clientError(_('No group specified.')); return false; } $this->group = User_group::staticGet('id', $group_id); if (empty($this->group)) { + // TRANS: Client error displayed trying to block a user from a group while specifying a non-existing group. $this->clientError(_('No such group.')); return false; } $user = common_current_user(); if (!$user->isAdmin($this->group)) { + // TRANS: Client error displayed trying to block a user from a group while not being an admin user. $this->clientError(_('Only an admin can block group members.'), 401); return false; } if (Group_block::isBlocked($this->group, $this->profile)) { + // TRANS: Client error displayed trying to block a user from a group while user is already blocked from the given group. $this->clientError(_('User is already blocked from group.')); return false; } // XXX: could have proactive blocks, but we don't have UI for it. if (!$this->profile->isMember($this->group)) { + // TRANS: Client error displayed trying to block a user from a group while user is not a member of given group. $this->clientError(_('User is not a member of group.')); return false; } @@ -131,6 +137,7 @@ class GroupblockAction extends RedirectingAction } function title() { + // TRANS: Title for block user from group page. return _('Block user from group'); } @@ -145,7 +152,6 @@ class GroupblockAction extends RedirectingAction * * @return void */ - function areYouSureForm() { $id = $this->profile->id; @@ -155,8 +161,11 @@ class GroupblockAction extends RedirectingAction 'action' => common_local_url('groupblock'))); $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); + // TRANS: Fieldset legend for block user from group form. $this->element('legend', _('Block user')); $this->element('p', null, + // TRANS: Explanatory text for block user from group form before setting the block. + // TRANS: %1$s is that to be blocked user, %2$s is the group the user will be blocked from. sprintf(_('Are you sure you want to block user "%1$s" from the group "%2$s"? '. 'They will be removed from the group, unable to post, and '. 'unable to subscribe to the group in the future.'), @@ -179,14 +188,14 @@ class GroupblockAction extends RedirectingAction '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')); + _('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')); + _('Block this user from this group.')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -196,24 +205,24 @@ class GroupblockAction extends RedirectingAction * * @return void */ - function blockProfile() { $block = Group_block::blockProfile($this->group, $this->profile, common_current_user()); if (empty($block)) { + // TRANS: Server error displayed when trying to block a user from a group fails because of an application error. $this->serverError(_("Database error blocking user from group.")); return false; } - + $this->returnToPrevious(); } /** * If we reached this form without returnto arguments, default to * the top of the group's member list. - * + * * @return string URL */ function defaultReturnTo() @@ -227,6 +236,4 @@ class GroupblockAction extends RedirectingAction parent::showScripts(); $this->autofocus('form_action-yes'); } - } - diff --git a/actions/groupbyid.php b/actions/groupbyid.php index 5af7109cb4..f18e4540c0 100644 --- a/actions/groupbyid.php +++ b/actions/groupbyid.php @@ -47,7 +47,6 @@ require_once INSTALLDIR.'/lib/feedlist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupbyidAction extends Action { /** group we're viewing. */ @@ -58,7 +57,6 @@ class GroupbyidAction extends Action * * @return boolean true */ - function isReadOnly($args) { return true; @@ -71,6 +69,7 @@ class GroupbyidAction extends Action $id = $this->arg('id'); if (!$id) { + // TRANS: Client error displayed referring to a group's permalink without providing a group ID. $this->clientError(_('No ID.')); return false; } @@ -80,6 +79,7 @@ class GroupbyidAction extends Action $this->group = User_group::staticGet('id', $id); if (!$this->group) { + // TRANS: Client error displayed referring to a group's permalink for a non-existing group ID. $this->clientError(_('No such group.'), 404); return false; } @@ -95,9 +95,8 @@ class GroupbyidAction extends Action * * @return void */ - function handle($args) { common_redirect($this->group->homeUrl(), 303); } -} \ No newline at end of file +} diff --git a/actions/groupdesignsettings.php b/actions/groupdesignsettings.php index 526226a285..3ef5e20e44 100644 --- a/actions/groupdesignsettings.php +++ b/actions/groupdesignsettings.php @@ -2,7 +2,7 @@ /** * StatusNet, the distributed open-source microblogging tool * - * Change user password + * Saves a design for a given group. * * PHP version 5 * @@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/designsettings.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupDesignSettingsAction extends DesignSettingsAction { var $group = null; @@ -59,12 +58,12 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return boolean true */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed trying to change group design settings while not logged in. $this->clientError(_('You must be logged in to edit a group.')); return false; } @@ -81,6 +80,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction } if (!$nickname) { + // TRANS: Client error displayed trying to change group design settings without providing a group nickname. $this->clientError(_('No nickname.'), 404); return false; } @@ -97,6 +97,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction } if (!$this->group) { + // TRANS: Client error displayed trying to change group design settings while providing a nickname for a non-existing group. $this->clientError(_('No such group.'), 404); return false; } @@ -104,6 +105,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction $cur = common_current_user(); if (!$cur->isAdmin($this->group)) { + // TRANS: Client error displayed trying to change group design settings without being a (group) admin. $this->clientError(_('You must be an admin to edit the group.'), 403); return false; } @@ -122,7 +124,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return Design a design object to use */ - function getDesign() { @@ -141,6 +142,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction function title() { + // TRANS: Title group design settings page. return _('Group design'); } @@ -149,9 +151,9 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return instructions for use */ - function getInstructions() { + // TRANS: Instructions for group design settings page. return _('Customize the way your group looks ' . 'with a background image and a colour palette of your choice.'); } @@ -161,7 +163,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return nothing */ - function showLocalNav() { $nav = new GroupNav($this, $this->group); @@ -173,7 +174,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return Design */ - function getWorkingDesign() { $design = null; @@ -192,7 +192,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return void */ - function showContent() { $design = $this->getWorkingDesign(); @@ -209,17 +208,14 @@ class GroupDesignSettingsAction extends DesignSettingsAction * * @return void */ - function saveDesign() { try { - $bgcolor = new WebColor($this->trimmed('design_background')); $ccolor = new WebColor($this->trimmed('design_content')); $sbcolor = new WebColor($this->trimmed('design_sidebar')); $tcolor = new WebColor($this->trimmed('design_text')); $lcolor = new WebColor($this->trimmed('design_links')); - } catch (WebColorException $e) { $this->showForm($e->getMessage()); return; @@ -246,7 +242,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction $design = $this->group->getDesign(); if (!empty($design)) { - // update design $original = clone($design); @@ -263,12 +258,11 @@ class GroupDesignSettingsAction extends DesignSettingsAction if ($result === false) { common_log_db_error($design, 'UPDATE', __FILE__); - $this->showForm(_('Couldn\'t update your design.')); + // TRANS: Form validation error displayed when group design settings could not be updated because of an application issue. + $this->showForm(_('Unable to update your design settings.')); return; } - } else { - $this->group->query('BEGIN'); // save new design @@ -287,6 +281,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction if (empty($id)) { common_log_db_error($id, 'INSERT', __FILE__); + // TRANS: Form validation error displayed when group design settings could not be saved because of an application issue. $this->showForm(_('Unable to save your design settings.')); return; } @@ -297,18 +292,18 @@ class GroupDesignSettingsAction extends DesignSettingsAction if (empty($result)) { common_log_db_error($original, 'UPDATE', __FILE__); + // TRANS: Form validation error displayed when group design settings could not be saved because of an application issue. $this->showForm(_('Unable to save your design settings.')); $this->group->query('ROLLBACK'); return; } $this->group->query('COMMIT'); - } $this->saveBackgroundImage($design); + // TRANS: Form text to confirm saved group design settings. $this->showForm(_('Design preferences saved.'), true); } - } diff --git a/actions/grouplogo.php b/actions/grouplogo.php index 69840485e0..d490cd9875 100644 --- a/actions/grouplogo.php +++ b/actions/grouplogo.php @@ -49,7 +49,6 @@ define('MAX_ORIGINAL', 480); * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GrouplogoAction extends GroupDesignAction { var $mode = null; @@ -61,12 +60,12 @@ class GrouplogoAction extends GroupDesignAction /** * Prepare to run */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed when trying to create a group while not logged in. $this->clientError(_('You must be logged in to create a group.')); return false; } @@ -83,6 +82,7 @@ class GrouplogoAction extends GroupDesignAction } if (!$nickname) { + // TRANS: Client error displayed when trying to change group logo settings without providing a nickname. $this->clientError(_('No nickname.'), 404); return false; } @@ -99,6 +99,7 @@ class GrouplogoAction extends GroupDesignAction } if (!$this->group) { + // TRANS: Client error displayed when trying to update logo settings for a non-existing group. $this->clientError(_('No such group.'), 404); return false; } @@ -106,6 +107,7 @@ class GrouplogoAction extends GroupDesignAction $cur = common_current_user(); if (!$cur->isAdmin($this->group)) { + // TRANS: Client error displayed when trying to change group logo settings while not being a group admin. $this->clientError(_('You must be an admin to edit the group.'), 403); return false; } @@ -136,9 +138,9 @@ class GrouplogoAction extends GroupDesignAction * * @return string Title of the page */ - function title() { + // TRANS: Title for group logo settings page. return _('Group logo'); } @@ -147,9 +149,10 @@ class GrouplogoAction extends GroupDesignAction * * @return instructions for use */ - function getInstructions() { + // TRANS: Instructions for group logo page. + // TRANS: %s is the maximum file size for that site. return sprintf(_('You can upload a logo image for your group. The maximum file size is %s.'), ImageFile::maxFileSize()); } @@ -160,7 +163,6 @@ class GrouplogoAction extends GroupDesignAction * * @return void */ - function showContent() { if ($this->mode == 'crop') { @@ -178,6 +180,7 @@ class GrouplogoAction extends GroupDesignAction if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); + // TRANS: Server error displayed coming across a request from a user without a profile. $this->serverError(_('User without matching profile.')); return; } @@ -192,6 +195,7 @@ class GrouplogoAction extends GroupDesignAction common_local_url('grouplogo', array('nickname' => $this->group->nickname)))); $this->elementStart('fieldset'); + // TRANS: Group logo form legend. $this->element('legend', null, _('Group logo')); $this->hidden('token', common_session_token()); @@ -199,7 +203,8 @@ class GrouplogoAction extends GroupDesignAction if ($original) { $this->elementStart('li', array('id' => 'avatar_original', 'class' => 'avatar_view')); - $this->element('h2', null, _("Original")); + // TRANS: Uploaded original file in group logo form. + $this->element('h2', null, _('Original')); $this->elementStart('div', array('id'=>'avatar_original_view')); $this->element('img', array('src' => $this->group->original_logo, 'alt' => $this->group->nickname)); @@ -210,7 +215,8 @@ class GrouplogoAction extends GroupDesignAction if ($this->group->homepage_logo) { $this->elementStart('li', array('id' => 'avatar_preview', 'class' => 'avatar_view')); - $this->element('h2', null, _("Preview")); + // TRANS: Header for preview of to be displayed group logo. + $this->element('h2', null, _('Preview')); $this->elementStart('div', array('id'=>'avatar_preview_view')); $this->element('img', array('src' => $this->group->homepage_logo, 'width' => AVATAR_PROFILE_SIZE, @@ -221,25 +227,25 @@ class GrouplogoAction extends GroupDesignAction } $this->elementStart('li', array ('id' => 'settings_attach')); - $this->element('input', array('name' => 'avatarfile', - 'type' => 'file', - 'id' => 'avatarfile')); $this->element('input', array('name' => 'MAX_FILE_SIZE', 'type' => 'hidden', 'id' => 'MAX_FILE_SIZE', 'value' => ImageFile::maxFileSizeInt())); + $this->element('input', array('name' => 'avatarfile', + 'type' => 'file', + 'id' => 'avatarfile')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->elementStart('ul', 'form_actions'); $this->elementStart('li'); + // TRANS: Submit button for uploading a group logo. $this->submit('upload', _('Upload')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->elementEnd('fieldset'); $this->elementEnd('form'); - } function showCropForm() @@ -251,6 +257,7 @@ class GrouplogoAction extends GroupDesignAction common_local_url('grouplogo', array('nickname' => $this->group->nickname)))); $this->elementStart('fieldset'); + // TRANS: Legend for group logo settings fieldset. $this->element('legend', null, _('Avatar settings')); $this->hidden('token', common_session_token()); @@ -259,7 +266,8 @@ class GrouplogoAction extends GroupDesignAction $this->elementStart('li', array('id' => 'avatar_original', 'class' => 'avatar_view')); - $this->element('h2', null, _("Original")); + // TRANS: Header for originally uploaded file before a crop on the group logo page. + $this->element('h2', null, _('Original')); $this->elementStart('div', array('id'=>'avatar_original_view')); $this->element('img', array('src' => Avatar::url($this->filedata['filename']), 'width' => $this->filedata['width'], @@ -271,7 +279,8 @@ class GrouplogoAction extends GroupDesignAction $this->elementStart('li', array('id' => 'avatar_preview', 'class' => 'avatar_view')); - $this->element('h2', null, _("Preview")); + // TRANS: Header for the cropped group logo on the group logo page. + $this->element('h2', null, _('Preview')); $this->elementStart('div', array('id'=>'avatar_preview_view')); $this->element('img', array('src' => Avatar::url($this->filedata['filename']), 'width' => AVATAR_PROFILE_SIZE, @@ -286,13 +295,13 @@ class GrouplogoAction extends GroupDesignAction 'id' => $crop_info)); } + // TRANS: Button text for cropping an uploaded group logo. $this->submit('crop', _('Crop')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->elementEnd('fieldset'); $this->elementEnd('form'); - } /** @@ -302,13 +311,13 @@ class GrouplogoAction extends GroupDesignAction * * @return void */ - function handlePost() { // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { + // TRANS: Form validation error message. $this->show_form(_('There was a problem with your session token. '. 'Try again, please.')); return; @@ -319,6 +328,7 @@ class GrouplogoAction extends GroupDesignAction } else if ($this->arg('crop')) { $this->cropLogo(); } else { + // TRANS: Form validation error message when an unsupported argument is used. $this->showForm(_('Unexpected form submission.')); } } @@ -331,7 +341,6 @@ class GrouplogoAction extends GroupDesignAction * * @return void */ - function uploadLogo() { try { @@ -341,20 +350,21 @@ class GrouplogoAction extends GroupDesignAction return; } + $type = $imagefile->preferredType(); $filename = Avatar::filename($this->group->id, - image_type_to_extension($imagefile->type), + image_type_to_extension($type), null, 'group-temp-'.common_timestamp()); $filepath = Avatar::path($filename); - move_uploaded_file($imagefile->filepath, $filepath); + $imagefile->copyTo($filepath); $filedata = array('filename' => $filename, 'filepath' => $filepath, 'width' => $imagefile->width, 'height' => $imagefile->height, - 'type' => $imagefile->type); + 'type' => $type); $_SESSION['FILEDATA'] = $filedata; @@ -362,6 +372,7 @@ class GrouplogoAction extends GroupDesignAction $this->mode = 'crop'; + // TRANS: Form instructions on the group logo page. $this->showForm(_('Pick a square area of the image to be the logo.'), true); } @@ -371,12 +382,12 @@ class GrouplogoAction extends GroupDesignAction * * @return void */ - function cropLogo() { $filedata = $_SESSION['FILEDATA']; if (!$filedata) { + // TRANS: Server error displayed trying to crop an uploaded group logo that is no longer present. $this->serverError(_('Lost our file data.')); return; } @@ -396,8 +407,10 @@ class GrouplogoAction extends GroupDesignAction @unlink($filedata['filepath']); unset($_SESSION['FILEDATA']); $this->mode = 'upload'; + // TRANS: Form success message after updating a group logo. $this->showForm(_('Logo updated.'), true); } else { + // TRANS: Form failure message after failing to update a group logo. $this->showForm(_('Failed updating logo.')); } } @@ -422,7 +435,6 @@ class GrouplogoAction extends GroupDesignAction * * @return void */ - function showStylesheets() { parent::showStylesheets(); @@ -434,7 +446,6 @@ class GrouplogoAction extends GroupDesignAction * * @return void */ - function showScripts() { parent::showScripts(); diff --git a/actions/groupmembers.php b/actions/groupmembers.php index d03d0b5a3a..7b1512dfab 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -43,7 +43,6 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupmembersAction extends GroupDesignAction { var $page = null; @@ -73,6 +72,7 @@ class GroupmembersAction extends GroupDesignAction } if (!$nickname) { + // TRANS: Client error displayed when trying to view group members without providing a group nickname. $this->clientError(_('No nickname.'), 404); return false; } @@ -80,6 +80,7 @@ class GroupmembersAction extends GroupDesignAction $local = Local_group::staticGet('nickname', $nickname); if (!$local) { + // TRANS: Client error displayed when trying to view group members for a non-existing group. $this->clientError(_('No such group.'), 404); return false; } @@ -87,6 +88,7 @@ class GroupmembersAction extends GroupDesignAction $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { + // TRANS: Client error displayed when trying to view group members for an object that is not a group. $this->clientError(_('No such group.'), 404); return false; } @@ -119,6 +121,7 @@ class GroupmembersAction extends GroupDesignAction function showPageNotice() { $this->element('p', 'instructions', + // TRANS: Page notice for group members page. _('A list of the users in this group.')); } @@ -182,7 +185,8 @@ class GroupMemberListItem extends ProfileListItem { parent::showFullName(); if ($this->profile->isAdmin($this->group)) { - $this->out->text(' '); + $this->out->text(' '); // for separating the classes. + // TRANS: Indicator in group members list that this user is a group administrator. $this->out->element('span', 'role', _('Admin')); } } @@ -254,7 +258,7 @@ class GroupMemberListItem extends ProfileListItem /** * Fetch necessary return-to arguments for the profile forms * to return to this list when they're done. - * + * * @return array */ protected function returnToArgs() @@ -281,7 +285,6 @@ class GroupMemberListItem extends ProfileListItem * * @see BlockForm */ - class GroupBlockForm extends Form { /** @@ -310,7 +313,6 @@ class GroupBlockForm extends Form * @param User_group $group group to block user from * @param array $args return-to args */ - function __construct($out=null, $profile=null, $group=null, $args=null) { parent::__construct($out); @@ -325,7 +327,6 @@ class GroupBlockForm extends Form * * @return int ID of the form */ - function id() { // This should be unique for the page. @@ -337,7 +338,6 @@ class GroupBlockForm extends Form * * @return string class of the form */ - function formClass() { return 'form_group_block'; @@ -348,7 +348,6 @@ class GroupBlockForm extends Form * * @return string URL of the action */ - function action() { return common_local_url('groupblock'); @@ -361,6 +360,7 @@ class GroupBlockForm extends Form */ function formLegend() { + // TRANS: Form legend for form to block user from a group. $this->out->element('legend', null, _('Block user from group')); } @@ -369,7 +369,6 @@ class GroupBlockForm extends Form * * @return void */ - function formData() { $this->out->hidden('blockto-' . $this->profile->id, @@ -390,7 +389,6 @@ class GroupBlockForm extends Form * * @return void */ - function formActions() { $this->out->submit( @@ -414,25 +412,21 @@ class GroupBlockForm extends Form * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class MakeAdminForm extends Form { /** * Profile of user to block */ - var $profile = null; /** * Group to block the user from */ - var $group = null; /** * Return-to args */ - var $args = null; /** @@ -443,7 +437,6 @@ class MakeAdminForm extends Form * @param User_group $group group to block user from * @param array $args return-to args */ - function __construct($out=null, $profile=null, $group=null, $args=null) { parent::__construct($out); @@ -458,7 +451,6 @@ class MakeAdminForm extends Form * * @return int ID of the form */ - function id() { // This should be unique for the page. @@ -470,7 +462,6 @@ class MakeAdminForm extends Form * * @return string class of the form */ - function formClass() { return 'form_make_admin'; @@ -481,7 +472,6 @@ class MakeAdminForm extends Form * * @return string URL of the action */ - function action() { return common_local_url('makeadmin', array('nickname' => $this->group->nickname)); @@ -492,9 +482,9 @@ class MakeAdminForm extends Form * * @return void */ - function formLegend() { + // TRANS: Form legend for form to make a user a group admin. $this->out->element('legend', null, _('Make user an admin of the group')); } @@ -503,7 +493,6 @@ class MakeAdminForm extends Form * * @return void */ - function formData() { $this->out->hidden('profileid-' . $this->profile->id, @@ -524,7 +513,6 @@ class MakeAdminForm extends Form * * @return void */ - function formActions() { $this->out->submit( diff --git a/actions/grouprss.php b/actions/grouprss.php index 98fdea38de..39dcff83d9 100644 --- a/actions/grouprss.php +++ b/actions/grouprss.php @@ -45,7 +45,6 @@ define('MEMBERS_PER_SECTION', 27); * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class groupRssAction extends Rss10Action { /** group we're viewing. */ @@ -56,7 +55,6 @@ class groupRssAction extends Rss10Action * * @return boolean true */ - function isReadOnly($args) { return true; @@ -71,7 +69,6 @@ class groupRssAction extends Rss10Action * * @return boolean success flag */ - function prepare($args) { parent::prepare($args); @@ -88,6 +85,7 @@ class groupRssAction extends Rss10Action } if (!$nickname) { + // TRANS: Client error displayed when requesting a group RSS feed without providing a group nickname. $this->clientError(_('No nickname.'), 404); return false; } @@ -95,6 +93,7 @@ class groupRssAction extends Rss10Action $local = Local_group::staticGet('nickname', $nickname); if (!$local) { + // TRANS: Client error displayed when requesting a group RSS feed for group that does not exist. $this->clientError(_('No such group.'), 404); return false; } @@ -102,6 +101,7 @@ class groupRssAction extends Rss10Action $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { + // TRANS: Client error displayed when requesting a group RSS feed for an object that is not a group. $this->clientError(_('No such group.'), 404); return false; } @@ -112,7 +112,6 @@ class groupRssAction extends Rss10Action function getNotices($limit=0) { - $group = $this->group; if (is_null($group)) { diff --git a/actions/groups.php b/actions/groups.php index 8aacff8b0e..958c5921bf 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -45,7 +45,6 @@ require_once INSTALLDIR.'/lib/grouplist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupsAction extends Action { var $page = null; @@ -59,9 +58,12 @@ class GroupsAction extends Action function title() { if ($this->page == 1) { - return _("Groups"); + // TRANS: Title for first page of the groups list. + return _m('TITLE',"Groups"); } else { - return sprintf(_("Groups, page %d"), $this->page); + // TRANS: Title for all but the first page of the groups list. + // TRANS: %d is the page number. + return sprintf(_m('TITLE',"Groups, page %d"), $this->page); } } @@ -87,12 +89,15 @@ class GroupsAction extends Action function showPageNotice() { $notice = + // TRANS: Page notice of group list. %%%%site.name%%%% is the StatusNet site name, + // TRANS: %%%%action.groupsearch%%%% and %%%%action.newgroup%%%% are URLs. Do not change them. + // TRANS: This message contains Markdown links in the form [link text](link). sprintf(_('%%%%site.name%%%% groups let you find and talk with ' . 'people of similar interests. After you join a group ' . 'you can send messages to all other members using the ' . 'syntax "!groupname". Don\'t see a group you like? Try ' . '[searching for one](%%%%action.groupsearch%%%%) or ' . - '[start your own!](%%%%action.newgroup%%%%)')); + '[start your own](%%%%action.newgroup%%%%)!')); $this->elementStart('div', 'instructions'); $this->raw(common_markup_to_html($notice)); $this->elementEnd('div'); @@ -104,6 +109,7 @@ class GroupsAction extends Action $this->elementStart('p', array('id' => 'new_group')); $this->element('a', array('href' => common_local_url('newgroup'), 'class' => 'more'), + // TRANS: Link to create a new group on the group list page. _('Create a new group')); $this->elementEnd('p'); } diff --git a/actions/groupsearch.php b/actions/groupsearch.php index 55f4cee625..fce5c2b16a 100644 --- a/actions/groupsearch.php +++ b/actions/groupsearch.php @@ -49,12 +49,14 @@ class GroupsearchAction extends SearchAction { function getInstructions() { + // TRANS: Instructions for page where groups can be searched. %%site.name%% is the name of the StatusNet site. return _('Search for groups on %%site.name%% by their name, location, or description. ' . 'Separate the terms by spaces; they must be 3 characters or more.'); } function title() { + // TRANS: Title for page where groups can be searched. return _('Group search'); } @@ -76,12 +78,17 @@ class GroupsearchAction extends SearchAction $this->pagination($page > 1, $cnt > GROUPS_PER_PAGE, $page, 'groupsearch', array('q' => $q)); } else { + // TRANS: Text on page where groups can be searched if no results were found for a query. $this->element('p', 'error', _('No results.')); $this->searchSuggestions($q); if (common_logged_in()) { - $message = _('If you can\'t find the group you\'re looking for, you can [create it](%%action.newgroup%%) yourself.'); + // TRANS: Additional text on page where groups can be searched if no results were found for a query for a logged in user. + // TRANS: This message contains Markdown links in the form [link text](link). + $message = _('If you cannot find the group you\'re looking for, you can [create it](%%action.newgroup%%) yourself.'); } else { + // TRANS: Additional text on page where groups can be searched if no results were found for a query for a not logged in user. + // TRANS: This message contains Markdown links in the form [link text](link). $message = _('Why not [register an account](%%action.register%%) and [create the group](%%action.newgroup%%) yourself!'); } $this->elementStart('div', 'guide'); @@ -116,4 +123,3 @@ class GroupSearchResults extends GroupList return preg_replace($this->pattern, '\\1', htmlspecialchars($text)); } } - diff --git a/actions/groupunblock.php b/actions/groupunblock.php index ef2380725e..de0af59821 100644 --- a/actions/groupunblock.php +++ b/actions/groupunblock.php @@ -79,6 +79,7 @@ class GroupunblockAction extends Action } $group_id = $this->trimmed('unblockgroup'); if (empty($group_id)) { + // TRANS: Client error displayed when trying to unblock a user from a group without providing a group. $this->clientError(_('No group specified.')); return false; } diff --git a/actions/hcard.php b/actions/hcard.php index 55d0f65c8f..8781f6f882 100644 --- a/actions/hcard.php +++ b/actions/hcard.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 * @link http://status.net/ */ - class HcardAction extends Action { var $user; @@ -64,6 +63,7 @@ class HcardAction extends Action $this->user = User::staticGet('nickname', $nickname); if (!$this->user) { + // TRANS: Client error displayed when trying to get a user hCard for a non-existing user. $this->clientError(_('No such user.'), 404); return false; } @@ -71,6 +71,7 @@ class HcardAction extends Action $this->profile = $this->user->getProfile(); if (!$this->profile) { + // TRANS: Server error displayed when trying to get a user hCard for a user without a profile. $this->serverError(_('User has no profile.')); return false; } @@ -117,4 +118,4 @@ class ShortUserProfile extends UserProfile { return; } -} \ No newline at end of file +} diff --git a/actions/hostmeta.php b/actions/hostmeta.php index 331fc8a999..e921b5ad59 100644 --- a/actions/hostmeta.php +++ b/actions/hostmeta.php @@ -28,9 +28,9 @@ if (!defined('STATUSNET')) { exit(1); } +// @todo XXX: Add documentation. class HostMetaAction extends Action { - /** * Is read only? * diff --git a/actions/imsettings.php b/actions/imsettings.php index 76fb2285c3..4680b3292b 100644 --- a/actions/imsettings.php +++ b/actions/imsettings.php @@ -50,10 +50,9 @@ class ImsettingsAction extends SettingsAction * * @return string Title of the page */ - function title() { - // TRANS: Title for instance messaging settings. + // TRANS: Title for Instant Messaging settings. return _('IM settings'); } @@ -62,7 +61,6 @@ class ImsettingsAction extends SettingsAction * * @return instructions for use */ - function getInstructions() { // TRANS: Instant messaging settings page instructions. @@ -82,7 +80,6 @@ class ImsettingsAction extends SettingsAction * * @return void */ - function showContent() { $transports = array(); @@ -210,8 +207,12 @@ class ImsettingsAction extends SettingsAction * * @return Confirm_address address object for this user */ +<<<<<<< HEAD function getConfirmation($transport) +======= + function getConfirmation() +>>>>>>> 0.9.x { $user = common_current_user(); @@ -237,7 +238,6 @@ class ImsettingsAction extends SettingsAction * * @return void */ - function handlePost() { // CSRF protection @@ -257,7 +257,7 @@ class ImsettingsAction extends SettingsAction } else if ($this->arg('remove')) { $this->removeAddress(); } else { - // TRANS: Message given submitting a form with an unknown action in IM settings. + // TRANS: Message given submitting a form with an unknown action in Instant Messaging settings. $this->showForm(_('Unexpected form submission.')); } } @@ -270,7 +270,6 @@ class ImsettingsAction extends SettingsAction * * @return void */ - function savePreferences() { $user = common_current_user(); @@ -312,7 +311,6 @@ class ImsettingsAction extends SettingsAction * * @return void */ - function addAddress() { $user = common_current_user(); @@ -365,8 +363,8 @@ class ImsettingsAction extends SettingsAction 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.')); + // TRANS: Server error thrown on database error adding Instant Messaging confirmation code. + $this->serverError(_('Could not insert confirmation code.')); return; } @@ -386,7 +384,6 @@ class ImsettingsAction extends SettingsAction * * @return void */ - function cancelConfirmation() { $screenname = $this->trimmed('screenname'); @@ -395,7 +392,7 @@ class ImsettingsAction extends SettingsAction $confirm = $this->getConfirmation($transport); if (!$confirm) { - // TRANS: Message given canceling IM address confirmation that is not pending. + // TRANS: Message given canceling Instant Messaging address confirmation that is not pending. $this->showForm(_('No pending confirmation to cancel.')); return; } @@ -425,7 +422,6 @@ class ImsettingsAction extends SettingsAction * * @return void */ - function removeAddress() { $user = common_current_user(); @@ -456,7 +452,7 @@ class ImsettingsAction extends SettingsAction // XXX: unsubscribe to the old address - // TRANS: Message given after successfully removing a registered IM address. + // TRANS: Message given after successfully removing a registered Instant Messaging address. $this->showForm(_('The IM address was removed.'), true); } diff --git a/actions/inbox.php b/actions/inbox.php index 8330f753ff..e9aa34317d 100644 --- a/actions/inbox.php +++ b/actions/inbox.php @@ -43,7 +43,6 @@ require_once INSTALLDIR.'/lib/mailbox.php'; * @link http://status.net/ * @see MailboxAction */ - class InboxAction extends MailboxAction { @@ -52,13 +51,16 @@ class InboxAction extends MailboxAction * * @return string page title */ - function title() { if ($this->page > 1) { + // TRANS: Title for all but the first page of the inbox page. + // TRANS: %1$s is the user's nickname, %2$s is the page number. return sprintf(_('Inbox for %1$s - page %2$d'), $this->user->nickname, $this->page); } else { + // TRANS: Title for the first page of the inbox page. + // TRANS: %s is the user's nickname. return sprintf(_('Inbox for %s'), $this->user->nickname); } } @@ -72,7 +74,6 @@ class InboxAction extends MailboxAction * * @see MailboxAction::getMessages() */ - function getMessages() { $message = new Message(); @@ -89,19 +90,9 @@ class InboxAction extends MailboxAction } } - /** - * Returns the profile we want to show with the message - * - * For inboxes, we show the sender; for outboxes, the recipient. - * - * @param Message $message The message to get the profile for - * - * @return Profile The profile that matches the message - */ - - function getMessageProfile($message) + function getMessageList($message) { - return $message->getFrom(); + return new InboxMessageList($this, $message); } /** @@ -109,9 +100,30 @@ class InboxAction extends MailboxAction * * @return string localised instructions for using the page */ - function getInstructions() { + // TRANS: Instructions for user inbox page. return _('This is your inbox, which lists your incoming private messages.'); } } + +class InboxMessageList extends MessageList +{ + function newItem($message) + { + return new InboxMessageListItem($this->out, $message); + } +} + +class InboxMessageListItem extends MessageListItem +{ + /** + * Returns the profile we want to show with the message + * + * @return Profile The profile that matches the message + */ + function getMessageProfile() + { + return $this->message->getFrom(); + } +} diff --git a/actions/invite.php b/actions/invite.php index e9adb3b7f9..a2a0e0714a 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -19,6 +19,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +// @todo XXX: Add documentation. class InviteAction extends CurrentUserDesignAction { var $mode = null; @@ -217,7 +218,7 @@ class InviteAction extends CurrentUserDesignAction $this->textarea('addresses', _('Email addresses'), $this->trimmed('addresses'), // TRANS: Tooltip for field label for a list of e-mail addresses. - _('Addresses of friends to invite (one per line)')); + _('Addresses of friends to invite (one per line).')); $this->elementEnd('li'); $this->elementStart('li'); // TRANS: Field label for a personal message to send to invitees. diff --git a/actions/joingroup.php b/actions/joingroup.php index f87e5dae29..7beaf4f64a 100644 --- a/actions/joingroup.php +++ b/actions/joingroup.php @@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class JoingroupAction extends Action { var $group = null; @@ -51,12 +50,12 @@ class JoingroupAction extends Action /** * Prepare to run */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed when trying to join a group while not logged in. $this->clientError(_('You must be logged in to join a group.')); return false; } @@ -79,17 +78,20 @@ class JoingroupAction extends Action $local = Local_group::staticGet('nickname', $nickname); if (!$local) { + // TRANS: Client error displayed when trying to join a non-local group. $this->clientError(_('No such group.'), 404); return false; } $this->group = User_group::staticGet('id', $local->group_id); } else { + // TRANS: Client error displayed when trying to join a group without providing a group name or group ID. $this->clientError(_('No nickname or ID.'), 404); return false; } if (!$this->group) { + // TRANS: Client error displayed when trying to join a non-existing group. $this->clientError(_('No such group.'), 404); return false; } @@ -97,11 +99,13 @@ class JoingroupAction extends Action $cur = common_current_user(); if ($cur->isMember($this->group)) { + // TRANS: Client error displayed when trying to join a group while already a member. $this->clientError(_('You are already a member of that group.'), 403); return false; } if (Group_block::isBlocked($this->group, $cur->getProfile())) { + // TRANS: Client error displayed when trying to join a group while being blocked form joining it. $this->clientError(_('You have been blocked from that group by the admin.'), 403); return false; } @@ -118,7 +122,6 @@ class JoingroupAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -131,6 +134,8 @@ class JoingroupAction extends Action Event::handle('EndJoinGroup', array($this->group, $cur)); } } catch (Exception $e) { + // TRANS: Server error displayed when joining a group failed in the database. + // TRANS: %1$s is the joining user's nickname, $2$s is the group nickname for which the join failed. $this->serverError(sprintf(_('Could not join user %1$s to group %2$s.'), $cur->nickname, $this->group->nickname)); } @@ -138,7 +143,8 @@ class JoingroupAction extends Action if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); - $this->element('title', null, sprintf(_('%1$s joined group %2$s'), + // TRANS: Title for join group page after joining. + $this->element('title', null, sprintf(_m('TITLE','%1$s joined group %2$s'), $cur->nickname, $this->group->nickname)); $this->elementEnd('head'); @@ -153,4 +159,4 @@ class JoingroupAction extends Action 303); } } -} \ No newline at end of file +} diff --git a/actions/leavegroup.php b/actions/leavegroup.php index 329b5aafe1..f5d1ccd08c 100644 --- a/actions/leavegroup.php +++ b/actions/leavegroup.php @@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class LeavegroupAction extends Action { var $group = null; @@ -51,12 +50,12 @@ class LeavegroupAction extends Action /** * Prepare to run */ - function prepare($args) { parent::prepare($args); if (!common_logged_in()) { + // TRANS: Client error displayed when trying to leave a group while not logged in. $this->clientError(_('You must be logged in to leave a group.')); return false; } @@ -79,17 +78,20 @@ class LeavegroupAction extends Action $local = Local_group::staticGet('nickname', $nickname); if (!$local) { + // TRANS: Client error displayed when trying to leave a non-local group. $this->clientError(_('No such group.'), 404); return false; } $this->group = User_group::staticGet('id', $local->group_id); } else { + // TRANS: Client error displayed when trying to leave a group without providing a group name or group ID. $this->clientError(_('No nickname or ID.'), 404); return false; } if (!$this->group) { + // TRANS: Client error displayed when trying to leave a non-existing group. $this->clientError(_('No such group.'), 404); return false; } @@ -97,6 +99,7 @@ class LeavegroupAction extends Action $cur = common_current_user(); if (!$cur->isMember($this->group)) { + // TRANS: Client error displayed when trying to join a group while already a member. $this->clientError(_('You are not a member of that group.'), 403); return false; } @@ -113,7 +116,6 @@ class LeavegroupAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -126,6 +128,8 @@ class LeavegroupAction extends Action Event::handle('EndLeaveGroup', array($this->group, $cur)); } } catch (Exception $e) { + // TRANS: Server error displayed when leaving a group failed in the database. + // TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed. $this->serverError(sprintf(_('Could not remove user %1$s from group %2$s.'), $cur->nickname, $this->group->nickname)); return; @@ -134,7 +138,8 @@ class LeavegroupAction extends Action if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); - $this->element('title', null, sprintf(_('%1$s left group %2$s'), + // TRANS: Title for leave group page after leaving. + $this->element('title', null, sprintf(_m('TITLE','%1$s left group %2$s'), $cur->nickname, $this->group->nickname)); $this->elementEnd('head'); diff --git a/actions/licenseadminpanel.php b/actions/licenseadminpanel.php index 95ac48cc8f..4adeb5c3c6 100644 --- a/actions/licenseadminpanel.php +++ b/actions/licenseadminpanel.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class LicenseadminpanelAction extends AdminPanelAction { @@ -61,7 +60,6 @@ class LicenseadminpanelAction extends AdminPanelAction * * @return string instructions */ - function getInstructions() { return _('License for this StatusNet site'); @@ -72,7 +70,6 @@ class LicenseadminpanelAction extends AdminPanelAction * * @return void */ - function showForm() { $form = new LicenseAdminPanelForm($this); @@ -85,7 +82,6 @@ class LicenseadminpanelAction extends AdminPanelAction * * @return void */ - function saveSettings() { static $settings = array( @@ -128,7 +124,6 @@ class LicenseadminpanelAction extends AdminPanelAction * * @return nothing */ - function validate(&$values) { // Validate license type (shouldn't have to do it, but just in case) @@ -197,7 +192,6 @@ class LicenseAdminPanelForm extends AdminForm * * @return int ID of the form */ - function id() { return 'licenseadminpanel'; @@ -208,7 +202,6 @@ class LicenseAdminPanelForm extends AdminForm * * @return string class of the form */ - function formClass() { return 'form_settings'; @@ -312,7 +305,6 @@ class LicenseAdminPanelForm extends AdminForm * * @return void */ - function formActions() { $this->out->submit( diff --git a/actions/login.php b/actions/login.php index 103df7ee5a..8d51a01449 100644 --- a/actions/login.php +++ b/actions/login.php @@ -42,13 +42,11 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class LoginAction extends Action { /** * Has there been an error? */ - var $error = null; /** @@ -56,12 +54,32 @@ class LoginAction extends Action * * @return boolean false */ - function isReadOnly($args) { return false; } + /** + * Prepare page to run + * + * + * @param $args + * @return string title + */ + function prepare($args) + { + parent::prepare($args); + + // @todo this check should really be in index.php for all sensitive actions + $ssl = common_config('site', 'ssl'); + if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) { + common_redirect(common_local_url('login')); + // exit + } + + return true; + } + /** * Handle input, produce output * @@ -71,7 +89,6 @@ class LoginAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -95,8 +112,7 @@ class LoginAction extends Action * * @return void */ - - function checkLogin($user_id=null) + function checkLogin($user_id=null, $token=null) { // XXX: login throttle @@ -147,7 +163,6 @@ class LoginAction extends Action * * @return void */ - function showForm($error=null) { $this->error = $error; @@ -165,7 +180,6 @@ class LoginAction extends Action * * @return string title of the page */ - function title() { return _('Login'); @@ -179,7 +193,6 @@ class LoginAction extends Action * * @return void */ - function showPageNotice() { if ($this->error) { @@ -199,7 +212,6 @@ class LoginAction extends Action * * @return void */ - function showContent() { $this->elementStart('form', array('method' => 'post', @@ -238,7 +250,6 @@ class LoginAction extends Action * * @return void */ - function getInstructions() { if (common_logged_in() && !common_is_real_login() && @@ -266,7 +277,6 @@ class LoginAction extends Action * * @return void */ - function showLocalNav() { $nav = new LoginGroupNav($this); diff --git a/actions/logout.php b/actions/logout.php index 1e0adae575..f747371225 100644 --- a/actions/logout.php +++ b/actions/logout.php @@ -66,6 +66,7 @@ class LogoutAction extends Action { parent::handle($args); if (!common_logged_in()) { + // TRANS: Client error displayed trying to log out when not logged in. $this->clientError(_('Not logged in.')); } else { if (Event::handle('StartLogout', array($this))) { @@ -83,5 +84,4 @@ class LogoutAction extends Action common_real_login(false); // not logged in common_forgetme(); // don't log back in! } - } diff --git a/actions/newapplication.php b/actions/newapplication.php index ae17545589..eb13593536 100644 --- a/actions/newapplication.php +++ b/actions/newapplication.php @@ -55,7 +55,6 @@ class NewApplicationAction extends OwnerDesignAction /** * Prepare to run */ - function prepare($args) { parent::prepare($args); @@ -78,7 +77,6 @@ class NewApplicationAction extends OwnerDesignAction * * @return void */ - function handle($args) { parent::handle($args); @@ -122,6 +120,7 @@ class NewApplicationAction extends OwnerDesignAction } elseif ($this->arg('save')) { $this->trySave(); } else { + // TRANS: Client error displayed when encountering an unexpected action on form submission. $this->clientError(_('Unexpected form submission.')); } } @@ -144,6 +143,7 @@ class NewApplicationAction extends OwnerDesignAction $this->element('p', 'error', $this->msg); } else { $this->element('p', 'instructions', + // TRANS: Form instructions for registering a new application. _('Use this form to register a new application.')); } } @@ -160,15 +160,19 @@ class NewApplicationAction extends OwnerDesignAction $access_type = $this->arg('default_access_type'); if (empty($name)) { + // TRANS: Validation error shown when not providing a name in the "New application" form. $this->showForm(_('Name is required.')); return; } else if ($this->nameExists($name)) { + // TRANS: Validation error shown when providing a name for an application that already exists in the "New application" form. $this->showForm(_('Name already in use. Try another one.')); return; } elseif (mb_strlen($name) > 255) { + // TRANS: Validation error shown when providing too long a name in the "New application" form. $this->showForm(_('Name is too long (maximum 255 characters).')); return; } elseif (empty($description)) { + // TRANS: Validation error shown when not providing a description in the "New application" form. $this->showForm(_('Description is required.')); return; } elseif (Oauth_application::descriptionTooLong($description)) { @@ -181,6 +185,7 @@ class NewApplicationAction extends OwnerDesignAction Oauth_application::maxDesc())); return; } elseif (empty($source_url)) { + // TRANS: Validation error shown when not providing a source URL in the "New application" form. $this->showForm(_('Source URL is required.')); return; } elseif ((strlen($source_url) > 0) @@ -190,15 +195,19 @@ class NewApplicationAction extends OwnerDesignAction ) ) { + // TRANS: Validation error shown when providing an invalid source URL in the "New application" form. $this->showForm(_('Source URL is not valid.')); return; } elseif (empty($organization)) { + // TRANS: Validation error shown when not providing an organisation in the "New application" form. $this->showForm(_('Organization is required.')); return; } elseif (mb_strlen($organization) > 255) { + // TRANS: Validation error shown when providing too long an arganisation name in the "Edit application" form. $this->showForm(_('Organization is too long (maximum 255 characters).')); return; } elseif (empty($homepage)) { + // TRANS: Form validation error show when an organisation name has not been provided in the new application form. $this->showForm(_('Organization homepage is required.')); return; } elseif ((strlen($homepage) > 0) @@ -208,9 +217,11 @@ class NewApplicationAction extends OwnerDesignAction ) ) { + // TRANS: Validation error shown when providing an invalid homepage URL in the "New application" form. $this->showForm(_('Homepage is not a valid URL.')); return; } elseif (mb_strlen($callback_url) > 255) { + // TRANS: Validation error shown when providing too long a callback URL in the "New application" form. $this->showForm(_('Callback is too long.')); return; } elseif (strlen($callback_url) > 0 @@ -220,6 +231,7 @@ class NewApplicationAction extends OwnerDesignAction ) ) { + // TRANS: Validation error shown when providing an invalid callback URL in the "New application" form. $this->showForm(_('Callback URL is not valid.')); return; } @@ -263,6 +275,7 @@ class NewApplicationAction extends OwnerDesignAction if (!$result) { common_log_db_error($consumer, 'INSERT', __FILE__); + // TRANS: Server error displayed when an application could not be registered in the database through the "New application" form. $this->serverError(_('Could not create application.')); } @@ -272,6 +285,7 @@ class NewApplicationAction extends OwnerDesignAction if (!$this->app_id) { common_log_db_error($app, 'INSERT', __FILE__); + // TRANS: Server error displayed when an application could not be registered in the database through the "New application" form. $this->serverError(_('Could not create application.')); $app->query('ROLLBACK'); } @@ -281,7 +295,6 @@ class NewApplicationAction extends OwnerDesignAction $app->query('COMMIT'); common_redirect(common_local_url('oauthappssettings'), 303); - } /** @@ -294,12 +307,9 @@ class NewApplicationAction extends OwnerDesignAction * * @return boolean true if the name already exists */ - function nameExists($name) { $app = Oauth_application::staticGet('name', $name); return !empty($app); } - } - diff --git a/actions/newgroup.php b/actions/newgroup.php index 42d488e54e..9682b875cb 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -120,105 +120,109 @@ class NewgroupAction extends Action function trySave() { - try { - $nickname = Nickname::normalize($this->trimmed('nickname')); - } catch (NicknameException $e) { - $this->showForm($e->getMessage()); - } - $fullname = $this->trimmed('fullname'); - $homepage = $this->trimmed('homepage'); - $description = $this->trimmed('description'); - $location = $this->trimmed('location'); - $aliasstring = $this->trimmed('aliases'); + if (Event::handle('StartGroupSaveForm', array($this))) { + try { + $nickname = Nickname::normalize($this->trimmed('nickname')); + } catch (NicknameException $e) { + $this->showForm($e->getMessage()); + } + $fullname = $this->trimmed('fullname'); + $homepage = $this->trimmed('homepage'); + $description = $this->trimmed('description'); + $location = $this->trimmed('location'); + $aliasstring = $this->trimmed('aliases'); - if ($this->nicknameExists($nickname)) { - // TRANS: Group create form validation error. - $this->showForm(_('Nickname already in use. Try another one.')); - return; - } else if (!User_group::allowedNickname($nickname)) { - // TRANS: Group create form validation error. - $this->showForm(_('Not a valid nickname.')); - return; - } else if (!is_null($homepage) && (strlen($homepage) > 0) && - !Validate::uri($homepage, - array('allowed_schemes' => - array('http', 'https')))) { - // TRANS: Group create form validation error. - $this->showForm(_('Homepage is not a valid URL.')); - return; - } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { - // TRANS: Group create form validation error. - $this->showForm(_('Full name is too long (maximum 255 characters).')); - return; - } else if (User_group::descriptionTooLong($description)) { - // TRANS: Group create form validation error. - // TRANS: %d is the maximum number of allowed characters. - $this->showForm(sprintf(_m('Description is too long (maximum %d character).', - 'Description is too long (maximum %d characters).', - User_group::maxDescription()), - User_group::maxDescription())); - return; - } else if (!is_null($location) && mb_strlen($location) > 255) { - // TRANS: Group create form validation error. - $this->showForm(_('Location is too long (maximum 255 characters).')); - return; - } - - if (!empty($aliasstring)) { - $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring))); - } else { - $aliases = array(); - } - - if (count($aliases) > common_config('group', 'maxaliases')) { - // TRANS: Group create form validation error. - // TRANS: %d is the maximum number of allowed aliases. - $this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.', - 'Too many aliases! Maximum %d allowed.', - common_config('group', 'maxaliases')), - common_config('group', 'maxaliases'))); - return; - } - - foreach ($aliases as $alias) { - if (!Nickname::isValid($alias)) { + if ($this->nicknameExists($nickname)) { // TRANS: Group create form validation error. - $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias)); + $this->showForm(_('Nickname already in use. Try another one.')); + return; + } else if (!User_group::allowedNickname($nickname)) { + // TRANS: Group create form validation error. + $this->showForm(_('Not a valid nickname.')); + return; + } else if (!is_null($homepage) && (strlen($homepage) > 0) && + !Validate::uri($homepage, + array('allowed_schemes' => + array('http', 'https')))) { + // TRANS: Group create form validation error. + $this->showForm(_('Homepage is not a valid URL.')); + return; + } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { + // TRANS: Group create form validation error. + $this->showForm(_('Full name is too long (maximum 255 characters).')); + return; + } else if (User_group::descriptionTooLong($description)) { + // TRANS: Group create form validation error. + // TRANS: %d is the maximum number of allowed characters. + $this->showForm(sprintf(_m('Description is too long (maximum %d character).', + 'Description is too long (maximum %d characters).', + User_group::maxDescription()), + User_group::maxDescription())); + return; + } else if (!is_null($location) && mb_strlen($location) > 255) { + // TRANS: Group create form validation error. + $this->showForm(_('Location is too long (maximum 255 characters).')); return; } - if ($this->nicknameExists($alias)) { + + if (!empty($aliasstring)) { + $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring))); + } else { + $aliases = array(); + } + + if (count($aliases) > common_config('group', 'maxaliases')) { // TRANS: Group create form validation error. - $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'), - $alias)); + // TRANS: %d is the maximum number of allowed aliases. + $this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.', + 'Too many aliases! Maximum %d allowed.', + common_config('group', 'maxaliases')), + common_config('group', 'maxaliases'))); return; } - // XXX assumes alphanum nicknames - if (strcmp($alias, $nickname) == 0) { - // TRANS: Group create form validation error. - $this->showForm(_('Alias can\'t be the same as nickname.')); - return; + + foreach ($aliases as $alias) { + if (!Nickname::isValid($alias)) { + // TRANS: Group create form validation error. + // TRANS: %s is the invalid alias. + $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias)); + return; + } + if ($this->nicknameExists($alias)) { + // TRANS: Group create form validation error. %s is the already used alias. + $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'), + $alias)); + return; + } + // XXX assumes alphanum nicknames + if (strcmp($alias, $nickname) == 0) { + // TRANS: Group create form validation error. + $this->showForm(_('Alias cannot be the same as nickname.')); + return; + } } + + $cur = common_current_user(); + + // Checked in prepare() above + + assert(!is_null($cur)); + + $group = User_group::register(array('nickname' => $nickname, + 'fullname' => $fullname, + 'homepage' => $homepage, + 'description' => $description, + 'location' => $location, + 'aliases' => $aliases, + 'userid' => $cur->id, + 'local' => true)); + + $this->group = $group; + + Event::handle('EndGroupSaveForm', array($this)); + + common_redirect($group->homeUrl(), 303); } - - $mainpage = common_local_url('showgroup', array('nickname' => $nickname)); - - $cur = common_current_user(); - - // Checked in prepare() above - - assert(!is_null($cur)); - - $group = User_group::register(array('nickname' => $nickname, - 'fullname' => $fullname, - 'homepage' => $homepage, - 'description' => $description, - 'location' => $location, - 'aliases' => $aliases, - 'userid' => $cur->id, - 'mainpage' => $mainpage, - 'local' => true)); - - common_redirect($group->homeUrl(), 303); } function nicknameExists($nickname) diff --git a/actions/noticesearch.php b/actions/noticesearch.php index d0673420d6..4f4c7a05ba 100644 --- a/actions/noticesearch.php +++ b/actions/noticesearch.php @@ -48,7 +48,6 @@ require_once INSTALLDIR.'/lib/searchaction.php'; */ class NoticesearchAction extends SearchAction { - function prepare($args) { parent::prepare($args); @@ -65,6 +64,8 @@ class NoticesearchAction extends SearchAction */ function getInstructions() { + // TRANS: Instructions for Notice search page. + // TRANS: %%site.name%% is the name of the StatusNet site. return _('Search for notices on %%site.name%% by their contents. Separate search terms by spaces; they must be 3 characters or more.'); } @@ -75,6 +76,7 @@ class NoticesearchAction extends SearchAction */ function title() { + // TRANS: Title of the page where users can search for notices. return _('Text search'); } @@ -88,6 +90,8 @@ class NoticesearchAction extends SearchAction return array(new Feed(Feed::RSS1, common_local_url('noticesearchrss', array('q' => $q)), + // TRANS: Test in RSS notice search. + // TRANS: %1$s is the query, %2$s is the StatusNet site name. sprintf(_('Search results for "%1$s" on %2$s'), $q, common_config('site', 'name')))); } @@ -114,13 +118,18 @@ class NoticesearchAction extends SearchAction $cnt = $notice->find(); } if ($cnt === 0) { + // TRANS: Text for notice search results is the query had no results. $this->element('p', 'error', _('No results.')); $this->searchSuggestions($q); if (common_logged_in()) { + // TRANS: Text for logged in users making a query for notices without results. + // TRANS: This message contains a Markdown link. $message = sprintf(_('Be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!'), urlencode($q)); } else { + // TRANS: Text for not logged in users making a query for notices without results. + // TRANS: This message contains Markdown links. $message = sprintf(_('Why not [register an account](%%%%action.register%%%%) and be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!'), urlencode($q)); } @@ -193,14 +202,20 @@ class SearchNoticeListItem extends NoticeListItem { $options = implode('|', array_map('preg_quote', array_map('htmlspecialchars', $terms), array_fill(0, sizeof($terms), '/'))); $pattern = "/($options)/i"; - $result = preg_replace($pattern, '\\1', $text); + $result = ''; + + /* Divide up into text (highlight me) and tags (don't touch) */ + $chunks = preg_split('/(<[^>]+>)/', $text, 0, PREG_SPLIT_DELIM_CAPTURE); + foreach ($chunks as $i => $chunk) { + if ($i % 2 == 1) { + // odd: delimiter (tag) + $result .= $chunk; + } else { + // even: freetext between tags + $result .= preg_replace($pattern, '\\1', $chunk); + } + } - /* Remove highlighting from inside links, loop incase multiple highlights in links */ - $pattern = '/(\w+="[^"]*)('.$options.')<\/strong>([^"]*")/iU'; - do { - $result = preg_replace($pattern, '\\1\\2\\3', $result, -1, $count); - } while ($count); return $result; } } - diff --git a/actions/noticesearchrss.php b/actions/noticesearchrss.php index a59e7b99be..14c280f62c 100644 --- a/actions/noticesearchrss.php +++ b/actions/noticesearchrss.php @@ -48,12 +48,11 @@ require_once INSTALLDIR.'/lib/rssaction.php'; */ class NoticesearchrssAction extends Rss10Action { - function init() { return true; } - + function prepare($args) { parent::prepare($args); @@ -63,7 +62,6 @@ class NoticesearchrssAction extends Rss10Action function getNotices($limit=0) { - $q = $this->trimmed('q'); $notices = array(); @@ -93,9 +91,12 @@ class NoticesearchrssAction extends Rss10Action { $q = $this->trimmed('q'); $c = array('url' => common_local_url('noticesearchrss', array('q' => $q)), + // TRANS: RSS notice search feed title. %s is the query. 'title' => sprintf(_('Updates with "%s"'), $q), 'link' => common_local_url('noticesearch', array('q' => $q)), - 'description' => sprintf(_('Updates matching search term "%1$s" on %2$s!'), + // TRANS: RSS notice search feed description. + // TRANS: %1$s is the query, %2$s is the StatusNet site name. + 'description' => sprintf(_('Updates matching search term "%1$s" on %2$s.'), $q, common_config('site', 'name'))); return $c; } diff --git a/actions/oauthappssettings.php b/actions/oauthappssettings.php index 3a8fc98966..a7a4b219a3 100644 --- a/actions/oauthappssettings.php +++ b/actions/oauthappssettings.php @@ -163,6 +163,5 @@ class OauthappssettingsAction extends SettingsAction 'Try again, please.')); return; } - } } diff --git a/actions/oauthconnectionssettings.php b/actions/oauthconnectionssettings.php index c173a32230..b2e6f713a9 100644 --- a/actions/oauthconnectionssettings.php +++ b/actions/oauthconnectionssettings.php @@ -62,7 +62,6 @@ class OauthconnectionssettingsAction extends SettingsAction * * @return string Title of the page */ - function title() { // TRANS: Title for OAuth connection settings. @@ -74,7 +73,6 @@ class OauthconnectionssettingsAction extends SettingsAction * * @return instructions for use */ - function getInstructions() { // TRANS: Instructions for OAuth connection settings. diff --git a/actions/oembed.php b/actions/oembed.php index bef707f92a..0d8be55656 100644 --- a/actions/oembed.php +++ b/actions/oembed.php @@ -61,7 +61,7 @@ class OembedAction extends Action $proxy_args = $r->map($path); if (!$proxy_args) { - $this->serverError(_("$path not found."), 404); + $this->serverError(sprintf(_('"%s" not found.'),$path), 404); } $oembed=array(); $oembed['version']='1.0'; @@ -73,7 +73,7 @@ class OembedAction extends Action $id = $proxy_args['notice']; $notice = Notice::staticGet($id); if(empty($notice)){ - $this->serverError(_("Notice $id not found."), 404); + $this->serverError(sprintf(_("Notice %s not found."),$id), 404); } $profile = $notice->getProfile(); if (empty($profile)) { @@ -92,7 +92,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(sprintf(_('Attachment %s not found.'),$id), 404); } if(empty($attachment->filename) && $file_oembed = File_oembed::staticGet('file_id', $attachment->id)){ // Proxy the existing oembed information @@ -133,7 +133,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(sprintf(_('"%s" not supported for oembed requests.'),$path), 501); } switch($args['format']){ case 'xml': diff --git a/actions/opensearch.php b/actions/opensearch.php index 861b53d7d8..7bf32277bb 100644 --- a/actions/opensearch.php +++ b/actions/opensearch.php @@ -1,5 +1,4 @@ clientError(_('Already logged in.')); return false; } @@ -66,6 +66,7 @@ class OtpAction extends Action $id = $this->trimmed('user_id'); if (empty($id)) { + // TRANS: Client error displayed trying to use "one time password login" without specifying a user. $this->clientError(_('No user ID specified.')); return false; } @@ -73,6 +74,7 @@ class OtpAction extends Action $this->user = User::staticGet('id', $id); if (empty($this->user)) { + // TRANS: Client error displayed trying to use "one time password login" without using an existing user. $this->clientError(_('No such user.')); return false; } @@ -80,6 +82,7 @@ class OtpAction extends Action $this->token = $this->trimmed('token'); if (empty($this->token)) { + // TRANS: Client error displayed trying to use "one time password login" without specifying a login token. $this->clientError(_('No login token specified.')); return false; } @@ -87,11 +90,13 @@ class OtpAction extends Action $this->lt = Login_token::staticGet('user_id', $id); if (empty($this->lt)) { + // TRANS: Client error displayed trying to use "one time password login" without requesting a login token. $this->clientError(_('No login token requested.')); return false; } if ($this->lt->token != $this->token) { + // TRANS: Client error displayed trying to use "one time password login" while specifying an invalid login token. $this->clientError(_('Invalid login token specified.')); return false; } @@ -101,6 +106,7 @@ class OtpAction extends Action //delete the token as it is useless $this->lt->delete(); $this->lt = null; + // TRANS: Client error displayed trying to use "one time password login" while specifying an expired login token. $this->clientError(_('Login token expired.')); return false; } @@ -111,12 +117,13 @@ class OtpAction extends Action return true; } - function handle($args) + function handle($args) { parent::handle($args); // success! if (!common_set_user($this->user)) { + // TRANS: Server error displayed when a user object could not be created trying to login using "one time password login". $this->serverError(_('Error setting user. You are probably not authorized.')); return; } diff --git a/actions/outbox.php b/actions/outbox.php index b81d4b9d0d..6d10c8119f 100644 --- a/actions/outbox.php +++ b/actions/outbox.php @@ -26,7 +26,6 @@ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } @@ -43,7 +42,6 @@ require_once INSTALLDIR.'/lib/mailbox.php'; * @link http://status.net/ * @see MailboxAction */ - class OutboxAction extends MailboxAction { /** @@ -51,13 +49,15 @@ class OutboxAction extends MailboxAction * * @return string page title */ - function title() { if ($this->page > 1) { + // TRANS: Title for outbox for any but the fist page. + // TRANS: %1$s is the user nickname, %2$d is the page number. return sprintf(_('Outbox for %1$s - page %2$d'), $this->user->nickname, $page); } else { + // TRANS: Title for first page of outbox. return sprintf(_('Outbox for %s'), $this->user->nickname); } } @@ -71,7 +71,6 @@ class OutboxAction extends MailboxAction * * @see MailboxAction::getMessages() */ - function getMessages() { $message = new Message(); @@ -88,21 +87,9 @@ class OutboxAction extends MailboxAction } } - /** - * returns the profile we want to show with the message - * - * For outboxes, we show the recipient. - * - * @param Message $message The message to get the profile for - * - * @return Profile The profile of the message recipient - * - * @see MailboxAction::getMessageProfile() - */ - - function getMessageProfile($message) + function getMessageList($message) { - return $message->getTo(); + return new OutboxMessageList($this, $message); } /** @@ -110,9 +97,30 @@ class OutboxAction extends MailboxAction * * @return string localised instructions for using the page */ - function getInstructions() { + // TRANS: Instructions for outbox. return _('This is your outbox, which lists private messages you have sent.'); } } + +class OutboxMessageList extends MessageList +{ + function newItem($message) + { + return new OutboxMessageListItem($this->out, $message); + } +} + +class OutboxMessageListItem extends MessageListItem +{ + /** + * Returns the profile we want to show with the message + * + * @return Profile The profile that matches the message + */ + function getMessageProfile() + { + return $this->message->getTo(); + } +} diff --git a/actions/passwordsettings.php b/actions/passwordsettings.php index c9bd200bd8..37877931ea 100644 --- a/actions/passwordsettings.php +++ b/actions/passwordsettings.php @@ -106,11 +106,11 @@ class PasswordsettingsAction extends SettingsAction } $this->elementStart('li'); $this->password('newpassword', _('New password'), - _('6 or more characters')); + _('6 or more characters.')); $this->elementEnd('li'); $this->elementStart('li'); $this->password('confirm', _('Confirm'), - _('Same as password above')); + _('Same as password above.')); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -128,7 +128,6 @@ class PasswordsettingsAction extends SettingsAction * * @return void */ - function handlePost() { // CSRF protection @@ -183,7 +182,7 @@ class PasswordsettingsAction extends SettingsAction } if (!$user->update($original)) { - $this->serverError(_('Can\'t save new password.')); + $this->serverError(_('Cannot save new password.')); return; } Event::handle('EndChangePassword', array($user)); diff --git a/actions/peoplesearch.php b/actions/peoplesearch.php index 69de44859f..6bc35828ec 100644 --- a/actions/peoplesearch.php +++ b/actions/peoplesearch.php @@ -49,12 +49,15 @@ class PeoplesearchAction extends SearchAction { function getInstructions() { + // TRANS: Instructions for the "People search" page. + // TRANS: %%site.name%% is the name of the StatusNet site. return _('Search for people on %%site.name%% by their name, location, or interests. ' . 'Separate the terms by spaces; they must be 3 characters or more.'); } function title() { + // TRANS: Title of a page where users can search for other users. return _('People search'); } @@ -80,6 +83,7 @@ class PeoplesearchAction extends SearchAction $page, 'peoplesearch', array('q' => $q)); } else { + // TRANS: Message on the "People search" page where a query has no results. $this->element('p', 'error', _('No results.')); $this->searchSuggestions($q); $profile->free(); @@ -136,4 +140,3 @@ class PeopleSearchResultItem extends ProfileListItem return preg_replace($this->pattern, '\\1', htmlspecialchars($text)); } } - diff --git a/actions/profilesettings.php b/actions/profilesettings.php index 1334644e9c..e1d686ca29 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -54,7 +54,6 @@ class ProfilesettingsAction extends SettingsAction * * @return string Title of the page */ - function title() { // TRANS: Page title for profile settings. @@ -66,7 +65,6 @@ class ProfilesettingsAction extends SettingsAction * * @return instructions for use */ - function getInstructions() { // TRANS: Usage instructions for profile settings. @@ -87,7 +85,6 @@ class ProfilesettingsAction extends SettingsAction * * @return void */ - function showContent() { $user = common_current_user(); @@ -165,14 +162,14 @@ class ProfilesettingsAction extends SettingsAction $this->input('tags', _('Tags'), ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()), // TRANS: Tooltip for field label in form for profile settings. - _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated')); + _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated.')); $this->elementEnd('li'); $this->elementStart('li'); $language = common_language(); // TRANS: Dropdownlist label in form for profile settings. $this->dropdown('language', _('Language'), // TRANS: Tooltip for dropdown list label in form for profile settings. - get_nice_language_list(), _('Preferred language'), + get_nice_language_list(), _('Preferred language.'), false, $language); $this->elementEnd('li'); $timezone = common_timezone(); @@ -191,7 +188,7 @@ class ProfilesettingsAction extends SettingsAction $this->checkbox('autosubscribe', // TRANS: Checkbox label in form for profile settings. _('Automatically subscribe to whoever '. - 'subscribes to me (best for non-humans)'), + 'subscribes to me (best for non-humans).'), ($this->arg('autosubscribe')) ? $this->boolean('autosubscribe') : $user->autosubscribe); $this->elementEnd('li'); @@ -212,12 +209,12 @@ class ProfilesettingsAction extends SettingsAction * * @return void */ - function handlePost() { // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { + // TRANS: Form validation error. $this->showForm(_('There was a problem with your session token. '. 'Try again, please.')); return; @@ -292,7 +289,7 @@ class ProfilesettingsAction extends SettingsAction if (!common_valid_profile_tag($tag)) { // TRANS: Validation error in form for profile settings. // TRANS: %s is an invalid tag. - $this->showForm(sprintf(_('Invalid tag: "%s"'), $tag)); + $this->showForm(sprintf(_('Invalid tag: "%s".'), $tag)); return; } } @@ -323,7 +320,7 @@ class ProfilesettingsAction extends SettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be updated. - $this->serverError(_('Couldn\'t update user.')); + $this->serverError(_('Could not update user.')); return; } else { // Re-initialize language environment if it changed @@ -348,7 +345,7 @@ class ProfilesettingsAction extends SettingsAction common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be updated to // TRANS: automatically subscribe to any subscriber. - $this->serverError(_('Couldn\'t update user for autosubscribe.')); + $this->serverError(_('Could not update user for autosubscribe.')); return; } } @@ -406,7 +403,7 @@ class ProfilesettingsAction extends SettingsAction if ($result === false) { common_log_db_error($prefs, ($exists) ? 'UPDATE' : 'INSERT', __FILE__); // TRANS: Server error thrown when user profile location preference settings could not be updated. - $this->serverError(_('Couldn\'t save location prefs.')); + $this->serverError(_('Could not save location prefs.')); return; } } @@ -419,7 +416,7 @@ class ProfilesettingsAction extends SettingsAction if ($result === false) { common_log_db_error($profile, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be saved. - $this->serverError(_('Couldn\'t save profile.')); + $this->serverError(_('Could not save profile.')); return; } @@ -428,7 +425,7 @@ class ProfilesettingsAction extends SettingsAction if (!$result) { // TRANS: Server error thrown when user profile settings tags could not be saved. - $this->serverError(_('Couldn\'t save tags.')); + $this->serverError(_('Could not save tags.')); return; } @@ -458,12 +455,16 @@ class ProfilesettingsAction extends SettingsAction $this->elementStart('div', array('id' => 'aside_primary', 'class' => 'aside')); + + $this->elementStart('div', array('id' => 'account_actions', + 'class' => 'section')); $this->elementStart('ul'); if (Event::handle('StartProfileSettingsActions', array($this))) { if ($user->hasRight(Right::BACKUPACCOUNT)) { $this->elementStart('li'); $this->element('a', array('href' => common_local_url('backupaccount')), + // TRANS: Option in profile settings to create a backup of the account of the currently logged in user. _('Backup account')); $this->elementEnd('li'); } @@ -471,6 +472,7 @@ class ProfilesettingsAction extends SettingsAction $this->elementStart('li'); $this->element('a', array('href' => common_local_url('deleteaccount')), + // TRANS: Option in profile settings to delete the account of the currently logged in user. _('Delete account')); $this->elementEnd('li'); } @@ -478,6 +480,7 @@ class ProfilesettingsAction extends SettingsAction $this->elementStart('li'); $this->element('a', array('href' => common_local_url('restoreaccount')), + // TRANS: Option in profile settings to restore the account of the currently logged in user from a backup. _('Restore account')); $this->elementEnd('li'); } @@ -485,5 +488,6 @@ class ProfilesettingsAction extends SettingsAction } $this->elementEnd('ul'); $this->elementEnd('div'); + $this->elementEnd('div'); } } diff --git a/actions/publicrss.php b/actions/publicrss.php index 0c5d061cb6..11db3b37a4 100644 --- a/actions/publicrss.php +++ b/actions/publicrss.php @@ -1,5 +1,4 @@ common_local_url('publicrss') - , 'title' => sprintf(_('%s public timeline'), common_config('site', 'name')) - , 'link' => common_local_url('public') - , 'description' => sprintf(_('%s updates from everyone!'), common_config('site', 'name'))); + 'url' => common_local_url('publicrss'), + // TRANS: Public RSS feed title. %s is the StatusNet site name. + 'title' => sprintf(_('%s public timeline'), $sitename), + 'link' => common_local_url('public'), + // TRANS: Public RSS feed description. %s is the StatusNet site name. + 'description' => sprintf(_('%s updates from everyone.'), $sitename)); return $c; } @@ -110,7 +111,7 @@ class PublicrssAction extends Rss10Action * Get image. * * @return nothing - */ + */ function getImage() { // nop @@ -121,4 +122,3 @@ class PublicrssAction extends Rss10Action return true; } } - diff --git a/actions/recoverpassword.php b/actions/recoverpassword.php index 33b0440e40..9019d6fb22 100644 --- a/actions/recoverpassword.php +++ b/actions/recoverpassword.php @@ -33,6 +33,7 @@ class RecoverpasswordAction extends Action { parent::handle($args); if (common_logged_in()) { + // TRANS: Client error displayed trying to recover password while already logged in. $this->clientError(_('You are already logged in!')); return; } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { @@ -41,6 +42,7 @@ class RecoverpasswordAction extends Action } else if ($this->arg('reset')) { $this->resetPassword(); } else { + // TRANS: Client error displayed when unexpected data is posted in the password recovery form. $this->clientError(_('Unexpected form submission.')); } } else { @@ -54,15 +56,16 @@ class RecoverpasswordAction extends Action function checkCode() { - $code = $this->trimmed('code'); $confirm = Confirm_address::staticGet('code', $code); if (!$confirm) { + // TRANS: Client error displayed when password recovery code is not correct. $this->clientError(_('No such recovery code.')); return; } if ($confirm->address_type != 'recover') { + // TRANS: Client error displayed when no proper password recovery code was submitted. $this->clientError(_('Not a recovery code.')); return; } @@ -70,6 +73,7 @@ class RecoverpasswordAction extends Action $user = User::staticGet($confirm->user_id); if (!$user) { + // TRANS: Server error displayed trying to recover password without providing a user. $this->serverError(_('Recovery code for unknown user.')); return; } @@ -83,6 +87,7 @@ class RecoverpasswordAction extends Action if (!$result) { common_log_db_error($confirm, 'DELETE', __FILE__); + // TRANS: Server error displayed removing a password recovery code from the database. $this->serverError(_('Error with confirmation code.')); return; } @@ -94,6 +99,7 @@ class RecoverpasswordAction extends Action common_log(LOG_WARNING, 'Attempted redemption on recovery code ' . 'that is ' . $touched . ' seconds old. '); + // TRANS: Client error displayed trying to recover password with too old a recovery code. $this->clientError(_('This confirmation code is too old. ' . 'Please start again.')); return; @@ -108,6 +114,7 @@ class RecoverpasswordAction extends Action $result = $user->updateKeys($orig); if (!$result) { common_log_db_error($user, 'UPDATE', __FILE__); + // TRANS: Server error displayed when updating a user's e-mail address in the database fails while recovering a password. $this->serverError(_('Could not update user with confirmed email address.')); return; } @@ -149,14 +156,16 @@ class RecoverpasswordAction extends Action $this->elementStart('div', 'instructions'); if ($this->mode == 'recover') { $this->element('p', null, + // TRANS: Page notice for password recovery page. _('If you have forgotten or lost your' . ' password, you can get a new one sent to' . ' the email address you have stored' . ' in your account.')); } else if ($this->mode == 'reset') { + // TRANS: Page notice for password change page. $this->element('p', null, _('You have been identified. Enter a' . - ' new password below. ')); + ' new password below.')); } $this->elementEnd('div'); } @@ -185,19 +194,24 @@ class RecoverpasswordAction extends Action 'class' => 'form_settings', 'action' => common_local_url('recoverpassword'))); $this->elementStart('fieldset'); + // TRANS: Fieldset legend for password recovery page. $this->element('legend', null, _('Password recovery')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label on password recovery page. $this->input('nicknameoremail', _('Nickname or email address'), $this->trimmed('nicknameoremail'), + // TRANS: Title for field label on password recovery page. _('Your nickname on this server, ' . 'or your registered email address.')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->element('input', array('name' => 'recover', 'type' => 'hidden', + // TRANS: Field label on password recovery page. 'value' => _('Recover'))); - $this->submit('recover', _('Recover')); + // TRANS: Button text on password recovery page. + $this->submit('recover', _m('BUTTON','Recover')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -205,11 +219,16 @@ class RecoverpasswordAction extends Action function title() { switch ($this->mode) { + // TRANS: Title for password recovery page in password reset mode. case 'reset': return _('Reset password'); + // TRANS: Title for password recovery page in password recover mode. case 'recover': return _('Recover password'); + // TRANS: Title for password recovery page in email sent mode. case 'sent': return _('Password recovery requested'); - case 'saved': return _('Password saved.'); + // TRANS: Title for password recovery page in password saved mode. + case 'saved': return _('Password saved'); default: + // TRANS: Title for password recovery page when an unknown action has been specified. return _('Unknown action'); } } @@ -228,19 +247,25 @@ class RecoverpasswordAction extends Action 'class' => 'form_settings', 'action' => common_local_url('recoverpassword'))); $this->elementStart('fieldset'); + // TRANS: Fieldset legend for password reset form. $this->element('legend', null, _('Password change')); $this->hidden('token', common_session_token()); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label for password reset form. $this->password('newpassword', _('New password'), - _('6 or more characters, and don\'t forget it!')); + // TRANS: Title for field label for password reset form. + _('6 or more characters, and do not forget it!')); $this->elementEnd('li'); $this->elementStart('li'); + // TRANS: Field label for password reset form where the password has to be typed again. $this->password('confirm', _('Confirm'), - _('Same as password above')); + // TRANS: Ttile for field label for password reset form where the password has to be typed again. + _('Same as password above.')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('reset', _('Reset')); + // TRANS: Button text for password reset form. + $this->submit('reset', _m('BUTTON','Reset')); $this->elementEnd('fieldset'); $this->elementEnd('form'); } @@ -249,6 +274,7 @@ class RecoverpasswordAction extends Action { $nore = $this->trimmed('nicknameoremail'); if (!$nore) { + // TRANS: Form instructions for password recovery form. $this->showForm(_('Enter a nickname or email address.')); return; } @@ -279,6 +305,7 @@ class RecoverpasswordAction extends Action } if (!$user) { + // TRANS: Information on password recovery form if no known username or e-mail address was specified. $this->showForm(_('No user with that email address or username.')); return; } @@ -296,6 +323,7 @@ class RecoverpasswordAction extends Action } if (!$user->email && !$confirm_email) { + // TRANS: Client error displayed on password recovery form if a user does not have a registered e-mail address. $this->clientError(_('No registered email address for that user.')); return; } @@ -310,10 +338,12 @@ class RecoverpasswordAction extends Action if (!$confirm->insert()) { common_log_db_error($confirm, 'INSERT', __FILE__); + // TRANS: Server error displayed if e-mail address confirmation fails in the database on the password recovery form. $this->serverError(_('Error saving address confirmation.')); return; } + // @todo FIXME: needs i18n. $body = "Hey, $user->nickname."; $body .= "\n\n"; $body .= 'Someone just asked for a new password ' . @@ -332,9 +362,11 @@ class RecoverpasswordAction extends Action $body .= "\n"; $headers = _mail_prepare_headers('recoverpassword', $user->nickname, $user->nickname); + // TRANS: Subject for password recovery e-mail. mail_to_user($user, _('Password recovery requested'), $body, $headers, $confirm->address); $this->mode = 'sent'; + // TRANS: User notification after an e-mail with instructions was sent from the password recovery form. $this->msg = _('Instructions for recovering your password ' . 'have been sent to the email address registered to your ' . 'account.'); @@ -347,6 +379,7 @@ class RecoverpasswordAction extends Action # CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { + // TRANS: Form validation error message. $this->showForm(_('There was a problem with your session token. Try again, please.')); return; } @@ -354,6 +387,7 @@ class RecoverpasswordAction extends Action $user = $this->getTempUser(); if (!$user) { + // TRANS: Client error displayed when trying to reset as password without providing a user. $this->clientError(_('Unexpected password reset.')); return; } @@ -362,10 +396,12 @@ class RecoverpasswordAction extends Action $confirm = $this->trimmed('confirm'); if (!$newpassword || strlen($newpassword) < 6) { + // TRANS: Reset password form validation error message. $this->showPasswordForm(_('Password must be 6 characters or more.')); return; } if ($newpassword != $confirm) { + // TRANS: Reset password form validation error message. $this->showPasswordForm(_('Password and confirmation do not match.')); return; } @@ -378,13 +414,15 @@ class RecoverpasswordAction extends Action if (!$user->update($original)) { common_log_db_error($user, 'UPDATE', __FILE__); - $this->serverError(_('Can\'t save new password.')); + // TRANS: Reset password form validation error message. + $this->serverError(_('Cannot save new password.')); return; } $this->clearTempUser(); if (!common_set_user($user->nickname)) { + // TRANS: Server error displayed when something does wrong with the user object during password reset. $this->serverError(_('Error setting user.')); return; } @@ -392,6 +430,7 @@ class RecoverpasswordAction extends Action common_real_login(true); $this->mode = 'saved'; + // TRANS: Success message for user after password reset. $this->msg = _('New password successfully saved. ' . 'You are now logged in.'); $this->success = true; diff --git a/actions/register.php b/actions/register.php index 075b1af99d..6b039c93f6 100644 --- a/actions/register.php +++ b/actions/register.php @@ -40,25 +40,21 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class RegisterAction extends Action { /** * Has there been an error? */ - var $error = null; /** * Have we registered? */ - var $registered = false; /** * Are we processing an invite? */ - var $invite = null; /** @@ -68,7 +64,6 @@ class RegisterAction extends Action * @param $args * @return string title */ - function prepare($args) { parent::prepare($args); @@ -105,7 +100,6 @@ class RegisterAction extends Action * * @return string title */ - function title() { if ($this->registered) { @@ -126,7 +120,6 @@ class RegisterAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -156,7 +149,6 @@ class RegisterAction extends Action * * @return void */ - function tryRegister() { if (Event::handle('StartRegistrationTry', array($this))) { @@ -199,7 +191,7 @@ class RegisterAction extends Action $email = common_canonical_email($email); if (!$this->boolean('license')) { - $this->showForm(_('You can\'t register if you don\'t '. + $this->showForm(_('You cannot register if you don\'t '. 'agree to the license.')); } else if ($email && !Validate::email($email, common_config('email', 'check_domain'))) { $this->showForm(_('Not a valid email address.')); @@ -277,7 +269,6 @@ class RegisterAction extends Action * * @return boolean true if the nickname already exists */ - function nicknameExists($nickname) { $user = User::staticGet('nickname', $nickname); @@ -293,7 +284,6 @@ class RegisterAction extends Action * * @return boolean true if the address already exists */ - function emailExists($email) { $email = common_canonical_email($email); @@ -332,7 +322,6 @@ class RegisterAction extends Action * * @return void */ - function showPageNotice() { if ($this->registered) { @@ -344,7 +333,7 @@ class RegisterAction extends Action common_markup_to_html(_('With this form you can create '. 'a new account. ' . 'You can then post notices and '. - 'link up to friends and colleagues. ')); + 'link up to friends and colleagues.')); $this->elementStart('div', 'instructions'); $this->raw($instr); @@ -361,7 +350,6 @@ class RegisterAction extends Action * * @return void */ - function showForm($error=null) { $this->error = $error; @@ -376,7 +364,6 @@ class RegisterAction extends Action * * @return void */ - function showContent() { if ($this->registered) { @@ -391,7 +378,6 @@ class RegisterAction extends Action * * @return void */ - function showFormContent() { $code = $this->trimmed('code'); @@ -423,38 +409,37 @@ class RegisterAction extends Action if (Event::handle('StartRegistrationFormData', array($this))) { $this->elementStart('li'); $this->input('nickname', _('Nickname'), $this->trimmed('nickname'), - _('1-64 lowercase letters or numbers, '. - 'no punctuation or spaces. Required.')); + _('1-64 lowercase letters or numbers, no punctuation or spaces.')); $this->elementEnd('li'); $this->elementStart('li'); $this->password('password', _('Password'), - _('6 or more characters. Required.')); + _('6 or more characters.')); $this->elementEnd('li'); $this->elementStart('li'); $this->password('confirm', _('Confirm'), - _('Same as password above. Required.')); + _('Same as password above.')); $this->elementEnd('li'); $this->elementStart('li'); if ($this->invite && $this->invite->address_type == 'email') { $this->input('email', _('Email'), $this->invite->address, _('Used only for updates, announcements, '. - 'and password recovery')); + 'and password recovery.')); } else { $this->input('email', _('Email'), $this->trimmed('email'), _('Used only for updates, announcements, '. - 'and password recovery')); + 'and password recovery.')); } $this->elementEnd('li'); $this->elementStart('li'); $this->input('fullname', _('Full name'), $this->trimmed('fullname'), - _('Longer name, preferably your "real" name')); + _('Longer name, preferably your "real" name.')); $this->elementEnd('li'); $this->elementStart('li'); $this->input('homepage', _('Homepage'), $this->trimmed('homepage'), _('URL of your homepage, blog, '. - 'or profile on another site')); + 'or profile on another site.')); $this->elementEnd('li'); $this->elementStart('li'); $maxBio = Profile::maxBio(); @@ -477,7 +462,7 @@ class RegisterAction extends Action $this->input('location', _('Location'), $this->trimmed('location'), _('Where you are, like "City, '. - 'State (or Region), Country"')); + 'State (or Region), Country".')); $this->elementEnd('li'); Event::handle('EndRegistrationFormData', array($this)); $this->elementStart('li', array('id' => 'settings_rememberme')); @@ -513,6 +498,7 @@ class RegisterAction extends Action switch (common_config('license', 'type')) { case 'private': // TRANS: Copyright checkbox label in registration dialog, for private sites. + // TRANS: %1$s is the StatusNet sitename. $out .= htmlspecialchars(sprintf( _('I understand that content and data of %1$s are private and confidential.'), common_config('site', 'name'))); @@ -556,7 +542,6 @@ class RegisterAction extends Action * * @return void */ - function showSuccess() { $this->registered = true; @@ -570,7 +555,6 @@ class RegisterAction extends Action * * @return void */ - function showSuccessContent() { $nickname = $this->arg('nickname'); @@ -617,11 +601,9 @@ class RegisterAction extends Action * * @return void */ - function showLocalNav() { $nav = new LoginGroupNav($this); $nav->show(); } } - diff --git a/actions/remotesubscribe.php b/actions/remotesubscribe.php index 9fc235e743..8200659278 100644 --- a/actions/remotesubscribe.php +++ b/actions/remotesubscribe.php @@ -44,7 +44,6 @@ require_once INSTALLDIR.'/extlib/libomb/profile.php'; * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class RemotesubscribeAction extends Action { var $nickname; @@ -127,11 +126,11 @@ class RemotesubscribeAction extends Action $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->input('nickname', _('User nickname'), $this->nickname, - _('Nickname of the user you want to follow')); + _('Nickname of the user you want to follow.')); $this->elementEnd('li'); $this->elementStart('li'); $this->input('profile_url', _('Profile URL'), $this->profile_url, - _('URL of your profile on another compatible microblogging service')); + _('URL of your profile on another compatible microblogging service.')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->submit('submit', _('Subscribe')); @@ -156,7 +155,7 @@ class RemotesubscribeAction extends Action } if (!common_valid_http_url($this->profile_url)) { - $this->showForm(_('Invalid profile URL (bad format)')); + $this->showForm(_('Invalid profile URL (bad format).')); return; } @@ -173,14 +172,14 @@ class RemotesubscribeAction extends Action if ($service->getServiceURI(OAUTH_ENDPOINT_REQUEST) == common_local_url('requesttoken') || User::staticGet('uri', $service->getRemoteUserURI())) { - $this->showForm(_('That’s a local profile! Login to subscribe.')); + $this->showForm(_('That is a local profile! Login to subscribe.')); return; } try { $service->requestToken(); } catch (OMB_RemoteServiceException $e) { - $this->showForm(_('Couldn’t get a request token.')); + $this->showForm(_('Could not get a request token.')); return; } @@ -204,4 +203,3 @@ class RemotesubscribeAction extends Action common_redirect($target_url, 303); } } -?> diff --git a/actions/repeat.php b/actions/repeat.php index 893cae4ffd..2ec641578b 100644 --- a/actions/repeat.php +++ b/actions/repeat.php @@ -41,7 +41,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class RepeatAction extends Action { var $user = null; @@ -73,7 +72,7 @@ class RepeatAction extends Action } if ($this->user->id == $this->notice->profile_id) { - $this->clientError(_("You can't repeat your own notice.")); + $this->clientError(_('You cannot repeat your own notice.')); return false; } @@ -101,7 +100,6 @@ class RepeatAction extends Action * * @return void */ - function handle($args) { $repeat = $this->notice->repeat($this->user->id, 'web'); diff --git a/actions/repliesrss.php b/actions/repliesrss.php index 76aae21adb..86cd173d3c 100644 --- a/actions/repliesrss.php +++ b/actions/repliesrss.php @@ -25,7 +25,6 @@ require_once(INSTALLDIR.'/lib/rssaction.php'); class RepliesrssAction extends Rss10Action { - var $user = null; function prepare($args) @@ -35,6 +34,7 @@ class RepliesrssAction extends Rss10Action $this->user = User::staticGet('nickname', $nickname); if (!$this->user) { + // TRANS: Client error displayed when providing a non-existing nickname in a RSS 1.0 action. $this->clientError(_('No such user.')); return false; } else { @@ -45,13 +45,12 @@ class RepliesrssAction extends Rss10Action function getNotices($limit=0) { - $user = $this->user; $notice = $user->getReplies(0, ($limit == 0) ? 48 : $limit); $notices = array(); - + while ($notice->fetch()) { $notices[] = clone($notice); } @@ -65,11 +64,14 @@ class RepliesrssAction extends Rss10Action $c = array('url' => common_local_url('repliesrss', array('nickname' => $user->nickname)), + // TRANS: RSS reply feed title. %s is a user nickname. 'title' => sprintf(_("Replies to %s"), $user->nickname), 'link' => common_local_url('replies', array('nickname' => $user->nickname)), - 'description' => sprintf(_('Replies to %1$s on %2$s!'), + // TRANS: RSS reply feed description. + // TRANS: %1$s is a user nickname, %2$s is the StatusNet site name. + 'description' => sprintf(_('Replies to %1$s on %2$s.'), $user->nickname, common_config('site', 'name'))); return $c; } diff --git a/actions/requesttoken.php b/actions/requesttoken.php index e095161a7d..3c8cea03c0 100644 --- a/actions/requesttoken.php +++ b/actions/requesttoken.php @@ -1,5 +1,4 @@ diff --git a/actions/restoreaccount.php b/actions/restoreaccount.php index 8cf220a424..22f0a8e5da 100644 --- a/actions/restoreaccount.php +++ b/actions/restoreaccount.php @@ -4,7 +4,7 @@ * Copyright (C) 2010, StatusNet, Inc. * * Restore a backup of your own account from the browser - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -44,7 +44,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class RestoreaccountAction extends Action { private $success = false; @@ -52,13 +51,13 @@ class RestoreaccountAction extends Action /** * Returns the title of the page - * + * * @return string page title */ - function title() { - return _("Restore account"); + // TRANS: Page title for page where a user account can be restored from backup. + return _('Restore account'); } /** @@ -68,7 +67,6 @@ class RestoreaccountAction extends Action * * @return boolean true */ - function prepare($argarray) { parent::prepare($argarray); @@ -76,10 +74,12 @@ class RestoreaccountAction extends Action $cur = common_current_user(); if (empty($cur)) { + // TRANS: Client exception displayed when trying to restore an account while not logged in. throw new ClientException(_('Only logged-in users can restore their account.'), 403); } if (!$cur->hasRight(Right::RESTOREACCOUNT)) { + // TRANS: Client exception displayed when trying to restore an account without having restore rights. throw new ClientException(_('You may not restore your account.'), 403); } @@ -93,7 +93,6 @@ class RestoreaccountAction extends Action * * @return void */ - function handle($argarray=null) { parent::handle($argarray); @@ -108,17 +107,17 @@ class RestoreaccountAction extends Action /** * Queue a file for restoration - * + * * Uses the UserActivityStream class; may take a long time! * * @return void */ - function restoreAccount() { $this->checkSessionToken(); if (!isset($_FILES['restorefile']['error'])) { + // TRANS: Client exception displayed trying to restore an account while something went wrong uploading a file. throw new ClientException(_('No uploaded file.')); } @@ -143,7 +142,7 @@ class RestoreaccountAction extends Action ' partially uploaded.')); return; case UPLOAD_ERR_NO_FILE: - // No file; probably just a non-AJAX submission. + // TRANS: Client exception. No file; probably just a non-AJAX submission. throw new ClientException(_('No uploaded file.')); return; case UPLOAD_ERR_NO_TMP_DIR: @@ -170,18 +169,21 @@ class RestoreaccountAction extends Action try { if (!file_exists($filename)) { - throw new ServerException("No such file '$filename'."); + // TRANS: Server exception thrown when an expected file upload could not be found. + throw new ServerException(_("No such file '$filename'.")); } - + if (!is_file($filename)) { - throw new ServerException("Not a regular file: '$filename'."); + // TRANS: Server exception thrown when an expected file upload is not an actual file. + throw new ServerException(_("Not a regular file: '$filename'.")); } - + if (!is_readable($filename)) { - throw new ServerException("File '$filename' not readable."); + // TRANS: Server exception thrown when an expected file upload could not be read. + throw new ServerException(_("File '$filename' not readable.")); } - - common_debug(sprintf(_("Getting backup from file '%s'."), $filename)); + + common_debug(sprintf("Getting backup from file '%s'.", $filename)); $xml = file_get_contents($filename); @@ -201,7 +203,8 @@ class RestoreaccountAction extends Action if (!$feed || $feed->namespaceURI != Activity::ATOM || $feed->localName != 'feed') { - throw new ClientException(_("Not an atom feed.")); + // TRANS: Client exception thrown when a feed is not an Atom feed. + throw new ClientException(_("Not an Atom feed.")); } // Enqueue for processing. @@ -230,21 +233,22 @@ class RestoreaccountAction extends Action * * @return void */ - function showContent() { if ($this->success) { $this->element('p', null, + // TRANS: Success message when a feed has been restored. _('Feed has been restored. Your old posts should now appear in search and your profile page.')); } else if ($this->inprogress) { $this->element('p', null, + // TRANS: Message when a feed restore is in progress. _('Feed will be restored. Please wait a few minutes for results.')); } else { $form = new RestoreAccountForm($this); $form->show(); } } - + /** * Return true if read only. * @@ -254,7 +258,6 @@ class RestoreaccountAction extends Action * * @return boolean is read only action? */ - function isReadOnly($args) { return false; @@ -267,7 +270,6 @@ class RestoreaccountAction extends Action * * @return string last modified http header */ - function lastModified() { // For comparison with If-Last-Modified @@ -282,7 +284,6 @@ class RestoreaccountAction extends Action * * @return string etag http header */ - function etag() { return null; @@ -299,7 +300,6 @@ class RestoreaccountAction extends Action * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - class RestoreAccountForm extends Form { function __construct($out=null) { @@ -312,7 +312,6 @@ class RestoreAccountForm extends Form * * @return string the form's class */ - function formClass() { return 'form_profile_restore'; @@ -323,7 +322,6 @@ class RestoreAccountForm extends Form * * @return string the form's action URL */ - function action() { return common_local_url('restoreaccount'); @@ -331,19 +329,19 @@ class RestoreAccountForm extends Form /** * Output form data - * + * * Really, just instructions for doing a backup. * * @return void */ - function formData() { $this->out->elementStart('p', 'instructions'); + // TRANS: Form instructions for feed restore. $this->out->raw(_('You can upload a backed-up stream in '. 'Activity Streams format.')); - + $this->out->elementEnd('p'); $this->out->elementStart('ul', 'form_data'); @@ -359,18 +357,19 @@ class RestoreAccountForm extends Form /** * Buttons for the form - * + * * In this case, a single submit button * * @return void */ - function formActions() { $this->out->submit('submit', + // TRANS: Submit button to confirm upload of a user backup file for account restore. _m('BUTTON', 'Upload'), 'submit', null, + // TRANS: Title for submit button to confirm upload of a user backup file for account restore. _('Upload the file')); } } diff --git a/actions/robotstxt.php b/actions/robotstxt.php index 5131097c8c..d686042cb1 100644 --- a/actions/robotstxt.php +++ b/actions/robotstxt.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class RobotstxtAction extends Action { /** @@ -53,7 +52,6 @@ class RobotstxtAction extends Action * * @return void */ - function handle($args) { if (Event::handle('StartRobotsTxt', array($this))) { @@ -65,9 +63,7 @@ class RobotstxtAction extends Action if (common_config('site', 'private')) { print "Disallow: /\n"; - } else { - $disallow = common_config('robotstxt', 'disallow'); foreach ($disallow as $dir) { @@ -92,7 +88,6 @@ class RobotstxtAction extends Action * * @return boolean is read only action? */ - function isReadOnly($args) { return true; diff --git a/actions/rsd.php b/actions/rsd.php index e02c85c41b..0a70117498 100644 --- a/actions/rsd.php +++ b/actions/rsd.php @@ -68,13 +68,11 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class RsdAction extends Action { /** * Optional attribute for the personal rsd.xml file. */ - var $user = null; /** @@ -87,7 +85,6 @@ class RsdAction extends Action * * @return boolean success flag */ - function prepare($args) { parent::prepare($args); @@ -132,7 +129,6 @@ class RsdAction extends Action * * @return nothing */ - function handle($args) { header('Content-Type: application/rsd+xml'); @@ -195,7 +191,6 @@ class RsdAction extends Action * * @return string date of last change of this page */ - function lastModified() { if (!empty($this->user)) { @@ -214,7 +209,6 @@ class RsdAction extends Action * * @return boolean true */ - function isReadOnly($args) { return true; @@ -228,7 +222,6 @@ class RsdAction extends Action * * @return string API root URI for this site */ - private function _apiRoot() { if (common_config('site', 'fancy')) { diff --git a/actions/showapplication.php b/actions/showapplication.php index b9e3b32914..02a4dc1517 100644 --- a/actions/showapplication.php +++ b/actions/showapplication.php @@ -40,19 +40,16 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ShowApplicationAction extends OwnerDesignAction { /** * Application to show */ - var $application = null; /** * User who owns the app */ - var $owner = null; var $msg = null; @@ -68,7 +65,6 @@ class ShowApplicationAction extends OwnerDesignAction * * @return success flag */ - function prepare($args) { parent::prepare($args); @@ -105,7 +101,6 @@ class ShowApplicationAction extends OwnerDesignAction * * @return void */ - function handle($args) { parent::handle($args); @@ -132,7 +127,6 @@ class ShowApplicationAction extends OwnerDesignAction * * @return string title of the page */ - function title() { if (!empty($this->application->name)) { @@ -274,7 +268,6 @@ class ShowApplicationAction extends OwnerDesignAction * * @return void */ - function showScripts() { parent::showScripts(); @@ -295,7 +288,6 @@ class ShowApplicationAction extends OwnerDesignAction * XXX: Should this be moved to its own page with a confirm? * */ - function resetKey() { $this->application->query('BEGIN'); @@ -355,5 +347,4 @@ class ShowApplicationAction extends OwnerDesignAction $this->msg = ('Consumer key and secret reset.'); $this->showPage(); } - } diff --git a/actions/showfavorites.php b/actions/showfavorites.php index 77b73711d2..eda2cf38eb 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -44,7 +44,6 @@ require_once INSTALLDIR.'/lib/feedlist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ShowfavoritesAction extends OwnerDesignAction { /** User we're getting the faves of */ @@ -57,7 +56,6 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return boolean true */ - function isReadOnly($args) { return true; @@ -70,12 +68,15 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return string title of page */ - function title() { if ($this->page == 1) { + // TRANS: Title for first page of favourite notices of a user. + // TRANS: %s is the user for whom the favourite notices are displayed. return sprintf(_('%s\'s favorite notices'), $this->user->nickname); } else { + // TRANS: Title for all but the first page of favourite notices of a user. + // TRANS: %1$s is the user for whom the favourite notices are displayed, %2$d is the page number. return sprintf(_('%1$s\'s favorite notices, page %2$d'), $this->user->nickname, $this->page); @@ -92,7 +93,6 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return boolean success flag */ - function prepare($args) { parent::prepare($args); @@ -102,6 +102,7 @@ class ShowfavoritesAction extends OwnerDesignAction $this->user = User::staticGet('nickname', $nickname); if (!$this->user) { + // TRANS: Client error displayed when trying to display favourite notices for a non-existing user. $this->clientError(_('No such user.')); return false; } @@ -129,6 +130,7 @@ class ShowfavoritesAction extends OwnerDesignAction } if (empty($this->notice)) { + // TRANS: Server error displayed when favourite notices could not be retrieved from the database. $this->serverError(_('Could not retrieve favorite notices.')); return; } @@ -150,7 +152,6 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return void */ - function handle($args) { parent::handle($args); @@ -162,12 +163,12 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return array Feed objects to show */ - function getFeeds() { return array(new Feed(Feed::RSS1, common_local_url('favoritesrss', array('nickname' => $this->user->nickname)), + // TRANS: Feed link text. %s is a username. sprintf(_('Feed for favorites of %s (RSS 1.0)'), $this->user->nickname)), new Feed(Feed::RSS2, @@ -175,6 +176,7 @@ class ShowfavoritesAction extends OwnerDesignAction array( 'id' => $this->user->nickname, 'format' => 'rss')), + // TRANS: Feed link text. %s is a username. sprintf(_('Feed for favorites of %s (RSS 2.0)'), $this->user->nickname)), new Feed(Feed::ATOM, @@ -182,6 +184,7 @@ class ShowfavoritesAction extends OwnerDesignAction array( 'id' => $this->user->nickname, 'format' => 'atom')), + // TRANS: Feed link text. %s is a username. sprintf(_('Feed for favorites of %s (Atom)'), $this->user->nickname))); } @@ -191,7 +194,6 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return void */ - function showLocalNav() { $nav = new PersonalGroupNav($this); @@ -203,12 +205,18 @@ class ShowfavoritesAction extends OwnerDesignAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { + // TRANS: Text displayed instead of favourite notices for the current logged in user that has no favourites. $message = _('You haven\'t chosen any favorite notices yet. Click the fave button on notices you like to bookmark them for later or shed a spotlight on them.'); } else { + // TRANS: Text displayed instead of favourite notices for a user that has no favourites while logged in. + // TRANS: %s is a username. $message = sprintf(_('%s hasn\'t added any favorite notices yet. Post something interesting they would add to their favorites :)'), $this->user->nickname); } } else { + // TRANS: Text displayed instead of favourite notices for a user that has no favourites while not logged in. + // TRANS: %s is a username, %%%%action.register%%%% is a link to the user registration page. + // TRANS: (link text)[link] is a Mark Down link. $message = sprintf(_('%s hasn\'t added any favorite notices yet. Why not [register an account](%%%%action.register%%%%) and then post something interesting they would add to their favorites :)'), $this->user->nickname); } @@ -224,7 +232,6 @@ class ShowfavoritesAction extends OwnerDesignAction * * @return void */ - function showContent() { $nl = new FavoritesNoticeList($this->notice, $this); @@ -240,6 +247,7 @@ class ShowfavoritesAction extends OwnerDesignAction } function showPageNotice() { + // TRANS: Page notice for show favourites page. $this->element('p', 'instructions', _('This is a way to share what you like.')); } } diff --git a/actions/showgroup.php b/actions/showgroup.php index a895f81b84..21256294f3 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -181,6 +181,7 @@ class ShowgroupAction extends GroupDesignAction function showContent() { $this->showGroupProfile(); + $this->showGroupActions(); $this->showGroupNotices(); } @@ -258,34 +259,62 @@ class ShowgroupAction extends GroupDesignAction 'aliases entity_aliases', implode(' ', $aliases)); } + + if ($this->group->description) { + $this->elementStart('dl', 'entity_note'); + // TRANS: Label for group description or group note (dt). Text hidden by default. + $this->element('dt', null, _('Note')); + $this->element('dd', 'note', $this->group->description); + $this->elementEnd('dl'); + } + + if (common_config('group', 'maxaliases') > 0) { + $aliases = $this->group->getAliases(); + + if (!empty($aliases)) { + $this->elementStart('dl', 'entity_aliases'); + // TRANS: Label for group aliases (dt). Text hidden by default. + $this->element('dt', null, _('Aliases')); + $this->element('dd', 'aliases', implode(' ', $aliases)); + $this->elementEnd('dl'); + } + } + + Event::handle('EndGroupProfileElements', array($this, $this->group)); } $this->elementEnd('div'); + } + function showGroupActions() + { $cur = common_current_user(); $this->elementStart('div', 'entity_actions'); // TRANS: Group actions header (h2). Text hidden by default. $this->element('h2', null, _('Group actions')); $this->elementStart('ul'); - $this->elementStart('li', 'entity_subscribe'); - if (Event::handle('StartGroupSubscribe', array($this, $this->group))) { - if ($cur) { - if ($cur->isMember($this->group)) { - $lf = new LeaveForm($this, $this->group); - $lf->show(); - } else if (!Group_block::isBlocked($this->group, $cur->getProfile())) { - $jf = new JoinForm($this, $this->group); - $jf->show(); + if (Event::handle('StartGroupActionsList', array($this, $this->group))) { + $this->elementStart('li', 'entity_subscribe'); + if (Event::handle('StartGroupSubscribe', array($this, $this->group))) { + if ($cur) { + if ($cur->isMember($this->group)) { + $lf = new LeaveForm($this, $this->group); + $lf->show(); + } else if (!Group_block::isBlocked($this->group, $cur->getProfile())) { + $jf = new JoinForm($this, $this->group); + $jf->show(); + } } + Event::handle('EndGroupSubscribe', array($this, $this->group)); } - Event::handle('EndGroupSubscribe', array($this, $this->group)); - } - $this->elementEnd('li'); - if ($cur && $cur->hasRight(Right::DELETEGROUP)) { - $this->elementStart('li', 'entity_delete'); - $df = new DeleteGroupForm($this, $this->group); - $df->show(); $this->elementEnd('li'); + if ($cur && $cur->hasRight(Right::DELETEGROUP)) { + $this->elementStart('li', 'entity_delete'); + $df = new DeleteGroupForm($this, $this->group); + $df->show(); + $this->elementEnd('li'); + } + Event::handle('EndGroupActionsList', array($this, $this->group)); } $this->elementEnd('ul'); $this->elementEnd('div'); diff --git a/actions/showmessage.php b/actions/showmessage.php index d737f85d3a..1c867af119 100644 --- a/actions/showmessage.php +++ b/actions/showmessage.php @@ -30,20 +30,17 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once INSTALLDIR.'/lib/mailbox.php'; - /** * Show a single message * - * // XXX: It is totally weird how this works! - * * @category Personal * @package StatusNet * @author Evan Prodromou * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -class ShowmessageAction extends MailboxAction + +class ShowmessageAction extends Action { /** * Message object to show @@ -82,22 +79,20 @@ class ShowmessageAction extends MailboxAction $this->user = common_current_user(); + if (empty($this->user) || + ($this->user->id != $this->message->from_profile && + $this->user->id != $this->message->to_profile)) { + // TRANS: Client error displayed requesting a single direct message the requesting user was not a party in. + throw new ClientException(_('Only the sender and recipient ' . + 'may read this message.'), 403); + } + return true; } function handle($args) { - Action::handle($args); - - if ($this->user && ($this->user->id == $this->message->from_profile || - $this->user->id == $this->message->to_profile)) { - $this->showPage(); - } else { - // TRANS: Client error displayed requesting a single direct message the requesting user was not a party in. - $this->clientError(_('Only the sender and recipient ' . - 'may read this message.'), 403); - return; - } + $this->showPage(); } function title() @@ -121,12 +116,38 @@ class ShowmessageAction extends MailboxAction } } - function getMessages() + + function showContent() { - $message = new Message(); - $message->id = $this->message->id; - $message->find(); - return $message; + $this->elementStart('ul', 'notices messages'); + $ml = new ShowMessageListItem($this, $this->message, $this->user); + $ml->show(); + $this->elementEnd('ul'); + } + + function isReadOnly($args) + { + return true; + } + + /** + * Don't show aside + * + * @return void + */ + + function showAside() { + } +} + +class ShowMessageListItem extends MessageListItem +{ + var $user; + + function __construct($out, $message, $user) + { + parent::__construct($out, $message); + $this->user = $user; } function getMessageProfile() @@ -140,46 +161,4 @@ class ShowmessageAction extends MailboxAction return null; } } - - /** - * Don't show local navigation - * - * @return void - */ - function showLocalNavBlock() - { - } - - /** - * Don't show page notice - * - * @return void - */ - function showPageNoticeBlock() - { - } - - /** - * Don't show aside - * - * @return void - */ - function showAside() - { - } - - /** - * Don't show any instructions - * - * @return string - */ - function getInstructions() - { - return ''; - } - - function isReadOnly($args) - { - return true; - } } diff --git a/actions/shownotice.php b/actions/shownotice.php index 91b0901bf4..3978f03ea9 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -338,7 +338,7 @@ class SingleNoticeItem extends DoFollowListItem * show the avatar of the notice's author * * We use the larger size for single notice page. - * + * * @return void */ diff --git a/actions/showstream.php b/actions/showstream.php index 1688677d84..0fd1c2c29f 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -70,7 +70,7 @@ class ShowstreamAction extends ProfileAction return sprintf(_('%1$s tagged %2$s'), $base, $this->tag); } else { // TRANS: Page title showing tagged notices in one user's stream. - // TRANS: %1$s is the username, %2$s is the hash tag, %1$d is the page number. + // TRANS: %1$s is the username, %2$s is the hash tag, %3$d is the page number. return sprintf(_('%1$s tagged %2$s, page %3$d'), $base, $this->tag, $this->page); } } else { diff --git a/actions/sitenoticeadminpanel.php b/actions/sitenoticeadminpanel.php index 797a6c4f4c..b1ac441af7 100644 --- a/actions/sitenoticeadminpanel.php +++ b/actions/sitenoticeadminpanel.php @@ -98,7 +98,7 @@ class SitenoticeadminpanelAction extends AdminPanelAction if (!$result) { // TRANS: Server error displayed when saving a site-wide notice was impossible. - $this->ServerError(_("Unable to save site notice.")); + $this->ServerError(_('Unable to save site notice.')); } } @@ -198,7 +198,7 @@ class SiteNoticeAdminPanelForm extends AdminForm 'submit', null, // TRANS: Title for button to save site notice in admin panel. - _('Save site notice') + _('Save site notice.') ); } } diff --git a/actions/smssettings.php b/actions/smssettings.php index 217db27888..cdf99a56d9 100644 --- a/actions/smssettings.php +++ b/actions/smssettings.php @@ -50,7 +50,6 @@ class SmssettingsAction extends SettingsAction * * @return string Title of the page */ - function title() { // TRANS: Title for SMS settings. @@ -62,7 +61,6 @@ class SmssettingsAction extends SettingsAction * * @return instructions for use */ - function getInstructions() { // XXX: For consistency of parameters in messages, this should be a @@ -86,7 +84,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function showContent() { if (!common_config('sms', 'enabled')) { @@ -152,7 +149,7 @@ class SmssettingsAction extends SettingsAction ($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')); + 'with area code.')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->carrierSelect(); @@ -217,7 +214,6 @@ class SmssettingsAction extends SettingsAction * * @todo very similar to EmailsettingsAction::getConfirmation(); refactor? */ - function getConfirmation() { $user = common_current_user(); @@ -244,7 +240,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function handlePost() { // CSRF protection @@ -283,7 +278,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function savePreferences() { $smsnotify = $this->boolean('smsnotify'); @@ -303,7 +297,7 @@ class SmssettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not update user.')); return; } @@ -321,7 +315,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function addAddress() { $user = common_current_user(); @@ -368,7 +361,7 @@ class SmssettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not insert confirmation code.')); return; } @@ -393,7 +386,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function cancelConfirmation() { $sms = $this->trimmed('sms'); @@ -417,7 +409,7 @@ class SmssettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not delete email confirmation.')); return; } @@ -430,7 +422,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function removeAddress() { $user = common_current_user(); @@ -459,7 +450,7 @@ class SmssettingsAction extends SettingsAction 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.')); + $this->serverError(_('Could not update user.')); return; } $user->query('COMMIT'); @@ -477,7 +468,6 @@ class SmssettingsAction extends SettingsAction * * @return boolean does the number exist */ - function smsExists($sms) { $user = common_current_user(); @@ -496,7 +486,6 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function carrierSelect() { $carrier = new Sms_carrier(); @@ -536,14 +525,13 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function confirmCode() { $code = $this->trimmed('code'); if (!$code) { // TRANS: Message given saving SMS phone number confirmation code without having provided one. - $this->showForm(_('No code entered')); + $this->showForm(_('No code entered.')); return; } @@ -557,12 +545,12 @@ class SmssettingsAction extends SettingsAction * * @return void */ - function removeIncoming() { $user = common_current_user(); if (!$user->incomingemail) { + // TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set. $this->showForm(_('No incoming email address.')); return; } @@ -573,9 +561,11 @@ class SmssettingsAction extends SettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); - $this->serverError(_("Couldn't update user record.")); + // TRANS: Server error displayed when the user could not be updated in SMS settings. + $this->serverError(_('Could not update user record.')); } + // TRANS: Confirmation text after updating SMS settings. $this->showForm(_('Incoming email address removed.'), true); } @@ -586,7 +576,6 @@ class SmssettingsAction extends SettingsAction * * @see Emailsettings::newIncoming */ - function newIncoming() { $user = common_current_user(); @@ -597,9 +586,11 @@ class SmssettingsAction extends SettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); - $this->serverError(_("Couldn't update user record.")); + // TRANS: Server error displayed when the user could not be updated in SMS settings. + $this->serverError(_('Could not update user record.')); } + // TRANS: Confirmation text after updating SMS settings. $this->showForm(_('New incoming email address added.'), true); } } diff --git a/actions/subscribe.php b/actions/subscribe.php index b1243f3933..3837915d53 100644 --- a/actions/subscribe.php +++ b/actions/subscribe.php @@ -53,7 +53,6 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 * @link http://status.net/ */ - class SubscribeAction extends Action { var $user; @@ -66,7 +65,6 @@ class SubscribeAction extends Action * * @return boolean success flag */ - function prepare($args) { parent::prepare($args); @@ -74,6 +72,8 @@ class SubscribeAction extends Action // Only allow POST requests if ($_SERVER['REQUEST_METHOD'] != 'POST') { + // TRANS: Client error displayed trying to perform any request method other than POST. + // TRANS: Do not translate POST. $this->clientError(_('This action only accepts POST requests.')); return false; } @@ -83,6 +83,7 @@ class SubscribeAction extends Action $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { + // TRANS: Client error displayed when the session token is not okay. $this->clientError(_('There was a problem with your session token.'. ' Try again, please.')); return false; @@ -93,6 +94,7 @@ class SubscribeAction extends Action $this->user = common_current_user(); if (empty($this->user)) { + // TRANS: Client error displayed trying to subscribe when not logged in. $this->clientError(_('Not logged in.')); return false; } @@ -104,6 +106,7 @@ class SubscribeAction extends Action $this->other = Profile::staticGet('id', $other_id); if (empty($this->other)) { + // TRANS: Client error displayed trying to subscribe to a non-existing profile. $this->clientError(_('No such profile.')); return false; } @@ -114,6 +117,7 @@ class SubscribeAction extends Action $omb01 = Remote_profile::staticGet('id', $other_id); if (!empty($omb01)) { + // TRANS: Client error displayed trying to subscribe to an OMB 0.1 remote profile. $this->clientError(_('You cannot subscribe to an OMB 0.1'. ' remote profile with this action.')); return false; @@ -131,7 +135,6 @@ class SubscribeAction extends Action * * @return void */ - function handle($args) { // Throws exception on error @@ -142,6 +145,7 @@ class SubscribeAction extends Action if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); + // TRANS: Page title when subscription succeeded. $this->element('title', null, _('Subscribed')); $this->elementEnd('head'); $this->elementStart('body'); diff --git a/actions/subscribers.php b/actions/subscribers.php index 2862f35c6d..ad522a4bae 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -100,8 +100,6 @@ class SubscribersAction extends GalleryAction } } - $subscribers->free(); - $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE, $this->page, 'subscribers', array('nickname' => $this->user->nickname)); diff --git a/actions/subscriptions.php b/actions/subscriptions.php index 10e8f28608..cfe2b5683a 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -106,8 +106,6 @@ class SubscriptionsAction extends GalleryAction } } - $subscriptions->free(); - $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE, $this->page, 'subscriptions', array('nickname' => $this->user->nickname)); @@ -169,15 +167,14 @@ class SubscriptionsAction extends GalleryAction * * @return array of Feed objects */ - function getFeeds() { return array(new Feed(Feed::ATOM, common_local_url('AtomPubSubscriptionFeed', array('subscriber' => $this->profile->id)), + // TRANS: Atom feed title. %s is a profile nickname. sprintf(_('Subscription feed for %s (Atom)'), $this->profile->nickname))); - } } @@ -265,5 +262,4 @@ class SubscriptionsListItem extends SubscriptionListItem $this->out->elementEnd('form'); return; } - } diff --git a/actions/sup.php b/actions/sup.php index 4e428dfa58..c4da9d3db6 100644 --- a/actions/sup.php +++ b/actions/sup.php @@ -19,6 +19,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +// @todo FIXME: documentation needed. class SupAction extends Action { function handle($args) diff --git a/actions/unblock.php b/actions/unblock.php index 0f63e1dae0..1f4d9606b8 100644 --- a/actions/unblock.php +++ b/actions/unblock.php @@ -42,7 +42,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class UnblockAction extends ProfileFormAction { function prepare($args) @@ -56,6 +55,7 @@ class UnblockAction extends ProfileFormAction assert(!empty($cur)); // checked by parent if (!$cur->hasBlocked($this->profile)) { + // TRANS: Client error displayed when trying to unblock a non-blocked user. $this->clientError(_("You haven't blocked that user.")); return false; } @@ -68,7 +68,6 @@ class UnblockAction extends ProfileFormAction * * @return void */ - function handlePost() { $cur = common_current_user(); @@ -83,6 +82,7 @@ class UnblockAction extends ProfileFormAction } if (!$result) { + // TRANS: Server error displayed when removing a user block. $this->serverError(_('Error removing the block.')); return; } diff --git a/actions/urlsettings.php b/actions/urlsettings.php index 140e28c999..807f9492c7 100644 --- a/actions/urlsettings.php +++ b/actions/urlsettings.php @@ -206,7 +206,7 @@ class UrlsettingsAction extends SettingsAction if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error displayed when "Other" settings in user profile could not be updated on the server. - $this->serverError(_('Couldn\'t update user.')); + $this->serverError(_('Could not update user.')); return; } @@ -238,6 +238,7 @@ class UrlsettingsAction extends SettingsAction $user->query('COMMIT'); + // TRANS: Confirmation message after saving preferences. $this->showForm(_('Preferences saved.'), true); } } diff --git a/actions/useradminpanel.php b/actions/useradminpanel.php index fc75e83b2d..c8861bd834 100644 --- a/actions/useradminpanel.php +++ b/actions/useradminpanel.php @@ -163,7 +163,7 @@ class UseradminpanelAction extends AdminPanelAction sprintf( // TRANS: Client error displayed when trying to set a non-existing user as default subscription for new // TRANS: users in user admin panel. %1$s is the invalid nickname. - _('Invalid default subscripton: \'%1$s\' is not a user.'), + _('Invalid default subscripton: "%1$s" is not a user.'), $values['newuser']['default'] ) ); @@ -299,6 +299,6 @@ class UserAdminPanelForm extends AdminForm 'submit', null, // TRANS: Title for button to save user settings in user admin panel. - _('Save user settings')); + _('Save user settings.')); } } diff --git a/actions/userauthorization.php b/actions/userauthorization.php index d460308c16..c86f4cdaa1 100644 --- a/actions/userauthorization.php +++ b/actions/userauthorization.php @@ -35,6 +35,7 @@ require_once INSTALLDIR.'/extlib/libomb/service_provider.php'; require_once INSTALLDIR.'/extlib/libomb/profile.php'; define('TIMESTAMP_THRESHOLD', 300); +// @todo FIXME: Missing documentation. class UserauthorizationAction extends Action { var $error; @@ -69,6 +70,8 @@ class UserauthorizationAction extends Action $profile = $user->getProfile(); if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); + // TRANS: Server error displayed when trying to authorise a remote subscription request + // TRANS: while the user has no profile. $this->serverError(_('User without matching profile.')); return; } @@ -102,16 +105,18 @@ class UserauthorizationAction extends Action function title() { + // TRANS: Page title. return _('Authorize subscription'); } function showPageNotice() { + // TRANS: Page notice on "Auhtorize subscription" page. $this->element('p', null, _('Please check these details to make sure '. 'that you want to subscribe to this ' . 'user’s notices. If you didn’t just ask ' . 'to subscribe to someone’s notices, '. - 'click “Reject”.')); + 'click "Reject".')); } function showContent() @@ -191,10 +196,14 @@ class UserauthorizationAction extends Action 'userauthorization'))); $this->hidden('token', common_session_token()); - $this->submit('accept', _('Accept'), 'submit accept', null, - _('Subscribe to this user')); - $this->submit('reject', _('Reject'), 'submit reject', null, - _('Reject this subscription')); + // TRANS: Button text on Authorise Subscription page. + $this->submit('accept', _m('BUTTON','Accept'), 'submit accept', null, + // TRANS: Title for button on Authorise Subscription page. + _('Subscribe to this user.')); + // TRANS: Button text on Authorise Subscription page. + $this->submit('reject', _m('BUTTON','Reject'), 'submit reject', null, + // TRANS: Title for button on Authorise Subscription page. + _('Reject this subscription.')); $this->elementEnd('form'); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -206,6 +215,7 @@ class UserauthorizationAction extends Action $srv = $this->getStoredParams(); if (is_null($srv)) { + // TRANS: Client error displayed for an empty authorisation request. $this->clientError(_('No authorization request!')); return; } @@ -228,7 +238,9 @@ class UserauthorizationAction extends Action function showAcceptMessage($tok) { + // TRANS: Accept message header from Authorise subscription page. common_show_header(_('Subscription authorized')); + // TRANS: Accept message text from Authorise subscription page. $this->element('p', null, _('The subscription has been authorized, but no '. 'callback URL was passed. Check with the site’s ' . @@ -240,7 +252,9 @@ class UserauthorizationAction extends Action function showRejectMessage() { + // TRANS: Reject message header from Authorise subscription page. common_show_header(_('Subscription rejected')); + // TRANS: Reject message from Authorise subscription page. $this->element('p', null, _('The subscription has been rejected, but no '. 'callback URL was passed. Check with the site’s ' . @@ -277,18 +291,24 @@ class UserauthorizationAction extends Action $user = User::staticGet('uri', $listener); if (!$user) { - throw new Exception(sprintf(_('Listener URI ‘%s’ not found here.'), + // TRANS: Exception thrown when no valid user is found for an authorisation request. + // TRANS: %s is a listener URI. + throw new Exception(sprintf(_('Listener URI "%s" not found here.'), $listener)); } if (strlen($listenee) > 255) { - throw new Exception(sprintf(_('Listenee URI ‘%s’ is too long.'), + // TRANS: Exception thrown when listenee URI is too long for an authorisation request. + // TRANS: %s is a listenee URI. + throw new Exception(sprintf(_('Listenee URI "%s" is too long.'), $listenee)); } $other = User::staticGet('uri', $listenee); if ($other) { - throw new Exception(sprintf(_('Listenee URI ‘%s’ is a local user.'), + // TRANS: Exception thrown when listenee URI is a local user for an authorisation request. + // TRANS: %s is a listenee URI. + throw new Exception(sprintf(_('Listenee URI "%s" is a local user.'), $listenee)); } @@ -298,12 +318,15 @@ class UserauthorizationAction extends Action $sub->subscriber = $user->id; $sub->subscribed = $remote->id; if ($sub->find(true)) { + // TRANS: Exception thrown when already subscribed. throw new Exception('You are already subscribed to this user.'); } } if ($profile == common_profile_url($nickname)) { - throw new Exception(sprintf(_('Profile URL ‘%s’ is for a local user.'), + // TRANS: Exception thrown when profile URL is a local user for an authorisation request. + // TRANS: %s is a profile URL. + throw new Exception(sprintf(_('Profile URL "%s" is for a local user.'), $profile)); } @@ -311,26 +334,34 @@ class UserauthorizationAction extends Action $license = $_GET['omb_listenee_license']; $site_license = common_config('license', 'url'); if (!common_compatible_license($license, $site_license)) { - throw new Exception(sprintf(_('Listenee stream license ‘%1$s’ is not ' . - 'compatible with site license ‘%2$s’.'), + // TRANS: Exception thrown when licenses are not compatible for an authorisation request. + // TRANS: %1$s is the license for the listenee, %2$s is the license for "this" StatusNet site. + throw new Exception(sprintf(_('Listenee stream license "%1$s" is not ' . + 'compatible with site license "%2$s".'), $license, $site_license)); } $avatar = $_GET['omb_listenee_avatar']; if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { - throw new Exception(sprintf(_('Avatar URL ‘%s’ is not valid.'), + // TRANS: Exception thrown when avatar URL is invalid for an authorisation request. + // TRANS: %s is an avatar URL. + throw new Exception(sprintf(_('Avatar URL "%s" is not valid.'), $avatar)); } $size = @getimagesize($avatar); if (!$size) { - throw new Exception(sprintf(_('Can’t read avatar URL ‘%s’.'), + // TRANS: Exception thrown when avatar URL could not be read for an authorisation request. + // TRANS: %s is an avatar URL. + throw new Exception(sprintf(_('Cannot read avatar URL "%s".'), $avatar)); } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { + // TRANS: Exception thrown when avatar URL return an invalid image type for an authorisation request. + // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Wrong image type for avatar URL '. - '‘%s’.'), $avatar)); + '"%s".'), $avatar)); } } } diff --git a/actions/userbyid.php b/actions/userbyid.php index f3e1556f3f..b8ccd0108e 100644 --- a/actions/userbyid.php +++ b/actions/userbyid.php @@ -1,5 +1,4 @@ trimmed('id'); if (!$id) { + // TRANS: Client error displayed trying to find a user by ID without providing an ID. $this->clientError(_('No ID.')); } $user = User::staticGet($id); if (!$user) { + // TRANS: Client error displayed trying to find a user by ID for a non-existing ID. $this->clientError(_('No such user.')); } diff --git a/actions/userdesignsettings.php b/actions/userdesignsettings.php index e6caea3a1b..8ce5e1f8f3 100644 --- a/actions/userdesignsettings.php +++ b/actions/userdesignsettings.php @@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/designsettings.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class UserDesignSettingsAction extends DesignSettingsAction { /** @@ -70,7 +69,6 @@ class UserDesignSettingsAction extends DesignSettingsAction * * @return string Title of the page */ - function title() { return _('Profile design'); @@ -81,7 +79,6 @@ class UserDesignSettingsAction extends DesignSettingsAction * * @return instructions for use */ - function getInstructions() { return _('Customize the way your profile looks ' . @@ -93,7 +90,6 @@ class UserDesignSettingsAction extends DesignSettingsAction * * @return Design */ - function getWorkingDesign() { $user = common_current_user(); @@ -108,7 +104,6 @@ class UserDesignSettingsAction extends DesignSettingsAction * * @return void */ - function showContent() { $design = $this->getWorkingDesign(); @@ -139,7 +134,6 @@ class UserDesignSettingsAction extends DesignSettingsAction * * @return void */ - function saveDesign() { $this->saveDesignPreferences(); @@ -185,7 +179,6 @@ class UserDesignSettingsAction extends DesignSettingsAction $design = $user->getDesign(); if (!empty($design)) { - $original = clone($design); $design->backgroundcolor = $bgcolor->intValue(); @@ -200,13 +193,11 @@ class UserDesignSettingsAction extends DesignSettingsAction if ($result === false) { common_log_db_error($design, 'UPDATE', __FILE__); - $this->showForm(_('Couldn\'t update your design.')); + $this->showForm(_('Could not update your design.')); return; } - // update design } else { - $user->query('BEGIN'); // save new design @@ -253,7 +244,6 @@ class UserDesignSettingsAction extends DesignSettingsAction * * @return nothing */ - function sethd() { diff --git a/actions/userxrd.php b/actions/userxrd.php index 582f7a35e7..7691ff155b 100644 --- a/actions/userxrd.php +++ b/actions/userxrd.php @@ -56,7 +56,7 @@ class UserxrdAction extends XrdAction } if (!$this->user) { - $this->clientError(_m('No such user.'), 404); + $this->clientError(_('No such user.'), 404); return false; } diff --git a/actions/xrds.php b/actions/xrds.php index 534182e3ed..818cd1032c 100644 --- a/actions/xrds.php +++ b/actions/xrds.php @@ -1,5 +1,4 @@ trimmed('nickname'); $this->user = User::staticGet('nickname', $nickname); if (!$this->user) { + // TRANS: Client error displayed providing a non-existing nickname. $this->clientError(_('No such user.')); return; } @@ -110,7 +110,7 @@ class XrdsAction extends Action null, array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1)); $xrdsOutputter->elementEnd('XRD'); - + //omb $xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', 'xml:id' => 'omb', @@ -122,7 +122,7 @@ class XrdsAction extends Action $xrdsOutputter->showXrdsService(OMB_ENDPOINT_UPDATEPROFILE, common_local_url('updateprofile')); $xrdsOutputter->elementEnd('XRD'); - + Event::handle('EndUserXRDS', array($this,&$xrdsOutputter)); //misc @@ -135,7 +135,5 @@ class XrdsAction extends Action $xrdsOutputter->elementEnd('XRD'); $xrdsOutputter->endXRDS(); - } } -?> diff --git a/classes/File.php b/classes/File.php index 29a8f0f1c5..e9a0131c4e 100644 --- a/classes/File.php +++ b/classes/File.php @@ -55,14 +55,20 @@ class File extends Memcached_DataObject return 'http://www.facebook.com/login.php' === $url; } - function getAttachments($post_id) { - $query = "select file.* from file join file_to_post on (file_id = file.id) join notice on (post_id = notice.id) where post_id = " . $this->escape($post_id); - $this->query($query); + /** + * Get the attachments for a particlar notice. + * + * @param int $post_id + * @return array of File objects + */ + static function getAttachments($post_id) { + $file = new File(); + $query = "select file.* from file join file_to_post on (file_id = file.id) where post_id = " . $file->escape($post_id); + $file = Memcached_DataObject::cachedQuery('File', $query); $att = array(); - while ($this->fetch()) { - $att[] = clone($this); + while ($file->fetch()) { + $att[] = clone($file); } - $this->free(); return $att; } diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index b92b67e775..97f793f4d8 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -341,6 +341,7 @@ class Memcached_DataObject extends Safe_DataObject $fail = false; $result = null; if (Event::handle('StartDBQuery', array($this, $string, &$result))) { + common_perf_counter('query', $string); try { $result = parent::_query($string); } catch (Exception $e) { @@ -494,6 +495,10 @@ class Memcached_DataObject extends Safe_DataObject } } } + // Needed to make timestamp values usefully comparable. + if (common_config('db', 'type') == 'mysql') { + parent::_query("set time_zone='+0:00'"); + } } return $result; diff --git a/classes/Notice.php b/classes/Notice.php index 3c56cd0cb4..157fdf2dc4 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -153,7 +153,7 @@ class Notice extends Memcached_DataObject function saveTags() { /* extract all #hastags */ - $count = preg_match_all('/(?:^|\s)#([\pL\pN_\-\.]{1,64})/', strtolower($this->content), $match); + $count = preg_match_all('/(?:^|\s)#([\pL\pN_\-\.]{1,64})/u', strtolower($this->content), $match); if (!$count) { return true; } @@ -241,7 +241,7 @@ class Notice extends Memcached_DataObject * array 'urls' list of attached/referred URLs to save with the * notice in place of extracting links from content * boolean 'distribute' whether to distribute the notice, default true - * + * * @fixme tag override * * @return Notice @@ -446,7 +446,10 @@ class Notice extends Memcached_DataObject function blowOnInsert($conversation = false) { self::blow('profile:notice_ids:%d', $this->profile_id); - self::blow('public'); + + if ($this->isPublic()) { + self::blow('public'); + } // XXX: Before we were blowing the casche only if the notice id // was not the root of the conversation. What to do now? @@ -481,7 +484,10 @@ class Notice extends Memcached_DataObject $this->blowOnInsert(); self::blow('profile:notice_ids:%d;last', $this->profile_id); - self::blow('public;last'); + + if ($this->isPublic()) { + self::blow('public;last'); + } } /** save all urls in the notice to the db @@ -819,9 +825,18 @@ class Notice extends Memcached_DataObject // Exclude any deleted, non-local, or blocking recipients. $profile = $this->getProfile(); + $originalProfile = null; + if ($this->repeat_of) { + // Check blocks against the original notice's poster as well. + $original = Notice::staticGet('id', $this->repeat_of); + if ($original) { + $originalProfile = $original->getProfile(); + } + } foreach ($ni as $id => $source) { $user = User::staticGet('id', $id); - if (empty($user) || $user->hasBlocked($profile)) { + if (empty($user) || $user->hasBlocked($profile) || + ($originalProfile && $user->hasBlocked($originalProfile))) { unset($ni[$id]); } } @@ -949,7 +964,7 @@ class Notice extends Memcached_DataObject $groups = array(); /* extract all !group */ - $count = preg_match_all('/(?:^|\s)!([A-Za-z0-9]{1,64})/', + $count = preg_match_all('/(?:^|\s)!(' . Nickname::DISPLAY_FMT . ')/', strtolower($this->content), $match); if (!$count) { @@ -1057,6 +1072,7 @@ class Notice extends Memcached_DataObject $reply->notice_id = $this->id; $reply->profile_id = $profile->id; + $reply->modified = $this->created; common_log(LOG_INFO, __METHOD__ . ": saving reply: notice $this->id to profile $profile->id"); @@ -1117,6 +1133,7 @@ class Notice extends Memcached_DataObject $reply->notice_id = $this->id; $reply->profile_id = $mentioned->id; + $reply->modified = $this->created; $id = $reply->insert(); @@ -1231,33 +1248,33 @@ class Notice extends Memcached_DataObject * Convert a notice into an activity for export. * * @param User $cur Current user - * + * * @return Activity activity object representing this Notice. */ - function asActivity() + function asActivity($cur) { $act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id)); if (!empty($act)) { return $act; } - $act = new Activity(); - + if (Event::handle('StartNoticeAsActivity', array($this, &$act))) { $profile = $this->getProfile(); - - $act->actor = ActivityObject::fromProfile($profile); - $act->verb = ActivityVerb::POST; - $act->objects[] = ActivityObject::fromNotice($this); + + $act->actor = ActivityObject::fromProfile($profile); + $act->actor->extra[] = $profile->profileInfo($cur); + $act->verb = ActivityVerb::POST; + $act->objects[] = ActivityObject::fromNotice($this); // XXX: should this be handled by default processing for object entry? $act->time = strtotime($this->created); $act->link = $this->bestUrl(); - + $act->content = common_xml_safe_str($this->rendered); $act->id = $this->uri; $act->title = common_xml_safe_str($this->content); @@ -1284,9 +1301,9 @@ class Notice extends Memcached_DataObject $act->enclosures[] = $enclosure; } } - + $ctx = new ActivityContext(); - + if (!empty($this->reply_to)) { $reply = Notice::staticGet('id', $this->reply_to); if (!empty($reply)) { @@ -1294,31 +1311,31 @@ class Notice extends Memcached_DataObject $ctx->replyToUrl = $reply->bestUrl(); } } - + $ctx->location = $this->getLocation(); - + $conv = null; - + if (!empty($this->conversation)) { $conv = Conversation::staticGet('id', $this->conversation); if (!empty($conv)) { $ctx->conversation = $conv->uri; } } - + $reply_ids = $this->getReplies(); - + foreach ($reply_ids as $id) { $profile = Profile::staticGet('id', $id); if (!empty($profile)) { $ctx->attention[] = $profile->getUri(); } } - + $groups = $this->getGroups(); - + foreach ($groups as $group) { - $ctx->attention[] = $group->uri; + $ctx->attention[] = $group->getUri(); } // XXX: deprecated; use ActivityVerb::SHARE instead @@ -1330,7 +1347,7 @@ class Notice extends Memcached_DataObject $ctx->forwardID = $repeat->uri; $ctx->forwardUrl = $repeat->bestUrl(); } - + $act->context = $ctx; // Source @@ -1340,7 +1357,7 @@ class Notice extends Memcached_DataObject if (!empty($atom_feed)) { $act->source = new ActivitySource(); - + // XXX: we should store the actual feed ID $act->source->id = $atom_feed; @@ -1353,7 +1370,7 @@ class Notice extends Memcached_DataObject $act->source->links['self'] = $atom_feed; $act->source->icon = $profile->avatarUrl(AVATAR_PROFILE_SIZE); - + $notice = $profile->getCurrentNotice(); if (!empty($notice)) { @@ -1375,7 +1392,7 @@ class Notice extends Memcached_DataObject Event::handle('EndNoticeAsActivity', array($this, &$act)); } - + self::cacheSet(Cache::codeKey('notice:as-activity:'.$this->id), $act); return $act; @@ -1386,17 +1403,17 @@ class Notice extends Memcached_DataObject function asAtomEntry($namespace=false, $source=false, - $author=true, + $author=true, $cur=null) { - $act = $this->asActivity(); + $act = $this->asActivity($cur); $act->extra[] = $this->noticeInfo($cur); return $act->asString($namespace, $author, $source); } /** * Extra notice info for atom entries - * + * * Clients use some extra notice info in the atom stream. * This gives it to them. * @@ -2098,4 +2115,14 @@ class Notice extends Memcached_DataObject $obj->whereAdd($max); } } + + function isPublic() + { + if (common_config('public', 'localonly')) { + return ($this->is_local == Notice::LOCAL_PUBLIC); + } else { + return (($this->is_local != Notice::LOCAL_NONPUBLIC) && + ($this->is_local != Notice::GATEWAY)); + } + } } diff --git a/classes/Profile.php b/classes/Profile.php index d658b6b0ba..2ad302ccb8 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -354,7 +354,10 @@ class Profile extends Memcached_DataObject $profiles = array(); while ($subs->fetch()) { - $profiles[] = Profile::staticGet($subs->subscribed); + $profile = Profile::staticGet($subs->subscribed); + if ($profile) { + $profiles[] = $profile; + } } return new ArrayWrapper($profiles); @@ -369,7 +372,10 @@ class Profile extends Memcached_DataObject $profiles = array(); while ($subs->fetch()) { - $profiles[] = Profile::staticGet($subs->subscriber); + $profile = Profile::staticGet($subs->subscriber); + if ($profile) { + $profiles[] = $profile; + } } return new ArrayWrapper($profiles); @@ -746,6 +752,10 @@ class Profile extends Memcached_DataObject throw new Exception("Can't save role '$name' for profile '{$this->id}'"); } + if ($name == 'owner') { + User::blow('user:site_owner'); + } + Event::handle('EndGrantRole', array($this, $name)); } @@ -774,6 +784,10 @@ class Profile extends Memcached_DataObject throw new Exception(sprintf(_('Cannot revoke role "%1$s" for user #%2$d; database error.'),$name, $this->id)); } + if ($name == 'owner') { + User::blow('user:site_owner'); + } + Event::handle('EndRevokeRole', array($this, $name)); return true; @@ -859,6 +873,12 @@ class Profile extends Memcached_DataObject case Right::EMAILONFAVE: $result = !$this->isSandboxed(); break; + case Right::WEBLOGIN: + $result = !$this->isSilenced(); + break; + case Right::API: + $result = !$this->isSilenced(); + break; case Right::BACKUPACCOUNT: $result = common_config('profile', 'backup'); break; @@ -918,6 +938,31 @@ class Profile extends Memcached_DataObject return $xs->getString(); } + /** + * Extra profile info for atom entries + * + * Clients use some extra profile info in the atom stream. + * This gives it to them. + * + * @param User $cur Current user + * + * @return array representation of element or null + */ + + function profileInfo($cur) + { + $profileInfoAttr = array('local_id' => $this->id); + + if ($cur != null) { + // Whether the current user is a subscribed to this profile + $profileInfoAttr['following'] = $cur->isSubscribed($this) ? 'true' : 'false'; + // Whether the current user is has blocked this profile + $profileInfoAttr['blocking'] = $cur->hasBlocked($this) ? 'true' : 'false'; + } + + return array('statusnet:profile_info', $profileInfoAttr, null); + } + /** * Returns an XML string fragment with profile information as an * Activity Streams element. diff --git a/classes/Session.php b/classes/Session.php index e1c83ad4dc..166b89815a 100644 --- a/classes/Session.php +++ b/classes/Session.php @@ -156,6 +156,13 @@ class Session extends Memcached_DataObject $session->selectAdd(); $session->selectAdd('id'); + $limit = common_config('sessions', 'gc_limit'); + if ($limit > 0) { + // On large sites, too many sessions to expire + // at once will just result in failure. + $session->limit($limit); + } + $session->find(); while ($session->fetch()) { diff --git a/classes/User.php b/classes/User.php index 04b9b4cc68..962714aa4d 100644 --- a/classes/User.php +++ b/classes/User.php @@ -970,7 +970,7 @@ class User extends Memcached_DataObject } /* - * Get a list of OAuth client application that have access to this + * Get a list of OAuth client applications that have access to this * user's account. */ function getConnectedApps($offset = 0, $limit = null) diff --git a/classes/User_group.php b/classes/User_group.php index 68f61cb7f4..5a9991fe9e 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -487,6 +487,7 @@ class User_group extends Memcached_DataObject } // MAGICALLY put fields into current scope + // @fixme kill extract(); it makes debugging absurdly hard extract($fields); @@ -498,6 +499,9 @@ class User_group extends Memcached_DataObject // fill in later... $uri = null; } + if (empty($mainpage)) { + $mainpage = common_local_url('showgroup', array('nickname' => $nickname)); + } $group->nickname = $nickname; $group->fullname = $fullname; @@ -508,64 +512,70 @@ class User_group extends Memcached_DataObject $group->mainpage = $mainpage; $group->created = common_sql_now(); - $result = $group->insert(); + if (Event::handle('StartGroupSave', array(&$group))) { - if (!$result) { - common_log_db_error($group, 'INSERT', __FILE__); - // TRANS: Server exception thrown when creating a group failed. - throw new ServerException(_('Could not create group.')); - } - - if (!isset($uri) || empty($uri)) { - $orig = clone($group); - $group->uri = common_local_url('groupbyid', array('id' => $group->id)); - $result = $group->update($orig); - if (!$result) { - common_log_db_error($group, 'UPDATE', __FILE__); - // TRANS: Server exception thrown when updating a group URI failed. - throw new ServerException(_('Could not set group URI.')); - } - } - - $result = $group->setAliases($aliases); - - if (!$result) { - // TRANS: Server exception thrown when creating group aliases failed. - throw new ServerException(_('Could not create aliases.')); - } - - $member = new Group_member(); - - $member->group_id = $group->id; - $member->profile_id = $userid; - $member->is_admin = 1; - $member->created = $group->created; - - $result = $member->insert(); - - if (!$result) { - common_log_db_error($member, 'INSERT', __FILE__); - // TRANS: Server exception thrown when setting group membership failed. - throw new ServerException(_('Could not set group membership.')); - } - - if ($local) { - $local_group = new Local_group(); - - $local_group->group_id = $group->id; - $local_group->nickname = $nickname; - $local_group->created = common_sql_now(); - - $result = $local_group->insert(); + $result = $group->insert(); if (!$result) { - common_log_db_error($local_group, 'INSERT', __FILE__); - // TRANS: Server exception thrown when saving local group information failed. - throw new ServerException(_('Could not save local group info.')); + common_log_db_error($group, 'INSERT', __FILE__); + // TRANS: Server exception thrown when creating a group failed. + throw new ServerException(_('Could not create group.')); } + + if (!isset($uri) || empty($uri)) { + $orig = clone($group); + $group->uri = common_local_url('groupbyid', array('id' => $group->id)); + $result = $group->update($orig); + if (!$result) { + common_log_db_error($group, 'UPDATE', __FILE__); + // TRANS: Server exception thrown when updating a group URI failed. + throw new ServerException(_('Could not set group URI.')); + } + } + + $result = $group->setAliases($aliases); + + if (!$result) { + // TRANS: Server exception thrown when creating group aliases failed. + throw new ServerException(_('Could not create aliases.')); + } + + $member = new Group_member(); + + $member->group_id = $group->id; + $member->profile_id = $userid; + $member->is_admin = 1; + $member->created = $group->created; + + $result = $member->insert(); + + if (!$result) { + common_log_db_error($member, 'INSERT', __FILE__); + // TRANS: Server exception thrown when setting group membership failed. + throw new ServerException(_('Could not set group membership.')); + } + + if ($local) { + $local_group = new Local_group(); + + $local_group->group_id = $group->id; + $local_group->nickname = $nickname; + $local_group->created = common_sql_now(); + + $result = $local_group->insert(); + + if (!$result) { + common_log_db_error($local_group, 'INSERT', __FILE__); + // TRANS: Server exception thrown when saving local group information failed. + throw new ServerException(_('Could not save local group info.')); + } + } + + $group->query('COMMIT'); + + Event::handle('EndGroupSave', array($group)); } - $group->query('COMMIT'); return $group; } diff --git a/classes/statusnet.ini b/classes/statusnet.ini index d1d2980fd3..bf8d173805 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -502,7 +502,8 @@ uri = U [reply] notice_id = 129 profile_id = 129 -modified = 384 +modified = 142 +;modified = 384 ; skipping the mysql_timestamp mode so we can override its setting replied_id = 1 [reply__keys] diff --git a/db/notice_source.sql b/db/notice_source.sql index 82074077b4..dec8080a01 100644 --- a/db/notice_source.sql +++ b/db/notice_source.sql @@ -24,6 +24,7 @@ VALUES ('HelloTxt','HelloTxt','http://hellotxt.com/', now()), ('identicatools','Laconica Tools','http://bitbucketlabs.net/laconica-tools/', now()), ('identichat','identichat','http://identichat.prosody.im/', now()), + ('IdentiCurse','IdentiCurse','http://identicurse.net/', now()), ('IdentiFox','IdentiFox','http://www.bitbucket.org/uncryptic/identifox/', now()), ('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()), ('Jiminy','Jiminy','http://code.google.com/p/jiminy/', now()), @@ -77,4 +78,5 @@ VALUES ('twitvim','TwitVim','http://vim.sourceforge.net/scripts/script.php?script_id=2204', now()), ('Updating.Me','Updating.Me','http://updating.me/', now()), ('urfastr','urfastr','http://urfastr.net/', now()), - ('yatca','Yatca','http://www.yatca.com/', now()); + ('yatca','Yatca','http://www.yatca.com/', now()), + ('rss.me', 'rss.me', 'http://rss.me/', now()); diff --git a/doc-src/im b/doc-src/im index 896c121879..9932632188 100644 --- a/doc-src/im +++ b/doc-src/im @@ -32,19 +32,40 @@ Commands You can do some minor management of your account through Jabber. These are the currently-implemented commands: -* **on**: Turn on notifications. You'll receive copies of messages by people - you subscribe to. -* **off**: Turn off notifications. You'll no longer receive Jabber - notifications. -* **stop**: Same as 'off' -* **quit**: Same as 'off' -* **help**: Show this help. List available Jabber/XMPP commands -* **follow <nickname>**: Subscribe to <nickname> -* **sub <nickname>**: Same as follow -* **leave <nickname>**: Unsubscribe from <nickname> -* **unsub <nickname>**: Same as leave -* **d <nickname> <text>**: Send direct message to <nickname> with message body <text> -* **get <nickname>**: Get last notice from <nickname> -* **last <nickname>**: Same as 'get' -* **whois <nickname>**: Get Profile info on <nickname> -* **fav <nickname>**: Add user's last notice as a favorite +* **on** - turn on notifications +* **off** - turn off notifications +* **help** - show this help +* **follow <nickname>** - subscribe to user +* **groups** - lists the groups you have joined +* **subscriptions** - list the people you follow +* **subscribers** - list the people that follow you +* **leave <nickname>** - unsubscribe from user +* **d <nickname> <text>** - direct message to user +* **get <nickname>** - get last notice from user +* **whois <nickname>** - get profile info on user +* **lose <nickname>** - force user to stop following you +* **fav <nickname>** - add user's last notice as a 'fave' +* **fav #<notice_id>** - add notice with the given id as a 'fave' +* **repeat #<notice_id>** - repeat a notice with a given id +* **repeat <nickname>** - repeat the last notice from user +* **reply #<notice_id>** - reply to notice with a given id +* **reply <nickname>** - reply to the last notice from user +* **join <group>** - join group +* **login** - Get a link to login to the web interface +* **drop <group>** - leave group +* **stats** - get your stats +* **stop** - same as 'off' +* **quit** - same as 'off' +* **sub <nickname>** - same as 'follow' +* **unsub <nickname>** - same as 'leave' +* **last <nickname>** - same as 'get' +* **on <nickname>** - not yet implemented. +* **off <nickname>** - not yet implemented. +* **nudge <nickname>** - remind a user to update. +* **invite <phone number>** - not yet implemented. +* **track <word>** - not yet implemented. +* **untrack <word>** - not yet implemented. +* **track off** - not yet implemented. +* **untrack all** - not yet implemented. +* **tracks** - not yet implemented. +* **tracking** - not yet implemented. diff --git a/extlib/Auth/SASL.php b/extlib/Auth/SASL.php new file mode 100644 index 0000000000..e70f0146bc --- /dev/null +++ b/extlib/Auth/SASL.php @@ -0,0 +1,104 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: SASL.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* Client implementation of various SASL mechanisms +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +require_once('PEAR.php'); + +class Auth_SASL +{ + /** + * Factory class. Returns an object of the request + * type. + * + * @param string $type One of: Anonymous + * Plain + * CramMD5 + * DigestMD5 + * Types are not case sensitive + */ + function &factory($type) + { + switch (strtolower($type)) { + case 'anonymous': + $filename = 'Auth/SASL/Anonymous.php'; + $classname = 'Auth_SASL_Anonymous'; + break; + + case 'login': + $filename = 'Auth/SASL/Login.php'; + $classname = 'Auth_SASL_Login'; + break; + + case 'plain': + $filename = 'Auth/SASL/Plain.php'; + $classname = 'Auth_SASL_Plain'; + break; + + case 'external': + $filename = 'Auth/SASL/External.php'; + $classname = 'Auth_SASL_External'; + break; + + case 'crammd5': + $filename = 'Auth/SASL/CramMD5.php'; + $classname = 'Auth_SASL_CramMD5'; + break; + + case 'digestmd5': + $filename = 'Auth/SASL/DigestMD5.php'; + $classname = 'Auth_SASL_DigestMD5'; + break; + + default: + return PEAR::raiseError('Invalid SASL mechanism type'); + break; + } + + require_once($filename); + $obj = new $classname(); + return $obj; + } +} + +?> diff --git a/extlib/Auth/SASL/Anonymous.php b/extlib/Auth/SASL/Anonymous.php new file mode 100644 index 0000000000..4eaaa399e6 --- /dev/null +++ b/extlib/Auth/SASL/Anonymous.php @@ -0,0 +1,71 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: Anonymous.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* Implmentation of ANONYMOUS SASL mechanism +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +require_once('Auth/SASL/Common.php'); + +class Auth_SASL_Anonymous extends Auth_SASL_Common +{ + /** + * Not much to do here except return the token supplied. + * No encoding, hashing or encryption takes place for this + * mechanism, simply one of: + * o An email address + * o An opaque string not containing "@" that can be interpreted + * by the sysadmin + * o Nothing + * + * We could have some logic here for the second option, but this + * would by no means create something interpretable. + * + * @param string $token Optional email address or string to provide + * as trace information. + * @return string The unaltered input token + */ + function getResponse($token = '') + { + return $token; + } +} +?> \ No newline at end of file diff --git a/extlib/Auth/SASL/Common.php b/extlib/Auth/SASL/Common.php new file mode 100644 index 0000000000..44181645c4 --- /dev/null +++ b/extlib/Auth/SASL/Common.php @@ -0,0 +1,74 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: Common.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* Common functionality to SASL mechanisms +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +class Auth_SASL_Common +{ + /** + * Function which implements HMAC MD5 digest + * + * @param string $key The secret key + * @param string $data The data to protect + * @return string The HMAC MD5 digest + */ + function _HMAC_MD5($key, $data) + { + if (strlen($key) > 64) { + $key = pack('H32', md5($key)); + } + + if (strlen($key) < 64) { + $key = str_pad($key, 64, chr(0)); + } + + $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64); + $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64); + + $inner = pack('H32', md5($k_ipad . $data)); + $digest = md5($k_opad . $inner); + + return $digest; + } +} +?> diff --git a/extlib/Auth/SASL/CramMD5.php b/extlib/Auth/SASL/CramMD5.php new file mode 100644 index 0000000000..177279c06b --- /dev/null +++ b/extlib/Auth/SASL/CramMD5.php @@ -0,0 +1,68 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: CramMD5.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* Implmentation of CRAM-MD5 SASL mechanism +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +require_once('Auth/SASL/Common.php'); + +class Auth_SASL_CramMD5 extends Auth_SASL_Common +{ + /** + * Implements the CRAM-MD5 SASL mechanism + * This DOES NOT base64 encode the return value, + * you will need to do that yourself. + * + * @param string $user Username + * @param string $pass Password + * @param string $challenge The challenge supplied by the server. + * this should be already base64_decoded. + * + * @return string The string to pass back to the server, of the form + * " ". This is NOT base64_encoded. + */ + function getResponse($user, $pass, $challenge) + { + return $user . ' ' . $this->_HMAC_MD5($pass, $challenge); + } +} +?> \ No newline at end of file diff --git a/extlib/Auth/SASL/DigestMD5.php b/extlib/Auth/SASL/DigestMD5.php new file mode 100644 index 0000000000..8c58787dfe --- /dev/null +++ b/extlib/Auth/SASL/DigestMD5.php @@ -0,0 +1,197 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: DigestMD5.php 294702 2010-02-07 16:03:55Z cweiske $ + +/** +* Implmentation of DIGEST-MD5 SASL mechanism +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +require_once('Auth/SASL/Common.php'); + +class Auth_SASL_DigestMD5 extends Auth_SASL_Common +{ + /** + * Provides the (main) client response for DIGEST-MD5 + * requires a few extra parameters than the other + * mechanisms, which are unavoidable. + * + * @param string $authcid Authentication id (username) + * @param string $pass Password + * @param string $challenge The digest challenge sent by the server + * @param string $hostname The hostname of the machine you're connecting to + * @param string $service The servicename (eg. imap, pop, acap etc) + * @param string $authzid Authorization id (username to proxy as) + * @return string The digest response (NOT base64 encoded) + * @access public + */ + function getResponse($authcid, $pass, $challenge, $hostname, $service, $authzid = '') + { + $challenge = $this->_parseChallenge($challenge); + $authzid_string = ''; + if ($authzid != '') { + $authzid_string = ',authzid="' . $authzid . '"'; + } + + if (!empty($challenge)) { + $cnonce = $this->_getCnonce(); + $digest_uri = sprintf('%s/%s', $service, $hostname); + $response_value = $this->_getResponseValue($authcid, $pass, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $authzid); + + if ($challenge['realm']) { + return sprintf('username="%s",realm="%s"' . $authzid_string . +',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']); + } else { + return sprintf('username="%s"' . $authzid_string . ',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']); + } + } else { + return PEAR::raiseError('Invalid digest challenge'); + } + } + + /** + * Parses and verifies the digest challenge* + * + * @param string $challenge The digest challenge + * @return array The parsed challenge as an assoc + * array in the form "directive => value". + * @access private + */ + function _parseChallenge($challenge) + { + $tokens = array(); + while (preg_match('/^([a-z-]+)=("[^"]+(? diff --git a/extlib/Auth/SASL/External.php b/extlib/Auth/SASL/External.php new file mode 100644 index 0000000000..86a17cb7ab --- /dev/null +++ b/extlib/Auth/SASL/External.php @@ -0,0 +1,63 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: External.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* Implmentation of EXTERNAL SASL mechanism +* +* @author Christoph Schulz +* @access public +* @version 1.0.3 +* @package Auth_SASL +*/ + +require_once('Auth/SASL/Common.php'); + +class Auth_SASL_External extends Auth_SASL_Common +{ + /** + * Returns EXTERNAL response + * + * @param string $authcid Authentication id (username) + * @param string $pass Password + * @param string $authzid Autorization id + * @return string EXTERNAL Response + */ + function getResponse($authcid, $pass, $authzid = '') + { + return $authzid; + } +} +?> diff --git a/extlib/Auth/SASL/Login.php b/extlib/Auth/SASL/Login.php new file mode 100644 index 0000000000..a925f53a79 --- /dev/null +++ b/extlib/Auth/SASL/Login.php @@ -0,0 +1,65 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: Login.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* This is technically not a SASL mechanism, however +* it's used by Net_Sieve, Net_Cyrus and potentially +* other protocols , so here is a good place to abstract +* it. +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +require_once('Auth/SASL/Common.php'); + +class Auth_SASL_Login extends Auth_SASL_Common +{ + /** + * Pseudo SASL LOGIN mechanism + * + * @param string $user Username + * @param string $pass Password + * @return string LOGIN string + */ + function getResponse($user, $pass) + { + return sprintf('LOGIN %s %s', $user, $pass); + } +} +?> \ No newline at end of file diff --git a/extlib/Auth/SASL/Plain.php b/extlib/Auth/SASL/Plain.php new file mode 100644 index 0000000000..912710169e --- /dev/null +++ b/extlib/Auth/SASL/Plain.php @@ -0,0 +1,63 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: Plain.php 286825 2009-08-05 06:23:42Z cweiske $ + +/** +* Implmentation of PLAIN SASL mechanism +* +* @author Richard Heyes +* @access public +* @version 1.0 +* @package Auth_SASL +*/ + +require_once('Auth/SASL/Common.php'); + +class Auth_SASL_Plain extends Auth_SASL_Common +{ + /** + * Returns PLAIN response + * + * @param string $authcid Authentication id (username) + * @param string $pass Password + * @param string $authzid Autorization id + * @return string PLAIN Response + */ + function getResponse($authcid, $pass, $authzid = '') + { + return $authzid . chr(0) . $authcid . chr(0) . $pass; + } +} +?> diff --git a/index.php b/index.php index f8b200a58a..c8d4fbee9b 100644 --- a/index.php +++ b/index.php @@ -37,6 +37,9 @@ * @license GNU Affero General Public License http://www.gnu.org/licenses/ */ +$_startTime = microtime(true); +$_perfCounters = array(); + define('INSTALLDIR', dirname(__FILE__)); define('STATUSNET', true); define('LACONICA', true); // compatibility diff --git a/js/jquery.form.js b/js/jquery.form.js index 2b853df428..936b847abe 100644 --- a/js/jquery.form.js +++ b/js/jquery.form.js @@ -1,785 +1,632 @@ -/*! - * jQuery Form Plugin - * version: 2.49 (18-OCT-2010) - * @requires jQuery v1.3.2 or later - * - * Examples and documentation at: http://malsup.com/jquery/form/ - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ -;(function($) { - -/* - Usage Note: - ----------- - Do not use both ajaxSubmit and ajaxForm on the same form. These - functions are intended to be exclusive. Use ajaxSubmit if you want - to bind your own submit handler to the form. For example, - - $(document).ready(function() { - $('#myForm').bind('submit', function(e) { - e.preventDefault(); // <-- important - $(this).ajaxSubmit({ - target: '#output' - }); - }); - }); - - Use ajaxForm when you want the plugin to manage all the event binding - for you. For example, - - $(document).ready(function() { - $('#myForm').ajaxForm({ - target: '#output' - }); - }); - - When using ajaxForm, the ajaxSubmit function will be invoked for you - at the appropriate time. -*/ - -/** - * ajaxSubmit() provides a mechanism for immediately submitting - * an HTML form using AJAX. - */ -$.fn.ajaxSubmit = function(options) { - // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) - if (!this.length) { - log('ajaxSubmit: skipping submit process - no element selected'); - return this; - } - - if (typeof options == 'function') { - options = { success: options }; - } - - var url = $.trim(this.attr('action')); - if (url) { - // clean url (don't include hash vaue) - url = (url.match(/^([^#]+)/)||[])[1]; - } - url = url || window.location.href || ''; - - options = $.extend(true, { - url: url, - type: this.attr('method') || 'GET', - iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' - }, options); - - // hook for manipulating the form data before it is extracted; - // convenient for use with rich editors like tinyMCE or FCKEditor - var veto = {}; - this.trigger('form-pre-serialize', [this, options, veto]); - if (veto.veto) { - log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); - return this; - } - - // provide opportunity to alter form data before it is serialized - if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { - log('ajaxSubmit: submit aborted via beforeSerialize callback'); - return this; - } - - var n,v,a = this.formToArray(options.semantic); - if (options.data) { - options.extraData = options.data; - for (n in options.data) { - if(options.data[n] instanceof Array) { - for (var k in options.data[n]) { - a.push( { name: n, value: options.data[n][k] } ); - } - } - else { - v = options.data[n]; - v = $.isFunction(v) ? v() : v; // if value is fn, invoke it - a.push( { name: n, value: v } ); - } - } - } - - // give pre-submit callback an opportunity to abort the submit - if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { - log('ajaxSubmit: submit aborted via beforeSubmit callback'); - return this; - } - - // fire vetoable 'validate' event - this.trigger('form-submit-validate', [a, this, options, veto]); - if (veto.veto) { - log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); - return this; - } - - var q = $.param(a); - - if (options.type.toUpperCase() == 'GET') { - options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; - options.data = null; // data is null for 'get' - } - else { - options.data = q; // data is the query string for 'post' - } - - var $form = this, callbacks = []; - if (options.resetForm) { - callbacks.push(function() { $form.resetForm(); }); - } - if (options.clearForm) { - callbacks.push(function() { $form.clearForm(); }); - } - - // perform a load on the target only if dataType is not provided - if (!options.dataType && options.target) { - var oldSuccess = options.success || function(){}; - callbacks.push(function(data) { - var fn = options.replaceTarget ? 'replaceWith' : 'html'; - $(options.target)[fn](data).each(oldSuccess, arguments); - }); - } - else if (options.success) { - callbacks.push(options.success); - } - - options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg - var context = options.context || options; // jQuery 1.4+ supports scope context - for (var i=0, max=callbacks.length; i < max; i++) { - callbacks[i].apply(context, [data, status, xhr || $form, $form]); - } - }; - - // are there files to upload? - var fileInputs = $('input:file', this).length > 0; - var mp = 'multipart/form-data'; - var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); - - // options.iframe allows user to force iframe mode - // 06-NOV-09: now defaulting to iframe mode if file input is detected - if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { - // hack to fix Safari hang (thanks to Tim Molendijk for this) - // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d - if (options.closeKeepAlive) { - $.get(options.closeKeepAlive, fileUpload); - } - else { - fileUpload(); - } - } - else { - $.ajax(options); - } - - // fire 'notify' event - this.trigger('form-submit-notify', [this, options]); - return this; - - - // private function for handling file uploads (hat tip to YAHOO!) - function fileUpload() { - var form = $form[0]; - - if ($(':input[name=submit],:input[id=submit]', form).length) { - // if there is an input with a name or id of 'submit' then we won't be - // able to invoke the submit fn on the form (at least not x-browser) - alert('Error: Form elements must not have name or id of "submit".'); - return; - } - - var s = $.extend(true, {}, $.ajaxSettings, options); - s.context = s.context || s; - var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id; - window[fn] = function() { - var f = $io.data('form-plugin-onload'); - if (f) { - f(); - window[fn] = undefined; - try { delete window[fn]; } catch(e){} - } - } - var $io = $('