Merge branch '0.9.x' of gitorious.org:statusnet/mainline into 0.9.x
* '0.9.x' of gitorious.org:statusnet/mainline: (102 commits) Fix for ticket #3010: blocks are now applied against the original poster of repeats. Fix XML API output for several profile update methods that returned a <user> entry but didn't set namespaces, causing XML parse failures. Fix for ticket #3007: .bmp avatar uploads weren't being properly converted to PNG in all cases Bookmark saving robustness fixes remove boilerplate from NewMenuPlugin Localisation updates from http://translatewiki.net. L10n consistency updates in wording and punctuation. Translator documentation added/updated. Superfluous whitespace removed. Add translator documentation Fix L10n issues Remove superfluous whitespace Add correct punctuation for client exceptions. Add correct punctuation for client exception. Add correct punctuation for client exception. Add email field to Twitter registration form; needed when RequireValidatedEmail plugin is present. Add email field on openid registration; needed to register if RequireValidatedEmail plugin is also present. Event hook points needed for recaptcha on facebook login form (untested, but should be legit -- same adds as openid & twitter reg forms) Event hook points needed to run Recaptcha on Twitter registration Fix inconsistent use of 'name' vs 'fullname' in tw_fields member variable Add Start/EndRegistrationData event hooks in finishopenidlogin: allows recaptcha to add its captcha display to the form (checked since addition of StartRegistrationTry) Ticket #2999: RequireValidatedEmail plugin now also prevents group creation by unvalidated users. Localisation updates from http://translatewiki.net. Translator comments added L10n updates Remove superfluous whitespace Number parameters in message when two or more are used ClientException and ServerException should end with a period ...
This commit is contained in:
commit
c0bb1a5798
@ -143,7 +143,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -154,7 +154,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -204,7 +204,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -188,7 +188,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -112,16 +112,17 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
return;
|
||||
}
|
||||
|
||||
$type = $imagefile->preferredType();
|
||||
$filename = Avatar::filename(
|
||||
$user->id,
|
||||
image_type_to_extension($imagefile->type),
|
||||
image_type_to_extension($type),
|
||||
null,
|
||||
'tmp'.common_timestamp()
|
||||
);
|
||||
|
||||
$filepath = Avatar::path($filename);
|
||||
|
||||
move_uploaded_file($imagefile->filepath, $filepath);
|
||||
$imagefile->copyTo($filepath);
|
||||
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
@ -139,7 +140,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -39,7 +39,6 @@ require_once INSTALLDIR.'/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
{
|
||||
/**
|
||||
@ -50,13 +49,13 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when making an Atom API request for an unknown user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -71,7 +70,6 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -83,13 +81,15 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
'xmlns:atom' => 'http://www.w3.org/2005/Atom',
|
||||
'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/'));
|
||||
$this->elementStart('workspace');
|
||||
$this->element('atom:title', null, _('Main'));
|
||||
// TRANS: Title for Atom feed.
|
||||
$this->element('atom:title', null, _m('ATOM','Main'));
|
||||
$this->elementStart('collection',
|
||||
array('href' => common_local_url('ApiTimelineUser',
|
||||
array('id' => $this->user->id,
|
||||
'format' => 'atom'))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
// TRANS: Title for Atom feed. %s is a user nickname.
|
||||
sprintf(_("%s timeline"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
@ -100,6 +100,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
array('subscriber' => $this->user->id))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
// TRANS: Title for Atom feed with a user's subscriptions. %s is a user nickname.
|
||||
sprintf(_("%s subscriptions"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
@ -110,6 +111,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
array('profile' => $this->user->id))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
// TRANS: Title for Atom feed with a user's favorite notices. %s is a user nickname.
|
||||
sprintf(_("%s favorites"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
@ -120,6 +122,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
array('profile' => $this->user->id))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
// TRANS: Title for Atom feed with a user's memberships. %s is a user nickname.
|
||||
sprintf(_("%s memberships"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
|
@ -92,6 +92,7 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->user) || empty($this->other)) {
|
||||
// TRANS: Client error displayed when trying to block a non-existing user or a user from another site.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
@ -66,6 +66,12 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
parent::prepare($args);
|
||||
|
||||
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed trying to show group membership on a non-existing group.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->profiles = $this->getProfiles();
|
||||
|
||||
return true;
|
||||
@ -84,12 +90,6 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed trying to show group membership on a non-existing group.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: RSS and Atom
|
||||
|
||||
switch($this->format) {
|
||||
|
@ -114,6 +114,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
$this->deleteNotice();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed calling an unsupported HTTP error in API status show.
|
||||
$this->clientError(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
@ -138,6 +139,8 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
$this->showSingleAtomStatus($this->notice);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Exception thrown requesting an unsupported notice output format.
|
||||
// TRANS: %s is the requested output format.
|
||||
throw new Exception(sprintf(_("Unsupported format: %s"), $this->format));
|
||||
}
|
||||
} else {
|
||||
@ -220,6 +223,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
function deleteNotice()
|
||||
{
|
||||
if ($this->format != 'atom') {
|
||||
// TRANS: Client error displayed when trying to delete a notice not using the Atom format.
|
||||
$this->clientError(_("Can only delete using the Atom format."));
|
||||
return;
|
||||
}
|
||||
@ -227,7 +231,8 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
if (empty($this->auth_user) ||
|
||||
($this->notice->profile_id != $this->auth_user->id &&
|
||||
!$this->auth_user->hasRight(Right::DELETEOTHERSNOTICE))) {
|
||||
$this->clientError(_('Can\'t delete this notice.'), 403);
|
||||
// TRANS: Client error displayed when a user has no rights to delete notices of other users.
|
||||
$this->clientError(_('Cannot delete this notice.'), 403);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -240,6 +245,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
|
||||
header('HTTP/1.1 200 OK');
|
||||
header('Content-Type: text/plain');
|
||||
// TRANS: Confirmation of notice deletion in API. %d is the ID (number) of the deleted notice.
|
||||
print(sprintf(_('Deleted notice %d'), $this->notice->id));
|
||||
print("\n");
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
function supported($cmd)
|
||||
{
|
||||
static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
|
||||
'FavCommand', 'OnCommand', 'OffCommand');
|
||||
'FavCommand', 'OnCommand', 'OffCommand', 'JoinCommand', 'LeaveCommand');
|
||||
|
||||
if (in_array(get_class($cmd), $cmdlist)) {
|
||||
return true;
|
||||
|
@ -307,11 +307,13 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
|
||||
$xml = trim(file_get_contents('php://input'));
|
||||
if (empty($xml)) {
|
||||
// TRANS: Client error displayed attempting to post an empty API notice.
|
||||
$this->clientError(_('Atom post must not be empty.'));
|
||||
}
|
||||
|
||||
$dom = DOMDocument::loadXML($xml);
|
||||
if (!$dom) {
|
||||
// TRANS: Client error displayed attempting to post an API that is not well-formed XML.
|
||||
$this->clientError(_('Atom post must be well-formed XML.'));
|
||||
}
|
||||
|
||||
@ -375,6 +377,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
} else {
|
||||
// @fixme fetch from $sourceUrl?
|
||||
// TRANS: Client error displayed when posting a notice without content through the API.
|
||||
// TRANS: %d is the notice ID (number).
|
||||
$this->clientError(sprintf(_('No content for notice %d.'),
|
||||
$note->id));
|
||||
return;
|
||||
@ -427,14 +430,14 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
$profile = Profile::fromURI($uri);
|
||||
|
||||
if (!empty($profile)) {
|
||||
$options['replies'] = $uri;
|
||||
$options['replies'][] = $uri;
|
||||
} else {
|
||||
$group = User_group::staticGet('uri', $uri);
|
||||
if (!empty($group)) {
|
||||
$options['groups'] = $uri;
|
||||
$options['groups'][] = $uri;
|
||||
} else {
|
||||
// @fixme: hook for discovery here
|
||||
common_log(LOG_WARNING, sprintf(_('AtomPub post with unknown attention URI %s'), $uri));
|
||||
common_log(LOG_WARNING, sprintf('AtomPub post with unknown attention URI %s', $uri));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
@ -59,7 +58,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
@ -67,7 +65,8 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
$this->_profile = Profile::staticGet('id', $this->trimmed('profile'));
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(_('No such profile'), 404);
|
||||
// TRANS: Client exception thrown when requesting a favorite feed for a non-existing profile.
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
$offset = ($this->page-1) * $this->count;
|
||||
@ -87,7 +86,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
@ -101,6 +99,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
$this->addFavorite();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client exception thrown when using an unsupported HTTP method.
|
||||
throw new ClientException(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
@ -113,7 +112,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
@ -139,10 +137,14 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
|
||||
// TRANS: Title for Atom favorites feed.
|
||||
// TRANS: %s is a user nickname.
|
||||
$feed->setTitle(sprintf(_("%s favorites"),
|
||||
$this->_profile->getBestName()));
|
||||
|
||||
$feed->setSubtitle(sprintf(_("Notices %s has favorited to on %s"),
|
||||
// TRANS: Subtitle for Atom favorites feed.
|
||||
// TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename.
|
||||
$feed->setSubtitle(sprintf(_("Notices %1$s has favorited on %2$s"),
|
||||
$this->_profile->getBestName(),
|
||||
common_config('site', 'name')));
|
||||
|
||||
@ -205,15 +207,15 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addFavorite()
|
||||
{
|
||||
// XXX: Refactor this; all the same for atompub
|
||||
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't add someone else's".
|
||||
" subscription"), 403);
|
||||
// TRANS: Client exception thrown when trying to set a favorite for another user.
|
||||
throw new ClientException(_("Cannot add someone else's".
|
||||
" subscription."), 403);
|
||||
}
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
@ -234,9 +236,8 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::FAVORITE) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
// TRANS: Do not translate POST.
|
||||
throw new ClientException(_('Can only handle Favorite activities.'));
|
||||
// TRANS: Client exception thrown when trying use an incorrect activity verb for the Atom pub method.
|
||||
throw new ClientException(_('Can only handle favorite activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -245,6 +246,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
if (!in_array($note->type, array(ActivityObject::NOTE,
|
||||
ActivityObject::BLOGENTRY,
|
||||
ActivityObject::STATUS))) {
|
||||
// TRANS: Client exception thrown when trying favorite an object that is not a notice.
|
||||
throw new ClientException(_('Can only fave notices.'));
|
||||
return;
|
||||
}
|
||||
@ -253,6 +255,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
|
||||
if (empty($notice)) {
|
||||
// XXX: import from listed URL or something
|
||||
// TRANS: Client exception thrown when trying favorite a notice without content.
|
||||
throw new ClientException(_('Unknown note.'));
|
||||
}
|
||||
|
||||
@ -260,6 +263,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
'notice_id' => $notice->id));
|
||||
|
||||
if (!empty($old)) {
|
||||
// TRANS: Client exception thrown when trying favorite an already favorited notice.
|
||||
throw new ClientException(_('Already a favorite.'));
|
||||
}
|
||||
|
||||
@ -296,7 +300,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
@ -328,7 +331,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
@ -339,7 +341,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
@ -359,7 +360,6 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function notify($fave, $notice, $user)
|
||||
{
|
||||
$other = User::staticGet('id', $notice->profile_id);
|
||||
|
@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
@ -59,7 +58,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
@ -69,6 +67,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
$this->_profile = Profile::staticGet('id', $profileId);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
// TRANS: Client exception.
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
@ -89,7 +88,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
@ -103,6 +101,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
$this->addMembership();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client exception thrown when using an unsupported HTTP method.
|
||||
throw new ClientException(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
@ -115,7 +114,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
@ -141,10 +139,14 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
|
||||
// TRANS: Title for group membership feed.
|
||||
// TRANS: %s is a username.
|
||||
$feed->setTitle(sprintf(_("%s group memberships"),
|
||||
$this->_profile->getBestName()));
|
||||
|
||||
$feed->setSubtitle(sprintf(_("Groups %s is a member of on %s"),
|
||||
// TRANS: Subtitle for group membership feed.
|
||||
// TRANS: %1$s is a username, %2$s is the StatusNet sitename.
|
||||
$feed->setSubtitle(sprintf(_("Groups %1$s is a member of on %2$s"),
|
||||
$this->_profile->getBestName(),
|
||||
common_config('site', 'name')));
|
||||
|
||||
@ -207,15 +209,15 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addMembership()
|
||||
{
|
||||
// XXX: Refactor this; all the same for atompub
|
||||
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't add someone else's".
|
||||
" membership"), 403);
|
||||
// TRANS: Client exception thrown when trying subscribe someone else to a group.
|
||||
throw new ClientException(_("Cannot add someone else's".
|
||||
" membership."), 403);
|
||||
}
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
@ -234,17 +236,17 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
$membership = null;
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::JOIN) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
// TRANS: Do not translate POST.
|
||||
throw new ClientException(_('Can only handle Join activities.'));
|
||||
throw new ClientException(_('Can only handle join activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$groupObj = $activity->objects[0];
|
||||
|
||||
if ($groupObj->type != ActivityObject::GROUP) {
|
||||
// TRANS: Client exception thrown when trying favorite an object that is not a notice.
|
||||
throw new ClientException(_('Can only fave notices.'));
|
||||
return;
|
||||
}
|
||||
@ -253,6 +255,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
|
||||
if (empty($group)) {
|
||||
// XXX: import from listed URL or something
|
||||
// TRANS: Client exception thrown when trying to subscribe to a non-existing group.
|
||||
throw new ClientException(_('Unknown group.'));
|
||||
}
|
||||
|
||||
@ -260,6 +263,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
'group_id' => $group->id));
|
||||
|
||||
if (!empty($old)) {
|
||||
// TRANS: Client exception thrown when trying to subscribe to an already subscribed group.
|
||||
throw new ClientException(_('Already a member.'));
|
||||
}
|
||||
|
||||
@ -267,6 +271,7 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
|
||||
if (Group_block::isBlocked($group, $profile)) {
|
||||
// XXX: import from listed URL or something
|
||||
// TRANS: Client exception thrown when trying to subscribe to group while blocked from that group.
|
||||
throw new ClientException(_('Blocked by admin.'));
|
||||
}
|
||||
|
||||
@ -299,7 +304,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
@ -331,7 +335,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
@ -342,7 +345,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
@ -62,7 +61,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
@ -73,12 +71,14 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
$this->_profile = Profile::staticGet('id', $profileId);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
// TRANS: Client exception.
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
$this->_notice = Notice::staticGet('id', $noticeId);
|
||||
|
||||
if (empty($this->_notice)) {
|
||||
// TRANS: Client exception thrown when referencing a non-existing notice.
|
||||
throw new ClientException(_('No such notice.'), 404);
|
||||
}
|
||||
|
||||
@ -86,6 +86,7 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
'notice_id' => $noticeId));
|
||||
|
||||
if (empty($this->_fave)) {
|
||||
// TRANS: Client exception thrown when referencing a non-existing favorite.
|
||||
throw new ClientException(_('No such favorite.'), 404);
|
||||
}
|
||||
|
||||
@ -99,7 +100,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
@ -113,6 +113,7 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
$this->deleteFave();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client exception thrown using an unsupported HTTP method.
|
||||
throw new ClientException(_('HTTP method not supported.'),
|
||||
405);
|
||||
}
|
||||
@ -124,7 +125,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFave()
|
||||
{
|
||||
$activity = $this->_fave->asActivity();
|
||||
@ -143,13 +143,13 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function deleteFave()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't delete someone else's".
|
||||
" favorite"), 403);
|
||||
// TRANS: Client exception thrown when trying to remove a favorite notice of another user.
|
||||
throw new ClientException(_("Cannot delete someone else's".
|
||||
" favorite."), 403);
|
||||
}
|
||||
|
||||
$this->_fave->delete();
|
||||
@ -166,7 +166,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
@ -184,7 +183,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
return max(strtotime($this->_profile->modified),
|
||||
@ -199,7 +197,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
$mtime = strtotime($this->_fave->modified);
|
||||
@ -215,7 +212,6 @@ class AtompubshowfavoriteAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
|
@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AtompubshowmembershipAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
@ -60,7 +59,6 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
@ -70,6 +68,7 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
$this->_profile = Profile::staticGet('id', $profileId);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
// TRANS: Client exception.
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
@ -78,7 +77,8 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
$this->_group = User_group::staticGet('id', $groupId);
|
||||
|
||||
if (empty($this->_group)) {
|
||||
throw new ClientException(_('No such group'), 404);
|
||||
// TRANS: Client exception thrown when referencing a non-existing group.
|
||||
throw new ClientException(_('No such group.'), 404);
|
||||
}
|
||||
|
||||
$kv = array('group_id' => $groupId,
|
||||
@ -87,7 +87,8 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
$this->_membership = Group_member::pkeyGet($kv);
|
||||
|
||||
if (empty($this->_membership)) {
|
||||
throw new ClientException(_('Not a member'), 404);
|
||||
// TRANS: Client exception thrown when trying to show membership of a non-subscribed group
|
||||
throw new ClientException(_('Not a member.'), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -100,7 +101,6 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
@ -112,7 +112,8 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
$this->deleteMembership();
|
||||
break;
|
||||
default:
|
||||
throw new ClientException(_('Method not supported'), 405);
|
||||
// TRANS: Client exception thrown when using an unsupported HTTP method.
|
||||
throw new ClientException(_('HTTP method not supported.'), 405);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@ -123,7 +124,6 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showMembership()
|
||||
{
|
||||
$activity = $this->_membership->asActivity();
|
||||
@ -147,8 +147,9 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't delete someone else's".
|
||||
" membership"), 403);
|
||||
// TRANS: Client exception thrown when deleting someone else's membership.
|
||||
throw new ClientException(_("Cannot delete someone else's".
|
||||
" membership."), 403);
|
||||
}
|
||||
|
||||
if (Event::handle('StartLeaveGroup', array($this->_group, $this->auth_user))) {
|
||||
@ -168,7 +169,6 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
@ -203,7 +203,6 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
$ctime = strtotime($this->_membership->created);
|
||||
@ -222,7 +221,6 @@ class AtompubshowmembershipAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
|
@ -69,7 +69,7 @@ class AtompubshowsubscriptionAction extends ApiAuthAction
|
||||
if (empty($this->_subscriber)) {
|
||||
// TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID.
|
||||
// TRANS: %d is the non-existing profile ID number.
|
||||
throw new ClientException(sprintf(_('No such profile id: %d'),
|
||||
throw new ClientException(sprintf(_('No such profile id: %d.'),
|
||||
$subscriberId), 404);
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ class AtompubshowsubscriptionAction extends ApiAuthAction
|
||||
if (empty($this->_subscribed)) {
|
||||
// TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID.
|
||||
// TRANS: %d is the non-existing profile ID number.
|
||||
throw new ClientException(sprintf(_('No such profile id: %d'),
|
||||
throw new ClientException(sprintf(_('No such profile id: %d.'),
|
||||
$subscribedId), 404);
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ class AtompubshowsubscriptionAction extends ApiAuthAction
|
||||
if (empty($this->_subscription)) {
|
||||
// TRANS: Client exception thrown when trying to display a subscription for a non-subscribed profile ID.
|
||||
// TRANS: %1$d is the non-existing subscriber ID number, $2$d is the ID of the profile that was not subscribed to.
|
||||
$msg = sprintf(_('Profile %1$d not subscribed to profile %2$d'),
|
||||
$msg = sprintf(_('Profile %1$d not subscribed to profile %2$d.'),
|
||||
$subscriberId, $subscribedId);
|
||||
throw new ClientException($msg, 404);
|
||||
}
|
||||
@ -155,7 +155,7 @@ class AtompubshowsubscriptionAction extends ApiAuthAction
|
||||
$this->auth_user->id != $this->_subscriber->id) {
|
||||
// TRANS: Client exception thrown when trying to delete a subscription of another user.
|
||||
throw new ClientException(_("Cannot delete someone else's ".
|
||||
"subscription"), 403);
|
||||
"subscription."), 403);
|
||||
}
|
||||
|
||||
Subscription::cancel($this->_subscriber,
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
@ -61,7 +60,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
@ -71,7 +69,9 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
$this->_profile = Profile::staticGet('id', $subscriber);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(sprintf(_('No such profile id: %d'),
|
||||
// TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID.
|
||||
// TRANS: %d is the non-existing profile ID number.
|
||||
throw new ClientException(sprintf(_('No such profile id: %d.'),
|
||||
$subscriber), 404);
|
||||
}
|
||||
|
||||
@ -93,7 +93,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
@ -106,6 +105,7 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
$this->addSubscription();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client exception thrown when using an unsupported HTTP method.
|
||||
$this->clientError(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
@ -118,7 +118,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
@ -144,10 +143,14 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
|
||||
// TRANS: Title for Atom subscription feed.
|
||||
// TRANS: %s is a user nickname.
|
||||
$feed->setTitle(sprintf(_("%s subscriptions"),
|
||||
$this->_profile->getBestName()));
|
||||
|
||||
$feed->setSubtitle(sprintf(_("People %s has subscribed to on %s"),
|
||||
// TRANS: Subtitle for Atom subscription feed.
|
||||
// TRANS: %1$s is a user nickname, %s$s is the StatusNet sitename.
|
||||
$feed->setSubtitle(sprintf(_("People %1$s has subscribed to on %2$s"),
|
||||
$this->_profile->getBestName(),
|
||||
common_config('site', 'name')));
|
||||
|
||||
@ -214,13 +217,13 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addSubscription()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't add someone else's".
|
||||
" subscription"), 403);
|
||||
// TRANS: Client exception thrown when trying to subscribe another user.
|
||||
throw new ClientException(_("Cannot add someone else's".
|
||||
" subscription."), 403);
|
||||
}
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
@ -250,6 +253,7 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
$person = $activity->objects[0];
|
||||
|
||||
if ($person->type != ActivityObject::PERSON) {
|
||||
// TRANS: Client exception thrown when subscribing to an object that is not a person.
|
||||
$this->clientError(_('Can only follow people.'));
|
||||
return;
|
||||
}
|
||||
@ -259,7 +263,16 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
$profile = Profile::fromURI($person->id);
|
||||
|
||||
if (empty($profile)) {
|
||||
$this->clientError(sprintf(_('Unknown profile %s'), $person->id));
|
||||
// TRANS: Client exception thrown when subscribing to a non-existing profile.
|
||||
$this->clientError(sprintf(_('Unknown profile %s.'), $person->id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Subscription::exists($this->_profile, $profile)) {
|
||||
// 409 Conflict
|
||||
$this->clientError(sprintf(_('Already subscribed to %s'),
|
||||
$person->id),
|
||||
409);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -290,7 +303,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return $_SERVER['REQUEST_METHOD'] != 'POST';
|
||||
@ -301,7 +313,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
return null;
|
||||
@ -312,7 +323,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
@ -323,7 +333,6 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
@ -320,21 +320,20 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
}
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
$type = $imagefile->preferredType();
|
||||
$filename = Avatar::filename($cur->id,
|
||||
image_type_to_extension($imagefile->type),
|
||||
image_type_to_extension($type),
|
||||
null,
|
||||
'tmp'.common_timestamp());
|
||||
|
||||
$filepath = Avatar::path($filename);
|
||||
|
||||
move_uploaded_file($imagefile->filepath, $filepath);
|
||||
$imagefile->copyTo($filepath);
|
||||
|
||||
$filedata = array('filename' => $filename,
|
||||
'filepath' => $filepath,
|
||||
'width' => $imagefile->width,
|
||||
'height' => $imagefile->height,
|
||||
'type' => $imagefile->type);
|
||||
'type' => $type);
|
||||
|
||||
$_SESSION['FILEDATA'] = $filedata;
|
||||
|
||||
|
@ -48,7 +48,6 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class BackupaccountAction extends Action
|
||||
{
|
||||
/**
|
||||
@ -56,9 +55,9 @@ class BackupaccountAction extends Action
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for backup account page.
|
||||
return _("Backup account");
|
||||
}
|
||||
|
||||
@ -69,7 +68,6 @@ class BackupaccountAction extends Action
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
@ -77,10 +75,12 @@ class BackupaccountAction extends Action
|
||||
$cur = common_current_user();
|
||||
|
||||
if (empty($cur)) {
|
||||
// TRANS: Client exception thrown when trying to backup an account while not logged in.
|
||||
throw new ClientException(_('Only logged-in users can backup their account.'), 403);
|
||||
}
|
||||
|
||||
if (!$cur->hasRight(Right::BACKUPACCOUNT)) {
|
||||
// TRANS: Client exception thrown when trying to backup an account without having backup rights.
|
||||
throw new ClientException(_('You may not backup your account.'), 403);
|
||||
}
|
||||
|
||||
@ -94,7 +94,6 @@ class BackupaccountAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
@ -148,7 +147,6 @@ class BackupaccountAction extends Action
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return false;
|
||||
@ -161,7 +159,6 @@ class BackupaccountAction extends Action
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
// For comparison with If-Last-Modified
|
||||
@ -176,7 +173,6 @@ class BackupaccountAction extends Action
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
@ -193,7 +189,6 @@ class BackupaccountAction extends Action
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class BackupAccountForm extends Form
|
||||
{
|
||||
/**
|
||||
@ -201,7 +196,6 @@ class BackupAccountForm extends Form
|
||||
*
|
||||
* @return string the form's class
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_profile_backup';
|
||||
@ -212,7 +206,6 @@ class BackupAccountForm extends Form
|
||||
*
|
||||
* @return string the form's action URL
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
return common_local_url('backupaccount');
|
||||
@ -225,13 +218,13 @@ class BackupAccountForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
$msg =
|
||||
// TRANS: Information displayed on the backup account page.
|
||||
_('You can backup your account data in '.
|
||||
'<a href="http://activitystrea.ms/">Activity Streams</a> '.
|
||||
'format. This is an experimental feature and provides an '.
|
||||
'format. This is an experimental feature and provides an '.
|
||||
'incomplete backup; private account '.
|
||||
'information like email and IM addresses is not backed up. '.
|
||||
'Additionally, uploaded files and direct messages are not '.
|
||||
@ -248,13 +241,14 @@ class BackupAccountForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit',
|
||||
// TRANS: Submit button to backup an account on the backup account page.
|
||||
_m('BUTTON', 'Backup'),
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Title for submit button to backup an account on the backup account page.
|
||||
_('Backup your account'));
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class ConfirmaddressAction extends Action
|
||||
if (!$result) {
|
||||
common_log_db_error($cur, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed when a user update to the database fails in the contact address confirmation action.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ class DeleteaccountAction extends Action
|
||||
if ($this->trimmed('iamsure') != $iamsure ) {
|
||||
// TRANS: Notification for user about the text that must be input to be able to delete a user account.
|
||||
// TRANS: %s is the text that needs to be input.
|
||||
$this->_error = sprintf(_('You must write "%s" exactly in the box.', $iamsure));
|
||||
$this->_error = sprintf(_('You must write "%s" exactly in the box.'), $iamsure);
|
||||
$this->showPage();
|
||||
return;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class DeletenoticeAction extends Action
|
||||
if ($this->notice->profile_id != $this->user_profile->id &&
|
||||
!$this->user->hasRight(Right::DELETEOTHERSNOTICE)) {
|
||||
// TRANS: Error message displayed trying to delete a notice that was not made by the current user.
|
||||
common_user_error(_('Can\'t delete this notice.'));
|
||||
common_user_error(_('Cannot delete this notice.'));
|
||||
exit;
|
||||
}
|
||||
// XXX: Ajax!
|
||||
|
@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class DeleteuserAction extends ProfileFormAction
|
||||
{
|
||||
var $user = null;
|
||||
@ -52,7 +51,6 @@ class DeleteuserAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
@ -64,6 +62,7 @@ class DeleteuserAction extends ProfileFormAction
|
||||
assert(!empty($cur)); // checked by parent
|
||||
|
||||
if (!$cur->hasRight(Right::DELETEUSER)) {
|
||||
// TRANS: Client error displayed when trying to delete a user without having the right to delete users.
|
||||
$this->clientError(_('You cannot delete users.'));
|
||||
return false;
|
||||
}
|
||||
@ -71,6 +70,7 @@ class DeleteuserAction extends ProfileFormAction
|
||||
$this->user = User::staticGet('id', $this->profile->id);
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when trying to delete a non-local user.
|
||||
$this->clientError(_('You can only delete local users.'));
|
||||
return false;
|
||||
}
|
||||
@ -87,7 +87,6 @@ class DeleteuserAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
@ -107,7 +106,8 @@ class DeleteuserAction extends ProfileFormAction
|
||||
}
|
||||
|
||||
function title() {
|
||||
return _('Delete user');
|
||||
// TRANS: Title of delete user page.
|
||||
return _m('TITLE','Delete user');
|
||||
}
|
||||
|
||||
function showNoticeForm() {
|
||||
@ -130,9 +130,11 @@ class DeleteuserAction extends ProfileFormAction
|
||||
'action' => common_local_url('deleteuser')));
|
||||
$this->elementStart('fieldset');
|
||||
$this->hidden('token', common_session_token());
|
||||
// TRANS: Fieldset legend on delete user page.
|
||||
$this->element('legend', _('Delete user'));
|
||||
if (Event::handle('StartDeleteUserForm', array($this, $this->user))) {
|
||||
$this->element('p', null,
|
||||
// TRANS: Information text to request if a user is certain that the described action has to be performed.
|
||||
_('Are you sure you want to delete this user? '.
|
||||
'This will clear all data about the user from the '.
|
||||
'database, without a backup.'));
|
||||
@ -153,7 +155,7 @@ class DeleteuserAction extends ProfileFormAction
|
||||
'submit form_action-primary',
|
||||
'no',
|
||||
// TRANS: Submit button title for 'No' when deleting a user.
|
||||
_('Do not block this user'));
|
||||
_('Do not delete this user'));
|
||||
$this->submit('form_action-yes',
|
||||
// TRANS: Button label on the delete user form.
|
||||
_m('BUTTON','Yes'),
|
||||
@ -170,7 +172,6 @@ class DeleteuserAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
if (Event::handle('StartDeleteUser', array($this, $this->user))) {
|
||||
|
@ -44,10 +44,8 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class DesignadminpanelAction extends AdminPanelAction
|
||||
{
|
||||
|
||||
/* The default site design */
|
||||
var $design = null;
|
||||
|
||||
@ -56,7 +54,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Message used as title for design settings for the site.
|
||||
@ -68,9 +65,9 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return string instructions
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// TRANS: Instructions for design adminsitration panel.
|
||||
return _('Design settings for this StatusNet site');
|
||||
}
|
||||
|
||||
@ -79,7 +76,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showForm()
|
||||
{
|
||||
$this->design = Design::siteDesign();
|
||||
@ -93,7 +89,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
if ($this->arg('save')) {
|
||||
@ -101,6 +96,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
} else if ($this->arg('defaults')) {
|
||||
$this->restoreDefaults();
|
||||
} else {
|
||||
// TRANS: Client error displayed when the submitted form contains unexpected data.
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
}
|
||||
}
|
||||
@ -110,7 +106,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveDesignSettings()
|
||||
{
|
||||
// Workaround for PHP returning empty $_POST and $_FILES when POST
|
||||
@ -225,11 +220,10 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the default design
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
* Restore the default design
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function restoreDefaults()
|
||||
{
|
||||
$this->deleteSetting('site', 'logo');
|
||||
@ -257,7 +251,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return string $filename the filename of the image
|
||||
*/
|
||||
|
||||
function saveBackgroundImage()
|
||||
{
|
||||
$filename = null;
|
||||
@ -302,7 +295,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
* @throws ClientException for invalid theme archives
|
||||
* @throws ServerException if trouble saving the theme files
|
||||
*/
|
||||
|
||||
function saveCustomTheme()
|
||||
{
|
||||
if (common_config('theme_upload', 'enabled') &&
|
||||
@ -327,20 +319,23 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function validate(&$values)
|
||||
{
|
||||
if (!empty($values['logo']) &&
|
||||
!Validate::uri($values['logo'], array('allowed_schemes' => array('http', 'https')))) {
|
||||
// TRANS: Client error displayed when a logo URL does is not valid.
|
||||
$this->clientError(_('Invalid logo URL.'));
|
||||
}
|
||||
|
||||
if (!empty($values['ssllogo']) &&
|
||||
!Validate::uri($values['ssllogo'], array('allowed_schemes' => array('https')))) {
|
||||
// TRANS: Client error displayed when an SSL logo URL is invalid.
|
||||
$this->clientError(_('Invalid SSL logo URL.'));
|
||||
}
|
||||
|
||||
if (!in_array($values['theme'], Theme::listAvailable())) {
|
||||
// TRANS: Client error displayed when a theme is submitted through the form that is not in the theme list.
|
||||
// TRANS: %s is the chosen unavailable theme.
|
||||
$this->clientError(sprintf(_("Theme not available: %s."), $values['theme']));
|
||||
}
|
||||
}
|
||||
@ -350,7 +345,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showStylesheets()
|
||||
{
|
||||
parent::showStylesheets();
|
||||
@ -362,7 +356,6 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
@ -383,7 +376,6 @@ class DesignAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return int ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
return 'form_design_admin_panel';
|
||||
@ -394,7 +386,6 @@ class DesignAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return string class of the form
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_settings';
|
||||
@ -408,7 +399,6 @@ class DesignAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return string the method to use for submitting
|
||||
*/
|
||||
|
||||
function method()
|
||||
{
|
||||
$this->enctype = 'multipart/form-data';
|
||||
@ -421,7 +411,6 @@ class DesignAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return string URL of the action
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
return common_local_url('designadminpanel');
|
||||
@ -432,7 +421,6 @@ class DesignAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
$this->showLogo();
|
||||
@ -445,16 +433,25 @@ class DesignAdminPanelForm extends AdminForm
|
||||
function showLogo()
|
||||
{
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_logo'));
|
||||
// TRANS: Fieldset legend for form to change logo.
|
||||
$this->out->element('legend', null, _('Change logo'));
|
||||
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
$this->input('logo', _('Site logo'), 'Logo for the site (full URL)');
|
||||
$this->input('logo',
|
||||
// TRANS: Field label for StatusNet site logo.
|
||||
_('Site logo'),
|
||||
// TRANS: Title for field label for StatusNet site logo.
|
||||
'Logo for the site (full URL)');
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input('ssllogo', _('SSL logo'), 'Logo to show on SSL pages');
|
||||
$this->input('ssllogo',
|
||||
// TRANS: Field label for SSL StatusNet site logo.
|
||||
_('SSL logo'),
|
||||
// TRANS: Title for field label for SSL StatusNet site logo.
|
||||
'Logo to show on SSL pages');
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
@ -466,6 +463,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
function showTheme()
|
||||
{
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_theme'));
|
||||
// TRANS: Fieldset legend for form change StatusNet site's theme.
|
||||
$this->out->element('legend', null, _('Change theme'));
|
||||
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
@ -483,17 +481,21 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$themes = array_combine($themes, $themes);
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for dropdown to choose site theme.
|
||||
$this->out->dropdown('theme', _('Site theme'),
|
||||
// TRANS: Title for field label for dropdown to choose site theme.
|
||||
$themes, _('Theme for the site.'),
|
||||
false, $this->value('theme'));
|
||||
$this->unli();
|
||||
|
||||
if (common_config('theme_upload', 'enabled')) {
|
||||
$this->li();
|
||||
// TRANS: Field label for uploading a cutom theme.
|
||||
$this->out->element('label', array('for' => 'design_upload_theme'), _('Custom theme'));
|
||||
$this->out->element('input', array('id' => 'design_upload_theme',
|
||||
'name' => 'design_upload_theme',
|
||||
'type' => 'file'));
|
||||
// TRANS: Form instructions for uploading a cutom StatusNet theme.
|
||||
$this->out->element('p', 'form_guide', _('You can upload a custom StatusNet theme as a .ZIP archive.'));
|
||||
$this->unli();
|
||||
}
|
||||
@ -509,16 +511,19 @@ class DesignAdminPanelForm extends AdminForm
|
||||
|
||||
$this->out->elementStart('fieldset', array('id' =>
|
||||
'settings_design_background-image'));
|
||||
// TRANS: Fieldset legend for theme background image.
|
||||
$this->out->element('legend', null, _('Change background image'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
$this->out->element('label', array('for' => 'design_background-image_file'),
|
||||
// TRANS: Field label for background image on theme designer page.
|
||||
_('Background'));
|
||||
$this->out->element('input', array('name' => 'design_background-image_file',
|
||||
'type' => 'file',
|
||||
'id' => 'design_background-image_file'));
|
||||
$this->out->element('p', 'form_guide',
|
||||
// TRANS: Form guide for background image upload form on theme designer page.
|
||||
sprintf(_('You can upload a background image for the site. ' .
|
||||
'The maximum file size is %1$s.'), ImageFile::maxFileSize()));
|
||||
$this->out->element('input', array('name' => 'MAX_FILE_SIZE',
|
||||
@ -568,11 +573,13 @@ class DesignAdminPanelForm extends AdminForm
|
||||
'class' => 'radio'),
|
||||
// TRANS: Used as radio button label to not add a background image.
|
||||
_('Off'));
|
||||
// TRANS: Form guide for turning background image on or off on theme designer page.
|
||||
$this->out->element('p', 'form_guide', _('Turn background image on or off.'));
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->out->checkbox('design_background-image_repeat',
|
||||
// TRANS: Checkbox label to title background image on theme designer page.
|
||||
_('Tile background image'),
|
||||
($design->disposition & BACKGROUND_TILE) ? true : false);
|
||||
$this->unli();
|
||||
@ -587,7 +594,8 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$design = $this->out->design;
|
||||
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
|
||||
$this->out->element('legend', null, _('Change colours'));
|
||||
// TRANS: Fieldset legend for theme colors.
|
||||
$this->out->element('legend', null, _('Change colors'));
|
||||
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
@ -597,6 +605,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$bgcolor = new WebColor($design->backgroundcolor);
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for background color selector.
|
||||
$this->out->element('label', array('for' => 'swatch-1'), _('Background'));
|
||||
$this->out->element('input', array('name' => 'design_background',
|
||||
'type' => 'text',
|
||||
@ -610,6 +619,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$ccolor = new WebColor($design->contentcolor);
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for content color selector.
|
||||
$this->out->element('label', array('for' => 'swatch-2'), _('Content'));
|
||||
$this->out->element('input', array('name' => 'design_content',
|
||||
'type' => 'text',
|
||||
@ -623,6 +633,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$sbcolor = new WebColor($design->sidebarcolor);
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for sidebar color selector.
|
||||
$this->out->element('label', array('for' => 'swatch-3'), _('Sidebar'));
|
||||
$this->out->element('input', array('name' => 'design_sidebar',
|
||||
'type' => 'text',
|
||||
@ -636,6 +647,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$tcolor = new WebColor($design->textcolor);
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for text color selector.
|
||||
$this->out->element('label', array('for' => 'swatch-4'), _('Text'));
|
||||
$this->out->element('input', array('name' => 'design_text',
|
||||
'type' => 'text',
|
||||
@ -649,6 +661,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$lcolor = new WebColor($design->linkcolor);
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for link color selector.
|
||||
$this->out->element('label', array('for' => 'swatch-5'), _('Links'));
|
||||
$this->out->element('input', array('name' => 'design_links',
|
||||
'type' => 'text',
|
||||
@ -674,10 +687,12 @@ class DesignAdminPanelForm extends AdminForm
|
||||
{
|
||||
if (common_config('custom_css', 'enabled')) {
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_advanced'));
|
||||
// TRANS: Fieldset legend for advanced theme design settings.
|
||||
$this->out->element('legend', null, _('Advanced'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
// TRANS: Field label for custom CSS.
|
||||
$this->out->element('label', array('for' => 'css'), _('Custom CSS'));
|
||||
$this->out->element('textarea', array('name' => 'css',
|
||||
'id' => 'css',
|
||||
@ -699,17 +714,25 @@ class DesignAdminPanelForm extends AdminForm
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('defaults', _('Use defaults'), 'submit form_action-default',
|
||||
// TRANS: Button text for resetting theme settings.
|
||||
$this->out->submit('defaults', _m('BUTTON','Use defaults'), 'submit form_action-default',
|
||||
// TRANS: Title for button for resetting theme settings.
|
||||
'defaults', _('Restore default designs'));
|
||||
|
||||
$this->out->element('input', array('id' => 'settings_design_reset',
|
||||
'type' => 'reset',
|
||||
// TRANS: Button text for resetting theme settings.
|
||||
'value' => 'Reset',
|
||||
'class' => 'submit form_action-primary',
|
||||
// TRANS: Title for button for resetting theme settings.
|
||||
'title' => _('Reset back to default')));
|
||||
|
||||
$this->out->submit('save', _('Save'), 'submit form_action-secondary',
|
||||
'save', _('Save design'));
|
||||
$this->out->submit('save',
|
||||
// TRANS: Button text for saving theme settings.
|
||||
_m('BUTTON','Save'),
|
||||
'submit form_action-secondary',
|
||||
'save',
|
||||
// TRANS: Title for button for saving theme settings.
|
||||
_('Save design'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ class DisfavorAction extends Action
|
||||
{
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to remove a favorite while not logged in.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
@ -71,6 +72,7 @@ class DisfavorAction extends Action
|
||||
$notice = Notice::staticGet($id);
|
||||
$token = $this->trimmed('token-'.$notice->id);
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
@ -78,12 +80,14 @@ class DisfavorAction extends Action
|
||||
$fave->user_id = $user->id;
|
||||
$fave->notice_id = $notice->id;
|
||||
if (!$fave->find(true)) {
|
||||
// TRANS: Client error displayed when trying to remove favorite status for a notice that is not a favorite.
|
||||
$this->clientError(_('This notice is not a favorite!'));
|
||||
return;
|
||||
}
|
||||
$result = $fave->delete();
|
||||
if (!$result) {
|
||||
common_log_db_error($fave, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed when removing a favorite from the database fails.
|
||||
$this->serverError(_('Could not delete favorite.'));
|
||||
return;
|
||||
}
|
||||
@ -91,6 +95,7 @@ class DisfavorAction extends Action
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
// TRANS: Title for page on which favorites can be added.
|
||||
$this->element('title', null, _('Add to favorites'));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
@ -105,4 +110,3 @@ class DisfavorAction extends Action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Documentation action.
|
||||
*
|
||||
@ -83,7 +82,6 @@ class DocAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showPageTitle()
|
||||
{
|
||||
$this->element('h1', array('class' => 'entry-title'), $this->title());
|
||||
@ -96,7 +94,6 @@ class DocAction extends Action
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
|
||||
function showContentBlock()
|
||||
{
|
||||
$this->elementStart('div', array('id' => 'content', 'class' => 'hentry'));
|
||||
@ -117,7 +114,6 @@ class DocAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$this->raw($this->output);
|
||||
@ -142,7 +138,6 @@ class DocAction extends Action
|
||||
*
|
||||
* @return boolean read-only flag (false)
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -155,7 +150,9 @@ class DocAction extends Action
|
||||
$this->filename = $this->getFilename();
|
||||
|
||||
if (empty($this->filename)) {
|
||||
throw new ClientException(sprintf(_('No such document "%s"'), $this->title), 404);
|
||||
// TRANS: Client exception thrown when requesting a document from the documentation that does not exist.
|
||||
// TRANS: %s is the non-existing document.
|
||||
throw new ClientException(sprintf(_('No such document "%s".'), $this->title), 404);
|
||||
}
|
||||
|
||||
$c = file_get_contents($this->filename);
|
||||
|
@ -356,7 +356,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error updating e-mail preferences.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -423,7 +423,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'INSERT', __FILE__);
|
||||
// TRANS: Server error thrown on database error adding e-mail confirmation code.
|
||||
$this->serverError(_('Couldn\'t insert confirmation code.'));
|
||||
$this->serverError(_('Could not insert confirmation code.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error thrown on database error canceling e-mail address confirmation.
|
||||
$this->serverError(_('Couldn\'t delete email confirmation.'));
|
||||
$this->serverError(_('Could not delete email confirmation.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -505,7 +505,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
if (!$result) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error removing a registered e-mail address.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
$user->query('COMMIT');
|
||||
@ -537,7 +537,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
if (!$user->updateKeys($orig)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error removing incoming e-mail address.
|
||||
$this->serverError(_("Couldn't update user record."));
|
||||
$this->serverError(_("Could not update user record."));
|
||||
}
|
||||
|
||||
// TRANS: Message given after successfully removing an incoming e-mail address.
|
||||
@ -562,7 +562,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
if (!$user->updateKeys($orig)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error adding incoming e-mail address.
|
||||
$this->serverError(_("Couldn't update user record."));
|
||||
$this->serverError(_("Could not update user record."));
|
||||
}
|
||||
|
||||
// TRANS: Message given after successfully adding an incoming e-mail address.
|
||||
|
@ -263,7 +263,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||
$this->showForm(_('Couldn\'t update your design.'));
|
||||
$this->showForm(_('Could not update your design.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,6 @@ define('MAX_ORIGINAL', 480);
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class GrouplogoAction extends GroupDesignAction
|
||||
{
|
||||
var $mode = null;
|
||||
@ -67,6 +66,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to create a group while not logged in.
|
||||
$this->clientError(_('You must be logged in to create a group.'));
|
||||
return false;
|
||||
}
|
||||
@ -83,6 +83,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
}
|
||||
|
||||
if (!$nickname) {
|
||||
// TRANS: Client error displayed when trying to change group logo settings without having a nickname.
|
||||
$this->clientError(_('No nickname.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -99,6 +100,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
}
|
||||
|
||||
if (!$this->group) {
|
||||
// TRANS: Client error displayed when trying to update logo settings for a non-existing group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -106,6 +108,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
$cur = common_current_user();
|
||||
|
||||
if (!$cur->isAdmin($this->group)) {
|
||||
// TRANS: Client error displayed when trying to change group logo settings while not being a group admin.
|
||||
$this->clientError(_('You must be an admin to edit the group.'), 403);
|
||||
return false;
|
||||
}
|
||||
@ -136,9 +139,9 @@ class GrouplogoAction extends GroupDesignAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for group logo settings page.
|
||||
return _('Group logo');
|
||||
}
|
||||
|
||||
@ -147,9 +150,10 @@ class GrouplogoAction extends GroupDesignAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// TRANS: Instructions for group logo page.
|
||||
// TRANS: %s is the maximum file size for that site.
|
||||
return sprintf(_('You can upload a logo image for your group. The maximum file size is %s.'), ImageFile::maxFileSize());
|
||||
}
|
||||
|
||||
@ -160,7 +164,6 @@ class GrouplogoAction extends GroupDesignAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
if ($this->mode == 'crop') {
|
||||
@ -178,6 +181,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Server error displayed coming across a request from a user without a profile.
|
||||
$this->serverError(_('User without matching profile.'));
|
||||
return;
|
||||
}
|
||||
@ -192,6 +196,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
common_local_url('grouplogo',
|
||||
array('nickname' => $this->group->nickname))));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Group logo form legend.
|
||||
$this->element('legend', null, _('Group logo'));
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
@ -199,6 +204,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
if ($original) {
|
||||
$this->elementStart('li', array('id' => 'avatar_original',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Uploaded original file in group logo form.
|
||||
$this->element('h2', null, _("Original"));
|
||||
$this->elementStart('div', array('id'=>'avatar_original_view'));
|
||||
$this->element('img', array('src' => $this->group->original_logo,
|
||||
@ -210,6 +216,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
if ($this->group->homepage_logo) {
|
||||
$this->elementStart('li', array('id' => 'avatar_preview',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header for preview of to be displayed group logo.
|
||||
$this->element('h2', null, _("Preview"));
|
||||
$this->elementStart('div', array('id'=>'avatar_preview_view'));
|
||||
$this->element('img', array('src' => $this->group->homepage_logo,
|
||||
@ -233,6 +240,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
|
||||
$this->elementStart('ul', 'form_actions');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Submit button for uploading a group logo.
|
||||
$this->submit('upload', _('Upload'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
@ -251,6 +259,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
common_local_url('grouplogo',
|
||||
array('nickname' => $this->group->nickname))));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Legend for group logo settings fieldset.
|
||||
$this->element('legend', null, _('Avatar settings'));
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
@ -259,6 +268,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
$this->elementStart('li',
|
||||
array('id' => 'avatar_original',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header for originally uploaded file before a crop on the group logo page.
|
||||
$this->element('h2', null, _("Original"));
|
||||
$this->elementStart('div', array('id'=>'avatar_original_view'));
|
||||
$this->element('img', array('src' => Avatar::url($this->filedata['filename']),
|
||||
@ -271,6 +281,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
$this->elementStart('li',
|
||||
array('id' => 'avatar_preview',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header for the cropped group logo on the group logo page.
|
||||
$this->element('h2', null, _("Preview"));
|
||||
$this->elementStart('div', array('id'=>'avatar_preview_view'));
|
||||
$this->element('img', array('src' => Avatar::url($this->filedata['filename']),
|
||||
@ -286,6 +297,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
'id' => $crop_info));
|
||||
}
|
||||
|
||||
// TRANS: Button text for cropping an uploaded group logo.
|
||||
$this->submit('crop', _('Crop'));
|
||||
|
||||
$this->elementEnd('li');
|
||||
@ -302,13 +314,13 @@ class GrouplogoAction extends GroupDesignAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
// CSRF protection
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Form validation error message.
|
||||
$this->show_form(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
@ -319,6 +331,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
} else if ($this->arg('crop')) {
|
||||
$this->cropLogo();
|
||||
} else {
|
||||
// TRANS: Form validation error message when an unsupported argument is used.
|
||||
$this->showForm(_('Unexpected form submission.'));
|
||||
}
|
||||
}
|
||||
@ -331,7 +344,6 @@ class GrouplogoAction extends GroupDesignAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function uploadLogo()
|
||||
{
|
||||
try {
|
||||
@ -341,20 +353,21 @@ class GrouplogoAction extends GroupDesignAction
|
||||
return;
|
||||
}
|
||||
|
||||
$type = $imagefile->preferredType();
|
||||
$filename = Avatar::filename($this->group->id,
|
||||
image_type_to_extension($imagefile->type),
|
||||
image_type_to_extension($type),
|
||||
null,
|
||||
'group-temp-'.common_timestamp());
|
||||
|
||||
$filepath = Avatar::path($filename);
|
||||
|
||||
move_uploaded_file($imagefile->filepath, $filepath);
|
||||
$imagefile->copyTo($filepath);
|
||||
|
||||
$filedata = array('filename' => $filename,
|
||||
'filepath' => $filepath,
|
||||
'width' => $imagefile->width,
|
||||
'height' => $imagefile->height,
|
||||
'type' => $imagefile->type);
|
||||
'type' => $type);
|
||||
|
||||
$_SESSION['FILEDATA'] = $filedata;
|
||||
|
||||
@ -362,6 +375,7 @@ class GrouplogoAction extends GroupDesignAction
|
||||
|
||||
$this->mode = 'crop';
|
||||
|
||||
// TRANS: Form instructions on the group logo page.
|
||||
$this->showForm(_('Pick a square area of the image to be the logo.'),
|
||||
true);
|
||||
}
|
||||
@ -371,12 +385,12 @@ class GrouplogoAction extends GroupDesignAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function cropLogo()
|
||||
{
|
||||
$filedata = $_SESSION['FILEDATA'];
|
||||
|
||||
if (!$filedata) {
|
||||
// TRANS: Server error displayed trying to crop an uploaded group logo that is no longer present.
|
||||
$this->serverError(_('Lost our file data.'));
|
||||
return;
|
||||
}
|
||||
@ -396,8 +410,10 @@ class GrouplogoAction extends GroupDesignAction
|
||||
@unlink($filedata['filepath']);
|
||||
unset($_SESSION['FILEDATA']);
|
||||
$this->mode = 'upload';
|
||||
// TRANS: Form success message after updating a group logo.
|
||||
$this->showForm(_('Logo updated.'), true);
|
||||
} else {
|
||||
// TRANS: Form failure message after failing to update a group logo.
|
||||
$this->showForm(_('Failed updating logo.'));
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ require_once INSTALLDIR.'/lib/jabber.php';
|
||||
*
|
||||
* @see SettingsAction
|
||||
*/
|
||||
|
||||
class ImsettingsAction extends ConnectSettingsAction
|
||||
{
|
||||
/**
|
||||
@ -53,7 +52,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for instance messaging settings.
|
||||
@ -65,7 +63,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// TRANS: Instant messaging settings page instructions.
|
||||
@ -85,7 +82,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
if (!common_config('xmpp', 'enabled')) {
|
||||
@ -194,7 +190,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return Confirm_address address object for this user
|
||||
*/
|
||||
|
||||
function getConfirmation()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -221,7 +216,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
// CSRF protection
|
||||
@ -254,7 +248,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function savePreferences()
|
||||
{
|
||||
$jabbernotify = $this->boolean('jabbernotify');
|
||||
@ -280,7 +273,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error updating IM preferences.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -298,7 +291,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addAddress()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -348,7 +340,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'INSERT', __FILE__);
|
||||
// TRANS: Server error thrown on database error adding IM confirmation code.
|
||||
$this->serverError(_('Couldn\'t insert confirmation code.'));
|
||||
$this->serverError(_('Could not insert confirmation code.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -374,7 +366,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function cancelConfirmation()
|
||||
{
|
||||
$jabber = $this->arg('jabber');
|
||||
@ -397,7 +388,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error thrown on database error canceling IM address confirmation.
|
||||
$this->serverError(_('Couldn\'t delete IM confirmation.'));
|
||||
$this->serverError(_('Could not delete IM confirmation.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -412,7 +403,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function removeAddress()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -439,7 +429,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
if (!$result) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error removing a registered IM address.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
$user->query('COMMIT');
|
||||
@ -459,7 +449,6 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return boolean whether the Jabber ID exists
|
||||
*/
|
||||
|
||||
function jabberExists($jabber)
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class JoingroupAction extends Action
|
||||
{
|
||||
var $group = null;
|
||||
@ -51,12 +50,12 @@ class JoingroupAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to join a group while not logged in.
|
||||
$this->clientError(_('You must be logged in to join a group.'));
|
||||
return false;
|
||||
}
|
||||
@ -79,17 +78,20 @@ class JoingroupAction extends Action
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$local) {
|
||||
// TRANS: Client error displayed when trying to join a non-local group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->group = User_group::staticGet('id', $local->group_id);
|
||||
} else {
|
||||
// TRANS: Client error displayed when trying to join a group without providing a group name or group ID.
|
||||
$this->clientError(_('No nickname or ID.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->group) {
|
||||
// TRANS: Client error displayed when trying to join a non-existing group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -97,11 +99,13 @@ class JoingroupAction extends Action
|
||||
$cur = common_current_user();
|
||||
|
||||
if ($cur->isMember($this->group)) {
|
||||
// TRANS: Client error displayed when trying to join a group while already a member.
|
||||
$this->clientError(_('You are already a member of that group.'), 403);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Group_block::isBlocked($this->group, $cur->getProfile())) {
|
||||
// TRANS: Client error displayed when trying to join a group while being blocked form joining it.
|
||||
$this->clientError(_('You have been blocked from that group by the admin.'), 403);
|
||||
return false;
|
||||
}
|
||||
@ -118,7 +122,6 @@ class JoingroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -131,6 +134,8 @@ class JoingroupAction extends Action
|
||||
Event::handle('EndJoinGroup', array($this->group, $cur));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// TRANS: Server error displayed when joining a group failed in the database.
|
||||
// TRANS: %1$s is the joining user's nickname, $2$s is the group nickname for which the join failed.
|
||||
$this->serverError(sprintf(_('Could not join user %1$s to group %2$s.'),
|
||||
$cur->nickname, $this->group->nickname));
|
||||
}
|
||||
@ -138,7 +143,8 @@ class JoingroupAction extends Action
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
$this->element('title', null, sprintf(_('%1$s joined group %2$s'),
|
||||
// TRANS: Title for join group page after joining.
|
||||
$this->element('title', null, sprintf(_m('TITLE','%1$s joined group %2$s'),
|
||||
$cur->nickname,
|
||||
$this->group->nickname));
|
||||
$this->elementEnd('head');
|
||||
|
@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class LeavegroupAction extends Action
|
||||
{
|
||||
var $group = null;
|
||||
@ -51,12 +50,12 @@ class LeavegroupAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to leave a group while not logged in.
|
||||
$this->clientError(_('You must be logged in to leave a group.'));
|
||||
return false;
|
||||
}
|
||||
@ -79,17 +78,20 @@ class LeavegroupAction extends Action
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$local) {
|
||||
// TRANS: Client error displayed when trying to leave a non-local group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->group = User_group::staticGet('id', $local->group_id);
|
||||
} else {
|
||||
// TRANS: Client error displayed when trying to leave a group without providing a group name or group ID.
|
||||
$this->clientError(_('No nickname or ID.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->group) {
|
||||
// TRANS: Client error displayed when trying to leave a non-existing group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -97,6 +99,7 @@ class LeavegroupAction extends Action
|
||||
$cur = common_current_user();
|
||||
|
||||
if (!$cur->isMember($this->group)) {
|
||||
// TRANS: Client error displayed when trying to join a group while already a member.
|
||||
$this->clientError(_('You are not a member of that group.'), 403);
|
||||
return false;
|
||||
}
|
||||
@ -113,7 +116,6 @@ class LeavegroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -126,6 +128,8 @@ class LeavegroupAction extends Action
|
||||
Event::handle('EndLeaveGroup', array($this->group, $cur));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// TRANS: Server error displayed when leaving a group failed in the database.
|
||||
// TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed.
|
||||
$this->serverError(sprintf(_('Could not remove user %1$s from group %2$s.'),
|
||||
$cur->nickname, $this->group->nickname));
|
||||
return;
|
||||
@ -134,7 +138,8 @@ class LeavegroupAction extends Action
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
$this->element('title', null, sprintf(_('%1$s left group %2$s'),
|
||||
// TRANS: Title for leave group page after leaving.
|
||||
$this->element('title', null, sprintf(_m('TITLE','%1$s left group %2$s'),
|
||||
$cur->nickname,
|
||||
$this->group->nickname));
|
||||
$this->elementEnd('head');
|
||||
|
@ -40,7 +40,6 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class LicenseadminpanelAction extends AdminPanelAction
|
||||
{
|
||||
|
||||
@ -61,7 +60,6 @@ class LicenseadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return string instructions
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('License for this StatusNet site');
|
||||
@ -72,7 +70,6 @@ class LicenseadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showForm()
|
||||
{
|
||||
$form = new LicenseAdminPanelForm($this);
|
||||
@ -85,7 +82,6 @@ class LicenseadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
static $settings = array(
|
||||
@ -128,7 +124,6 @@ class LicenseadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function validate(&$values)
|
||||
{
|
||||
// Validate license type (shouldn't have to do it, but just in case)
|
||||
@ -197,7 +192,6 @@ class LicenseAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return int ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
return 'licenseadminpanel';
|
||||
@ -208,7 +202,6 @@ class LicenseAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return string class of the form
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_settings';
|
||||
@ -312,7 +305,6 @@ class LicenseAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit(
|
||||
|
@ -200,8 +200,6 @@ class NewgroupAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$mainpage = common_local_url('showgroup', array('nickname' => $nickname));
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
// Checked in prepare() above
|
||||
@ -215,7 +213,6 @@ class NewgroupAction extends Action
|
||||
'location' => $location,
|
||||
'aliases' => $aliases,
|
||||
'userid' => $cur->id,
|
||||
'mainpage' => $mainpage,
|
||||
'local' => true));
|
||||
|
||||
common_redirect($group->homeUrl(), 303);
|
||||
|
@ -181,7 +181,7 @@ class OthersettingsAction extends AccountSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed when "Other" settings in user profile could not be updated on the server.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@ require_once INSTALLDIR.'/lib/accountsettingsaction.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ProfilesettingsAction extends AccountSettingsAction
|
||||
{
|
||||
/**
|
||||
@ -54,7 +53,6 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Page title for profile settings.
|
||||
@ -66,7 +64,6 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// TRANS: Usage instructions for profile settings.
|
||||
@ -87,7 +84,6 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -212,12 +208,12 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Form validation error.
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
@ -323,7 +319,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown when user profile settings could not be updated.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
} else {
|
||||
// Re-initialize language environment if it changed
|
||||
@ -348,7 +344,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown when user profile settings could not be updated to
|
||||
// TRANS: automatically subscribe to any subscriber.
|
||||
$this->serverError(_('Couldn\'t update user for autosubscribe.'));
|
||||
$this->serverError(_('Could not update user for autosubscribe.'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -406,7 +402,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($prefs, ($exists) ? 'UPDATE' : 'INSERT', __FILE__);
|
||||
// TRANS: Server error thrown when user profile location preference settings could not be updated.
|
||||
$this->serverError(_('Couldn\'t save location prefs.'));
|
||||
$this->serverError(_('Could not save location prefs.'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -419,7 +415,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($profile, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown when user profile settings could not be saved.
|
||||
$this->serverError(_('Couldn\'t save profile.'));
|
||||
$this->serverError(_('Could not save profile.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -428,7 +424,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
|
||||
if (!$result) {
|
||||
// TRANS: Server error thrown when user profile settings tags could not be saved.
|
||||
$this->serverError(_('Couldn\'t save tags.'));
|
||||
$this->serverError(_('Could not save tags.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -458,12 +454,16 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
|
||||
$this->elementStart('div', array('id' => 'aside_primary',
|
||||
'class' => 'aside'));
|
||||
|
||||
$this->elementStart('div', array('id' => 'account_actions',
|
||||
'class' => 'section'));
|
||||
$this->elementStart('ul');
|
||||
if (Event::handle('StartProfileSettingsActions', array($this))) {
|
||||
if ($user->hasRight(Right::BACKUPACCOUNT)) {
|
||||
$this->elementStart('li');
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('backupaccount')),
|
||||
// TRANS: Option in profile settings to create a backup of the account of the currently logged in user.
|
||||
_('Backup account'));
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
@ -471,6 +471,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
$this->elementStart('li');
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('deleteaccount')),
|
||||
// TRANS: Option in profile settings to delete the account of the currently logged in user.
|
||||
_('Delete account'));
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
@ -478,6 +479,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
$this->elementStart('li');
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('restoreaccount')),
|
||||
// TRANS: Option in profile settings to restore the account of the currently logged in user from a backup.
|
||||
_('Restore account'));
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
@ -485,5 +487,6 @@ class ProfilesettingsAction extends AccountSettingsAction
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('div');
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ class RecoverpasswordAction extends Action
|
||||
{
|
||||
parent::handle($args);
|
||||
if (common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to recover password while already logged in.
|
||||
$this->clientError(_('You are already logged in!'));
|
||||
return;
|
||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
@ -41,6 +42,7 @@ class RecoverpasswordAction extends Action
|
||||
} else if ($this->arg('reset')) {
|
||||
$this->resetPassword();
|
||||
} else {
|
||||
// TRANS: Client error displayed when unexpected data is posted in the password recovery form.
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
}
|
||||
} else {
|
||||
@ -54,15 +56,16 @@ class RecoverpasswordAction extends Action
|
||||
|
||||
function checkCode()
|
||||
{
|
||||
|
||||
$code = $this->trimmed('code');
|
||||
$confirm = Confirm_address::staticGet('code', $code);
|
||||
|
||||
if (!$confirm) {
|
||||
// TRANS: Client error displayed when password recovery code is not correct.
|
||||
$this->clientError(_('No such recovery code.'));
|
||||
return;
|
||||
}
|
||||
if ($confirm->address_type != 'recover') {
|
||||
// TRANS: Client error displayed when no proper password recovery code was submitted.
|
||||
$this->clientError(_('Not a recovery code.'));
|
||||
return;
|
||||
}
|
||||
@ -70,6 +73,7 @@ class RecoverpasswordAction extends Action
|
||||
$user = User::staticGet($confirm->user_id);
|
||||
|
||||
if (!$user) {
|
||||
// TRANS: Server error displayed trying to recover password without providing a user.
|
||||
$this->serverError(_('Recovery code for unknown user.'));
|
||||
return;
|
||||
}
|
||||
@ -83,6 +87,7 @@ class RecoverpasswordAction extends Action
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed removing a password recovery code from the database.
|
||||
$this->serverError(_('Error with confirmation code.'));
|
||||
return;
|
||||
}
|
||||
@ -94,6 +99,7 @@ class RecoverpasswordAction extends Action
|
||||
common_log(LOG_WARNING,
|
||||
'Attempted redemption on recovery code ' .
|
||||
'that is ' . $touched . ' seconds old. ');
|
||||
// TRANS: Client error displayed trying to recover password with too old a recovery code.
|
||||
$this->clientError(_('This confirmation code is too old. ' .
|
||||
'Please start again.'));
|
||||
return;
|
||||
@ -108,6 +114,7 @@ class RecoverpasswordAction extends Action
|
||||
$result = $user->updateKeys($orig);
|
||||
if (!$result) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed when updating a user's e-mail address in the database fails while recovering a password.
|
||||
$this->serverError(_('Could not update user with confirmed email address.'));
|
||||
return;
|
||||
}
|
||||
@ -149,14 +156,16 @@ class RecoverpasswordAction extends Action
|
||||
$this->elementStart('div', 'instructions');
|
||||
if ($this->mode == 'recover') {
|
||||
$this->element('p', null,
|
||||
// TRANS: Page notice for password recovery page.
|
||||
_('If you have forgotten or lost your' .
|
||||
' password, you can get a new one sent to' .
|
||||
' the email address you have stored' .
|
||||
' in your account.'));
|
||||
} else if ($this->mode == 'reset') {
|
||||
// TRANS: Page notice for password change page.
|
||||
$this->element('p', null,
|
||||
_('You have been identified. Enter a' .
|
||||
' new password below. '));
|
||||
' new password below.'));
|
||||
}
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
@ -185,19 +194,24 @@ class RecoverpasswordAction extends Action
|
||||
'class' => 'form_settings',
|
||||
'action' => common_local_url('recoverpassword')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Fieldset legend for password recovery page.
|
||||
$this->element('legend', null, _('Password recovery'));
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label on password recovery page.
|
||||
$this->input('nicknameoremail', _('Nickname or email address'),
|
||||
$this->trimmed('nicknameoremail'),
|
||||
// TRANS: Title for field label on password recovery page.
|
||||
_('Your nickname on this server, ' .
|
||||
'or your registered email address.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
$this->element('input', array('name' => 'recover',
|
||||
'type' => 'hidden',
|
||||
// TRANS: Field label on password recovery page.
|
||||
'value' => _('Recover')));
|
||||
$this->submit('recover', _('Recover'));
|
||||
// TRANS: Button text on password recovery page.
|
||||
$this->submit('recover', _m('BUTTON','Recover'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
@ -205,11 +219,16 @@ class RecoverpasswordAction extends Action
|
||||
function title()
|
||||
{
|
||||
switch ($this->mode) {
|
||||
// TRANS: Title for password recovery page in password reset mode.
|
||||
case 'reset': return _('Reset password');
|
||||
// TRANS: Title for password recovery page in password recover mode.
|
||||
case 'recover': return _('Recover password');
|
||||
// TRANS: Title for password recovery page in email sent mode.
|
||||
case 'sent': return _('Password recovery requested');
|
||||
// TRANS: Title for password recovery page in password saved mode.
|
||||
case 'saved': return _('Password saved.');
|
||||
default:
|
||||
// TRANS: Title for password recovery page when an unknown action has been specified.
|
||||
return _('Unknown action');
|
||||
}
|
||||
}
|
||||
@ -228,19 +247,25 @@ class RecoverpasswordAction extends Action
|
||||
'class' => 'form_settings',
|
||||
'action' => common_local_url('recoverpassword')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Fieldset legend for password reset form.
|
||||
$this->element('legend', null, _('Password change'));
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for password reset form.
|
||||
$this->password('newpassword', _('New password'),
|
||||
_('6 or more characters, and don\'t forget it!'));
|
||||
// TRANS: Title for field label for password reset form.
|
||||
_('6 or more characters, and do not forget it!'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for password reset form where the password has to be typed again.
|
||||
$this->password('confirm', _('Confirm'),
|
||||
_('Same as password above'));
|
||||
// TRANS: Ttile for field label for password reset form where the password has to be typed again.
|
||||
_('Same as password above.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
$this->submit('reset', _('Reset'));
|
||||
// TRANS: Button text for password reset form.
|
||||
$this->submit('reset', _m('BUTTON','Reset'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
@ -249,6 +274,7 @@ class RecoverpasswordAction extends Action
|
||||
{
|
||||
$nore = $this->trimmed('nicknameoremail');
|
||||
if (!$nore) {
|
||||
// TRANS: Form instructions for password recovery form.
|
||||
$this->showForm(_('Enter a nickname or email address.'));
|
||||
return;
|
||||
}
|
||||
@ -279,6 +305,7 @@ class RecoverpasswordAction extends Action
|
||||
}
|
||||
|
||||
if (!$user) {
|
||||
// TRANS: Information on password recovery form if no known username or e-mail address was specified.
|
||||
$this->showForm(_('No user with that email address or username.'));
|
||||
return;
|
||||
}
|
||||
@ -296,6 +323,7 @@ class RecoverpasswordAction extends Action
|
||||
}
|
||||
|
||||
if (!$user->email && !$confirm_email) {
|
||||
// TRANS: Client error displayed on password recovery form if a user does not have a registered e-mail address.
|
||||
$this->clientError(_('No registered email address for that user.'));
|
||||
return;
|
||||
}
|
||||
@ -310,10 +338,12 @@ class RecoverpasswordAction extends Action
|
||||
|
||||
if (!$confirm->insert()) {
|
||||
common_log_db_error($confirm, 'INSERT', __FILE__);
|
||||
// TRANS: Server error displayed if e-mail address confirmation fails in the database on the password recovery form.
|
||||
$this->serverError(_('Error saving address confirmation.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo FIXME: needs i18n.
|
||||
$body = "Hey, $user->nickname.";
|
||||
$body .= "\n\n";
|
||||
$body .= 'Someone just asked for a new password ' .
|
||||
@ -332,9 +362,11 @@ class RecoverpasswordAction extends Action
|
||||
$body .= "\n";
|
||||
|
||||
$headers = _mail_prepare_headers('recoverpassword', $user->nickname, $user->nickname);
|
||||
// TRANS: Subject for password recovery e-mail.
|
||||
mail_to_user($user, _('Password recovery requested'), $body, $headers, $confirm->address);
|
||||
|
||||
$this->mode = 'sent';
|
||||
// TRANS: User notification after an e-mail with instructions was sent from the password recovery form.
|
||||
$this->msg = _('Instructions for recovering your password ' .
|
||||
'have been sent to the email address registered to your ' .
|
||||
'account.');
|
||||
@ -347,6 +379,7 @@ class RecoverpasswordAction extends Action
|
||||
# CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Form validation error message.
|
||||
$this->showForm(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
@ -354,6 +387,7 @@ class RecoverpasswordAction extends Action
|
||||
$user = $this->getTempUser();
|
||||
|
||||
if (!$user) {
|
||||
// TRANS: Client error displayed when trying to reset as password without providing a user.
|
||||
$this->clientError(_('Unexpected password reset.'));
|
||||
return;
|
||||
}
|
||||
@ -362,10 +396,12 @@ class RecoverpasswordAction extends Action
|
||||
$confirm = $this->trimmed('confirm');
|
||||
|
||||
if (!$newpassword || strlen($newpassword) < 6) {
|
||||
// TRANS: Reset password form validation error message.
|
||||
$this->showPasswordForm(_('Password must be 6 characters or more.'));
|
||||
return;
|
||||
}
|
||||
if ($newpassword != $confirm) {
|
||||
// TRANS: Reset password form validation error message.
|
||||
$this->showPasswordForm(_('Password and confirmation do not match.'));
|
||||
return;
|
||||
}
|
||||
@ -378,13 +414,15 @@ class RecoverpasswordAction extends Action
|
||||
|
||||
if (!$user->update($original)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
$this->serverError(_('Can\'t save new password.'));
|
||||
// TRANS: Reset password form validation error message.
|
||||
$this->serverError(_('Cannot save new password.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->clearTempUser();
|
||||
|
||||
if (!common_set_user($user->nickname)) {
|
||||
// TRANS: Server error displayed when something does wrong with the user object during password reset.
|
||||
$this->serverError(_('Error setting user.'));
|
||||
return;
|
||||
}
|
||||
@ -392,6 +430,7 @@ class RecoverpasswordAction extends Action
|
||||
common_real_login(true);
|
||||
|
||||
$this->mode = 'saved';
|
||||
// TRANS: Success message for user after password reset.
|
||||
$this->msg = _('New password successfully saved. ' .
|
||||
'You are now logged in.');
|
||||
$this->success = true;
|
||||
|
@ -430,16 +430,15 @@ class RegisterAction extends Action
|
||||
if (Event::handle('StartRegistrationFormData', array($this))) {
|
||||
$this->elementStart('li');
|
||||
$this->input('nickname', _('Nickname'), $this->trimmed('nickname'),
|
||||
_('1-64 lowercase letters or numbers, '.
|
||||
'no punctuation or spaces. Required.'));
|
||||
_('1-64 lowercase letters or numbers, no punctuation or spaces.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->password('password', _('Password'),
|
||||
_('6 or more characters. Required.'));
|
||||
_('6 or more characters.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->password('confirm', _('Confirm'),
|
||||
_('Same as password above. Required.'));
|
||||
_('Same as password above.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
if ($this->invite && $this->invite->address_type == 'email') {
|
||||
|
@ -44,7 +44,6 @@ require_once INSTALLDIR.'/extlib/libomb/profile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class RemotesubscribeAction extends Action
|
||||
{
|
||||
var $nickname;
|
||||
@ -173,14 +172,14 @@ class RemotesubscribeAction extends Action
|
||||
if ($service->getServiceURI(OAUTH_ENDPOINT_REQUEST) ==
|
||||
common_local_url('requesttoken') ||
|
||||
User::staticGet('uri', $service->getRemoteUserURI())) {
|
||||
$this->showForm(_('That’s a local profile! Login to subscribe.'));
|
||||
$this->showForm(_('That is a local profile! Login to subscribe.'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$service->requestToken();
|
||||
} catch (OMB_RemoteServiceException $e) {
|
||||
$this->showForm(_('Couldn’t get a request token.'));
|
||||
$this->showForm(_('Could not get a request token.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,4 +203,3 @@ class RemotesubscribeAction extends Action
|
||||
common_redirect($target_url, 303);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -41,7 +41,6 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class RepeatAction extends Action
|
||||
{
|
||||
var $user = null;
|
||||
@ -73,7 +72,7 @@ class RepeatAction extends Action
|
||||
}
|
||||
|
||||
if ($this->user->id == $this->notice->profile_id) {
|
||||
$this->clientError(_("You can't repeat your own notice."));
|
||||
$this->clientError(_("You cannot repeat your own notice."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -101,7 +100,6 @@ class RepeatAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
$repeat = $this->notice->repeat($this->user->id, 'web');
|
||||
|
@ -44,7 +44,6 @@ require_once INSTALLDIR.'/lib/connectsettingsaction.php';
|
||||
*
|
||||
* @see SettingsAction
|
||||
*/
|
||||
|
||||
class SmssettingsAction extends ConnectSettingsAction
|
||||
{
|
||||
/**
|
||||
@ -52,7 +51,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for SMS settings.
|
||||
@ -64,7 +62,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// XXX: For consistency of parameters in messages, this should be a
|
||||
@ -88,7 +85,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
if (!common_config('sms', 'enabled')) {
|
||||
@ -219,7 +215,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @todo very similar to EmailsettingsAction::getConfirmation(); refactor?
|
||||
*/
|
||||
|
||||
function getConfirmation()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -246,7 +241,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
// CSRF protection
|
||||
@ -285,7 +279,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function savePreferences()
|
||||
{
|
||||
$smsnotify = $this->boolean('smsnotify');
|
||||
@ -305,7 +298,7 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error updating SMS preferences.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -323,7 +316,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addAddress()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -370,7 +362,7 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'INSERT', __FILE__);
|
||||
// TRANS: Server error thrown on database error adding SMS confirmation code.
|
||||
$this->serverError(_('Couldn\'t insert confirmation code.'));
|
||||
$this->serverError(_('Could not insert confirmation code.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -395,7 +387,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function cancelConfirmation()
|
||||
{
|
||||
$sms = $this->trimmed('sms');
|
||||
@ -419,7 +410,7 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error thrown on database error canceling SMS phone number confirmation.
|
||||
$this->serverError(_('Couldn\'t delete email confirmation.'));
|
||||
$this->serverError(_('Could not delete email confirmation.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -432,7 +423,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function removeAddress()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -461,7 +451,7 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
if (!$result) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error removing a registered SMS phone number.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
$user->query('COMMIT');
|
||||
@ -479,7 +469,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return boolean does the number exist
|
||||
*/
|
||||
|
||||
function smsExists($sms)
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -498,7 +487,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function carrierSelect()
|
||||
{
|
||||
$carrier = new Sms_carrier();
|
||||
@ -538,7 +526,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function confirmCode()
|
||||
{
|
||||
$code = $this->trimmed('code');
|
||||
@ -559,7 +546,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function removeIncoming()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -575,7 +561,7 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
|
||||
if (!$user->updateKeys($orig)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
$this->serverError(_("Couldn't update user record."));
|
||||
$this->serverError(_("Could not update user record."));
|
||||
}
|
||||
|
||||
$this->showForm(_('Incoming email address removed.'), true);
|
||||
@ -588,7 +574,6 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
*
|
||||
* @see Emailsettings::newIncoming
|
||||
*/
|
||||
|
||||
function newIncoming()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -599,7 +584,7 @@ class SmssettingsAction extends ConnectSettingsAction
|
||||
|
||||
if (!$user->updateKeys($orig)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
$this->serverError(_("Couldn't update user record."));
|
||||
$this->serverError(_("Could not update user record."));
|
||||
}
|
||||
|
||||
$this->showForm(_('New incoming email address added.'), true);
|
||||
|
@ -100,8 +100,6 @@ class SubscribersAction extends GalleryAction
|
||||
}
|
||||
}
|
||||
|
||||
$subscribers->free();
|
||||
|
||||
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
||||
$this->page, 'subscribers',
|
||||
array('nickname' => $this->user->nickname));
|
||||
|
@ -106,8 +106,6 @@ class SubscriptionsAction extends GalleryAction
|
||||
}
|
||||
}
|
||||
|
||||
$subscriptions->free();
|
||||
|
||||
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
||||
$this->page, 'subscriptions',
|
||||
array('nickname' => $this->user->nickname));
|
||||
|
@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/designsettings.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class UserDesignSettingsAction extends DesignSettingsAction
|
||||
{
|
||||
/**
|
||||
@ -70,7 +69,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
return _('Profile design');
|
||||
@ -81,7 +79,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Customize the way your profile looks ' .
|
||||
@ -93,7 +90,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
*
|
||||
* @return Design
|
||||
*/
|
||||
|
||||
function getWorkingDesign()
|
||||
{
|
||||
$user = common_current_user();
|
||||
@ -108,7 +104,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$design = $this->getWorkingDesign();
|
||||
@ -125,7 +120,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveDesign()
|
||||
{
|
||||
foreach ($this->args as $key => $val) {
|
||||
@ -168,7 +162,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
$design = $user->getDesign();
|
||||
|
||||
if (!empty($design)) {
|
||||
|
||||
$original = clone($design);
|
||||
|
||||
$design->backgroundcolor = $bgcolor->intValue();
|
||||
@ -183,13 +176,11 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||
$this->showForm(_('Couldn\'t update your design.'));
|
||||
$this->showForm(_('Could not update your design.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// update design
|
||||
} else {
|
||||
|
||||
$user->query('BEGIN');
|
||||
|
||||
// save new design
|
||||
@ -236,7 +227,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function sethd()
|
||||
{
|
||||
|
||||
@ -281,5 +271,4 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
||||
|
||||
$this->showForm(_('Enjoy your hotdog!'), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -819,9 +819,18 @@ class Notice extends Memcached_DataObject
|
||||
|
||||
// Exclude any deleted, non-local, or blocking recipients.
|
||||
$profile = $this->getProfile();
|
||||
$originalProfile = null;
|
||||
if ($this->repeat_of) {
|
||||
// Check blocks against the original notice's poster as well.
|
||||
$original = Notice::staticGet('id', $this->repeat_of);
|
||||
if ($original) {
|
||||
$originalProfile = $original->getProfile();
|
||||
}
|
||||
}
|
||||
foreach ($ni as $id => $source) {
|
||||
$user = User::staticGet('id', $id);
|
||||
if (empty($user) || $user->hasBlocked($profile)) {
|
||||
if (empty($user) || $user->hasBlocked($profile) ||
|
||||
($originalProfile && $user->hasBlocked($originalProfile))) {
|
||||
unset($ni[$id]);
|
||||
}
|
||||
}
|
||||
|
@ -487,6 +487,7 @@ class User_group extends Memcached_DataObject
|
||||
}
|
||||
|
||||
// MAGICALLY put fields into current scope
|
||||
// @fixme kill extract(); it makes debugging absurdly hard
|
||||
|
||||
extract($fields);
|
||||
|
||||
@ -498,6 +499,9 @@ class User_group extends Memcached_DataObject
|
||||
// fill in later...
|
||||
$uri = null;
|
||||
}
|
||||
if (empty($mainpage)) {
|
||||
$mainpage = common_local_url('showgroup', array('nickname' => $nickname));
|
||||
}
|
||||
|
||||
$group->nickname = $nickname;
|
||||
$group->fullname = $fullname;
|
||||
|
@ -78,4 +78,5 @@ VALUES
|
||||
('twitvim','TwitVim','http://vim.sourceforge.net/scripts/script.php?script_id=2204', now()),
|
||||
('Updating.Me','Updating.Me','http://updating.me/', now()),
|
||||
('urfastr','urfastr','http://urfastr.net/', now()),
|
||||
('yatca','Yatca','http://www.yatca.com/', now());
|
||||
('yatca','Yatca','http://www.yatca.com/', now()),
|
||||
('rss.me', 'rss.me', 'http://rss.me/', now());
|
||||
|
147
lib/accountmover.php
Normal file
147
lib/accountmover.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* A class for moving an account to a new server
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @category Account
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an account from this server to another
|
||||
*
|
||||
* @category Account
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AccountMover extends QueueHandler
|
||||
{
|
||||
function transport()
|
||||
{
|
||||
return 'acctmove';
|
||||
}
|
||||
|
||||
function handle($object)
|
||||
{
|
||||
list($user, $remote, $password) = $object;
|
||||
|
||||
$remote = Discovery::normalize($remote);
|
||||
|
||||
$oprofile = Ostatus_profile::ensureProfileURI($remote);
|
||||
|
||||
if (empty($oprofile)) {
|
||||
throw new Exception("Can't locate account {$remote}");
|
||||
}
|
||||
|
||||
list($svcDocUrl, $username) = self::getServiceDocument($remote);
|
||||
|
||||
$sink = new ActivitySink($svcDocUrl, $username, $password);
|
||||
|
||||
$this->log(LOG_INFO,
|
||||
"Moving user {$user->nickname} ".
|
||||
"to {$remote}.");
|
||||
|
||||
$stream = new UserActivityStream($user);
|
||||
|
||||
// Reverse activities to run in correct chron order
|
||||
|
||||
$acts = array_reverse($stream->activities);
|
||||
|
||||
$this->log(LOG_INFO,
|
||||
"Got ".count($acts)." activities ".
|
||||
"for {$user->nickname}.");
|
||||
|
||||
$qm = QueueManager::get();
|
||||
|
||||
foreach ($acts as $act) {
|
||||
$qm->enqueue(array($act, $sink, $user->uri, $remote), 'actmove');
|
||||
}
|
||||
|
||||
$this->log(LOG_INFO,
|
||||
"Finished moving user {$user->nickname} ".
|
||||
"to {$remote}.");
|
||||
}
|
||||
|
||||
static function getServiceDocument($remote)
|
||||
{
|
||||
$discovery = new Discovery();
|
||||
|
||||
$xrd = $discovery->lookup($remote);
|
||||
|
||||
if (empty($xrd)) {
|
||||
throw new Exception("Can't find XRD for $remote");
|
||||
}
|
||||
|
||||
$svcDocUrl = null;
|
||||
$username = null;
|
||||
|
||||
foreach ($xrd->links as $link) {
|
||||
if ($link['rel'] == 'http://apinamespace.org/atom' &&
|
||||
$link['type'] == 'application/atomsvc+xml') {
|
||||
$svcDocUrl = $link['href'];
|
||||
if (!empty($link['property'])) {
|
||||
foreach ($link['property'] as $property) {
|
||||
if ($property['type'] == 'http://apinamespace.org/atom/username') {
|
||||
$username = $property['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($svcDocUrl)) {
|
||||
throw new Exception("No AtomPub API service for $remote.");
|
||||
}
|
||||
|
||||
return array($svcDocUrl, $username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log some data
|
||||
*
|
||||
* Add a header for our class so we know who did it.
|
||||
*
|
||||
* @param int $level Log level, like LOG_ERR or LOG_INFO
|
||||
* @param string $message Message to log
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
protected function log($level, $message)
|
||||
{
|
||||
common_log($level, "AccountMover: " . $message);
|
||||
}
|
||||
}
|
@ -96,7 +96,7 @@ class AccountSettingsNav extends Widget
|
||||
$action_name = $this->action->trimmed('action');
|
||||
$this->action->elementStart('ul', array('class' => 'nav'));
|
||||
|
||||
if (Event::handle('StartAccountSettingsNav', array(&$this->action))) {
|
||||
if (Event::handle('StartAccountSettingsNav', array($this->action))) {
|
||||
$user = common_current_user();
|
||||
|
||||
if(Event::handle('StartAccountSettingsProfileMenuItem', array($this, &$menu))){
|
||||
@ -142,7 +142,7 @@ class AccountSettingsNav extends Widget
|
||||
Event::handle('EndAccountSettingsOtherMenuItem', array($this, &$menu));
|
||||
}
|
||||
|
||||
Event::handle('EndAccountSettingsNav', array(&$this->action));
|
||||
Event::handle('EndAccountSettingsNav', array($this->action));
|
||||
}
|
||||
|
||||
$this->action->elementEnd('ul');
|
||||
|
@ -182,6 +182,9 @@ class Activity
|
||||
$actorEl = $this->_child($entry, self::ACTOR);
|
||||
|
||||
if (!empty($actorEl)) {
|
||||
// Standalone <activity:actor> elements are a holdover from older
|
||||
// versions of ActivityStreams. Newer feeds should have this data
|
||||
// integrated straight into <atom:author>.
|
||||
|
||||
$this->actor = new ActivityObject($actorEl);
|
||||
|
||||
@ -196,19 +199,24 @@ class Activity
|
||||
$this->actor->id = $authorObj->id;
|
||||
}
|
||||
}
|
||||
} else if (!empty($feed) &&
|
||||
$subjectEl = $this->_child($feed, self::SUBJECT)) {
|
||||
|
||||
$this->actor = new ActivityObject($subjectEl);
|
||||
|
||||
} else if ($authorEl = $this->_child($entry, self::AUTHOR, self::ATOM)) {
|
||||
|
||||
// An <atom:author> in the entry overrides any author info on
|
||||
// the surrounding feed.
|
||||
$this->actor = new ActivityObject($authorEl);
|
||||
|
||||
} else if (!empty($feed) && $authorEl = $this->_child($feed, self::AUTHOR,
|
||||
self::ATOM)) {
|
||||
|
||||
// If there's no <atom:author> on the entry, it's safe to assume
|
||||
// the containing feed's authorship info applies.
|
||||
$this->actor = new ActivityObject($authorEl);
|
||||
} else if (!empty($feed) &&
|
||||
$subjectEl = $this->_child($feed, self::SUBJECT)) {
|
||||
|
||||
// Feed subject is used for things like groups.
|
||||
// Should actually possibly not be interpreted as an actor...?
|
||||
$this->actor = new ActivityObject($subjectEl);
|
||||
}
|
||||
|
||||
$contextEl = $this->_child($entry, self::CONTEXT);
|
||||
@ -322,6 +330,7 @@ class Activity
|
||||
*
|
||||
* @return DOMElement Atom entry
|
||||
*/
|
||||
|
||||
function toAtomEntry()
|
||||
{
|
||||
return null;
|
||||
@ -330,7 +339,12 @@ class Activity
|
||||
function asString($namespace=false, $author=true, $source=false)
|
||||
{
|
||||
$xs = new XMLStringer(true);
|
||||
$this->outputTo($xs, $namespace, $author, $source);
|
||||
return $xs->getString();
|
||||
}
|
||||
|
||||
function outputTo($xs, $namespace=false, $author=true, $source=false)
|
||||
{
|
||||
if ($namespace) {
|
||||
$attrs = array('xmlns' => 'http://www.w3.org/2005/Atom',
|
||||
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0',
|
||||
@ -518,9 +532,7 @@ class Activity
|
||||
|
||||
$xs->elementEnd('entry');
|
||||
|
||||
$str = $xs->getString();
|
||||
|
||||
return $str;
|
||||
return;
|
||||
}
|
||||
|
||||
private function _child($element, $tag, $namespace=self::SPEC)
|
||||
|
168
lib/activitymover.php
Normal file
168
lib/activitymover.php
Normal file
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Title of module
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @category Cache
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class comment
|
||||
*
|
||||
* @category General
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ActivityMover extends QueueHandler
|
||||
{
|
||||
function transport()
|
||||
{
|
||||
return 'actmove';
|
||||
}
|
||||
|
||||
function handle($data)
|
||||
{
|
||||
list ($act, $sink, $userURI, $remoteURI) = $data;
|
||||
|
||||
$user = User::staticGet('uri', $userURI);
|
||||
$remote = Profile::fromURI($remoteURI);
|
||||
|
||||
try {
|
||||
$this->moveActivity($act, $sink, $user, $remote);
|
||||
} catch (ClientException $cex) {
|
||||
$this->log(LOG_WARNING,
|
||||
$cex->getMessage());
|
||||
// "don't retry me"
|
||||
return true;
|
||||
} catch (ServerException $sex) {
|
||||
$this->log(LOG_WARNING,
|
||||
$sex->getMessage());
|
||||
// "retry me" (because we think the server might handle it next time)
|
||||
return false;
|
||||
} catch (Exception $ex) {
|
||||
$this->log(LOG_WARNING,
|
||||
$ex->getMessage());
|
||||
// "don't retry me"
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function moveActivity($act, $sink, $user, $remote)
|
||||
{
|
||||
if (empty($user)) {
|
||||
throw new Exception("No such user {$act->actor->id}");
|
||||
}
|
||||
|
||||
switch ($act->verb) {
|
||||
case ActivityVerb::FAVORITE:
|
||||
$this->log(LOG_INFO,
|
||||
"Moving favorite of {$act->objects[0]->id} by ".
|
||||
"{$act->actor->id} to {$remote->nickname}.");
|
||||
// push it, then delete local
|
||||
$sink->postActivity($act);
|
||||
$notice = Notice::staticGet('uri', $act->objects[0]->id);
|
||||
if (!empty($notice)) {
|
||||
$fave = Fave::pkeyGet(array('user_id' => $user->id,
|
||||
'notice_id' => $notice->id));
|
||||
$fave->delete();
|
||||
}
|
||||
break;
|
||||
case ActivityVerb::POST:
|
||||
$this->log(LOG_INFO,
|
||||
"Moving notice {$act->objects[0]->id} by ".
|
||||
"{$act->actor->id} to {$remote->nickname}.");
|
||||
// XXX: send a reshare, not a post
|
||||
$sink->postActivity($act);
|
||||
$notice = Notice::staticGet('uri', $act->objects[0]->id);
|
||||
if (!empty($notice)) {
|
||||
$notice->delete();
|
||||
}
|
||||
break;
|
||||
case ActivityVerb::JOIN:
|
||||
$this->log(LOG_INFO,
|
||||
"Moving group join of {$act->objects[0]->id} by ".
|
||||
"{$act->actor->id} to {$remote->nickname}.");
|
||||
$sink->postActivity($act);
|
||||
$group = User_group::staticGet('uri', $act->objects[0]->id);
|
||||
if (!empty($group)) {
|
||||
Group_member::leave($group->id, $user->id);
|
||||
}
|
||||
break;
|
||||
case ActivityVerb::FOLLOW:
|
||||
if ($act->actor->id == $user->uri) {
|
||||
$this->log(LOG_INFO,
|
||||
"Moving subscription to {$act->objects[0]->id} by ".
|
||||
"{$act->actor->id} to {$remote->nickname}.");
|
||||
$sink->postActivity($act);
|
||||
$other = Profile::fromURI($act->objects[0]->id);
|
||||
if (!empty($other)) {
|
||||
Subscription::cancel($user->getProfile(), $other);
|
||||
}
|
||||
} else {
|
||||
$otherUser = User::staticGet('uri', $act->actor->id);
|
||||
if (!empty($otherUser)) {
|
||||
$this->log(LOG_INFO,
|
||||
"Changing sub to {$act->objects[0]->id}".
|
||||
"by {$act->actor->id} to {$remote->nickname}.");
|
||||
$otherProfile = $otherUser->getProfile();
|
||||
Subscription::start($otherProfile, $remote);
|
||||
Subscription::cancel($otherProfile, $user->getProfile());
|
||||
} else {
|
||||
$this->log(LOG_NOTICE,
|
||||
"Not changing sub to {$act->objects[0]->id}".
|
||||
"by remote {$act->actor->id} ".
|
||||
"to {$remote->nickname}.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log some data
|
||||
*
|
||||
* Add a header for our class so we know who did it.
|
||||
*
|
||||
* @param int $level Log level, like LOG_ERR or LOG_INFO
|
||||
* @param string $message Message to log
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
protected function log($level, $message)
|
||||
{
|
||||
common_log($level, "ActivityMover: " . $message);
|
||||
}
|
||||
}
|
169
lib/activitysink.php
Normal file
169
lib/activitysink.php
Normal file
@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* A remote, atompub-receiving service
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @category AtomPub
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote service that supports AtomPub
|
||||
*
|
||||
* @category AtomPub
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ActivitySink
|
||||
{
|
||||
protected $svcDocUrl = null;
|
||||
protected $username = null;
|
||||
protected $password = null;
|
||||
protected $collections = array();
|
||||
|
||||
function __construct($svcDocUrl, $username, $password)
|
||||
{
|
||||
$this->svcDocUrl = $svcDocUrl;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
|
||||
$this->_parseSvcDoc();
|
||||
}
|
||||
|
||||
private function _parseSvcDoc()
|
||||
{
|
||||
$client = new HTTPClient();
|
||||
$response = $client->get($this->svcDocUrl);
|
||||
|
||||
if ($response->getStatus() != 200) {
|
||||
throw new Exception("Can't get {$this->svcDocUrl}; response status " . $response->getStatus());
|
||||
}
|
||||
|
||||
$xml = $response->getBody();
|
||||
|
||||
$dom = new DOMDocument();
|
||||
|
||||
// We don't want to bother with white spaces
|
||||
$dom->preserveWhiteSpace = false;
|
||||
|
||||
// Don't spew XML warnings to output
|
||||
$old = error_reporting();
|
||||
error_reporting($old & ~E_WARNING);
|
||||
$ok = $dom->loadXML($xml);
|
||||
error_reporting($old);
|
||||
|
||||
$path = new DOMXPath($dom);
|
||||
|
||||
$path->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
|
||||
$path->registerNamespace('app', 'http://www.w3.org/2007/app');
|
||||
$path->registerNamespace('activity', 'http://activitystrea.ms/spec/1.0/');
|
||||
|
||||
$collections = $path->query('//app:collection');
|
||||
|
||||
for ($i = 0; $i < $collections->length; $i++) {
|
||||
$collection = $collections->item($i);
|
||||
$url = $collection->getAttribute('href');
|
||||
$takesEntries = false;
|
||||
$accepts = $path->query('app:accept', $collection);
|
||||
for ($j = 0; $j < $accepts->length; $j++) {
|
||||
$accept = $accepts->item($j);
|
||||
$acceptValue = $accept->nodeValue;
|
||||
if (preg_match('#application/atom\+xml(;\s*type=entry)?#', $acceptValue)) {
|
||||
$takesEntries = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$takesEntries) {
|
||||
continue;
|
||||
}
|
||||
$verbs = $path->query('activity:verb', $collection);
|
||||
if ($verbs->length == 0) {
|
||||
$this->_addCollection(ActivityVerb::POST, $url);
|
||||
} else {
|
||||
for ($k = 0; $k < $verbs->length; $k++) {
|
||||
$verb = $verbs->item($k);
|
||||
$this->_addCollection($verb->nodeValue, $url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function _addCollection($verb, $url)
|
||||
{
|
||||
if (array_key_exists($verb, $this->collections)) {
|
||||
$this->collections[$verb][] = $url;
|
||||
} else {
|
||||
$this->collections[$verb] = array($url);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
function postActivity($activity)
|
||||
{
|
||||
if (!array_key_exists($activity->verb, $this->collections)) {
|
||||
throw new Exception("No collection for verb {$activity->verb}");
|
||||
} else {
|
||||
if (count($this->collections[$activity->verb]) > 1) {
|
||||
common_log(LOG_NOTICE, "More than one collection for verb {$activity->verb}");
|
||||
}
|
||||
$this->postToCollection($this->collections[$activity->verb][0], $activity);
|
||||
}
|
||||
}
|
||||
|
||||
function postToCollection($url, $activity)
|
||||
{
|
||||
$client = new HTTPClient($url);
|
||||
|
||||
$client->setMethod('POST');
|
||||
$client->setAuth($this->username, $this->password);
|
||||
$client->setHeader('Content-Type', 'application/atom+xml;type=entry');
|
||||
$client->setBody($activity->asString(true, true, true));
|
||||
|
||||
$response = $client->send();
|
||||
|
||||
$status = $response->getStatus();
|
||||
$reason = $response->getReasonPhrase();
|
||||
|
||||
if ($status >= 200 && $status < 300) {
|
||||
return true;
|
||||
} else if ($status >= 400 && $status < 500) {
|
||||
throw new ClientException("{$url} {$status} {$reason}");
|
||||
} else if ($status >= 500 && $status < 600) {
|
||||
throw new ServerException("{$url} {$status} {$reason}");
|
||||
} else {
|
||||
// That's unexpected.
|
||||
throw new Exception("{$url} {$status} {$reason}");
|
||||
}
|
||||
}
|
||||
}
|
@ -1437,41 +1437,23 @@ class ApiAction extends Action
|
||||
{
|
||||
if (empty($id)) {
|
||||
if (self::is_decimal($this->arg('id'))) {
|
||||
return User_group::staticGet($this->arg('id'));
|
||||
return User_group::staticGet('id', $this->arg('id'));
|
||||
} else if ($this->arg('id')) {
|
||||
$nickname = common_canonical_nickname($this->arg('id'));
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
if (empty($local)) {
|
||||
return null;
|
||||
} else {
|
||||
return User_group::staticGet('id', $local->id);
|
||||
}
|
||||
return User_group::getForNickname($this->arg('id'));
|
||||
} else if ($this->arg('group_id')) {
|
||||
// This is to ensure that a non-numeric user_id still
|
||||
// overrides screen_name even if it doesn't get used
|
||||
// This is to ensure that a non-numeric group_id still
|
||||
// overrides group_name even if it doesn't get used
|
||||
if (self::is_decimal($this->arg('group_id'))) {
|
||||
return User_group::staticGet('id', $this->arg('group_id'));
|
||||
}
|
||||
} else if ($this->arg('group_name')) {
|
||||
$nickname = common_canonical_nickname($this->arg('group_name'));
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
if (empty($local)) {
|
||||
return null;
|
||||
} else {
|
||||
return User_group::staticGet('id', $local->group_id);
|
||||
}
|
||||
return User_group::getForNickname($this->arg('group_name'));
|
||||
}
|
||||
|
||||
} else if (self::is_decimal($id)) {
|
||||
return User_group::staticGet($id);
|
||||
return User_group::staticGet('id', $id);
|
||||
} else {
|
||||
$nickname = common_canonical_nickname($id);
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
if (empty($local)) {
|
||||
return null;
|
||||
} else {
|
||||
return User_group::staticGet('id', $local->group_id);
|
||||
}
|
||||
return User_group::getForNickname($id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,10 @@ class ArrayWrapper
|
||||
function __call($name, $args)
|
||||
{
|
||||
$item =& $this->_items[$this->_i];
|
||||
if (!is_object($item)) {
|
||||
common_log(LOG_ERR, "Invalid entry " . var_export($item, true) . " at index $this->_i of $this->N; calling $name()");
|
||||
throw new ServerException("Internal error: bad entry in array wrapper list.");
|
||||
}
|
||||
return call_user_func_array(array($item, $name), $args);
|
||||
}
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
//exit with 200 response, if this is checking fancy from the installer
|
||||
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
|
||||
|
||||
define('STATUSNET_BASE_VERSION', '0.9.8');
|
||||
define('STATUSNET_LIFECYCLE', 'dev'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
||||
define('STATUSNET_BASE_VERSION', '0.9.7');
|
||||
define('STATUSNET_LIFECYCLE', 'alpha1'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
||||
define('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE);
|
||||
|
||||
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
|
||||
|
||||
define('STATUSNET_CODENAME', 'Letter Never Sent');
|
||||
define('STATUSNET_CODENAME', 'World Leader Pretend');
|
||||
|
||||
define('AVATAR_PROFILE_SIZE', 96);
|
||||
define('AVATAR_STREAM_SIZE', 48);
|
||||
@ -63,8 +63,13 @@ if (!function_exists('dl')) {
|
||||
// Fortunately trying to call the disabled one will only trigger
|
||||
// a warning, not a fatal, so it's safe to leave it for our case.
|
||||
// Callers will be suppressing warnings anyway.
|
||||
$disabled = array_filter(array_map('trim', explode(',', ini_get('disable_functions'))));
|
||||
if (!in_array('dl', $disabled)) {
|
||||
try {
|
||||
// Reading the ini setting is hard as we don't know PHP's parsing,
|
||||
// but we can check if it is disabled through reflection.
|
||||
$dl = new ReflectionFunction('dl');
|
||||
// $disabled = $dl->isDisabled(); // don't need to check this now
|
||||
} catch (ReflectionException $e) {
|
||||
// Ok, it *really* doesn't exist!
|
||||
function dl($library) {
|
||||
return false;
|
||||
}
|
||||
@ -95,7 +100,11 @@ function _have_config()
|
||||
return StatusNet::haveConfig();
|
||||
}
|
||||
|
||||
function __autoload($cls)
|
||||
/**
|
||||
* Wrapper for class autoloaders.
|
||||
* This used to be the special function name __autoload(), but that causes bugs with PHPUnit 3.5+
|
||||
*/
|
||||
function autoload_sn($cls)
|
||||
{
|
||||
if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) {
|
||||
require_once(INSTALLDIR.'/classes/' . $cls . '.php');
|
||||
@ -111,6 +120,8 @@ function __autoload($cls)
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('autoload_sn');
|
||||
|
||||
// XXX: how many of these could be auto-loaded on use?
|
||||
// XXX: note that these files should not use config options
|
||||
// at compile time since DB config options are not yet loaded.
|
||||
|
@ -96,7 +96,7 @@ class ConnectSettingsNav extends Widget
|
||||
$action_name = $this->action->trimmed('action');
|
||||
$this->action->elementStart('ul', array('class' => 'nav'));
|
||||
|
||||
if (Event::handle('StartConnectSettingsNav', array(&$this->action))) {
|
||||
if (Event::handle('StartConnectSettingsNav', array($this->action))) {
|
||||
|
||||
# action => array('prompt', 'title')
|
||||
$menu = array();
|
||||
@ -129,7 +129,7 @@ class ConnectSettingsNav extends Widget
|
||||
$action_name === $menuaction);
|
||||
}
|
||||
|
||||
Event::handle('EndConnectSettingsNav', array(&$this->action));
|
||||
Event::handle('EndConnectSettingsNav', array($this->action));
|
||||
}
|
||||
|
||||
$this->action->elementEnd('ul');
|
||||
|
@ -41,7 +41,6 @@ if (!defined('STATUSNET')) {
|
||||
* @link http://status.net/
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteUserForm extends ProfileActionForm
|
||||
{
|
||||
/**
|
||||
@ -49,7 +48,6 @@ class DeleteUserForm extends ProfileActionForm
|
||||
*
|
||||
* @return string Name of the action, lowercased.
|
||||
*/
|
||||
|
||||
function target()
|
||||
{
|
||||
return 'deleteuser';
|
||||
@ -60,9 +58,9 @@ class DeleteUserForm extends ProfileActionForm
|
||||
*
|
||||
* @return string Title of the form, internationalized
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title of form for deleting a user.
|
||||
return _('Delete');
|
||||
}
|
||||
|
||||
@ -71,9 +69,9 @@ class DeleteUserForm extends ProfileActionForm
|
||||
*
|
||||
* @return string description of the form, internationalized
|
||||
*/
|
||||
|
||||
function description()
|
||||
{
|
||||
// TRANS: Description of form for deleting a user.
|
||||
return _('Delete this user');
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* A sample module to show best practices for StatusNet plugins
|
||||
* Use Hammer discovery stack to find out interesting things about an URI
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -20,6 +20,7 @@
|
||||
* 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/>.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
@ -27,22 +28,41 @@
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements LRDD-based service discovery based on the "Hammer Draft"
|
||||
* (including webfinger)
|
||||
*
|
||||
* @see http://groups.google.com/group/webfinger/browse_thread/thread/9f3d93a479e91bbf
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*
|
||||
* @see http://groups.google.com/group/webfinger/browse_thread/thread/9f3d93a479e91bbf
|
||||
*/
|
||||
|
||||
class Discovery
|
||||
{
|
||||
|
||||
const LRDD_REL = 'lrdd';
|
||||
const LRDD_REL = 'lrdd';
|
||||
const PROFILEPAGE = 'http://webfinger.net/rel/profile-page';
|
||||
const UPDATESFROM = 'http://schemas.google.com/g/2010#updates-from';
|
||||
const HCARD = 'http://microformats.org/profile/hcard';
|
||||
const HCARD = 'http://microformats.org/profile/hcard';
|
||||
|
||||
public $methods = array();
|
||||
|
||||
/**
|
||||
* Constructor for a discovery object
|
||||
*
|
||||
* Registers different discovery methods.
|
||||
*
|
||||
* @return Discovery this
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerMethod('Discovery_LRDD_Host_Meta');
|
||||
@ -50,6 +70,14 @@ class Discovery
|
||||
$this->registerMethod('Discovery_LRDD_Link_HTML');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a discovery class
|
||||
*
|
||||
* @param string $class Class name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function registerMethod($class)
|
||||
{
|
||||
$this->methods[] = $class;
|
||||
@ -58,7 +86,12 @@ class Discovery
|
||||
/**
|
||||
* Given a "user id" make sure it's normalized to either a webfinger
|
||||
* acct: uri or a profile HTTP URL.
|
||||
*
|
||||
* @param string $user_id User ID to normalize
|
||||
*
|
||||
* @return string normalized acct: or http(s)?: URI
|
||||
*/
|
||||
|
||||
public static function normalize($user_id)
|
||||
{
|
||||
if (substr($user_id, 0, 5) == 'http:' ||
|
||||
@ -67,13 +100,23 @@ class Discovery
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
if (strpos($user_id, '@') !== FALSE) {
|
||||
if (strpos($user_id, '@') !== false) {
|
||||
return 'acct:' . $user_id;
|
||||
}
|
||||
|
||||
return 'http://' . $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a string is a Webfinger ID
|
||||
*
|
||||
* Webfinger IDs look like foo@example.com or acct:foo@example.com
|
||||
*
|
||||
* @param string $user_id ID to check
|
||||
*
|
||||
* @return boolean true if $user_id is a Webfinger, else false
|
||||
*/
|
||||
|
||||
public static function isWebfinger($user_id)
|
||||
{
|
||||
$uri = Discovery::normalize($user_id);
|
||||
@ -82,8 +125,13 @@ class Discovery
|
||||
}
|
||||
|
||||
/**
|
||||
* This implements the actual lookup procedure
|
||||
* Given a user ID, return the first available XRD
|
||||
*
|
||||
* @param string $id User ID URI
|
||||
*
|
||||
* @return XRD XRD object for the user
|
||||
*/
|
||||
|
||||
public function lookup($id)
|
||||
{
|
||||
// Normalize the incoming $id to make sure we have a uri
|
||||
@ -107,10 +155,20 @@ class Discovery
|
||||
}
|
||||
|
||||
// TRANS: Exception.
|
||||
throw new Exception(sprintf(_m('Unable to find services for %s.'),$id));
|
||||
throw new Exception(sprintf(_('Unable to find services for %s.'), $id));
|
||||
}
|
||||
|
||||
public static function getService($links, $service) {
|
||||
/**
|
||||
* Given an array of links, returns the matching service
|
||||
*
|
||||
* @param array $links Links to check
|
||||
* @param string $service Service to find
|
||||
*
|
||||
* @return array $link assoc array representing the link
|
||||
*/
|
||||
|
||||
public static function getService($links, $service)
|
||||
{
|
||||
if (!is_array($links)) {
|
||||
return false;
|
||||
}
|
||||
@ -122,6 +180,17 @@ class Discovery
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a template using an ID
|
||||
*
|
||||
* Replaces {uri} in template string with the ID given.
|
||||
*
|
||||
* @param string $template Template to match
|
||||
* @param string $id User ID to replace with
|
||||
*
|
||||
* @return string replaced values
|
||||
*/
|
||||
|
||||
public static function applyTemplate($template, $id)
|
||||
{
|
||||
$template = str_replace('{uri}', urlencode($id), $template);
|
||||
@ -129,10 +198,18 @@ class Discovery
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an XRD file and parse
|
||||
*
|
||||
* @param string $url URL of the XRD
|
||||
*
|
||||
* @return XRD object representing the XRD file
|
||||
*/
|
||||
|
||||
public static function fetchXrd($url)
|
||||
{
|
||||
try {
|
||||
$client = new HTTPClient();
|
||||
$client = new HTTPClient();
|
||||
$response = $client->get($url);
|
||||
} catch (HTTP_Request2_Exception $e) {
|
||||
return false;
|
||||
@ -146,13 +223,60 @@ class Discovery
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract interface for discovery
|
||||
*
|
||||
* Objects that implement this interface can retrieve an array of
|
||||
* XRD links for the URI.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
interface Discovery_LRDD
|
||||
{
|
||||
/**
|
||||
* Discover interesting info about the URI
|
||||
*
|
||||
* @param string $uri URI to inquire about
|
||||
*
|
||||
* @return array Links in the XRD file
|
||||
*/
|
||||
|
||||
public function discover($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of discovery using host-meta file
|
||||
*
|
||||
* Discovers XRD file for a user by going to the organization's
|
||||
* host-meta file and trying to find a template for LRDD.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class Discovery_LRDD_Host_Meta implements Discovery_LRDD
|
||||
{
|
||||
/**
|
||||
* Discovery core method
|
||||
*
|
||||
* For Webfinger and HTTP URIs, fetch the host-meta file
|
||||
* and look for LRDD templates
|
||||
*
|
||||
* @param string $uri URI to inquire about
|
||||
*
|
||||
* @return array Links in the XRD file
|
||||
*/
|
||||
|
||||
public function discover($uri)
|
||||
{
|
||||
if (Discovery::isWebfinger($uri)) {
|
||||
@ -176,12 +300,38 @@ class Discovery_LRDD_Host_Meta implements Discovery_LRDD
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of discovery using HTTP Link header
|
||||
*
|
||||
* Discovers XRD file for a user by fetching the URL and reading any
|
||||
* Link: headers in the HTTP response.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class Discovery_LRDD_Link_Header implements Discovery_LRDD
|
||||
{
|
||||
/**
|
||||
* Discovery core method
|
||||
*
|
||||
* For HTTP IDs fetch the URL and look for Link headers.
|
||||
*
|
||||
* @param string $uri URI to inquire about
|
||||
*
|
||||
* @return array Links in the XRD file
|
||||
*
|
||||
* @todo fail out of Webfinger URIs faster
|
||||
*/
|
||||
|
||||
public function discover($uri)
|
||||
{
|
||||
try {
|
||||
$client = new HTTPClient();
|
||||
$client = new HTTPClient();
|
||||
$response = $client->get($uri);
|
||||
} catch (HTTP_Request2_Exception $e) {
|
||||
return false;
|
||||
@ -199,6 +349,14 @@ class Discovery_LRDD_Link_Header implements Discovery_LRDD
|
||||
return array(Discovery_LRDD_Link_Header::parseHeader($link_header));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string or array of headers, returns XRD-like assoc array
|
||||
*
|
||||
* @param string|array $header string or array of strings for headers
|
||||
*
|
||||
* @return array Link header in XRD-like format
|
||||
*/
|
||||
|
||||
protected static function parseHeader($header)
|
||||
{
|
||||
$lh = new LinkHeader($header);
|
||||
@ -209,12 +367,39 @@ class Discovery_LRDD_Link_Header implements Discovery_LRDD
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of discovery using HTML <link> element
|
||||
*
|
||||
* Discovers XRD file for a user by fetching the URL and reading any
|
||||
* <link> elements in the HTML response.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class Discovery_LRDD_Link_HTML implements Discovery_LRDD
|
||||
{
|
||||
/**
|
||||
* Discovery core method
|
||||
*
|
||||
* For HTTP IDs, fetch the URL and look for <link> elements
|
||||
* in the HTML response.
|
||||
*
|
||||
* @param string $uri URI to inquire about
|
||||
*
|
||||
* @return array Links in XRD-ish assoc array
|
||||
*
|
||||
* @todo fail out of Webfinger URIs faster
|
||||
*/
|
||||
|
||||
public function discover($uri)
|
||||
{
|
||||
try {
|
||||
$client = new HTTPClient();
|
||||
$client = new HTTPClient();
|
||||
$response = $client->get($uri);
|
||||
} catch (HTTP_Request2_Exception $e) {
|
||||
return false;
|
||||
@ -227,6 +412,16 @@ class Discovery_LRDD_Link_HTML implements Discovery_LRDD
|
||||
return Discovery_LRDD_Link_HTML::parse($response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse HTML and return <link> elements
|
||||
*
|
||||
* Given an HTML string, scans the string for <link> elements
|
||||
*
|
||||
* @param string $html HTML to scan
|
||||
*
|
||||
* @return array array of associative arrays in XRD-ish format
|
||||
*/
|
||||
|
||||
public function parse($html)
|
||||
{
|
||||
$links = array();
|
||||
@ -237,8 +432,8 @@ class Discovery_LRDD_Link_HTML implements Discovery_LRDD
|
||||
preg_match_all('/<link\s[^>]*>/i', $head_html, $link_matches);
|
||||
|
||||
foreach ($link_matches[0] as $link_html) {
|
||||
$link_url = null;
|
||||
$link_rel = null;
|
||||
$link_url = null;
|
||||
$link_rel = null;
|
||||
$link_type = null;
|
||||
|
||||
preg_match('/\srel=(("|\')([^\\2]*?)\\2|[^"\'\s]+)/i', $link_html, $rel_matches);
|
@ -46,13 +46,11 @@ require_once INSTALLDIR.'/lib/form.php';
|
||||
*
|
||||
* @see UnsubscribeForm
|
||||
*/
|
||||
|
||||
class GroupEditForm extends Form
|
||||
{
|
||||
/**
|
||||
* group for user to join
|
||||
*/
|
||||
|
||||
var $group = null;
|
||||
|
||||
/**
|
||||
@ -61,7 +59,6 @@ class GroupEditForm extends Form
|
||||
* @param Action $out output channel
|
||||
* @param User_group $group group to join
|
||||
*/
|
||||
|
||||
function __construct($out=null, $group=null)
|
||||
{
|
||||
parent::__construct($out);
|
||||
@ -74,7 +71,6 @@ class GroupEditForm extends Form
|
||||
*
|
||||
* @return string ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
if ($this->group) {
|
||||
@ -89,7 +85,6 @@ class GroupEditForm extends Form
|
||||
*
|
||||
* @return string of the form class
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_settings';
|
||||
@ -100,7 +95,6 @@ class GroupEditForm extends Form
|
||||
*
|
||||
* @return string URL of the action
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
if ($this->group) {
|
||||
@ -116,7 +110,6 @@ class GroupEditForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formLegend()
|
||||
{
|
||||
$this->out->element('legend', null, _('Create a new group'));
|
||||
@ -127,7 +120,6 @@ class GroupEditForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
if ($this->group) {
|
||||
@ -151,7 +143,7 @@ class GroupEditForm extends Form
|
||||
$this->out->hidden('groupid', $id);
|
||||
$this->out->input('nickname', _('Nickname'),
|
||||
($this->out->arg('nickname')) ? $this->out->arg('nickname') : $nickname,
|
||||
_('1-64 lowercase letters or numbers, no punctuation or spaces'));
|
||||
_('1-64 lowercase letters or numbers, no punctuation or spaces.'));
|
||||
$this->out->elementEnd('li');
|
||||
$this->out->elementStart('li');
|
||||
$this->out->input('fullname', _('Full name'),
|
||||
@ -167,8 +159,8 @@ class GroupEditForm extends Form
|
||||
if ($desclimit == 0) {
|
||||
$descinstr = _('Describe the group or topic');
|
||||
} else {
|
||||
$descinstr = sprintf(_m('Describe the group or topic in %d character or less',
|
||||
'Describe the group or topic in %d characters or less',
|
||||
$descinstr = sprintf(_m('Describe the group or topic in %d character or less.',
|
||||
'Describe the group or topic in %d characters or less.',
|
||||
$desclimit),
|
||||
$desclimit);
|
||||
}
|
||||
@ -201,7 +193,6 @@ class GroupEditForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _m('BUTTON','Save'));
|
||||
|
@ -128,7 +128,7 @@ class ImageFile
|
||||
*/
|
||||
function resize($size, $x = 0, $y = 0, $w = null, $h = null)
|
||||
{
|
||||
$targetType = $this->preferredType($this->type);
|
||||
$targetType = $this->preferredType();
|
||||
$outname = Avatar::filename($this->id,
|
||||
image_type_to_extension($targetType),
|
||||
$size,
|
||||
@ -138,6 +138,19 @@ class ImageFile
|
||||
return $outname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the image file to the given destination.
|
||||
* For obscure formats, this will automatically convert to PNG;
|
||||
* otherwise the original file will be copied as-is.
|
||||
*
|
||||
* @param string $outpath
|
||||
* @return string filename
|
||||
*/
|
||||
function copyTo($outpath)
|
||||
{
|
||||
return $this->resizeTo($outpath, $this->width, $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and save a thumbnail image.
|
||||
*
|
||||
@ -154,7 +167,7 @@ class ImageFile
|
||||
{
|
||||
$w = ($w === null) ? $this->width:$w;
|
||||
$h = ($h === null) ? $this->height:$h;
|
||||
$targetType = $this->preferredType($this->type);
|
||||
$targetType = $this->preferredType();
|
||||
|
||||
if (!file_exists($this->filepath)) {
|
||||
throw new Exception(_('Lost our file.'));
|
||||
@ -247,25 +260,25 @@ class ImageFile
|
||||
/**
|
||||
* Several obscure file types should be normalized to PNG on resize.
|
||||
*
|
||||
* @param int $type
|
||||
* @fixme consider flattening anything not GIF or JPEG to PNG
|
||||
* @return int
|
||||
*/
|
||||
function preferredType($type)
|
||||
function preferredType()
|
||||
{
|
||||
if($type == IMAGETYPE_BMP) {
|
||||
if($this->type == IMAGETYPE_BMP) {
|
||||
//we don't want to save BMP... it's an inefficient, rare, antiquated format
|
||||
//save png instead
|
||||
return IMAGETYPE_PNG;
|
||||
} else if($type == IMAGETYPE_WBMP) {
|
||||
} else if($this->type == IMAGETYPE_WBMP) {
|
||||
//we don't want to save WBMP... it's a rare format that we can't guarantee clients will support
|
||||
//save png instead
|
||||
return IMAGETYPE_PNG;
|
||||
} else if($type == IMAGETYPE_XBM) {
|
||||
} else if($this->type == IMAGETYPE_XBM) {
|
||||
//we don't want to save XBM... it's a rare format that we can't guarantee clients will support
|
||||
//save png instead
|
||||
return IMAGETYPE_PNG;
|
||||
}
|
||||
return $type;
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
function unlink()
|
||||
|
132
lib/linkheader.php
Normal file
132
lib/linkheader.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Parse HTTP response for interesting Link: headers
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to represent Link: headers in an HTTP response
|
||||
*
|
||||
* Since these are a fairly important part of Hammer-stack discovery, they're
|
||||
* reified and implemented here.
|
||||
*
|
||||
* @category Discovery
|
||||
* @package StatusNet
|
||||
* @author James Walker <james@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*
|
||||
* @see Discovery
|
||||
*/
|
||||
|
||||
class LinkHeader
|
||||
{
|
||||
var $href;
|
||||
var $rel;
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* Initialize from a string
|
||||
*
|
||||
* @param string $str Link: header value
|
||||
*
|
||||
* @return LinkHeader self
|
||||
*/
|
||||
|
||||
function __construct($str)
|
||||
{
|
||||
preg_match('/^<[^>]+>/', $str, $uri_reference);
|
||||
//if (empty($uri_reference)) return;
|
||||
|
||||
$this->href = trim($uri_reference[0], '<>');
|
||||
$this->rel = array();
|
||||
$this->type = null;
|
||||
|
||||
// remove uri-reference from header
|
||||
$str = substr($str, strlen($uri_reference[0]));
|
||||
|
||||
// parse link-params
|
||||
$params = explode(';', $str);
|
||||
|
||||
foreach ($params as $param) {
|
||||
if (empty($param)) {
|
||||
continue;
|
||||
}
|
||||
list($param_name, $param_value) = explode('=', $param, 2);
|
||||
|
||||
$param_name = trim($param_name);
|
||||
$param_value = preg_replace('(^"|"$)', '', trim($param_value));
|
||||
|
||||
// for now we only care about 'rel' and 'type' link params
|
||||
// TODO do something with the other links-params
|
||||
switch ($param_name) {
|
||||
case 'rel':
|
||||
$this->rel = trim($param_value);
|
||||
break;
|
||||
|
||||
case 'type':
|
||||
$this->type = trim($param_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an HTTP response, return the requested Link: header
|
||||
*
|
||||
* @param HTTP_Request2_Response $response response to check
|
||||
* @param string $rel relationship to look for
|
||||
* @param string $type media type to look for
|
||||
*
|
||||
* @return LinkHeader discovered header, or null on failure
|
||||
*/
|
||||
|
||||
static function getLink($response, $rel=null, $type=null)
|
||||
{
|
||||
$headers = $response->getHeader('Link');
|
||||
if ($headers) {
|
||||
// Can get an array or string, so try to simplify the path
|
||||
if (!is_array($headers)) {
|
||||
$headers = array($headers);
|
||||
}
|
||||
|
||||
foreach ($headers as $header) {
|
||||
$lh = new LinkHeader($header);
|
||||
|
||||
if ((is_null($rel) || $lh->rel == $rel) &&
|
||||
(is_null($type) || $lh->type == $type)) {
|
||||
return $lh->href;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -73,7 +73,7 @@ class LoginGroupNav extends Widget
|
||||
|
||||
$this->action->elementStart('ul', array('class' => 'nav'));
|
||||
|
||||
if (Event::handle('StartLoginGroupNav', array(&$this->action))) {
|
||||
if (Event::handle('StartLoginGroupNav', array($this->action))) {
|
||||
|
||||
$this->action->menuItem(common_local_url('login'),
|
||||
_('Login'),
|
||||
@ -87,7 +87,7 @@ class LoginGroupNav extends Widget
|
||||
$action_name === 'register');
|
||||
}
|
||||
|
||||
Event::handle('EndLoginGroupNav', array(&$this->action));
|
||||
Event::handle('EndLoginGroupNav', array($this->action));
|
||||
}
|
||||
|
||||
$this->action->elementEnd('ul');
|
||||
|
@ -121,7 +121,7 @@ function mail_notify_from()
|
||||
|
||||
$domain = mail_domain();
|
||||
|
||||
$notifyfrom = '"'.common_config('site', 'name') .'" <noreply@'.$domain.'>';
|
||||
$notifyfrom = '"'. str_replace('"', '\\"', common_config('site', 'name')) .'" <noreply@'.$domain.'>';
|
||||
}
|
||||
|
||||
return $notifyfrom;
|
||||
|
@ -99,6 +99,21 @@ class ProfileAction extends OwnerDesignAction
|
||||
$this->showStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function for common pattern of links to subscription/groups sections.
|
||||
*
|
||||
* @param string $actionClass
|
||||
* @param string $title
|
||||
* @param string $cssClass
|
||||
*/
|
||||
private function statsSectionLink($actionClass, $title, $cssClass='')
|
||||
{
|
||||
$this->element('a', array('href' => common_local_url($actionClass,
|
||||
array('nickname' => $this->profile->nickname)),
|
||||
'class' => $cssClass),
|
||||
$title);
|
||||
}
|
||||
|
||||
function showSubscriptions()
|
||||
{
|
||||
$profile = $this->profile->getSubscriptions(0, PROFILES_PER_MINILIST + 1);
|
||||
@ -106,7 +121,9 @@ class ProfileAction extends OwnerDesignAction
|
||||
$this->elementStart('div', array('id' => 'entity_subscriptions',
|
||||
'class' => 'section'));
|
||||
if (Event::handle('StartShowSubscriptionsMiniList', array($this))) {
|
||||
$this->element('h2', null, _('Subscriptions'));
|
||||
$this->elementStart('h2');
|
||||
$this->statsSectionLink('subscriptions', _('Subscriptions'));
|
||||
$this->elementEnd('h2');
|
||||
|
||||
$cnt = 0;
|
||||
|
||||
@ -120,10 +137,7 @@ class ProfileAction extends OwnerDesignAction
|
||||
|
||||
if ($cnt > PROFILES_PER_MINILIST) {
|
||||
$this->elementStart('p');
|
||||
$this->element('a', array('href' => common_local_url('subscriptions',
|
||||
array('nickname' => $this->profile->nickname)),
|
||||
'class' => 'more'),
|
||||
_('All subscriptions'));
|
||||
$this->statsSectionLink('subscriptions', _('All subscriptions'), 'more');
|
||||
$this->elementEnd('p');
|
||||
}
|
||||
|
||||
@ -141,7 +155,9 @@ class ProfileAction extends OwnerDesignAction
|
||||
|
||||
if (Event::handle('StartShowSubscribersMiniList', array($this))) {
|
||||
|
||||
$this->element('h2', null, _('Subscribers'));
|
||||
$this->elementStart('h2');
|
||||
$this->statsSectionLink('subscribers', _('Subscribers'));
|
||||
$this->elementEnd('h2');
|
||||
|
||||
$cnt = 0;
|
||||
|
||||
@ -155,10 +171,7 @@ class ProfileAction extends OwnerDesignAction
|
||||
|
||||
if ($cnt > PROFILES_PER_MINILIST) {
|
||||
$this->elementStart('p');
|
||||
$this->element('a', array('href' => common_local_url('subscribers',
|
||||
array('nickname' => $this->profile->nickname)),
|
||||
'class' => 'more'),
|
||||
_('All subscribers'));
|
||||
$this->statsSectionLink('subscribers', _('All subscribers'), 'more');
|
||||
$this->elementEnd('p');
|
||||
}
|
||||
|
||||
@ -170,10 +183,7 @@ class ProfileAction extends OwnerDesignAction
|
||||
|
||||
function showStatistics()
|
||||
{
|
||||
$subs_count = $this->profile->subscriptionCount();
|
||||
$subbed_count = $this->profile->subscriberCount();
|
||||
$notice_count = $this->profile->noticeCount();
|
||||
$group_count = $this->profile->getGroups()->N;
|
||||
$age_days = (time() - strtotime($this->profile->created)) / 86400;
|
||||
if ($age_days < 1) {
|
||||
// Rather than extrapolating out to a bajillion...
|
||||
@ -186,59 +196,73 @@ class ProfileAction extends OwnerDesignAction
|
||||
|
||||
$this->element('h2', null, _('Statistics'));
|
||||
|
||||
// Other stats...?
|
||||
$this->elementStart('dl', 'entity_user-id');
|
||||
$this->element('dt', null, _('User ID'));
|
||||
$this->element('dd', null, $this->profile->id);
|
||||
$this->elementEnd('dl');
|
||||
$profile = $this->profile;
|
||||
$actionParams = array('nickname' => $profile->nickname);
|
||||
$stats = array(
|
||||
array(
|
||||
'id' => 'user-id',
|
||||
'label' => _('User ID'),
|
||||
'value' => $profile->id,
|
||||
),
|
||||
array(
|
||||
'id' => 'member-since',
|
||||
'label' => _('Member since'),
|
||||
'value' => date('j M Y', strtotime($profile->created))
|
||||
),
|
||||
array(
|
||||
'id' => 'subscriptions',
|
||||
'label' => _('Subscriptions'),
|
||||
'link' => common_local_url('subscriptions', $actionParams),
|
||||
'value' => $profile->subscriptionCount(),
|
||||
),
|
||||
array(
|
||||
'id' => 'subscribers',
|
||||
'label' => _('Subscribers'),
|
||||
'link' => common_local_url('subscribers', $actionParams),
|
||||
'value' => $profile->subscriberCount(),
|
||||
),
|
||||
array(
|
||||
'id' => 'groups',
|
||||
'label' => _('Groups'),
|
||||
'link' => common_local_url('usergroups', $actionParams),
|
||||
'value' => $profile->getGroups()->N,
|
||||
),
|
||||
array(
|
||||
'id' => 'notices',
|
||||
'label' => _('Notices'),
|
||||
'value' => $notice_count,
|
||||
),
|
||||
array(
|
||||
'id' => 'daily_notices',
|
||||
// TRANS: Average count of posts made per day since account registration
|
||||
'label' => _('Daily average'),
|
||||
'value' => $daily_count
|
||||
)
|
||||
);
|
||||
|
||||
$this->elementStart('dl', 'entity_member-since');
|
||||
$this->element('dt', null, _('Member since'));
|
||||
$this->element('dd', null, date('j M Y',
|
||||
strtotime($this->profile->created)));
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_subscriptions');
|
||||
$this->elementStart('dt');
|
||||
$this->element('a', array('href' => common_local_url('subscriptions',
|
||||
array('nickname' => $this->profile->nickname))),
|
||||
_('Subscriptions'));
|
||||
$this->elementEnd('dt');
|
||||
$this->element('dd', null, $subs_count);
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_subscribers');
|
||||
$this->elementStart('dt');
|
||||
$this->element('a', array('href' => common_local_url('subscribers',
|
||||
array('nickname' => $this->profile->nickname))),
|
||||
_('Subscribers'));
|
||||
$this->elementEnd('dt');
|
||||
$this->element('dd', 'subscribers', $subbed_count);
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_groups');
|
||||
$this->elementStart('dt');
|
||||
$this->element('a', array('href' => common_local_url('usergroups',
|
||||
array('nickname' => $this->profile->nickname))),
|
||||
_('Groups'));
|
||||
$this->elementEnd('dt');
|
||||
$this->element('dd', 'groups', $group_count);
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_notices');
|
||||
$this->element('dt', null, _('Notices'));
|
||||
$this->element('dd', null, $notice_count);
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_daily_notices');
|
||||
// TRANS: Average count of posts made per day since account registration
|
||||
$this->element('dt', null, _('Daily average'));
|
||||
$this->element('dd', null, $daily_count);
|
||||
$this->elementEnd('dl');
|
||||
// Give plugins a chance to add stats entries
|
||||
Event::handle('ProfileStats', array($profile, &$stats));
|
||||
|
||||
foreach ($stats as $row) {
|
||||
$this->showStatsRow($row);
|
||||
}
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
private function showStatsRow($row)
|
||||
{
|
||||
$this->elementStart('dl', 'entity_' . $row['id']);
|
||||
$this->elementStart('dt');
|
||||
if (!empty($row['link'])) {
|
||||
$this->element('a', array('href' => $row['link']), $row['label']);
|
||||
} else {
|
||||
$this->text($row['label']);
|
||||
}
|
||||
$this->elementEnd('dt');
|
||||
$this->element('dd', null, $row['value']);
|
||||
$this->elementEnd('dl');
|
||||
}
|
||||
|
||||
function showGroups()
|
||||
{
|
||||
$groups = $this->profile->getGroups(0, GROUPS_PER_MINILIST + 1);
|
||||
@ -246,7 +270,9 @@ class ProfileAction extends OwnerDesignAction
|
||||
$this->elementStart('div', array('id' => 'entity_groups',
|
||||
'class' => 'section'));
|
||||
if (Event::handle('StartShowGroupsMiniList', array($this))) {
|
||||
$this->element('h2', null, _('Groups'));
|
||||
$this->elementStart('h2');
|
||||
$this->statsSectionLink('usergroups', _('Groups'));
|
||||
$this->elementEnd('h2');
|
||||
|
||||
if ($groups) {
|
||||
$gml = new GroupMiniList($groups, $this->profile, $this);
|
||||
@ -258,10 +284,7 @@ class ProfileAction extends OwnerDesignAction
|
||||
|
||||
if ($cnt > GROUPS_PER_MINILIST) {
|
||||
$this->elementStart('p');
|
||||
$this->element('a', array('href' => common_local_url('usergroups',
|
||||
array('nickname' => $this->profile->nickname)),
|
||||
'class' => 'more'),
|
||||
_('All groups'));
|
||||
$this->statsSectionLink('usergroups', _('All groups'), 'more');
|
||||
$this->elementEnd('p');
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,8 @@ abstract class QueueManager extends IoManager
|
||||
$this->connect('deluser', 'DelUserQueueHandler');
|
||||
$this->connect('feedimp', 'FeedImporter');
|
||||
$this->connect('actimp', 'ActivityImporter');
|
||||
$this->connect('acctmove', 'AccountMover');
|
||||
$this->connect('actmove', 'ActivityMover');
|
||||
|
||||
// Broadcasting profile updates to OMB remote subscribers
|
||||
$this->connect('profile', 'ProfileQueueHandler');
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
class UserActivityStream extends AtomUserNoticeFeed
|
||||
{
|
||||
public $activities = array();
|
||||
|
||||
function __construct($user, $indent = true)
|
||||
{
|
||||
parent::__construct($user, null, $indent);
|
||||
@ -45,10 +47,15 @@ class UserActivityStream extends AtomUserNoticeFeed
|
||||
usort($objs, 'UserActivityStream::compareObject');
|
||||
|
||||
foreach ($objs as $obj) {
|
||||
$act = $obj->asActivity();
|
||||
$this->activities[] = $obj->asActivity();
|
||||
}
|
||||
}
|
||||
|
||||
function renderEntries()
|
||||
{
|
||||
foreach ($this->activities as $act) {
|
||||
// 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);
|
||||
$act->outputTo($this, false, ($act->actor->id != $this->user->uri));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ class UserProfile extends Widget
|
||||
$this->out->elementEnd('div');
|
||||
return;
|
||||
}
|
||||
if (Event::handle('StartProfilePageActionsSection', array(&$this->out, $this->profile))) {
|
||||
if (Event::handle('StartProfilePageActionsSection', array($this->out, $this->profile))) {
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
@ -250,13 +250,13 @@ class UserProfile extends Widget
|
||||
$this->out->element('h2', null, _('User actions'));
|
||||
$this->out->elementStart('ul');
|
||||
|
||||
if (Event::handle('StartProfilePageActionsElements', array(&$this->out, $this->profile))) {
|
||||
if (Event::handle('StartProfilePageActionsElements', array($this->out, $this->profile))) {
|
||||
if (empty($cur)) { // not logged in
|
||||
if (Event::handle('StartProfileRemoteSubscribe', array(&$this->out, $this->profile))) {
|
||||
if (Event::handle('StartProfileRemoteSubscribe', array($this->out, $this->profile))) {
|
||||
$this->out->elementStart('li', 'entity_subscribe');
|
||||
$this->showRemoteSubscribeLink();
|
||||
$this->out->elementEnd('li');
|
||||
Event::handle('EndProfileRemoteSubscribe', array(&$this->out, $this->profile));
|
||||
Event::handle('EndProfileRemoteSubscribe', array($this->out, $this->profile));
|
||||
}
|
||||
} else {
|
||||
if ($cur->id == $this->profile->id) { // your own page
|
||||
@ -376,13 +376,13 @@ class UserProfile extends Widget
|
||||
}
|
||||
}
|
||||
|
||||
Event::handle('EndProfilePageActionsElements', array(&$this->out, $this->profile));
|
||||
Event::handle('EndProfilePageActionsElements', array($this->out, $this->profile));
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('div');
|
||||
|
||||
Event::handle('EndProfilePageActionsSection', array(&$this->out, $this->profile));
|
||||
Event::handle('EndProfilePageActionsSection', array($this->out, $this->profile));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ class WebColor {
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function __construct($color = null)
|
||||
{
|
||||
if (isset($color)) {
|
||||
@ -77,7 +76,9 @@ class WebColor {
|
||||
if (preg_match('/(#([0-9A-Fa-f]{3,6})\b)/u', $color) > 0) {
|
||||
$this->setHexColor($color);
|
||||
} else {
|
||||
$errmsg = _('%s is not a valid color!');
|
||||
// TRANS: Web color exception thrown when a hexadecimal color code does not validate.
|
||||
// TRANS: %s is the provided (invalid) color code.
|
||||
$errmsg = _('%s is not a valid color! Use 3 or 6 hex characters.');
|
||||
throw new WebColorException(sprintf($errmsg, $color));
|
||||
}
|
||||
}
|
||||
@ -115,8 +116,8 @@ class WebColor {
|
||||
$hexcolor[1].$hexcolor[1],
|
||||
$hexcolor[2].$hexcolor[2]);
|
||||
} else {
|
||||
// TRANS: Validation error for a web colour.
|
||||
// TRANS: %s is the provided (invalid) text for colour.
|
||||
// TRANS: Web color exception thrown when a hexadecimal color code does not validate.
|
||||
// TRANS: %s is the provided (invalid) color code.
|
||||
$errmsg = _('%s is not a valid color! Use 3 or 6 hex characters.');
|
||||
throw new WebColorException(sprintf($errmsg, $hexcolor));
|
||||
}
|
||||
|
@ -173,6 +173,13 @@ class XRD
|
||||
switch($node->tagName) {
|
||||
case 'Title':
|
||||
$link['title'][] = $node->nodeValue;
|
||||
break;
|
||||
case 'Property':
|
||||
$link['property'][] = array('type' => $node->getAttribute('type'),
|
||||
'value' => $node->nodeValue);
|
||||
break;
|
||||
default:
|
||||
common_log(LOG_NOTICE, "Unexpected tag name {$node->tagName} found in XRD file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,9 @@ class XrdAction extends Action
|
||||
|
||||
$xrd->links[] = array('rel' => 'http://apinamespace.org/atom',
|
||||
'type' => 'application/atomsvc+xml',
|
||||
'href' => common_local_url('ApiAtomService', array('id' => $nick)));
|
||||
'href' => common_local_url('ApiAtomService', array('id' => $nick)),
|
||||
'property' => array(array('type' => 'http://apinamespace.org/atom/username',
|
||||
'value' => $nick)));
|
||||
|
||||
if (common_config('site', 'fancy')) {
|
||||
$apiRoot = common_path('api/', true);
|
||||
|
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
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
Loading…
Reference in New Issue
Block a user