Merge branch '0.9.x'

This commit is contained in:
Evan Prodromou 2010-09-23 09:50:46 -04:00
commit 0f1fc36a05
317 changed files with 32526 additions and 20414 deletions

View File

@ -83,6 +83,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error message. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, $this->format 400, $this->format
); );

View File

@ -86,6 +86,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, $this->format 400, $this->format
); );

View File

@ -83,6 +83,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, $this->format 400, $this->format
); );

View File

@ -107,6 +107,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, $this->format 400, $this->format
); );

View File

@ -81,6 +81,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, $this->format 400, $this->format
); );

View File

@ -86,6 +86,7 @@ class ApiBlockCreateAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -85,6 +85,7 @@ class ApiBlockDestroyAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -357,6 +357,7 @@ class ApiDirectMessageAction extends ApiAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
strtotime($this->messages[0]->created), strtotime($this->messages[0]->created),
strtotime($this->messages[$last]->created) strtotime($this->messages[$last]->created)

View File

@ -106,6 +106,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -88,6 +88,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -89,6 +89,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -88,6 +88,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -88,6 +88,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -102,6 +102,7 @@ class ApiGroupCreateAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -89,6 +89,7 @@ class ApiGroupJoinAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -89,6 +89,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -213,6 +213,7 @@ class ApiGroupListAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
strtotime($this->groups[0]->created), strtotime($this->groups[0]->created),

View File

@ -204,6 +204,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
strtotime($this->groups[0]->created), strtotime($this->groups[0]->created),
strtotime($this->groups[$last]->created)) strtotime($this->groups[$last]->created))

View File

@ -183,6 +183,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->group->id, $this->group->id,
strtotime($this->profiles[0]->created), strtotime($this->profiles[0]->created),

View File

@ -149,6 +149,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->group->id, $this->group->id,
strtotime($this->group->modified)) strtotime($this->group->modified))

View File

@ -64,6 +64,7 @@ class ApiMediaUploadAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, $this->format 400, $this->format
); );

View File

@ -62,6 +62,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
parent::prepare($args); parent::prepare($args);
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
// TRANS: Client error. POST is a HTTP command. It should not be translated.
$this->clientError(_('This method requires a POST.'), $this->clientError(_('This method requires a POST.'),
400, $this->format); 400, $this->format);
return false; return false;

View File

@ -194,6 +194,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->notice->id, $this->notice->id,
strtotime($this->notice->created)) strtotime($this->notice->created))

View File

@ -195,6 +195,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') { if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError( $this->clientError(
// TRANS: Client error. POST is a HTTP command. It should not be translated.
_('This method requires a POST.'), _('This method requires a POST.'),
400, 400,
$this->format $this->format

View File

@ -181,6 +181,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
isset($this->ids_only) ? 'IDs' : 'Profiles', isset($this->ids_only) ? 'IDs' : 'Profiles',

View File

@ -259,6 +259,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -346,6 +346,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -229,6 +229,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->group->id, $this->group->id,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -254,6 +254,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -244,6 +244,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -311,6 +311,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created)) strtotime($this->notices[$last]->created))

View File

@ -232,6 +232,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->tag, $this->tag,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -234,6 +234,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
return '"' . implode( return '"' . implode(
':', ':',
array($this->arg('action'), array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(), common_language(),
$this->user->id, $this->user->id,
strtotime($this->notices[0]->created), strtotime($this->notices[0]->created),

View File

@ -188,7 +188,7 @@ class EditApplicationAction extends OwnerDesignAction
} elseif (Oauth_application::descriptionTooLong($description)) { } elseif (Oauth_application::descriptionTooLong($description)) {
$this->showForm(sprintf( $this->showForm(sprintf(
_('Description is too long (max %d chars).'), _('Description is too long (max %d chars).'),
Oauth_application::maxDescription())); Oauth_application::maxDesc()));
return; return;
} elseif (mb_strlen($source_url) > 255) { } elseif (mb_strlen($source_url) > 255) {
$this->showForm(_('Source URL is too long.')); $this->showForm(_('Source URL is too long.'));
@ -253,7 +253,10 @@ class EditApplicationAction extends OwnerDesignAction
$result = $this->app->update($orig); $result = $this->app->update($orig);
if (!$result) { // Note: 0 means no rows changed, which can happen if the only
// thing we changed was the icon, since it's not altered until
// the next step.
if ($result === false) {
common_log_db_error($this->app, 'UPDATE', __FILE__); common_log_db_error($this->app, 'UPDATE', __FILE__);
$this->serverError(_('Could not update application.')); $this->serverError(_('Could not update application.'));
} }

View File

@ -131,7 +131,11 @@ class EmailsettingsAction extends AccountSettingsAction
// TRANS: Field label for e-mail address input in e-mail settings form. // TRANS: Field label for e-mail address input in e-mail settings form.
$this->input('email', _('Email address'), $this->input('email', _('Email address'),
($this->arg('email')) ? $this->arg('email') : null, ($this->arg('email')) ? $this->arg('email') : null,
// TRANS: Instructions for e-mail address input form. // TRANS: Instructions for e-mail address input form. Do not translate
// TRANS: "example.org". It is one of the domain names reserved for
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
// TRANS: Any other domain may be owned by a legitimate person or
// TRANS: organization.
_('Email address, like "UserName@example.org"')); _('Email address, like "UserName@example.org"'));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');

View File

@ -97,9 +97,13 @@ class GroupmembersAction extends GroupDesignAction
function title() function title()
{ {
if ($this->page == 1) { if ($this->page == 1) {
// TRANS: Title of the page showing group members.
// TRANS: %s is the name of the group.
return sprintf(_('%s group members'), return sprintf(_('%s group members'),
$this->group->nickname); $this->group->nickname);
} else { } else {
// TRANS: Title of the page showing group members.
// TRANS: %1$s is the name of the group, %2$d is the page number of the members list.
return sprintf(_('%1$s group members, page %2$d'), return sprintf(_('%1$s group members, page %2$d'),
$this->group->nickname, $this->group->nickname,
$this->page); $this->page);
@ -389,7 +393,14 @@ class GroupBlockForm extends Form
function formActions() function formActions()
{ {
$this->out->submit('submit', _('Block'), 'submit', null, _('Block this user')); $this->out->submit(
'submit',
// TRANS: Button text for the form that will block a user from a group.
_m('BUTTON','Block'),
'submit',
null,
// TRANS: Submit button title.
_m('TOOLTIP',_('Block this user'));
} }
} }
@ -516,6 +527,13 @@ class MakeAdminForm extends Form
function formActions() function formActions()
{ {
$this->out->submit('submit', _('Make Admin'), 'submit', null, _('Make this user an admin')); $this->out->submit(
'submit',
// TRANS: Button text for the form that will make a user administrator.
_m('BUTTON','Make Admin'),
'submit',
null,
// TRANS: Submit button title.
_m('TOOLTIP','Make this user an admin'));
} }
} }

View File

@ -137,6 +137,9 @@ class ImsettingsAction extends ConnectSettingsAction
($this->arg('jabber')) ? $this->arg('jabber') : null, ($this->arg('jabber')) ? $this->arg('jabber') : null,
// TRANS: IM address input field instructions in IM settings form. // TRANS: IM address input field instructions in IM settings form.
// TRANS: %s is the IM address set for the site. // TRANS: %s is the IM address set for the site.
// TRANS: Do not translate "example.org". It is one of the domain names reserved for use in examples by
// TRANS: http://www.rfc-editor.org/rfc/rfc2606.txt. Any other domain may be owned by a legitimate
// TRANS: person or organization.
sprintf(_('Jabber or GTalk address, '. sprintf(_('Jabber or GTalk address, '.
'like "UserName@example.org". '. 'like "UserName@example.org". '.
'First, make sure to add %s to your '. 'First, make sure to add %s to your '.

View File

@ -170,7 +170,7 @@ class NewApplicationAction extends OwnerDesignAction
} elseif (Oauth_application::descriptionTooLong($description)) { } elseif (Oauth_application::descriptionTooLong($description)) {
$this->showForm(sprintf( $this->showForm(sprintf(
_('Description is too long (max %d chars).'), _('Description is too long (max %d chars).'),
Oauth_application::maxDescription())); Oauth_application::maxDesc()));
return; return;
} elseif (empty($source_url)) { } elseif (empty($source_url)) {
$this->showForm(_('Source URL is required.')); $this->showForm(_('Source URL is required.'));

View File

@ -80,7 +80,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
function getInstructions() function getInstructions()
{ {
return _('You have allowed the following applications to access you account.'); return _('You have allowed the following applications to access your account.');
} }
/** /**

View File

@ -151,6 +151,7 @@ class ShownoticeAction extends OwnerDesignAction
strtotime($this->avatar->modified) : 0; strtotime($this->avatar->modified) : 0;
return 'W/"' . implode(':', array($this->arg('action'), return 'W/"' . implode(':', array($this->arg('action'),
common_user_cache_hash(),
common_language(), common_language(),
$this->notice->id, $this->notice->id,
strtotime($this->notice->created), strtotime($this->notice->created),

View File

@ -129,4 +129,29 @@ class Fave extends Memcached_DataObject
return $ids; return $ids;
} }
function asActivity()
{
$notice = Notice::staticGet('id', $this->notice_id);
$profile = Profile::staticGet('id', $this->user_id);
$act = new Activity();
$act->verb = ActivityVerb::FAVORITE;
$act->id = TagURI::mint('favor:%d:%d:%s',
$profile->id,
$notice->id,
common_date_iso8601($this->modified));
$act->time = strtotime($this->modified);
$act->title = _("Favor");
$act->content = sprintf(_("%s marked notice %s as a favorite."),
$profile->getBestName(),
$notice->uri);
$act->actor = ActivityObject::fromProfile($profile);
$act->objects[] = ActivityObject::fromNotice($notice);
return $act;
}
} }

View File

@ -65,4 +65,54 @@ class Group_member extends Memcached_DataObject
return true; return true;
} }
function getMember()
{
$member = Profile::staticGet('id', $this->profile_id);
if (empty($member)) {
throw new Exception("Profile ID {$this->profile_id} invalid.");
}
return $member;
}
function getGroup()
{
$group = User_group::staticGet('id', $this->group_id);
if (empty($group)) {
throw new Exception("Group ID {$this->group_id} invalid.");
}
return $group;
}
function asActivity()
{
$member = $this->getMember();
$group = $this->getGroup();
$act = new Activity();
$act->id = TagURI::mint('join:%d:%d:%s',
$member->id,
$group->id,
common_date_iso8601($this->created));
$act->actor = ActivityObject::fromProfile($member);
$act->verb = ActivityVerb::JOIN;
$act->objects[] = ActivityObject::fromGroup($group);
$act->time = strtotime($this->created);
$act->title = _("Join");
// TRANS: Success message for subscribe to group attempt through OStatus.
// TRANS: %1$s is the member name, %2$s is the subscribed group's name.
$act->content = sprintf(_('%1$s has joined group %2$s.'),
$member->getBestName(),
$group->getBestName());
return $act;
}
} }

View File

@ -753,8 +753,15 @@ class Notice extends Memcached_DataObject
} }
/** /**
* @param $groups array of Group *objects* * Pull up a full list of local recipients who will be getting
* @param $recipients array of profile *ids* * this notice in their inbox. Results will be cached, so don't
* change the input data wily-nilly!
*
* @param array $groups optional list of Group objects;
* if left empty, will be loaded from group_inbox records
* @param array $recipient optional list of reply profile ids
* if left empty, will be loaded from reply records
* @return array associating recipient user IDs with an inbox source constant
*/ */
function whoGets($groups=null, $recipients=null) function whoGets($groups=null, $recipients=null)
{ {
@ -787,27 +794,27 @@ class Notice extends Memcached_DataObject
$ni[$id] = NOTICE_INBOX_SOURCE_SUB; $ni[$id] = NOTICE_INBOX_SOURCE_SUB;
} }
$profile = $this->getProfile();
foreach ($groups as $group) { foreach ($groups as $group) {
$users = $group->getUserMembers(); $users = $group->getUserMembers();
foreach ($users as $id) { foreach ($users as $id) {
if (!array_key_exists($id, $ni)) { if (!array_key_exists($id, $ni)) {
$user = User::staticGet('id', $id); $ni[$id] = NOTICE_INBOX_SOURCE_GROUP;
if (!$user->hasBlocked($profile)) {
$ni[$id] = NOTICE_INBOX_SOURCE_GROUP;
}
} }
} }
} }
foreach ($recipients as $recipient) { foreach ($recipients as $recipient) {
if (!array_key_exists($recipient, $ni)) { if (!array_key_exists($recipient, $ni)) {
$recipientUser = User::staticGet('id', $recipient); $ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY;
if (!empty($recipientUser)) { }
$ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY; }
}
// Exclude any deleted, non-local, or blocking recipients.
$profile = $this->getProfile();
foreach ($ni as $id => $source) {
$user = User::staticGet('id', $id);
if (empty($user) || $user->hasBlocked($profile)) {
unset($ni[$id]);
} }
} }
@ -1212,6 +1219,64 @@ class Notice extends Memcached_DataObject
return $groups; return $groups;
} }
function asActivity()
{
$profile = $this->getProfile();
$act = new Activity();
$act->actor = ActivityObject::fromProfile($profile);
$act->verb = ActivityVerb::POST;
$act->objects[] = ActivityObject::fromNotice($this);
$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);
$ctx = new ActivityContext();
if (!empty($this->reply_to)) {
$reply = Notice::staticGet('id', $this->reply_to);
if (!empty($reply)) {
$ctx->replyToID = $reply->uri;
$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;
}
$act->context = $ctx;
return $act;
}
// This has gotten way too long. Needs to be sliced up into functional bits // This has gotten way too long. Needs to be sliced up into functional bits
// or ideally exported to a utility class. // or ideally exported to a utility class.

View File

@ -235,4 +235,30 @@ class Subscription extends Memcached_DataObject
'subscribed' => $other->id)); 'subscribed' => $other->id));
return (empty($sub)) ? false : true; return (empty($sub)) ? false : true;
} }
function asActivity()
{
$subscriber = Profile::staticGet('id', $this->subscriber);
$subscribed = Profile::staticGet('id', $this->subscribed);
$act = new Activity();
$act->verb = ActivityVerb::FOLLOW;
$act->id = TagURI::mint('follow:%d:%d:%s',
$subscriber->id,
$subscribed->id,
common_date_iso8601($this->created));
$act->time = strtotime($this->created);
$act->title = _("Follow");
$act->content = sprintf(_("%s is now following %s."),
$subscriber->getBestName(),
$subscribed->getBestName());
$act->actor = ActivityObject::fromProfile($subscriber);
$act->objects[] = ActivityObject::fromProfile($subscribed);
return $act;
}
} }

View File

@ -255,6 +255,19 @@ class User extends Memcached_DataObject
$user->inboxed = 1; $user->inboxed = 1;
// Set default-on options here, otherwise they'll be disabled
// initially for sites using caching, since the initial encache
// doesn't know about the defaults in the database.
$user->emailnotifysub = 1;
$user->emailnotifyfav = 1;
$user->emailnotifynudge = 1;
$user->emailnotifymsg = 1;
$user->emailnotifyattn = 1;
$user->emailmicroid = 1;
$user->emailpost = 1;
$user->jabbermicroid = 1;
$user->viewdesigns = 1;
$user->created = common_sql_now(); $user->created = common_sql_now();
if (Event::handle('StartUserRegister', array(&$user, &$profile))) { if (Event::handle('StartUserRegister', array(&$user, &$profile))) {
@ -269,7 +282,13 @@ class User extends Memcached_DataObject
} }
$user->id = $id; $user->id = $id;
$user->uri = common_user_uri($user);
if (!empty($uri)) {
$user->uri = $uri;
} else {
$user->uri = common_user_uri($user);
}
if (!empty($password)) { // may not have a password for OpenID users if (!empty($password)) { // may not have a password for OpenID users
$user->password = common_munge_password($password, $id); $user->password = common_munge_password($password, $id);
} }
@ -552,6 +571,9 @@ class User extends Memcached_DataObject
if (Subscription::exists($other, $self)) { if (Subscription::exists($other, $self)) {
Subscription::cancel($other, $self); Subscription::cancel($other, $self);
} }
if (Subscription::exists($self, $other)) {
Subscription::cancel($self, $other);
}
$block->query('COMMIT'); $block->query('COMMIT');

View File

@ -52,6 +52,10 @@ VALUES
('socialoomphBfD4pMqz31', 'SocialOomph', 'http://www.socialoomph.com/', now()), ('socialoomphBfD4pMqz31', 'SocialOomph', 'http://www.socialoomph.com/', now()),
('spaz','Spaz','http://funkatron.com/spaz', now()), ('spaz','Spaz','http://funkatron.com/spaz', now()),
('StatusNet Desktop', 'StatusNet Desktop', 'http://status.net/desktop', now()), ('StatusNet Desktop', 'StatusNet Desktop', 'http://status.net/desktop', now()),
('StatusNet Mobile', 'StatusNet Mobile', 'http://status.net/mobile', now()),
('StatusNet iPhone', 'iPhone', 'http://status.net/iphone', now()),
('StatusNet Android', 'Android', 'http://status.net/android', now()),
('StatusNet Blackberry', 'Blackberry', 'http://status.net/blackberry', now()),
('tarpipe','tarpipe','http://tarpipe.com/', now()), ('tarpipe','tarpipe','http://tarpipe.com/', now()),
('tjunar','Tjunar','http://nederflash.nl/boek/titels/tjunar-air', now()), ('tjunar','Tjunar','http://nederflash.nl/boek/titels/tjunar-air', now()),
('tr.im','tr.im','http://tr.im/', now()), ('tr.im','tr.im','http://tr.im/', now()),

View File

@ -840,6 +840,9 @@ class Action extends HTMLOutputter // lawsuit
$this->elementStart('dd', null); $this->elementStart('dd', null);
if (common_config('site', 'broughtby')) { if (common_config('site', 'broughtby')) {
// TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is set. // TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is set.
// TRANS: Text between [] is a link description, text between () is the link itself.
// TRANS: Make sure there is no whitespace between "]" and "(".
// TRANS: "%%site.broughtby%%" is the value of the variable site.broughtby
$instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%).'); $instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%).');
} else { } else {
// TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is not set. // TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is not set.
@ -847,6 +850,9 @@ class Action extends HTMLOutputter // lawsuit
} }
$instr .= ' '; $instr .= ' ';
// TRANS: Second sentence of the StatusNet site license. Mentions the StatusNet source code license. // TRANS: Second sentence of the StatusNet site license. Mentions the StatusNet source code license.
// TRANS: Make sure there is no whitespace between "]" and "(".
// TRANS: Text between [] is a link description, text between () is the link itself.
// TRANS: %s is the version of StatusNet that is being used.
$instr .= sprintf(_('It runs the [StatusNet](http://status.net/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), STATUSNET_VERSION); $instr .= sprintf(_('It runs the [StatusNet](http://status.net/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), STATUSNET_VERSION);
$output = common_markup_to_html($instr); $output = common_markup_to_html($instr);
$this->raw($output); $this->raw($output);
@ -893,7 +899,8 @@ class Action extends HTMLOutputter // lawsuit
'width' => '80', 'width' => '80',
'height' => '15')); 'height' => '15'));
$this->text(' '); $this->text(' ');
// TRANS: license message in footer. %1$s is the site name, %2$s is a link to the license URL, with a licence name set in configuration. // TRANS: license message in footer.
// TRANS: %1$s is the site name, %2$s is a link to the license URL, with a licence name set in configuration.
$notice = _('All %1$s content and data are available under the %2$s license.'); $notice = _('All %1$s content and data are available under the %2$s license.');
$link = "<a class=\"license\" rel=\"external license\" href=\"" . $link = "<a class=\"license\" rel=\"external license\" href=\"" .
htmlspecialchars(common_config('license', 'url')) . htmlspecialchars(common_config('license', 'url')) .
@ -1011,17 +1018,22 @@ class Action extends HTMLOutputter // lawsuit
} }
} }
$checked = false;
if ($etag) { if ($etag) {
$if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ? $if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ?
$_SERVER['HTTP_IF_NONE_MATCH'] : null; $_SERVER['HTTP_IF_NONE_MATCH'] : null;
if ($if_none_match && $this->_hasEtag($etag, $if_none_match)) { if ($if_none_match) {
header('HTTP/1.1 304 Not Modified'); // If this check fails, ignore the if-modified-since below.
// Better way to do this? $checked = true;
exit(0); if ($this->_hasEtag($etag, $if_none_match)) {
header('HTTP/1.1 304 Not Modified');
// Better way to do this?
exit(0);
}
} }
} }
if ($lm && array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) { if (!$checked && $lm && array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
$if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
$ims = strtotime($if_modified_since); $ims = strtotime($if_modified_since);
if ($lm <= $ims) { if ($lm <= $ims) {
@ -1304,6 +1316,7 @@ class Action extends HTMLOutputter // lawsuit
// CSRF protection // CSRF protection
$token = $this->trimmed('token'); $token = $this->trimmed('token');
if (empty($token) || $token != common_session_token()) { if (empty($token) || $token != common_session_token()) {
// TRANS: Client error text when there is a problem with the session token.
$this->clientError(_('There was a problem with your session token.')); $this->clientError(_('There was a problem with your session token.'));
} }
} }

View File

@ -319,7 +319,7 @@ class Activity
return null; return null;
} }
function asString($namespace=false) function asString($namespace=false, $author=true)
{ {
$xs = new XMLStringer(true); $xs = new XMLStringer(true);
@ -338,7 +338,7 @@ class Activity
$xs->element('id', null, $this->id); $xs->element('id', null, $this->id);
$xs->element('title', null, $this->title); $xs->element('title', null, $this->title);
$xs->element('published', null, common_date_iso8601($this->time)); $xs->element('published', null, self::iso8601Date($this->time));
$xs->element('content', array('type' => 'html'), $this->content); $xs->element('content', array('type' => 'html'), $this->content);
if (!empty($this->summary)) { if (!empty($this->summary)) {
@ -353,13 +353,15 @@ class Activity
// XXX: add context // XXX: add context
$xs->elementStart('author'); if ($author) {
$xs->element('uri', array(), $this->actor->id); $xs->elementStart('author');
if ($this->actor->title) { $xs->element('uri', array(), $this->actor->id);
$xs->element('name', array(), $this->actor->title); if ($this->actor->title) {
$xs->element('name', array(), $this->actor->title);
}
$xs->elementEnd('author');
$xs->raw($this->actor->asString('activity:actor'));
} }
$xs->elementEnd('author');
$xs->raw($this->actor->asString('activity:actor'));
$xs->element('activity:verb', null, $this->verb); $xs->element('activity:verb', null, $this->verb);
@ -386,5 +388,12 @@ class Activity
{ {
return ActivityUtils::child($element, $tag, $namespace); return ActivityUtils::child($element, $tag, $namespace);
} }
}
static function iso8601Date($tm)
{
$dateStr = date('d F Y H:i:s', $tm);
$d = new DateTime($dateStr, new DateTimeZone('UTC'));
$d->setTimezone(new DateTimeZone(common_timezone()));
return $d->format('c');
}
}

View File

@ -54,8 +54,12 @@ class ActivityContext
const MENTIONED = 'mentioned'; const MENTIONED = 'mentioned';
const CONVERSATION = 'ostatus:conversation'; const CONVERSATION = 'ostatus:conversation';
function __construct($element) function __construct($element = null)
{ {
if (empty($element)) {
return;
}
$replyToEl = ActivityUtils::child($element, self::INREPLYTO, self::THR); $replyToEl = ActivityUtils::child($element, self::INREPLYTO, self::THR);
if (!empty($replyToEl)) { if (!empty($replyToEl)) {
@ -73,7 +77,6 @@ class ActivityContext
$attention = array(); $attention = array();
for ($i = 0; $i < $links->length; $i++) { for ($i = 0; $i < $links->length; $i++) {
$link = $links->item($i); $link = $links->item($i);
$linkRel = $link->getAttribute(ActivityUtils::REL); $linkRel = $link->getAttribute(ActivityUtils::REL);

View File

@ -168,7 +168,6 @@ class ActivityObject
ActivityObject::MEDIA_DESCRIPTION, ActivityObject::MEDIA_DESCRIPTION,
Activity::MEDIA Activity::MEDIA
); );
} }
} }
@ -418,7 +417,6 @@ class ActivityObject
); );
foreach ($sizes as $size) { foreach ($sizes as $size) {
$alink = null; $alink = null;
$avatar = $profile->getAvatar($size); $avatar = $profile->getAvatar($size);

View File

@ -46,7 +46,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/ * @link http://status.net/
*/ */
class ActivityUtils class ActivityUtils
{ {
const ATOM = 'http://www.w3.org/2005/Atom'; const ATOM = 'http://www.w3.org/2005/Atom';
@ -66,7 +65,6 @@ class ActivityUtils
* *
* @return string related link, if any * @return string related link, if any
*/ */
static function getPermalink($element) static function getPermalink($element)
{ {
return self::getLink($element, 'alternate', 'text/html'); return self::getLink($element, 'alternate', 'text/html');
@ -79,7 +77,6 @@ class ActivityUtils
* *
* @return string related link, if any * @return string related link, if any
*/ */
static function getLink(DOMNode $element, $rel, $type=null) static function getLink(DOMNode $element, $rel, $type=null)
{ {
$els = $element->childNodes; $els = $element->childNodes;
@ -135,7 +132,6 @@ class ActivityUtils
* *
* @return DOMElement found element or null * @return DOMElement found element or null
*/ */
static function child(DOMNode $element, $tag, $namespace=self::ATOM) static function child(DOMNode $element, $tag, $namespace=self::ATOM)
{ {
$els = $element->childNodes; $els = $element->childNodes;
@ -160,7 +156,6 @@ class ActivityUtils
* *
* @return string content of the child * @return string content of the child
*/ */
static function childContent(DOMNode $element, $tag, $namespace=self::ATOM) static function childContent(DOMNode $element, $tag, $namespace=self::ATOM)
{ {
$el = self::child($element, $tag, $namespace); $el = self::child($element, $tag, $namespace);
@ -194,7 +189,6 @@ class ActivityUtils
* @todo handle embedded XML mime types * @todo handle embedded XML mime types
* @todo handle base64-encoded non-XML and non-text mime types * @todo handle base64-encoded non-XML and non-text mime types
*/ */
static function getContent($element) static function getContent($element)
{ {
return self::childHtmlContent($element, self::CONTENT, self::ATOM); return self::childHtmlContent($element, self::CONTENT, self::ATOM);
@ -205,6 +199,7 @@ class ActivityUtils
$src = $el->getAttribute(self::SRC); $src = $el->getAttribute(self::SRC);
if (!empty($src)) { if (!empty($src)) {
// TRANS: Client exception thrown when there is no source attribute.
throw new ClientException(_("Can't handle remote content yet.")); throw new ClientException(_("Can't handle remote content yet."));
} }
@ -241,10 +236,12 @@ class ActivityUtils
return trim($text); return trim($text);
} else if (in_array($type, array('text/xml', 'application/xml')) || } else if (in_array($type, array('text/xml', 'application/xml')) ||
preg_match('#(+|/)xml$#', $type)) { preg_match('#(+|/)xml$#', $type)) {
// TRANS: Client exception thrown when there embedded XML content is found that cannot be processed yet.
throw new ClientException(_("Can't handle embedded XML content yet.")); throw new ClientException(_("Can't handle embedded XML content yet."));
} else if (strncasecmp($type, 'text/', 5)) { } else if (strncasecmp($type, 'text/', 5)) {
return $el->textContent; return $el->textContent;
} else { } else {
// TRANS: Client exception thrown when base64 encoded content is found that cannot be processed yet.
throw new ClientException(_("Can't handle embedded Base64 content yet.")); throw new ClientException(_("Can't handle embedded Base64 content yet."));
} }
} }

View File

@ -42,7 +42,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/ * @link http://status.net/
*/ */
class ActivityVerb class ActivityVerb
{ {
const POST = 'http://activitystrea.ms/schema/1.0/post'; const POST = 'http://activitystrea.ms/schema/1.0/post';

View File

@ -45,7 +45,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* *
* @see Form * @see Form
*/ */
class AdminForm extends Form class AdminForm extends Form
{ {
/** /**
@ -59,7 +58,6 @@ class AdminForm extends Form
* *
* @return void * @return void
*/ */
function input($setting, $title, $instructions, $section='site') function input($setting, $title, $instructions, $section='site')
{ {
$this->out->input($setting, $title, $this->value($setting, $section), $instructions); $this->out->input($setting, $title, $this->value($setting, $section), $instructions);
@ -73,7 +71,6 @@ class AdminForm extends Form
* *
* @return string param value if posted, or current config value * @return string param value if posted, or current config value
*/ */
function value($setting, $main='site') function value($setting, $main='site')
{ {
$value = $this->out->trimmed($setting); $value = $this->out->trimmed($setting);

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* *
* @todo Find some commonalities with SettingsAction and combine * @todo Find some commonalities with SettingsAction and combine
*/ */
class AdminPanelAction extends Action class AdminPanelAction extends Action
{ {
var $success = true; var $success = true;
@ -61,7 +60,6 @@ class AdminPanelAction extends Action
* *
* @return boolean success flag * @return boolean success flag
*/ */
function prepare($args) function prepare($args)
{ {
parent::prepare($args); parent::prepare($args);
@ -124,7 +122,6 @@ class AdminPanelAction extends Action
* *
* @return void * @return void
*/ */
function handle($args) function handle($args)
{ {
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
@ -155,7 +152,6 @@ class AdminPanelAction extends Action
* @return void * @return void
* @see AdminPanelNav * @see AdminPanelNav
*/ */
function showLocalNav() function showLocalNav()
{ {
$nav = new AdminPanelNav($this); $nav = new AdminPanelNav($this);
@ -169,7 +165,6 @@ class AdminPanelAction extends Action
* *
* @return void. * @return void.
*/ */
function showContent() function showContent()
{ {
$this->showForm(); $this->showForm();
@ -199,7 +194,6 @@ class AdminPanelAction extends Action
* *
* @return void * @return void
*/ */
function showPageNotice() function showPageNotice()
{ {
if ($this->msg) { if ($this->msg) {
@ -222,7 +216,6 @@ class AdminPanelAction extends Action
* *
* @return void * @return void
*/ */
function showForm() function showForm()
{ {
// TRANS: Client error message. // TRANS: Client error message.
@ -239,7 +232,6 @@ class AdminPanelAction extends Action
* *
* @return void * @return void
*/ */
function getInstructions() function getInstructions()
{ {
return ''; return '';
@ -252,7 +244,6 @@ class AdminPanelAction extends Action
* *
* @return void * @return void
*/ */
function saveSettings() function saveSettings()
{ {
// TRANS: Client error message // TRANS: Client error message
@ -267,7 +258,6 @@ class AdminPanelAction extends Action
* *
* @return mixed $result false if something didn't work * @return mixed $result false if something didn't work
*/ */
function deleteSetting($section, $setting) function deleteSetting($section, $setting)
{ {
$config = new Config(); $config = new Config();
@ -314,7 +304,6 @@ class AdminPanelAction extends Action
* *
* @see Widget * @see Widget
*/ */
class AdminPanelNav extends Widget class AdminPanelNav extends Widget
{ {
var $action = null; var $action = null;
@ -324,7 +313,6 @@ class AdminPanelNav extends Widget
* *
* @param Action $action current action, used for output * @param Action $action current action, used for output
*/ */
function __construct($action=null) function __construct($action=null)
{ {
parent::__construct($action); parent::__construct($action);
@ -336,7 +324,6 @@ class AdminPanelNav extends Widget
* *
* @return void * @return void
*/ */
function show() function show()
{ {
$action_name = $this->action->trimmed('action'); $action_name = $this->action->trimmed('action');
@ -421,5 +408,4 @@ class AdminPanelNav extends Widget
} }
$this->action->elementEnd('ul'); $this->action->elementEnd('ul');
} }
} }

View File

@ -112,7 +112,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ApiAction extends Action class ApiAction extends Action
{ {
const READ_ONLY = 1; const READ_ONLY = 1;
@ -139,7 +138,6 @@ class ApiAction extends Action
* *
* @return boolean false if user doesn't exist * @return boolean false if user doesn't exist
*/ */
function prepare($args) function prepare($args)
{ {
StatusNet::setApi(true); // reduce exception reports to aid in debugging StatusNet::setApi(true); // reduce exception reports to aid in debugging
@ -172,7 +170,6 @@ class ApiAction extends Action
* *
* @return void * @return void
*/ */
function handle($args) function handle($args)
{ {
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
@ -862,7 +859,6 @@ class ApiAction extends Action
} }
$this->endDocument('atom'); $this->endDocument('atom');
} }
function showRssGroups($group, $title, $link, $subtitle) function showRssGroups($group, $title, $link, $subtitle)
@ -1015,7 +1011,6 @@ class ApiAction extends Action
function showAtomGroups($group, $title, $id, $link, $subtitle=null, $selfuri=null) function showAtomGroups($group, $title, $id, $link, $subtitle=null, $selfuri=null)
{ {
$this->initDocument('atom'); $this->initDocument('atom');
$this->element('title', null, common_xml_safe_str($title)); $this->element('title', null, common_xml_safe_str($title));
@ -1046,7 +1041,6 @@ class ApiAction extends Action
function showJsonTimeline($notice) function showJsonTimeline($notice)
{ {
$this->initDocument('json'); $this->initDocument('json');
$statuses = array(); $statuses = array();
@ -1072,7 +1066,6 @@ class ApiAction extends Action
function showJsonGroups($group) function showJsonGroups($group)
{ {
$this->initDocument('json'); $this->initDocument('json');
$groups = array(); $groups = array();
@ -1118,7 +1111,6 @@ class ApiAction extends Action
function showTwitterXmlUsers($user) function showTwitterXmlUsers($user)
{ {
$this->initDocument('xml'); $this->initDocument('xml');
$this->elementStart('users', array('type' => 'array', $this->elementStart('users', array('type' => 'array',
'xmlns:statusnet' => 'http://status.net/schema/api/1/')); 'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
@ -1141,7 +1133,6 @@ class ApiAction extends Action
function showJsonUsers($user) function showJsonUsers($user)
{ {
$this->initDocument('json'); $this->initDocument('json');
$users = array(); $users = array();
@ -1226,7 +1217,6 @@ class ApiAction extends Action
$this->endXML(); $this->endXML();
break; break;
case 'json': case 'json':
// Check for JSONP callback // Check for JSONP callback
if (isset($this->callback)) { if (isset($this->callback)) {
print ')'; print ')';
@ -1483,7 +1473,6 @@ class ApiAction extends Action
*/ */
function arg($key, $def=null) function arg($key, $def=null)
{ {
// XXX: Do even more input validation/scrubbing? // XXX: Do even more input validation/scrubbing?
if (array_key_exists($key, $this->args)) { if (array_key_exists($key, $this->args)) {
@ -1550,5 +1539,4 @@ class ApiAction extends Action
return $uri; return $uri;
} }
} }

View File

@ -68,7 +68,6 @@ require_once INSTALLDIR . '/lib/apioauth.php';
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ApiAuthAction extends ApiAction class ApiAuthAction extends ApiAction
{ {
var $auth_user_nickname = null; var $auth_user_nickname = null;
@ -83,7 +82,6 @@ class ApiAuthAction extends ApiAction
* @return boolean success flag * @return boolean success flag
* *
*/ */
function prepare($args) function prepare($args)
{ {
parent::prepare($args); parent::prepare($args);
@ -126,7 +124,6 @@ class ApiAuthAction extends ApiAction
* *
* @return mixed the OAuthRequest or false * @return mixed the OAuthRequest or false
*/ */
function getOAuthRequest() function getOAuthRequest()
{ {
ApiOauthAction::cleanRequest(); ApiOauthAction::cleanRequest();
@ -154,7 +151,6 @@ class ApiAuthAction extends ApiAction
* *
* @return nothing * @return nothing
*/ */
function checkOAuthRequest($request) function checkOAuthRequest($request)
{ {
$datastore = new ApiStatusNetOAuthDataStore(); $datastore = new ApiStatusNetOAuthDataStore();
@ -164,7 +160,6 @@ class ApiAuthAction extends ApiAction
$server->add_signature_method($hmac_method); $server->add_signature_method($hmac_method);
try { try {
$server->verify_request($request); $server->verify_request($request);
$consumer = $request->get_parameter('oauth_consumer_key'); $consumer = $request->get_parameter('oauth_consumer_key');
@ -176,7 +171,8 @@ class ApiAuthAction extends ApiAction
common_log(LOG_WARNING, common_log(LOG_WARNING,
'Couldn\'t find the OAuth app for consumer key: ' . 'Couldn\'t find the OAuth app for consumer key: ' .
$consumer); $consumer);
throw new OAuthException('No application for that consumer key.'); // TRANS: OAuth exception thrown when no application is found for a given consumer key.
throw new OAuthException(_('No application for that consumer key.'));
} }
// set the source attr // set the source attr
@ -186,19 +182,15 @@ class ApiAuthAction extends ApiAction
$appUser = Oauth_application_user::staticGet('token', $access_token); $appUser = Oauth_application_user::staticGet('token', $access_token);
if (!empty($appUser)) { if (!empty($appUser)) {
// If access_type == 0 we have either a request token // If access_type == 0 we have either a request token
// or a bad / revoked access token // or a bad / revoked access token
if ($appUser->access_type != 0) { if ($appUser->access_type != 0) {
// Set the access level for the api call // Set the access level for the api call
$this->access = ($appUser->access_type & Oauth_application::$writeAccess) $this->access = ($appUser->access_type & Oauth_application::$writeAccess)
? self::READ_WRITE : self::READ_ONLY; ? self::READ_WRITE : self::READ_ONLY;
// Set the auth user // Set the auth user
if (Event::handle('StartSetApiUser', array(&$user))) { if (Event::handle('StartSetApiUser', array(&$user))) {
$this->auth_user = User::staticGet('id', $appUser->profile_id); $this->auth_user = User::staticGet('id', $appUser->profile_id);
Event::handle('EndSetApiUser', array($user)); Event::handle('EndSetApiUser', array($user));
@ -216,13 +208,13 @@ class ApiAuthAction extends ApiAction
'read-write' : 'read-only' 'read-write' : 'read-only'
)); ));
} else { } else {
throw new OAuthException('Bad access token.'); // TRANS: OAuth exception given when an incorrect access token was given for a user.
throw new OAuthException(_('Bad access token.'));
} }
} else { } else {
// Also should not happen // Also should not happen
// TRANS: OAuth exception given when no user was found for a given token (no token was found).
throw new OAuthException('No user for that token.'); throw new OAuthException(_('No user for that token.'));
} }
} catch (OAuthException $e) { } catch (OAuthException $e) {
@ -237,7 +229,6 @@ class ApiAuthAction extends ApiAction
* *
* @return boolean true * @return boolean true
*/ */
function requiresAuth() function requiresAuth()
{ {
return true; return true;
@ -249,7 +240,6 @@ class ApiAuthAction extends ApiAction
* *
* @return boolean true or false * @return boolean true or false
*/ */
function checkBasicAuthUser($required = true) function checkBasicAuthUser($required = true)
{ {
$this->basicAuthProcessHeader(); $this->basicAuthProcessHeader();
@ -264,8 +254,8 @@ class ApiAuthAction extends ApiAction
header('WWW-Authenticate: Basic realm="' . $realm . '"'); header('WWW-Authenticate: Basic realm="' . $realm . '"');
// show error if the user clicks 'cancel' // show error if the user clicks 'cancel'
// TRANS: Client error thrown when authentication fails becaus a user clicked "Cancel".
$this->clientError("Could not authenticate you.", 401, $this->format); $this->clientError(_("Could not authenticate you."), 401, $this->format);
exit; exit;
} else { } else {
@ -283,13 +273,11 @@ class ApiAuthAction extends ApiAction
} }
// By default, basic auth users have rw access // By default, basic auth users have rw access
$this->access = self::READ_WRITE; $this->access = self::READ_WRITE;
if (empty($this->auth_user) && ($required || isset($_SERVER['PHP_AUTH_USER']))) { if (empty($this->auth_user) && ($required || isset($_SERVER['PHP_AUTH_USER']))) {
// basic authentication failed // basic authentication failed
list($proxy, $ip) = common_client_ip(); list($proxy, $ip) = common_client_ip();
$msg = sprintf( 'Failed API auth attempt, nickname = %1$s, ' . $msg = sprintf( 'Failed API auth attempt, nickname = %1$s, ' .
@ -298,7 +286,8 @@ class ApiAuthAction extends ApiAction
$proxy, $proxy,
$ip); $ip);
common_log(LOG_WARNING, $msg); common_log(LOG_WARNING, $msg);
$this->clientError("Could not authenticate you.", 401, $this->format); // TRANS: Client error thrown when authentication fails.
$this->clientError(_("Could not authenticate you."), 401, $this->format);
exit; exit;
} }
} }
@ -310,7 +299,6 @@ class ApiAuthAction extends ApiAction
* *
* @return void * @return void
*/ */
function basicAuthProcessHeader() function basicAuthProcessHeader()
{ {
$authHeaders = array('AUTHORIZATION', $authHeaders = array('AUTHORIZATION',
@ -332,7 +320,6 @@ class ApiAuthAction extends ApiAction
// Decode the HTTP_AUTHORIZATION header on php-cgi server self // Decode the HTTP_AUTHORIZATION header on php-cgi server self
// on fcgid server the header name is AUTHORIZATION // on fcgid server the header name is AUTHORIZATION
$auth_hash = base64_decode(substr($authorization_header, 6)); $auth_hash = base64_decode(substr($authorization_header, 6));
list($this->auth_user_nickname, list($this->auth_user_nickname,
$this->auth_user_password) = explode(':', $auth_hash); $this->auth_user_password) = explode(':', $auth_hash);

View File

@ -30,7 +30,7 @@
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author mEDI <medi@milaro.net> * @author mEDI <medi@milaro.net>
* @author Sarven Capadisli <csarven@status.net> * @author Sarven Capadisli <csarven@status.net>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc. * @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
@ -60,7 +60,6 @@ require_once INSTALLDIR.'/lib/apiauth.php';
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ApiBareAuthAction extends ApiAuthAction class ApiBareAuthAction extends ApiAuthAction
{ {
@ -72,7 +71,6 @@ class ApiBareAuthAction extends ApiAuthAction
* @return boolean success flag * @return boolean success flag
* *
*/ */
function prepare($args) function prepare($args)
{ {
parent::prepare($args); parent::prepare($args);
@ -84,18 +82,15 @@ class ApiBareAuthAction extends ApiAuthAction
* *
* @return boolean true or false * @return boolean true or false
*/ */
function requiresAuth() function requiresAuth()
{ {
// If the site is "private", all API methods except statusnet/config // If the site is "private", all API methods except statusnet/config
// need authentication // need authentication
if (common_config('site', 'private')) { if (common_config('site', 'private')) {
return true; return true;
} }
// check whether a user has been specified somehow // check whether a user has been specified somehow
$id = $this->arg('id'); $id = $this->arg('id');
$user_id = $this->arg('user_id'); $user_id = $this->arg('user_id');
$screen_name = $this->arg('screen_name'); $screen_name = $this->arg('screen_name');
@ -106,5 +101,4 @@ class ApiBareAuthAction extends ApiAuthAction
return false; return false;
} }
} }

View File

@ -44,7 +44,6 @@ require_once INSTALLDIR . '/lib/apioauthstore.php';
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ApiOauthAction extends Action class ApiOauthAction extends Action
{ {
/** /**
@ -52,7 +51,6 @@ class ApiOauthAction extends Action
* *
* @return boolean false * @return boolean false
*/ */
function isReadOnly($args) function isReadOnly($args)
{ {
return false; return false;
@ -73,7 +71,6 @@ class ApiOauthAction extends Action
* *
* @return void * @return void
*/ */
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
@ -83,7 +80,6 @@ class ApiOauthAction extends Action
static function cleanRequest() static function cleanRequest()
{ {
// kill evil effects of magical slashing // kill evil effects of magical slashing
if (get_magic_quotes_gpc() == 1) { if (get_magic_quotes_gpc() == 1) {
$_POST = array_map('stripslashes', $_POST); $_POST = array_map('stripslashes', $_POST);
$_GET = array_map('stripslashes', $_GET); $_GET = array_map('stripslashes', $_GET);
@ -93,7 +89,6 @@ class ApiOauthAction extends Action
// XXX: should we strip anything else? Or alternatively // XXX: should we strip anything else? Or alternatively
// only allow a known list of params? // only allow a known list of params?
unset($_GET['p']); unset($_GET['p']);
unset($_POST['p']); unset($_POST['p']);
} }
@ -118,5 +113,4 @@ class ApiOauthAction extends Action
return ($url . '&' . $k . '=' . $v); return ($url . '&' . $k . '=' . $v);
} }
} }
} }

View File

@ -23,7 +23,6 @@ require_once INSTALLDIR . '/lib/oauthstore.php';
class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
{ {
function lookup_consumer($consumer_key) function lookup_consumer($consumer_key)
{ {
$con = Consumer::staticGet('consumer_key', $consumer_key); $con = Consumer::staticGet('consumer_key', $consumer_key);
@ -39,7 +38,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
function getAppByRequestToken($token_key) function getAppByRequestToken($token_key)
{ {
// Look up the full req tokenx // Look up the full req tokenx
$req_token = $this->lookup_token(null, $req_token = $this->lookup_token(null,
'request', 'request',
$token_key); $token_key);
@ -50,7 +48,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
} }
// Look up the full Token // Look up the full Token
$token = new Token(); $token = new Token();
$token->tok = $req_token->key; $token->tok = $req_token->key;
$result = $token->find(true); $result = $token->find(true);
@ -150,7 +147,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
} }
// Okay, good // Okay, good
return new OAuthToken($at->tok, $at->secret); return new OAuthToken($at->tok, $at->secret);
} }
@ -172,19 +168,18 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
* *
* @return void * @return void
*/ */
public function revoke_token($token_key, $type = 0) { public function revoke_token($token_key, $type = 0) {
$rt = new Token(); $rt = new Token();
$rt->tok = $token_key; $rt->tok = $token_key;
$rt->type = $type; $rt->type = $type;
$rt->state = 0; $rt->state = 0;
if (!$rt->find(true)) { if (!$rt->find(true)) {
throw new Exception('Tried to revoke unknown token'); // TRANS: Exception thrown when an attempt is made to revoke an unknown token.
throw new Exception(_('Tried to revoke unknown token.'));
} }
if (!$rt->delete()) { if (!$rt->delete()) {
throw new Exception('Failed to delete revoked token'); // TRANS: Exception thrown when an attempt is made to remove a revoked token.
throw new Exception(_('Failed to delete revoked token.'));
} }
} }
} }

View File

@ -29,7 +29,7 @@
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @author mEDI <medi@milaro.net> * @author mEDI <medi@milaro.net>
* @author Sarven Capadisli <csarven@status.net> * @author Sarven Capadisli <csarven@status.net>
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc. * @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
@ -58,26 +58,21 @@ require_once INSTALLDIR.'/lib/apiauth.php';
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ApiPrivateAuthAction extends ApiAuthAction class ApiPrivateAuthAction extends ApiAuthAction
{ {
/** /**
* Does this API resource require authentication? * Does this API resource require authentication?
* *
* @return boolean true or false * @return boolean true or false
*/ */
function requiresAuth() function requiresAuth()
{ {
// If the site is "private", all API methods except statusnet/config // If the site is "private", all API methods except statusnet/config
// need authentication // need authentication
if (common_config('site', 'private')) { if (common_config('site', 'private')) {
return true; return true;
} }
return false; return false;
} }
} }

View File

@ -43,13 +43,11 @@ require_once INSTALLDIR . '/lib/form.php';
* @link http://status.net/ * @link http://status.net/
* *
*/ */
class ApplicationEditForm extends Form class ApplicationEditForm extends Form
{ {
/** /**
* group for user to join * group for user to join
*/ */
var $application = null; var $application = null;
/** /**
@ -58,7 +56,6 @@ class ApplicationEditForm extends Form
* @param Action $out output channel * @param Action $out output channel
* @param User_group $group group to join * @param User_group $group group to join
*/ */
function __construct($out=null, $application=null) function __construct($out=null, $application=null)
{ {
parent::__construct($out); parent::__construct($out);
@ -71,7 +68,6 @@ class ApplicationEditForm extends Form
* *
* @return string ID of the form * @return string ID of the form
*/ */
function id() function id()
{ {
if ($this->application) { if ($this->application) {
@ -89,7 +85,6 @@ class ApplicationEditForm extends Form
* *
* @return string the method to use for submitting * @return string the method to use for submitting
*/ */
function method() function method()
{ {
$this->enctype = 'multipart/form-data'; $this->enctype = 'multipart/form-data';
@ -101,7 +96,6 @@ class ApplicationEditForm extends Form
* *
* @return string of the form class * @return string of the form class
*/ */
function formClass() function formClass()
{ {
return 'form_settings'; return 'form_settings';
@ -112,7 +106,6 @@ class ApplicationEditForm extends Form
* *
* @return string URL of the action * @return string URL of the action
*/ */
function action() function action()
{ {
$cur = common_current_user(); $cur = common_current_user();
@ -130,7 +123,6 @@ class ApplicationEditForm extends Form
* *
* @return void * @return void
*/ */
function formLegend() function formLegend()
{ {
// TRANS: Form legend. // TRANS: Form legend.
@ -142,7 +134,6 @@ class ApplicationEditForm extends Form
* *
* @return void * @return void
*/ */
function formData() function formData()
{ {
if ($this->application) { if ($this->application) {
@ -265,8 +256,9 @@ class ApplicationEditForm extends Form
// Default to Browser // Default to Browser
if ($this->application->type == Oauth_application::$browser if (empty($this->application)
|| empty($this->application->type)) { || empty($this->application->type)
|| $this->application->type == Oauth_application::$browser) {
$attrs['checked'] = 'checked'; $attrs['checked'] = 'checked';
} }
@ -283,7 +275,7 @@ class ApplicationEditForm extends Form
'class' => 'radio', 'class' => 'radio',
'value' => Oauth_application::$desktop); 'value' => Oauth_application::$desktop);
if ($this->application->type == Oauth_application::$desktop) { if (!empty($this->application) && $this->application->type == Oauth_application::$desktop) {
$attrs['checked'] = 'checked'; $attrs['checked'] = 'checked';
} }
@ -307,8 +299,9 @@ class ApplicationEditForm extends Form
// default to read-only access // default to read-only access
if ($this->application->access_type & Oauth_application::$readAccess if (empty($this->application)
|| empty($this->application->access_type)) { || empty($this->application->access_type)
|| $this->application->access_type & Oauth_application::$readAccess) {
$attrs['checked'] = 'checked'; $attrs['checked'] = 'checked';
} }
@ -325,7 +318,8 @@ class ApplicationEditForm extends Form
'class' => 'radio', 'class' => 'radio',
'value' => 'rw'); 'value' => 'rw');
if ($this->application->access_type & Oauth_application::$readAccess if (!empty($this->application)
&& $this->application->access_type & Oauth_application::$readAccess
&& $this->application->access_type & Oauth_application::$writeAccess && $this->application->access_type & Oauth_application::$writeAccess
) { ) {
$attrs['checked'] = 'checked'; $attrs['checked'] = 'checked';
@ -350,16 +344,15 @@ class ApplicationEditForm extends Form
* *
* @return void * @return void
*/ */
function formActions() function formActions()
{ {
// TRANS: Button label // TRANS: Button label in the "Edit application" form.
$this->out->submit('cancel', _m('BUTTON','Cancel'), 'submit form_action-primary', $this->out->submit('cancel', _m('BUTTON','Cancel'), 'submit form_action-primary',
// TRANS: Submit button title // TRANS: Submit button title.
'cancel', _('Cancel')); 'cancel', _('Cancel'));
// TRANS: Button label // TRANS: Button label in the "Edit application" form.
$this->out->submit('save', _m('BUTTON','Save'), 'submit form_action-secondary', $this->out->submit('save', _m('BUTTON','Save'), 'submit form_action-secondary',
// TRANS: Submit button title // TRANS: Submit button title.
'save', _('Save')); 'save', _('Save'));
} }
} }

View File

@ -45,7 +45,6 @@ define('APPS_PER_PAGE', 20);
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ApplicationList extends Widget class ApplicationList extends Widget
{ {
/** Current application, application query */ /** Current application, application query */
@ -164,10 +163,8 @@ class ApplicationList extends Widget
} }
/* Override this in subclasses. */ /* Override this in subclasses. */
function showOwnerControls() function showOwnerControls()
{ {
return; return;
} }
} }

View File

@ -44,7 +44,7 @@ if (!defined('STATUSNET'))
*/ */
class AtomUserNoticeFeed extends AtomNoticeFeed class AtomUserNoticeFeed extends AtomNoticeFeed
{ {
private $user; protected $user;
/** /**
* Constructor * Constructor
@ -90,7 +90,7 @@ class AtomUserNoticeFeed extends AtomNoticeFeed
array('nickname' => $user->nickname) array('nickname' => $user->nickname)
) )
); );
$self = common_local_url('ApiTimelineUser', $self = common_local_url('ApiTimelineUser',
array('id' => $user->id, array('id' => $user->id,
'format' => 'atom')); 'format' => 'atom'));

View File

@ -64,6 +64,7 @@ class AttachmentNoticeSection extends NoticeSection
function title() function title()
{ {
// TRANS: Title.
return _('Notices where this attachment appears'); return _('Notices where this attachment appears');
} }

View File

@ -45,6 +45,7 @@ class AttachmentTagCloudSection extends TagCloudSection
{ {
function title() function title()
{ {
// TRANS: Title.
return _('Tags for this attachment'); return _('Tags for this attachment');
} }

View File

@ -66,6 +66,7 @@ class BlockForm extends ProfileActionForm
function title() function title()
{ {
// TRANS: Title for the form to block a user.
return _('Block'); return _('Block');
} }
@ -77,6 +78,7 @@ class BlockForm extends ProfileActionForm
function description() function description()
{ {
// TRANS: Description of the form to block a user.
return _('Block this user'); return _('Block this user');
} }
} }

View File

@ -831,7 +831,7 @@ class SubscriptionsCommand extends Command
$out=_('You are not subscribed to anyone.'); $out=_('You are not subscribed to anyone.');
}else{ }else{
// TRANS: Text shown after requesting other users a user is subscribed to. // TRANS: Text shown after requesting other users a user is subscribed to.
// TRANS: This message support plural forms. This message is followed by a // TRANS: This message supports plural forms. This message is followed by a
// TRANS: hard coded space and a comma separated list of subscribed users. // TRANS: hard coded space and a comma separated list of subscribed users.
$out = ngettext('You are subscribed to this person:', $out = ngettext('You are subscribed to this person:',
'You are subscribed to these people:', 'You are subscribed to these people:',
@ -858,7 +858,7 @@ class SubscribersCommand extends Command
$out=_('No one is subscribed to you.'); $out=_('No one is subscribed to you.');
}else{ }else{
// TRANS: Text shown after requesting other users that are subscribed to a user (followers). // TRANS: Text shown after requesting other users that are subscribed to a user (followers).
// TRANS: This message support plural forms. This message is followed by a // TRANS: This message supports plural forms. This message is followed by a
// TRANS: hard coded space and a comma separated list of subscribing users. // TRANS: hard coded space and a comma separated list of subscribing users.
$out = ngettext('This person is subscribed to you:', $out = ngettext('This person is subscribed to you:',
'These people are subscribed to you:', 'These people are subscribed to you:',
@ -885,7 +885,7 @@ class GroupsCommand extends Command
$out=_('You are not a member of any groups.'); $out=_('You are not a member of any groups.');
}else{ }else{
// TRANS: Text shown after requesting groups a user is subscribed to. // TRANS: Text shown after requesting groups a user is subscribed to.
// TRANS: This message support plural forms. This message is followed by a // TRANS: This message supports plural forms. This message is followed by a
// TRANS: hard coded space and a comma separated list of subscribed groups. // TRANS: hard coded space and a comma separated list of subscribed groups.
$out = ngettext('You are a member of this group:', $out = ngettext('You are a member of this group:',
'You are a member of these groups:', 'You are a member of these groups:',
@ -900,8 +900,8 @@ class HelpCommand extends Command
{ {
function handle($channel) function handle($channel)
{ {
// TRANS: Help text for commands.
$channel->output($this->user, $channel->output($this->user,
// TRANS: Help text for commands. Do not translate the command names themselves; they are fixed strings.
_("Commands:\n". _("Commands:\n".
"on - turn on notifications\n". "on - turn on notifications\n".
"off - turn off notifications\n". "off - turn off notifications\n".

View File

@ -100,7 +100,7 @@ class DBQueueManager extends QueueManager
} }
} else { } else {
$this->_log(LOG_INFO, "[$queue] Got empty/deleted item, discarding"); $this->_log(LOG_INFO, "[$queue] Got empty/deleted item, discarding");
$this->_fail($qi); $this->_done($qi);
} }
return true; return true;
} }

View File

@ -82,14 +82,20 @@ class GroupNav extends Widget
if (Event::handle('StartGroupGroupNav', array($this))) { if (Event::handle('StartGroupGroupNav', array($this))) {
$this->out->menuItem(common_local_url('showgroup', array('nickname' => $this->out->menuItem(common_local_url('showgroup', array('nickname' =>
$nickname)), $nickname)),
_('Group'), // TRANS: Menu item in the group navigation page.
sprintf(_('%s group'), $nickname), _m('MENU','Group'),
// TRANS: Tooltip for menu item in the group navigation page.
// TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','%s group'), $nickname),
$action_name == 'showgroup', $action_name == 'showgroup',
'nav_group_group'); 'nav_group_group');
$this->out->menuItem(common_local_url('groupmembers', array('nickname' => $this->out->menuItem(common_local_url('groupmembers', array('nickname' =>
$nickname)), $nickname)),
_('Members'), // TRANS: Menu item in the group navigation page.
sprintf(_('%s group members'), $nickname), _m('MENU','Members'),
// TRANS: Tooltip for menu item in the group navigation page.
// TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','%s group members'), $nickname),
$action_name == 'groupmembers', $action_name == 'groupmembers',
'nav_group_members'); 'nav_group_members');
@ -98,26 +104,38 @@ class GroupNav extends Widget
if ($cur && $cur->isAdmin($this->group)) { if ($cur && $cur->isAdmin($this->group)) {
$this->out->menuItem(common_local_url('blockedfromgroup', array('nickname' => $this->out->menuItem(common_local_url('blockedfromgroup', array('nickname' =>
$nickname)), $nickname)),
_('Blocked'), // TRANS: Menu item in the group navigation page. Only shown for group administrators.
sprintf(_('%s blocked users'), $nickname), _m('MENU','Blocked'),
// TRANS: Tooltip for menu item in the group navigation page. Only shown for group administrators.
// TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','%s blocked users'), $nickname),
$action_name == 'blockedfromgroup', $action_name == 'blockedfromgroup',
'nav_group_blocked'); 'nav_group_blocked');
$this->out->menuItem(common_local_url('editgroup', array('nickname' => $this->out->menuItem(common_local_url('editgroup', array('nickname' =>
$nickname)), $nickname)),
_('Admin'), // TRANS: Menu item in the group navigation page. Only shown for group administrators.
sprintf(_('Edit %s group properties'), $nickname), _m('MENU','Admin'),
// TRANS: Tooltip for menu item in the group navigation page. Only shown for group administrators.
// TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','Edit %s group properties'), $nickname),
$action_name == 'editgroup', $action_name == 'editgroup',
'nav_group_admin'); 'nav_group_admin');
$this->out->menuItem(common_local_url('grouplogo', array('nickname' => $this->out->menuItem(common_local_url('grouplogo', array('nickname' =>
$nickname)), $nickname)),
_('Logo'), // TRANS: Menu item in the group navigation page. Only shown for group administrators.
sprintf(_('Add or edit %s logo'), $nickname), _m('MENU','Logo'),
// TRANS: Tooltip for menu item in the group navigation page. Only shown for group administrators.
// TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','Add or edit %s logo'), $nickname),
$action_name == 'grouplogo', $action_name == 'grouplogo',
'nav_group_logo'); 'nav_group_logo');
$this->out->menuItem(common_local_url('groupdesignsettings', array('nickname' => $this->out->menuItem(common_local_url('groupdesignsettings', array('nickname' =>
$nickname)), $nickname)),
_('Design'), // TRANS: Menu item in the group navigation page. Only shown for group administrators.
sprintf(_('Add or edit %s design'), $nickname), _m('MENU','Design'),
// TRANS: Tooltip for menu item in the group navigation page. Only shown for group administrators.
// TRANS: %s is the nickname of the group.
sprintf(_m('TOOLTIP','Add or edit %s design'), $nickname),
$action_name == 'groupdesignsettings', $action_name == 'groupdesignsettings',
'nav_group_design'); 'nav_group_design');
} }

View File

@ -325,6 +325,7 @@ class HTMLOutputter extends XMLOutputter
* @param string $label text of the button * @param string $label text of the button
* @param string $cls class of the button, default 'submit' * @param string $cls class of the button, default 'submit'
* @param string $name name, if different than ID * @param string $name name, if different than ID
* @param string $title title text for the submit button
* *
* @return void * @return void
* *

View File

@ -95,6 +95,7 @@ class MediaFile
if (!$file_id) { if (!$file_id) {
common_log_db_error($file, "INSERT", __FILE__); common_log_db_error($file, "INSERT", __FILE__);
// TRANS: Client exception thrown when a database error was thrown during a file upload operation.
throw new ClientException(_('There was a database error while saving your file. Please try again.')); throw new ClientException(_('There was a database error while saving your file. Please try again.'));
} }
@ -120,6 +121,7 @@ class MediaFile
if (!$result) { if (!$result) {
common_log_db_error($file_redir, "INSERT", __FILE__); common_log_db_error($file_redir, "INSERT", __FILE__);
// TRANS: Client exception thrown when a database error was thrown during a file upload operation.
throw new ClientException(_('There was a database error while saving your file. Please try again.')); throw new ClientException(_('There was a database error while saving your file. Please try again.'));
} }
} }
@ -139,16 +141,19 @@ class MediaFile
case UPLOAD_ERR_OK: // success, jump out case UPLOAD_ERR_OK: // success, jump out
break; break;
case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_INI_SIZE:
// TRANS: Client exception thrown when an uploaded file is larger than set in php.ini.
throw new ClientException(_('The uploaded file exceeds the ' . throw new ClientException(_('The uploaded file exceeds the ' .
'upload_max_filesize directive in php.ini.')); 'upload_max_filesize directive in php.ini.'));
return; return;
case UPLOAD_ERR_FORM_SIZE: case UPLOAD_ERR_FORM_SIZE:
throw new ClientException( throw new ClientException(
// TRANS: Client exception.
_('The uploaded file exceeds the MAX_FILE_SIZE directive' . _('The uploaded file exceeds the MAX_FILE_SIZE directive' .
' that was specified in the HTML form.')); ' that was specified in the HTML form.'));
return; return;
case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_PARTIAL:
@unlink($_FILES[$param]['tmp_name']); @unlink($_FILES[$param]['tmp_name']);
// TRANS: Client exception.
throw new ClientException(_('The uploaded file was only' . throw new ClientException(_('The uploaded file was only' .
' partially uploaded.')); ' partially uploaded.'));
return; return;
@ -156,17 +161,21 @@ class MediaFile
// No file; probably just a non-AJAX submission. // No file; probably just a non-AJAX submission.
return; return;
case UPLOAD_ERR_NO_TMP_DIR: case UPLOAD_ERR_NO_TMP_DIR:
// TRANS: Client exception thrown when a temporary folder is not present to store a file upload.
throw new ClientException(_('Missing a temporary folder.')); throw new ClientException(_('Missing a temporary folder.'));
return; return;
case UPLOAD_ERR_CANT_WRITE: case UPLOAD_ERR_CANT_WRITE:
// TRANS: Client exception thrown when writing to disk is not possible during a file upload operation.
throw new ClientException(_('Failed to write file to disk.')); throw new ClientException(_('Failed to write file to disk.'));
return; return;
case UPLOAD_ERR_EXTENSION: case UPLOAD_ERR_EXTENSION:
// TRANS: Client exception thrown when a file upload operation has been stopped by an extension.
throw new ClientException(_('File upload stopped by extension.')); throw new ClientException(_('File upload stopped by extension.'));
return; return;
default: default:
common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " . common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
$_FILES[$param]['error']); $_FILES[$param]['error']);
// TRANS: Client exception thrown when a file upload operation has failed with an unknown reason.
throw new ClientException(_('System error uploading file.')); throw new ClientException(_('System error uploading file.'));
return; return;
} }
@ -176,6 +185,7 @@ class MediaFile
// Should never actually get here // Should never actually get here
@unlink($_FILES[$param]['tmp_name']); @unlink($_FILES[$param]['tmp_name']);
// TRANS: Client exception thrown when a file upload operation would cause a user to exceed a set quota.
throw new ClientException(_('File exceeds user\'s quota.')); throw new ClientException(_('File exceeds user\'s quota.'));
return; return;
} }
@ -194,11 +204,15 @@ class MediaFile
$result = move_uploaded_file($_FILES[$param]['tmp_name'], $filepath); $result = move_uploaded_file($_FILES[$param]['tmp_name'], $filepath);
if (!$result) { if (!$result) {
// TRANS: Client exception thrown when a file upload operation fails because the file could
// TRANS: not be moved from the temporary folder to the permanent file location.
throw new ClientException(_('File could not be moved to destination directory.')); throw new ClientException(_('File could not be moved to destination directory.'));
return; return;
} }
} else { } else {
// TRANS: Client exception thrown when a file upload operation has been stopped because the MIME
// TRANS: type of the uploaded file could not be determined.
throw new ClientException(_('Could not determine file\'s MIME type.')); throw new ClientException(_('Could not determine file\'s MIME type.'));
return; return;
} }
@ -214,6 +228,7 @@ class MediaFile
// Should never actually get here // Should never actually get here
// TRANS: Client exception thrown when a file upload operation would cause a user to exceed a set quota.
throw new ClientException(_('File exceeds user\'s quota.')); throw new ClientException(_('File exceeds user\'s quota.'));
return; return;
} }
@ -231,10 +246,14 @@ class MediaFile
$result = copy($stream['uri'], $filepath) && chmod($filepath, 0664); $result = copy($stream['uri'], $filepath) && chmod($filepath, 0664);
if (!$result) { if (!$result) {
// TRANS: Client exception thrown when a file upload operation fails because the file could
// TRANS: not be moved from the temporary folder to the permanent file location.
throw new ClientException(_('File could not be moved to destination directory.' . throw new ClientException(_('File could not be moved to destination directory.' .
$stream['uri'] . ' ' . $filepath)); $stream['uri'] . ' ' . $filepath));
} }
} else { } else {
// TRANS: Client exception thrown when a file upload operation has been stopped because the MIME
// TRANS: type of the uploaded file could not be determined.
throw new ClientException(_('Could not determine file\'s MIME type.')); throw new ClientException(_('Could not determine file\'s MIME type.'));
return; return;
} }
@ -315,12 +334,17 @@ class MediaFile
} }
$media = MIME_Type::getMedia($filetype); $media = MIME_Type::getMedia($filetype);
if ('application' !== $media) { if ('application' !== $media) {
$hint = sprintf(_(' Try using another %s format.'), $media); // TRANS: Client exception thrown trying to upload a forbidden MIME type.
// TRANS: %1$s is the file type that was denied, %2$s is the application part of
// TRANS: the MIME type that was denied.
$hint = sprintf(_('"%1$s" is not a supported file type on this server. ' .
'Try using another %2$s format.'), $filetype, $media);
} else { } else {
$hint = ''; // TRANS: Client exception thrown trying to upload a forbidden MIME type.
// TRANS: %s is the file type that was denied.
$hint = sprintf(_('"%s" is not a supported file type on this server.'), $filetype);
} }
throw new ClientException(sprintf( throw new ClientException($hint);
_('%s is not a supported file type on this server.'), $filetype) . $hint);
} }
static function respectsQuota($user, $filesize) static function respectsQuota($user, $filesize)

View File

@ -280,7 +280,7 @@ class StatusNetOAuthDataStore extends OAuthDataStore
$profile->created = DB_DataObject_Cast::dateTime(); # current time $profile->created = DB_DataObject_Cast::dateTime(); # current time
$id = $profile->insert(); $id = $profile->insert();
if (!$id) { if (!$id) {
throw new Exception(_('Error inserting new profile')); throw new Exception(_('Error inserting new profile.'));
} }
$remote->id = $id; $remote->id = $id;
} }
@ -288,7 +288,7 @@ class StatusNetOAuthDataStore extends OAuthDataStore
$avatar_url = $omb_profile->getAvatarURL(); $avatar_url = $omb_profile->getAvatarURL();
if ($avatar_url) { if ($avatar_url) {
if (!$this->add_avatar($profile, $avatar_url)) { if (!$this->add_avatar($profile, $avatar_url)) {
throw new Exception(_('Error inserting avatar')); throw new Exception(_('Error inserting avatar.'));
} }
} else { } else {
$avatar = $profile->getOriginalAvatar(); $avatar = $profile->getOriginalAvatar();
@ -303,12 +303,12 @@ class StatusNetOAuthDataStore extends OAuthDataStore
if ($exists) { if ($exists) {
if (!$remote->update($orig_remote)) { if (!$remote->update($orig_remote)) {
throw new Exception(_('Error updating remote profile')); throw new Exception(_('Error updating remote profile.'));
} }
} else { } else {
$remote->created = DB_DataObject_Cast::dateTime(); # current time $remote->created = DB_DataObject_Cast::dateTime(); # current time
if (!$remote->insert()) { if (!$remote->insert()) {
throw new Exception(_('Error inserting remote profile')); throw new Exception(_('Error inserting remote profile.'));
} }
} }
} }
@ -342,7 +342,8 @@ class StatusNetOAuthDataStore extends OAuthDataStore
**/ **/
public function saveNotice(&$omb_notice) { public function saveNotice(&$omb_notice) {
if (Notice::staticGet('uri', $omb_notice->getIdentifierURI())) { if (Notice::staticGet('uri', $omb_notice->getIdentifierURI())) {
throw new Exception(_('Duplicate notice')); // TRANS: Exception thrown when a notice is denied because it has been sent before.
throw new Exception(_('Duplicate notice.'));
} }
$author_uri = $omb_notice->getAuthor()->getIdentifierURI(); $author_uri = $omb_notice->getAuthor()->getIdentifierURI();
common_log(LOG_DEBUG, $author_uri, __FILE__); common_log(LOG_DEBUG, $author_uri, __FILE__);

View File

@ -112,9 +112,9 @@ class Plugin
$name = mb_substr($cls, 0, -6); $name = mb_substr($cls, 0, -6);
$versions[] = array('name' => $name, $versions[] = array('name' => $name,
// TRANS: Displayed as version information for a plugin if no version information was found.
'version' => _('Unknown')); 'version' => _('Unknown'));
return true; return true;
} }
} }

View File

@ -117,14 +117,17 @@ class SearchAction extends Action
'class' => 'form_settings', 'class' => 'form_settings',
'action' => common_local_url($this->trimmed('action')))); 'action' => common_local_url($this->trimmed('action'))));
$this->elementStart('fieldset'); $this->elementStart('fieldset');
// TRANS: Fieldset legend for the search form.
$this->element('legend', null, _('Search site')); $this->element('legend', null, _('Search site'));
$this->elementStart('ul', 'form_data'); $this->elementStart('ul', 'form_data');
$this->elementStart('li'); $this->elementStart('li');
if (!common_config('site', 'fancy')) { if (!common_config('site', 'fancy')) {
$this->hidden('action', $this->trimmed('action')); $this->hidden('action', $this->trimmed('action'));
} }
// TRANS: Used as a field label for the field where one or more keywords
// TRANS: for searching can be entered.
$this->input('q', _('Keyword(s)'), $q); $this->input('q', _('Keyword(s)'), $q);
$this->submit('search', _('Search')); $this->submit('search', _m('BUTTON','Search'));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
$this->elementEnd('fieldset'); $this->elementEnd('fieldset');
@ -135,6 +138,8 @@ class SearchAction extends Action
} }
function searchSuggestions($q) { function searchSuggestions($q) {
// @todo FIXME: This formatting does not make this string get picked up by gettext.
// TRANS: Standard search suggestions shown when a search does not give any results.
$message = _(<<<E_O_T $message = _(<<<E_O_T
* Make sure all words are spelled correctly. * Make sure all words are spelled correctly.
* Try different keywords. * Try different keywords.
@ -145,6 +150,8 @@ E_O_T
); );
if (!common_config('site', 'private')) { if (!common_config('site', 'private')) {
$qe = urlencode($q); $qe = urlencode($q);
// @todo FIXME: This formatting does not make this string get picked up by gettext.
// TRANS: Standard search suggestions shown when a search does not give any results.
$message .= sprintf(_(<<<E_O_T $message .= sprintf(_(<<<E_O_T
You can also try your search on other engines: You can also try your search on other engines:
@ -159,6 +166,7 @@ E_O_T
), $qe, $qe, $qe, $qe, $qe); ), $qe, $qe, $qe, $qe, $qe);
} }
$this->elementStart('dl', array('id' => 'help_search', 'class' => 'help')); $this->elementStart('dl', array('id' => 'help_search', 'class' => 'help'));
// TRANS: Definition list item with instructions on how to get (better) search results.
$this->element('dt', null, _('Search help')); $this->element('dt', null, _('Search help'));
$this->elementStart('dd', 'instructions'); $this->elementStart('dd', 'instructions');
$this->raw(common_markup_to_html($message)); $this->raw(common_markup_to_html($message));
@ -166,4 +174,3 @@ E_O_T
$this->elementEnd('div'); $this->elementEnd('div');
} }
} }

View File

@ -66,6 +66,7 @@ class UnblockForm extends ProfileActionForm
function title() function title()
{ {
// TRANS: Title for the form to unblock a user.
return _('Unblock'); return _('Unblock');
} }
@ -77,6 +78,7 @@ class UnblockForm extends ProfileActionForm
function description() function description()
{ {
// TRANS: Description of the form to unblock a user.
return _('Unblock this user'); return _('Unblock this user');
} }
} }

151
lib/useractivitystream.php Normal file
View File

@ -0,0 +1,151 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2010 StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Class for activity streams
*
* Includes faves, notices, and subscriptions.
*
* We extend atomusernoticefeed since it does some nice setup for us.
*
*/
class UserActivityStream extends AtomUserNoticeFeed
{
function __construct($user, $indent = true)
{
parent::__construct($user, null, $indent);
$subscriptions = $this->getSubscriptions();
$subscribers = $this->getSubscribers();
$groups = $this->getGroups();
$faves = $this->getFaves();
$notices = $this->getNotices();
$objs = array_merge($subscriptions, $subscribers, $groups, $faves, $notices);
// Sort by create date
usort($objs, 'UserActivityStream::compareObject');
foreach ($objs as $obj) {
$act = $obj->asActivity();
// Only show the author sub-element if it's different from default user
$str = $act->asString(false, ($act->actor->id != $this->user->uri));
$this->addEntryRaw($str);
}
}
function compareObject($a, $b)
{
$ac = strtotime((empty($a->created)) ? $a->modified : $a->created);
$bc = strtotime((empty($b->created)) ? $b->modified : $b->created);
return (($ac == $bc) ? 0 : (($ac < $bc) ? 1 : -1));
}
function getSubscriptions()
{
$subs = array();
$sub = new Subscription();
$sub->subscriber = $this->user->id;
if ($sub->find()) {
while ($sub->fetch()) {
if ($sub->subscribed != $this->user->id) {
$subs[] = clone($sub);
}
}
}
return $subs;
}
function getSubscribers()
{
$subs = array();
$sub = new Subscription();
$sub->subscribed = $this->user->id;
if ($sub->find()) {
while ($sub->fetch()) {
if ($sub->subscriber != $this->user->id) {
$subs[] = clone($sub);
}
}
}
return $subs;
}
function getFaves()
{
$faves = array();
$fave = new Fave();
$fave->user_id = $this->user->id;
if ($fave->find()) {
while ($fave->fetch()) {
$faves[] = clone($fave);
}
}
return $faves;
}
function getNotices()
{
$notices = array();
$notice = new Notice();
$notice->profile_id = $this->user->id;
if ($notice->find()) {
while ($notice->fetch()) {
$notices[] = clone($notice);
}
}
return $notices;
}
function getGroups()
{
$groups = array();
$gm = new Group_member();
$gm->profile_id = $this->user->id;
if ($gm->find()) {
while ($gm->fetch()) {
$groups[] = clone($gm);
}
}
return $groups;
}
}

View File

@ -19,15 +19,18 @@
/* XXX: break up into separate modules (HTTP, user, files) */ /* XXX: break up into separate modules (HTTP, user, files) */
// Show a server error /**
* Show a server error.
*/
function common_server_error($msg, $code=500) function common_server_error($msg, $code=500)
{ {
$err = new ServerErrorAction($msg, $code); $err = new ServerErrorAction($msg, $code);
$err->showPage(); $err->showPage();
} }
// Show a user error /**
* Show a user error.
*/
function common_user_error($msg, $code=400) function common_user_error($msg, $code=400)
{ {
$err = new ClientErrorAction($msg, $code); $err = new ClientErrorAction($msg, $code);
@ -37,7 +40,7 @@ function common_user_error($msg, $code=400)
/** /**
* This should only be used at setup; processes switching languages * This should only be used at setup; processes switching languages
* to send text to other users should use common_switch_locale(). * to send text to other users should use common_switch_locale().
* *
* @param string $language Locale language code (optional; empty uses * @param string $language Locale language code (optional; empty uses
* current user's preference or site default) * current user's preference or site default)
* @return mixed success * @return mixed success
@ -61,10 +64,10 @@ function common_init_locale($language=null)
/** /**
* Initialize locale and charset settings and gettext with our message catalog, * Initialize locale and charset settings and gettext with our message catalog,
* using the current user's language preference or the site default. * using the current user's language preference or the site default.
* *
* This should generally only be run at framework initialization; code switching * This should generally only be run at framework initialization; code switching
* languages at runtime should call common_switch_language(). * languages at runtime should call common_switch_language().
* *
* @access private * @access private
*/ */
function common_init_language() function common_init_language()
@ -157,7 +160,6 @@ function common_timezone()
function common_language() function common_language()
{ {
// If there is a user logged in and they've set a language preference // If there is a user logged in and they've set a language preference
// then return that one... // then return that one...
if (_have_config() && common_logged_in()) { if (_have_config() && common_logged_in()) {
@ -189,8 +191,10 @@ function common_language()
// Finally, if none of the above worked, use the site's default... // Finally, if none of the above worked, use the site's default...
return common_config('site', 'language'); return common_config('site', 'language');
} }
// salted, hashed passwords are stored in the DB
/**
* Salted, hashed passwords are stored in the DB.
*/
function common_munge_password($password, $id) function common_munge_password($password, $id)
{ {
if (is_object($id) || is_object($password)) { if (is_object($id) || is_object($password)) {
@ -201,8 +205,9 @@ function common_munge_password($password, $id)
return md5($password . $id); return md5($password . $id);
} }
// check if a username exists and has matching password /**
* Check if a username exists and has matching password.
*/
function common_check_user($nickname, $password) function common_check_user($nickname, $password)
{ {
// empty nickname always unacceptable // empty nickname always unacceptable
@ -229,7 +234,9 @@ function common_check_user($nickname, $password)
return $authenticatedUser; return $authenticatedUser;
} }
// is the current user logged in? /**
* Is the current user logged in?
*/
function common_logged_in() function common_logged_in()
{ {
return (!is_null(common_current_user())); return (!is_null(common_current_user()));
@ -275,12 +282,10 @@ function common_ensure_session()
// 3) null to clear // 3) null to clear
// Initialize to false; set to null if none found // Initialize to false; set to null if none found
$_cur = false; $_cur = false;
function common_set_user($user) function common_set_user($user)
{ {
global $_cur; global $_cur;
if (is_null($user) && common_have_session()) { if (is_null($user) && common_have_session()) {
@ -366,7 +371,6 @@ function common_rememberme($user=null)
function common_remembered_user() function common_remembered_user()
{ {
$user = null; $user = null;
$packed = isset($_COOKIE[REMEMBERME]) ? $_COOKIE[REMEMBERME] : null; $packed = isset($_COOKIE[REMEMBERME]) ? $_COOKIE[REMEMBERME] : null;
@ -428,14 +432,17 @@ function common_remembered_user()
return $user; return $user;
} }
// must be called with a valid user! /**
* must be called with a valid user!
*/
function common_forgetme() function common_forgetme()
{ {
common_set_cookie(REMEMBERME, '', 0); common_set_cookie(REMEMBERME, '', 0);
} }
// who is the current user? /**
* Who is the current user?
*/
function common_current_user() function common_current_user()
{ {
global $_cur; global $_cur;
@ -471,10 +478,11 @@ function common_current_user()
return $_cur; return $_cur;
} }
// Logins that are 'remembered' aren't 'real' -- they're subject to /**
// cookie-stealing. So, we don't let them do certain things. New reg, * Logins that are 'remembered' aren't 'real' -- they're subject to
// OpenID, and password logins _are_ real. * cookie-stealing. So, we don't let them do certain things. New reg,
* OpenID, and password logins _are_ real.
*/
function common_real_login($real=true) function common_real_login($real=true)
{ {
common_ensure_session(); common_ensure_session();
@ -486,6 +494,29 @@ function common_is_real_login()
return common_logged_in() && $_SESSION['real_login']; return common_logged_in() && $_SESSION['real_login'];
} }
/**
* Get a hash portion for HTTP caching Etags and such including
* info on the current user's session. If login/logout state changes,
* or we've changed accounts, or we've renamed the current user,
* we'll get a new hash value.
*
* This should not be considered secure information.
*
* @param User $user (optional; uses common_current_user() if left out)
* @return string
*/
function common_user_cache_hash($user=false)
{
if ($user === false) {
$user = common_current_user();
}
if ($user) {
return crc32($user->id . ':' . $user->nickname);
} else {
return '0';
}
}
// get canonical version of nickname for comparison // get canonical version of nickname for comparison
function common_canonical_nickname($nickname) function common_canonical_nickname($nickname)
{ {
@ -577,9 +608,7 @@ function common_find_mentions($text, $notice)
} }
if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) { if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) {
// Get the context of the original notice, if any // Get the context of the original notice, if any
$originalAuthor = null; $originalAuthor = null;
$originalNotice = null; $originalNotice = null;
$originalMentions = array(); $originalMentions = array();
@ -615,7 +644,6 @@ function common_find_mentions($text, $notice)
$matches = array_merge($tmatches[1], $atmatches[1]); $matches = array_merge($tmatches[1], $atmatches[1]);
foreach ($matches as $match) { foreach ($matches as $match) {
$nickname = common_canonical_nickname($match[0]); $nickname = common_canonical_nickname($match[0]);
// Try to get a profile for this nickname. // Try to get a profile for this nickname.
@ -623,19 +651,15 @@ function common_find_mentions($text, $notice)
// sender context. // sender context.
if (!empty($originalAuthor) && $originalAuthor->nickname == $nickname) { if (!empty($originalAuthor) && $originalAuthor->nickname == $nickname) {
$mentioned = $originalAuthor; $mentioned = $originalAuthor;
} else if (!empty($originalMentions) && } else if (!empty($originalMentions) &&
array_key_exists($nickname, $originalMentions)) { array_key_exists($nickname, $originalMentions)) {
$mentioned = $originalMentions[$nickname]; $mentioned = $originalMentions[$nickname];
} else { } else {
$mentioned = common_relative_profile($sender, $nickname); $mentioned = common_relative_profile($sender, $nickname);
} }
if (!empty($mentioned)) { if (!empty($mentioned)) {
$user = User::staticGet('id', $mentioned->id); $user = User::staticGet('id', $mentioned->id);
if ($user) { if ($user) {
@ -1104,30 +1128,30 @@ function common_date_string($dt)
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return _('about a minute ago'); return _('about a minute ago');
} else if ($diff < 3300) { } else if ($diff < 3300) {
// XXX: should support plural. $minutes = round($diff/60);
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return sprintf(_('about %d minutes ago'), round($diff/60)); return sprintf( ngettext('about one minute ago', 'about %d minutes ago', $minutes), $minutes);
} else if ($diff < 5400) { } else if ($diff < 5400) {
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return _('about an hour ago'); return _('about an hour ago');
} else if ($diff < 22 * 3600) { } else if ($diff < 22 * 3600) {
// XXX: should support plural. $hours = round($diff/3600);
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return sprintf(_('about %d hours ago'), round($diff/3600)); return sprintf( ngettext('about one hour ago', 'about %d hours ago', $hours), $hours);
} else if ($diff < 37 * 3600) { } else if ($diff < 37 * 3600) {
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return _('about a day ago'); return _('about a day ago');
} else if ($diff < 24 * 24 * 3600) { } else if ($diff < 24 * 24 * 3600) {
// XXX: should support plural. $days = round($diff/(24*3600));
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return sprintf(_('about %d days ago'), round($diff/(24*3600))); return sprintf( ngettext('about one day ago', 'about %d days ago', $days), $days);
} else if ($diff < 46 * 24 * 3600) { } else if ($diff < 46 * 24 * 3600) {
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return _('about a month ago'); return _('about a month ago');
} else if ($diff < 330 * 24 * 3600) { } else if ($diff < 330 * 24 * 3600) {
// XXX: should support plural. $months = round($diff/(30*24*3600));
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return sprintf(_('about %d months ago'), round($diff/(30*24*3600))); return sprintf( ngettext('about one month ago', 'about %d months ago',$months), $months);
} else if ($diff < 480 * 24 * 3600) { } else if ($diff < 480 * 24 * 3600) {
// TRANS: Used in notices to indicate when the notice was made compared to now. // TRANS: Used in notices to indicate when the notice was made compared to now.
return _('about a year ago'); return _('about a year ago');
@ -1230,8 +1254,9 @@ function common_broadcast_notice($notice, $remote=false)
// DO NOTHING! // DO NOTHING!
} }
// Stick the notice on the queue /**
* Stick the notice on the queue.
*/
function common_enqueue_notice($notice) function common_enqueue_notice($notice)
{ {
static $localTransports = array('omb', static $localTransports = array('omb',
@ -1293,8 +1318,9 @@ function common_profile_url($nickname)
null, null, false); null, null, false);
} }
// Should make up a reasonable root URL /**
* Should make up a reasonable root URL
*/
function common_root_url($ssl=false) function common_root_url($ssl=false)
{ {
$url = common_path('', $ssl, false); $url = common_path('', $ssl, false);
@ -1305,9 +1331,10 @@ function common_root_url($ssl=false)
return $url; return $url;
} }
// returns $bytes bytes of random data as a hexadecimal string /**
// "good" here is a goal and not a guarantee * returns $bytes bytes of random data as a hexadecimal string
* "good" here is a goal and not a guarantee
*/
function common_good_rand($bytes) function common_good_rand($bytes)
{ {
// XXX: use random.org...? // XXX: use random.org...?
@ -1343,13 +1370,13 @@ function common_mtrand($bytes)
/** /**
* Record the given URL as the return destination for a future * Record the given URL as the return destination for a future
* form submission, to be read by common_get_returnto(). * form submission, to be read by common_get_returnto().
* *
* @param string $url * @param string $url
* *
* @fixme as a session-global setting, this can allow multiple forms * @fixme as a session-global setting, this can allow multiple forms
* to conflict and overwrite each others' returnto destinations if * to conflict and overwrite each others' returnto destinations if
* the user has multiple tabs or windows open. * the user has multiple tabs or windows open.
* *
* Should refactor to index with a token or otherwise only pass the * Should refactor to index with a token or otherwise only pass the
* data along its intended path. * data along its intended path.
*/ */
@ -1362,13 +1389,13 @@ function common_set_returnto($url)
/** /**
* Fetch a return-destination URL previously recorded by * Fetch a return-destination URL previously recorded by
* common_set_returnto(). * common_set_returnto().
* *
* @return mixed URL string or null * @return mixed URL string or null
* *
* @fixme as a session-global setting, this can allow multiple forms * @fixme as a session-global setting, this can allow multiple forms
* to conflict and overwrite each others' returnto destinations if * to conflict and overwrite each others' returnto destinations if
* the user has multiple tabs or windows open. * the user has multiple tabs or windows open.
* *
* Should refactor to index with a token or otherwise only pass the * Should refactor to index with a token or otherwise only pass the
* data along its intended path. * data along its intended path.
*/ */
@ -1453,7 +1480,12 @@ function common_log_db_error(&$object, $verb, $filename=null)
{ {
$objstr = common_log_objstring($object); $objstr = common_log_objstring($object);
$last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
common_log(LOG_ERR, $last_error->message . '(' . $verb . ' on ' . $objstr . ')', $filename); if (is_object($last_error)) {
$msg = $last_error->message;
} else {
$msg = 'Unknown error (' . var_export($last_error, true) . ')';
}
common_log(LOG_ERR, $msg . '(' . $verb . ' on ' . $objstr . ')', $filename);
} }
function common_log_objstring(&$object) function common_log_objstring(&$object)
@ -1495,7 +1527,7 @@ function common_valid_tag($tag)
* Determine if given domain or address literal is valid * Determine if given domain or address literal is valid
* eg for use in JIDs and URLs. Does not check if the domain * eg for use in JIDs and URLs. Does not check if the domain
* exists! * exists!
* *
* @param string $domain * @param string $domain
* @return boolean valid or not * @return boolean valid or not
*/ */
@ -1826,7 +1858,6 @@ function common_compatible_license($from, $to)
*/ */
function common_database_tablename($tablename) function common_database_tablename($tablename)
{ {
if(common_config('db','quote_identifiers')) { if(common_config('db','quote_identifiers')) {
$tablename = '"'. $tablename .'"'; $tablename = '"'. $tablename .'"';
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More