Merge branch '0.9.x' into tinymce

This commit is contained in:
Brion Vibber 2010-08-10 15:01:29 -07:00
commit 819d33210d
541 changed files with 115862 additions and 43687 deletions

View File

@ -141,7 +141,7 @@ StartLogout: Before logging out
EndLogout: After logging out
- $action: the logout action
ArgsInitialized: After the argument array has been initialized
ArgsInitialize: After the argument array has been initialized
- $args: associative array of arguments, can be modified
StartAddressData: Allows the site owner to provide additional information about themselves for contact (e.g., tagline, email, location)
@ -818,3 +818,230 @@ EndDeleteUser: handling the post for deleting a user
- $action: action being shown
- $user: user being deleted
StartActivityStart: starting the output for a notice activity <event>
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$attrs: <entry> attributes (mostly namespace declarations, if any)
EndActivityStart: end the opening tag for an activity <event>
- &$notice: notice being output
- &$xs: XMLStringer for output
- $attrs: <entry> attributes (mostly namespace declarations, if any)
StartActivitySource: before outputting the <source> element for a notice activity
- &$notice: notice being output
- &$xs: XMLStringer for output
EndActivitySource: after outputting the <source> element for a notice activity
- &$notice: notice being output
- &$xs: XMLStringer for output
StartActivityTitle: before outputting notice activity title
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$title: title of the notice, mutable
EndActivityTitle: after outputting notice activity title
- $notice: notice being output
- &$xs: XMLStringer for output
- $title: title of the notice
StartActivityAuthor: before outputting atom author
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$atomAuthor: string for XML representing atom author
EndActivityAuthor: after outputting atom author
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$atomAuthor: string for XML representing atom author
StartActivityActor: before outputting activity actor element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$actor: string for XML representing activity actor
EndActivityActor: after outputting activity actor element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$actor: string for XML representing activity actor
StartActivityLink: before outputting activity HTML link element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$url: URL for activity HTML link element for a notice activity entry
EndActivityLink: before outputting activity HTML link element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $url: URL for activity HTML link element for a notice activity entry
StartActivityId: before outputting atom:id element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$id: atom:id (notice URI by default)
EndActivityId: after outputting atom:id element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $id: atom:id (notice URI by default)
StartActivityPublished: before outputting atom:published element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$published: atom:published value (notice created by default)
EndActivityPublished: before outputting atom:published element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $published: atom:published value (notice created by default)
StartActivityUpdated: before outputting atom:updated element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$updated: atom:updated value (same as atom:published by default)
EndActivityUpdated: after outputting atom:updated element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $updated: atom:updated value (same as atom:published by default)
StartActivityContent: before outputting atom:content element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$content: atom:content value (notice rendered HTML by default)
EndActivityContent: after outputting atom:content element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $content: atom:content value (notice rendered HTML by default)
StartActivityVerb: before outputting activity:verb element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$verb: activity:verb URI ('http://activitystrea.ms/schema/1.0/post' by default)
EndActivityVerb: after outputting activity:verb element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $verb: activity:verb URI ('http://activitystrea.ms/schema/1.0/post' by default)
StartActivityDefaultObjectType: before outputting activity:object-type element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$type: activity:object-type URI for default object ('http://activitystrea.ms/schema/1.0/note' by default)
EndActivityDefaultObjectType: after outputting activity:verb element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $type: activity:object-type URI for default object ('http://activitystrea.ms/schema/1.0/note' by default)
StartActivityObjects: before outputting activity:object elements for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$objects: array of ActivityObject objects to output (empty by default)
EndActivityObjects: after outputting activity:object elements for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $objects: array of ActivityObject objects to output (empty by default)
StartActivityNoticeInfo: before outputting statusnet:notice-info element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$noticeInfoAttr: array of attributes for notice info element
EndActivityNoticeInfo: after outputting statusnet:notice-info element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $noticeInfoAttr: array of attributes for notice info element
StartActivityInReplyTo: before outputting thr:in-reply-to element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$replyNotice: Notice object the main notice is in-reply-to
EndActivityInReplyTo: after outputting thr:in-reply-to element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $replyNotice: Notice object the main notice is in-reply-to
StartActivityConversation: before outputting ostatus:conversation link element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$conv: Conversation object
EndActivityConversation: after outputting ostatus:conversation link element for a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $conv: Conversation object
StartActivityAttentionProfiles: before outputting ostatus:attention link element for people in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$replyProfiles: array of profiles of people being replied to
EndActivityAttentionProfiles: after outputting ostatus:attention link element for people in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $replyProfiles: array of Profile object of people being replied to
StartActivityAttentionGroups: before outputting ostatus:attention link element for groups in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$groups: array of Group objects of groups being addressed
EndActivityAttentionGroups: after outputting ostatus:attention link element for groups in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $groups: array of Group objects of groups being addressed
StartActivityForward: before outputting ostatus:forward link element in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$repeat: Notice that was repeated
EndActivityForward: after outputting ostatus:forward link element in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $repeat: Notice that was repeated
StartActivityCategories: before outputting atom:category elements in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$tags: array of strings for tags on the notice (used for categories)
EndActivityCategories: after outputting atom:category elements in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $tags: array of strings for tags on the notice (used for categories)
StartActivityEnclosures: before outputting enclosure link elements in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$enclosures: array of enclosure objects (see File::getEnclosure() for details)
EndActivityEnclosures: after outputting enclosure link elements in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $enclosures: array of enclosure objects (see File::getEnclosure() for details)
StartActivityGeo: before outputting geo:rss element in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- &$lat: latitude
- &$lon: longitude
EndActivityGeo: after outputting geo:rss element in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output
- $lat: latitude
- $lon: longitude
StartActivityEnd: before the closing </entry> in a notice activity entry (last chance for data!)
- &$notice: notice being output
- &$xs: XMLStringer for output
EndActivityEnd: after the closing </entry> in a notice activity entry
- &$notice: notice being output
- &$xs: XMLStringer for output

110
README
View File

@ -2,8 +2,8 @@
README
------
StatusNet 0.9.0 ("Stand")
4 Mar 2010
StatusNet 0.9.3 ("Half a World Away")
29 June 2010
This is the README file for StatusNet, the Open Source microblogging
platform. It includes installation instructions, descriptions of
@ -77,57 +77,27 @@ for additional terms.
New this version
================
This is a major feature release since version 0.8.3, released Feb 1
2010. It is the final release version of 0.9.0, replacing any beta
versions.
This is a minor bug and feature release since version 0.9.2 released on
4 May 2010.
For best compatibility with client software and site federation, and a lot of
bug fixes, it is highly recommended that all public sites upgrade to the new
version.
Notable changes this version:
- Support for the new distributed status update standard OStatus
<http://ostatus.org>, based on PubSubHubbub, Salmon, Webfinger,
and Activity Streams.
- Support for location using the Geolocation API. Notices are (optionally)
marked with lat-long information with geo microformats, and can be shown
on a map.
- No fixed content size. Notice size is configurable, from 1 to
unlimited number of characters. Default is still 140!
- An authorization framework, allowing different levels of users.
- A Web-based administration panel.
- A moderation system that lets site moderators sandbox, silence,
or delete uncooperative users.
- A flag system that lets users flag profiles for moderator review.
- Support for OAuth <http://oauth.net> authentication in the Twitter
API.
- User roles system that lets the owner of the site to assign
administrator and moderator roles to other users.
- A pluggable authentication system.
- An authentication plugin for LDAP servers.
- Many features that were core in 0.8.x are now plugins, such
as OpenID, Twitter integration, Facebook integration
- A much-improved offline processing system
- In-browser "realtime" updates using a number of realtime
servers (Meteor, Orbited, Cometd)
- A plugin to provide an interface optimized for mobile browsers
- Support for Facebook Connect
- Support for logging in with a Twitter account
- Vastly improved translation with additional languages and
translation in plugins
- Support for all-SSL instances
- Core support for "repeats" (like Twitter's "retweets")
- Pluggable caching system, with plugins for Memcached,
APC, XCache, and a disk-based cache
- Plugin to support RSSCloud
- A framework for adding advertisements to a public site,
and plugins for Google AdSense and OpenX server
- Plugins to throttle excessive subscriptions and registrations.
- A plugin to blacklist particular URLs or nicknames.
- Enhanced API output to aid StatusNet-specific clients
- Many updates to user interface translation from TranslateWiki
- OStatus now works subscribing to SSL-protected sites by default
- OpenID now works on PHP 5.3, supports closer site integration.
- Numerous API and FOAF output fixes.
- Fixes to Facebook integration for FB API behavior changes
- PostgreSQL support updates
- Initial version of a custom theme uploader (disabled by default)
- LDAP auth plugins cleanup
- Many other bugfixes
There are also literally thousands of bugs fixed and minor features
added. A full changelog is available at http://status.net/wiki/StatusNet_0.9.0.
Under the covers, the software has a vastly improved plugin and
extension mechanism that makes writing powerful and flexible additions
to the core functionality much easier.
A full changelog is available at http://status.net/wiki/StatusNet_0.9.3.
Prerequisites
=============
@ -138,8 +108,8 @@ run correctly.
- PHP 5.2.3+. It may be possible to run this software on earlier
versions of PHP, but many of the functions used are only available
in PHP 5.2 or above. 5.2.6 or later is needed for XMPP background
daemons on 64-bit platforms. PHP 5.3.x should work but is known
to cause some failures for OpenID.
daemons on 64-bit platforms. PHP 5.3.x should work correctly in this
release, but problems with some plugins are possible.
- MySQL 5.x. The StatusNet database is stored, by default, in a MySQL
server. It has been primarily tested on 5.x servers, although it may
be possible to install on earlier (or later!) versions. The server
@ -239,9 +209,9 @@ especially if you've previously installed PHP/MySQL packages.
1. Unpack the tarball you downloaded on your Web server. Usually a
command like this will work:
tar zxf statusnet-0.9.0.tar.gz
tar zxf statusnet-0.9.2.tar.gz
...which will make a statusnet-0.9.0 subdirectory in your current
...which will make a statusnet-0.9.2 subdirectory in your current
directory. (If you don't have shell access on your Web server, you
may have to unpack the tarball on your local computer and FTP the
files to the server.)
@ -249,7 +219,7 @@ especially if you've previously installed PHP/MySQL packages.
2. Move the tarball to a directory of your choosing in your Web root
directory. Usually something like this will work:
mv statusnet-0.9.0 /var/www/statusnet
mv statusnet-0.9.2 /var/www/statusnet
This will make your StatusNet instance available in the statusnet path of
your server, like "http://example.net/statusnet". "microblog" or
@ -664,7 +634,7 @@ with this situation.
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
been tracking the "git" version of the software, you will probably
want to upgrade and keep your existing data. There is no automated
upgrade procedure in StatusNet 0.9.0. Try these step-by-step
upgrade procedure in StatusNet 0.9.2. Try these step-by-step
instructions; read to the end first before trying them.
0. Download StatusNet and set up all the prerequisites as if you were
@ -685,7 +655,7 @@ instructions; read to the end first before trying them.
5. Once all writing processes to your site are turned off, make a
final backup of the Web directory and database.
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
7. Unpack your StatusNet 0.9.0 tarball and move it to "statusnet" or
7. Unpack your StatusNet 0.9.2 tarball and move it to "statusnet" or
wherever your code used to be.
8. Copy the config.php file and avatar directory from your old
directory to your new directory.
@ -965,6 +935,26 @@ stomp_password: password for connecting to the stomp server; defaults
to null.
stomp_persistent: keep items across queue server restart, if enabled.
Under ActiveMQ, the server configuration determines if and how
persistent storage is actually saved.
If using a message queue server other than ActiveMQ, you may
need to disable this if it does not support persistence.
stomp_transactions: use transactions to aid in error detection.
A broken transaction will be seen quickly, allowing a message
to be redelivered immediately if a daemon crashes.
If using a message queue server other than ActiveMQ, you may
need to disable this if it does not support transactions.
stomp_acks: send acknowledgements to aid in flow control.
An acknowledgement of successful processing tells the server
we're ready for more and can help keep things moving smoothly.
This should *not* be turned off when running with ActiveMQ, but
if using another message queue server that does not support
acknowledgements you might need to disable this.
softlimit: an absolute or relative "soft memory limit"; daemons will
restart themselves gracefully when they find they've hit
@ -993,6 +983,12 @@ max_retries: for stomp, drop messages after N failed attempts to process.
dead_letter_dir: for stomp, optional directory to dump data on failed
queue processing events after discarding them.
stomp_no_transactions: for stomp, the server does not support transactions,
so do not try to user them. This is needed for http://www.morbidq.com/.
stomp_no_acks: for stomp, the server does not support acknowledgements.
so do not try to user them. This is needed for http://www.morbidq.com/.
license
-------
@ -1522,7 +1518,7 @@ repository (see below), and you get a compilation error ("unexpected
T_STRING") in the browser, check to see that you don't have any
conflicts in your code.
If you upgraded to StatusNet 0.9.0 without reading the "Notice
If you upgraded to StatusNet 0.9.2 without reading the "Notice
inboxes" section above, and all your users' 'Personal' tabs are empty,
read the "Notice inboxes" section above.

View File

@ -18,15 +18,19 @@
*
* @category Actions
* @package Actions
* @author Evan Prodromou <evan@status.net>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <millette@controlyourself.ca>
* @author Adrian Lang <mail@adrianlang.de>
* @author Meitar Moscovitz <meitarm@gmail.com>
* @author Sarven Capadisli <csarven@status.net>
* @author Brenda Wallace <shiny@cpan.org>
* @author Brion Vibber <brion@pobox.com>
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@controlyourself.ca>
* @author Meitar Moscovitz <meitarm@gmail.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <millette@status.net>
* @author Sarven Capadisli <csarven@status.net>
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
* @author Zach Copley <zach@status.net>
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license GNU Affero General Public License http://www.gnu.org/licenses/
* @link http://status.net
*/
@ -61,7 +65,7 @@ class AllAction extends ProfileAction
if ($this->page > 1 && $this->notice->N == 0) {
// TRANS: Server error when page not found (404)
$this->serverError(_('No such page'), $code = 404);
$this->serverError(_('No such page.'), $code = 404);
}
return true;
@ -139,10 +143,10 @@ class AllAction extends ProfileAction
$message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.');
} else {
// TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@"
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
}
} else {
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->user->nickname);
}
$this->elementStart('div', 'guide');

View File

@ -112,10 +112,12 @@ class AllrssAction extends Rss10Action
$c = array('url' => common_local_url('allrss',
array('nickname' =>
$user->nickname)),
// TRANS: Message is used as link title. %s is a user nickname.
'title' => sprintf(_('%s and friends'), $user->nickname),
'link' => common_local_url('all',
array('nickname' =>
$user->nickname)),
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
'description' => sprintf(_('Updates from %1$s and friends on %2$s!'),
$user->nickname, common_config('site', 'name')));
return $c;

View File

@ -21,8 +21,10 @@
*
* @category API
* @package StatusNet
* @author Brion Vibber <brion@pobox.com>
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <robin@millette.info>
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0

View File

@ -21,6 +21,7 @@
*
* @category API
* @package StatusNet
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
@ -103,7 +104,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
$this->clientError(
_(
'You must specify a parameter named ' .
'\'device\' with a value of one of: sms, im, none'
'\'device\' with a value of one of: sms, im, none.'
)
);
return;

View File

@ -22,7 +22,7 @@
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -131,7 +131,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
try {
$this->setColors($design);
} catch (WebColorException $e) {
$this->clientError($e->getMessage());
$this->clientError($e->getMessage(), 400, $this->format);
return false;
}
@ -153,7 +153,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
try {
$this->setColors($design);
} catch (WebColorException $e) {
$this->clientError($e->getMessage());
$this->clientError($e->getMessage(), 400, $this->format);
return false;
}

View File

@ -75,7 +75,7 @@ class ApiAccountVerifyCredentialsAction 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');

View File

@ -23,7 +23,7 @@
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -65,7 +65,7 @@ class ApiBlockCreateAction extends ApiAuthAction
parent::prepare($args);
$this->user = $this->auth_user;
$this->other = $this->getTargetUser($this->arg('id'));
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}

View File

@ -23,7 +23,7 @@
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -64,7 +64,7 @@ class ApiBlockDestroyAction extends ApiAuthAction
parent::prepare($args);
$this->user = $this->auth_user;
$this->other = $this->getTargetUser($this->arg('id'));
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}

View File

@ -232,7 +232,8 @@ class ApiDirectMessageAction extends ApiAuthAction
function showXmlDirectMessages()
{
$this->initDocument('xml');
$this->elementStart('direct-messages', array('type' => 'array'));
$this->elementStart('direct-messages', array('type' => 'array',
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
foreach ($this->messages as $m) {
$dm_array = $this->directMessageArray($m);

View File

@ -52,7 +52,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
class ApiDirectMessageNewAction extends ApiAuthAction
{
var $source = null;
var $other = null;
var $content = null;
@ -76,13 +75,6 @@ class ApiDirectMessageNewAction extends ApiAuthAction
return;
}
$this->source = $this->trimmed('source'); // Not supported by Twitter.
$reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
if (empty($this->source) || in_array($this->source, $reserved_sources)) {
$source = 'api';
}
$this->content = $this->trimmed('text');
$this->user = $this->auth_user;

View File

@ -25,6 +25,7 @@
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -123,7 +124,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
return;
}
$fave = Fave::addNew($this->user, $this->notice);
$fave = Fave::addNew($this->user->getProfile(), $this->notice);
if (empty($fave)) {
$this->clientError(

View File

@ -25,6 +25,7 @@
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/

View File

@ -24,7 +24,7 @@
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -67,7 +67,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
parent::prepare($args);
$this->user = $this->auth_user;
$this->other = $this->getTargetUser($id);
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}
@ -106,7 +106,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
if (empty($this->other)) {
$this->clientError(
_('Could not follow user: User not found.'),
_('Could not follow user: profile not found.'),
403,
$this->format
);

View File

@ -24,7 +24,7 @@
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -67,7 +67,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
parent::prepare($args);
$this->user = $this->auth_user;
$this->other = $this->getTargetUser($id);
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}
@ -125,8 +125,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
}
// throws an exception on error
Subscription::cancel($this->user->getProfile(),
$this->other->getProfile());
Subscription::cancel($this->user->getProfile(), $this->other);
$this->initDocument($this->format);
$this->showProfile($this->other, $this->format);

View File

@ -24,7 +24,7 @@
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -50,8 +50,8 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
{
var $user_a = null;
var $user_b = null;
var $profile_a = null;
var $profile_b = null;
/**
* Take arguments for running
@ -66,11 +66,8 @@ class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
{
parent::prepare($args);
$user_a_id = $this->trimmed('user_a');
$user_b_id = $this->trimmed('user_b');
$this->user_a = $this->getTargetUser($user_a_id);
$this->user_b = $this->getTargetUser($user_b_id);
$this->profile_a = $this->getTargetProfile($this->trimmed('user_a'));
$this->profile_b = $this->getTargetProfile($this->trimmed('user_b'));
return true;
}
@ -89,16 +86,16 @@ class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
{
parent::handle($args);
if (empty($this->user_a) || empty($this->user_b)) {
if (empty($this->profile_a) || empty($this->profile_b)) {
$this->clientError(
_('Two user ids or screen_names must be supplied.'),
_('Two valid IDs or screen_names must be supplied.'),
400,
$this->format
);
return;
}
$result = $this->user_a->isSubscribed($this->user_b);
$result = Subscription::exists($this->profile_a, $this->profile_b);
switch ($this->format) {
case 'xml':

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -263,7 +264,7 @@ class ApiGroupCreateAction extends ApiAuthAction
if (!$valid) {
$this->clientError(
sprintf(_('Invalid alias: "%s"'), $alias),
sprintf(_('Invalid alias: "%s".'), $alias),
403,
$this->format
);

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -92,7 +93,7 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
}
if (empty($this->group)) {
$this->clientError(_('Group not found!'), 404, $this->format);
$this->clientError(_('Group not found.'), 404, $this->format);
return false;
}

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -101,7 +102,7 @@ class ApiGroupJoinAction extends ApiAuthAction
}
if (empty($this->group)) {
$this->clientError(_('Group not found!'), 404, $this->format);
$this->clientError(_('Group not found.'), 404, $this->format);
return false;
}

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -101,7 +102,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
}
if (empty($this->group)) {
$this->clientError(_('Group not found!'), 404, $this->format);
$this->clientError(_('Group not found.'), 404, $this->format);
return false;
}

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -66,7 +67,13 @@ class ApiGroupListAction extends ApiBareAuthAction
{
parent::prepare($args);
$this->user = $this->getTargetUser($id);
$this->user = $this->getTargetUser(null);
if (empty($this->user)) {
$this->clientError(_('No such user.'), 404, $this->format);
return false;
}
$this->groups = $this->getGroups();
return true;
@ -86,12 +93,8 @@ class ApiGroupListAction extends ApiBareAuthAction
{
parent::handle($args);
if (empty($this->user)) {
$this->clientError(_('No such user.'), 404, $this->format);
return;
}
$sitename = common_config('site', 'name');
// TRANS: %s is a user name
$title = sprintf(_("%s's groups"), $this->user->nickname);
$taguribase = TagURI::base();
$id = "tag:$taguribase:Groups";
@ -99,10 +102,12 @@ class ApiGroupListAction extends ApiBareAuthAction
'usergroups',
array('nickname' => $this->user->nickname)
);
$subtitle = sprintf(
_("Groups %1$s is a member of on %2$s."),
$this->user->nickname,
$sitename
// TRANS: Meant to convey the user %2$s is a member of each of the groups listed on site %1$s
_("%1\$s groups %2\$s is a member of."),
$sitename,
$this->user->nickname
);
switch($this->format) {

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -66,7 +67,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
{
parent::prepare($args);
$this->user = $this->getTargetUser($id);
$this->user = $this->getTargetUser(null);
$this->groups = $this->getGroups();
return true;
@ -87,6 +88,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
parent::handle($args);
$sitename = common_config('site', 'name');
// TRANS: Message is used as a title. %s is a site name.
$title = sprintf(_("%s groups"), $sitename);
$taguribase = TagURI::base();
$id = "tag:$taguribase:Groups";
@ -137,11 +139,18 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
$qry = 'SELECT user_group.* '.
'from user_group join local_group on user_group.id = local_group.group_id '.
'order by created desc ';
$offset = intval($this->page - 1) * intval($this->count);
$limit = intval($this->count);
if (common_config('db', 'type') == 'pgsql') {
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
} else {
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
}
$group = new User_group();
$group->query($qry);
$groups = array();
while ($group->fetch()) {
$groups[] = clone($group);
}

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -88,7 +89,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
parent::handle($args);
if (empty($this->group)) {
$this->clientError(_('Group not found!'), 404, $this->format);
$this->clientError(_('Group not found.'), 404, $this->format);
return false;
}

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -79,7 +80,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
common_redirect(common_local_url('ApiGroupShow', $args), 301);
} else {
$this->clientError(
_('Group not found!'),
_('Group not found.'),
404,
$this->format
);

View File

@ -88,15 +88,15 @@ class ApiMediaUploadAction extends ApiAuthAction
try {
$upload = MediaFile::fromUpload('media', $this->auth_user);
} catch (ClientException $ce) {
$this->clientError($ce->getMessage());
} catch (Exception $e) {
$this->clientError($e->getMessage(), $e->getCode());
return;
}
if (isset($upload)) {
$this->showResponse($upload);
} else {
$this->clientError('Upload failed.');
$this->clientError(_('Upload failed.'));
return;
}
}

View File

@ -22,7 +22,7 @@
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2008-2009 StatusNet, Inc.
* @copyright 2008-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/apiprivateauth.php';
/**
* Action for outputting search results in Twitter compatible Atom
* format.
@ -44,10 +46,10 @@ 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/
*
* @see ApiAction
* @see ApiPrivateAuthAction
*/
class TwitapisearchatomAction extends ApiAction
class ApiSearchAtomAction extends ApiPrivateAuthAction
{
var $cnt;
@ -96,8 +98,11 @@ class TwitapisearchatomAction extends ApiAction
function prepare($args)
{
common_debug("in apisearchatom prepare()");
parent::prepare($args);
$this->query = $this->trimmed('q');
$this->lang = $this->trimmed('lang');
$this->rpp = $this->trimmed('rpp');
@ -138,6 +143,7 @@ class TwitapisearchatomAction extends ApiAction
function handle($args)
{
parent::handle($args);
common_debug("In apisearchatom handle()");
$this->showAtom();
}
@ -342,10 +348,24 @@ class TwitapisearchatomAction extends ApiAction
'rel' => 'related',
'href' => $profile->avatarUrl()));
// TODO: Here is where we'd put in a link to an atom feed for threads
// @todo: Here is where we'd put in a link to an atom feed for threads
$this->element("twitter:source", null,
htmlentities($this->sourceLink($notice->source)));
$source = null;
$ns = $notice->getSource();
if ($ns) {
if (!empty($ns->name) && !empty($ns->url)) {
$source = '<a href="'
. htmlspecialchars($ns->url)
. '" rel="nofollow">'
. htmlspecialchars($ns->name)
. '</a>';
} else {
$source = $ns->code;
}
}
$this->element("twitter:source", null, $source);
$this->elementStart('author');

View File

@ -22,7 +22,7 @@
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2008-2009 StatusNet, Inc.
* @copyright 2008-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -31,6 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/apiprivateauth.php';
require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
/**
@ -44,7 +45,7 @@ require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
* @see ApiAction
*/
class TwitapisearchjsonAction extends ApiAction
class ApiSearchJSONAction extends ApiPrivateAuthAction
{
var $query;
var $lang;
@ -64,6 +65,8 @@ class TwitapisearchjsonAction extends ApiAction
function prepare($args)
{
common_debug("apisearchjson prepare()");
parent::prepare($args);
$this->query = $this->trimmed('q');

View File

@ -29,6 +29,7 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -57,7 +58,7 @@ require_once INSTALLDIR . '/lib/apiauth.php';
class ApiStatusesDestroyAction extends ApiAuthAction
{
var $status = null;
var $status = null;
/**
* Take arguments for running
@ -99,39 +100,43 @@ class ApiStatusesDestroyAction extends ApiAuthAction
parent::handle($args);
if (!in_array($this->format, array('xml', 'json'))) {
$this->clientError(_('API method not found.'), $code = 404);
return;
$this->clientError(
_('API method not found.'),
404
);
return;
}
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
$this->clientError(_('This method requires a POST or DELETE.'),
400, $this->format);
return;
}
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
$this->clientError(
_('This method requires a POST or DELETE.'),
400,
$this->format
);
return;
}
if (empty($this->notice)) {
$this->clientError(_('No status found with that ID.'),
404, $this->format);
return;
}
if (empty($this->notice)) {
$this->clientError(
_('No status found with that ID.'),
404, $this->format
);
return;
}
if ($this->user->id == $this->notice->profile_id) {
$replies = new Reply;
$replies->get('notice_id', $this->notice_id);
$replies->delete();
$this->notice->delete();
if ($this->format == 'xml') {
$this->showSingleXmlStatus($this->notice);
} elseif ($this->format == 'json') {
$this->show_single_json_status($this->notice);
}
} else {
$this->clientError(_('You may not delete another user\'s status.'),
403, $this->format);
}
$this->showNotice();
if ($this->user->id == $this->notice->profile_id) {
$replies = new Reply;
$replies->get('notice_id', $this->notice_id);
$replies->delete();
$this->notice->delete();
$this->showNotice();
} else {
$this->clientError(
_('You may not delete another user\'s status.'),
403,
$this->format
);
}
}
/**

View File

@ -79,7 +79,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
$this->user = $this->auth_user;
if ($this->user->id == $notice->profile_id) {
if ($this->user->id == $this->original->profile_id) {
$this->clientError(_('Cannot repeat your own notice.'),
400, $this->format);
return false;

View File

@ -29,6 +29,7 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/

View File

@ -29,10 +29,102 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
/* External API usage documentation. Please update when you change how this method works. */
/*! @page statusesupdate statuses/update
@section Description
Updates the authenticating user's status. Requires the status parameter specified below.
Request must be a POST.
@par URL pattern
/api/statuses/update.:format
@par Formats (:format)
xml, json
@par HTTP Method(s)
POST
@par Requires Authentication
Yes
@param status (Required) The URL-encoded text of the status update.
@param source (Optional) The source of the status.
@param in_reply_to_status_id (Optional) The ID of an existing status that the update is in reply to.
@param lat (Optional) The latitude the status refers to.
@param long (Optional) The longitude the status refers to.
@param media (Optional) a media upload, such as an image or movie file.
@sa @ref authentication
@sa @ref apiroot
@subsection usagenotes Usage notes
@li The URL pattern is relative to the @ref apiroot.
@li If the @e source parameter is not supplied the source of the status will default to 'api'.
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
to encode the latitude and longitude (see example response below <georss:point>).
@li Data uploaded via the @e media parameter should be multipart/form-data encoded.
@subsection exampleusage Example usage
@verbatim
curl -u username:password http://example.com/api/statuses/update.xml -d status='Howdy!' -d lat='30.468' -d long='-94.743'
@endverbatim
@subsection exampleresponse Example response
@verbatim
<?xml version="1.0" encoding="UTF-8"?>
<status>
<text>Howdy!</text>
<truncated>false</truncated>
<created_at>Tue Mar 30 23:28:05 +0000 2010</created_at>
<in_reply_to_status_id/>
<source>api</source>
<id>26668724</id>
<in_reply_to_user_id/>
<in_reply_to_screen_name/>
<geo xmlns:georss="http://www.georss.org/georss">
<georss:point>30.468 -94.743</georss:point>
</geo>
<favorited>false</favorited>
<user>
<id>25803</id>
<name>Jed Sanders</name>
<screen_name>jedsanders</screen_name>
<location>Hoop and Holler, Texas</location>
<description>I like to think of myself as America's Favorite.</description>
<profile_image_url>http://avatar.example.com/25803-48-20080924200604.png</profile_image_url>
<url>http://jedsanders.net</url>
<protected>false</protected>
<followers_count>5</followers_count>
<profile_background_color/>
<profile_text_color/>
<profile_link_color/>
<profile_sidebar_fill_color/>
<profile_sidebar_border_color/>
<friends_count>2</friends_count>
<created_at>Wed Sep 24 20:04:00 +0000 2008</created_at>
<favourites_count>0</favourites_count>
<utc_offset>0</utc_offset>
<time_zone>UTC</time_zone>
<profile_background_image_url/>
<profile_background_tile>false</profile_background_tile>
<statuses_count>70</statuses_count>
<following>true</following>
<notifications>true</notifications>
</user>
</status>
@endverbatim
*/
if (!defined('STATUSNET')) {
exit(1);
}
@ -64,8 +156,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction
var $lat = null;
var $lon = null;
static $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
/**
* Take arguments for running
*
@ -80,19 +170,9 @@ class ApiStatusesUpdateAction extends ApiAuthAction
parent::prepare($args);
$this->status = $this->trimmed('status');
$this->source = $this->trimmed('source');
$this->lat = $this->trimmed('lat');
$this->lon = $this->trimmed('long');
// try to set the source attr from OAuth app
if (empty($this->source)) {
$this->source = $this->oauth_source;
}
if (empty($this->source) || in_array($this->source, self::$reserved_sources)) {
$this->source = 'api';
}
$this->in_reply_to_status_id
= intval($this->trimmed('in_reply_to_status_id'));
@ -116,7 +196,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->clientError(
_('This method requires a POST.'),
400, $this->format
400,
$this->format
);
return;
}
@ -137,7 +218,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
if (empty($this->status)) {
$this->clientError(
'Client must provide a \'status\' parameter with a value.',
_('Client must provide a \'status\' parameter with a value.'),
400,
$this->format
);
@ -199,7 +280,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
$reply_to = $this->in_reply_to_status_id;
} else {
$this->clientError(
_('Not found'),
_('Not found.'),
$code = 404,
$this->format
);
@ -211,8 +292,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction
try {
$upload = MediaFile::fromUpload('media', $this->auth_user);
} catch (ClientException $ce) {
$this->clientError($ce->getMessage());
} catch (Exception $e) {
$this->clientError($e->getMessage(), $e->getCode(), $this->format);
return;
}
@ -225,7 +306,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction
'Max notice size is %d chars, ' .
'including attachment URL.'
);
$this->clientError(sprintf($msg, Notice::maxContent()));
$this->clientError(
sprintf($msg, Notice::maxContent()),
400,
$this->format
);
}
}
@ -252,7 +337,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
$options
);
} catch (Exception $e) {
$this->clientError($e->getMessage());
$this->clientError($e->getMessage(), $e->getCode(), $this->format);
return;
}

View File

@ -103,9 +103,9 @@ class ApiStatusnetConfigAction extends ApiAction
$value = common_config($section, $setting);
if (is_array($value)) {
$value = implode(',', $value);
} else if ($value === false) {
} else if ($value === false || $value == '0') {
$value = 'false';
} else if ($value === true) {
} else if ($value === true || $value == '1') {
$value = 'true';
}

View File

@ -206,7 +206,8 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
{
switch ($this->format) {
case 'xml':
$this->elementStart('users', array('type' => 'array'));
$this->elementStart('users', array('type' => 'array',
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
foreach ($this->profiles as $profile) {
$this->showProfile(
$profile,

View File

@ -25,6 +25,7 @@
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -150,7 +151,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
@ -185,17 +186,23 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
{
$notices = array();
common_debug("since id = " . $this->since_id . " max id = " . $this->max_id);
if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
$notice = $this->user->favoriteNotices(
true,
($this->page-1) * $this->count,
$this->count,
true
$this->since_id,
$this->max_id
);
} else {
$notice = $this->user->favoriteNotices(
false,
($this->page-1) * $this->count,
$this->count,
false
$this->since_id,
$this->max_id
);
}

View File

@ -28,11 +28,107 @@
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
/* External API usage documentation. Please update when you change how this method works. */
/*! @page friendstimeline statuses/friends_timeline
@section Description
Returns the 20 most recent statuses posted by the authenticating
user and that user's friends. This is the equivalent of "You and
friends" page in the web interface.
@par URL patterns
@li /api/statuses/friends_timeline.:format
@li /api/statuses/friends_timeline/:id.:format
@par Formats (:format)
xml, json, rss, atom
@par ID (:id)
username, user id
@par HTTP Method(s)
GET
@par Requires Authentication
Sometimes (see: @ref authentication)
@param user_id (Optional) Specifies a user by ID
@param screen_name (Optional) Specifies a user by screename (nickname)
@param since_id (Optional) Returns only statuses with an ID greater
than (that is, more recent than) the specified ID.
@param max_id (Optional) Returns only statuses with an ID less than
(that is, older than) or equal to the specified ID.
@param count (Optional) Specifies the number of statuses to retrieve.
@param page (Optional) Specifies the page of results to retrieve.
@sa @ref authentication
@sa @ref apiroot
@subsection usagenotes Usage notes
@li The URL pattern is relative to the @ref apiroot.
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
to encode the latitude and longitude (see example response below <georss:point>).
@subsection exampleusage Example usage
@verbatim
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
@endverbatim
@subsection exampleresponse Example response
@verbatim
<?xml version="1.0"?>
<statuses type="array">
<status>
<text>back from the !yul !drupal meet with Evolving Web folk, @anarcat, @webchick and others, and an interesting refresher on SQL indexing</text>
<truncated>false</truncated>
<created_at>Wed Mar 31 01:33:02 +0000 2010</created_at>
<in_reply_to_status_id/>
<source>&lt;a href="http://code.google.com/p/microblog-purple/"&gt;mbpidgin&lt;/a&gt;</source>
<id>26674201</id>
<in_reply_to_user_id/>
<in_reply_to_screen_name/>
<geo/>
<favorited>false</favorited>
<user>
<id>246</id>
<name>Mark</name>
<screen_name>lambic</screen_name>
<location>Montreal, Canada</location>
<description>Geek</description>
<profile_image_url>http://avatar.identi.ca/246-48-20080702141545.png</profile_image_url>
<url>http://lambic.co.uk</url>
<protected>false</protected>
<followers_count>73</followers_count>
<profile_background_color>#F0F2F5</profile_background_color>
<profile_text_color/>
<profile_link_color>#002E6E</profile_link_color>
<profile_sidebar_fill_color>#CEE1E9</profile_sidebar_fill_color>
<profile_sidebar_border_color/>
<friends_count>58</friends_count>
<created_at>Wed Jul 02 14:12:15 +0000 2008</created_at>
<favourites_count>2</favourites_count>
<utc_offset>-14400</utc_offset>
<time_zone>US/Eastern</time_zone>
<profile_background_image_url/>
<profile_background_tile>false</profile_background_tile>
<statuses_count>933</statuses_count>
<following>false</following>
<notifications>false</notifications>
</user>
</status>
</statuses>
@endverbatim
*/
if (!defined('STATUSNET')) {
exit(1);
}
@ -116,6 +212,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
$id = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
$subtitle = sprintf(
// TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name.
_('Updates from %1$s and friends on %2$s!'),
$this->user->nickname,
$sitename
@ -152,7 +249,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);

View File

@ -25,7 +25,8 @@
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -88,7 +89,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
parent::handle($args);
if (empty($this->group)) {
$this->clientError(_('Group not found!'), 404, $this->format);
$this->clientError(_('Group not found.'), 404, $this->format);
return false;
}
@ -105,7 +106,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
function showTimeline()
{
// We'll pull common formatting out of this for other formats
$atom = new AtomGroupNoticeFeed($this->group);
$atom = new AtomGroupNoticeFeed($this->group, $this->auth_user);
$self = $this->getSelfUri();
@ -137,7 +138,9 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
$this->raw($atom->getString());
} catch (Atom10FeedException $e) {
$this->serverError(
'Could not generate feed for group - ' . $e->getMessage()
'Could not generate feed for group - ' . $e->getMessage(),
400,
$this->format
);
return;
}

View File

@ -29,6 +29,7 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -117,6 +118,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
$id = "tag:$taguribase:HomeTimeline:" . $this->user->id;
$subtitle = sprintf(
// TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name.
_('Updates from %1$s and friends on %2$s!'),
$this->user->nickname, $sitename
);
@ -151,7 +153,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);

View File

@ -29,6 +29,7 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -151,7 +152,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);

View File

@ -29,6 +29,7 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -55,6 +56,95 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
* @link http://status.net/
*/
/* External API usage documentation. Please update when you change how this method works. */
/*! @page publictimeline statuses/public_timeline
@section Description
Returns the 20 most recent notices from users throughout the system who have
uploaded their own avatars. Depending on configuration, it may or may not
not include notices from automatic posting services.
@par URL patterns
@li /api/statuses/public_timeline.:format
@par Formats (:format)
xml, json, rss, atom
@par HTTP Method(s)
GET
@par Requires Authentication
No
@param since_id (Optional) Returns only statuses with an ID greater
than (that is, more recent than) the specified ID.
@param max_id (Optional) Returns only statuses with an ID less than
(that is, older than) or equal to the specified ID.
@param count (Optional) Specifies the number of statuses to retrieve.
@param page (Optional) Specifies the page of results to retrieve.
@sa @ref apiroot
@subsection usagenotes Usage notes
@li The URL pattern is relative to the @ref apiroot.
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
to encode the latitude and longitude (see example response below <georss:point>).
@subsection exampleusage Example usage
@verbatim
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
@endverbatim
@subsection exampleresponse Example response
@verbatim
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
<text>@skwashd oh, commbank reenabled me super quick both times. but disconcerting when you don't expect it though</text>
<truncated>false</truncated>
<created_at>Sat Apr 17 00:49:12 +0000 2010</created_at>
<in_reply_to_status_id>28838393</in_reply_to_status_id>
<source>xmpp</source>
<id>28838456</id>
<in_reply_to_user_id>39303</in_reply_to_user_id>
<in_reply_to_screen_name>skwashd</in_reply_to_screen_name>
<geo></geo>
<favorited>false</favorited>
<user>
<id>44517</id>
<name>joshua may</name>
<screen_name>notjosh</screen_name>
<location></location>
<description></description>
<profile_image_url>http://avatar.identi.ca/44517-48-20090321004106.jpeg</profile_image_url>
<url></url>
<protected>false</protected>
<followers_count>17</followers_count>
<profile_background_color></profile_background_color>
<profile_text_color></profile_text_color>
<profile_link_color></profile_link_color>
<profile_sidebar_fill_color></profile_sidebar_fill_color>
<profile_sidebar_border_color></profile_sidebar_border_color>
<friends_count>20</friends_count>
<created_at>Sat Mar 21 00:40:25 +0000 2009</created_at>
<favourites_count>0</favourites_count>
<utc_offset>0</utc_offset>
<time_zone>UTC</time_zone>
<profile_background_image_url></profile_background_image_url>
<profile_background_tile>false</profile_background_tile>
<statuses_count>100</statuses_count>
<following>false</following>
<notifications>false</notifications>
</user>
</status>
[....]
</statuses>
@endverbatim
*/
class ApiTimelinePublicAction extends ApiPrivateAuthAction
{
@ -130,7 +220,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);

View File

@ -69,7 +69,7 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction
{
parent::prepare($args);
$this->serverError('Unimplemented', 503);
$this->serverError('Unimplemented.', 503);
return false;
}

View File

@ -117,7 +117,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);

View File

@ -26,6 +26,7 @@
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -138,7 +139,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed();
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);

View File

@ -29,6 +29,7 @@
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -115,7 +116,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
// We'll use the shared params from the Atom stub
// for other feed types.
$atom = new AtomUserNoticeFeed($this->user);
$atom = new AtomUserNoticeFeed($this->user, $this->auth_user);
$link = common_local_url(
'showstream',

View File

@ -22,7 +22,7 @@
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2008-2009 StatusNet, Inc.
* @copyright 2008-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/apiprivateauth.php';
/**
* Returns the top ten queries that are currently trending
*
@ -43,7 +45,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* @see ApiAction
*/
class TwitapitrendsAction extends ApiAction
class ApiTrendsAction extends ApiPrivateAuthAction
{
var $callback;
@ -82,7 +84,7 @@ class TwitapitrendsAction extends ApiAction
*/
function showTrends()
{
$this->serverError(_('API method under construction.'), $code = 501);
$this->serverError(_('API method under construction.'), 501);
}
}

View File

@ -113,7 +113,7 @@ class ApiUserShowAction extends ApiPrivateAuthAction
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');

View File

@ -103,7 +103,7 @@ class AvatarsettingsAction extends AccountSettingsAction
if (!$profile) {
common_log_db_error($user, 'SELECT', __FILE__);
$this->serverError(_('User without matching profile'));
$this->serverError(_('User without matching profile.'));
return;
}
@ -182,7 +182,7 @@ class AvatarsettingsAction extends AccountSettingsAction
if (!$profile) {
common_log_db_error($user, 'SELECT', __FILE__);
$this->serverError(_('User without matching profile'));
$this->serverError(_('User without matching profile.'));
return;
}

View File

@ -66,7 +66,7 @@ class BlockAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if ($cur->hasBlocked($this->profile)) {
$this->clientError(_("You already blocked that user."));
$this->clientError(_('You already blocked that user.'));
return false;
}
@ -87,13 +87,15 @@ class BlockAction extends ProfileFormAction
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) {
$this->returnToArgs();
$this->returnToPrevious();
} elseif ($this->arg('yes')) {
$this->handlePost();
$this->returnToArgs();
$this->returnToPrevious();
} else {
$this->showPage();
}
} else {
$this->showPage();
}
}
@ -118,6 +120,12 @@ class BlockAction extends ProfileFormAction
*/
function areYouSureForm()
{
// @fixme if we ajaxify the confirmation form, skip the preview on ajax hits
$profile = new ArrayWrapper(array($this->profile));
$preview = new ProfileList($profile, $this);
$preview->show();
$id = $this->profile->id;
$this->elementStart('form', array('id' => 'block-' . $id,
'method' => 'post',
@ -140,8 +148,20 @@ class BlockAction extends ProfileFormAction
$this->hidden($k, $v);
}
}
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user"));
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user'));
$this->submit('form_action-no',
// TRANS: Button label on the user block form.
_m('BUTTON','No'),
'submit form_action-primary',
'no',
// TRANS: Submit button title for 'No' when blocking a user.
_('Do not block this user'));
$this->submit('form_action-yes',
// TRANS: Button label on the user block form.
_m('BUTTON','Yes'),
'submit form_action-secondary',
'yes',
// TRANS: Submit button title for 'Yes' when blocking a user.
_('Block this user'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
@ -168,4 +188,45 @@ class BlockAction extends ProfileFormAction
return;
}
}
function showScripts()
{
parent::showScripts();
$this->autofocus('form_action-yes');
}
/**
* Override for form session token checks; on our first hit we're just
* requesting confirmation, which doesn't need a token. We need to be
* able to take regular GET requests from email!
*
* @throws ClientException if token is bad on POST request or if we have
* confirmation parameters which could trigger something.
*/
function checkSessionToken()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST' ||
$this->arg('yes') ||
$this->arg('no')) {
return parent::checkSessionToken();
}
}
/**
* If we reached this form without returnto arguments, return to the
* current user's subscription list.
*
* @return string URL
*/
function defaultReturnTo()
{
$user = common_current_user();
if ($user) {
return common_local_url('subscribers',
array('nickname' => $user->nickname));
} else {
return common_local_url('public');
}
}
}

View File

@ -47,7 +47,8 @@ class BookmarkletAction extends NewnoticeAction
{
function showTitle()
{
$this->element('title', null, _('Post to ').common_config('site', 'name'));
// TRANS: Title for mini-posting window loaded from bookmarklet.
$this->element('title', null, sprintf(_('Post to %s'), common_config('site', 'name')));
}
function showHeader()

View File

@ -87,10 +87,12 @@ class ConfirmaddressAction extends Action
}
$type = $confirm->address_type;
if (!in_array($type, array('email', 'jabber', 'sms'))) {
$this->serverError(sprintf(_('Unrecognized address type %s'), $type));
// TRANS: Server error for an unknow address type, which can be 'email', 'jabber', or 'sms'.
$this->serverError(sprintf(_('Unrecognized address type %s.'), $type));
return;
}
if ($cur->$type == $confirm->address) {
// TRANS: Client error for an already confirmed email/jabbel/sms address.
$this->clientError(_('That address has already been confirmed.'));
return;
}

View File

@ -150,13 +150,17 @@ class DeleteapplicationAction extends Action
'This will clear all data about the application from the '.
'database, including all existing user connections.'));
$this->submit('form_action-no',
_('No'),
// TRANS: Button label on the delete application form.
_m('BUTTON','No'),
'submit form_action-primary',
'no',
_("Do not delete this application"));
// TRANS: Submit button title for 'No' when deleting an application.
_('Do not delete this application'));
$this->submit('form_action-yes',
_('Yes'),
// TRANS: Button label on the delete application form.
_m('BUTTON','Yes'),
'submit form_action-secondary',
// TRANS: Submit button title for 'Yes' when deleting an application.
'yes', _('Delete this application'));
$this->elementEnd('fieldset');
$this->elementEnd('form');

View File

@ -142,8 +142,20 @@ class DeletenoticeAction extends Action
$this->hidden('token', common_session_token());
$this->hidden('notice', $this->trimmed('notice'));
$this->element('p', null, _('Are you sure you want to delete this notice?'));
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not delete this notice"));
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this notice'));
$this->submit('form_action-no',
// TRANS: Button label on the delete notice form.
_m('BUTTON','No'),
'submit form_action-primary',
'no',
// TRANS: Submit button title for 'No' when deleting a notice.
_("Do not delete this notice"));
$this->submit('form_action-yes',
// TRANS: Button label on the delete notice form.
_m('BUTTON','Yes'),
'submit form_action-secondary',
'yes',
// TRANS: Submit button title for 'Yes' when deleting a notice.
_('Delete this notice'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}

View File

@ -64,14 +64,14 @@ class DeleteuserAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::DELETEUSER)) {
$this->clientError(_("You cannot delete users."));
$this->clientError(_('You cannot delete users.'));
return false;
}
$this->user = User::staticGet('id', $this->profile->id);
if (empty($this->user)) {
$this->clientError(_("You can only delete local users."));
$this->clientError(_('You can only delete local users.'));
return false;
}
@ -92,10 +92,10 @@ class DeleteuserAction extends ProfileFormAction
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) {
$this->returnToArgs();
$this->returnToPrevious();
} elseif ($this->arg('yes')) {
$this->handlePost();
$this->returnToArgs();
$this->returnToPrevious();
} else {
$this->showPage();
}
@ -147,8 +147,20 @@ class DeleteuserAction extends ProfileFormAction
}
Event::handle('EndDeleteUserForm', array($this, $this->user));
}
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user"));
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this user'));
$this->submit('form_action-no',
// TRANS: Button label on the delete user form.
_m('BUTTON','No'),
'submit form_action-primary',
'no',
// TRANS: Submit button title for 'No' when deleting a user.
_('Do not block this user'));
$this->submit('form_action-yes',
// TRANS: Button label on the delete user form.
_m('BUTTON','Yes'),
'submit form_action-secondary',
'yes',
// TRANS: Submit button title for 'Yes' when deleting a user.
_('Delete this user'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}

View File

@ -59,6 +59,7 @@ class DesignadminpanelAction extends AdminPanelAction
function title()
{
// TRANS: Message used as title for design settings for the site.
return _('Design');
}
@ -125,9 +126,19 @@ class DesignadminpanelAction extends AdminPanelAction
return;
}
// check for an image upload
// check for file uploads
$bgimage = $this->saveBackgroundImage();
$customTheme = $this->saveCustomTheme();
$oldtheme = common_config('site', 'theme');
if ($customTheme) {
// This feels pretty hacky :D
$this->args['theme'] = $customTheme;
$themeChanged = true;
} else {
$themeChanged = ($this->trimmed('theme') != $oldtheme);
}
static $settings = array('theme', 'logo');
@ -139,15 +150,13 @@ class DesignadminpanelAction extends AdminPanelAction
$this->validate($values);
$oldtheme = common_config('site', 'theme');
$config = new Config();
$config->query('BEGIN');
// Only update colors if the theme has not changed.
if ($oldtheme == $values['theme']) {
if (!$themeChanged) {
$bgcolor = new WebColor($this->trimmed('design_background'));
$ccolor = new WebColor($this->trimmed('design_content'));
@ -189,6 +198,13 @@ class DesignadminpanelAction extends AdminPanelAction
Config::save('design', 'backgroundimage', $bgimage);
}
if (common_config('custom_css', 'enabled')) {
$css = $this->arg('css');
if ($css != common_config('custom_css', 'css')) {
Config::save('custom_css', 'css', $css);
}
}
$config->query('COMMIT');
}
@ -262,6 +278,33 @@ class DesignadminpanelAction extends AdminPanelAction
}
}
/**
* Save the custom theme if the user uploaded one.
*
* @return mixed custom theme name, if succesful, or null if no theme upload.
* @throws ClientException for invalid theme archives
* @throws ServerException if trouble saving the theme files
*/
function saveCustomTheme()
{
if (common_config('theme_upload', 'enabled') &&
$_FILES['design_upload_theme']['error'] == UPLOAD_ERR_OK) {
$upload = ThemeUploader::fromUpload('design_upload_theme');
$basedir = common_config('local', 'dir');
if (empty($basedir)) {
$basedir = INSTALLDIR . '/local';
}
$name = 'custom'; // @todo allow multiples, custom naming?
$outdir = $basedir . '/theme/' . $name;
$upload->extract($outdir);
return $name;
} else {
return null;
}
}
/**
* Attempt to validate setting values
*
@ -272,11 +315,11 @@ class DesignadminpanelAction extends AdminPanelAction
{
if (!empty($values['logo']) &&
!Validate::uri($values['logo'], array('allowed_schemes' => array('http', 'https')))) {
$this->clientError(_("Invalid logo URL."));
$this->clientError(_('Invalid logo URL.'));
}
if (!in_array($values['theme'], Theme::listAvailable())) {
$this->clientError(sprintf(_("Theme not available: %s"), $values['theme']));
$this->clientError(sprintf(_("Theme not available: %s."), $values['theme']));
}
}
@ -370,7 +413,15 @@ class DesignAdminPanelForm extends AdminForm
function formData()
{
$this->showLogo();
$this->showTheme();
$this->showBackground();
$this->showColors();
$this->showAdvanced();
}
function showLogo()
{
$this->out->elementStart('fieldset', array('id' => 'settings_design_logo'));
$this->out->element('legend', null, _('Change logo'));
@ -383,6 +434,11 @@ class DesignAdminPanelForm extends AdminForm
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset');
}
function showTheme()
{
$this->out->elementStart('fieldset', array('id' => 'settings_design_theme'));
$this->out->element('legend', null, _('Change theme'));
@ -406,10 +462,23 @@ class DesignAdminPanelForm extends AdminForm
false, $this->value('theme'));
$this->unli();
if (common_config('theme_upload', 'enabled')) {
$this->li();
$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'));
$this->out->element('p', 'form_guide', _('You can upload a custom StatusNet theme as a .ZIP archive.'));
$this->unli();
}
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset');
}
function showBackground()
{
$design = $this->out->design;
$this->out->elementStart('fieldset', array('id' =>
@ -454,6 +523,7 @@ class DesignAdminPanelForm extends AdminForm
$this->out->element('label', array('for' => 'design_background-image_on',
'class' => 'radio'),
// TRANS: Used as radio button label to add a background image.
_('On'));
$attrs = array('name' => 'design_background-image_onoff',
@ -470,6 +540,7 @@ class DesignAdminPanelForm extends AdminForm
$this->out->element('label', array('for' => 'design_background-image_off',
'class' => 'radio'),
// TRANS: Used as radio button label to not add a background image.
_('Off'));
$this->out->element('p', 'form_guide', _('Turn background image on or off.'));
$this->unli();
@ -483,6 +554,11 @@ class DesignAdminPanelForm extends AdminForm
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset');
}
function showColors()
{
$design = $this->out->design;
$this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
$this->out->element('legend', null, _('Change colours'));
@ -490,6 +566,7 @@ class DesignAdminPanelForm extends AdminForm
$this->out->elementStart('ul', 'form_data');
try {
// @fixme avoid loop unrolling in non-performance-critical contexts like this
$bgcolor = new WebColor($design->backgroundcolor);
@ -557,6 +634,7 @@ class DesignAdminPanelForm extends AdminForm
$this->unli();
} catch (WebColorException $e) {
// @fixme normalize them individually!
common_log(LOG_ERR, 'Bad color values in site design: ' .
$e->getMessage());
}
@ -566,6 +644,27 @@ class DesignAdminPanelForm extends AdminForm
$this->out->elementEnd('ul');
}
function showAdvanced()
{
if (common_config('custom_css', 'enabled')) {
$this->out->elementStart('fieldset', array('id' => 'settings_design_advanced'));
$this->out->element('legend', null, _('Advanced'));
$this->out->elementStart('ul', 'form_data');
$this->li();
$this->out->element('label', array('for' => 'css'), _('Custom CSS'));
$this->out->element('textarea', array('name' => 'css',
'id' => 'css',
'cols' => '50',
'rows' => '10'),
strval(common_config('custom_css', 'css')));
$this->unli();
$this->out->elementEnd('fieldset');
$this->out->elementEnd('ul');
}
}
/**
* Action elements
*

View File

@ -71,7 +71,7 @@ class DisfavorAction extends Action
$notice = Notice::staticGet($id);
$token = $this->trimmed('token-'.$notice->id);
if (!$token || $token != common_session_token()) {
$this->clientError(_("There was a problem with your session token. Try again, please."));
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return;
}
$fave = new Fave();

View File

@ -57,6 +57,7 @@ class EmailsettingsAction extends AccountSettingsAction
function title()
{
// TRANS: Title for e-mail settings.
return _('Email settings');
}
@ -68,6 +69,10 @@ class EmailsettingsAction extends AccountSettingsAction
function getInstructions()
{
// XXX: For consistency of parameters in messages, this should be a
// regular parameters, replaced with sprintf().
// TRANS: E-mail settings page instructions.
// TRANS: %%site.name%% is the name of the site.
return _('Manage how you get email from %%site.name%%.');
}
@ -97,102 +102,126 @@ class EmailsettingsAction extends AccountSettingsAction
common_local_url('emailsettings')));
$this->elementStart('fieldset');
$this->elementStart('fieldset', array('id' => 'settings_email_address'));
$this->element('legend', null, _('Address'));
// TRANS: Form legend for e-mail settings form.
$this->element('legend', null, _('Email address'));
$this->hidden('token', common_session_token());
if ($user->email) {
$this->element('p', array('id' => 'form_confirmed'), $user->email);
// TRANS: Form note in e-mail settings form.
$this->element('p', array('class' => 'form_note'), _('Current confirmed email address.'));
$this->hidden('email', $user->email);
$this->submit('remove', _('Remove'));
// TRANS: Button label to remove a confirmed e-mail address.
$this->submit('remove', _m('BUTTON','Remove'));
} else {
$confirm = $this->getConfirmation();
if ($confirm) {
$this->element('p', array('id' => 'form_unconfirmed'), $confirm->address);
// TRANS: Form note in e-mail settings form.
$this->element('p', array('class' => 'form_note'),
_('Awaiting confirmation on this address. '.
'Check your inbox (and spam box!) for a message '.
'with further instructions.'));
$this->hidden('email', $confirm->address);
$this->submit('cancel', _('Cancel'));
// TRANS: Button label to cancel an e-mail address confirmation procedure.
$this->submit('cancel', _m('BUTTON','Cancel'));
} else {
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
// TRANS: Field label for e-mail address input in e-mail settings form.
$this->input('email', _('Email address'),
($this->arg('email')) ? $this->arg('email') : null,
// TRANS: Instructions for e-mail address input form.
_('Email address, like "UserName@example.org"'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('add', _('Add'));
// TRANS: Button label for adding an e-mail address in e-mail settings form.
$this->submit('add', _m('BUTTON','Add'));
}
}
$this->elementEnd('fieldset');
if (common_config('emailpost', 'enabled') && $user->email) {
$this->elementStart('fieldset', array('id' => 'settings_email_incoming'));
// TRANS: Form legend for incoming e-mail settings form.
$this->element('legend', null, _('Incoming email'));
if ($user->incomingemail) {
$this->elementStart('p');
$this->element('span', 'address', $user->incomingemail);
// XXX: Looks a little awkward in the UI.
// Something like "xxxx@identi.ca Send email ..". Needs improvement.
$this->element('span', 'input_instructions',
// TRANS: Form instructions for incoming e-mail form in e-mail settings.
_('Send email to this address to post new notices.'));
$this->elementEnd('p');
$this->submit('removeincoming', _('Remove'));
// TRANS: Button label for removing a set sender e-mail address to post notices from.
$this->submit('removeincoming', _m('BUTTON','Remove'));
}
$this->elementStart('p');
$this->element('span', 'input_instructions',
// TRANS: Instructions for incoming e-mail address input form.
_('Make a new email address for posting to; '.
'cancels the old one.'));
$this->elementEnd('p');
$this->submit('newincoming', _('New'));
// TRANS: Button label for adding an e-mail address to send notices from.
$this->submit('newincoming', _m('BUTTON','New'));
$this->elementEnd('fieldset');
}
$this->elementStart('fieldset', array('id' => 'settings_email_preferences'));
$this->element('legend', null, _('Preferences'));
// TRANS: Form legend for e-mail preferences form.
$this->element('legend', null, _('Email preferences'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->checkbox('emailnotifysub',
// TRANS: Checkbox label in e-mail preferences form.
_('Send me notices of new subscriptions through email.'),
$user->emailnotifysub);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('emailnotifyfav',
// TRANS: Checkbox label in e-mail preferences form.
_('Send me email when someone '.
'adds my notice as a favorite.'),
$user->emailnotifyfav);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('emailnotifymsg',
// TRANS: Checkbox label in e-mail preferences form.
_('Send me email when someone sends me a private message.'),
$user->emailnotifymsg);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('emailnotifyattn',
// TRANS: Checkbox label in e-mail preferences form.
_('Send me email when someone sends me an "@-reply".'),
$user->emailnotifyattn);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('emailnotifynudge',
// TRANS: Checkbox label in e-mail preferences form.
_('Allow friends to nudge me and send me an email.'),
$user->emailnotifynudge);
$this->elementEnd('li');
if (common_config('emailpost', 'enabled')) {
$this->elementStart('li');
$this->checkbox('emailpost',
// TRANS: Checkbox label in e-mail preferences form.
_('I want to post notices by email.'),
$user->emailpost);
$this->elementEnd('li');
}
$this->elementStart('li');
$this->checkbox('emailmicroid',
// TRANS: Checkbox label in e-mail preferences form.
_('Publish a MicroID for my email address.'),
$user->emailmicroid);
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('save', _('Save'));
// TRANS: Button label to save e-mail preferences.
$this->submit('save', _m('BUTTON','Save'));
$this->elementEnd('fieldset');
$this->elementEnd('fieldset');
$this->elementEnd('form');
@ -253,6 +282,7 @@ class EmailsettingsAction extends AccountSettingsAction
} else if ($this->arg('newincoming')) {
$this->newIncoming();
} else {
// TRANS: Message given submitting a form with an unknown action in e-mail settings.
$this->showForm(_('Unexpected form submission.'));
}
}
@ -293,13 +323,15 @@ class EmailsettingsAction extends AccountSettingsAction
if ($result === false) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error updating e-mail preferences.
$this->serverError(_('Couldn\'t update user.'));
return;
}
$user->query('COMMIT');
$this->showForm(_('Preferences saved.'), true);
// TRANS: Confirmation message for successful e-mail preferences save.
$this->showForm(_('Email preferences saved.'), true);
}
/**
@ -317,6 +349,7 @@ class EmailsettingsAction extends AccountSettingsAction
// Some validation
if (!$email) {
// TRANS: Message given saving e-mail address without having provided one.
$this->showForm(_('No email address.'));
return;
}
@ -324,16 +357,20 @@ class EmailsettingsAction extends AccountSettingsAction
$email = common_canonical_email($email);
if (!$email) {
// TRANS: Message given saving e-mail address that cannot be normalised.
$this->showForm(_('Cannot normalize that email address'));
return;
}
if (!Validate::email($email, common_config('email', 'check_domain'))) {
// TRANS: Message given saving e-mail address that not valid.
$this->showForm(_('Not a valid email address.'));
return;
} else if ($user->email == $email) {
// TRANS: Message given saving e-mail address that is already set.
$this->showForm(_('That is already your email address.'));
return;
} else if ($this->emailExists($email)) {
// TRANS: Message given saving e-mail address that is already set for another user.
$this->showForm(_('That email address already belongs '.
'to another user.'));
return;
@ -350,12 +387,14 @@ class EmailsettingsAction extends AccountSettingsAction
if ($result === false) {
common_log_db_error($confirm, 'INSERT', __FILE__);
// TRANS: Server error thrown on database error adding e-mail confirmation code.
$this->serverError(_('Couldn\'t insert confirmation code.'));
return;
}
mail_confirm_address($user, $confirm->code, $user->nickname, $email);
// TRANS: Message given saving valid e-mail address that is to be confirmed.
$msg = _('A confirmation code was sent to the email address you added. '.
'Check your inbox (and spam box!) for the code and instructions '.
'on how to use it.');
@ -376,11 +415,13 @@ class EmailsettingsAction extends AccountSettingsAction
$confirm = $this->getConfirmation();
if (!$confirm) {
// TRANS: Message given canceling e-mail address confirmation that is not pending.
$this->showForm(_('No pending confirmation to cancel.'));
return;
}
if ($confirm->address != $email) {
$this->showForm(_('That is the wrong IM address.'));
// TRANS: Message given canceling e-mail address confirmation for the wrong e-mail address.
$this->showForm(_('That is the wrong email address.'));
return;
}
@ -388,11 +429,13 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$result) {
common_log_db_error($confirm, 'DELETE', __FILE__);
// TRANS: Server error thrown on database error canceling e-mail address confirmation.
$this->serverError(_('Couldn\'t delete email confirmation.'));
return;
}
$this->showForm(_('Confirmation cancelled.'), true);
// TRANS: Message given after successfully canceling e-mail address confirmation.
$this->showForm(_('Email confirmation cancelled.'), true);
}
/**
@ -410,6 +453,8 @@ class EmailsettingsAction extends AccountSettingsAction
// Maybe an old tab open...?
if ($user->email != $email) {
// TRANS: Message given trying to remove an e-mail address that is not
// TRANS: registered for the active user.
$this->showForm(_('That is not your email address.'));
return;
}
@ -424,12 +469,14 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$result) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error removing a registered e-mail address.
$this->serverError(_('Couldn\'t update user.'));
return;
}
$user->query('COMMIT');
$this->showForm(_('The address was removed.'), true);
// TRANS: Message given after successfully removing a registered e-mail address.
$this->showForm(_('The email address was removed.'), true);
}
/**
@ -453,9 +500,11 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error removing incoming e-mail address.
$this->serverError(_("Couldn't update user record."));
}
// TRANS: Message given after successfully removing an incoming e-mail address.
$this->showForm(_('Incoming email address removed.'), true);
}
@ -475,9 +524,11 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error adding incoming e-mail address.
$this->serverError(_("Couldn't update user record."));
}
// TRANS: Message given after successfully adding an incoming e-mail address.
$this->showForm(_('New incoming email address added.'), true);
}

View File

@ -72,7 +72,7 @@ class FavorAction extends Action
$notice = Notice::staticGet($id);
$token = $this->trimmed('token-'.$notice->id);
if (!$token || $token != common_session_token()) {
$this->clientError(_("There was a problem with your session token. Try again, please."));
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return;
}
if ($user->hasFave($notice)) {
@ -104,7 +104,7 @@ class FavorAction extends Action
}
/**
* Notifies a user when his notice is favorited.
* Notifies a user when their notice is favorited.
*
* @param class $notice favorited notice
* @param class $user user declaring a favorite

View File

@ -89,7 +89,7 @@ class FavoritesrssAction extends Rss10Action
function getNotices($limit=0)
{
$user = $this->user;
$notice = $user->favoriteNotices(0, $limit);
$notice = $user->favoriteNotices(false, 0, $limit);
$notices = array();
while ($notice->fetch()) {
$notices[] = clone($notice);

View File

@ -37,7 +37,7 @@ require_once INSTALLDIR.'/lib/omb.php';
* Handler for remote subscription finish callback
*
* When a remote user subscribes a local user, a redirect to this action is
* issued after the remote user authorized his service to subscribe.
* issued after the remote user authorized their service to subscribe.
*
* @category Action
* @package Laconica
@ -135,7 +135,7 @@ class FinishremotesubscribeAction extends Action
$service->getServiceURI(OMB_ENDPOINT_UPDATEPROFILE);
if (!$remote->update($orig_remote)) {
$this->serverError(_('Error updating remote profile'));
$this->serverError(_('Error updating remote profile.'));
return;
}

View File

@ -95,7 +95,9 @@ class FoafAction extends Action
// Would be nice to tell if they were a Person or not (e.g. a #person usertag?)
$this->elementStart('Agent', array('rdf:about' =>
$this->user->uri));
$this->element('mbox_sha1sum', null, sha1('mailto:' . $this->user->email));
if ($this->user->email) {
$this->element('mbox_sha1sum', null, sha1('mailto:' . $this->user->email));
}
if ($this->profile->fullname) {
$this->element('name', null, $this->profile->fullname);
}
@ -126,7 +128,7 @@ class FoafAction extends Action
$this->element('geo:lat', null, $location->lat);
}
if ($location->lon) {
$this->element('geo:long', null, $location->lat);
$this->element('geo:long', null, $location->lon);
}
if ($location->getURL()) {
$this->element('page', array('rdf:resource'=>$location->getURL()));
@ -152,7 +154,9 @@ class FoafAction extends Action
}
$person = $this->showMicrobloggingAccount($this->profile,
common_root_url(), $this->user->uri, false);
common_root_url(), $this->user->uri,
/*$fetchSubscriptions*/true,
/*$isSubscriber*/false);
// Get people who subscribe to user
@ -162,40 +166,29 @@ class FoafAction extends Action
if ($sub->find()) {
while ($sub->fetch()) {
if ($sub->token) {
$other = Remote_profile::staticGet('id', $sub->subscriber);
$profile = Profile::staticGet('id', $sub->subscriber);
} else {
$other = User::staticGet('id', $sub->subscriber);
$profile = Profile::staticGet('id', $sub->subscriber);
}
if (!$other) {
$profile = Profile::staticGet('id', $sub->subscriber);
if (empty($profile)) {
common_debug('Got a bad subscription: '.print_r($sub,true));
continue;
}
if (array_key_exists($other->uri, $person)) {
$person[$other->uri][0] = BOTH;
$user = $profile->getUser();
$other_uri = $profile->getUri();
if (array_key_exists($other_uri, $person)) {
$person[$other_uri][0] = BOTH;
} else {
$person[$other->uri] = array(LISTENER,
$other->id,
$profile->nickname,
(empty($sub->token)) ? 'User' : 'Remote_profile');
$person[$other_uri] = array(LISTENER,
$profile->id,
$profile->nickname,
$user ? 'local' : 'remote');
}
$other->free();
$other = null;
unset($other);
$profile->free();
$profile = null;
unset($profile);
}
}
$sub->free();
$sub = null;
unset($sub);
foreach ($person as $uri => $p) {
list($type, $id, $nickname, $cls) = $p;
list($type, $id, $nickname, $local) = $p;
if ($type == BOTH) {
$this->element('knows', array('rdf:resource' => $uri));
}
@ -206,8 +199,8 @@ class FoafAction extends Action
foreach ($person as $uri => $p) {
$foaf_url = null;
list($type, $id, $nickname, $cls) = $p;
if ($cls == 'User') {
list($type, $id, $nickname, $local) = $p;
if ($local == 'local') {
$foaf_url = common_local_url('foaf', array('nickname' => $nickname));
}
$profile = Profile::staticGet($id);
@ -216,9 +209,10 @@ class FoafAction extends Action
$this->element('knows', array('rdf:resource' => $this->user->uri));
}
$this->showMicrobloggingAccount($profile,
($cls == 'User') ? common_root_url() : null,
($local == 'local') ? common_root_url() : null,
$uri,
true);
/*$fetchSubscriptions*/false,
/*$isSubscriber*/($type == LISTENER || $type == BOTH));
if ($foaf_url) {
$this->element('rdfs:seeAlso', array('rdf:resource' => $foaf_url));
}
@ -243,7 +237,21 @@ class FoafAction extends Action
$this->elementEnd('PersonalProfileDocument');
}
function showMicrobloggingAccount($profile, $service=null, $useruri=null, $isSubscriber=false)
/**
* Output FOAF <account> bit for the given profile.
*
* @param Profile $profile
* @param mixed $service Root URL of this StatusNet instance for a local
* user, otherwise null.
* @param mixed $useruri URI string for the referenced profile..
* @param boolean $fetchSubscriptions Should we load and list all their subscriptions?
* @param boolean $isSubscriber if not fetching subs, we can still mark the user as following the current page.
*
* @return array if $fetchSubscribers is set, return a list of info on those
* subscriptions.
*/
function showMicrobloggingAccount($profile, $service=null, $useruri=null, $fetchSubscriptions=false, $isSubscriber=false)
{
$attr = array();
if ($useruri) {
@ -265,9 +273,7 @@ class FoafAction extends Action
$person = array();
if ($isSubscriber) {
$this->element('sioc:follows', array('rdf:resource'=>$this->user->uri . '#acct'));
} else {
if ($fetchSubscriptions) {
// Get people user is subscribed to
$sub = new Subscription();
$sub->subscriber = $profile->id;
@ -275,34 +281,26 @@ class FoafAction extends Action
if ($sub->find()) {
while ($sub->fetch()) {
if (!empty($sub->token)) {
$other = Remote_profile::staticGet('id', $sub->subscribed);
$profile = Profile::staticGet('id', $sub->subscribed);
} else {
$other = User::staticGet('id', $sub->subscribed);
$profile = Profile::staticGet('id', $sub->subscribed);
}
if (empty($other)) {
$profile = Profile::staticGet('id', $sub->subscribed);
if (empty($profile)) {
common_debug('Got a bad subscription: '.print_r($sub,true));
continue;
}
$this->element('sioc:follows', array('rdf:resource' => $other->uri.'#acct'));
$person[$other->uri] = array(LISTENEE,
$other->id,
$profile->nickname,
(empty($sub->token)) ? 'User' : 'Remote_profile');
$other->free();
$other = null;
unset($other);
$profile->free();
$profile = null;
$user = $profile->getUser();
$other_uri = $profile->getUri();
$this->element('sioc:follows', array('rdf:resource' => $other_uri.'#acct'));
$person[$other_uri] = array(LISTENEE,
$profile->id,
$profile->nickname,
$user ? 'local' : 'remote');
unset($profile);
}
}
$sub->free();
$sub = null;
unset($sub);
} else if ($isSubscriber) {
// Just declare that they follow the user whose FOAF we're showing.
$this->element('sioc:follows', array('rdf:resource' => $this->user->uri . '#acct'));
}
$this->elementEnd('OnlineAccount');

View File

@ -56,7 +56,7 @@ class FoafGroupAction extends Action
return false;
}
$local = Local_group::staticGet('nickname', $nickname);
$local = Local_group::staticGet('nickname', $this->nickname);
if (!$local) {
$this->clientError(_('No such group.'), 404);
@ -126,7 +126,8 @@ class FoafGroupAction extends Action
while ($members->fetch()) {
$member_uri = common_local_url('userbyid', array('id'=>$members->id));
$member_details[$member_uri] = array(
'nickname' => $members->nickname
'nickname' => $members->nickname,
'is_admin' => false,
);
$this->element('member', array('rdf:resource' => $member_uri));
}

View File

@ -37,6 +37,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* @category Action
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*/

View File

@ -59,11 +59,11 @@ class GrantRoleAction extends ProfileFormAction
$this->role = $this->arg('role');
if (!Profile_role::isValid($this->role)) {
$this->clientError(_("Invalid role."));
$this->clientError(_('Invalid role.'));
return false;
}
if (!Profile_role::isSettable($this->role)) {
$this->clientError(_("This role is reserved and cannot be set."));
$this->clientError(_('This role is reserved and cannot be set.'));
return false;
}
@ -72,14 +72,14 @@ class GrantRoleAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::GRANTROLE)) {
$this->clientError(_("You cannot grant user roles on this site."));
$this->clientError(_('You cannot grant user roles on this site.'));
return false;
}
assert(!empty($this->profile)); // checked by parent
if ($this->profile->hasRole($this->role)) {
$this->clientError(_("User already has this role."));
$this->clientError(_('User already has this role.'));
return false;
}

View File

@ -41,7 +41,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* @link http://status.net/
*/
class GroupblockAction extends Action
class GroupblockAction extends RedirectingAction
{
var $profile = null;
var $group = null;
@ -117,9 +117,7 @@ class GroupblockAction extends Action
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) {
common_redirect(common_local_url('groupmembers',
array('nickname' => $this->group->nickname)),
303);
$this->returnToPrevious();
} elseif ($this->arg('yes')) {
$this->blockProfile();
} elseif ($this->arg('blockto')) {
@ -175,8 +173,20 @@ class GroupblockAction extends Action
$this->hidden($k, $v);
}
}
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group"));
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group'));
$this->submit('form_action-no',
// TRANS: Button label on the form to block a user from a group.
_m('BUTTON','No'),
'submit form_action-primary',
'no',
// TRANS: Submit button title for 'No' when blocking a user from a group.
_('Do not block this user from this group'));
$this->submit('form_action-yes',
// TRANS: Button label on the form to block a user from a group.
_m('BUTTON','Yes'),
'submit form_action-secondary',
'yes',
// TRANS: Submit button title for 'Yes' when blocking a user from a group.
_('Block this user from this group'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
@ -196,23 +206,27 @@ class GroupblockAction extends Action
$this->serverError(_("Database error blocking user from group."));
return false;
}
// Now, gotta figure where we go back to
foreach ($this->args as $k => $v) {
if ($k == 'returnto-action') {
$action = $v;
} elseif (substr($k, 0, 9) == 'returnto-') {
$args[substr($k, 9)] = $v;
}
}
if ($action) {
common_redirect(common_local_url($action, $args), 303);
} else {
common_redirect(common_local_url('groupmembers',
array('nickname' => $this->group->nickname)),
303);
}
$this->returnToPrevious();
}
/**
* If we reached this form without returnto arguments, default to
* the top of the group's member list.
*
* @return string URL
*/
function defaultReturnTo()
{
return common_local_url('groupmembers',
array('nickname' => $this->group->nickname));
}
function showScripts()
{
parent::showScripts();
$this->autofocus('form_action-yes');
}
}

View File

@ -205,13 +205,13 @@ class GroupMemberListItem extends ProfileListItem
!$this->profile->isAdmin($this->group)) {
$this->out->elementStart('li', 'entity_make_admin');
$maf = new MakeAdminForm($this->out, $this->profile, $this->group,
array('action' => 'groupmembers',
'nickname' => $this->group->nickname));
$this->returnToArgs());
$maf->show();
$this->out->elementEnd('li');
}
}
function showGroupBlockForm()
{
$user = common_current_user();
@ -219,12 +219,49 @@ class GroupMemberListItem extends ProfileListItem
if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) {
$this->out->elementStart('li', 'entity_block');
$bf = new GroupBlockForm($this->out, $this->profile, $this->group,
array('action' => 'groupmembers',
'nickname' => $this->group->nickname));
$this->returnToArgs());
$bf->show();
$this->out->elementEnd('li');
}
}
function linkAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'members')) {
$aAttrs['rel'] .= ' nofollow';
}
return $aAttrs;
}
function homepageAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'members')) {
$aAttrs['rel'] = 'nofollow';
}
return $aAttrs;
}
/**
* Fetch necessary return-to arguments for the profile forms
* to return to this list when they're done.
*
* @return array
*/
protected function returnToArgs()
{
$args = array('action' => 'groupmembers',
'nickname' => $this->group->nickname);
$page = $this->out->arg('page');
if ($page) {
$args['param-page'] = $page;
}
return $args;
}
}

View File

@ -135,8 +135,10 @@ class groupRssAction extends Rss10Action
$c = array('url' => common_local_url('grouprss',
array('nickname' =>
$group->nickname)),
// TRANS: Message is used as link title. %s is a user nickname.
'title' => sprintf(_('%s timeline'), $group->nickname),
'link' => common_local_url('showgroup', array('nickname' => $group->nickname)),
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
'description' => sprintf(_('Updates from members of %1$s on %2$s!'),
$group->nickname, common_config('site', 'name')));
return $c;

View File

@ -56,6 +56,7 @@ class ImsettingsAction extends ConnectSettingsAction
function title()
{
// TRANS: Title for instance messaging settings.
return _('IM settings');
}
@ -67,6 +68,9 @@ class ImsettingsAction extends ConnectSettingsAction
function getInstructions()
{
// TRANS: Instant messaging settings page instructions.
// TRANS: [instant messages] is link text, "(%%doc.im%%)" is the link.
// TRANS: the order and formatting of link text and link should remain unchanged.
return _('You can send and receive notices through '.
'Jabber/GTalk [instant messages](%%doc.im%%). '.
'Configure your address and settings below.');
@ -86,6 +90,7 @@ class ImsettingsAction extends ConnectSettingsAction
{
if (!common_config('xmpp', 'enabled')) {
$this->element('div', array('class' => 'error'),
// TRANS: Message given in the IM settings if XMPP is not enabled on the site.
_('IM is not available.'));
return;
}
@ -97,32 +102,41 @@ class ImsettingsAction extends ConnectSettingsAction
'action' =>
common_local_url('imsettings')));
$this->elementStart('fieldset', array('id' => 'settings_im_address'));
$this->element('legend', null, _('Address'));
// TRANS: Form legend for IM settings form.
$this->element('legend', null, _('IM address'));
$this->hidden('token', common_session_token());
if ($user->jabber) {
$this->element('p', 'form_confirmed', $user->jabber);
// TRANS: Form note in IM settings form.
$this->element('p', 'form_note',
_('Current confirmed Jabber/GTalk address.'));
$this->hidden('jabber', $user->jabber);
$this->submit('remove', _('Remove'));
// TRANS: Button label to remove a confirmed IM address.
$this->submit('remove', _m('BUTTON','Remove'));
} else {
$confirm = $this->getConfirmation();
if ($confirm) {
$this->element('p', 'form_unconfirmed', $confirm->address);
$this->element('p', 'form_note',
// TRANS: Form note in IM settings form.
// TRANS: %s is the IM address set for the site.
sprintf(_('Awaiting confirmation on this address. '.
'Check your Jabber/GTalk account for a '.
'message with further instructions. '.
'(Did you add %s to your buddy list?)'),
jabber_daemon_address()));
$this->hidden('jabber', $confirm->address);
$this->submit('cancel', _('Cancel'));
// TRANS: Button label to cancel an IM address confirmation procedure.
$this->submit('cancel', _m('BUTTON','Cancel'));
} else {
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
// TRANS: Field label for IM address input in IM settings form.
$this->input('jabber', _('IM address'),
($this->arg('jabber')) ? $this->arg('jabber') : null,
// TRANS: IM address input field instructions in IM settings form.
// TRANS: %s is the IM address set for the site.
sprintf(_('Jabber or GTalk address, '.
'like "UserName@example.org". '.
'First, make sure to add %s to your '.
@ -130,37 +144,44 @@ class ImsettingsAction extends ConnectSettingsAction
jabber_daemon_address()));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('add', _('Add'));
// TRANS: Button label for adding an IM address in IM settings form.
$this->submit('add', _m('BUTTON','Add'));
}
}
$this->elementEnd('fieldset');
$this->elementStart('fieldset', array('id' => 'settings_im_preferences'));
$this->element('legend', null, _('Preferences'));
// TRANS: Form legend for IM preferences form.
$this->element('legend', null, _('IM preferences'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->checkbox('jabbernotify',
// TRANS: Checkbox label in IM preferences form.
_('Send me notices through Jabber/GTalk.'),
$user->jabbernotify);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('updatefrompresence',
// TRANS: Checkbox label in IM preferences form.
_('Post a notice when my Jabber/GTalk status changes.'),
$user->updatefrompresence);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('jabberreplies',
// TRANS: Checkbox label in IM preferences form.
_('Send me replies through Jabber/GTalk '.
'from people I\'m not subscribed to.'),
$user->jabberreplies);
$this->elementEnd('li');
$this->elementStart('li');
$this->checkbox('jabbermicroid',
// TRANS: Checkbox label in IM preferences form.
_('Publish a MicroID for my Jabber/GTalk address.'),
$user->jabbermicroid);
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('save', _('Save'));
// TRANS: Button label to save IM preferences.
$this->submit('save', _m('BUTTON','Save'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
@ -217,6 +238,7 @@ class ImsettingsAction extends ConnectSettingsAction
} else if ($this->arg('remove')) {
$this->removeAddress();
} else {
// TRANS: Message given submitting a form with an unknown action in IM settings.
$this->showForm(_('Unexpected form submission.'));
}
}
@ -232,7 +254,6 @@ class ImsettingsAction extends ConnectSettingsAction
function savePreferences()
{
$jabbernotify = $this->boolean('jabbernotify');
$updatefrompresence = $this->boolean('updatefrompresence');
$jabberreplies = $this->boolean('jabberreplies');
@ -255,12 +276,14 @@ class ImsettingsAction extends ConnectSettingsAction
if ($result === false) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error updating IM preferences.
$this->serverError(_('Couldn\'t update user.'));
return;
}
$user->query('COMMIT');
// TRANS: Confirmation message for successful IM preferences save.
$this->showForm(_('Preferences saved.'), true);
}
@ -282,6 +305,7 @@ class ImsettingsAction extends ConnectSettingsAction
// Some validation
if (!$jabber) {
// TRANS: Message given saving IM address without having provided one.
$this->showForm(_('No Jabber ID.'));
return;
}
@ -289,16 +313,20 @@ class ImsettingsAction extends ConnectSettingsAction
$jabber = jabber_normalize_jid($jabber);
if (!$jabber) {
// TRANS: Message given saving IM address that cannot be normalised.
$this->showForm(_('Cannot normalize that Jabber ID'));
return;
}
if (!jabber_valid_base_jid($jabber)) {
if (!jabber_valid_base_jid($jabber, common_config('email', 'domain_check'))) {
// TRANS: Message given saving IM address that not valid.
$this->showForm(_('Not a valid Jabber ID'));
return;
} else if ($user->jabber == $jabber) {
// TRANS: Message given saving IM address that is already set.
$this->showForm(_('That is already your Jabber ID.'));
return;
} else if ($this->jabberExists($jabber)) {
// TRANS: Message given saving IM address that is already set for another user.
$this->showForm(_('Jabber ID already belongs to another user.'));
return;
}
@ -316,6 +344,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.'));
return;
}
@ -324,6 +353,8 @@ class ImsettingsAction extends ConnectSettingsAction
$user->nickname,
$jabber);
// TRANS: Message given saving valid IM address that is to be confirmed.
// TRANS: %s is the IM address set for the site.
$msg = sprintf(_('A confirmation code was sent '.
'to the IM address you added. '.
'You must approve %s for '.
@ -348,10 +379,12 @@ class ImsettingsAction extends ConnectSettingsAction
$confirm = $this->getConfirmation();
if (!$confirm) {
// TRANS: Message given canceling IM address confirmation that is not pending.
$this->showForm(_('No pending confirmation to cancel.'));
return;
}
if ($confirm->address != $jabber) {
// TRANS: Message given canceling IM address confirmation for the wrong IM address.
$this->showForm(_('That is the wrong IM address.'));
return;
}
@ -360,11 +393,13 @@ class ImsettingsAction extends ConnectSettingsAction
if (!$result) {
common_log_db_error($confirm, 'DELETE', __FILE__);
$this->serverError(_('Couldn\'t delete email confirmation.'));
// TRANS: Server error thrown on database error canceling IM address confirmation.
$this->serverError(_('Couldn\'t delete IM confirmation.'));
return;
}
$this->showForm(_('Confirmation cancelled.'), true);
// TRANS: Message given after successfully canceling IM address confirmation.
$this->showForm(_('IM confirmation cancelled.'), true);
}
/**
@ -384,6 +419,8 @@ class ImsettingsAction extends ConnectSettingsAction
// Maybe an old tab open...?
if ($user->jabber != $jabber) {
// TRANS: Message given trying to remove an IM address that is not
// TRANS: registered for the active user.
$this->showForm(_('That is not your Jabber ID.'));
return;
}
@ -398,6 +435,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.'));
return;
}
@ -405,7 +443,8 @@ class ImsettingsAction extends ConnectSettingsAction
// XXX: unsubscribe to the old address
$this->showForm(_('The address was removed.'), true);
// TRANS: Message given after successfully removing a registered IM address.
$this->showForm(_('The IM address was removed.'), true);
}
/**

View File

@ -38,7 +38,7 @@ class InviteAction extends CurrentUserDesignAction
if (!common_config('invite', 'enabled')) {
$this->clientError(_('Invites have been disabled.'));
} else if (!common_logged_in()) {
$this->clientError(sprintf(_('You must be logged in to invite other users to use %s'),
$this->clientError(sprintf(_('You must be logged in to invite other users to use %s.'),
common_config('site', 'name')));
return;
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
@ -224,8 +224,10 @@ class InviteAction extends CurrentUserDesignAction
$headers['From'] = mail_notify_from();
$headers['To'] = trim($email);
// TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral singular 3rd-person pronoun in English.
$headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename);
// TRANS: Body text for invitation email. Note that 'them' is correct as a gender-neutral singular 3rd-person pronoun in English.
$body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n".
"%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
"You can also share news about yourself, your thoughts, or your life online with people who know about you. ".

View File

@ -62,6 +62,28 @@ class LoginAction extends Action
return false;
}
/**
* Prepare page to run
*
*
* @param $args
* @return string title
*/
function prepare($args)
{
parent::prepare($args);
// @todo this check should really be in index.php for all sensitive actions
$ssl = common_config('site', 'ssl');
if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) {
common_redirect(common_local_url('login'));
// exit
}
return true;
}
/**
* Handle input, produce output
*
@ -267,9 +289,13 @@ class LoginAction extends Action
'user name and password ' .
'before changing your settings.');
} else {
return _('Login with your username and password. ' .
'Don\'t have a username yet? ' .
'[Register](%%action.register%%) a new account.');
$prompt = _('Login with your username and password.');
if (!common_config('site', 'closed') && !common_config('site', 'inviteonly')) {
$prompt .= ' ';
$prompt .= _('Don\'t have a username yet? ' .
'[Register](%%action.register%%) a new account.');
}
return $prompt;
}
}

View File

@ -41,7 +41,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* @link http://status.net/
*/
class MakeadminAction extends Action
class MakeadminAction extends RedirectingAction
{
var $profile = null;
var $group = null;
@ -148,20 +148,19 @@ class MakeadminAction extends Action
$this->group->getBestName());
}
foreach ($this->args as $k => $v) {
if ($k == 'returnto-action') {
$action = $v;
} else if (substr($k, 0, 9) == 'returnto-') {
$args[substr($k, 9)] = $v;
}
}
if ($action) {
common_redirect(common_local_url($action, $args), 303);
} else {
common_redirect(common_local_url('groupmembers',
array('nickname' => $this->group->nickname)),
303);
}
$this->returnToArgs();
}
/**
* If we reached this form without returnto arguments, default to
* the top of the group's member list.
*
* @return string URL
*/
function defaultReturnTo()
{
return common_local_url('groupmembers',
array('nickname' => $this->group->nickname));
}
}

View File

@ -66,7 +66,7 @@ class MicrosummaryAction extends Action
$notice = $user->getCurrentNotice();
if (!$notice) {
$this->clientError(_('No current status'), 404);
$this->clientError(_('No current status.'), 404);
}
header('Content-Type: text/plain');

View File

@ -184,13 +184,21 @@ class NewnoticeAction extends Action
$options = array('reply_to' => ($replyto == 'false') ? null : $replyto);
if ($user->shareLocation() && $this->arg('notice_data-geo')) {
$locOptions = Notice::locationOptions($this->trimmed('lat'),
$this->trimmed('lon'),
$this->trimmed('location_id'),
$this->trimmed('location_ns'),
$user->getProfile());
if ($user->shareLocation()) {
// use browser data if checked; otherwise profile data
if ($this->arg('notice_data-geo')) {
$locOptions = Notice::locationOptions($this->trimmed('lat'),
$this->trimmed('lon'),
$this->trimmed('location_id'),
$this->trimmed('location_ns'),
$user->getProfile());
} else {
$locOptions = Notice::locationOptions(null,
null,
null,
null,
$user->getProfile());
}
$options = array_merge($options, $locOptions);
}
@ -201,8 +209,6 @@ class NewnoticeAction extends Action
$upload->attachToNotice($notice);
}
if ($this->boolean('ajax')) {
header('Content-Type: text/xml;charset=utf-8');
$this->xw->startDocument('1.0', 'UTF-8');

View File

@ -82,7 +82,7 @@ class NudgeAction extends Action
}
if (!$other->email || !$other->emailnotifynudge) {
$this->clientError(_('This user doesn\'t allow nudges or hasn\'t confirmed or set his email yet.'));
$this->clientError(_('This user doesn\'t allow nudges or hasn\'t confirmed or set their email yet.'));
return;
}

View File

@ -183,7 +183,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
if (!$result) {
common_log_db_error($orig, 'DELETE', __FILE__);
$this->clientError(_('Unable to revoke access for app: ' . $app->id));
$this->clientError(sprintf(_('Unable to revoke access for app: %s.'), $app->id));
return false;
}
@ -195,7 +195,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
function showEmptyListMessage()
{
$message = sprintf(_('You have not authorized any applications to use your account.'));
$message = _('You have not authorized any applications to use your account.');
$this->elementStart('div', 'guide');
$this->raw(common_markup_to_html($message));

View File

@ -23,6 +23,7 @@
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2008 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
@ -60,7 +61,7 @@ class OembedAction extends Action
$proxy_args = $r->map($path);
if (!$proxy_args) {
$this->serverError(_("$path not found"), 404);
$this->serverError(_("$path not found."), 404);
}
$oembed=array();
$oembed['version']='1.0';
@ -72,11 +73,11 @@ class OembedAction extends Action
$id = $proxy_args['notice'];
$notice = Notice::staticGet($id);
if(empty($notice)){
$this->serverError(_("notice $id not found"), 404);
$this->serverError(_("Notice $id not found."), 404);
}
$profile = $notice->getProfile();
if (empty($profile)) {
$this->serverError(_('Notice has no profile'), 500);
$this->serverError(_('Notice has no profile.'), 500);
}
if (!empty($profile->fullname)) {
$authorname = $profile->fullname . ' (' . $profile->nickname . ')';
@ -95,7 +96,7 @@ class OembedAction extends Action
$id = $proxy_args['attachment'];
$attachment = File::staticGet($id);
if(empty($attachment)){
$this->serverError(_("attachment $id not found"), 404);
$this->serverError(_("Attachment $id not found."), 404);
}
if(empty($attachment->filename) && $file_oembed = File_oembed::staticGet('file_id', $attachment->id)){
// Proxy the existing oembed information
@ -123,7 +124,7 @@ class OembedAction extends Action
if($attachment->title) $oembed['title']=$attachment->title;
break;
default:
$this->serverError(_("$path not supported for oembed requests"), 501);
$this->serverError(_("$path not supported for oembed requests."), 501);
}
switch($args['format']){
case 'xml':
@ -154,10 +155,12 @@ class OembedAction extends Action
$this->end_document('json');
break;
default:
$this->serverError(_('content type ' . $apidata['content-type'] . ' not supported'), 501);
// TRANS: Error message displaying attachments. %s is a raw MIME type (eg 'image/png')
$this->serverError(sprintf(_('Content type %s not supported.'), $apidata['content-type']), 501);
}
}else{
$this->serverError(_('Only ' . common_root_url() . ' urls over plain http please'), 404);
// TRANS: Error message displaying attachments. %s is the site's base URL.
$this->serverError(sprintf(_('Only %s URLs over plain HTTP please.'), common_root_url()), 404);
}
}

View File

@ -154,19 +154,19 @@ class PathsadminpanelAction extends AdminPanelAction
// Validate theme dir
if (!empty($values['theme']['dir']) && !is_readable($values['theme']['dir'])) {
$this->clientError(sprintf(_("Theme directory not readable: %s"), $values['theme']['dir']));
$this->clientError(sprintf(_("Theme directory not readable: %s."), $values['theme']['dir']));
}
// Validate avatar dir
if (empty($values['avatar']['dir']) || !is_writable($values['avatar']['dir'])) {
$this->clientError(sprintf(_("Avatar directory not writable: %s"), $values['avatar']['dir']));
$this->clientError(sprintf(_("Avatar directory not writable: %s."), $values['avatar']['dir']));
}
// Validate background dir
if (empty($values['background']['dir']) || !is_writable($values['background']['dir'])) {
$this->clientError(sprintf(_("Background directory not writable: %s"), $values['background']['dir']));
$this->clientError(sprintf(_("Background directory not writable: %s."), $values['background']['dir']));
}
// Validate locales dir
@ -174,13 +174,13 @@ class PathsadminpanelAction extends AdminPanelAction
// XXX: What else do we need to validate for lacales path here? --Z
if (!empty($values['site']['locale_path']) && !is_readable($values['site']['locale_path'])) {
$this->clientError(sprintf(_("Locales directory not readable: %s"), $values['site']['locale_path']));
$this->clientError(sprintf(_("Locales directory not readable: %s."), $values['site']['locale_path']));
}
// Validate SSL setup
if (mb_strlen($values['site']['sslserver']) > 255) {
$this->clientError(_("Invalid SSL server. The maximum length is 255 characters."));
$this->clientError(_('Invalid SSL server. The maximum length is 255 characters.'));
}
}

View File

@ -32,8 +32,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/profilelist.php';
/**
* This class outputs a paginated list of profiles self-tagged with a given tag
*
@ -67,7 +65,7 @@ class PeopletagAction extends Action
$this->tag = $this->trimmed('tag');
if (!common_valid_profile_tag($this->tag)) {
$this->clientError(sprintf(_('Not a valid people tag: %s'),
$this->clientError(sprintf(_('Not a valid people tag: %s.'),
$this->tag));
return;
}
@ -124,8 +122,8 @@ class PeopletagAction extends Action
$profile->query(sprintf($qry, $this->tag, $lim));
$pl = new ProfileList($profile, $this);
$cnt = $pl->show();
$ptl = new PeopleTagList($profile, $this); // pass the ammunition
$cnt = $ptl->show();
$this->pagination($this->page > 1,
$cnt > PROFILES_PER_PAGE,
@ -146,3 +144,37 @@ class PeopletagAction extends Action
}
}
class PeopleTagList extends ProfileList
{
function newListItem($profile)
{
return new PeopleTagListItem($profile, $this->action);
}
}
class PeopleTagListItem extends ProfileListItem
{
function linkAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'peopletag')) {
$aAttrs['rel'] .= ' nofollow';
}
return $aAttrs;
}
function homepageAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'peopletag')) {
$aAttrs['rel'] = 'nofollow';
}
return $aAttrs;
}
}

View File

@ -92,7 +92,7 @@ class PostnoticeAction extends Action
{
$content = common_shorten_links($_POST['omb_notice_content']);
if (Notice::contentTooLong($content)) {
$this->clientError(_('Invalid notice content'), 400);
$this->clientError(_('Invalid notice content.'), 400);
return false;
}
$license = $_POST['omb_notice_license'];

View File

@ -80,7 +80,7 @@ class PublicAction extends Action
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
if ($this->page > MAX_PUBLIC_PAGE) {
$this->clientError(sprintf(_("Beyond the page limit (%s)"), MAX_PUBLIC_PAGE));
$this->clientError(sprintf(_("Beyond the page limit (%s)."), MAX_PUBLIC_PAGE));
}
common_set_returnto($this->selfUrl());
@ -95,7 +95,7 @@ class PublicAction extends Action
if($this->page > 1 && $this->notice->N == 0){
// TRANS: Server error when page not found (404)
$this->serverError(_('No such page'),$code=404);
$this->serverError(_('No such page.'),$code=404);
}
return true;

View File

@ -8,7 +8,9 @@
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Craig Andrews <candrews@integralblue.com>
* @author Robin Millette <millette@status.net>
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
@ -44,6 +46,7 @@ require_once INSTALLDIR.'/lib/xrdsoutputter.php';
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*

View File

@ -74,6 +74,13 @@ class RegisterAction extends Action
parent::prepare($args);
$this->code = $this->trimmed('code');
// @todo this check should really be in index.php for all sensitive actions
$ssl = common_config('site', 'ssl');
if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) {
common_redirect(common_local_url('register'));
// exit
}
if (empty($this->code)) {
common_ensure_session();
if (array_key_exists('invitecode', $_SESSION)) {
@ -341,7 +348,7 @@ class RegisterAction extends Action
} else {
$instr =
common_markup_to_html(_('With this form you can create '.
' a new account. ' .
'a new account. ' .
'You can then post notices and '.
'link up to friends and colleagues. '));
@ -491,11 +498,7 @@ class RegisterAction extends Action
$this->elementStart('li');
$this->element('input', $attrs);
$this->elementStart('label', array('class' => 'checkbox', 'for' => 'license'));
$this->text(_('My text and files are available under '));
$this->element('a', array('href' => common_config('license', 'url')),
common_config('license', 'title'), _("Creative Commons Attribution 3.0"));
$this->text(_(' except this private data: password, '.
'email address, IM address, and phone number.'));
$this->raw($this->licenseCheckbox());
$this->elementEnd('label');
$this->elementEnd('li');
}
@ -505,6 +508,48 @@ class RegisterAction extends Action
$this->elementEnd('form');
}
function licenseCheckbox()
{
$out = '';
switch (common_config('license', 'type')) {
case 'private':
// TRANS: Copyright checkbox label in registration dialog, for private sites.
$out .= htmlspecialchars(sprintf(
_('I understand that content and data of %1$s are private and confidential.'),
common_config('site', 'name')));
// fall through
case 'allrightsreserved':
if ($out != '') {
$out .= ' ';
}
if (common_config('license', 'owner')) {
// TRANS: Copyright checkbox label in registration dialog, for all rights reserved with a specified copyright owner.
$out .= htmlspecialchars(sprintf(
_('My text and files are copyright by %1$s.'),
common_config('license', 'owner')));
} else {
// TRANS: Copyright checkbox label in registration dialog, for all rights reserved with ownership left to contributors.
$out .= htmlspecialchars(_('My text and files remain under my own copyright.'));
}
// TRANS: Copyright checkbox label in registration dialog, for all rights reserved.
$out .= ' ' . _('All rights reserved.');
break;
case 'cc': // fall through
default:
// TRANS: Copyright checkbox label in registration dialog, for Creative Commons-style licenses.
$message = _('My text and files are available under %s ' .
'except this private data: password, ' .
'email address, IM address, and phone number.');
$link = '<a href="' .
htmlspecialchars(common_config('license', 'url')) .
'">' .
htmlspecialchars(common_config('license', 'title')) .
'</a>';
$out .= sprintf(htmlspecialchars($message), $link);
}
return $out;
}
/**
* Show some information about registering for the site
*

View File

@ -188,7 +188,7 @@ class RemotesubscribeAction extends Action
$profile = $user->getProfile();
if (!$profile) {
common_log_db_error($user, 'SELECT', __FILE__);
$this->serverError(_('User without matching profile'));
$this->serverError(_('User without matching profile.'));
return;
}

View File

@ -54,21 +54,21 @@ class RepeatAction extends Action
$this->user = common_current_user();
if (empty($this->user)) {
$this->clientError(_("Only logged-in users can repeat notices."));
$this->clientError(_('Only logged-in users can repeat notices.'));
return false;
}
$id = $this->trimmed('notice');
if (empty($id)) {
$this->clientError(_("No notice specified."));
$this->clientError(_('No notice specified.'));
return false;
}
$this->notice = Notice::staticGet('id', $id);
if (empty($this->notice)) {
$this->clientError(_("No notice specified."));
$this->clientError(_('No notice specified.'));
return false;
}
@ -80,14 +80,14 @@ class RepeatAction extends Action
$token = $this->trimmed('token-'.$id);
if (empty($token) || $token != common_session_token()) {
$this->clientError(_("There was a problem with your session token. Try again, please."));
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return false;
}
$profile = $this->user->getProfile();
if ($profile->hasRepeated($id)) {
$this->clientError(_("You already repeated that notice."));
$this->clientError(_('You already repeated that notice.'));
return false;
}

View File

@ -90,7 +90,7 @@ class RepliesAction extends OwnerDesignAction
if($this->page > 1 && $this->notice->N == 0){
// TRANS: Server error when page not found (404)
$this->serverError(_('No such page'),$code=404);
$this->serverError(_('No such page.'),$code=404);
}
return true;
@ -196,18 +196,18 @@ class RepliesAction extends OwnerDesignAction
function showEmptyListMessage()
{
$message = sprintf(_('This is the timeline showing replies to %1$s but %2$s hasn\'t received a notice to his attention yet.'), $this->user->nickname, $this->user->nickname) . ' ';
$message = sprintf(_('This is the timeline showing replies to %1$s but %2$s hasn\'t received a notice to them yet.'), $this->user->nickname, $this->user->nickname) . ' ';
if (common_logged_in()) {
$current_user = common_current_user();
if ($this->user->id === $current_user->id) {
$message .= _('You can engage other users in a conversation, subscribe to more people or [join groups](%%action.groups%%).');
} else {
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
}
}
else {
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->user->nickname);
}
$this->elementStart('div', 'guide');

View File

@ -59,11 +59,11 @@ class RevokeRoleAction extends ProfileFormAction
$this->role = $this->arg('role');
if (!Profile_role::isValid($this->role)) {
$this->clientError(_("Invalid role."));
$this->clientError(_('Invalid role.'));
return false;
}
if (!Profile_role::isSettable($this->role)) {
$this->clientError(_("This role is reserved and cannot be set."));
$this->clientError(_('This role is reserved and cannot be set.'));
return false;
}
@ -72,7 +72,7 @@ class RevokeRoleAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::REVOKEROLE)) {
$this->clientError(_("You cannot revoke user roles on this site."));
$this->clientError(_('You cannot revoke user roles on this site.'));
return false;
}

View File

@ -62,14 +62,14 @@ class SandboxAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::SANDBOXUSER)) {
$this->clientError(_("You cannot sandbox users on this site."));
$this->clientError(_('You cannot sandbox users on this site.'));
return false;
}
assert(!empty($this->profile)); // checked by parent
if ($this->profile->isSandboxed()) {
$this->clientError(_("User is already sandboxed."));
$this->clientError(_('User is already sandboxed.'));
return false;
}

View File

@ -119,13 +119,13 @@ class ShowfavoritesAction extends OwnerDesignAction
if (!empty($cur) && $cur->id == $this->user->id) {
// Show imported/gateway notices as well as local if
// the user is looking at his own favorites
// the user is looking at their own favorites
$this->notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1, true);
$this->notice = $this->user->favoriteNotices(true, ($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
} else {
$this->notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1, false);
$this->notice = $this->user->favoriteNotices(false, ($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
}
if (empty($this->notice)) {
@ -135,7 +135,7 @@ class ShowfavoritesAction extends OwnerDesignAction
if($this->page > 1 && $this->notice->N == 0){
// TRANS: Server error when page not found (404)
$this->serverError(_('No such page'),$code=404);
$this->serverError(_('No such page.'),$code=404);
}
return true;
@ -205,11 +205,11 @@ class ShowfavoritesAction extends OwnerDesignAction
if ($this->user->id === $current_user->id) {
$message = _('You haven\'t chosen any favorite notices yet. Click the fave button on notices you like to bookmark them for later or shed a spotlight on them.');
} else {
$message = sprintf(_('%s hasn\'t added any notices to his favorites yet. Post something interesting they would add to their favorites :)'), $this->user->nickname);
$message = sprintf(_('%s hasn\'t added any favorite notices yet. Post something interesting they would add to their favorites :)'), $this->user->nickname);
}
}
else {
$message = sprintf(_('%s hasn\'t added any notices to his favorites yet. Why not [register an account](%%%%action.register%%%%) and then post something interesting they would add to their favorites :)'), $this->user->nickname);
$message = sprintf(_('%s hasn\'t added any favorite notices yet. Why not [register an account](%%%%action.register%%%%) and then post something interesting they would add to their favorites :)'), $this->user->nickname);
}
$this->elementStart('div', 'guide');

View File

@ -221,7 +221,8 @@ class ShowgroupAction extends GroupDesignAction
function showGroupProfile()
{
$this->elementStart('div', 'entity_profile vcard author');
$this->elementStart('div', array('id' => 'i',
'class' => 'entity_profile vcard author'));
$this->element('h2', null, _('Group profile'));
@ -387,18 +388,23 @@ class ShowgroupAction extends GroupDesignAction
$this->elementStart('div', array('id' => 'entity_members',
'class' => 'section'));
$this->element('h2', null, _('Members'));
if (Event::handle('StartShowGroupMembersMiniList', array($this))) {
$pml = new ProfileMiniList($member, $this);
$cnt = $pml->show();
if ($cnt == 0) {
$this->element('p', null, _('(None)'));
}
$this->element('h2', null, _('Members'));
if ($cnt > MEMBERS_PER_SECTION) {
$this->element('a', array('href' => common_local_url('groupmembers',
array('nickname' => $this->group->nickname))),
_('All members'));
$gmml = new GroupMembersMiniList($member, $this);
$cnt = $gmml->show();
if ($cnt == 0) {
$this->element('p', null, _('(None)'));
}
if ($cnt > MEMBERS_PER_SECTION) {
$this->element('a', array('href' => common_local_url('groupmembers',
array('nickname' => $this->group->nickname))),
_('All members'));
}
Event::handle('EndShowGroupMembersMiniList', array($this));
}
$this->elementEnd('div');
@ -424,14 +430,6 @@ class ShowgroupAction extends GroupDesignAction
function showStatistics()
{
// XXX: WORM cache this
$members = $this->group->getMembers();
$members_count = 0;
/** $member->count() doesn't work. */
while ($members->fetch()) {
$members_count++;
}
$this->elementStart('div', array('id' => 'entity_statistics',
'class' => 'section'));
@ -445,7 +443,7 @@ class ShowgroupAction extends GroupDesignAction
$this->elementStart('dl', 'entity_members');
$this->element('dt', null, _('Members'));
$this->element('dd', null, (is_int($members_count)) ? $members_count : '0');
$this->element('dd', null, $this->group->getMemberCount());
$this->elementEnd('dl');
$this->elementEnd('div');
@ -501,3 +499,26 @@ class GroupAdminSection extends ProfileSection
return null;
}
}
class GroupMembersMiniList extends ProfileMiniList
{
function newListItem($profile)
{
return new GroupMembersMiniListItem($profile, $this->action);
}
}
class GroupMembersMiniListItem extends ProfileMiniListItem
{
function linkAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'members')) {
$aAttrs['rel'] .= ' nofollow';
}
return $aAttrs;
}
}

View File

@ -97,7 +97,7 @@ class ShownoticeAction extends OwnerDesignAction
$this->profile = $this->notice->getProfile();
if (empty($this->profile)) {
$this->serverError(_('Notice has no profile'), 500);
$this->serverError(_('Notice has no profile.'), 500);
return false;
}
@ -167,7 +167,7 @@ class ShownoticeAction extends OwnerDesignAction
function title()
{
if (!empty($this->profile->fullname)) {
$base = $this->profile->fullname . ' (' . $this->profile->nickname . ') ';
$base = $this->profile->fullname . ' (' . $this->profile->nickname . ')';
} else {
$base = $this->profile->nickname;
}

View File

@ -204,11 +204,11 @@ class ShowstreamAction extends ProfileAction
if ($this->user->id === $current_user->id) {
$message .= _('Seen anything interesting recently? You haven\'t posted any notices yet, now would be a good time to start :)');
} else {
$message .= sprintf(_('You can try to nudge %1$s or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%2$s).'), $this->user->nickname, '@' . $this->user->nickname);
$message .= sprintf(_('You can try to nudge %1$s or [post something to them](%%%%action.newnotice%%%%?status_textarea=%2$s).'), $this->user->nickname, '@' . $this->user->nickname);
}
}
else {
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->user->nickname);
}
$this->elementStart('div', 'guide');

View File

@ -62,14 +62,14 @@ class SilenceAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::SILENCEUSER)) {
$this->clientError(_("You cannot silence users on this site."));
$this->clientError(_('You cannot silence users on this site.'));
return false;
}
assert(!empty($this->profile)); // checked by parent
if ($this->profile->isSilenced()) {
$this->clientError(_("User is already silenced."));
$this->clientError(_('User is already silenced.'));
return false;
}

View File

@ -130,7 +130,7 @@ class SiteadminpanelAction extends AdminPanelAction
// Validate site name
if (empty($values['site']['name'])) {
$this->clientError(_("Site name must have non-zero length."));
$this->clientError(_('Site name must have non-zero length.'));
}
// Validate email
@ -168,7 +168,7 @@ class SiteadminpanelAction extends AdminPanelAction
// Validate dupe limit
if (!Validate::number($values['site']['dupelimit'], array('min' => 1))) {
$this->clientError(_("Dupe limit must 1 or more seconds."));
$this->clientError(_("Dupe limit must be one or more seconds."));
}
}

View File

@ -110,7 +110,7 @@ class SitenoticeadminpanelAction extends AdminPanelAction
if (mb_strlen($siteNotice) > 255) {
$this->clientError(
_('Max length for the site-wide notice is 255 chars')
_('Max length for the site-wide notice is 255 chars.')
);
}

View File

@ -55,6 +55,7 @@ class SmssettingsAction extends ConnectSettingsAction
function title()
{
// TRANS: Title for SMS settings.
return _('SMS settings');
}
@ -66,6 +67,10 @@ class SmssettingsAction extends ConnectSettingsAction
function getInstructions()
{
// XXX: For consistency of parameters in messages, this should be a
// regular parameters, replaced with sprintf().
// TRANS: SMS settings page instructions.
// TRANS: %%site.name%% is the name of the site.
return _('You can receive SMS messages through email from %%site.name%%.');
}
@ -88,6 +93,7 @@ class SmssettingsAction extends ConnectSettingsAction
{
if (!common_config('sms', 'enabled')) {
$this->element('div', array('class' => 'error'),
// TRANS: Message given in the SMS settings if SMS is not enabled on the site.
_('SMS is not available.'));
return;
}
@ -101,7 +107,8 @@ class SmssettingsAction extends ConnectSettingsAction
common_local_url('smssettings')));
$this->elementStart('fieldset', array('id' => 'settings_sms_address'));
$this->element('legend', null, _('Address'));
// TRANS: Form legend for SMS settings form.
$this->element('legend', null, _('SMS address'));
$this->hidden('token', common_session_token());
if ($user->sms) {
@ -109,10 +116,12 @@ class SmssettingsAction extends ConnectSettingsAction
$this->element('p', 'form_confirmed',
$user->sms . ' (' . $carrier->name . ')');
$this->element('p', 'form_guide',
// TRANS: Form guide in SMS settings form.
_('Current confirmed SMS-enabled phone number.'));
$this->hidden('sms', $user->sms);
$this->hidden('carrier', $user->carrier);
$this->submit('remove', _('Remove'));
// TRANS: Button label to remove a confirmed SMS address.
$this->submit('remove', _m('BUTTON','Remove'));
} else {
$confirm = $this->getConfirmation();
if ($confirm) {
@ -120,57 +129,75 @@ class SmssettingsAction extends ConnectSettingsAction
$this->element('p', 'form_unconfirmed',
$confirm->address . ' (' . $carrier->name . ')');
$this->element('p', 'form_guide',
// TRANS: Form guide in IM settings form.
_('Awaiting confirmation on this phone number.'));
$this->hidden('sms', $confirm->address);
$this->hidden('carrier', $confirm->address_extra);
$this->submit('cancel', _('Cancel'));
// TRANS: Button label to cancel a SMS address confirmation procedure.
$this->submit('cancel', _m('BUTTON','Cancel'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
// TRANS: Field label for SMS address input in SMS settings form.
$this->input('code', _('Confirmation code'), null,
// TRANS: Form field instructions in SMS settings form.
_('Enter the code you received on your phone.'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('confirm', _('Confirm'));
// TRANS: Button label to confirm SMS confirmation code in SMS settings.
$this->submit('confirm', _m('BUTTON','Confirm'));
} else {
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
// TRANS: Field label for SMS phone number input in SMS settings form.
$this->input('sms', _('SMS phone number'),
($this->arg('sms')) ? $this->arg('sms') : null,
// TRANS: SMS phone number input field instructions in SMS settings form.
_('Phone number, no punctuation or spaces, '.
'with area code'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->carrierSelect();
$this->submit('add', _('Add'));
// TRANS: Button label for adding a SMS phone number in SMS settings form.
$this->submit('add', _m('BUTTON','Add'));
}
}
$this->elementEnd('fieldset');
if ($user->sms) {
$this->elementStart('fieldset', array('id' => 'settings_sms_incoming_email'));
// XXX: Confused! This is about SMS. Should this message be updated?
// TRANS: Form legend for incoming SMS settings form.
$this->element('legend', null, _('Incoming email'));
if ($user->incomingemail) {
$this->element('p', 'form_unconfirmed', $user->incomingemail);
$this->element('p', 'form_note',
// XXX: Confused! This is about SMS. Should this message be updated?
// TRANS: Form instructions for incoming SMS e-mail address form in SMS settings.
_('Send email to this address to post new notices.'));
$this->submit('removeincoming', _('Remove'));
// TRANS: Button label for removing a set sender SMS e-mail address to post notices from.
$this->submit('removeincoming', _m('BUTTON','Remove'));
}
$this->element('p', 'form_guide',
// XXX: Confused! This is about SMS. Should this message be updated?
// TRANS: Instructions for incoming SMS e-mail address input form.
_('Make a new email address for posting to; '.
'cancels the old one.'));
$this->submit('newincoming', _('New'));
// TRANS: Button label for adding an SMS e-mail address to send notices from.
$this->submit('newincoming', _m('BUTTON','New'));
$this->elementEnd('fieldset');
}
$this->elementStart('fieldset', array('id' => 'settings_sms_preferences'));
$this->element('legend', null, _('Preferences'));
// TRANS: Form legend for SMS preferences form.
$this->element('legend', null, _('SMS preferences'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->checkbox('smsnotify',
// TRANS: Checkbox label in SMS preferences form.
_('Send me notices through SMS; '.
'I understand I may incur '.
'exorbitant charges from my carrier.'),
@ -178,7 +205,8 @@ class SmssettingsAction extends ConnectSettingsAction
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('save', _('Save'));
// TRANS: Button label to save SMS preferences.
$this->submit('save', _m('BUTTON','Save'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
@ -245,6 +273,7 @@ class SmssettingsAction extends ConnectSettingsAction
} else if ($this->arg('confirm')) {
$this->confirmCode();
} else {
// TRANS: Message given submitting a form with an unknown action in SMS settings.
$this->showForm(_('Unexpected form submission.'));
}
}
@ -275,13 +304,15 @@ class SmssettingsAction extends ConnectSettingsAction
if ($result === false) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error updating SMS preferences.
$this->serverError(_('Couldn\'t update user.'));
return;
}
$user->query('COMMIT');
$this->showForm(_('Preferences saved.'), true);
// TRANS: Confirmation message for successful SMS preferences save.
$this->showForm(_('SMS preferences saved.'), true);
}
/**
@ -303,11 +334,13 @@ class SmssettingsAction extends ConnectSettingsAction
// Some validation
if (!$sms) {
// TRANS: Message given saving SMS phone number without having provided one.
$this->showForm(_('No phone number.'));
return;
}
if (!$carrier_id) {
// TRANS: Message given saving SMS phone number without having selected a carrier.
$this->showForm(_('No carrier selected.'));
return;
}
@ -315,9 +348,11 @@ class SmssettingsAction extends ConnectSettingsAction
$sms = common_canonical_sms($sms);
if ($user->sms == $sms) {
// TRANS: Message given saving SMS phone number that is already set.
$this->showForm(_('That is already your phone number.'));
return;
} else if ($this->smsExists($sms)) {
// TRANS: Message given saving SMS phone number that is already set for another user.
$this->showForm(_('That phone number already belongs to another user.'));
return;
}
@ -334,6 +369,7 @@ class SmssettingsAction extends ConnectSettingsAction
if ($result === false) {
common_log_db_error($confirm, 'INSERT', __FILE__);
// TRANS: Server error thrown on database error adding SMS confirmation code.
$this->serverError(_('Couldn\'t insert confirmation code.'));
return;
}
@ -344,6 +380,7 @@ class SmssettingsAction extends ConnectSettingsAction
$user->nickname,
$carrier->toEmailAddress($sms));
// TRANS: Message given saving valid SMS phone number that is to be confirmed.
$msg = _('A confirmation code was sent to the phone number you added. '.
'Check your phone for the code and instructions '.
'on how to use it.');
@ -367,10 +404,12 @@ class SmssettingsAction extends ConnectSettingsAction
$confirm = $this->getConfirmation();
if (!$confirm) {
// TRANS: Message given canceling SMS phone number confirmation that is not pending.
$this->showForm(_('No pending confirmation to cancel.'));
return;
}
if ($confirm->address != $sms) {
// TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
$this->showForm(_('That is the wrong confirmation number.'));
return;
}
@ -379,11 +418,13 @@ class SmssettingsAction extends ConnectSettingsAction
if (!$result) {
common_log_db_error($confirm, 'DELETE', __FILE__);
// TRANS: Server error thrown on database error canceling SMS phone number confirmation.
$this->serverError(_('Couldn\'t delete email confirmation.'));
return;
}
$this->showForm(_('Confirmation cancelled.'), true);
// TRANS: Message given after successfully canceling SMS phone number confirmation.
$this->showForm(_('SMS confirmation cancelled.'), true);
}
/**
@ -402,6 +443,8 @@ class SmssettingsAction extends ConnectSettingsAction
// Maybe an old tab open...?
if ($user->sms != $sms) {
// TRANS: Message given trying to remove an SMS phone number that is not
// TRANS: registered for the active user.
$this->showForm(_('That is not your phone number.'));
return;
}
@ -417,12 +460,14 @@ class SmssettingsAction extends ConnectSettingsAction
$result = $user->updateKeys($original);
if (!$result) {
common_log_db_error($user, 'UPDATE', __FILE__);
// TRANS: Server error thrown on database error removing a registered SMS phone number.
$this->serverError(_('Couldn\'t update user.'));
return;
}
$user->query('COMMIT');
$this->showForm(_('The address was removed.'), true);
// TRANS: Message given after successfully removing a registered SMS phone number.
$this->showForm(_('The SMS phone number was removed.'), true);
}
/**
@ -462,10 +507,12 @@ class SmssettingsAction extends ConnectSettingsAction
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
// TRANS: Label for mobile carrier dropdown menu in SMS settings.
$this->element('label', array('for' => 'carrier'), _('Mobile carrier'));
$this->elementStart('select', array('name' => 'carrier',
'id' => 'carrier'));
$this->element('option', array('value' => 0),
// TRANS: Default option for mobile carrier dropdown menu in SMS settings.
_('Select a carrier'));
while ($carrier->fetch()) {
$this->element('option', array('value' => $carrier->id),
@ -473,6 +520,8 @@ class SmssettingsAction extends ConnectSettingsAction
}
$this->elementEnd('select');
$this->element('p', 'form_guide',
// TRANS: Form instructions for mobile carrier dropdown menu in SMS settings.
// TRANS: %s is an administrative contact's e-mail address.
sprintf(_('Mobile carrier for your phone. '.
'If you know a carrier that accepts ' .
'SMS over email but isn\'t listed here, ' .
@ -495,6 +544,7 @@ class SmssettingsAction extends ConnectSettingsAction
$code = $this->trimmed('code');
if (!$code) {
// TRANS: Message given saving SMS phone number confirmation code without having provided one.
$this->showForm(_('No code entered'));
return;
}

View File

@ -124,13 +124,13 @@ class SnapshotadminpanelAction extends AdminPanelAction
// Validate snapshot run value
if (!in_array($values['snapshot']['run'], array('web', 'cron', 'never'))) {
$this->clientError(_("Invalid snapshot run value."));
$this->clientError(_('Invalid snapshot run value.'));
}
// Validate snapshot frequency value
if (!Validate::number($values['snapshot']['frequency'])) {
$this->clientError(_("Snapshot frequency must be a number."));
$this->clientError(_('Snapshot frequency must be a number.'));
}
// Validate report URL
@ -141,7 +141,7 @@ class SnapshotadminpanelAction extends AdminPanelAction
array('allowed_schemes' => array('http', 'https')
)
)) {
$this->clientError(_("Invalid snapshot report URL."));
$this->clientError(_('Invalid snapshot report URL.'));
}
}
}
@ -197,7 +197,7 @@ class SnapshotAdminPanelForm extends AdminForm
$this->out->elementStart('ul', 'form_data');
$this->li();
$snapshot = array(
'web' => _('Randomly during Web hit'),
'web' => _('Randomly during web hit'),
'cron' => _('In a scheduled job'),
'never' => _('Never')
);

View File

@ -157,10 +157,36 @@ class SubscribersListItem extends SubscriptionListItem
$user = common_current_user();
if (!empty($user) && $this->owner->id == $user->id) {
$bf = new BlockForm($this->out, $this->profile,
array('action' => 'subscribers',
'nickname' => $this->owner->nickname));
$returnto = array('action' => 'subscribers',
'nickname' => $this->owner->nickname);
$page = $this->out->arg('page');
if ($page) {
$returnto['param-page'] = $page;
}
$bf = new BlockForm($this->out, $this->profile, $returnto);
$bf->show();
}
}
function linkAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'subscribers')) {
$aAttrs['rel'] .= ' nofollow';
}
return $aAttrs;
}
function homepageAttributes()
{
$aAttrs = parent::linkAttributes();
if (common_config('nofollow', 'subscribers')) {
$aAttrs['rel'] = 'nofollow';
}
return $aAttrs;
}
}

View File

@ -196,12 +196,30 @@ class SubscriptionsListItem extends SubscriptionListItem
$this->out->hidden('token', common_session_token());
$this->out->hidden('profile', $this->profile->id);
if (common_config('xmpp', 'enabled')) {
$this->out->checkbox('jabber', _('Jabber'), $sub->jabber);
$attrs = array('name' => 'jabber',
'type' => 'checkbox',
'class' => 'checkbox',
'id' => 'jabber-'.$this->profile->id);
if ($sub->jabber) {
$attrs['checked'] = 'checked';
}
$this->out->element('input', $attrs);
$this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _('Jabber'));
} else {
$this->out->hidden('jabber', $sub->jabber);
}
if (common_config('sms', 'enabled')) {
$this->out->checkbox('sms', _('SMS'), $sub->sms);
$attrs = array('name' => 'sms',
'type' => 'checkbox',
'class' => 'checkbox',
'id' => 'sms-'.$this->profile->id);
if ($sub->sms) {
$attrs['checked'] = 'checked';
}
$this->out->element('input', $attrs);
$this->out->element('label', array('for' => 'sms-'.$this->profile->id), _('SMS'));
} else {
$this->out->hidden('sms', $sub->sms);
}

View File

@ -49,7 +49,7 @@ class TagAction extends Action
if($this->page > 1 && $this->notice->N == 0){
// TRANS: Server error when page not found (404)
$this->serverError(_('No such page'),$code=404);
$this->serverError(_('No such page.'),$code=404);
}
return true;
@ -102,12 +102,17 @@ class TagAction extends Action
function showContent()
{
$nl = new NoticeList($this->notice, $this);
if(Event::handle('StartTagShowContent', array($this))) {
$nl = new NoticeList($this->notice, $this);
$cnt = $nl->show();
$cnt = $nl->show();
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'tag', array('tag' => $this->tag));
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'tag', array('tag' => $this->tag));
Event::handle('EndTagShowContent', array($this));
}
}
function isReadOnly($args)

View File

@ -62,14 +62,14 @@ class UnsandboxAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::SANDBOXUSER)) {
$this->clientError(_("You cannot sandbox users on this site."));
$this->clientError(_('You cannot sandbox users on this site.'));
return false;
}
assert(!empty($this->profile)); // checked by parent
if (!$this->profile->isSandboxed()) {
$this->clientError(_("User is not sandboxed."));
$this->clientError(_('User is not sandboxed.'));
return false;
}

View File

@ -62,14 +62,14 @@ class UnsilenceAction extends ProfileFormAction
assert(!empty($cur)); // checked by parent
if (!$cur->hasRight(Right::SILENCEUSER)) {
$this->clientError(_("You cannot silence users on this site."));
$this->clientError(_('You cannot silence users on this site.'));
return false;
}
assert(!empty($this->profile)); // checked by parent
if (!$this->profile->isSilenced()) {
$this->clientError(_("User is not silenced."));
$this->clientError(_('User is not silenced.'));
return false;
}

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