Merge branch 'master' of git://gitorious.org/statusnet/mainline

This commit is contained in:
Ian Denhardt 2010-08-02 11:10:19 -04:00
commit 762731d8ee
337 changed files with 30136 additions and 17820 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)

53
README
View File

@ -2,8 +2,8 @@
README
------
StatusNet 0.9.2 ("King of Birds")
3 May 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,40 +77,27 @@ for additional terms.
New this version
================
This is a minor bug and feature release since version 0.9.1 released 28
March 2010.
This is a minor bug and feature release since version 0.9.2 released on
4 May 2010.
Because of fixes to OStatus bugs, it is highly recommended that all
public sites upgrade to the new version immediately.
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:
- Installer no longer fails with a PHP fatal error when trying to set up the
subscription to update@status.net
- Fixed email notifications for @-replies that come in via OStatus
- OStatus related Fixes to the cloudy theme
- Pass geo locations over Twitter bridge (will only be used if enabled on the
Twitter side)
- scripts/showplugins.php - script to dump the list of activated plugins and
their settings
- scripts/fixup_blocks.php - script to finds any stray subscriptions in
violation of blocks, and removes them
- Allow blocking someone who's not currently subscribed to you (prevents
seeing @-replies from them, or them subbing to you in future)
- Default 2-second timeout on Geonames web service lookups
- Improved localization for plugins
- New anti-spam measures: added nofollow rels to group members list,
subscribers list
- Shared cache key option for Geonames plugin (lets multi-instance sites
share their cached geoname lookups)
- Stability fixes to the TwitterStatusFetcher
- If user allows location sharing but turned off browser location use profile
location
- Improved group listing via the API
- Improved FOAF output
- Several other bugfixes
- 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
A full changelog is available at http://status.net/wiki/StatusNet_0.9.2.
A full changelog is available at http://status.net/wiki/StatusNet_0.9.3.
Prerequisites
=============
@ -121,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

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
*/
@ -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 their attention](%%%%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 their attention.'), $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

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

@ -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

@ -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/
*/

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/
*/

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/
*/

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/
*/

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/
*/
@ -93,6 +94,7 @@ class ApiGroupListAction extends ApiBareAuthAction
parent::handle($args);
$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";
@ -100,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/
*/
@ -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";

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/
*/

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/
*/

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();
}

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/
*/
@ -99,32 +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();
$this->showNotice();
} else {
$this->clientError(_('You may not delete another user\'s status.'),
403, $this->format);
}
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

@ -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);
}
@ -104,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;
}
@ -125,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,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;
}
@ -213,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
);
}
}
@ -240,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

@ -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/
*/

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

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/
*/
@ -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
);

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,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
{

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/
*/

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

@ -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

@ -148,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');
}

View File

@ -87,10 +87,12 @@ class ConfirmaddressAction extends Action
}
$type = $confirm->address_type;
if (!in_array($type, array('email', 'jabber', 'sms'))) {
// 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

@ -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
*
@ -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

@ -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

@ -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

@ -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

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);
}
@ -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
@ -207,7 +211,8 @@ class FoafAction extends Action
$this->showMicrobloggingAccount($profile,
($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));
}
@ -232,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) {
@ -254,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;
@ -281,6 +298,9 @@ class FoafAction extends Action
}
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

@ -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

@ -173,8 +173,20 @@ class GroupblockAction extends RedirectingAction
$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');
}

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, 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

@ -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

@ -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

@ -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/
*/

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

@ -348,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. '));

View File

@ -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 their attention 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 their attention](%%%%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 their attention.'), $this->user->nickname);
}
$this->elementStart('div', 'guide');

View File

@ -119,7 +119,7 @@ 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(true, ($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
@ -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

@ -430,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'));
@ -451,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');

View File

@ -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 their attention](%%%%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 their attention.'), $this->user->nickname);
}
$this->elementStart('div', 'guide');

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

@ -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

@ -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

@ -59,8 +59,10 @@ class UsergroupsAction extends OwnerDesignAction
function title()
{
if ($this->page == 1) {
// TRANS: Message is used as a page title. %s is a nick name.
return sprintf(_('%s groups'), $this->user->nickname);
} else {
// TRANS: Message is used as a page title. %1$s is a nick name, %2$d is a page number.
return sprintf(_('%1$s groups, page %2$d'),
$this->user->nickname,
$this->page);

View File

@ -72,7 +72,7 @@ class UserrssAction extends Rss10Action
{
$notice = $this->user->getNotices(
0,
($limit == 0) ? NOTICES_PER_PAGE : $limit
($this->limit == 0) ? NOTICES_PER_PAGE : $this->limit
);
$notices = array();
@ -90,8 +90,10 @@ class UserrssAction extends Rss10Action
$c = array('url' => common_local_url('userrss',
array('nickname' =>
$user->nickname)),
// TRANS: Message is used as link title. %s is a user nickname.
'title' => sprintf(_('%s timeline'), $user->nickname),
'link' => $profile->profileurl,
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
'description' => sprintf(_('Updates from %1$s on %2$s!'),
$user->nickname, common_config('site', 'name')));
return $c;

View File

@ -41,6 +41,8 @@ if (!defined('STATUSNET')) {
* @category Info
* @package StatusNet
* @author Evan Prodromou <evan@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-3.0.html AGPLv3
* @link http://status.net/
*/

View File

@ -302,7 +302,10 @@ class File extends Memcached_DataObject
if(! isset($this->filename)){
$notEnclosureMimeTypes = array(null,'text/html','application/xhtml+xml');
$mimetype = strtolower($this->mimetype);
$mimetype = $this->mimetype;
if($mimetype != null){
$mimetype = strtolower($this->mimetype);
}
$semicolon = strpos($mimetype,';');
if($semicolon){
$mimetype = substr($mimetype,0,$semicolon);

View File

@ -39,6 +39,22 @@ class Foreign_user extends Memcached_DataObject
return null;
}
static function getByNickname($nickname, $service)
{
if (empty($nickname) || empty($service)) {
return null;
} else {
$fuser = new Foreign_user();
$fuser->service = $service;
$fuser->nickname = $nickname;
$fuser->limit(1);
$result = $fuser->find(true);
return empty($result) ? null : $fuser;
}
}
function updateKeys(&$orig)
{
$this->_connect();

View File

@ -115,9 +115,12 @@ class Inbox extends Memcached_DataObject
*/
static function insertNotice($user_id, $notice_id)
{
$inbox = DB_DataObject::staticGet('inbox', 'user_id', $user_id);
if (empty($inbox)) {
// Going straight to the DB rather than trusting our caching
// during an update. Note: not using DB_DataObject::staticGet,
// which is unsafe to use directly (in-process caching causes
// memory leaks, which accumulate in queue processes).
$inbox = new Inbox();
if (!$inbox->get('user_id', $user_id)) {
$inbox = Inbox::initialize($user_id);
}

View File

@ -128,12 +128,13 @@ class Memcached_DataObject extends Safe_DataObject
}
static function cacheKey($cls, $k, $v) {
if (is_object($cls) || is_object($k) || is_object($v)) {
if (is_object($cls) || is_object($k) || (is_object($v) && !($v instanceof DB_DataObject_Cast))) {
$e = new Exception();
common_log(LOG_ERR, __METHOD__ . ' object in param: ' .
str_replace("\n", " ", $e->getTraceAsString()));
}
return common_cache_key(strtolower($cls).':'.$k.':'.$v);
$vstr = self::valueString($v);
return common_cache_key(strtolower($cls).':'.$k.':'.$vstr);
}
static function getcached($cls, $k, $v) {
@ -229,10 +230,10 @@ class Memcached_DataObject extends Safe_DataObject
if (empty($this->$key)) {
continue;
}
$ckeys[] = $this->cacheKey($this->tableName(), $key, $this->$key);
$ckeys[] = $this->cacheKey($this->tableName(), $key, self::valueString($this->$key));
} else if ($type == 'K' || $type == 'N') {
$pkey[] = $key;
$pval[] = $this->$key;
$pval[] = self::valueString($this->$key);
} else {
throw new Exception("Unknown key type $key => $type for " . $this->tableName());
}
@ -351,7 +352,7 @@ class Memcached_DataObject extends Safe_DataObject
* low-level database function and add a comment to the
* query string. This should then be visible in process lists
* and slow query logs, to help identify problem areas.
*
*
* Also marks whether this was a web GET/POST or which daemon
* was running it.
*
@ -592,7 +593,7 @@ class Memcached_DataObject extends Safe_DataObject
return $c->get($cacheKey);
}
static function cacheSet($keyPart, $value)
static function cacheSet($keyPart, $value, $flag=null, $expiry=null)
{
$c = self::memcache();
@ -602,7 +603,32 @@ class Memcached_DataObject extends Safe_DataObject
$cacheKey = common_cache_key($keyPart);
return $c->set($cacheKey, $value);
return $c->set($cacheKey, $value, $flag, $expiry);
}
static function valueString($v)
{
$vstr = null;
if (is_object($v) && $v instanceof DB_DataObject_Cast) {
switch ($v->type) {
case 'date':
$vstr = $v->year . '-' . $v->month . '-' . $v->day;
break;
case 'blob':
case 'string':
case 'sql':
case 'datetime':
case 'time':
throw new ServerException("Unhandled DB_DataObject_Cast type passed as cacheKey value: '$v->type'");
break;
default:
throw new ServerException("Unknown DB_DataObject_Cast type passed as cacheKey value: '$v->type'");
break;
}
} else {
$vstr = strval($v);
}
return $vstr;
}
}

View File

@ -29,6 +29,7 @@
* @author Robin Millette <millette@controlyourself.ca>
* @author Sarven Capadisli <csarven@controlyourself.ca>
* @author Tom Adams <tom@holizz.com>
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license GNU Affero General Public License http://www.gnu.org/licenses/
*/
@ -41,10 +42,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
*/
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
/* We keep the first three 20-notice pages, plus one for pagination check,
/* We keep 200 notices, the max number of notices available per API request,
* in the memcached cache. */
define('NOTICE_CACHE_WINDOW', 61);
define('NOTICE_CACHE_WINDOW', 200);
define('MAX_BOXCARS', 128);
@ -89,7 +90,13 @@ class Notice extends Memcached_DataObject
function getProfile()
{
return Profile::staticGet('id', $this->profile_id);
$profile = Profile::staticGet('id', $this->profile_id);
if (empty($profile)) {
throw new ServerException(sprintf(_('No such profile (%d) for notice (%d)'), $this->profile_id, $this->id));
}
return $profile;
}
function delete()
@ -177,7 +184,8 @@ class Notice extends Memcached_DataObject
$id = $tag->insert();
if (!$id) {
throw new ServerException(sprintf(_('DB error inserting hashtag: %s'),
// TRANS: Server exception. %s are the error details.
throw new ServerException(sprintf(_('Database error inserting hashtag: %s'),
$last_error->message));
return;
}
@ -267,7 +275,7 @@ class Notice extends Memcached_DataObject
if (!$profile->hasRight(Right::NEWNOTICE)) {
common_log(LOG_WARNING, "Attempted post from user disallowed to post: " . $profile->nickname);
throw new ClientException(_('You are banned from posting notices on this site.'));
throw new ClientException(_('You are banned from posting notices on this site.'), 403);
}
$notice = new Notice();
@ -1190,7 +1198,7 @@ class Notice extends Memcached_DataObject
'xmlns:media' => 'http://purl.org/syndication/atommedia',
'xmlns:poco' => 'http://portablecontacts.net/spec/1.0',
'xmlns:ostatus' => 'http://ostatus.org/schema/1.0',
'xmlns:statusnet' => 'http://status.net/ont/');
'xmlns:statusnet' => 'http://status.net/schema/api/1/');
} else {
$attrs = array();
}
@ -1225,7 +1233,7 @@ class Notice extends Memcached_DataObject
$xs->element('title', null, common_xml_safe_str($this->content));
if ($author) {
$xs->raw($profile->asAtomAuthor());
$xs->raw($profile->asAtomAuthor($cur));
$xs->raw($profile->asActivityActor());
}
@ -1238,9 +1246,25 @@ class Notice extends Memcached_DataObject
$xs->element('published', null, common_date_w3dtf($this->created));
$xs->element('updated', null, common_date_w3dtf($this->created));
$source = null;
$ns = $this->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;
}
}
$noticeInfoAttr = array(
'local_id' => $this->id, // local notice ID (useful to clients for ordering)
'source' => $this->source, // the client name (source attribution)
'local_id' => $this->id, // local notice ID (useful to clients for ordering)
'source' => $source, // the client name (source attribution)
);
$ns = $this->getSource();
@ -1252,6 +1276,8 @@ class Notice extends Memcached_DataObject
if (!empty($cur)) {
$noticeInfoAttr['favorite'] = ($cur->hasFave($this)) ? "true" : "false";
$profile = $cur->getProfile();
$noticeInfoAttr['repeated'] = ($profile->hasRepeated($this->id)) ? "true" : "false";
}
if (!empty($this->repeat_of)) {
@ -1555,6 +1581,8 @@ class Notice extends Memcached_DataObject
{
$author = Profile::staticGet('id', $this->profile_id);
// TRANS: Message used to repeat a notice. RT is the abbreviation of 'retweet'.
// TRANS: %1$s is the repeated user's name, %2$s is the repeated notice.
$content = sprintf(_('RT @%1$s %2$s'),
$author->nickname,
$this->content);
@ -1861,4 +1889,16 @@ class Notice extends Memcached_DataObject
return $ns;
}
/**
* Determine whether the notice was locally created
*
* @return boolean locality
*/
public function isLocal()
{
return ($this->is_local == Notice::LOCAL_PUBLIC ||
$this->is_local == Notice::LOCAL_NONPUBLIC);
}
}

View File

@ -849,15 +849,23 @@ class Profile extends Memcached_DataObject
*
* Assumes that Atom has been previously set up as the base namespace.
*
* @param Profile $cur the current authenticated user
*
* @return string
*/
function asAtomAuthor()
function asAtomAuthor($cur = null)
{
$xs = new XMLStringer(true);
$xs->elementStart('author');
$xs->element('name', null, $this->nickname);
$xs->element('uri', null, $this->getUri());
if ($cur != null) {
$attrs = Array();
$attrs['following'] = $cur->isSubscribed($this) ? 'true' : 'false';
$attrs['blocking'] = $cur->hasBlocked($this) ? 'true' : 'false';
$xs->element('statusnet:profile_info', $attrs, null);
}
$xs->elementEnd('author');
return $xs->getString();

View File

@ -64,4 +64,17 @@ class Queue_item extends Memcached_DataObject
$qi = null;
return null;
}
/**
* Release a claimed item.
*/
function releaseCLaim()
{
// DB_DataObject doesn't let us save nulls right now
$sql = sprintf("UPDATE queue_item SET claimed=NULL WHERE id=%d", $this->id);
$this->query($sql);
$this->claimed = null;
$this->encache();
}
}

View File

@ -96,6 +96,30 @@ class Safe_DataObject extends DB_DataObject
$this->_link_loaded = false;
}
/**
* Magic function called when someone attempts to call a method
* that doesn't exist. DB_DataObject uses this to implement
* setters and getters for fields, but neglects to throw an error
* when you just misspell an actual method name. This leads to
* silent failures which can cause all kinds of havoc.
*
* @param string $method
* @param array $params
* @return mixed
* @throws Exception
*/
function __call($method, $params)
{
$return = null;
// Yes, that's _call with one underscore, which does the
// actual implementation.
if ($this->_call($method, $params, $return)) {
return $return;
} else {
throw new Exception('Call to undefined method ' .
get_class($this) . '::' . $method);
}
}
/**
* Work around memory-leak bugs...

View File

@ -144,26 +144,49 @@ class Status_network extends Safe_DataObject
return parent::update($orig);
}
/**
* DB_DataObject doesn't allow updating keys (even non-primary)
*/
function updateKeys(&$orig)
{
$this->_connect();
foreach (array('hostname', 'pathname') as $k) {
if (strcmp($this->$k, $orig->$k) != 0) {
$parts[] = $k . ' = ' . $this->_quote($this->$k);
}
}
if (count($parts) == 0) {
// No changes
return true;
}
$toupdate = implode(', ', $parts);
$table = common_database_tablename($this->tableName());
$qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
' WHERE nickname = ' . $this->_quote($this->nickname);
$orig->decache();
$result = $this->query($qry);
if ($result) {
$this->encache();
}
return $result;
}
function delete()
{
$this->decache(); # while we still have the values!
return parent::delete();
}
/**
* @param string $servername hostname
* @param string $pathname URL base path
* @param string $wildcard hostname suffix to match wildcard config
* @return mixed Status_network or null
*/
static function setupSite($servername, $pathname, $wildcard)
static function getFromHostname($servername, $wildcard)
{
global $config;
$sn = null;
// XXX I18N, probably not crucial for hostnames
// XXX This probably needs a tune up
if (0 == strncasecmp(strrev($wildcard), strrev($servername), strlen($wildcard))) {
// special case for exact match
if (0 == strcasecmp($servername, $wildcard)) {
@ -182,6 +205,23 @@ class Status_network extends Safe_DataObject
}
}
}
return $sn;
}
/**
* @param string $servername hostname
* @param string $pathname URL base path
* @param string $wildcard hostname suffix to match wildcard config
*/
static function setupSite($servername, $pathname, $wildcard)
{
global $config;
$sn = null;
// XXX I18N, probably not crucial for hostnames
// XXX This probably needs a tune up
$sn = self::getFromHostname($servername, $wildcard);
if (!empty($sn)) {

View File

@ -88,8 +88,8 @@ class Subscription extends Memcached_DataObject
self::blow('user:notices_with_friends:%d', $subscriber->id);
$subscriber->blowSubscriptionsCount();
$other->blowSubscribersCount();
$subscriber->blowSubscriptionCount();
$other->blowSubscriberCount();
$otherUser = User::staticGet('id', $other->id);
@ -213,8 +213,8 @@ class Subscription extends Memcached_DataObject
self::blow('user:notices_with_friends:%d', $subscriber->id);
$subscriber->blowSubscriptionsCount();
$other->blowSubscribersCount();
$subscriber->blowSubscriptionCount();
$other->blowSubscriberCount();
Event::handle('EndUnsubscribe', array($subscriber, $other));
}

View File

@ -524,7 +524,7 @@ class User extends Memcached_DataObject
if ($this->id == $other->id) {
common_log(LOG_WARNING,
sprintf(
"Profile ID %d (%s) tried to block his or herself.",
"Profile ID %d (%s) tried to block themself.",
$this->id,
$this->nickname
)

View File

@ -154,6 +154,21 @@ class User_group extends Memcached_DataObject
return $members;
}
function getMemberCount()
{
// XXX: WORM cache this
$members = $this->getMembers();
$member_count = 0;
/** $member->count() doesn't work. */
while ($members->fetch()) {
$member_count++;
}
return $member_count;
}
function getAdmins($offset=0, $limit=null)
{
$qry =

View File

@ -45,7 +45,7 @@ $config['site']['path'] = 'statusnet';
// lighttpd, nginx), you can enable X-Sendfile support for better
// performance. Presently, only attachment serving when the site is
// in private mode will use X-Sendfile.
// $config['site']['X-Sendfile'] = false;
// $config['site']['use_x_sendfile'] = false;
// You may also need to enable X-Sendfile support for your web server and
// allow it to access files outside of the web root. For Apache with
// mod_xsendfile, you can add these to your .htaccess or server config:

View File

@ -81,3 +81,42 @@ ALTER TABLE profile ADD COLUMN lon decimal(10,7) /*comment 'longitude'*/;
ALTER TABLE profile ADD COLUMN location_id integer /* comment 'location id if possible'*/;
ALTER TABLE profile ADD COLUMN location_ns integer /* comment 'namespace for location'*/;
ALTER TABLE consumer add COLUMN consumer_secret varchar(255) not null ; /*comment 'secret value'*/
ALTER TABLE token ADD COLUMN verifier varchar(255); /* comment 'verifier string for OAuth 1.0a',*/
ALTER TABLE token ADD COLUMN verified_callback varchar(255); /* comment 'verified callback URL for OAuth 1.0a',*/
create table queue_item_new (
id serial /* comment 'unique identifier'*/,
frame bytea not null /* comment 'data: object reference or opaque string'*/,
transport varchar(8) not null /*comment 'queue for what? "email", "jabber", "sms", "irc", ...'*/,
created timestamp not null default CURRENT_TIMESTAMP /*comment 'date this record was created'*/,
claimed timestamp /*comment 'date this item was claimed'*/,
PRIMARY KEY (id)
);
insert into queue_item_new (frame,transport,created,claimed)
select ('0x' || notice_id::text)::bytea,transport,created,claimed from queue_item;
alter table queue_item rename to queue_item_old;
alter table queue_item_new rename to queue_item;
ALTER TABLE confirm_address ALTER column sent set default CURRENT_TIMESTAMP;
create table user_location_prefs (
user_id integer not null /*comment 'user who has the preference'*/ references "user" (id),
share_location int default 1 /* comment 'Whether to share location data'*/,
created timestamp not null /*comment 'date this record was created'*/,
modified timestamp /* comment 'date this record was modified'*/,
primary key (user_id)
);
create table inbox (
user_id integer not null /* comment 'user receiving the notice' */ references "user" (id),
notice_ids bytea /* comment 'packed list of notice ids' */,
primary key (user_id)
);

View File

@ -9,6 +9,7 @@ VALUES
('bti','bti','http://gregkh.github.com/bti/', now()),
('choqok', 'Choqok', 'http://choqok.gnufolks.org/', now()),
('cliqset', 'Cliqset', 'http://www.cliqset.com/', now()),
('DarterosStatus', 'Darteros Status', 'http://www.darteros.com/doc/Darteros_Status', now()),
('deskbar','Deskbar-Applet','http://www.gnome.org/projects/deskbar-applet/', now()),
('Do','Gnome Do','http://do.davebsd.com/wiki/index.php?title=Microblog_Plugin', now()),
('drupal','Drupal','http://drupal.org/', now()),
@ -17,6 +18,7 @@ VALUES
('Facebook','Facebook','http://apps.facebook.com/identica/', now()),
('feed2omb','feed2omb','http://projects.ciarang.com/p/feed2omb/', now()),
('get2gnow', 'get2gnow', 'http://uberchicgeekchick.com/?projects=get2gnow', now()),
('gNewBook', 'gNewBook', 'http://www.gnewbook.org/', now()),
('gravity', 'Gravity', 'http://mobileways.de/gravity', now()),
('Gwibber','Gwibber','http://launchpad.net/gwibber', now()),
('HelloTxt','HelloTxt','http://hellotxt.com/', now()),
@ -49,6 +51,7 @@ VALUES
('smob','SMOB','http://smob.sioc-project.org/', now()),
('socialoomphBfD4pMqz31', 'SocialOomph', 'http://www.socialoomph.com/', now()),
('spaz','Spaz','http://funkatron.com/spaz', now()),
('StatusNet Desktop', 'StatusNet Desktop', 'http://status.net/desktop', now()),
('tarpipe','tarpipe','http://tarpipe.com/', now()),
('tjunar','Tjunar','http://nederflash.nl/boek/titels/tjunar-air', now()),
('tr.im','tr.im','http://tr.im/', now()),

View File

@ -8,6 +8,10 @@ create table profile (
homepage varchar(255) /* comment 'identifying URL' */,
bio varchar(140) /* comment 'descriptive biography' */,
location varchar(255) /* comment 'physical location' */,
lat decimal(10,7) /* comment 'latitude'*/ ,
lon decimal(10,7) /* comment 'longitude'*/ ,
location_id integer /* comment 'location id if possible'*/ ,
location_ns integer /* comment 'namespace for location'*/ ,
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */,
@ -132,6 +136,7 @@ create table notice (
is_local integer default 0 /* comment 'notice was generated by a user' */,
source varchar(32) /* comment 'source of comment, like "web", "im", or "clientname"' */,
conversation integer /*id of root notice in this conversation' */ references notice (id),
location varchar(255) /* comment 'physical location' */,
lat decimal(10,7) /* comment 'latitude'*/ ,
lon decimal(10,7) /* comment 'longitude'*/ ,
location_id integer /* comment 'location id if possible'*/ ,
@ -182,6 +187,7 @@ create index fave_modified_idx on fave using btree(modified);
create table consumer (
consumer_key varchar(255) primary key /* comment 'unique identifier, root URL' */,
consumer_secret varchar(255) not null /* comment 'secret value', */,
seed char(32) not null /* comment 'seed for new tokens by this consumer' */,
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
@ -195,6 +201,9 @@ create table token (
type integer not null default 0 /* comment 'request or access' */,
state integer default 0 /* comment 'for requests 0 = initial, 1 = authorized, 2 = used' */,
verifier varchar(255) /*comment 'verifier string for OAuth 1.0a'*/,
verified_callback varchar(255) /*comment 'verified callback URL for OAuth 1.0a'*/,
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */,
@ -213,17 +222,33 @@ create table nonce (
primary key (consumer_key, ts, nonce)
);
/* One-to-many relationship of user to openid_url */
create table user_openid (
canonical varchar(255) primary key /* comment 'Canonical true URL' */,
display varchar(255) not null unique /* comment 'URL for viewing, may be different from canonical' */,
user_id integer not null /* comment 'user owning this URL' */ references "user" (id) ,
create sequence oauth_application_seq;
create table oauth_application (
id bigint default nextval('oauth_application_seq') primary key /* comment 'unique identifier' */,
owner integer not null /* comment 'owner of the application' */ references profile (id),
consumer_key varchar(255) not null /* comment 'application consumer key' */ references consumer (consumer_key),
name varchar(255) unique not null /* comment 'name of the application' */,
description varchar(255) /* comment 'description of the application' */,
icon varchar(255) not null /* comment 'application icon' */,
source_url varchar(255) /* comment 'application homepage - used for source link' */,
organization varchar(255) /* comment 'name of the organization running the application' */,
homepage varchar(255) /* comment 'homepage for the organization' */,
callback_url varchar(255) /* comment 'url to redirect to after authentication' */,
"type" integer default 0 /* comment 'type of app, 1 = browser, 2 = desktop' */,
access_type integer default 0 /* comment 'default access type, bit 1 = read, bit 2 = write' */,
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */
);
create index user_openid_user_id_idx on user_openid using btree(user_id);
create table oauth_application_user (
profile_id integer not null /* 'user of the application' */ references profile (id),
application_id integer not null /* 'id of the application' */ references oauth_application (id),
access_type integer default 0 /* 'access type, bit 1 = read, bit 2 = write' */,
token varchar(255) /* 'request or access token' */,
created timestamp not null default CURRENT_TIMESTAMP /* 'date this record was created' */,
modified timestamp /* 'date this record was modified' */,
primary key (profile_id, application_id)
);
/* These are used by JanRain OpenID library */
@ -251,7 +276,7 @@ create table confirm_address (
address_extra varchar(255) not null default '' /* comment 'carrier ID, for SMS' */,
address_type varchar(8) not null /* comment 'address type ("email", "jabber", "sms")' */,
claimed timestamp /* comment 'date this was claimed for queueing' */,
sent timestamp /* comment 'date this was sent for queueing' */,
sent timestamp default CURRENT_TIMESTAMP /* comment 'date this was sent for queueing' */,
modified timestamp /* comment 'date this record was modified' */
);
@ -262,14 +287,12 @@ create table remember_me (
);
create table queue_item (
notice_id integer not null /* comment 'notice queued' */ references notice (id) ,
transport varchar(8) not null /* comment 'queue for what? "email", "jabber", "sms", "irc", ...' */,
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
claimed timestamp /* comment 'date this item was claimed' */,
primary key (notice_id, transport)
id serial /* comment 'unique identifier'*/,
frame bytea not null /* comment 'data: object reference or opaque string'*/,
transport varchar(8) not null /*comment 'queue for what? "email", "jabber", "sms", "irc", ...'*/,
created timestamp not null default CURRENT_TIMESTAMP /*comment 'date this record was created'*/,
claimed timestamp /*comment 'date this item was claimed'*/,
PRIMARY KEY (id)
);
create index queue_item_created_idx on queue_item using btree(created);
@ -589,3 +612,39 @@ create table login_token (
primary key (user_id)
);
create table user_location_prefs (
user_id integer not null /* comment 'user who has the preference' */ references "user" (id),
share_location integer default 1 /* comment 'Whether to share location data' */,
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */,
primary key (user_id)
);
create table inbox (
user_id integer not null /* comment 'user receiving the notice' */ references "user" (id),
notice_ids bytea /* comment 'packed list of notice ids' */,
primary key (user_id)
);
create sequence conversation_seq;
create table conversation (
id bigint default nextval('conversation_seq') primary key /* comment 'unique identifier' */,
uri varchar(225) unique /* comment 'URI of the conversation' */,
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */
);
create table local_group (
group_id integer primary key /* comment 'group represented' */ references user_group (id),
nickname varchar(64) unique /* comment 'group represented' */,
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */
);

View File

@ -20,7 +20,7 @@
/**
* The library version string
*/
define('Auth_OpenID_VERSION', '2.1.3');
define('Auth_OpenID_VERSION', '2.2.2');
/**
* Require the fetcher code.
@ -102,9 +102,7 @@ define('Auth_OpenID_digits',
define('Auth_OpenID_punct',
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
if (Auth_OpenID_getMathLib() === null) {
Auth_OpenID_setNoMathSupport();
}
Auth_OpenID_include_init();
/**
* The OpenID utility function class.
@ -120,7 +118,7 @@ class Auth_OpenID {
*
* @access private
*/
function isFailure($thing)
static function isFailure($thing)
{
return is_a($thing, 'Auth_OpenID_FailureResponse');
}
@ -139,9 +137,12 @@ class Auth_OpenID {
* Returns an empty array if neither GET nor POST was used, or if
* POST was used but php://input cannot be opened.
*
* See background:
* http://lists.openidenabled.com/pipermail/dev/2007-March/000395.html
*
* @access private
*/
function getQuery($query_str=null)
static function getQuery($query_str=null)
{
$data = array();
@ -177,7 +178,7 @@ class Auth_OpenID {
return $data;
}
function params_from_string($str)
static function params_from_string($str)
{
$chunks = explode("&", $str);
@ -190,7 +191,7 @@ class Auth_OpenID {
}
list($k, $v) = $parts;
$data[$k] = urldecode($v);
$data[urldecode($k)] = urldecode($v);
}
return $data;
@ -203,7 +204,7 @@ class Auth_OpenID {
*
* @access private
*/
function ensureDir($dir_name)
static function ensureDir($dir_name)
{
if (is_dir($dir_name) || @mkdir($dir_name)) {
return true;
@ -225,7 +226,7 @@ class Auth_OpenID {
*
* @access private
*/
function addPrefix($values, $prefix)
static function addPrefix($values, $prefix)
{
$new_values = array();
foreach ($values as $s) {
@ -241,7 +242,7 @@ class Auth_OpenID {
*
* @access private
*/
function arrayGet($arr, $key, $fallback = null)
static function arrayGet($arr, $key, $fallback = null)
{
if (is_array($arr)) {
if (array_key_exists($key, $arr)) {
@ -261,7 +262,7 @@ class Auth_OpenID {
/**
* Replacement for PHP's broken parse_str.
*/
function parse_str($query)
static function parse_str($query)
{
if ($query === null) {
return null;
@ -278,7 +279,7 @@ class Auth_OpenID {
}
list($key, $value) = $pair;
$new_parts[$key] = urldecode($value);
$new_parts[urldecode($key)] = urldecode($value);
}
return $new_parts;
@ -295,7 +296,7 @@ class Auth_OpenID {
* pairs from $data into a URL query string
* (e.g. "username=bob&id=56").
*/
function httpBuildQuery($data)
static function httpBuildQuery($data)
{
$pairs = array();
foreach ($data as $key => $value) {
@ -323,7 +324,7 @@ class Auth_OpenID {
* @return string $url The original URL with the new parameters added.
*
*/
function appendArgs($url, $args)
static function appendArgs($url, $args)
{
if (count($args) == 0) {
return $url;
@ -367,7 +368,7 @@ class Auth_OpenID {
* @return string $url The URL resulting from assembling the
* specified components.
*/
function urlunparse($scheme, $host, $port = null, $path = '/',
static function urlunparse($scheme, $host, $port = null, $path = '/',
$query = '', $fragment = '')
{
@ -412,7 +413,7 @@ class Auth_OpenID {
* @return mixed $new_url The URL after normalization, or null if
* $url was malformed.
*/
function normalizeUrl($url)
static function normalizeUrl($url)
{
@$parsed = parse_url($url);
@ -443,7 +444,7 @@ class Auth_OpenID {
*
* @access private
*/
function intval($value)
static function intval($value)
{
$re = "/^\\d+$/";
@ -461,7 +462,7 @@ class Auth_OpenID {
* @param string $str The string of bytes to count.
* @return int The number of bytes in $str.
*/
function bytes($str)
static function bytes($str)
{
return strlen(bin2hex($str)) / 2;
}
@ -470,7 +471,7 @@ class Auth_OpenID {
* Get the bytes in a string independently of multibyte support
* conditions.
*/
function toBytes($str)
static function toBytes($str)
{
$hex = bin2hex($str);
@ -486,7 +487,7 @@ class Auth_OpenID {
return $b;
}
function urldefrag($url)
static function urldefrag($url)
{
$parts = explode("#", $url, 2);
@ -497,7 +498,7 @@ class Auth_OpenID {
}
}
function filter($callback, &$sequence)
static function filter($callback, &$sequence)
{
$result = array();
@ -510,7 +511,7 @@ class Auth_OpenID {
return $result;
}
function update(&$dest, &$src)
static function update(&$dest, &$src)
{
foreach ($src as $k => $v) {
$dest[$k] = $v;
@ -524,14 +525,14 @@ class Auth_OpenID {
*
* @param string $format_string The sprintf format for the message
*/
function log($format_string)
static function log($format_string)
{
$args = func_get_args();
$message = call_user_func_array('sprintf', $args);
error_log($message);
}
function autoSubmitHTML($form, $title="OpenId transaction in progress")
static function autoSubmitHTML($form, $title="OpenId transaction in progress")
{
return("<html>".
"<head><title>".
@ -549,4 +550,14 @@ class Auth_OpenID {
"</html>");
}
}
?>
/*
* Function to run when this file is included.
* Abstracted to a function to make life easier
* for some PHP optimizers.
*/
function Auth_OpenID_include_init() {
if (Auth_OpenID_getMathLib() === null) {
Auth_OpenID_setNoMathSupport();
}
}

View File

@ -38,7 +38,7 @@ class Auth_OpenID_AX {
* @return bool true if $thing is an Auth_OpenID_AX_Error; false
* if not.
*/
function isError($thing)
static function isError($thing)
{
return is_a($thing, 'Auth_OpenID_AX_Error');
}
@ -191,7 +191,7 @@ class Auth_OpenID_AX_AttrInfo {
* Construct an attribute information object. For parameter
* details, see the constructor.
*/
function make($type_uri, $count=1, $required=false,
static function make($type_uri, $count=1, $required=false,
$alias=null)
{
if ($alias !== null) {
@ -235,7 +235,7 @@ class Auth_OpenID_AX_AttrInfo {
* return null If an alias is present in the list of aliases but
* is not present in the namespace map.
*/
function Auth_OpenID_AX_toTypeURIs(&$namespace_map, $alias_list_s)
function Auth_OpenID_AX_toTypeURIs($namespace_map, $alias_list_s)
{
$uris = array();
@ -386,7 +386,7 @@ class Auth_OpenID_AX_FetchRequest extends Auth_OpenID_AX_Message {
* Auth_OpenID_AX_FetchRequest extracted from the request message if
* successful
*/
function &fromOpenIDRequest($request)
static function fromOpenIDRequest($request)
{
$m = $request->message;
$obj = new Auth_OpenID_AX_FetchRequest();
@ -484,7 +484,7 @@ class Auth_OpenID_AX_FetchRequest extends Auth_OpenID_AX_Message {
Auth_OpenID::arrayGet($ax_args, 'required'));
foreach ($required as $type_uri) {
$attrib =& $this->requested_attributes[$type_uri];
$attrib = $this->requested_attributes[$type_uri];
$attrib->required = true;
}
@ -587,7 +587,7 @@ class Auth_OpenID_AX_KeyValueMessage extends Auth_OpenID_AX_Message {
*
* @access private
*/
function _getExtensionKVArgs(&$aliases)
function _getExtensionKVArgs($aliases)
{
if ($aliases === null) {
$aliases = new Auth_OpenID_NamespaceMap();
@ -652,7 +652,7 @@ class Auth_OpenID_AX_KeyValueMessage extends Auth_OpenID_AX_Message {
foreach ($aliases->iteritems() as $pair) {
list($type_uri, $alias) = $pair;
if (array_key_exists('count.' . $alias, $ax_args)) {
if (array_key_exists('count.' . $alias, $ax_args) && ($ax_args['count.' . $alias] !== Auth_OpenID_AX_UNLIMITED_VALUES)) {
$count_key = 'count.' . $alias;
$count_s = $ax_args[$count_key];
@ -888,7 +888,7 @@ class Auth_OpenID_AX_FetchResponse extends Auth_OpenID_AX_KeyValueMessage {
$ax_args['update_url'] = $update_url;
}
Auth_OpenID::update(&$ax_args, $kv_args);
Auth_OpenID::update($ax_args, $kv_args);
return $ax_args;
}
@ -922,7 +922,7 @@ class Auth_OpenID_AX_FetchResponse extends Auth_OpenID_AX_KeyValueMessage {
* @return $response A FetchResponse containing the data from the
* OpenID message
*/
function fromSuccessResponse($success_response, $signed=true)
static function fromSuccessResponse($success_response, $signed=true)
{
$obj = new Auth_OpenID_AX_FetchResponse();
if ($signed) {
@ -960,7 +960,7 @@ class Auth_OpenID_AX_StoreRequest extends Auth_OpenID_AX_KeyValueMessage {
{
$ax_args = $this->_newArgs();
$kv_args = $this->_getExtensionKVArgs($aliases);
Auth_OpenID::update(&$ax_args, $kv_args);
Auth_OpenID::update($ax_args, $kv_args);
return $ax_args;
}
}
@ -980,7 +980,7 @@ class Auth_OpenID_AX_StoreResponse extends Auth_OpenID_AX_Message {
* Returns Auth_OpenID_AX_Error on error or an
* Auth_OpenID_AX_StoreResponse object on success.
*/
function &make($succeeded=true, $error_message=null)
function make($succeeded=true, $error_message=null)
{
if (($succeeded) && ($error_message !== null)) {
return new Auth_OpenID_AX_Error('An error message may only be '.
@ -1020,4 +1020,3 @@ class Auth_OpenID_AX_StoreResponse extends Auth_OpenID_AX_Message {
}
}
?>

View File

@ -94,7 +94,7 @@ class Auth_OpenID_Association {
* @return association An {@link Auth_OpenID_Association}
* instance.
*/
function fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
static function fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
{
$issued = time();
$lifetime = $expires_in;
@ -132,7 +132,7 @@ class Auth_OpenID_Association {
$handle, $secret, $issued, $lifetime, $assoc_type)
{
if (!in_array($assoc_type,
Auth_OpenID_getSupportedAssociationTypes())) {
Auth_OpenID_getSupportedAssociationTypes(), true)) {
$fmt = 'Unsupported association type (%s)';
trigger_error(sprintf($fmt, $assoc_type), E_USER_ERROR);
}
@ -206,7 +206,7 @@ class Auth_OpenID_Association {
* @param string $assoc_s Association as serialized by serialize()
* @return Auth_OpenID_Association $result instance of this class
*/
function deserialize($class_name, $assoc_s)
static function deserialize($class_name, $assoc_s)
{
$pairs = Auth_OpenID_KVForm::toArray($assoc_s, $strict = true);
$keys = array();
@ -327,7 +327,7 @@ class Auth_OpenID_Association {
*
* @access private
*/
function _makePairs(&$message)
function _makePairs($message)
{
$signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
if (!$signed || Auth_OpenID::isFailure($signed)) {
@ -352,7 +352,7 @@ class Auth_OpenID_Association {
*
* @access private
*/
function getMessageSignature(&$message)
function getMessageSignature($message)
{
$pairs = $this->_makePairs($message);
return base64_encode($this->sign($pairs));
@ -364,7 +364,7 @@ class Auth_OpenID_Association {
*
* @access private
*/
function checkMessageSignature(&$message)
function checkMessageSignature($message)
{
$sig = $message->getArg(Auth_OpenID_OPENID_NS,
'sig');
@ -374,7 +374,42 @@ class Auth_OpenID_Association {
}
$calculated_sig = $this->getMessageSignature($message);
return $calculated_sig == $sig;
return $this->constantTimeCompare($calculated_sig, $sig);
}
/**
* String comparison function which will complete in a constant time
* for strings of any given matching length, to help prevent an attacker
* from distinguishing how much of a signature token they have guessed
* correctly.
*
* For this usage, it's assumed that the length of the string is known,
* so we may safely short-circuit on mismatched lengths which will be known
* to be invalid by the attacker.
*
* http://lists.openid.net/pipermail/openid-security/2010-July/001156.html
* http://rdist.root.org/2010/01/07/timing-independent-array-comparison/
*/
private function constantTimeCompare($a, $b)
{
$len = strlen($a);
if (strlen($b) !== $len) {
// Short-circuit on length mismatch; attackers will already know
// the correct target length so this is safe.
return false;
}
if ($len == 0) {
// 0-length valid input shouldn't really happen. :)
return true;
}
$result = 0;
for ($i = 0; $i < strlen($a); $i++) {
// We use scary bitwise operations to avoid logical short-circuits
// in lower-level code.
$result |= ord($a{$i}) ^ ord($b{$i});
}
return ($result == 0);
}
}
@ -469,18 +504,16 @@ function Auth_OpenID_getOnlyEncryptedOrder()
return $result;
}
function &Auth_OpenID_getDefaultNegotiator()
function Auth_OpenID_getDefaultNegotiator()
{
$x = new Auth_OpenID_SessionNegotiator(
return new Auth_OpenID_SessionNegotiator(
Auth_OpenID_getDefaultAssociationOrder());
return $x;
}
function &Auth_OpenID_getEncryptedNegotiator()
function Auth_OpenID_getEncryptedNegotiator()
{
$x = new Auth_OpenID_SessionNegotiator(
return new Auth_OpenID_SessionNegotiator(
Auth_OpenID_getOnlyEncryptedOrder());
return $x;
}
/**
@ -610,4 +643,3 @@ class Auth_OpenID_SessionNegotiator {
}
}
?>

View File

@ -351,8 +351,7 @@ function Auth_OpenID_math_extensions()
'class' => 'Auth_OpenID_GmpMathWrapper');
}
$result[] = array(
'modules' => array('bcmath', 'php_bcmath'),
$result[] = array('modules' => array('bcmath', 'php_bcmath'),
'extension' => 'bcmath',
'class' => 'Auth_OpenID_BcMathWrapper');
@ -366,27 +365,9 @@ function Auth_OpenID_detectMathLibrary($exts)
{
$loaded = false;
$hasDl = function_exists('dl');
foreach ($exts as $extension) {
// See if the extension specified is already loaded.
if ($extension['extension'] &&
extension_loaded($extension['extension'])) {
$loaded = true;
}
// Try to load dynamic modules.
if (!$loaded) {
foreach ($extension['modules'] as $module) {
if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
$loaded = true;
break;
}
}
}
// If the load succeeded, supply an instance of
// Auth_OpenID_MathWrapper which wraps the specified
// module's functionality.
if ($loaded) {
if (extension_loaded($extension['extension'])) {
return $extension;
}
}
@ -405,7 +386,7 @@ function Auth_OpenID_detectMathLibrary($exts)
* instance of a wrapper for that extension module. If no extension
* module is found, an instance of {@link Auth_OpenID_MathWrapper} is
* returned, which wraps the native PHP integer implementation. The
* proper calling convention for this method is $lib =&
* proper calling convention for this method is $lib =
* Auth_OpenID_getMathLib().
*
* This function checks for the existence of specific long number
@ -416,7 +397,7 @@ function Auth_OpenID_detectMathLibrary($exts)
*
* @package OpenID
*/
function &Auth_OpenID_getMathLib()
function Auth_OpenID_getMathLib()
{
// The instance of Auth_OpenID_MathWrapper that we choose to
// supply will be stored here, so that subseqent calls to this
@ -468,4 +449,4 @@ function Auth_OpenID_noMathSupport()
return defined('Auth_OpenID_NO_MATH_SUPPORT');
}
?>

View File

@ -258,19 +258,19 @@ class Auth_OpenID_Consumer {
* when creating the internal consumer object. This is used for
* testing.
*/
function Auth_OpenID_Consumer(&$store, $session = null,
function Auth_OpenID_Consumer($store, $session = null,
$consumer_cls = null)
{
if ($session === null) {
$session = new Auth_Yadis_PHPSession();
}
$this->session =& $session;
$this->session = $session;
if ($consumer_cls !== null) {
$this->consumer =& new $consumer_cls($store);
$this->consumer = new $consumer_cls($store);
} else {
$this->consumer =& new Auth_OpenID_GenericConsumer($store);
$this->consumer = new Auth_OpenID_GenericConsumer($store);
}
$this->_token_key = $this->session_key_prefix . $this->_token_suffix;
@ -281,7 +281,7 @@ class Auth_OpenID_Consumer {
*
* @access private
*/
function getDiscoveryObject(&$session, $openid_url,
function getDiscoveryObject($session, $openid_url,
$session_key_prefix)
{
return new Auth_Yadis_Discovery($session, $openid_url,
@ -339,7 +339,7 @@ class Auth_OpenID_Consumer {
$this->consumer->fetcher);
// Reset the 'stale' attribute of the manager.
$m =& $disco->getManager();
$m = $disco->getManager();
if ($m) {
$m->stale = false;
$disco->session->set($disco->session_key,
@ -370,7 +370,7 @@ class Auth_OpenID_Consumer {
* @return Auth_OpenID_AuthRequest $auth_request An OpenID
* authentication request object.
*/
function &beginWithoutDiscovery($endpoint, $anonymous=false)
function beginWithoutDiscovery($endpoint, $anonymous=false)
{
$loader = new Auth_OpenID_ServiceEndpointLoader();
$auth_req = $this->consumer->begin($endpoint);
@ -467,7 +467,7 @@ class Auth_OpenID_DiffieHellmanSHA1ConsumerSession {
function getRequest()
{
$math =& Auth_OpenID_getMathLib();
$math = Auth_OpenID_getMathLib();
$cpub = $math->longToBase64($this->dh->public);
@ -496,7 +496,7 @@ class Auth_OpenID_DiffieHellmanSHA1ConsumerSession {
return null;
}
$math =& Auth_OpenID_getMathLib();
$math = Auth_OpenID_getMathLib();
$spub = $math->base64ToLong($response->getArg(Auth_OpenID_OPENID_NS,
'dh_server_public'));
@ -611,11 +611,11 @@ class Auth_OpenID_GenericConsumer {
* in the module description. The default value is False, which
* disables immediate mode.
*/
function Auth_OpenID_GenericConsumer(&$store)
function Auth_OpenID_GenericConsumer($store)
{
$this->store =& $store;
$this->negotiator =& Auth_OpenID_getDefaultNegotiator();
$this->_use_assocs = ($this->store ? true : false);
$this->store = $store;
$this->negotiator = Auth_OpenID_getDefaultNegotiator();
$this->_use_assocs = (is_null($this->store) ? false : true);
$this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
@ -665,14 +665,14 @@ class Auth_OpenID_GenericConsumer {
$method = Auth_OpenID::arrayGet($mode_methods, $mode,
'_completeInvalid');
return call_user_func_array(array(&$this, $method),
array($message, $endpoint, $return_to));
return call_user_func_array(array($this, $method),
array($message, &$endpoint, $return_to));
}
/**
* @access private
*/
function _completeInvalid($message, &$endpoint, $unused)
function _completeInvalid($message, $endpoint, $unused)
{
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
'<No mode set>');
@ -684,7 +684,7 @@ class Auth_OpenID_GenericConsumer {
/**
* @access private
*/
function _complete_cancel($message, &$endpoint, $unused)
function _complete_cancel($message, $endpoint, $unused)
{
return new Auth_OpenID_CancelResponse($endpoint);
}
@ -692,7 +692,7 @@ class Auth_OpenID_GenericConsumer {
/**
* @access private
*/
function _complete_error($message, &$endpoint, $unused)
function _complete_error($message, $endpoint, $unused)
{
$error = $message->getArg(Auth_OpenID_OPENID_NS, 'error');
$contact = $message->getArg(Auth_OpenID_OPENID_NS, 'contact');
@ -705,7 +705,7 @@ class Auth_OpenID_GenericConsumer {
/**
* @access private
*/
function _complete_setup_needed($message, &$endpoint, $unused)
function _complete_setup_needed($message, $endpoint, $unused)
{
if (!$message->isOpenID2()) {
return $this->_completeInvalid($message, $endpoint);
@ -719,7 +719,7 @@ class Auth_OpenID_GenericConsumer {
/**
* @access private
*/
function _complete_id_res($message, &$endpoint, $return_to)
function _complete_id_res($message, $endpoint, $return_to)
{
$user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
'user_setup_url');
@ -1181,7 +1181,7 @@ class Auth_OpenID_GenericConsumer {
// oidutil.log('Performing discovery on %s' % (claimed_id,))
list($unused, $services) = call_user_func($this->discoverMethod,
$claimed_id,
$this->fetcher);
&$this->fetcher);
if (!$services) {
return new Auth_OpenID_FailureResponse(null,
@ -1197,7 +1197,7 @@ class Auth_OpenID_GenericConsumer {
* @access private
*/
function _verifyDiscoveryServices($claimed_id,
&$services, &$to_match_endpoints)
$services, $to_match_endpoints)
{
// Search the services resulting from discovery to find one
// that matches the information from the assertion
@ -1216,8 +1216,8 @@ class Auth_OpenID_GenericConsumer {
}
return new Auth_OpenID_FailureResponse(null,
sprintf('No matching endpoint found after discovering %s',
$claimed_id));
sprintf('No matching endpoint found after discovering %s: %s',
$claimed_id, $result->message));
}
/**
@ -1397,7 +1397,7 @@ class Auth_OpenID_GenericConsumer {
*
* @access private
*/
function _httpResponseToMessage($response, $server_url)
static function _httpResponseToMessage($response, $server_url)
{
// Should this function be named Message.fromHTTPResponse instead?
$response_message = Auth_OpenID_Message::fromKVForm($response->body);
@ -1461,7 +1461,7 @@ class Auth_OpenID_GenericConsumer {
*
* @access private
*/
function _extractSupportedAssociationType(&$server_error, &$endpoint,
function _extractSupportedAssociationType($server_error, $endpoint,
$assoc_type)
{
// Any error message whose code is not 'unsupported-type'
@ -1566,7 +1566,7 @@ class Auth_OpenID_GenericConsumer {
/**
* @access private
*/
function _extractAssociation(&$assoc_response, &$assoc_session)
function _extractAssociation($assoc_response, $assoc_session)
{
// Extract the common fields from the response, raising an
// exception if they are not found
@ -1748,10 +1748,10 @@ class Auth_OpenID_AuthRequest {
* class. Instances of this class are created by the library when
* needed.
*/
function Auth_OpenID_AuthRequest(&$endpoint, $assoc)
function Auth_OpenID_AuthRequest($endpoint, $assoc)
{
$this->assoc = $assoc;
$this->endpoint =& $endpoint;
$this->endpoint = $endpoint;
$this->return_to_args = array();
$this->message = new Auth_OpenID_Message(
$endpoint->preferredNamespace());
@ -1764,7 +1764,7 @@ class Auth_OpenID_AuthRequest {
* $extension_request: An object that implements the extension
* request interface for adding arguments to an OpenID message.
*/
function addExtension(&$extension_request)
function addExtension($extension_request)
{
$extension_request->toMessage($this->message);
}
@ -2089,7 +2089,7 @@ class Auth_OpenID_SuccessResponse extends Auth_OpenID_ConsumerResponse {
foreach ($msg_args as $key => $value) {
if (!$this->isSigned($ns_uri, $key)) {
return null;
unset($msg_args[$key]);
}
}
@ -2167,7 +2167,7 @@ class Auth_OpenID_ServerErrorContainer {
/**
* @access private
*/
function fromMessage($message)
static function fromMessage($message)
{
$error_text = $message->getArg(
Auth_OpenID_OPENID_NS, 'error', '<no error message supplied>');
@ -2227,4 +2227,4 @@ class Auth_OpenID_SetupNeededResponse extends Auth_OpenID_ConsumerResponse {
}
}
?>

View File

@ -37,7 +37,7 @@ class Auth_OpenID_CryptUtil {
* @param int $num_bytes The length of the return value
* @return string $bytes random bytes
*/
function getBytes($num_bytes)
static function getBytes($num_bytes)
{
static $f = null;
$bytes = '';
@ -77,7 +77,7 @@ class Auth_OpenID_CryptUtil {
* @return string $result A string of randomly-chosen characters
* from $chrs
*/
function randomString($length, $population = null)
static function randomString($length, $population = null)
{
if ($population === null) {
return Auth_OpenID_CryptUtil::getBytes($length);
@ -106,4 +106,3 @@ class Auth_OpenID_CryptUtil {
}
}
?>

View File

@ -128,4 +128,3 @@ class Auth_OpenID_DatabaseConnection {
}
}
?>

View File

@ -51,9 +51,9 @@ class Auth_OpenID_DiffieHellman {
$private = null, $lib = null)
{
if ($lib === null) {
$this->lib =& Auth_OpenID_getMathLib();
$this->lib = Auth_OpenID_getMathLib();
} else {
$this->lib =& $lib;
$this->lib = $lib;
}
if ($mod === null) {
@ -110,4 +110,4 @@ class Auth_OpenID_DiffieHellman {
}
}
?>

View File

@ -28,8 +28,34 @@ function Auth_OpenID_getOpenIDTypeURIs()
Auth_OpenID_TYPE_2_0,
Auth_OpenID_TYPE_1_2,
Auth_OpenID_TYPE_1_1,
Auth_OpenID_TYPE_1_0,
Auth_OpenID_RP_RETURN_TO_URL_TYPE);
Auth_OpenID_TYPE_1_0);
}
function Auth_OpenID_getOpenIDConsumerTypeURIs()
{
return array(Auth_OpenID_RP_RETURN_TO_URL_TYPE);
}
/*
* Provides a user-readable interpretation of a type uri.
* Useful for error messages.
*/
function Auth_OpenID_getOpenIDTypeName($type_uri) {
switch ($type_uri) {
case Auth_OpenID_TYPE_2_0_IDP:
return 'OpenID 2.0 IDP';
case Auth_OpenID_TYPE_2_0:
return 'OpenID 2.0';
case Auth_OpenID_TYPE_1_2:
return 'OpenID 1.2';
case Auth_OpenID_TYPE_1_1:
return 'OpenID 1.1';
case Auth_OpenID_TYPE_1_0:
return 'OpenID 1.0';
case Auth_OpenID_RP_RETURN_TO_URL_TYPE:
return 'OpenID relying party';
}
}
/**
@ -124,7 +150,7 @@ class Auth_OpenID_ServiceEndpoint {
return in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris);
}
function fromOPEndpointURL($op_endpoint_url)
static function fromOPEndpointURL($op_endpoint_url)
{
// Construct an OP-Identifier OpenIDServiceEndpoint object for
// a given OP Endpoint URL
@ -171,15 +197,34 @@ class Auth_OpenID_ServiceEndpoint {
}
}
/*
* Parse the given document as XRDS looking for OpenID consumer services.
*
* @return array of Auth_OpenID_ServiceEndpoint or null if the
* document cannot be parsed.
*/
function consumerFromXRDS($uri, $xrds_text)
{
$xrds =& Auth_Yadis_XRDS::parseXRDS($xrds_text);
if ($xrds) {
$yadis_services =
$xrds->services(array('filter_MatchesAnyOpenIDConsumerType'));
return Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services);
}
return null;
}
/*
* Parse the given document as XRDS looking for OpenID services.
*
* @return array of Auth_OpenID_ServiceEndpoint or null if the
* document cannot be parsed.
*/
function fromXRDS($uri, $xrds_text)
static function fromXRDS($uri, $xrds_text)
{
$xrds =& Auth_Yadis_XRDS::parseXRDS($xrds_text);
$xrds = Auth_Yadis_XRDS::parseXRDS($xrds_text);
if ($xrds) {
$yadis_services =
@ -197,7 +242,7 @@ class Auth_OpenID_ServiceEndpoint {
* @return array of Auth_OpenID_ServiceEndpoint or null if
* endpoints cannot be created.
*/
function fromDiscoveryResult($discoveryResult)
static function fromDiscoveryResult($discoveryResult)
{
if ($discoveryResult->isXRDS()) {
return Auth_OpenID_ServiceEndpoint::fromXRDS(
@ -210,7 +255,7 @@ class Auth_OpenID_ServiceEndpoint {
}
}
function fromHTML($uri, $html)
static function fromHTML($uri, $html)
{
$discovery_types = array(
array(Auth_OpenID_TYPE_2_0,
@ -273,7 +318,7 @@ function Auth_OpenID_findOPLocalIdentifier($service, $type_uris)
$service->parser->registerNamespace('xrd',
Auth_Yadis_XMLNS_XRD_2_0);
$parser =& $service->parser;
$parser = $service->parser;
$permitted_tags = array();
@ -305,7 +350,7 @@ function Auth_OpenID_findOPLocalIdentifier($service, $type_uris)
return $local_id;
}
function filter_MatchesAnyOpenIDType(&$service)
function filter_MatchesAnyOpenIDType($service)
{
$uris = $service->getTypes();
@ -318,6 +363,19 @@ function filter_MatchesAnyOpenIDType(&$service)
return false;
}
function filter_MatchesAnyOpenIDConsumerType(&$service)
{
$uris = $service->getTypes();
foreach ($uris as $uri) {
if (in_array($uri, Auth_OpenID_getOpenIDConsumerTypeURIs())) {
return true;
}
}
return false;
}
function Auth_OpenID_bestMatchingService($service, $preferred_types)
{
// Return the index of the first matching type, or something
@ -415,7 +473,7 @@ function Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services)
return $s;
}
function Auth_OpenID_discoverWithYadis($uri, &$fetcher,
function Auth_OpenID_discoverWithYadis($uri, $fetcher,
$endpoint_filter='Auth_OpenID_getOPOrUserServices',
$discover_function=null)
{
@ -433,12 +491,12 @@ function Auth_OpenID_discoverWithYadis($uri, &$fetcher,
$openid_services = array();
$response = call_user_func_array($discover_function,
array($uri, &$fetcher));
array($uri, $fetcher));
$yadis_url = $response->normalized_uri;
$yadis_services = array();
if ($response->isFailure()) {
if ($response->isFailure() && !$response->isXRDS()) {
return array($uri, array());
}
@ -460,18 +518,18 @@ function Auth_OpenID_discoverWithYadis($uri, &$fetcher,
}
$openid_services = call_user_func_array($endpoint_filter,
array(&$openid_services));
array($openid_services));
return array($yadis_url, $openid_services);
}
function Auth_OpenID_discoverURI($uri, &$fetcher)
function Auth_OpenID_discoverURI($uri, $fetcher)
{
$uri = Auth_OpenID::normalizeUrl($uri);
return Auth_OpenID_discoverWithYadis($uri, $fetcher);
}
function Auth_OpenID_discoverWithoutYadis($uri, &$fetcher)
function Auth_OpenID_discoverWithoutYadis($uri, $fetcher)
{
$http_resp = @$fetcher->get($uri);
@ -490,7 +548,7 @@ function Auth_OpenID_discoverWithoutYadis($uri, &$fetcher)
return array($identity_url, $openid_services);
}
function Auth_OpenID_discoverXRI($iname, &$fetcher)
function Auth_OpenID_discoverXRI($iname, $fetcher)
{
$resolver = new Auth_Yadis_ProxyResolver($fetcher);
list($canonicalID, $yadis_services) =
@ -513,7 +571,7 @@ function Auth_OpenID_discoverXRI($iname, &$fetcher)
return array($iname, $openid_services);
}
function Auth_OpenID_discover($uri, &$fetcher)
function Auth_OpenID_discover($uri, $fetcher)
{
// If the fetcher (i.e., PHP) doesn't support SSL, we can't do
// discovery on an HTTPS URL.
@ -545,4 +603,4 @@ function Auth_OpenID_discover($uri, &$fetcher)
return $result;
}
?>

View File

@ -97,4 +97,3 @@ class Auth_OpenID_DumbStore extends Auth_OpenID_OpenIDStore {
}
}
?>

View File

@ -39,7 +39,7 @@ class Auth_OpenID_Extension {
*
* Returns the message with the extension arguments added.
*/
function toMessage(&$message)
function toMessage($message)
{
$implicit = $message->isOpenID1();
$added = $message->namespaces->addAlias($this->ns_uri,
@ -59,4 +59,3 @@ class Auth_OpenID_Extension {
}
}
?>

View File

@ -367,7 +367,7 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
}
if ( abs($timestamp - time()) > $Auth_OpenID_SKEW ) {
return False;
return false;
}
if ($server_url) {
@ -519,7 +519,7 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
/**
* @access private
*/
function _mkdtemp($dir)
static function _mkdtemp($dir)
{
foreach (range(0, 4) as $i) {
$name = $dir . strval(DIRECTORY_SEPARATOR) . strval(getmypid()) .
@ -615,4 +615,4 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
}
}
?>

View File

@ -96,4 +96,3 @@ if (function_exists('hash_hmac') &&
define('Auth_OpenID_HMACSHA256_SUPPORTED', false);
}
?>

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