From 5efe588174c71979fc1970353c9a556ea441f138 Mon Sep 17 00:00:00 2001
From: Zach Copley
Date: Wed, 26 Aug 2009 00:59:06 +0000
Subject: Moved the rest of the Twitter stuff into the TwitterBridge plugin
---
.../TwitterBridge/daemons/synctwitterfriends.php | 280 +++++++++++
.../TwitterBridge/daemons/twitterqueuehandler.php | 73 +++
.../TwitterBridge/daemons/twitterstatusfetcher.php | 559 +++++++++++++++++++++
3 files changed, 912 insertions(+)
create mode 100755 plugins/TwitterBridge/daemons/synctwitterfriends.php
create mode 100755 plugins/TwitterBridge/daemons/twitterqueuehandler.php
create mode 100755 plugins/TwitterBridge/daemons/twitterstatusfetcher.php
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
new file mode 100755
index 000000000..b7be5d043
--- /dev/null
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -0,0 +1,280 @@
+#!/usr/bin/env php
+.
+ */
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
+
+$shortoptions = 'di::';
+$longoptions = array('id::', 'debug');
+
+$helptext = <<
+ * @author Evan Prodromou
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://laconi.ca/
+ */
+
+$helptext = <<_id);
+ }
+
+ /**
+ * Find all the Twitter foreign links for users who have requested
+ * automatically subscribing to their Twitter friends locally.
+ *
+ * @return array flinks an array of Foreign_link objects
+ */
+ function getObjects()
+ {
+ $flinks = array();
+ $flink = new Foreign_link();
+
+ $conn = &$flink->getDatabaseConnection();
+
+ $flink->service = TWITTER_SERVICE;
+ $flink->orderBy('last_friendsync');
+ $flink->limit(25); // sync this many users during this run
+ $flink->find();
+
+ while ($flink->fetch()) {
+ if (($flink->friendsync & FOREIGN_FRIEND_RECV) == FOREIGN_FRIEND_RECV) {
+ $flinks[] = clone($flink);
+ }
+ }
+
+ $conn->disconnect();
+
+ global $_DB_DATAOBJECT;
+ unset($_DB_DATAOBJECT['CONNECTIONS']);
+
+ return $flinks;
+ }
+
+ function childTask($flink) {
+
+ // Each child ps needs its own DB connection
+
+ // Note: DataObject::getDatabaseConnection() creates
+ // a new connection if there isn't one already
+
+ $conn = &$flink->getDatabaseConnection();
+
+ $this->subscribeTwitterFriends($flink);
+
+ $flink->last_friendsync = common_sql_now();
+ $flink->update();
+
+ $conn->disconnect();
+
+ // XXX: Couldn't find a less brutal way to blow
+ // away a cached connection
+
+ global $_DB_DATAOBJECT;
+ unset($_DB_DATAOBJECT['CONNECTIONS']);
+ }
+
+ function fetchTwitterFriends($flink)
+ {
+ $friends = array();
+
+ $token = TwitterOAuthClient::unpackToken($flink->credentials);
+
+ $client = new TwitterOAuthClient($token->key, $token->secret);
+
+ try {
+ $friends_ids = $client->friendsIds();
+ } catch (OAuthCurlException $e) {
+ common_log(LOG_WARNING, $this->name() .
+ ' - cURL error getting friend ids ' .
+ $e->getCode() . ' - ' . $e->getMessage());
+ return $friends;
+ }
+
+ if (empty($friends_ids)) {
+ common_debug($this->name() .
+ " - Twitter user $flink->foreign_id " .
+ 'doesn\'t have any friends!');
+ return $friends;
+ }
+
+ common_debug($this->name() . ' - Twitter\'s API says Twitter user id ' .
+ "$flink->foreign_id has " .
+ count($friends_ids) . ' friends.');
+
+ // Calculate how many pages to get...
+ $pages = ceil(count($friends_ids) / 100);
+
+ if ($pages == 0) {
+ common_debug($this->name() . " - $user seems to have no friends.");
+ }
+
+ for ($i = 1; $i <= $pages; $i++) {
+
+ try {
+ $more_friends = $client->statusesFriends(null, null, null, $i);
+ } catch (OAuthCurlException $e) {
+ common_log(LOG_WARNING, $this->name() .
+ ' - cURL error getting Twitter statuses/friends ' .
+ "page $i - " . $e->getCode() . ' - ' .
+ $e->getMessage());
+ }
+
+ if (empty($more_friends)) {
+ common_log(LOG_WARNING, $this->name() .
+ " - Couldn't retrieve page $i " .
+ "of Twitter user $flink->foreign_id friends.");
+ continue;
+ } else {
+ $friends = array_merge($friends, $more_friends);
+ }
+ }
+
+ return $friends;
+ }
+
+ function subscribeTwitterFriends($flink)
+ {
+ $friends = $this->fetchTwitterFriends($flink);
+
+ if (empty($friends)) {
+ common_debug($this->name() .
+ ' - Couldn\'t get friends from Twitter for ' .
+ "Twitter user $flink->foreign_id.");
+ return false;
+ }
+
+ $user = $flink->getUser();
+
+ foreach ($friends as $friend) {
+
+ $friend_name = $friend->screen_name;
+ $friend_id = (int) $friend->id;
+
+ // Update or create the Foreign_user record for each
+ // Twitter friend
+
+ if (!save_twitter_user($friend_id, $friend_name)) {
+ common_log(LOG_WARNING, $this-name() .
+ " - Couldn't save $screen_name's friend, $friend_name.");
+ continue;
+ }
+
+ // Check to see if there's a related local user
+
+ $friend_flink = Foreign_link::getByForeignID($friend_id,
+ TWITTER_SERVICE);
+
+ if (!empty($friend_flink)) {
+
+ // Get associated user and subscribe her
+
+ $friend_user = User::staticGet('id', $friend_flink->user_id);
+
+ if (!empty($friend_user)) {
+ $result = subs_subscribe_to($user, $friend_user);
+
+ if ($result === true) {
+ common_log(LOG_INFO,
+ $this->name() . ' - Subscribed ' .
+ "$friend_user->nickname to $user->nickname.");
+ } else {
+ common_debug($this->name() .
+ ' - Tried subscribing ' .
+ "$friend_user->nickname to $user->nickname - " .
+ $result);
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+}
+
+$id = null;
+$debug = null;
+
+if (have_option('i')) {
+ $id = get_option_value('i');
+} else if (have_option('--id')) {
+ $id = get_option_value('--id');
+} else if (count($args) > 0) {
+ $id = $args[0];
+} else {
+ $id = null;
+}
+
+if (have_option('d') || have_option('debug')) {
+ $debug = true;
+}
+
+$syncer = new SyncTwitterFriendsDaemon($id, 60, 2, $debug);
+$syncer->runOnce();
+
diff --git a/plugins/TwitterBridge/daemons/twitterqueuehandler.php b/plugins/TwitterBridge/daemons/twitterqueuehandler.php
new file mode 100755
index 000000000..9aa9d1ed0
--- /dev/null
+++ b/plugins/TwitterBridge/daemons/twitterqueuehandler.php
@@ -0,0 +1,73 @@
+#!/usr/bin/env php
+.
+ */
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
+
+$shortoptions = 'i::';
+$longoptions = array('id::');
+
+$helptext = <<log(LOG_INFO, "INITIALIZE");
+ return true;
+ }
+
+ function handle_notice($notice)
+ {
+ return broadcast_twitter($notice);
+ }
+
+ function finish()
+ {
+ }
+
+}
+
+if (have_option('i')) {
+ $id = get_option_value('i');
+} else if (have_option('--id')) {
+ $id = get_option_value('--id');
+} else if (count($args) > 0) {
+ $id = $args[0];
+} else {
+ $id = null;
+}
+
+$handler = new TwitterQueueHandler($id);
+
+$handler->runOnce();
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
new file mode 100755
index 000000000..3023bf423
--- /dev/null
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -0,0 +1,559 @@
+#!/usr/bin/env php
+.
+ */
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
+
+// Tune number of processes and how often to poll Twitter
+// XXX: Should these things be in config.php?
+define('MAXCHILDREN', 2);
+define('POLL_INTERVAL', 60); // in seconds
+
+$shortoptions = 'di::';
+$longoptions = array('id::', 'debug');
+
+$helptext = <<
+ * @author Evan Prodromou
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://laconi.ca/
+ */
+
+// NOTE: an Avatar path MUST be set in config.php for this
+// script to work: e.g.: $config['avatar']['path'] = '/laconica/avatar';
+
+class TwitterStatusFetcher extends ParallelizingDaemon
+{
+ /**
+ * Constructor
+ *
+ * @param string $id the name/id of this daemon
+ * @param int $interval sleep this long before doing everything again
+ * @param int $max_children maximum number of child processes at a time
+ * @param boolean $debug debug output flag
+ *
+ * @return void
+ *
+ **/
+ function __construct($id = null, $interval = 60,
+ $max_children = 2, $debug = null)
+ {
+ parent::__construct($id, $interval, $max_children, $debug);
+ }
+
+ /**
+ * Name of this daemon
+ *
+ * @return string Name of the daemon.
+ */
+
+ function name()
+ {
+ return ('twitterstatusfetcher.'.$this->_id);
+ }
+
+ /**
+ * Find all the Twitter foreign links for users who have requested
+ * importing of their friends' timelines
+ *
+ * @return array flinks an array of Foreign_link objects
+ */
+
+ function getObjects()
+ {
+ global $_DB_DATAOBJECT;
+
+ $flink = new Foreign_link();
+ $conn = &$flink->getDatabaseConnection();
+
+ $flink->service = TWITTER_SERVICE;
+ $flink->orderBy('last_noticesync');
+ $flink->find();
+
+ $flinks = array();
+
+ while ($flink->fetch()) {
+
+ if (($flink->noticesync & FOREIGN_NOTICE_RECV) ==
+ FOREIGN_NOTICE_RECV) {
+ $flinks[] = clone($flink);
+ }
+ }
+
+ $flink->free();
+ unset($flink);
+
+ $conn->disconnect();
+ unset($_DB_DATAOBJECT['CONNECTIONS']);
+
+ return $flinks;
+ }
+
+ function childTask($flink) {
+
+ // Each child ps needs its own DB connection
+
+ // Note: DataObject::getDatabaseConnection() creates
+ // a new connection if there isn't one already
+
+ $conn = &$flink->getDatabaseConnection();
+
+ $this->getTimeline($flink);
+
+ $flink->last_friendsync = common_sql_now();
+ $flink->update();
+
+ $conn->disconnect();
+
+ // XXX: Couldn't find a less brutal way to blow
+ // away a cached connection
+
+ global $_DB_DATAOBJECT;
+ unset($_DB_DATAOBJECT['CONNECTIONS']);
+ }
+
+ function getTimeline($flink)
+ {
+ if (empty($flink)) {
+ common_log(LOG_WARNING, $this->name() .
+ " - Can't retrieve Foreign_link for foreign ID $fid");
+ return;
+ }
+
+ common_debug($this->name() . ' - Trying to get timeline for Twitter user ' .
+ $flink->foreign_id);
+
+ // XXX: Biggest remaining issue - How do we know at which status
+ // to start importing? How many statuses? Right now I'm going
+ // with the default last 20.
+
+ $token = TwitterOAuthClient::unpackToken($flink->credentials);
+
+ $client = new TwitterOAuthClient($token->key, $token->secret);
+
+ $timeline = null;
+
+ try {
+ $timeline = $client->statusesFriendsTimeline();
+ } catch (OAuthClientCurlException $e) {
+ common_log(LOG_WARNING, $this->name() .
+ ' - OAuth client unable to get friends timeline for user ' .
+ $flink->user_id . ' - code: ' .
+ $e->getCode() . 'msg: ' . $e->getMessage());
+ }
+
+ if (empty($timeline)) {
+ common_log(LOG_WARNING, $this->name() . " - Empty timeline.");
+ return;
+ }
+
+ // Reverse to preserve order
+
+ foreach (array_reverse($timeline) as $status) {
+
+ // Hacktastic: filter out stuff coming from this Laconica
+
+ $source = mb_strtolower(common_config('integration', 'source'));
+
+ if (preg_match("/$source/", mb_strtolower($status->source))) {
+ common_debug($this->name() . ' - Skipping import of status ' .
+ $status->id . ' with source ' . $source);
+ continue;
+ }
+
+ $this->saveStatus($status, $flink);
+ }
+
+ // Okay, record the time we synced with Twitter for posterity
+
+ $flink->last_noticesync = common_sql_now();
+ $flink->update();
+ }
+
+ function saveStatus($status, $flink)
+ {
+ $id = $this->ensureProfile($status->user);
+
+ $profile = Profile::staticGet($id);
+
+ if (empty($profile)) {
+ common_log(LOG_ERR, $this->name() .
+ ' - Problem saving notice. No associated Profile.');
+ return null;
+ }
+
+ // XXX: change of screen name?
+
+ $uri = 'http://twitter.com/' . $status->user->screen_name .
+ '/status/' . $status->id;
+
+ $notice = Notice::staticGet('uri', $uri);
+
+ // check to see if we've already imported the status
+
+ if (empty($notice)) {
+
+ $notice = new Notice();
+
+ $notice->profile_id = $id;
+ $notice->uri = $uri;
+ $notice->created = strftime('%Y-%m-%d %H:%M:%S',
+ strtotime($status->created_at));
+ $notice->content = common_shorten_links($status->text); // XXX
+ $notice->rendered = common_render_content($notice->content, $notice);
+ $notice->source = 'twitter';
+ $notice->reply_to = null; // XXX: lookup reply
+ $notice->is_local = Notice::GATEWAY;
+
+ if (Event::handle('StartNoticeSave', array(&$notice))) {
+ $id = $notice->insert();
+ Event::handle('EndNoticeSave', array($notice));
+ }
+ }
+
+ if (!Notice_inbox::pkeyGet(array('notice_id' => $notice->id,
+ 'user_id' => $flink->user_id))) {
+ // Add to inbox
+ $inbox = new Notice_inbox();
+
+ $inbox->user_id = $flink->user_id;
+ $inbox->notice_id = $notice->id;
+ $inbox->created = $notice->created;
+ $inbox->source = NOTICE_INBOX_SOURCE_GATEWAY; // From a private source
+
+ $inbox->insert();
+ }
+ }
+
+ function ensureProfile($user)
+ {
+ // check to see if there's already a profile for this user
+
+ $profileurl = 'http://twitter.com/' . $user->screen_name;
+ $profile = Profile::staticGet('profileurl', $profileurl);
+
+ if (!empty($profile)) {
+ common_debug($this->name() .
+ " - Profile for $profile->nickname found.");
+
+ // Check to see if the user's Avatar has changed
+
+ $this->checkAvatar($user, $profile);
+ return $profile->id;
+
+ } else {
+ common_debug($this->name() . ' - Adding profile and remote profile ' .
+ "for Twitter user: $profileurl.");
+
+ $profile = new Profile();
+ $profile->query("BEGIN");
+
+ $profile->nickname = $user->screen_name;
+ $profile->fullname = $user->name;
+ $profile->homepage = $user->url;
+ $profile->bio = $user->description;
+ $profile->location = $user->location;
+ $profile->profileurl = $profileurl;
+ $profile->created = common_sql_now();
+
+ $id = $profile->insert();
+
+ if (empty($id)) {
+ common_log_db_error($profile, 'INSERT', __FILE__);
+ $profile->query("ROLLBACK");
+ return false;
+ }
+
+ // check for remote profile
+
+ $remote_pro = Remote_profile::staticGet('uri', $profileurl);
+
+ if (empty($remote_pro)) {
+
+ $remote_pro = new Remote_profile();
+
+ $remote_pro->id = $id;
+ $remote_pro->uri = $profileurl;
+ $remote_pro->created = common_sql_now();
+
+ $rid = $remote_pro->insert();
+
+ if (empty($rid)) {
+ common_log_db_error($profile, 'INSERT', __FILE__);
+ $profile->query("ROLLBACK");
+ return false;
+ }
+ }
+
+ $profile->query("COMMIT");
+
+ $this->saveAvatars($user, $id);
+
+ return $id;
+ }
+ }
+
+ function checkAvatar($twitter_user, $profile)
+ {
+ global $config;
+
+ $path_parts = pathinfo($twitter_user->profile_image_url);
+
+ $newname = 'Twitter_' . $twitter_user->id . '_' .
+ $path_parts['basename'];
+
+ $oldname = $profile->getAvatar(48)->filename;
+
+ if ($newname != $oldname) {
+ common_debug($this->name() . ' - Avatar for Twitter user ' .
+ "$profile->nickname has changed.");
+ common_debug($this->name() . " - old: $oldname new: $newname");
+
+ $this->updateAvatars($twitter_user, $profile);
+ }
+
+ if ($this->missingAvatarFile($profile)) {
+ common_debug($this->name() . ' - Twitter user ' .
+ $profile->nickname .
+ ' is missing one or more local avatars.');
+ common_debug($this->name() ." - old: $oldname new: $newname");
+
+ $this->updateAvatars($twitter_user, $profile);
+ }
+
+ }
+
+ function updateAvatars($twitter_user, $profile) {
+
+ global $config;
+
+ $path_parts = pathinfo($twitter_user->profile_image_url);
+
+ $img_root = substr($path_parts['basename'], 0, -11);
+ $ext = $path_parts['extension'];
+ $mediatype = $this->getMediatype($ext);
+
+ foreach (array('mini', 'normal', 'bigger') as $size) {
+ $url = $path_parts['dirname'] . '/' .
+ $img_root . '_' . $size . ".$ext";
+ $filename = 'Twitter_' . $twitter_user->id . '_' .
+ $img_root . "_$size.$ext";
+
+ $this->updateAvatar($profile->id, $size, $mediatype, $filename);
+ $this->fetchAvatar($url, $filename);
+ }
+ }
+
+ function missingAvatarFile($profile) {
+
+ foreach (array(24, 48, 73) as $size) {
+
+ $filename = $profile->getAvatar($size)->filename;
+ $avatarpath = Avatar::path($filename);
+
+ if (file_exists($avatarpath) == FALSE) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function getMediatype($ext)
+ {
+ $mediatype = null;
+
+ switch (strtolower($ext)) {
+ case 'jpg':
+ $mediatype = 'image/jpg';
+ break;
+ case 'gif':
+ $mediatype = 'image/gif';
+ break;
+ default:
+ $mediatype = 'image/png';
+ }
+
+ return $mediatype;
+ }
+
+ function saveAvatars($user, $id)
+ {
+ global $config;
+
+ $path_parts = pathinfo($user->profile_image_url);
+ $ext = $path_parts['extension'];
+ $end = strlen('_normal' . $ext);
+ $img_root = substr($path_parts['basename'], 0, -($end+1));
+ $mediatype = $this->getMediatype($ext);
+
+ foreach (array('mini', 'normal', 'bigger') as $size) {
+ $url = $path_parts['dirname'] . '/' .
+ $img_root . '_' . $size . ".$ext";
+ $filename = 'Twitter_' . $user->id . '_' .
+ $img_root . "_$size.$ext";
+
+ if ($this->fetchAvatar($url, $filename)) {
+ $this->newAvatar($id, $size, $mediatype, $filename);
+ } else {
+ common_log(LOG_WARNING, $this->id() .
+ " - Problem fetching Avatar: $url");
+ }
+ }
+ }
+
+ function updateAvatar($profile_id, $size, $mediatype, $filename) {
+
+ common_debug($this->name() . " - Updating avatar: $size");
+
+ $profile = Profile::staticGet($profile_id);
+
+ if (empty($profile)) {
+ common_debug($this->name() . " - Couldn't get profile: $profile_id!");
+ return;
+ }
+
+ $sizes = array('mini' => 24, 'normal' => 48, 'bigger' => 73);
+ $avatar = $profile->getAvatar($sizes[$size]);
+
+ // Delete the avatar, if present
+
+ if ($avatar) {
+ $avatar->delete();
+ }
+
+ $this->newAvatar($profile->id, $size, $mediatype, $filename);
+ }
+
+ function newAvatar($profile_id, $size, $mediatype, $filename)
+ {
+ global $config;
+
+ $avatar = new Avatar();
+ $avatar->profile_id = $profile_id;
+
+ switch($size) {
+ case 'mini':
+ $avatar->width = 24;
+ $avatar->height = 24;
+ break;
+ case 'normal':
+ $avatar->width = 48;
+ $avatar->height = 48;
+ break;
+ default:
+
+ // Note: Twitter's big avatars are a different size than
+ // Laconica's (Laconica's = 96)
+
+ $avatar->width = 73;
+ $avatar->height = 73;
+ }
+
+ $avatar->original = 0; // we don't have the original
+ $avatar->mediatype = $mediatype;
+ $avatar->filename = $filename;
+ $avatar->url = Avatar::url($filename);
+
+ common_debug($this->name() . " - New filename: $avatar->url");
+
+ $avatar->created = common_sql_now();
+
+ $id = $avatar->insert();
+
+ if (empty($id)) {
+ common_log_db_error($avatar, 'INSERT', __FILE__);
+ return null;
+ }
+
+ common_debug($this->name() .
+ " - Saved new $size avatar for $profile_id.");
+
+ return $id;
+ }
+
+ function fetchAvatar($url, $filename)
+ {
+ $avatar_dir = INSTALLDIR . '/avatar/';
+
+ $avatarfile = $avatar_dir . $filename;
+
+ $out = fopen($avatarfile, 'wb');
+ if (!$out) {
+ common_log(LOG_WARNING, $this->name() .
+ " - Couldn't open file $filename");
+ return false;
+ }
+
+ common_debug($this->name() . " - Fetching Twitter avatar: $url");
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_FILE, $out);
+ curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
+ $result = curl_exec($ch);
+ curl_close($ch);
+
+ fclose($out);
+
+ return $result;
+ }
+}
+
+$id = null;
+$debug = null;
+
+if (have_option('i')) {
+ $id = get_option_value('i');
+} else if (have_option('--id')) {
+ $id = get_option_value('--id');
+} else if (count($args) > 0) {
+ $id = $args[0];
+} else {
+ $id = null;
+}
+
+if (have_option('d') || have_option('debug')) {
+ $debug = true;
+}
+
+$fetcher = new TwitterStatusFetcher($id, 60, 2, $debug);
+$fetcher->runOnce();
+
--
cgit v1.2.3-54-g00ecf
From 0fd8e758ade32204b452cc9fd40e071f0ec8c0f6 Mon Sep 17 00:00:00 2001
From: Zach Copley
Date: Wed, 14 Oct 2009 04:50:16 +0000
Subject: Make queuing and daemons work via events
---
classes/Avatar.php | 2 +-
plugins/TwitterBridge/TwitterBridgePlugin.php | 17 +++++++++++++++++
plugins/TwitterBridge/daemons/synctwitterfriends.php | 10 ++--------
plugins/TwitterBridge/daemons/twitterstatusfetcher.php | 9 ++++-----
plugins/TwitterBridge/twitter.php | 3 +++
scripts/getvaliddaemons.php | 9 ---------
6 files changed, 27 insertions(+), 23 deletions(-)
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/classes/Avatar.php b/classes/Avatar.php
index 5e8b315fe..64f105179 100644
--- a/classes/Avatar.php
+++ b/classes/Avatar.php
@@ -81,7 +81,7 @@ class Avatar extends Memcached_DataObject
if (empty($server)) {
$server = common_config('site', 'server');
}
-
+ common_debug('path = ' . $path);
// XXX: protocol
return 'http://'.$server.$path.$filename;
diff --git a/plugins/TwitterBridge/TwitterBridgePlugin.php b/plugins/TwitterBridge/TwitterBridgePlugin.php
index a8de1c664..69bec0651 100644
--- a/plugins/TwitterBridge/TwitterBridgePlugin.php
+++ b/plugins/TwitterBridge/TwitterBridgePlugin.php
@@ -97,5 +97,22 @@ class TwitterBridgePlugin extends Plugin
}
}
+ function onStartEnqueueNotice($notice, $transports)
+ {
+ array_push($transports, 'twitter');
+ return true;
+ }
+
+ function onGetValidDaemons($daemons)
+ {
+ array_push($daemons, INSTALLDIR . '/plugins/TwitterBridge/daemons/twitterqueuehandler.php');
+ array_push($daemons, INSTALLDIR . '/plugins/TwitterBridge/daemons/synctwitterfriends.php');
+
+ if (common_config('twitterbridge', 'enabled')) {
+ array_push($daemons, INSTALLDIR . '/plugins/TwitterBridge/daemons/twitterstatusfetcher.php');
+ }
+
+ return true;
+ }
}
\ No newline at end of file
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index 0668c6222..ed2bf48a2 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -33,6 +33,8 @@ END_OF_TRIM_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
require_once INSTALLDIR . '/lib/parallelizingdaemon.php';
require_once INSTALLDIR . '/plugins/TwitterBridge/twitter.php';
+require_once INSTALLDIR . '/plugins/TwitterBridge/twitterbasicauthclient.php';
+require_once INSTALLDIR . '/plugins/TwitterBridge/twitteroauthclient.php';
/**
* Daemon to sync local friends with Twitter friends
@@ -45,14 +47,6 @@ require_once INSTALLDIR . '/plugins/TwitterBridge/twitter.php';
* @link http://status.net/
*/
-$helptext = <<filename = $filename;
$avatar->url = Avatar::url($filename);
- common_debug($this->name() . " - New filename: $avatar->url");
-
$avatar->created = common_sql_now();
$id = $avatar->insert();
@@ -516,9 +517,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
function fetchAvatar($url, $filename)
{
- $avatar_dir = INSTALLDIR . '/avatar/';
-
- $avatarfile = $avatar_dir . $filename;
+ $avatarfile = Avatar::path($filename);
$out = fopen($avatarfile, 'wb');
if (!$out) {
diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php
index afc3f55ba..ac1f49c36 100644
--- a/plugins/TwitterBridge/twitter.php
+++ b/plugins/TwitterBridge/twitter.php
@@ -23,6 +23,9 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
define('TWITTER_SERVICE', 1); // Twitter is foreign_service ID 1
+require_once INSTALLDIR . '/plugins/TwitterBridge/twitterbasicauthclient.php';
+require_once INSTALLDIR . '/plugins/TwitterBridge/twitteroauthclient.php';
+
function updateTwitter_user($twitter_id, $screen_name)
{
$uri = 'http://twitter.com/' . $screen_name;
diff --git a/scripts/getvaliddaemons.php b/scripts/getvaliddaemons.php
index 6dd019712..7caea1bb7 100755
--- a/scripts/getvaliddaemons.php
+++ b/scripts/getvaliddaemons.php
@@ -49,15 +49,6 @@ if(common_config('xmpp','enabled')) {
$daemons[] = INSTALLDIR.'/scripts/xmppconfirmhandler.php';
}
-if(common_config('twitterbridge','enabled')) {
- $daemons[] = INSTALLDIR.'/scripts/twitterstatusfetcher.php';
-}
-
-if (common_config('twitter', 'enabled')) {
- $daemons[] = INSTALLDIR.'/scripts/twitterqueuehandler.php';
- $daemons[] = INSTALLDIR.'/scripts/synctwitterfriends.php';
-}
-
if (common_config('sms', 'enabled')) {
$daemons[] = INSTALLDIR.'/scripts/smsqueuehandler.php';
}
--
cgit v1.2.3-54-g00ecf
From fa37967858c3c29000797e510e5f98aca8ab558f Mon Sep 17 00:00:00 2001
From: Brion Vibber
Date: Wed, 28 Oct 2009 15:29:20 -0400
Subject: Rebuilt HTTPClient class as an extension of PEAR HTTP_Request2
package, adding redirect handling and convenience functions. Caching support
will be added in future work after unit tests have been added.
* extlib: add PEAR HTTP_Request2 0.4.1 alpha
* extlib: update PEAR Net_URL2 to 0.3.0 beta for HTTP_Request2 compatibility
* moved direct usage of CURL and file_get_contents to HTTPClient class, excluding external-sourced libraries
Note some plugins haven't been tested yet.
---
classes/File_redirection.php | 68 +-
extlib/HTTP/Request2.php | 844 ++++++++++++++++++
extlib/HTTP/Request2/Adapter.php | 152 ++++
extlib/HTTP/Request2/Adapter/Curl.php | 383 ++++++++
extlib/HTTP/Request2/Adapter/Mock.php | 171 ++++
extlib/HTTP/Request2/Adapter/Socket.php | 971 +++++++++++++++++++++
extlib/HTTP/Request2/Exception.php | 62 ++
extlib/HTTP/Request2/MultipartBody.php | 274 ++++++
extlib/HTTP/Request2/Observer/Log.php | 215 +++++
extlib/HTTP/Request2/Response.php | 549 ++++++++++++
extlib/Net/URL2.php | 471 ++++++----
install.php | 7 +
lib/Shorturl_api.php | 23 +-
lib/curlclient.php | 179 ----
lib/default.php | 2 -
lib/httpclient.php | 180 +++-
lib/oauthclient.php | 65 +-
lib/ping.php | 14 +-
lib/snapshot.php | 21 +-
plugins/BlogspamNetPlugin.php | 17 +-
plugins/LinkbackPlugin.php | 36 +-
plugins/SimpleUrl/SimpleUrlPlugin.php | 11 +-
.../TwitterBridge/daemons/synctwitterfriends.php | 4 +-
.../TwitterBridge/daemons/twitterstatusfetcher.php | 45 +-
plugins/TwitterBridge/twitter.php | 2 +-
plugins/TwitterBridge/twitterauthorization.php | 2 +-
plugins/TwitterBridge/twitterbasicauthclient.php | 66 +-
plugins/WikiHashtagsPlugin.php | 12 +-
scripts/enjitqueuehandler.php | 64 +-
29 files changed, 4241 insertions(+), 669 deletions(-)
create mode 100644 extlib/HTTP/Request2.php
create mode 100644 extlib/HTTP/Request2/Adapter.php
create mode 100644 extlib/HTTP/Request2/Adapter/Curl.php
create mode 100644 extlib/HTTP/Request2/Adapter/Mock.php
create mode 100644 extlib/HTTP/Request2/Adapter/Socket.php
create mode 100644 extlib/HTTP/Request2/Exception.php
create mode 100644 extlib/HTTP/Request2/MultipartBody.php
create mode 100644 extlib/HTTP/Request2/Observer/Log.php
create mode 100644 extlib/HTTP/Request2/Response.php
delete mode 100644 lib/curlclient.php
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/classes/File_redirection.php b/classes/File_redirection.php
index 79052bf7d..b7945699a 100644
--- a/classes/File_redirection.php
+++ b/classes/File_redirection.php
@@ -47,18 +47,15 @@ class File_redirection extends Memcached_DataObject
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
- function _commonCurl($url, $redirs) {
- $curlh = curl_init();
- curl_setopt($curlh, CURLOPT_URL, $url);
- curl_setopt($curlh, CURLOPT_AUTOREFERER, true); // # setup referer header when folowing redirects
- curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 10); // # seconds to wait
- curl_setopt($curlh, CURLOPT_MAXREDIRS, $redirs); // # max number of http redirections to follow
- curl_setopt($curlh, CURLOPT_USERAGENT, USER_AGENT);
- curl_setopt($curlh, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
- curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curlh, CURLOPT_FILETIME, true);
- curl_setopt($curlh, CURLOPT_HEADER, true); // Include header in output
- return $curlh;
+ static function _commonHttp($url, $redirs) {
+ $request = new HTTPClient($url);
+ $request->setConfig(array(
+ 'connect_timeout' => 10, // # seconds to wait
+ 'max_redirs' => $redirs, // # max number of http redirections to follow
+ 'follow_redirects' => true, // Follow redirects
+ 'store_body' => false, // We won't need body content here.
+ ));
+ return $request;
}
function _redirectWhere_imp($short_url, $redirs = 10, $protected = false) {
@@ -82,32 +79,39 @@ class File_redirection extends Memcached_DataObject
if(strpos($short_url,'://') === false){
return $short_url;
}
- $curlh = File_redirection::_commonCurl($short_url, $redirs);
- // Don't include body in output
- curl_setopt($curlh, CURLOPT_NOBODY, true);
- curl_exec($curlh);
- $info = curl_getinfo($curlh);
- curl_close($curlh);
-
- if (405 == $info['http_code']) {
- $curlh = File_redirection::_commonCurl($short_url, $redirs);
- curl_exec($curlh);
- $info = curl_getinfo($curlh);
- curl_close($curlh);
+ try {
+ $request = self::_commonHttp($short_url, $redirs);
+ // Don't include body in output
+ $request->setMethod(HTTP_Request2::METHOD_HEAD);
+ $response = $request->send();
+
+ if (405 == $response->getCode()) {
+ // Server doesn't support HEAD method? Can this really happen?
+ // We'll try again as a GET and ignore the response data.
+ $request = self::_commonHttp($short_url, $redirs);
+ $response = $request->send();
+ }
+ } catch (Exception $e) {
+ // Invalid URL or failure to reach server
+ return $short_url;
}
- if (!empty($info['redirect_count']) && File::isProtected($info['url'])) {
- return File_redirection::_redirectWhere_imp($short_url, $info['redirect_count'] - 1, true);
+ if ($response->getRedirectCount() && File::isProtected($response->getUrl())) {
+ // Bump back up the redirect chain until we find a non-protected URL
+ return self::_redirectWhere_imp($short_url, $response->getRedirectCount() - 1, true);
}
- $ret = array('code' => $info['http_code']
- , 'redirects' => $info['redirect_count']
- , 'url' => $info['url']);
+ $ret = array('code' => $response->getCode()
+ , 'redirects' => $response->getRedirectCount()
+ , 'url' => $response->getUrl());
- if (!empty($info['content_type'])) $ret['type'] = $info['content_type'];
+ $type = $response->getHeader('Content-Type');
+ if ($type) $ret['type'] = $type;
if ($protected) $ret['protected'] = true;
- if (!empty($info['download_content_length'])) $ret['size'] = $info['download_content_length'];
- if (isset($info['filetime']) && ($info['filetime'] > 0)) $ret['time'] = $info['filetime'];
+ $size = $request->getHeader('Content-Length'); // @fixme bytes?
+ if ($size) $ret['size'] = $size;
+ $time = $request->getHeader('Last-Modified');
+ if ($time) $ret['time'] = strtotime($time);
return $ret;
}
diff --git a/extlib/HTTP/Request2.php b/extlib/HTTP/Request2.php
new file mode 100644
index 000000000..e06bb86bc
--- /dev/null
+++ b/extlib/HTTP/Request2.php
@@ -0,0 +1,844 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Request2.php 278226 2009-04-03 21:32:48Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * A class representing an URL as per RFC 3986.
+ */
+require_once 'Net/URL2.php';
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * Class representing a HTTP request
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ * @link http://tools.ietf.org/html/rfc2616#section-5
+ */
+class HTTP_Request2 implements SplSubject
+{
+ /**#@+
+ * Constants for HTTP request methods
+ *
+ * @link http://tools.ietf.org/html/rfc2616#section-5.1.1
+ */
+ const METHOD_OPTIONS = 'OPTIONS';
+ const METHOD_GET = 'GET';
+ const METHOD_HEAD = 'HEAD';
+ const METHOD_POST = 'POST';
+ const METHOD_PUT = 'PUT';
+ const METHOD_DELETE = 'DELETE';
+ const METHOD_TRACE = 'TRACE';
+ const METHOD_CONNECT = 'CONNECT';
+ /**#@-*/
+
+ /**#@+
+ * Constants for HTTP authentication schemes
+ *
+ * @link http://tools.ietf.org/html/rfc2617
+ */
+ const AUTH_BASIC = 'basic';
+ const AUTH_DIGEST = 'digest';
+ /**#@-*/
+
+ /**
+ * Regular expression used to check for invalid symbols in RFC 2616 tokens
+ * @link http://pear.php.net/bugs/bug.php?id=15630
+ */
+ const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!';
+
+ /**
+ * Regular expression used to check for invalid symbols in cookie strings
+ * @link http://pear.php.net/bugs/bug.php?id=15630
+ * @link http://cgi.netscape.com/newsref/std/cookie_spec.html
+ */
+ const REGEXP_INVALID_COOKIE = '/[\s,;]/';
+
+ /**
+ * Fileinfo magic database resource
+ * @var resource
+ * @see detectMimeType()
+ */
+ private static $_fileinfoDb;
+
+ /**
+ * Observers attached to the request (instances of SplObserver)
+ * @var array
+ */
+ protected $observers = array();
+
+ /**
+ * Request URL
+ * @var Net_URL2
+ */
+ protected $url;
+
+ /**
+ * Request method
+ * @var string
+ */
+ protected $method = self::METHOD_GET;
+
+ /**
+ * Authentication data
+ * @var array
+ * @see getAuth()
+ */
+ protected $auth;
+
+ /**
+ * Request headers
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * Configuration parameters
+ * @var array
+ * @see setConfig()
+ */
+ protected $config = array(
+ 'adapter' => 'HTTP_Request2_Adapter_Socket',
+ 'connect_timeout' => 10,
+ 'timeout' => 0,
+ 'use_brackets' => true,
+ 'protocol_version' => '1.1',
+ 'buffer_size' => 16384,
+ 'store_body' => true,
+
+ 'proxy_host' => '',
+ 'proxy_port' => '',
+ 'proxy_user' => '',
+ 'proxy_password' => '',
+ 'proxy_auth_scheme' => self::AUTH_BASIC,
+
+ 'ssl_verify_peer' => true,
+ 'ssl_verify_host' => true,
+ 'ssl_cafile' => null,
+ 'ssl_capath' => null,
+ 'ssl_local_cert' => null,
+ 'ssl_passphrase' => null,
+
+ 'digest_compat_ie' => false
+ );
+
+ /**
+ * Last event in request / response handling, intended for observers
+ * @var array
+ * @see getLastEvent()
+ */
+ protected $lastEvent = array(
+ 'name' => 'start',
+ 'data' => null
+ );
+
+ /**
+ * Request body
+ * @var string|resource
+ * @see setBody()
+ */
+ protected $body = '';
+
+ /**
+ * Array of POST parameters
+ * @var array
+ */
+ protected $postParams = array();
+
+ /**
+ * Array of file uploads (for multipart/form-data POST requests)
+ * @var array
+ */
+ protected $uploads = array();
+
+ /**
+ * Adapter used to perform actual HTTP request
+ * @var HTTP_Request2_Adapter
+ */
+ protected $adapter;
+
+
+ /**
+ * Constructor. Can set request URL, method and configuration array.
+ *
+ * Also sets a default value for User-Agent header.
+ *
+ * @param string|Net_Url2 Request URL
+ * @param string Request method
+ * @param array Configuration for this Request instance
+ */
+ public function __construct($url = null, $method = self::METHOD_GET, array $config = array())
+ {
+ if (!empty($url)) {
+ $this->setUrl($url);
+ }
+ if (!empty($method)) {
+ $this->setMethod($method);
+ }
+ $this->setConfig($config);
+ $this->setHeader('user-agent', 'HTTP_Request2/0.4.1 ' .
+ '(http://pear.php.net/package/http_request2) ' .
+ 'PHP/' . phpversion());
+ }
+
+ /**
+ * Sets the URL for this request
+ *
+ * If the URL has userinfo part (username & password) these will be removed
+ * and converted to auth data. If the URL does not have a path component,
+ * that will be set to '/'.
+ *
+ * @param string|Net_URL2 Request URL
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setUrl($url)
+ {
+ if (is_string($url)) {
+ $url = new Net_URL2($url);
+ }
+ if (!$url instanceof Net_URL2) {
+ throw new HTTP_Request2_Exception('Parameter is not a valid HTTP URL');
+ }
+ // URL contains username / password?
+ if ($url->getUserinfo()) {
+ $username = $url->getUser();
+ $password = $url->getPassword();
+ $this->setAuth(rawurldecode($username), $password? rawurldecode($password): '');
+ $url->setUserinfo('');
+ }
+ if ('' == $url->getPath()) {
+ $url->setPath('/');
+ }
+ $this->url = $url;
+
+ return $this;
+ }
+
+ /**
+ * Returns the request URL
+ *
+ * @return Net_URL2
+ */
+ public function getUrl()
+ {
+ return $this->url;
+ }
+
+ /**
+ * Sets the request method
+ *
+ * @param string
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception if the method name is invalid
+ */
+ public function setMethod($method)
+ {
+ // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1
+ if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) {
+ throw new HTTP_Request2_Exception("Invalid request method '{$method}'");
+ }
+ $this->method = $method;
+
+ return $this;
+ }
+
+ /**
+ * Returns the request method
+ *
+ * @return string
+ */
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ /**
+ * Sets the configuration parameter(s)
+ *
+ * The following parameters are available:
+ *
+ * - 'adapter' - adapter to use (string)
+ * - 'connect_timeout' - Connection timeout in seconds (integer)
+ * - 'timeout' - Total number of seconds a request can take.
+ * Use 0 for no limit, should be greater than
+ * 'connect_timeout' if set (integer)
+ * - 'use_brackets' - Whether to append [] to array variable names (bool)
+ * - 'protocol_version' - HTTP Version to use, '1.0' or '1.1' (string)
+ * - 'buffer_size' - Buffer size to use for reading and writing (int)
+ * - 'store_body' - Whether to store response body in response object.
+ * Set to false if receiving a huge response and
+ * using an Observer to save it (boolean)
+ * - 'proxy_host' - Proxy server host (string)
+ * - 'proxy_port' - Proxy server port (integer)
+ * - 'proxy_user' - Proxy auth username (string)
+ * - 'proxy_password' - Proxy auth password (string)
+ * - 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)
+ * - 'ssl_verify_peer' - Whether to verify peer's SSL certificate (bool)
+ * - 'ssl_verify_host' - Whether to check that Common Name in SSL
+ * certificate matches host name (bool)
+ * - 'ssl_cafile' - Cerificate Authority file to verify the peer
+ * with (use with 'ssl_verify_peer') (string)
+ * - 'ssl_capath' - Directory holding multiple Certificate
+ * Authority files (string)
+ * - 'ssl_local_cert' - Name of a file containing local cerificate (string)
+ * - 'ssl_passphrase' - Passphrase with which local certificate
+ * was encoded (string)
+ * - 'digest_compat_ie' - Whether to imitate behaviour of MSIE 5 and 6
+ * in using URL without query string in digest
+ * authentication (boolean)
+ *
+ *
+ * @param string|array configuration parameter name or array
+ * ('parameter name' => 'parameter value')
+ * @param mixed parameter value if $nameOrConfig is not an array
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception If the parameter is unknown
+ */
+ public function setConfig($nameOrConfig, $value = null)
+ {
+ if (is_array($nameOrConfig)) {
+ foreach ($nameOrConfig as $name => $value) {
+ $this->setConfig($name, $value);
+ }
+
+ } else {
+ if (!array_key_exists($nameOrConfig, $this->config)) {
+ throw new HTTP_Request2_Exception(
+ "Unknown configuration parameter '{$nameOrConfig}'"
+ );
+ }
+ $this->config[$nameOrConfig] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the value(s) of the configuration parameter(s)
+ *
+ * @param string parameter name
+ * @return mixed value of $name parameter, array of all configuration
+ * parameters if $name is not given
+ * @throws HTTP_Request2_Exception If the parameter is unknown
+ */
+ public function getConfig($name = null)
+ {
+ if (null === $name) {
+ return $this->config;
+ } elseif (!array_key_exists($name, $this->config)) {
+ throw new HTTP_Request2_Exception(
+ "Unknown configuration parameter '{$name}'"
+ );
+ }
+ return $this->config[$name];
+ }
+
+ /**
+ * Sets the autentification data
+ *
+ * @param string user name
+ * @param string password
+ * @param string authentication scheme
+ * @return HTTP_Request2
+ */
+ public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC)
+ {
+ if (empty($user)) {
+ $this->auth = null;
+ } else {
+ $this->auth = array(
+ 'user' => (string)$user,
+ 'password' => (string)$password,
+ 'scheme' => $scheme
+ );
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the authentication data
+ *
+ * The array has the keys 'user', 'password' and 'scheme', where 'scheme'
+ * is one of the HTTP_Request2::AUTH_* constants.
+ *
+ * @return array
+ */
+ public function getAuth()
+ {
+ return $this->auth;
+ }
+
+ /**
+ * Sets request header(s)
+ *
+ * The first parameter may be either a full header string 'header: value' or
+ * header name. In the former case $value parameter is ignored, in the latter
+ * the header's value will either be set to $value or the header will be
+ * removed if $value is null. The first parameter can also be an array of
+ * headers, in that case method will be called recursively.
+ *
+ * Note that headers are treated case insensitively as per RFC 2616.
+ *
+ *
+ * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar'
+ * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz'
+ * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux'
+ * $req->setHeader('FOO'); // removes 'Foo' header from request
+ *
+ *
+ * @param string|array header name, header string ('Header: value')
+ * or an array of headers
+ * @param string|null header value, header will be removed if null
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setHeader($name, $value = null)
+ {
+ if (is_array($name)) {
+ foreach ($name as $k => $v) {
+ if (is_string($k)) {
+ $this->setHeader($k, $v);
+ } else {
+ $this->setHeader($v);
+ }
+ }
+ } else {
+ if (null === $value && strpos($name, ':')) {
+ list($name, $value) = array_map('trim', explode(':', $name, 2));
+ }
+ // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2
+ if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) {
+ throw new HTTP_Request2_Exception("Invalid header name '{$name}'");
+ }
+ // Header names are case insensitive anyway
+ $name = strtolower($name);
+ if (null === $value) {
+ unset($this->headers[$name]);
+ } else {
+ $this->headers[$name] = $value;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the request headers
+ *
+ * The array is of the form ('header name' => 'header value'), header names
+ * are lowercased
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * Appends a cookie to "Cookie:" header
+ *
+ * @param string cookie name
+ * @param string cookie value
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function addCookie($name, $value)
+ {
+ $cookie = $name . '=' . $value;
+ if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
+ throw new HTTP_Request2_Exception("Invalid cookie: '{$cookie}'");
+ }
+ $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
+ $this->setHeader('cookie', $cookies . $cookie);
+
+ return $this;
+ }
+
+ /**
+ * Sets the request body
+ *
+ * @param string Either a string with the body or filename containing body
+ * @param bool Whether first parameter is a filename
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setBody($body, $isFilename = false)
+ {
+ if (!$isFilename) {
+ $this->body = (string)$body;
+ } else {
+ if (!($fp = @fopen($body, 'rb'))) {
+ throw new HTTP_Request2_Exception("Cannot open file {$body}");
+ }
+ $this->body = $fp;
+ if (empty($this->headers['content-type'])) {
+ $this->setHeader('content-type', self::detectMimeType($body));
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the request body
+ *
+ * @return string|resource|HTTP_Request2_MultipartBody
+ */
+ public function getBody()
+ {
+ if (self::METHOD_POST == $this->method &&
+ (!empty($this->postParams) || !empty($this->uploads))
+ ) {
+ if ('application/x-www-form-urlencoded' == $this->headers['content-type']) {
+ $body = http_build_query($this->postParams, '', '&');
+ if (!$this->getConfig('use_brackets')) {
+ $body = preg_replace('/%5B\d+%5D=/', '=', $body);
+ }
+ // support RFC 3986 by not encoding '~' symbol (request #15368)
+ return str_replace('%7E', '~', $body);
+
+ } elseif ('multipart/form-data' == $this->headers['content-type']) {
+ require_once 'HTTP/Request2/MultipartBody.php';
+ return new HTTP_Request2_MultipartBody(
+ $this->postParams, $this->uploads, $this->getConfig('use_brackets')
+ );
+ }
+ }
+ return $this->body;
+ }
+
+ /**
+ * Adds a file to form-based file upload
+ *
+ * Used to emulate file upload via a HTML form. The method also sets
+ * Content-Type of HTTP request to 'multipart/form-data'.
+ *
+ * If you just want to send the contents of a file as the body of HTTP
+ * request you should use setBody() method.
+ *
+ * @param string name of file-upload field
+ * @param mixed full name of local file
+ * @param string filename to send in the request
+ * @param string content-type of file being uploaded
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function addUpload($fieldName, $filename, $sendFilename = null,
+ $contentType = null)
+ {
+ if (!is_array($filename)) {
+ if (!($fp = @fopen($filename, 'rb'))) {
+ throw new HTTP_Request2_Exception("Cannot open file {$filename}");
+ }
+ $this->uploads[$fieldName] = array(
+ 'fp' => $fp,
+ 'filename' => empty($sendFilename)? basename($filename): $sendFilename,
+ 'size' => filesize($filename),
+ 'type' => empty($contentType)? self::detectMimeType($filename): $contentType
+ );
+ } else {
+ $fps = $names = $sizes = $types = array();
+ foreach ($filename as $f) {
+ if (!is_array($f)) {
+ $f = array($f);
+ }
+ if (!($fp = @fopen($f[0], 'rb'))) {
+ throw new HTTP_Request2_Exception("Cannot open file {$f[0]}");
+ }
+ $fps[] = $fp;
+ $names[] = empty($f[1])? basename($f[0]): $f[1];
+ $sizes[] = filesize($f[0]);
+ $types[] = empty($f[2])? self::detectMimeType($f[0]): $f[2];
+ }
+ $this->uploads[$fieldName] = array(
+ 'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types
+ );
+ }
+ if (empty($this->headers['content-type']) ||
+ 'application/x-www-form-urlencoded' == $this->headers['content-type']
+ ) {
+ $this->setHeader('content-type', 'multipart/form-data');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds POST parameter(s) to the request.
+ *
+ * @param string|array parameter name or array ('name' => 'value')
+ * @param mixed parameter value (can be an array)
+ * @return HTTP_Request2
+ */
+ public function addPostParameter($name, $value = null)
+ {
+ if (!is_array($name)) {
+ $this->postParams[$name] = $value;
+ } else {
+ foreach ($name as $k => $v) {
+ $this->addPostParameter($k, $v);
+ }
+ }
+ if (empty($this->headers['content-type'])) {
+ $this->setHeader('content-type', 'application/x-www-form-urlencoded');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Attaches a new observer
+ *
+ * @param SplObserver
+ */
+ public function attach(SplObserver $observer)
+ {
+ foreach ($this->observers as $attached) {
+ if ($attached === $observer) {
+ return;
+ }
+ }
+ $this->observers[] = $observer;
+ }
+
+ /**
+ * Detaches an existing observer
+ *
+ * @param SplObserver
+ */
+ public function detach(SplObserver $observer)
+ {
+ foreach ($this->observers as $key => $attached) {
+ if ($attached === $observer) {
+ unset($this->observers[$key]);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Notifies all observers
+ */
+ public function notify()
+ {
+ foreach ($this->observers as $observer) {
+ $observer->update($this);
+ }
+ }
+
+ /**
+ * Sets the last event
+ *
+ * Adapters should use this method to set the current state of the request
+ * and notify the observers.
+ *
+ * @param string event name
+ * @param mixed event data
+ */
+ public function setLastEvent($name, $data = null)
+ {
+ $this->lastEvent = array(
+ 'name' => $name,
+ 'data' => $data
+ );
+ $this->notify();
+ }
+
+ /**
+ * Returns the last event
+ *
+ * Observers should use this method to access the last change in request.
+ * The following event names are possible:
+ *
+ * - 'connect' - after connection to remote server,
+ * data is the destination (string)
+ * - 'disconnect' - after disconnection from server
+ * - 'sentHeaders' - after sending the request headers,
+ * data is the headers sent (string)
+ * - 'sentBodyPart' - after sending a part of the request body,
+ * data is the length of that part (int)
+ * - 'receivedHeaders' - after receiving the response headers,
+ * data is HTTP_Request2_Response object
+ * - 'receivedBodyPart' - after receiving a part of the response
+ * body, data is that part (string)
+ * - 'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still
+ * encoded by Content-Encoding
+ * - 'receivedBody' - after receiving the complete response
+ * body, data is HTTP_Request2_Response object
+ *
+ * Different adapters may not send all the event types. Mock adapter does
+ * not send any events to the observers.
+ *
+ * @return array The array has two keys: 'name' and 'data'
+ */
+ public function getLastEvent()
+ {
+ return $this->lastEvent;
+ }
+
+ /**
+ * Sets the adapter used to actually perform the request
+ *
+ * You can pass either an instance of a class implementing HTTP_Request2_Adapter
+ * or a class name. The method will only try to include a file if the class
+ * name starts with HTTP_Request2_Adapter_, it will also try to prepend this
+ * prefix to the class name if it doesn't contain any underscores, so that
+ *
+ * $request->setAdapter('curl');
+ *
+ * will work.
+ *
+ * @param string|HTTP_Request2_Adapter
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setAdapter($adapter)
+ {
+ if (is_string($adapter)) {
+ if (!class_exists($adapter, false)) {
+ if (false === strpos($adapter, '_')) {
+ $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter);
+ }
+ if (preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter)) {
+ include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php';
+ }
+ if (!class_exists($adapter, false)) {
+ throw new HTTP_Request2_Exception("Class {$adapter} not found");
+ }
+ }
+ $adapter = new $adapter;
+ }
+ if (!$adapter instanceof HTTP_Request2_Adapter) {
+ throw new HTTP_Request2_Exception('Parameter is not a HTTP request adapter');
+ }
+ $this->adapter = $adapter;
+
+ return $this;
+ }
+
+ /**
+ * Sends the request and returns the response
+ *
+ * @throws HTTP_Request2_Exception
+ * @return HTTP_Request2_Response
+ */
+ public function send()
+ {
+ // Sanity check for URL
+ if (!$this->url instanceof Net_URL2) {
+ throw new HTTP_Request2_Exception('No URL given');
+ } elseif (!$this->url->isAbsolute()) {
+ throw new HTTP_Request2_Exception('Absolute URL required');
+ } elseif (!in_array(strtolower($this->url->getScheme()), array('https', 'http'))) {
+ throw new HTTP_Request2_Exception('Not a HTTP URL');
+ }
+ if (empty($this->adapter)) {
+ $this->setAdapter($this->getConfig('adapter'));
+ }
+ // magic_quotes_runtime may break file uploads and chunked response
+ // processing; see bug #4543
+ if ($magicQuotes = ini_get('magic_quotes_runtime')) {
+ ini_set('magic_quotes_runtime', false);
+ }
+ // force using single byte encoding if mbstring extension overloads
+ // strlen() and substr(); see bug #1781, bug #10605
+ if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
+ $oldEncoding = mb_internal_encoding();
+ mb_internal_encoding('iso-8859-1');
+ }
+
+ try {
+ $response = $this->adapter->sendRequest($this);
+ } catch (Exception $e) {
+ }
+ // cleanup in either case (poor man's "finally" clause)
+ if ($magicQuotes) {
+ ini_set('magic_quotes_runtime', true);
+ }
+ if (!empty($oldEncoding)) {
+ mb_internal_encoding($oldEncoding);
+ }
+ // rethrow the exception
+ if (!empty($e)) {
+ throw $e;
+ }
+ return $response;
+ }
+
+ /**
+ * Tries to detect MIME type of a file
+ *
+ * The method will try to use fileinfo extension if it is available,
+ * deprecated mime_content_type() function in the other case. If neither
+ * works, default 'application/octet-stream' MIME type is returned
+ *
+ * @param string filename
+ * @return string file MIME type
+ */
+ protected static function detectMimeType($filename)
+ {
+ // finfo extension from PECL available
+ if (function_exists('finfo_open')) {
+ if (!isset(self::$_fileinfoDb)) {
+ self::$_fileinfoDb = @finfo_open(FILEINFO_MIME);
+ }
+ if (self::$_fileinfoDb) {
+ $info = finfo_file(self::$_fileinfoDb, $filename);
+ }
+ }
+ // (deprecated) mime_content_type function available
+ if (empty($info) && function_exists('mime_content_type')) {
+ return mime_content_type($filename);
+ }
+ return empty($info)? 'application/octet-stream': $info;
+ }
+}
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Adapter.php b/extlib/HTTP/Request2/Adapter.php
new file mode 100644
index 000000000..39b092b34
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter.php
@@ -0,0 +1,152 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Adapter.php 274684 2009-01-26 23:07:27Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP response
+ */
+require_once 'HTTP/Request2/Response.php';
+
+/**
+ * Base class for HTTP_Request2 adapters
+ *
+ * HTTP_Request2 class itself only defines methods for aggregating the request
+ * data, all actual work of sending the request to the remote server and
+ * receiving its response is performed by adapters.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+abstract class HTTP_Request2_Adapter
+{
+ /**
+ * A list of methods that MUST NOT have a request body, per RFC 2616
+ * @var array
+ */
+ protected static $bodyDisallowed = array('TRACE');
+
+ /**
+ * Methods having defined semantics for request body
+ *
+ * Content-Length header (indicating that the body follows, section 4.3 of
+ * RFC 2616) will be sent for these methods even if no body was added
+ *
+ * @var array
+ * @link http://pear.php.net/bugs/bug.php?id=12900
+ * @link http://pear.php.net/bugs/bug.php?id=14740
+ */
+ protected static $bodyRequired = array('POST', 'PUT');
+
+ /**
+ * Request being sent
+ * @var HTTP_Request2
+ */
+ protected $request;
+
+ /**
+ * Request body
+ * @var string|resource|HTTP_Request2_MultipartBody
+ * @see HTTP_Request2::getBody()
+ */
+ protected $requestBody;
+
+ /**
+ * Length of the request body
+ * @var integer
+ */
+ protected $contentLength;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ abstract public function sendRequest(HTTP_Request2 $request);
+
+ /**
+ * Calculates length of the request body, adds proper headers
+ *
+ * @param array associative array of request headers, this method will
+ * add proper 'Content-Length' and 'Content-Type' headers
+ * to this array (or remove them if not needed)
+ */
+ protected function calculateRequestLength(&$headers)
+ {
+ $this->requestBody = $this->request->getBody();
+
+ if (is_string($this->requestBody)) {
+ $this->contentLength = strlen($this->requestBody);
+ } elseif (is_resource($this->requestBody)) {
+ $stat = fstat($this->requestBody);
+ $this->contentLength = $stat['size'];
+ rewind($this->requestBody);
+ } else {
+ $this->contentLength = $this->requestBody->getLength();
+ $headers['content-type'] = 'multipart/form-data; boundary=' .
+ $this->requestBody->getBoundary();
+ $this->requestBody->rewind();
+ }
+
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength
+ ) {
+ unset($headers['content-type']);
+ // No body: send a Content-Length header nonetheless (request #12900),
+ // but do that only for methods that require a body (bug #14740)
+ if (in_array($this->request->getMethod(), self::$bodyRequired)) {
+ $headers['content-length'] = 0;
+ } else {
+ unset($headers['content-length']);
+ }
+ } else {
+ if (empty($headers['content-type'])) {
+ $headers['content-type'] = 'application/x-www-form-urlencoded';
+ }
+ $headers['content-length'] = $this->contentLength;
+ }
+ }
+}
+?>
diff --git a/extlib/HTTP/Request2/Adapter/Curl.php b/extlib/HTTP/Request2/Adapter/Curl.php
new file mode 100644
index 000000000..4d4de0dcc
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter/Curl.php
@@ -0,0 +1,383 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Curl.php 278226 2009-04-03 21:32:48Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Adapter for HTTP_Request2 wrapping around cURL extension
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
+{
+ /**
+ * Mapping of header names to cURL options
+ * @var array
+ */
+ protected static $headerMap = array(
+ 'accept-encoding' => CURLOPT_ENCODING,
+ 'cookie' => CURLOPT_COOKIE,
+ 'referer' => CURLOPT_REFERER,
+ 'user-agent' => CURLOPT_USERAGENT
+ );
+
+ /**
+ * Mapping of SSL context options to cURL options
+ * @var array
+ */
+ protected static $sslContextMap = array(
+ 'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
+ 'ssl_cafile' => CURLOPT_CAINFO,
+ 'ssl_capath' => CURLOPT_CAPATH,
+ 'ssl_local_cert' => CURLOPT_SSLCERT,
+ 'ssl_passphrase' => CURLOPT_SSLCERTPASSWD
+ );
+
+ /**
+ * Response being received
+ * @var HTTP_Request2_Response
+ */
+ protected $response;
+
+ /**
+ * Whether 'sentHeaders' event was sent to observers
+ * @var boolean
+ */
+ protected $eventSentHeaders = false;
+
+ /**
+ * Whether 'receivedHeaders' event was sent to observers
+ * @var boolean
+ */
+ protected $eventReceivedHeaders = false;
+
+ /**
+ * Position within request body
+ * @var integer
+ * @see callbackReadBody()
+ */
+ protected $position = 0;
+
+ /**
+ * Information about last transfer, as returned by curl_getinfo()
+ * @var array
+ */
+ protected $lastInfo;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ if (!extension_loaded('curl')) {
+ throw new HTTP_Request2_Exception('cURL extension not available');
+ }
+
+ $this->request = $request;
+ $this->response = null;
+ $this->position = 0;
+ $this->eventSentHeaders = false;
+ $this->eventReceivedHeaders = false;
+
+ try {
+ if (false === curl_exec($ch = $this->createCurlHandle())) {
+ $errorMessage = 'Error sending request: #' . curl_errno($ch) .
+ ' ' . curl_error($ch);
+ }
+ } catch (Exception $e) {
+ }
+ $this->lastInfo = curl_getinfo($ch);
+ curl_close($ch);
+
+ if (!empty($e)) {
+ throw $e;
+ } elseif (!empty($errorMessage)) {
+ throw new HTTP_Request2_Exception($errorMessage);
+ }
+
+ if (0 < $this->lastInfo['size_download']) {
+ $this->request->setLastEvent('receivedBody', $this->response);
+ }
+ return $this->response;
+ }
+
+ /**
+ * Returns information about last transfer
+ *
+ * @return array associative array as returned by curl_getinfo()
+ */
+ public function getInfo()
+ {
+ return $this->lastInfo;
+ }
+
+ /**
+ * Creates a new cURL handle and populates it with data from the request
+ *
+ * @return resource a cURL handle, as created by curl_init()
+ * @throws HTTP_Request2_Exception
+ */
+ protected function createCurlHandle()
+ {
+ $ch = curl_init();
+
+ curl_setopt_array($ch, array(
+ // setup callbacks
+ CURLOPT_READFUNCTION => array($this, 'callbackReadBody'),
+ CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
+ CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'),
+ // disallow redirects
+ CURLOPT_FOLLOWLOCATION => false,
+ // buffer size
+ CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'),
+ // connection timeout
+ CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
+ // save full outgoing headers, in case someone is interested
+ CURLINFO_HEADER_OUT => true,
+ // request url
+ CURLOPT_URL => $this->request->getUrl()->getUrl()
+ ));
+
+ // request timeout
+ if ($timeout = $this->request->getConfig('timeout')) {
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ }
+
+ // set HTTP version
+ switch ($this->request->getConfig('protocol_version')) {
+ case '1.0':
+ curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ break;
+ case '1.1':
+ curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ }
+
+ // set request method
+ switch ($this->request->getMethod()) {
+ case HTTP_Request2::METHOD_GET:
+ curl_setopt($ch, CURLOPT_HTTPGET, true);
+ break;
+ case HTTP_Request2::METHOD_POST:
+ curl_setopt($ch, CURLOPT_POST, true);
+ break;
+ default:
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
+ }
+
+ // set proxy, if needed
+ if ($host = $this->request->getConfig('proxy_host')) {
+ if (!($port = $this->request->getConfig('proxy_port'))) {
+ throw new HTTP_Request2_Exception('Proxy port not provided');
+ }
+ curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
+ if ($user = $this->request->getConfig('proxy_user')) {
+ curl_setopt($ch, CURLOPT_PROXYUSERPWD, $user . ':' .
+ $this->request->getConfig('proxy_password'));
+ switch ($this->request->getConfig('proxy_auth_scheme')) {
+ case HTTP_Request2::AUTH_BASIC:
+ curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+ break;
+ case HTTP_Request2::AUTH_DIGEST:
+ curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
+ }
+ }
+ }
+
+ // set authentication data
+ if ($auth = $this->request->getAuth()) {
+ curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
+ switch ($auth['scheme']) {
+ case HTTP_Request2::AUTH_BASIC:
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ break;
+ case HTTP_Request2::AUTH_DIGEST:
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+ }
+ }
+
+ // set SSL options
+ if (0 == strcasecmp($this->request->getUrl()->getScheme(), 'https')) {
+ foreach ($this->request->getConfig() as $name => $value) {
+ if ('ssl_verify_host' == $name && null !== $value) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
+ } elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
+ curl_setopt($ch, self::$sslContextMap[$name], $value);
+ }
+ }
+ }
+
+ $headers = $this->request->getHeaders();
+ // make cURL automagically send proper header
+ if (!isset($headers['accept-encoding'])) {
+ $headers['accept-encoding'] = '';
+ }
+
+ // set headers having special cURL keys
+ foreach (self::$headerMap as $name => $option) {
+ if (isset($headers[$name])) {
+ curl_setopt($ch, $option, $headers[$name]);
+ unset($headers[$name]);
+ }
+ }
+
+ $this->calculateRequestLength($headers);
+
+ // set headers not having special keys
+ $headersFmt = array();
+ foreach ($headers as $name => $value) {
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $headersFmt[] = $canonicalName . ': ' . $value;
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
+
+ return $ch;
+ }
+
+ /**
+ * Callback function called by cURL for reading the request body
+ *
+ * @param resource cURL handle
+ * @param resource file descriptor (not used)
+ * @param integer maximum length of data to return
+ * @return string part of the request body, up to $length bytes
+ */
+ protected function callbackReadBody($ch, $fd, $length)
+ {
+ if (!$this->eventSentHeaders) {
+ $this->request->setLastEvent(
+ 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
+ );
+ $this->eventSentHeaders = true;
+ }
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength || $this->position >= $this->contentLength
+ ) {
+ return '';
+ }
+ if (is_string($this->requestBody)) {
+ $string = substr($this->requestBody, $this->position, $length);
+ } elseif (is_resource($this->requestBody)) {
+ $string = fread($this->requestBody, $length);
+ } else {
+ $string = $this->requestBody->read($length);
+ }
+ $this->request->setLastEvent('sentBodyPart', strlen($string));
+ $this->position += strlen($string);
+ return $string;
+ }
+
+ /**
+ * Callback function called by cURL for saving the response headers
+ *
+ * @param resource cURL handle
+ * @param string response header (with trailing CRLF)
+ * @return integer number of bytes saved
+ * @see HTTP_Request2_Response::parseHeaderLine()
+ */
+ protected function callbackWriteHeader($ch, $string)
+ {
+ // we may receive a second set of headers if doing e.g. digest auth
+ if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
+ // don't bother with 100-Continue responses (bug #15785)
+ if (!$this->eventSentHeaders ||
+ $this->response->getStatus() >= 200
+ ) {
+ $this->request->setLastEvent(
+ 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
+ );
+ }
+ $this->eventSentHeaders = true;
+ // we'll need a new response object
+ if ($this->eventReceivedHeaders) {
+ $this->eventReceivedHeaders = false;
+ $this->response = null;
+ }
+ }
+ if (empty($this->response)) {
+ $this->response = new HTTP_Request2_Response($string, false);
+ } else {
+ $this->response->parseHeaderLine($string);
+ if ('' == trim($string)) {
+ // don't bother with 100-Continue responses (bug #15785)
+ if (200 <= $this->response->getStatus()) {
+ $this->request->setLastEvent('receivedHeaders', $this->response);
+ }
+ $this->eventReceivedHeaders = true;
+ }
+ }
+ return strlen($string);
+ }
+
+ /**
+ * Callback function called by cURL for saving the response body
+ *
+ * @param resource cURL handle (not used)
+ * @param string part of the response body
+ * @return integer number of bytes saved
+ * @see HTTP_Request2_Response::appendBody()
+ */
+ protected function callbackWriteBody($ch, $string)
+ {
+ // cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
+ // response doesn't start with proper HTTP status line (see bug #15716)
+ if (empty($this->response)) {
+ throw new HTTP_Request2_Exception("Malformed response: {$string}");
+ }
+ if ($this->request->getConfig('store_body')) {
+ $this->response->appendBody($string);
+ }
+ $this->request->setLastEvent('receivedBodyPart', $string);
+ return strlen($string);
+ }
+}
+?>
diff --git a/extlib/HTTP/Request2/Adapter/Mock.php b/extlib/HTTP/Request2/Adapter/Mock.php
new file mode 100644
index 000000000..89688003b
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter/Mock.php
@@ -0,0 +1,171 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Mock.php 274406 2009-01-23 18:01:57Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Mock adapter intended for testing
+ *
+ * Can be used to test applications depending on HTTP_Request2 package without
+ * actually performing any HTTP requests. This adapter will return responses
+ * previously added via addResponse()
+ *
+ * $mock = new HTTP_Request2_Adapter_Mock();
+ * $mock->addResponse("HTTP/1.1 ... ");
+ *
+ * $request = new HTTP_Request2();
+ * $request->setAdapter($mock);
+ *
+ * // This will return the response set above
+ * $response = $req->send();
+ *
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
+{
+ /**
+ * A queue of responses to be returned by sendRequest()
+ * @var array
+ */
+ protected $responses = array();
+
+ /**
+ * Returns the next response from the queue built by addResponse()
+ *
+ * If the queue is empty will return default empty response with status 400,
+ * if an Exception object was added to the queue it will be thrown.
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ if (count($this->responses) > 0) {
+ $response = array_shift($this->responses);
+ if ($response instanceof HTTP_Request2_Response) {
+ return $response;
+ } else {
+ // rethrow the exception,
+ $class = get_class($response);
+ $message = $response->getMessage();
+ $code = $response->getCode();
+ throw new $class($message, $code);
+ }
+ } else {
+ return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
+ }
+ }
+
+ /**
+ * Adds response to the queue
+ *
+ * @param mixed either a string, a pointer to an open file,
+ * a HTTP_Request2_Response or Exception object
+ * @throws HTTP_Request2_Exception
+ */
+ public function addResponse($response)
+ {
+ if (is_string($response)) {
+ $response = self::createResponseFromString($response);
+ } elseif (is_resource($response)) {
+ $response = self::createResponseFromFile($response);
+ } elseif (!$response instanceof HTTP_Request2_Response &&
+ !$response instanceof Exception
+ ) {
+ throw new HTTP_Request2_Exception('Parameter is not a valid response');
+ }
+ $this->responses[] = $response;
+ }
+
+ /**
+ * Creates a new HTTP_Request2_Response object from a string
+ *
+ * @param string
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public static function createResponseFromString($str)
+ {
+ $parts = preg_split('!(\r?\n){2}!m', $str, 2);
+ $headerLines = explode("\n", $parts[0]);
+ $response = new HTTP_Request2_Response(array_shift($headerLines));
+ foreach ($headerLines as $headerLine) {
+ $response->parseHeaderLine($headerLine);
+ }
+ $response->parseHeaderLine('');
+ if (isset($parts[1])) {
+ $response->appendBody($parts[1]);
+ }
+ return $response;
+ }
+
+ /**
+ * Creates a new HTTP_Request2_Response object from a file
+ *
+ * @param resource file pointer returned by fopen()
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public static function createResponseFromFile($fp)
+ {
+ $response = new HTTP_Request2_Response(fgets($fp));
+ do {
+ $headerLine = fgets($fp);
+ $response->parseHeaderLine($headerLine);
+ } while ('' != trim($headerLine));
+
+ while (!feof($fp)) {
+ $response->appendBody(fread($fp, 8192));
+ }
+ return $response;
+ }
+}
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Adapter/Socket.php b/extlib/HTTP/Request2/Adapter/Socket.php
new file mode 100644
index 000000000..ff44d4959
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter/Socket.php
@@ -0,0 +1,971 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * This adapter uses only PHP sockets and will work on almost any PHP
+ * environment. Code is based on original HTTP_Request PEAR package.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
+{
+ /**
+ * Regular expression for 'token' rule from RFC 2616
+ */
+ const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
+
+ /**
+ * Regular expression for 'quoted-string' rule from RFC 2616
+ */
+ const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
+
+ /**
+ * Connected sockets, needed for Keep-Alive support
+ * @var array
+ * @see connect()
+ */
+ protected static $sockets = array();
+
+ /**
+ * Data for digest authentication scheme
+ *
+ * The keys for the array are URL prefixes.
+ *
+ * The values are associative arrays with data (realm, nonce, nonce-count,
+ * opaque...) needed for digest authentication. Stored here to prevent making
+ * duplicate requests to digest-protected resources after we have already
+ * received the challenge.
+ *
+ * @var array
+ */
+ protected static $challenges = array();
+
+ /**
+ * Connected socket
+ * @var resource
+ * @see connect()
+ */
+ protected $socket;
+
+ /**
+ * Challenge used for server digest authentication
+ * @var array
+ */
+ protected $serverChallenge;
+
+ /**
+ * Challenge used for proxy digest authentication
+ * @var array
+ */
+ protected $proxyChallenge;
+
+ /**
+ * Global timeout, exception will be raised if request continues past this time
+ * @var integer
+ */
+ protected $timeout = null;
+
+ /**
+ * Remaining length of the current chunk, when reading chunked response
+ * @var integer
+ * @see readChunked()
+ */
+ protected $chunkLength = 0;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ $this->request = $request;
+ $keepAlive = $this->connect();
+ $headers = $this->prepareHeaders();
+
+ // Use global request timeout if given, see feature requests #5735, #8964
+ if ($timeout = $request->getConfig('timeout')) {
+ $this->timeout = time() + $timeout;
+ } else {
+ $this->timeout = null;
+ }
+
+ try {
+ if (false === @fwrite($this->socket, $headers, strlen($headers))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // provide request headers to the observer, see request #7633
+ $this->request->setLastEvent('sentHeaders', $headers);
+ $this->writeBody();
+
+ if ($this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $request->getConfig('timeout') . ' second(s)'
+ );
+ }
+
+ $response = $this->readResponse();
+
+ if (!$this->canKeepAlive($keepAlive, $response)) {
+ $this->disconnect();
+ }
+
+ if ($this->shouldUseProxyDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($this->shouldUseServerDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($authInfo = $response->getHeader('authentication-info')) {
+ $this->updateChallenge($this->serverChallenge, $authInfo);
+ }
+ if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
+ $this->updateChallenge($this->proxyChallenge, $proxyInfo);
+ }
+
+ } catch (Exception $e) {
+ $this->disconnect();
+ throw $e;
+ }
+
+ return $response;
+ }
+
+ /**
+ * Connects to the remote server
+ *
+ * @return bool whether the connection can be persistent
+ * @throws HTTP_Request2_Exception
+ */
+ protected function connect()
+ {
+ $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
+ $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $headers = $this->request->getHeaders();
+ $reqHost = $this->request->getUrl()->getHost();
+ if (!($reqPort = $this->request->getUrl()->getPort())) {
+ $reqPort = $secure? 443: 80;
+ }
+
+ if ($host = $this->request->getConfig('proxy_host')) {
+ if (!($port = $this->request->getConfig('proxy_port'))) {
+ throw new HTTP_Request2_Exception('Proxy port not provided');
+ }
+ $proxy = true;
+ } else {
+ $host = $reqHost;
+ $port = $reqPort;
+ $proxy = false;
+ }
+
+ if ($tunnel && !$proxy) {
+ throw new HTTP_Request2_Exception(
+ "Trying to perform CONNECT request without proxy"
+ );
+ }
+ if ($secure && !in_array('ssl', stream_get_transports())) {
+ throw new HTTP_Request2_Exception(
+ 'Need OpenSSL support for https:// requests'
+ );
+ }
+
+ // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+ // connection token to a proxy server...
+ if ($proxy && !$secure &&
+ !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
+ ) {
+ $this->request->setHeader('connection');
+ }
+
+ $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
+ empty($headers['connection'])) ||
+ (!empty($headers['connection']) &&
+ 'Keep-Alive' == $headers['connection']);
+ $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
+
+ $options = array();
+ if ($secure || $tunnel) {
+ foreach ($this->request->getConfig() as $name => $value) {
+ if ('ssl_' == substr($name, 0, 4) && null !== $value) {
+ if ('ssl_verify_host' == $name) {
+ if ($value) {
+ $options['CN_match'] = $reqHost;
+ }
+ } else {
+ $options[substr($name, 4)] = $value;
+ }
+ }
+ }
+ ksort($options);
+ }
+
+ // Changing SSL context options after connection is established does *not*
+ // work, we need a new connection if options change
+ $remote = $host . ':' . $port;
+ $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
+ (empty($options)? '': ':' . serialize($options));
+ unset($this->socket);
+
+ // We use persistent connections and have a connected socket?
+ // Ensure that the socket is still connected, see bug #16149
+ if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
+ !feof(self::$sockets[$socketKey])
+ ) {
+ $this->socket =& self::$sockets[$socketKey];
+
+ } elseif ($secure && $proxy && !$tunnel) {
+ $this->establishTunnel();
+ $this->request->setLastEvent(
+ 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
+ );
+ self::$sockets[$socketKey] =& $this->socket;
+
+ } else {
+ // Set SSL context options if doing HTTPS request or creating a tunnel
+ $context = stream_context_create();
+ foreach ($options as $name => $value) {
+ if (!stream_context_set_option($context, 'ssl', $name, $value)) {
+ throw new HTTP_Request2_Exception(
+ "Error setting SSL context option '{$name}'"
+ );
+ }
+ }
+ $this->socket = @stream_socket_client(
+ $remote, $errno, $errstr,
+ $this->request->getConfig('connect_timeout'),
+ STREAM_CLIENT_CONNECT, $context
+ );
+ if (!$this->socket) {
+ throw new HTTP_Request2_Exception(
+ "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
+ );
+ }
+ $this->request->setLastEvent('connect', $remote);
+ self::$sockets[$socketKey] =& $this->socket;
+ }
+ return $keepAlive;
+ }
+
+ /**
+ * Establishes a tunnel to a secure remote server via HTTP CONNECT request
+ *
+ * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
+ * sees that we are connected to a proxy server (duh!) rather than the server
+ * that presents its certificate.
+ *
+ * @link http://tools.ietf.org/html/rfc2817#section-5.2
+ * @throws HTTP_Request2_Exception
+ */
+ protected function establishTunnel()
+ {
+ $donor = new self;
+ $connect = new HTTP_Request2(
+ $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
+ array_merge($this->request->getConfig(),
+ array('adapter' => $donor))
+ );
+ $response = $connect->send();
+ // Need any successful (2XX) response
+ if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
+ throw new HTTP_Request2_Exception(
+ 'Failed to connect via HTTPS proxy. Proxy response: ' .
+ $response->getStatus() . ' ' . $response->getReasonPhrase()
+ );
+ }
+ $this->socket = $donor->socket;
+
+ $modes = array(
+ STREAM_CRYPTO_METHOD_TLS_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv2_CLIENT
+ );
+
+ foreach ($modes as $mode) {
+ if (stream_socket_enable_crypto($this->socket, true, $mode)) {
+ return;
+ }
+ }
+ throw new HTTP_Request2_Exception(
+ 'Failed to enable secure connection when connecting through proxy'
+ );
+ }
+
+ /**
+ * Checks whether current connection may be reused or should be closed
+ *
+ * @param boolean whether connection could be persistent
+ * in the first place
+ * @param HTTP_Request2_Response response object to check
+ * @return boolean
+ */
+ protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
+ {
+ // Do not close socket on successful CONNECT request
+ if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()
+ ) {
+ return true;
+ }
+
+ $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
+ null !== $response->getHeader('content-length');
+ $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
+ (null === $response->getHeader('connection') &&
+ '1.1' == $response->getVersion());
+ return $requestKeepAlive && $lengthKnown && $persistent;
+ }
+
+ /**
+ * Disconnects from the remote server
+ */
+ protected function disconnect()
+ {
+ if (is_resource($this->socket)) {
+ fclose($this->socket);
+ $this->socket = null;
+ $this->request->setLastEvent('disconnect');
+ }
+ }
+
+ /**
+ * Checks whether another request should be performed with server digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 401
+ * - auth credentials should be set in the request object
+ * - response should contain WWW-Authenticate header with digest challenge
+ * - there is either no challenge stored for this URL or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
+ {
+ // no sense repeating a request if we don't have credentials
+ if (401 != $response->getStatus() || !$this->request->getAuth()) {
+ return false;
+ }
+ if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
+ return false;
+ }
+
+ $url = $this->request->getUrl();
+ $scheme = $url->getScheme();
+ $host = $scheme . '://' . $url->getHost();
+ if ($port = $url->getPort()) {
+ if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
+ (0 == strcasecmp($scheme, 'https') && 443 != $port)
+ ) {
+ $host .= ':' . $port;
+ }
+ }
+
+ if (!empty($challenge['domain'])) {
+ $prefixes = array();
+ foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
+ // don't bother with different servers
+ if ('/' == substr($prefix, 0, 1)) {
+ $prefixes[] = $host . $prefix;
+ }
+ }
+ }
+ if (empty($prefixes)) {
+ $prefixes = array($host . '/');
+ }
+
+ $ret = true;
+ foreach ($prefixes as $prefix) {
+ if (!empty(self::$challenges[$prefix]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ // probably credentials are invalid
+ $ret = false;
+ }
+ self::$challenges[$prefix] =& $challenge;
+ }
+ return $ret;
+ }
+
+ /**
+ * Checks whether another request should be performed with proxy digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 407
+ * - proxy auth credentials should be set in the request object
+ * - response should contain Proxy-Authenticate header with digest challenge
+ * - there is either no challenge stored for this proxy or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
+ {
+ if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
+ return false;
+ }
+ if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
+ return false;
+ }
+
+ $key = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+
+ if (!empty(self::$challenges[$key]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ $ret = false;
+ } else {
+ $ret = true;
+ }
+ self::$challenges[$key] = $challenge;
+ return $ret;
+ }
+
+ /**
+ * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
+ *
+ * There is a problem with implementation of RFC 2617: several of the parameters
+ * here are defined as quoted-string and thus may contain backslash escaped
+ * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
+ * just value of quoted-string X without surrounding quotes, it doesn't speak
+ * about removing backslash escaping.
+ *
+ * Now realm parameter is user-defined and human-readable, strange things
+ * happen when it contains quotes:
+ * - Apache allows quotes in realm, but apparently uses realm value without
+ * backslashes for digest computation
+ * - Squid allows (manually escaped) quotes there, but it is impossible to
+ * authorize with either escaped or unescaped quotes used in digest,
+ * probably it can't parse the response (?)
+ * - Both IE and Firefox display realm value with backslashes in
+ * the password popup and apparently use the same value for digest
+ *
+ * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
+ * quoted-string handling, unfortunately that means failure to authorize
+ * sometimes
+ *
+ * @param string value of WWW-Authenticate or Proxy-Authenticate header
+ * @return mixed associative array with challenge parameters, false if
+ * no challenge is present in header value
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function parseDigestChallenge($headerValue)
+ {
+ $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
+ $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
+ if (!preg_match($challenge, $headerValue, $matches)) {
+ return false;
+ }
+
+ preg_match_all('!' . $authParam . '!', $matches[0], $params);
+ $paramsAry = array();
+ $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
+ 'algorithm', 'qop');
+ for ($i = 0; $i < count($params[0]); $i++) {
+ // section 3.2.1: Any unrecognized directive MUST be ignored.
+ if (in_array($params[1][$i], $knownParams)) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ }
+ // we only support qop=auth
+ if (!empty($paramsAry['qop']) &&
+ !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
+ ) {
+ throw new HTTP_Request2_Exception(
+ "Only 'auth' qop is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['qop']}'"
+ );
+ }
+ // we only support algorithm=MD5
+ if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
+ throw new HTTP_Request2_Exception(
+ "Only 'MD5' algorithm is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['algorithm']}'"
+ );
+ }
+
+ return $paramsAry;
+ }
+
+ /**
+ * Parses [Proxy-]Authentication-Info header value and updates challenge
+ *
+ * @param array challenge to update
+ * @param string value of [Proxy-]Authentication-Info header
+ * @todo validate server rspauth response
+ */
+ protected function updateChallenge(&$challenge, $headerValue)
+ {
+ $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
+ $paramsAry = array();
+
+ preg_match_all($authParam, $headerValue, $params);
+ for ($i = 0; $i < count($params[0]); $i++) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ // for now, just update the nonce value
+ if (!empty($paramsAry['nextnonce'])) {
+ $challenge['nonce'] = $paramsAry['nextnonce'];
+ $challenge['nc'] = 1;
+ }
+ }
+
+ /**
+ * Creates a value for [Proxy-]Authorization header when using digest authentication
+ *
+ * @param string user name
+ * @param string password
+ * @param string request URL
+ * @param array digest challenge parameters
+ * @return string value of [Proxy-]Authorization request header
+ * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
+ */
+ protected function createDigestResponse($user, $password, $url, &$challenge)
+ {
+ if (false !== ($q = strpos($url, '?')) &&
+ $this->request->getConfig('digest_compat_ie')
+ ) {
+ $url = substr($url, 0, $q);
+ }
+
+ $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
+ $a2 = md5($this->request->getMethod() . ':' . $url);
+
+ if (empty($challenge['qop'])) {
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
+ } else {
+ $challenge['cnonce'] = 'Req2.' . rand();
+ if (empty($challenge['nc'])) {
+ $challenge['nc'] = 1;
+ }
+ $nc = sprintf('%08x', $challenge['nc']++);
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
+ $challenge['cnonce'] . ':auth:' . $a2);
+ }
+ return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
+ 'realm="' . $challenge['realm'] . '", ' .
+ 'nonce="' . $challenge['nonce'] . '", ' .
+ 'uri="' . $url . '", ' .
+ 'response="' . $digest . '"' .
+ (!empty($challenge['opaque'])?
+ ', opaque="' . $challenge['opaque'] . '"':
+ '') .
+ (!empty($challenge['qop'])?
+ ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
+ '');
+ }
+
+ /**
+ * Adds 'Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request host (needed for digest authentication)
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
+ {
+ if (!($auth = $this->request->getAuth())) {
+ return;
+ }
+ switch ($auth['scheme']) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['authorization'] =
+ 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->serverChallenge);
+ $fullUrl = ('/' == $requestUrl[0])?
+ $this->request->getUrl()->getScheme() . '://' .
+ $requestHost . $requestUrl:
+ $requestUrl;
+ foreach (array_keys(self::$challenges) as $key) {
+ if ($key == substr($fullUrl, 0, strlen($key))) {
+ $headers['authorization'] = $this->createDigestResponse(
+ $auth['user'], $auth['password'],
+ $requestUrl, self::$challenges[$key]
+ );
+ $this->serverChallenge =& self::$challenges[$key];
+ break;
+ }
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '{$auth['scheme']}'"
+ );
+ }
+ }
+
+ /**
+ * Adds 'Proxy-Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
+ {
+ if (!$this->request->getConfig('proxy_host') ||
+ !($user = $this->request->getConfig('proxy_user')) ||
+ (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
+ HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
+ ) {
+ return;
+ }
+
+ $password = $this->request->getConfig('proxy_password');
+ switch ($this->request->getConfig('proxy_auth_scheme')) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['proxy-authorization'] =
+ 'Basic ' . base64_encode($user . ':' . $password);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->proxyChallenge);
+ $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+ if (!empty(self::$challenges[$proxyUrl])) {
+ $headers['proxy-authorization'] = $this->createDigestResponse(
+ $user, $password,
+ $requestUrl, self::$challenges[$proxyUrl]
+ );
+ $this->proxyChallenge =& self::$challenges[$proxyUrl];
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '" .
+ $this->request->getConfig('proxy_auth_scheme') . "'"
+ );
+ }
+ }
+
+
+ /**
+ * Creates the string with the Request-Line and request headers
+ *
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function prepareHeaders()
+ {
+ $headers = $this->request->getHeaders();
+ $url = $this->request->getUrl();
+ $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $host = $url->getHost();
+
+ $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
+ if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
+ $host .= ':' . (empty($port)? $defaultPort: $port);
+ }
+ // Do not overwrite explicitly set 'Host' header, see bug #16146
+ if (!isset($headers['host'])) {
+ $headers['host'] = $host;
+ }
+
+ if ($connect) {
+ $requestUrl = $host;
+
+ } else {
+ if (!$this->request->getConfig('proxy_host') ||
+ 0 == strcasecmp($url->getScheme(), 'https')
+ ) {
+ $requestUrl = '';
+ } else {
+ $requestUrl = $url->getScheme() . '://' . $host;
+ }
+ $path = $url->getPath();
+ $query = $url->getQuery();
+ $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
+ }
+
+ if ('1.1' == $this->request->getConfig('protocol_version') &&
+ extension_loaded('zlib') && !isset($headers['accept-encoding'])
+ ) {
+ $headers['accept-encoding'] = 'gzip, deflate';
+ }
+
+ $this->addAuthorizationHeader($headers, $host, $requestUrl);
+ $this->addProxyAuthorizationHeader($headers, $requestUrl);
+ $this->calculateRequestLength($headers);
+
+ $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
+ $this->request->getConfig('protocol_version') . "\r\n";
+ foreach ($headers as $name => $value) {
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $headersStr .= $canonicalName . ': ' . $value . "\r\n";
+ }
+ return $headersStr . "\r\n";
+ }
+
+ /**
+ * Sends the request body
+ *
+ * @throws HTTP_Request2_Exception
+ */
+ protected function writeBody()
+ {
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength
+ ) {
+ return;
+ }
+
+ $position = 0;
+ $bufferSize = $this->request->getConfig('buffer_size');
+ while ($position < $this->contentLength) {
+ if (is_string($this->requestBody)) {
+ $str = substr($this->requestBody, $position, $bufferSize);
+ } elseif (is_resource($this->requestBody)) {
+ $str = fread($this->requestBody, $bufferSize);
+ } else {
+ $str = $this->requestBody->read($bufferSize);
+ }
+ if (false === @fwrite($this->socket, $str, strlen($str))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // Provide the length of written string to the observer, request #7630
+ $this->request->setLastEvent('sentBodyPart', strlen($str));
+ $position += strlen($str);
+ }
+ }
+
+ /**
+ * Reads the remote server's response
+ *
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readResponse()
+ {
+ $bufferSize = $this->request->getConfig('buffer_size');
+
+ do {
+ $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
+ do {
+ $headerLine = $this->readLine($bufferSize);
+ $response->parseHeaderLine($headerLine);
+ } while ('' != $headerLine);
+ } while (in_array($response->getStatus(), array(100, 101)));
+
+ $this->request->setLastEvent('receivedHeaders', $response);
+
+ // No body possible in such responses
+ if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
+ (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
+ in_array($response->getStatus(), array(204, 304))
+ ) {
+ return $response;
+ }
+
+ $chunked = 'chunked' == $response->getHeader('transfer-encoding');
+ $length = $response->getHeader('content-length');
+ $hasBody = false;
+ if ($chunked || null === $length || 0 < intval($length)) {
+ // RFC 2616, section 4.4:
+ // 3. ... If a message is received with both a
+ // Transfer-Encoding header field and a Content-Length header field,
+ // the latter MUST be ignored.
+ $toRead = ($chunked || null === $length)? null: $length;
+ $this->chunkLength = 0;
+
+ while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
+ if ($chunked) {
+ $data = $this->readChunked($bufferSize);
+ } elseif (is_null($toRead)) {
+ $data = $this->fread($bufferSize);
+ } else {
+ $data = $this->fread(min($toRead, $bufferSize));
+ $toRead -= strlen($data);
+ }
+ if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
+ break;
+ }
+
+ $hasBody = true;
+ if ($this->request->getConfig('store_body')) {
+ $response->appendBody($data);
+ }
+ if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
+ $this->request->setLastEvent('receivedEncodedBodyPart', $data);
+ } else {
+ $this->request->setLastEvent('receivedBodyPart', $data);
+ }
+ }
+ }
+
+ if ($hasBody) {
+ $this->request->setLastEvent('receivedBody', $response);
+ }
+ return $response;
+ }
+
+ /**
+ * Reads until either the end of the socket or a newline, whichever comes first
+ *
+ * Strips the trailing newline from the returned data, handles global
+ * request timeout. Method idea borrowed from Net_Socket PEAR package.
+ *
+ * @param int buffer size to use for reading
+ * @return Available data up to the newline (not including newline)
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function readLine($bufferSize)
+ {
+ $line = '';
+ while (!feof($this->socket)) {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $line .= @fgets($this->socket, $bufferSize);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ if (substr($line, -1) == "\n") {
+ return rtrim($line, "\r\n");
+ }
+ }
+ return $line;
+ }
+
+ /**
+ * Wrapper around fread(), handles global request timeout
+ *
+ * @param int Reads up to this number of bytes
+ * @return Data read from socket
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function fread($length)
+ {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $data = fread($this->socket, $length);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ return $data;
+ }
+
+ /**
+ * Reads a part of response body encoded with chunked Transfer-Encoding
+ *
+ * @param int buffer size to use for reading
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readChunked($bufferSize)
+ {
+ // at start of the next chunk?
+ if (0 == $this->chunkLength) {
+ $line = $this->readLine($bufferSize);
+ if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
+ throw new HTTP_Request2_Exception(
+ "Cannot decode chunked response, invalid chunk length '{$line}'"
+ );
+ } else {
+ $this->chunkLength = hexdec($matches[1]);
+ // Chunk with zero length indicates the end
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize);
+ return '';
+ }
+ }
+ }
+ $data = $this->fread(min($this->chunkLength, $bufferSize));
+ $this->chunkLength -= strlen($data);
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize); // Trailing CRLF
+ }
+ return $data;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Exception.php b/extlib/HTTP/Request2/Exception.php
new file mode 100644
index 000000000..bfef7d6c2
--- /dev/null
+++ b/extlib/HTTP/Request2/Exception.php
@@ -0,0 +1,62 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Exception.php 273003 2009-01-07 19:28:22Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for exceptions in PEAR
+ */
+require_once 'PEAR/Exception.php';
+
+/**
+ * Exception class for HTTP_Request2 package
+ *
+ * Such a class is required by the Exception RFC:
+ * http://pear.php.net/pepr/pepr-proposal-show.php?id=132
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Exception extends PEAR_Exception
+{
+}
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/MultipartBody.php b/extlib/HTTP/Request2/MultipartBody.php
new file mode 100644
index 000000000..d8afd8344
--- /dev/null
+++ b/extlib/HTTP/Request2/MultipartBody.php
@@ -0,0 +1,274 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: MultipartBody.php 287306 2009-08-14 15:22:52Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class for building multipart/form-data request body
+ *
+ * The class helps to reduce memory consumption by streaming large file uploads
+ * from disk, it also allows monitoring of upload progress (see request #7630)
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ * @link http://tools.ietf.org/html/rfc1867
+ */
+class HTTP_Request2_MultipartBody
+{
+ /**
+ * MIME boundary
+ * @var string
+ */
+ private $_boundary;
+
+ /**
+ * Form parameters added via {@link HTTP_Request2::addPostParameter()}
+ * @var array
+ */
+ private $_params = array();
+
+ /**
+ * File uploads added via {@link HTTP_Request2::addUpload()}
+ * @var array
+ */
+ private $_uploads = array();
+
+ /**
+ * Header for parts with parameters
+ * @var string
+ */
+ private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
+
+ /**
+ * Header for parts with uploads
+ * @var string
+ */
+ private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
+
+ /**
+ * Current position in parameter and upload arrays
+ *
+ * First number is index of "current" part, second number is position within
+ * "current" part
+ *
+ * @var array
+ */
+ private $_pos = array(0, 0);
+
+
+ /**
+ * Constructor. Sets the arrays with POST data.
+ *
+ * @param array values of form fields set via {@link HTTP_Request2::addPostParameter()}
+ * @param array file uploads set via {@link HTTP_Request2::addUpload()}
+ * @param bool whether to append brackets to array variable names
+ */
+ public function __construct(array $params, array $uploads, $useBrackets = true)
+ {
+ $this->_params = self::_flattenArray('', $params, $useBrackets);
+ foreach ($uploads as $fieldName => $f) {
+ if (!is_array($f['fp'])) {
+ $this->_uploads[] = $f + array('name' => $fieldName);
+ } else {
+ for ($i = 0; $i < count($f['fp']); $i++) {
+ $upload = array(
+ 'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
+ );
+ foreach (array('fp', 'filename', 'size', 'type') as $key) {
+ $upload[$key] = $f[$key][$i];
+ }
+ $this->_uploads[] = $upload;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the length of the body to use in Content-Length header
+ *
+ * @return integer
+ */
+ public function getLength()
+ {
+ $boundaryLength = strlen($this->getBoundary());
+ $headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
+ $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
+ $length = $boundaryLength + 6;
+ foreach ($this->_params as $p) {
+ $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
+ }
+ foreach ($this->_uploads as $u) {
+ $length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
+ strlen($u['filename']) + $u['size'] + 2;
+ }
+ return $length;
+ }
+
+ /**
+ * Returns the boundary to use in Content-Type header
+ *
+ * @return string
+ */
+ public function getBoundary()
+ {
+ if (empty($this->_boundary)) {
+ $this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
+ }
+ return $this->_boundary;
+ }
+
+ /**
+ * Returns next chunk of request body
+ *
+ * @param integer Amount of bytes to read
+ * @return string Up to $length bytes of data, empty string if at end
+ */
+ public function read($length)
+ {
+ $ret = '';
+ $boundary = $this->getBoundary();
+ $paramCount = count($this->_params);
+ $uploadCount = count($this->_uploads);
+ while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
+ $oldLength = $length;
+ if ($this->_pos[0] < $paramCount) {
+ $param = sprintf($this->_headerParam, $boundary,
+ $this->_params[$this->_pos[0]][0]) .
+ $this->_params[$this->_pos[0]][1] . "\r\n";
+ $ret .= substr($param, $this->_pos[1], $length);
+ $length -= min(strlen($param) - $this->_pos[1], $length);
+
+ } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
+ $pos = $this->_pos[0] - $paramCount;
+ $header = sprintf($this->_headerUpload, $boundary,
+ $this->_uploads[$pos]['name'],
+ $this->_uploads[$pos]['filename'],
+ $this->_uploads[$pos]['type']);
+ if ($this->_pos[1] < strlen($header)) {
+ $ret .= substr($header, $this->_pos[1], $length);
+ $length -= min(strlen($header) - $this->_pos[1], $length);
+ }
+ $filePos = max(0, $this->_pos[1] - strlen($header));
+ if ($length > 0 && $filePos < $this->_uploads[$pos]['size']) {
+ $ret .= fread($this->_uploads[$pos]['fp'], $length);
+ $length -= min($length, $this->_uploads[$pos]['size'] - $filePos);
+ }
+ if ($length > 0) {
+ $start = $this->_pos[1] + ($oldLength - $length) -
+ strlen($header) - $this->_uploads[$pos]['size'];
+ $ret .= substr("\r\n", $start, $length);
+ $length -= min(2 - $start, $length);
+ }
+
+ } else {
+ $closing = '--' . $boundary . "--\r\n";
+ $ret .= substr($closing, $this->_pos[1], $length);
+ $length -= min(strlen($closing) - $this->_pos[1], $length);
+ }
+ if ($length > 0) {
+ $this->_pos = array($this->_pos[0] + 1, 0);
+ } else {
+ $this->_pos[1] += $oldLength;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Sets the current position to the start of the body
+ *
+ * This allows reusing the same body in another request
+ */
+ public function rewind()
+ {
+ $this->_pos = array(0, 0);
+ foreach ($this->_uploads as $u) {
+ rewind($u['fp']);
+ }
+ }
+
+ /**
+ * Returns the body as string
+ *
+ * Note that it reads all file uploads into memory so it is a good idea not
+ * to use this method with large file uploads and rely on read() instead.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $this->rewind();
+ return $this->read($this->getLength());
+ }
+
+
+ /**
+ * Helper function to change the (probably multidimensional) associative array
+ * into the simple one.
+ *
+ * @param string name for item
+ * @param mixed item's values
+ * @param bool whether to append [] to array variables' names
+ * @return array array with the following items: array('item name', 'item value');
+ */
+ private static function _flattenArray($name, $values, $useBrackets)
+ {
+ if (!is_array($values)) {
+ return array(array($name, $values));
+ } else {
+ $ret = array();
+ foreach ($values as $k => $v) {
+ if (empty($name)) {
+ $newName = $k;
+ } elseif ($useBrackets) {
+ $newName = $name . '[' . $k . ']';
+ } else {
+ $newName = $name;
+ }
+ $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
+ }
+ return $ret;
+ }
+ }
+}
+?>
diff --git a/extlib/HTTP/Request2/Observer/Log.php b/extlib/HTTP/Request2/Observer/Log.php
new file mode 100644
index 000000000..b1a055278
--- /dev/null
+++ b/extlib/HTTP/Request2/Observer/Log.php
@@ -0,0 +1,215 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author David Jean Louis
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Log.php 272593 2009-01-02 16:27:14Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * A debug observer useful for debugging / testing.
+ *
+ * This observer logs to a log target data corresponding to the various request
+ * and response events, it logs by default to php://output but can be configured
+ * to log to a file or via the PEAR Log package.
+ *
+ * A simple example:
+ *
+ * require_once 'HTTP/Request2.php';
+ * require_once 'HTTP/Request2/Observer/Log.php';
+ *
+ * $request = new HTTP_Request2('http://www.example.com');
+ * $observer = new HTTP_Request2_Observer_Log();
+ * $request->attach($observer);
+ * $request->send();
+ *
+ *
+ * A more complex example with PEAR Log:
+ *
+ * require_once 'HTTP/Request2.php';
+ * require_once 'HTTP/Request2/Observer/Log.php';
+ * require_once 'Log.php';
+ *
+ * $request = new HTTP_Request2('http://www.example.com');
+ * // we want to log with PEAR log
+ * $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
+ *
+ * // we only want to log received headers
+ * $observer->events = array('receivedHeaders');
+ *
+ * $request->attach($observer);
+ * $request->send();
+ *
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author David Jean Louis
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: 0.4.1
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+class HTTP_Request2_Observer_Log implements SplObserver
+{
+ // properties {{{
+
+ /**
+ * The log target, it can be a a resource or a PEAR Log instance.
+ *
+ * @var resource|Log $target
+ */
+ protected $target = null;
+
+ /**
+ * The events to log.
+ *
+ * @var array $events
+ */
+ public $events = array(
+ 'connect',
+ 'sentHeaders',
+ 'sentBodyPart',
+ 'receivedHeaders',
+ 'receivedBody',
+ 'disconnect',
+ );
+
+ // }}}
+ // __construct() {{{
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $target Can be a file path (default: php://output), a resource,
+ * or an instance of the PEAR Log class.
+ * @param array $events Array of events to listen to (default: all events)
+ *
+ * @return void
+ */
+ public function __construct($target = 'php://output', array $events = array())
+ {
+ if (!empty($events)) {
+ $this->events = $events;
+ }
+ if (is_resource($target) || $target instanceof Log) {
+ $this->target = $target;
+ } elseif (false === ($this->target = @fopen($target, 'w'))) {
+ throw new HTTP_Request2_Exception("Unable to open '{$target}'");
+ }
+ }
+
+ // }}}
+ // update() {{{
+
+ /**
+ * Called when the request notify us of an event.
+ *
+ * @param HTTP_Request2 $subject The HTTP_Request2 instance
+ *
+ * @return void
+ */
+ public function update(SplSubject $subject)
+ {
+ $event = $subject->getLastEvent();
+ if (!in_array($event['name'], $this->events)) {
+ return;
+ }
+
+ switch ($event['name']) {
+ case 'connect':
+ $this->log('* Connected to ' . $event['data']);
+ break;
+ case 'sentHeaders':
+ $headers = explode("\r\n", $event['data']);
+ array_pop($headers);
+ foreach ($headers as $header) {
+ $this->log('> ' . $header);
+ }
+ break;
+ case 'sentBodyPart':
+ $this->log('> ' . $event['data']);
+ break;
+ case 'receivedHeaders':
+ $this->log(sprintf('< HTTP/%s %s %s',
+ $event['data']->getVersion(),
+ $event['data']->getStatus(),
+ $event['data']->getReasonPhrase()));
+ $headers = $event['data']->getHeader();
+ foreach ($headers as $key => $val) {
+ $this->log('< ' . $key . ': ' . $val);
+ }
+ $this->log('< ');
+ break;
+ case 'receivedBody':
+ $this->log($event['data']->getBody());
+ break;
+ case 'disconnect':
+ $this->log('* Disconnected');
+ break;
+ }
+ }
+
+ // }}}
+ // log() {{{
+
+ /**
+ * Log the given message to the configured target.
+ *
+ * @param string $message Message to display
+ *
+ * @return void
+ */
+ protected function log($message)
+ {
+ if ($this->target instanceof Log) {
+ $this->target->debug($message);
+ } elseif (is_resource($this->target)) {
+ fwrite($this->target, $message . "\r\n");
+ }
+ }
+
+ // }}}
+}
+
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Response.php b/extlib/HTTP/Request2/Response.php
new file mode 100644
index 000000000..c7c1021fb
--- /dev/null
+++ b/extlib/HTTP/Request2/Response.php
@@ -0,0 +1,549 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Response.php 287948 2009-09-01 17:12:18Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * Class representing a HTTP response
+ *
+ * The class is designed to be used in "streaming" scenario, building the
+ * response as it is being received:
+ *
+ * $statusLine = read_status_line();
+ * $response = new HTTP_Request2_Response($statusLine);
+ * do {
+ * $headerLine = read_header_line();
+ * $response->parseHeaderLine($headerLine);
+ * } while ($headerLine != '');
+ *
+ * while ($chunk = read_body()) {
+ * $response->appendBody($chunk);
+ * }
+ *
+ * var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
+ *
+ *
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ * @link http://tools.ietf.org/html/rfc2616#section-6
+ */
+class HTTP_Request2_Response
+{
+ /**
+ * HTTP protocol version (e.g. 1.0, 1.1)
+ * @var string
+ */
+ protected $version;
+
+ /**
+ * Status code
+ * @var integer
+ * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
+ */
+ protected $code;
+
+ /**
+ * Reason phrase
+ * @var string
+ * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
+ */
+ protected $reasonPhrase;
+
+ /**
+ * Associative array of response headers
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * Cookies set in the response
+ * @var array
+ */
+ protected $cookies = array();
+
+ /**
+ * Name of last header processed by parseHederLine()
+ *
+ * Used to handle the headers that span multiple lines
+ *
+ * @var string
+ */
+ protected $lastHeader = null;
+
+ /**
+ * Response body
+ * @var string
+ */
+ protected $body = '';
+
+ /**
+ * Whether the body is still encoded by Content-Encoding
+ *
+ * cURL provides the decoded body to the callback; if we are reading from
+ * socket the body is still gzipped / deflated
+ *
+ * @var bool
+ */
+ protected $bodyEncoded;
+
+ /**
+ * Associative array of HTTP status code / reason phrase.
+ *
+ * @var array
+ * @link http://tools.ietf.org/html/rfc2616#section-10
+ */
+ protected static $phrases = array(
+
+ // 1xx: Informational - Request received, continuing process
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+
+ // 2xx: Success - The action was successfully received, understood and
+ // accepted
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+
+ // 3xx: Redirection - Further action must be taken in order to complete
+ // the request
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found', // 1.1
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+
+ // 4xx: Client Error - The request contains bad syntax or cannot be
+ // fulfilled
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+
+ // 5xx: Server Error - The server failed to fulfill an apparently
+ // valid request
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 509 => 'Bandwidth Limit Exceeded',
+
+ );
+
+ /**
+ * Constructor, parses the response status line
+ *
+ * @param string Response status line (e.g. "HTTP/1.1 200 OK")
+ * @param bool Whether body is still encoded by Content-Encoding
+ * @throws HTTP_Request2_Exception if status line is invalid according to spec
+ */
+ public function __construct($statusLine, $bodyEncoded = true)
+ {
+ if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
+ throw new HTTP_Request2_Exception("Malformed response: {$statusLine}");
+ }
+ $this->version = $m[1];
+ $this->code = intval($m[2]);
+ if (!empty($m[3])) {
+ $this->reasonPhrase = trim($m[3]);
+ } elseif (!empty(self::$phrases[$this->code])) {
+ $this->reasonPhrase = self::$phrases[$this->code];
+ }
+ $this->bodyEncoded = (bool)$bodyEncoded;
+ }
+
+ /**
+ * Parses the line from HTTP response filling $headers array
+ *
+ * The method should be called after reading the line from socket or receiving
+ * it into cURL callback. Passing an empty string here indicates the end of
+ * response headers and triggers additional processing, so be sure to pass an
+ * empty string in the end.
+ *
+ * @param string Line from HTTP response
+ */
+ public function parseHeaderLine($headerLine)
+ {
+ $headerLine = trim($headerLine, "\r\n");
+
+ // empty string signals the end of headers, process the received ones
+ if ('' == $headerLine) {
+ if (!empty($this->headers['set-cookie'])) {
+ $cookies = is_array($this->headers['set-cookie'])?
+ $this->headers['set-cookie']:
+ array($this->headers['set-cookie']);
+ foreach ($cookies as $cookieString) {
+ $this->parseCookie($cookieString);
+ }
+ unset($this->headers['set-cookie']);
+ }
+ foreach (array_keys($this->headers) as $k) {
+ if (is_array($this->headers[$k])) {
+ $this->headers[$k] = implode(', ', $this->headers[$k]);
+ }
+ }
+
+ // string of the form header-name: header value
+ } elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
+ $name = strtolower($m[1]);
+ $value = trim($m[2]);
+ if (empty($this->headers[$name])) {
+ $this->headers[$name] = $value;
+ } else {
+ if (!is_array($this->headers[$name])) {
+ $this->headers[$name] = array($this->headers[$name]);
+ }
+ $this->headers[$name][] = $value;
+ }
+ $this->lastHeader = $name;
+
+ // string
+ } elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
+ if (!is_array($this->headers[$this->lastHeader])) {
+ $this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
+ } else {
+ $key = count($this->headers[$this->lastHeader]) - 1;
+ $this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
+ }
+ }
+ }
+
+ /**
+ * Parses a Set-Cookie header to fill $cookies array
+ *
+ * @param string value of Set-Cookie header
+ * @link http://cgi.netscape.com/newsref/std/cookie_spec.html
+ */
+ protected function parseCookie($cookieString)
+ {
+ $cookie = array(
+ 'expires' => null,
+ 'domain' => null,
+ 'path' => null,
+ 'secure' => false
+ );
+
+ // Only a name=value pair
+ if (!strpos($cookieString, ';')) {
+ $pos = strpos($cookieString, '=');
+ $cookie['name'] = trim(substr($cookieString, 0, $pos));
+ $cookie['value'] = trim(substr($cookieString, $pos + 1));
+
+ // Some optional parameters are supplied
+ } else {
+ $elements = explode(';', $cookieString);
+ $pos = strpos($elements[0], '=');
+ $cookie['name'] = trim(substr($elements[0], 0, $pos));
+ $cookie['value'] = trim(substr($elements[0], $pos + 1));
+
+ for ($i = 1; $i < count($elements); $i++) {
+ if (false === strpos($elements[$i], '=')) {
+ $elName = trim($elements[$i]);
+ $elValue = null;
+ } else {
+ list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
+ }
+ $elName = strtolower($elName);
+ if ('secure' == $elName) {
+ $cookie['secure'] = true;
+ } elseif ('expires' == $elName) {
+ $cookie['expires'] = str_replace('"', '', $elValue);
+ } elseif ('path' == $elName || 'domain' == $elName) {
+ $cookie[$elName] = urldecode($elValue);
+ } else {
+ $cookie[$elName] = $elValue;
+ }
+ }
+ }
+ $this->cookies[] = $cookie;
+ }
+
+ /**
+ * Appends a string to the response body
+ * @param string
+ */
+ public function appendBody($bodyChunk)
+ {
+ $this->body .= $bodyChunk;
+ }
+
+ /**
+ * Returns the status code
+ * @return integer
+ */
+ public function getStatus()
+ {
+ return $this->code;
+ }
+
+ /**
+ * Returns the reason phrase
+ * @return string
+ */
+ public function getReasonPhrase()
+ {
+ return $this->reasonPhrase;
+ }
+
+ /**
+ * Returns either the named header or all response headers
+ *
+ * @param string Name of header to return
+ * @return string|array Value of $headerName header (null if header is
+ * not present), array of all response headers if
+ * $headerName is null
+ */
+ public function getHeader($headerName = null)
+ {
+ if (null === $headerName) {
+ return $this->headers;
+ } else {
+ $headerName = strtolower($headerName);
+ return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
+ }
+ }
+
+ /**
+ * Returns cookies set in response
+ *
+ * @return array
+ */
+ public function getCookies()
+ {
+ return $this->cookies;
+ }
+
+ /**
+ * Returns the body of the response
+ *
+ * @return string
+ * @throws HTTP_Request2_Exception if body cannot be decoded
+ */
+ public function getBody()
+ {
+ if (!$this->bodyEncoded ||
+ !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
+ ) {
+ return $this->body;
+
+ } else {
+ if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
+ $oldEncoding = mb_internal_encoding();
+ mb_internal_encoding('iso-8859-1');
+ }
+
+ try {
+ switch (strtolower($this->getHeader('content-encoding'))) {
+ case 'gzip':
+ $decoded = self::decodeGzip($this->body);
+ break;
+ case 'deflate':
+ $decoded = self::decodeDeflate($this->body);
+ }
+ } catch (Exception $e) {
+ }
+
+ if (!empty($oldEncoding)) {
+ mb_internal_encoding($oldEncoding);
+ }
+ if (!empty($e)) {
+ throw $e;
+ }
+ return $decoded;
+ }
+ }
+
+ /**
+ * Get the HTTP version of the response
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Decodes the message-body encoded by gzip
+ *
+ * The real decoding work is done by gzinflate() built-in function, this
+ * method only parses the header and checks data for compliance with
+ * RFC 1952
+ *
+ * @param string gzip-encoded data
+ * @return string decoded data
+ * @throws HTTP_Request2_Exception
+ * @link http://tools.ietf.org/html/rfc1952
+ */
+ public static function decodeGzip($data)
+ {
+ $length = strlen($data);
+ // If it doesn't look like gzip-encoded data, don't bother
+ if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
+ return $data;
+ }
+ if (!function_exists('gzinflate')) {
+ throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
+ }
+ $method = ord(substr($data, 2, 1));
+ if (8 != $method) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: unknown compression method');
+ }
+ $flags = ord(substr($data, 3, 1));
+ if ($flags & 224) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: reserved bits are set');
+ }
+
+ // header is 10 bytes minimum. may be longer, though.
+ $headerLength = 10;
+ // extra fields, need to skip 'em
+ if ($flags & 4) {
+ if ($length - $headerLength - 2 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $extraLength = unpack('v', substr($data, 10, 2));
+ if ($length - $headerLength - 2 - $extraLength[1] < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $headerLength += $extraLength[1] + 2;
+ }
+ // file name, need to skip that
+ if ($flags & 8) {
+ if ($length - $headerLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $filenameLength = strpos(substr($data, $headerLength), chr(0));
+ if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $headerLength += $filenameLength + 1;
+ }
+ // comment, need to skip that also
+ if ($flags & 16) {
+ if ($length - $headerLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $commentLength = strpos(substr($data, $headerLength), chr(0));
+ if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $headerLength += $commentLength + 1;
+ }
+ // have a CRC for header. let's check
+ if ($flags & 2) {
+ if ($length - $headerLength - 2 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $crcReal = 0xffff & crc32(substr($data, 0, $headerLength));
+ $crcStored = unpack('v', substr($data, $headerLength, 2));
+ if ($crcReal != $crcStored[1]) {
+ throw new HTTP_Request2_Exception('Header CRC check failed');
+ }
+ $headerLength += 2;
+ }
+ // unpacked data CRC and size at the end of encoded data
+ $tmp = unpack('V2', substr($data, -8));
+ $dataCrc = $tmp[1];
+ $dataSize = $tmp[2];
+
+ // finally, call the gzinflate() function
+ // don't pass $dataSize to gzinflate, see bugs #13135, #14370
+ $unpacked = gzinflate(substr($data, $headerLength, -8));
+ if (false === $unpacked) {
+ throw new HTTP_Request2_Exception('gzinflate() call failed');
+ } elseif ($dataSize != strlen($unpacked)) {
+ throw new HTTP_Request2_Exception('Data size check failed');
+ } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
+ throw new HTTP_Request2_Exception('Data CRC check failed');
+ }
+ return $unpacked;
+ }
+
+ /**
+ * Decodes the message-body encoded by deflate
+ *
+ * @param string deflate-encoded data
+ * @return string decoded data
+ * @throws HTTP_Request2_Exception
+ */
+ public static function decodeDeflate($data)
+ {
+ if (!function_exists('gzuncompress')) {
+ throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
+ }
+ // RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
+ // while many applications send raw deflate stream from RFC 1951.
+ // We should check for presence of zlib header and use gzuncompress() or
+ // gzinflate() as needed. See bug #15305
+ $header = unpack('n', substr($data, 0, 2));
+ return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
+ }
+}
+?>
\ No newline at end of file
diff --git a/extlib/Net/URL2.php b/extlib/Net/URL2.php
index 7a654aed8..f7fbcd9ce 100644
--- a/extlib/Net/URL2.php
+++ b/extlib/Net/URL2.php
@@ -1,44 +1,58 @@
|
-// +-----------------------------------------------------------------------+
-//
-// $Id: URL2.php,v 1.10 2008/04/26 21:57:08 schmidt Exp $
-//
-// Net_URL2 Class (PHP5 Only)
-
-// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php
/**
- * @license BSD License
+ * Net_URL2, a class representing a URL as per RFC 3986.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2007-2009, Peytz & Co. A/S
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_LexerGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Networking
+ * @package Net_URL2
+ * @author Christian Schmidt
+ * @copyright 2007-2008 Peytz & Co. A/S
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: URL2.php 286661 2009-08-02 12:50:54Z schmidt $
+ * @link http://www.rfc-editor.org/rfc/rfc3986.txt
+ */
+
+/**
+ * Represents a URL as per RFC 3986.
+ *
+ * @category Networking
+ * @package Net_URL2
+ * @author Christian Schmidt
+ * @copyright 2007-2008 Peytz & Co. ApS
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/Net_URL2
*/
class Net_URL2
{
@@ -46,24 +60,24 @@ class Net_URL2
* Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
* is true.
*/
- const OPTION_STRICT = 'strict';
+ const OPTION_STRICT = 'strict';
/**
* Represent arrays in query using PHP's [] notation. Default is true.
*/
- const OPTION_USE_BRACKETS = 'use_brackets';
+ const OPTION_USE_BRACKETS = 'use_brackets';
/**
* URL-encode query variable keys. Default is true.
*/
- const OPTION_ENCODE_KEYS = 'encode_keys';
+ const OPTION_ENCODE_KEYS = 'encode_keys';
/**
* Query variable separators when parsing the query string. Every character
* is considered a separator. Default is specified by the
* arg_separator.input php.ini setting (this defaults to "&").
*/
- const OPTION_SEPARATOR_INPUT = 'input_separator';
+ const OPTION_SEPARATOR_INPUT = 'input_separator';
/**
* Query variable separator used when generating the query string. Default
@@ -75,7 +89,7 @@ class Net_URL2
/**
* Default options corresponds to how PHP handles $_GET.
*/
- private $options = array(
+ private $_options = array(
self::OPTION_STRICT => true,
self::OPTION_USE_BRACKETS => true,
self::OPTION_ENCODE_KEYS => true,
@@ -86,41 +100,43 @@ class Net_URL2
/**
* @var string|bool
*/
- private $scheme = false;
+ private $_scheme = false;
/**
* @var string|bool
*/
- private $userinfo = false;
+ private $_userinfo = false;
/**
* @var string|bool
*/
- private $host = false;
+ private $_host = false;
/**
* @var int|bool
*/
- private $port = false;
+ private $_port = false;
/**
* @var string
*/
- private $path = '';
+ private $_path = '';
/**
* @var string|bool
*/
- private $query = false;
+ private $_query = false;
/**
* @var string|bool
*/
- private $fragment = false;
+ private $_fragment = false;
/**
+ * Constructor.
+ *
* @param string $url an absolute or relative URL
- * @param array $options
+ * @param array $options an array of OPTION_xxx constants
*/
public function __construct($url, $options = null)
{
@@ -130,12 +146,12 @@ class Net_URL2
ini_get('arg_separator.output'));
if (is_array($options)) {
foreach ($options as $optionName => $value) {
- $this->setOption($optionName);
+ $this->setOption($optionName, $value);
}
}
if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
- $this->scheme = $reg[1];
+ $this->_scheme = $reg[1];
$url = substr($url, strlen($reg[0]));
}
@@ -145,19 +161,58 @@ class Net_URL2
}
$i = strcspn($url, '?#');
- $this->path = substr($url, 0, $i);
+ $this->_path = substr($url, 0, $i);
$url = substr($url, $i);
if (preg_match('@^\?([^#]*)@', $url, $reg)) {
- $this->query = $reg[1];
+ $this->_query = $reg[1];
$url = substr($url, strlen($reg[0]));
}
if ($url) {
- $this->fragment = substr($url, 1);
+ $this->_fragment = substr($url, 1);
}
}
+ /**
+ * Magic Setter.
+ *
+ * This method will magically set the value of a private variable ($var)
+ * with the value passed as the args
+ *
+ * @param string $var The private variable to set.
+ * @param mixed $arg An argument of any type.
+ * @return void
+ */
+ public function __set($var, $arg)
+ {
+ $method = 'set' . $var;
+ if (method_exists($this, $method)) {
+ $this->$method($arg);
+ }
+ }
+
+ /**
+ * Magic Getter.
+ *
+ * This is the magic get method to retrieve the private variable
+ * that was set by either __set() or it's setter...
+ *
+ * @param string $var The property name to retrieve.
+ * @return mixed $this->$var Either a boolean false if the
+ * property is not set or the value
+ * of the private property.
+ */
+ public function __get($var)
+ {
+ $method = 'get' . $var;
+ if (method_exists($this, $method)) {
+ return $this->$method();
+ }
+
+ return false;
+ }
+
/**
* Returns the scheme, e.g. "http" or "urn", or false if there is no
* scheme specified, i.e. if this is a relative URL.
@@ -166,18 +221,23 @@ class Net_URL2
*/
public function getScheme()
{
- return $this->scheme;
+ return $this->_scheme;
}
/**
- * @param string|bool $scheme
+ * Sets the scheme, e.g. "http" or "urn". Specify false if there is no
+ * scheme specified, i.e. if this is a relative URL.
+ *
+ * @param string|bool $scheme e.g. "http" or "urn", or false if there is no
+ * scheme specified, i.e. if this is a relative
+ * URL
*
* @return void
* @see getScheme()
*/
public function setScheme($scheme)
{
- $this->scheme = $scheme;
+ $this->_scheme = $scheme;
}
/**
@@ -188,7 +248,9 @@ class Net_URL2
*/
public function getUser()
{
- return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false;
+ return $this->_userinfo !== false
+ ? preg_replace('@:.*$@', '', $this->_userinfo)
+ : false;
}
/**
@@ -201,7 +263,9 @@ class Net_URL2
*/
public function getPassword()
{
- return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false;
+ return $this->_userinfo !== false
+ ? substr(strstr($this->_userinfo, ':'), 1)
+ : false;
}
/**
@@ -212,7 +276,7 @@ class Net_URL2
*/
public function getUserinfo()
{
- return $this->userinfo;
+ return $this->_userinfo;
}
/**
@@ -220,15 +284,15 @@ class Net_URL2
* in the userinfo part as username ":" password.
*
* @param string|bool $userinfo userinfo or username
- * @param string|bool $password
+ * @param string|bool $password optional password, or false
*
* @return void
*/
public function setUserinfo($userinfo, $password = false)
{
- $this->userinfo = $userinfo;
+ $this->_userinfo = $userinfo;
if ($password !== false) {
- $this->userinfo .= ':' . $password;
+ $this->_userinfo .= ':' . $password;
}
}
@@ -236,21 +300,24 @@ class Net_URL2
* Returns the host part, or false if there is no authority part, e.g.
* relative URLs.
*
- * @return string|bool
+ * @return string|bool a hostname, an IP address, or false
*/
public function getHost()
{
- return $this->host;
+ return $this->_host;
}
/**
- * @param string|bool $host
+ * Sets the host part. Specify false if there is no authority part, e.g.
+ * relative URLs.
+ *
+ * @param string|bool $host a hostname, an IP address, or false
*
* @return void
*/
public function setHost($host)
{
- $this->host = $host;
+ $this->_host = $host;
}
/**
@@ -261,65 +328,72 @@ class Net_URL2
*/
public function getPort()
{
- return $this->port;
+ return $this->_port;
}
/**
- * @param int|bool $port
+ * Sets the port number. Specify false if there is no port number specified,
+ * i.e. if the default port is to be used.
+ *
+ * @param int|bool $port a port number, or false
*
* @return void
*/
public function setPort($port)
{
- $this->port = intval($port);
+ $this->_port = intval($port);
}
/**
* Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
- * false if there is no authority none.
+ * false if there is no authority.
*
* @return string|bool
*/
public function getAuthority()
{
- if (!$this->host) {
+ if (!$this->_host) {
return false;
}
$authority = '';
- if ($this->userinfo !== false) {
- $authority .= $this->userinfo . '@';
+ if ($this->_userinfo !== false) {
+ $authority .= $this->_userinfo . '@';
}
- $authority .= $this->host;
+ $authority .= $this->_host;
- if ($this->port !== false) {
- $authority .= ':' . $this->port;
+ if ($this->_port !== false) {
+ $authority .= ':' . $this->_port;
}
return $authority;
}
/**
- * @param string|false $authority
+ * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
+ * false if there is no authority.
+ *
+ * @param string|false $authority a hostname or an IP addresse, possibly
+ * with userinfo prefixed and port number
+ * appended, e.g. "foo:bar@example.org:81".
*
* @return void
*/
public function setAuthority($authority)
{
- $this->user = false;
- $this->pass = false;
- $this->host = false;
- $this->port = false;
- if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
+ $this->_userinfo = false;
+ $this->_host = false;
+ $this->_port = false;
+ if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
if ($reg[1]) {
- $this->userinfo = $reg[2];
+ $this->_userinfo = $reg[2];
}
- $this->host = $reg[3];
+ $this->_host = $reg[3];
if (isset($reg[5])) {
- $this->port = intval($reg[5]);
+ $this->_port = intval($reg[5]);
}
}
}
@@ -331,65 +405,74 @@ class Net_URL2
*/
public function getPath()
{
- return $this->path;
+ return $this->_path;
}
/**
- * @param string $path
+ * Sets the path part (possibly an empty string).
+ *
+ * @param string $path a path
*
* @return void
*/
public function setPath($path)
{
- $this->path = $path;
+ $this->_path = $path;
}
/**
* Returns the query string (excluding the leading "?"), or false if "?"
- * isn't present in the URL.
+ * is not present in the URL.
*
* @return string|bool
* @see self::getQueryVariables()
*/
public function getQuery()
{
- return $this->query;
+ return $this->_query;
}
/**
- * @param string|bool $query
+ * Sets the query string (excluding the leading "?"). Specify false if "?"
+ * is not present in the URL.
+ *
+ * @param string|bool $query a query string, e.g. "foo=1&bar=2"
*
* @return void
* @see self::setQueryVariables()
*/
public function setQuery($query)
{
- $this->query = $query;
+ $this->_query = $query;
}
/**
- * Returns the fragment name, or false if "#" isn't present in the URL.
+ * Returns the fragment name, or false if "#" is not present in the URL.
*
* @return string|bool
*/
public function getFragment()
{
- return $this->fragment;
+ return $this->_fragment;
}
/**
- * @param string|bool $fragment
+ * Sets the fragment name. Specify false if "#" is not present in the URL.
+ *
+ * @param string|bool $fragment a fragment excluding the leading "#", or
+ * false
*
* @return void
*/
public function setFragment($fragment)
{
- $this->fragment = $fragment;
+ $this->_fragment = $fragment;
}
/**
* Returns the query string like an array as the variables would appear in
- * $_GET in a PHP script.
+ * $_GET in a PHP script. If the URL does not contain a "?", an empty array
+ * is returned.
*
* @return array
*/
@@ -398,7 +481,7 @@ class Net_URL2
$pattern = '/[' .
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
']/';
- $parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY);
+ $parts = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach ($parts as $part) {
@@ -445,6 +528,8 @@ class Net_URL2
}
/**
+ * Sets the query string to the specified variable in the query string.
+ *
* @param array $array (name => value) array
*
* @return void
@@ -452,11 +537,11 @@ class Net_URL2
public function setQueryVariables(array $array)
{
if (!$array) {
- $this->query = false;
+ $this->_query = false;
} else {
foreach ($array as $name => $value) {
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
- $name = rawurlencode($name);
+ $name = self::urlencode($name);
}
if (is_array($value)) {
@@ -466,19 +551,21 @@ class Net_URL2
: ($name . '=' . $v);
}
} elseif (!is_null($value)) {
- $parts[] = $name . '=' . $value;
+ $parts[] = $name . '=' . self::urlencode($value);
} else {
$parts[] = $name;
}
}
- $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
- $parts);
+ $this->_query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
+ $parts);
}
}
/**
- * @param string $name
- * @param mixed $value
+ * Sets the specified variable in the query string.
+ *
+ * @param string $name variable name
+ * @param mixed $value variable value
*
* @return array
*/
@@ -490,7 +577,9 @@ class Net_URL2
}
/**
- * @param string $name
+ * Removes the specifed variable from the query string.
+ *
+ * @param string $name a query string variable, e.g. "foo" in "?foo=1"
*
* @return void
*/
@@ -511,27 +600,38 @@ class Net_URL2
// See RFC 3986, section 5.3
$url = "";
- if ($this->scheme !== false) {
- $url .= $this->scheme . ':';
+ if ($this->_scheme !== false) {
+ $url .= $this->_scheme . ':';
}
$authority = $this->getAuthority();
if ($authority !== false) {
$url .= '//' . $authority;
}
- $url .= $this->path;
+ $url .= $this->_path;
- if ($this->query !== false) {
- $url .= '?' . $this->query;
+ if ($this->_query !== false) {
+ $url .= '?' . $this->_query;
}
- if ($this->fragment !== false) {
- $url .= '#' . $this->fragment;
+ if ($this->_fragment !== false) {
+ $url .= '#' . $this->_fragment;
}
return $url;
}
+ /**
+ * Returns a string representation of this URL.
+ *
+ * @return string
+ * @see toString()
+ */
+ public function __toString()
+ {
+ return $this->getURL();
+ }
+
/**
* Returns a normalized string representation of this URL. This is useful
* for comparison of URLs.
@@ -555,36 +655,38 @@ class Net_URL2
// See RFC 3886, section 6
// Schemes are case-insensitive
- if ($this->scheme) {
- $this->scheme = strtolower($this->scheme);
+ if ($this->_scheme) {
+ $this->_scheme = strtolower($this->_scheme);
}
// Hostnames are case-insensitive
- if ($this->host) {
- $this->host = strtolower($this->host);
+ if ($this->_host) {
+ $this->_host = strtolower($this->_host);
}
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
- if ($this->port &&
- $this->scheme &&
- $this->port == getservbyname($this->scheme, 'tcp')) {
+ if ($this->_port &&
+ $this->_scheme &&
+ $this->_port == getservbyname($this->_scheme, 'tcp')) {
- $this->port = false;
+ $this->_port = false;
}
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
- foreach (array('userinfo', 'host', 'path') as $part) {
+ foreach (array('_userinfo', '_host', '_path') as $part) {
if ($this->$part) {
- $this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part);
+ $this->$part = preg_replace('/%[0-9a-f]{2}/ie',
+ 'strtoupper("\0")',
+ $this->$part);
}
}
// Path segment normalization (RFC 3986, section 6.2.2.3)
- $this->path = self::removeDotSegments($this->path);
+ $this->_path = self::removeDotSegments($this->_path);
// Scheme based normalization (RFC 3986, section 6.2.3)
- if ($this->host && !$this->path) {
- $this->path = '/';
+ if ($this->_host && !$this->_path) {
+ $this->_path = '/';
}
}
@@ -595,7 +697,7 @@ class Net_URL2
*/
public function isAbsolute()
{
- return (bool) $this->scheme;
+ return (bool) $this->_scheme;
}
/**
@@ -608,7 +710,7 @@ class Net_URL2
*/
public function resolve($reference)
{
- if (is_string($reference)) {
+ if (!$reference instanceof Net_URL2) {
$reference = new self($reference);
}
if (!$this->isAbsolute()) {
@@ -617,54 +719,54 @@ class Net_URL2
// A non-strict parser may ignore a scheme in the reference if it is
// identical to the base URI's scheme.
- if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) {
- $reference->scheme = false;
+ if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
+ $reference->_scheme = false;
}
$target = new self('');
- if ($reference->scheme !== false) {
- $target->scheme = $reference->scheme;
+ if ($reference->_scheme !== false) {
+ $target->_scheme = $reference->_scheme;
$target->setAuthority($reference->getAuthority());
- $target->path = self::removeDotSegments($reference->path);
- $target->query = $reference->query;
+ $target->_path = self::removeDotSegments($reference->_path);
+ $target->_query = $reference->_query;
} else {
$authority = $reference->getAuthority();
if ($authority !== false) {
$target->setAuthority($authority);
- $target->path = self::removeDotSegments($reference->path);
- $target->query = $reference->query;
+ $target->_path = self::removeDotSegments($reference->_path);
+ $target->_query = $reference->_query;
} else {
- if ($reference->path == '') {
- $target->path = $this->path;
- if ($reference->query !== false) {
- $target->query = $reference->query;
+ if ($reference->_path == '') {
+ $target->_path = $this->_path;
+ if ($reference->_query !== false) {
+ $target->_query = $reference->_query;
} else {
- $target->query = $this->query;
+ $target->_query = $this->_query;
}
} else {
- if (substr($reference->path, 0, 1) == '/') {
- $target->path = self::removeDotSegments($reference->path);
+ if (substr($reference->_path, 0, 1) == '/') {
+ $target->_path = self::removeDotSegments($reference->_path);
} else {
// Merge paths (RFC 3986, section 5.2.3)
- if ($this->host !== false && $this->path == '') {
- $target->path = '/' . $this->path;
+ if ($this->_host !== false && $this->_path == '') {
+ $target->_path = '/' . $this->_path;
} else {
- $i = strrpos($this->path, '/');
+ $i = strrpos($this->_path, '/');
if ($i !== false) {
- $target->path = substr($this->path, 0, $i + 1);
+ $target->_path = substr($this->_path, 0, $i + 1);
}
- $target->path .= $reference->path;
+ $target->_path .= $reference->_path;
}
- $target->path = self::removeDotSegments($target->path);
+ $target->_path = self::removeDotSegments($target->_path);
}
- $target->query = $reference->query;
+ $target->_query = $reference->_query;
}
$target->setAuthority($this->getAuthority());
}
- $target->scheme = $this->scheme;
+ $target->_scheme = $this->_scheme;
}
- $target->fragment = $reference->fragment;
+ $target->_fragment = $reference->_fragment;
return $target;
}
@@ -677,7 +779,7 @@ class Net_URL2
*
* @return string a path
*/
- private static function removeDotSegments($path)
+ public static function removeDotSegments($path)
{
$output = '';
@@ -685,28 +787,25 @@ class Net_URL2
// method
$j = 0;
while ($path && $j++ < 100) {
- // Step A
if (substr($path, 0, 2) == './') {
+ // Step 2.A
$path = substr($path, 2);
} elseif (substr($path, 0, 3) == '../') {
+ // Step 2.A
$path = substr($path, 3);
-
- // Step B
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
+ // Step 2.B
$path = '/' . substr($path, 3);
-
- // Step C
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
- $path = '/' . substr($path, 4);
- $i = strrpos($output, '/');
+ // Step 2.C
+ $path = '/' . substr($path, 4);
+ $i = strrpos($output, '/');
$output = $i === false ? '' : substr($output, 0, $i);
-
- // Step D
} elseif ($path == '.' || $path == '..') {
+ // Step 2.D
$path = '';
-
- // Step E
} else {
+ // Step 2.E
$i = strpos($path, '/');
if ($i === 0) {
$i = strpos($path, '/', 1);
@@ -722,6 +821,22 @@ class Net_URL2
return $output;
}
+ /**
+ * Percent-encodes all non-alphanumeric characters except these: _ . - ~
+ * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
+ * 5.2.x and earlier.
+ *
+ * @param $raw the string to encode
+ * @return string
+ */
+ public static function urlencode($string)
+ {
+ $encoded = rawurlencode($string);
+ // This is only necessary in PHP < 5.3.
+ $encoded = str_replace('%7E', '~', $encoded);
+ return $encoded;
+ }
+
/**
* Returns a Net_URL2 instance representing the canonical URL of the
* currently executing PHP script.
@@ -737,13 +852,13 @@ class Net_URL2
// Begin with a relative URL
$url = new self($_SERVER['PHP_SELF']);
- $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
- $url->host = $_SERVER['SERVER_NAME'];
+ $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $url->_host = $_SERVER['SERVER_NAME'];
$port = intval($_SERVER['SERVER_PORT']);
- if ($url->scheme == 'http' && $port != 80 ||
- $url->scheme == 'https' && $port != 443) {
+ if ($url->_scheme == 'http' && $port != 80 ||
+ $url->_scheme == 'https' && $port != 443) {
- $url->port = $port;
+ $url->_port = $port;
}
return $url;
}
@@ -773,7 +888,7 @@ class Net_URL2
// Begin with a relative URL
$url = new self($_SERVER['REQUEST_URI']);
- $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
// Set host and possibly port
$url->setAuthority($_SERVER['HTTP_HOST']);
return $url;
@@ -792,10 +907,10 @@ class Net_URL2
*/
function setOption($optionName, $value)
{
- if (!array_key_exists($optionName, $this->options)) {
+ if (!array_key_exists($optionName, $this->_options)) {
return false;
}
- $this->options[$optionName] = $value;
+ $this->_options[$optionName] = $value;
}
/**
@@ -807,7 +922,7 @@ class Net_URL2
*/
function getOption($optionName)
{
- return isset($this->options[$optionName])
- ? $this->options[$optionName] : false;
+ return isset($this->_options[$optionName])
+ ? $this->_options[$optionName] : false;
}
}
diff --git a/install.php b/install.php
index 6bfc4c2e2..d34e92dab 100644
--- a/install.php
+++ b/install.php
@@ -93,6 +93,13 @@ $external_libraries=array(
'include'=>'HTTP/Request.php',
'check_class'=>'HTTP_Request'
),
+ array(
+ 'name'=>'HTTP_Request2',
+ 'pear'=>'HTTP_Request2',
+ 'url'=>'http://pear.php.net/package/HTTP_Request2',
+ 'include'=>'HTTP/Request2.php',
+ 'check_class'=>'HTTP_Request2'
+ ),
array(
'name'=>'Mail',
'pear'=>'Mail',
diff --git a/lib/Shorturl_api.php b/lib/Shorturl_api.php
index 18ae7719b..ef0d8dda4 100644
--- a/lib/Shorturl_api.php
+++ b/lib/Shorturl_api.php
@@ -41,22 +41,17 @@ abstract class ShortUrlApi
return strlen($url) >= common_config('site', 'shorturllength');
}
- protected function http_post($data) {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $this->service_url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
- $response = curl_exec($ch);
- $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- curl_close($ch);
- if (($code < 200) || ($code >= 400)) return false;
- return $response;
+ protected function http_post($data)
+ {
+ $request = new HTTPClient($this->service_url);
+ return $request->post($data);
}
- protected function http_get($url) {
- $encoded_url = urlencode($url);
- return file_get_contents("{$this->service_url}$encoded_url");
+ protected function http_get($url)
+ {
+ $service = $this->service_url . urlencode($url);
+ $request = new HTTPClient($service);
+ return $request->get();
}
protected function tidy($response) {
diff --git a/lib/curlclient.php b/lib/curlclient.php
deleted file mode 100644
index c307c2984..000000000
--- a/lib/curlclient.php
+++ /dev/null
@@ -1,179 +0,0 @@
-.
- *
- * @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @copyright 2009 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/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-define(CURLCLIENT_VERSION, "0.1");
-
-/**
- * Wrapper for Curl
- *
- * Makes Curl HTTP client calls within our HTTPClient framework
- *
- * @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class CurlClient extends HTTPClient
-{
- function __construct()
- {
- }
-
- function head($url, $headers=null)
- {
- $ch = curl_init($url);
-
- $this->setup($ch);
-
- curl_setopt_array($ch,
- array(CURLOPT_NOBODY => true));
-
- if (!is_null($headers)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- return $this->parseResults($result);
- }
-
- function get($url, $headers=null)
- {
- $ch = curl_init($url);
-
- $this->setup($ch);
-
- if (!is_null($headers)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- return $this->parseResults($result);
- }
-
- function post($url, $headers=null, $body=null)
- {
- $ch = curl_init($url);
-
- $this->setup($ch);
-
- curl_setopt($ch, CURLOPT_POST, true);
-
- if (!is_null($body)) {
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
-
- if (!is_null($headers)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- return $this->parseResults($result);
- }
-
- function setup($ch)
- {
- curl_setopt_array($ch,
- array(CURLOPT_USERAGENT => $this->userAgent(),
- CURLOPT_HEADER => true,
- CURLOPT_RETURNTRANSFER => true));
- }
-
- function userAgent()
- {
- $version = curl_version();
- return parent::userAgent() . " CurlClient/".CURLCLIENT_VERSION . " cURL/" . $version['version'];
- }
-
- function parseResults($results)
- {
- $resp = new HTTPResponse();
-
- $lines = explode("\r\n", $results);
-
- if (preg_match("#^HTTP/1.[01] (\d\d\d) .+$#", $lines[0], $match)) {
- $resp->code = $match[1];
- } else {
- throw Exception("Bad format: initial line is not HTTP status line");
- }
-
- $lastk = null;
-
- for ($i = 1; $i < count($lines); $i++) {
- $l =& $lines[$i];
- if (mb_strlen($l) == 0) {
- $resp->body = implode("\r\n", array_slice($lines, $i + 1));
- break;
- }
- if (preg_match("#^(\S+):\s+(.*)$#", $l, $match)) {
- $k = $match[1];
- $v = $match[2];
-
- if (array_key_exists($k, $resp->headers)) {
- if (is_array($resp->headers[$k])) {
- $resp->headers[$k][] = $v;
- } else {
- $resp->headers[$k] = array($resp->headers[$k], $v);
- }
- } else {
- $resp->headers[$k] = $v;
- }
- $lastk = $k;
- } else if (preg_match("#^\s+(.*)$#", $l, $match)) {
- // continuation line
- if (is_null($lastk)) {
- throw Exception("Bad format: initial whitespace in headers");
- }
- $h =& $resp->headers[$lastk];
- if (is_array($h)) {
- $n = count($h);
- $h[$n-1] .= $match[1];
- } else {
- $h .= $match[1];
- }
- }
- }
-
- return $resp;
- }
-}
diff --git a/lib/default.php b/lib/default.php
index 7ec8558b0..f6cc4b725 100644
--- a/lib/default.php
+++ b/lib/default.php
@@ -228,8 +228,6 @@ $default =
array('contentlimit' => null),
'message' =>
array('contentlimit' => null),
- 'http' =>
- array('client' => 'curl'), // XXX: should this be the default?
'location' =>
array('namespace' => 1), // 1 = geonames, 2 = Yahoo Where on Earth
);
diff --git a/lib/httpclient.php b/lib/httpclient.php
index f16e31e10..ee894e983 100644
--- a/lib/httpclient.php
+++ b/lib/httpclient.php
@@ -31,6 +31,9 @@ if (!defined('STATUSNET')) {
exit(1);
}
+require_once 'HTTP/Request2.php';
+require_once 'HTTP/Request2/Response.php';
+
/**
* Useful structure for HTTP responses
*
@@ -38,18 +41,42 @@ if (!defined('STATUSNET')) {
* ways of doing them. This class hides the specifics of what underlying
* library (curl or PHP-HTTP or whatever) that's used.
*
+ * This extends the HTTP_Request2_Response class with methods to get info
+ * about any followed redirects.
+ *
* @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
+ * @package StatusNet
+ * @author Evan Prodromou
+ * @author Brion Vibber
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
*/
-
-class HTTPResponse
+class HTTPResponse extends HTTP_Request2_Response
{
- public $code = null;
- public $headers = array();
- public $body = null;
+ function __construct(HTTP_Request2_Response $response, $url, $redirects=0)
+ {
+ foreach (get_object_vars($response) as $key => $val) {
+ $this->$key = $val;
+ }
+ $this->url = strval($url);
+ $this->redirectCount = intval($redirects);
+ }
+
+ /**
+ * Get the count of redirects that have been followed, if any.
+ * @return int
+ */
+ function getRedirectCount() {
+ return $this->redirectCount;
+ }
+
+ /**
+ * Gets the final target URL, after any redirects have been followed.
+ * @return string URL
+ */
+ function getUrl() {
+ return $this->url;
+ }
}
/**
@@ -59,64 +86,133 @@ class HTTPResponse
* ways of doing them. This class hides the specifics of what underlying
* library (curl or PHP-HTTP or whatever) that's used.
*
+ * This extends the PEAR HTTP_Request2 package:
+ * - sends StatusNet-specific User-Agent header
+ * - 'follow_redirects' config option, defaulting off
+ * - 'max_redirs' config option, defaulting to 10
+ * - extended response class adds getRedirectCount() and getUrl() methods
+ * - get() and post() convenience functions return body content directly
+ *
* @category HTTP
* @package StatusNet
* @author Evan Prodromou
+ * @author Brion Vibber
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
-class HTTPClient
+class HTTPClient extends HTTP_Request2
{
- static $_client = null;
- static function start()
+ function __construct($url=null, $method=self::METHOD_GET, $config=array())
{
- if (!is_null(self::$_client)) {
- return self::$_client;
- }
-
- $type = common_config('http', 'client');
-
- switch ($type) {
- case 'curl':
- self::$_client = new CurlClient();
- break;
- default:
- throw new Exception("Unknown HTTP client type '$type'");
- break;
- }
-
- return self::$_client;
+ $this->config['max_redirs'] = 10;
+ $this->config['follow_redirects'] = false;
+ parent::__construct($url, $method, $config);
+ $this->setHeader('User-Agent', $this->userAgent());
}
- function head($url, $headers)
+ /**
+ * Convenience function to run a get request and return the response body.
+ * Use when you don't need to get into details of the response.
+ *
+ * @return mixed string on success, false on failure
+ */
+ function get()
{
- throw new Exception("HEAD method unimplemented");
+ $this->setMethod(self::METHOD_GET);
+ return $this->doRequest();
}
- function get($url, $headers)
+ /**
+ * Convenience function to post form data and return the response body.
+ * Use when you don't need to get into details of the response.
+ *
+ * @param array associative array of form data to submit
+ * @return mixed string on success, false on failure
+ */
+ public function post($data=array())
{
- throw new Exception("GET method unimplemented");
+ $this->setMethod(self::METHOD_POST);
+ if ($data) {
+ $this->addPostParameter($data);
+ }
+ return $this->doRequest();
}
- function post($url, $headers, $body)
+ /**
+ * @return mixed string on success, false on failure
+ */
+ protected function doRequest()
{
- throw new Exception("POST method unimplemented");
+ try {
+ $response = $this->send();
+ $code = $response->getStatus();
+ if (($code < 200) || ($code >= 400)) {
+ return false;
+ }
+ return $response->getBody();
+ } catch (HTTP_Request2_Exception $e) {
+ $this->log(LOG_ERR, $e->getMessage());
+ return false;
+ }
}
-
- function put($url, $headers, $body)
- {
- throw new Exception("PUT method unimplemented");
+
+ protected function log($level, $detail) {
+ $method = $this->getMethod();
+ $url = $this->getUrl();
+ common_log($level, __CLASS__ . ": HTTP $method $url - $detail");
}
- function delete($url, $headers)
+ /**
+ * Pulls up StatusNet's customized user-agent string, so services
+ * we hit can track down the responsible software.
+ */
+ function userAgent()
{
- throw new Exception("DELETE method unimplemented");
+ return "StatusNet/".STATUSNET_VERSION." (".STATUSNET_CODENAME.")";
}
- function userAgent()
+ function send()
{
- return "StatusNet/".STATUSNET_VERSION." (".STATUSNET_CODENAME.")";
+ $maxRedirs = intval($this->config['max_redirs']);
+ if (empty($this->config['follow_redirects'])) {
+ $maxRedirs = 0;
+ }
+ $redirs = 0;
+ do {
+ try {
+ $response = parent::send();
+ } catch (HTTP_Request2_Exception $e) {
+ $this->log(LOG_ERR, $e->getMessage());
+ throw $e;
+ }
+ $code = $response->getStatus();
+ if ($code >= 200 && $code < 300) {
+ $reason = $response->getReasonPhrase();
+ $this->log(LOG_INFO, "$code $reason");
+ } elseif ($code >= 300 && $code < 400) {
+ $url = $this->getUrl();
+ $target = $response->getHeader('Location');
+
+ if (++$redirs >= $maxRedirs) {
+ common_log(LOG_ERR, __CLASS__ . ": Too many redirects: skipping $code redirect from $url to $target");
+ break;
+ }
+ try {
+ $this->setUrl($target);
+ $this->setHeader('Referer', $url);
+ common_log(LOG_INFO, __CLASS__ . ": Following $code redirect from $url to $target");
+ continue;
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_ERR, __CLASS__ . ": Invalid $code redirect from $url to $target");
+ }
+ } else {
+ $reason = $response->getReasonPhrase();
+ $this->log(LOG_ERR, "$code $reason");
+ }
+ break;
+ } while ($maxRedirs);
+ return new HTTPResponse($response, $this->getUrl(), $redirs);
}
}
diff --git a/lib/oauthclient.php b/lib/oauthclient.php
index f1827726e..1a86e2460 100644
--- a/lib/oauthclient.php
+++ b/lib/oauthclient.php
@@ -43,7 +43,7 @@ require_once 'OAuth.php';
* @link http://status.net/
*
*/
-class OAuthClientCurlException extends Exception
+class OAuthClientException extends Exception
{
}
@@ -97,9 +97,14 @@ class OAuthClient
function getRequestToken($url)
{
$response = $this->oAuthGet($url);
- parse_str($response);
- $token = new OAuthToken($oauth_token, $oauth_token_secret);
- return $token;
+ $arr = array();
+ parse_str($response, $arr);
+ if (isset($arr['oauth_token']) && isset($arr['oauth_token_secret'])) {
+ $token = new OAuthToken($arr['oauth_token'], @$arr['oauth_token_secret']);
+ return $token;
+ } else {
+ throw new OAuthClientException();
+ }
}
/**
@@ -177,7 +182,7 @@ class OAuthClient
}
/**
- * Make a HTTP request using cURL.
+ * Make a HTTP request.
*
* @param string $url Where to make the
* @param array $params post parameters
@@ -186,40 +191,32 @@ class OAuthClient
*/
function httpRequest($url, $params = null)
{
- $options = array(
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FAILONERROR => true,
- CURLOPT_HEADER => false,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_USERAGENT => 'StatusNet',
- CURLOPT_CONNECTTIMEOUT => 120,
- CURLOPT_TIMEOUT => 120,
- CURLOPT_HTTPAUTH => CURLAUTH_ANY,
- CURLOPT_SSL_VERIFYPEER => false,
-
- // Twitter is strict about accepting invalid "Expect" headers
-
- CURLOPT_HTTPHEADER => array('Expect:')
- );
+ $request = new HTTPClient($url);
+ $request->setConfig(array(
+ 'connect_timeout' => 120,
+ 'timeout' => 120,
+ 'follow_redirects' => true,
+ 'ssl_verify_peer' => false,
+ ));
+
+ // Twitter is strict about accepting invalid "Expect" headers
+ $request->setHeader('Expect', '');
if (isset($params)) {
- $options[CURLOPT_POST] = true;
- $options[CURLOPT_POSTFIELDS] = $params;
+ $request->setMethod(HTTP_Request2::METHOD_POST);
+ $request->setBody($params);
}
- $ch = curl_init($url);
- curl_setopt_array($ch, $options);
- $response = curl_exec($ch);
-
- if ($response === false) {
- $msg = curl_error($ch);
- $code = curl_errno($ch);
- throw new OAuthClientCurlException($msg, $code);
+ try {
+ $response = $request->send();
+ $code = $response->getStatus();
+ if ($code < 200 || $code >= 400) {
+ throw new OAuthClientException($response->getBody(), $code);
+ }
+ return $response->getBody();
+ } catch (Exception $e) {
+ throw new OAuthClientException($e->getMessage(), $e->getCode());
}
-
- curl_close($ch);
-
- return $response;
}
}
diff --git a/lib/ping.php b/lib/ping.php
index 175bf8440..2797c1b2d 100644
--- a/lib/ping.php
+++ b/lib/ping.php
@@ -44,20 +44,18 @@ function ping_broadcast_notice($notice) {
array('nickname' => $profile->nickname)),
$tags));
- $context = stream_context_create(array('http' => array('method' => "POST",
- 'header' =>
- "Content-Type: text/xml\r\n".
- "User-Agent: StatusNet/".STATUSNET_VERSION."\r\n",
- 'content' => $req)));
- $file = file_get_contents($notify_url, false, $context);
+ $request = new HTTPClient($notify_url, HTTP_Request2::METHOD_POST);
+ $request->setHeader('Content-Type', 'text/xml');
+ $request->setBody($req);
+ $httpResponse = $request->send();
- if ($file === false || mb_strlen($file) == 0) {
+ if (!$httpResponse || mb_strlen($httpResponse->getBody()) == 0) {
common_log(LOG_WARNING,
"XML-RPC empty results for ping ($notify_url, $notice->id) ");
continue;
}
- $response = xmlrpc_decode($file);
+ $response = xmlrpc_decode($httpResponse->getBody());
if (is_array($response) && xmlrpc_is_fault($response)) {
common_log(LOG_WARNING,
diff --git a/lib/snapshot.php b/lib/snapshot.php
index ede846e5b..6829e8a75 100644
--- a/lib/snapshot.php
+++ b/lib/snapshot.php
@@ -172,26 +172,11 @@ class Snapshot
{
// XXX: Use OICU2 and OAuth to make authorized requests
- $postdata = http_build_query($this->stats);
-
- $opts =
- array('http' =>
- array(
- 'method' => 'POST',
- 'header' => 'Content-type: '.
- 'application/x-www-form-urlencoded',
- 'content' => $postdata,
- 'user_agent' => 'StatusNet/'.STATUSNET_VERSION
- )
- );
-
- $context = stream_context_create($opts);
-
$reporturl = common_config('snapshot', 'reporturl');
- $result = @file_get_contents($reporturl, false, $context);
-
- return $result;
+ $request = new HTTPClient($reporturl, HTTP_Request2::METHOD_POST);
+ $request->addPostParameter($this->stats);
+ $request->send();
}
/**
diff --git a/plugins/BlogspamNetPlugin.php b/plugins/BlogspamNetPlugin.php
index c14569746..3bdc73556 100644
--- a/plugins/BlogspamNetPlugin.php
+++ b/plugins/BlogspamNetPlugin.php
@@ -22,6 +22,7 @@
* @category Plugin
* @package StatusNet
* @author Evan Prodromou
+ * @author Brion Vibber
* @copyright 2009 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/
@@ -69,14 +70,14 @@ class BlogspamNetPlugin extends Plugin
{
$args = $this->testArgs($notice);
common_debug("Blogspamnet args = " . print_r($args, TRUE));
- $request = xmlrpc_encode_request('testComment', array($args));
- $context = stream_context_create(array('http' => array('method' => "POST",
- 'header' =>
- "Content-Type: text/xml\r\n".
- "User-Agent: " . $this->userAgent(),
- 'content' => $request)));
- $file = file_get_contents($this->baseUrl, false, $context);
- $response = xmlrpc_decode($file);
+ $requestBody = xmlrpc_encode_request('testComment', array($args));
+
+ $request = new HTTPClient($this->baseUrl, HTTP_Request2::METHOD_POST);
+ $request->addHeader('Content-Type: text/xml');
+ $request->setBody($requestBody);
+ $httpResponse = $request->send();
+
+ $response = xmlrpc_decode($httpResponse->getBody());
if (xmlrpc_is_fault($response)) {
throw new ServerException("$response[faultString] ($response[faultCode])", 500);
} else {
diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php
index 60f7a60c7..0513687e9 100644
--- a/plugins/LinkbackPlugin.php
+++ b/plugins/LinkbackPlugin.php
@@ -129,27 +129,25 @@ class LinkbackPlugin extends Plugin
}
}
- $request = xmlrpc_encode_request('pingback.ping', $args);
- $context = stream_context_create(array('http' => array('method' => "POST",
- 'header' =>
- "Content-Type: text/xml\r\n".
- "User-Agent: " . $this->userAgent(),
- 'content' => $request)));
- $file = file_get_contents($endpoint, false, $context);
- if (!$file) {
+ $request = new HTTPClient($endpoint, 'POST');
+ $request->setHeader('User-Agent', $this->userAgent());
+ $request->setHeader('Content-Type', 'text/xml');
+ $request->setBody(xmlrpc_encode_request('pingback.ping', $args));
+ try {
+ $response = $request->send();
+ } catch (HTTP_Request2_Exception $e) {
common_log(LOG_WARNING,
- "Pingback request failed for '$url' ($endpoint)");
+ "Pingback request failed for '$url' ($endpoint)");
+ }
+ $response = xmlrpc_decode($response->getBody());
+ if (xmlrpc_is_fault($response)) {
+ common_log(LOG_WARNING,
+ "Pingback error for '$url' ($endpoint): ".
+ "$response[faultString] ($response[faultCode])");
} else {
- $response = xmlrpc_decode($file);
- if (xmlrpc_is_fault($response)) {
- common_log(LOG_WARNING,
- "Pingback error for '$url' ($endpoint): ".
- "$response[faultString] ($response[faultCode])");
- } else {
- common_log(LOG_INFO,
- "Pingback success for '$url' ($endpoint): ".
- "'$response'");
- }
+ common_log(LOG_INFO,
+ "Pingback success for '$url' ($endpoint): ".
+ "'$response'");
}
}
diff --git a/plugins/SimpleUrl/SimpleUrlPlugin.php b/plugins/SimpleUrl/SimpleUrlPlugin.php
index 82d772048..d59d63e47 100644
--- a/plugins/SimpleUrl/SimpleUrlPlugin.php
+++ b/plugins/SimpleUrl/SimpleUrlPlugin.php
@@ -65,15 +65,6 @@ class SimpleUrlPlugin extends Plugin
class SimpleUrl extends ShortUrlApi
{
protected function shorten_imp($url) {
- $curlh = curl_init();
- curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
- curl_setopt($curlh, CURLOPT_USERAGENT, 'StatusNet');
- curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
-
- curl_setopt($curlh, CURLOPT_URL, $this->service_url.urlencode($url));
- $short_url = curl_exec($curlh);
-
- curl_close($curlh);
- return $short_url;
+ return $this->http_get($url);
}
}
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index ed2bf48a2..671e3c7af 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -152,8 +152,8 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
$friends_ids = $client->friendsIds();
} catch (Exception $e) {
common_log(LOG_WARNING, $this->name() .
- ' - cURL error getting friend ids ' .
- $e->getCode() . ' - ' . $e->getMessage());
+ ' - error getting friend ids: ' .
+ $e->getMessage());
return $friends;
}
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index 81bbbc7c5..6c91b2860 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -109,12 +109,16 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$flink->find();
$flinks = array();
+ common_log(LOG_INFO, "hello");
while ($flink->fetch()) {
if (($flink->noticesync & FOREIGN_NOTICE_RECV) ==
FOREIGN_NOTICE_RECV) {
$flinks[] = clone($flink);
+ common_log(LOG_INFO, "sync: foreign id $flink->foreign_id");
+ } else {
+ common_log(LOG_INFO, "nothing to sync");
}
}
@@ -515,31 +519,34 @@ class TwitterStatusFetcher extends ParallelizingDaemon
return $id;
}
+ /**
+ * Fetch a remote avatar image and save to local storage.
+ *
+ * @param string $url avatar source URL
+ * @param string $filename bare local filename for download
+ * @return bool true on success, false on failure
+ */
function fetchAvatar($url, $filename)
{
- $avatarfile = Avatar::path($filename);
+ common_debug($this->name() . " - Fetching Twitter avatar: $url");
- $out = fopen($avatarfile, 'wb');
- if (!$out) {
- common_log(LOG_WARNING, $this->name() .
- " - Couldn't open file $filename");
+ $request = new HTTPClient($url, 'GET', array(
+ 'follow_redirects' => true,
+ ));
+ $data = $request->get();
+ if ($data) {
+ $avatarfile = Avatar::path($filename);
+ $ok = file_put_contents($avatarfile, $data);
+ if (!$ok) {
+ common_log(LOG_WARNING, $this->name() .
+ " - Couldn't open file $filename");
+ return false;
+ }
+ } else {
return false;
}
- common_debug($this->name() . " - Fetching Twitter avatar: $url");
-
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_FILE, $out);
- curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
- $result = curl_exec($ch);
- curl_close($ch);
-
- fclose($out);
-
- return $result;
+ return true;
}
}
diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php
index 1a5248a9b..3c6803e49 100644
--- a/plugins/TwitterBridge/twitter.php
+++ b/plugins/TwitterBridge/twitter.php
@@ -215,7 +215,7 @@ function broadcast_basicauth($notice, $flink)
try {
$status = $client->statusesUpdate($statustxt);
- } catch (BasicAuthCurlException $e) {
+ } catch (HTTP_Request2_Exception $e) {
return process_error($e, $flink);
}
diff --git a/plugins/TwitterBridge/twitterauthorization.php b/plugins/TwitterBridge/twitterauthorization.php
index 2a93ff13e..f1daefab1 100644
--- a/plugins/TwitterBridge/twitterauthorization.php
+++ b/plugins/TwitterBridge/twitterauthorization.php
@@ -125,7 +125,7 @@ class TwitterauthorizationAction extends Action
$auth_link = $client->getAuthorizeLink($req_tok);
- } catch (TwitterOAuthClientException $e) {
+ } catch (OAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage());
$this->serverError(_('Couldn\'t link your Twitter account.'));
diff --git a/plugins/TwitterBridge/twitterbasicauthclient.php b/plugins/TwitterBridge/twitterbasicauthclient.php
index 1040d72fb..e4cae7373 100644
--- a/plugins/TwitterBridge/twitterbasicauthclient.php
+++ b/plugins/TwitterBridge/twitterbasicauthclient.php
@@ -31,26 +31,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
-/**
- * Exception wrapper for cURL errors
- *
- * @category Integration
- * @package StatusNet
- * @author Adrian Lang
- * @author Brenda Wallace
- * @author Craig Andrews
- * @author Dan Moore
- * @author Evan Prodromou
- * @author mEDI
- * @author Sarven Capadisli
- * @author Zach Copley * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- */
-class BasicAuthCurlException extends Exception
-{
-}
-
/**
* Class for talking to the Twitter API with HTTP Basic Auth.
*
@@ -198,45 +178,27 @@ class TwitterBasicAuthClient
*/
function httpRequest($url, $params = null, $auth = true)
{
- $options = array(
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FAILONERROR => true,
- CURLOPT_HEADER => false,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_USERAGENT => 'StatusNet',
- CURLOPT_CONNECTTIMEOUT => 120,
- CURLOPT_TIMEOUT => 120,
- CURLOPT_HTTPAUTH => CURLAUTH_ANY,
- CURLOPT_SSL_VERIFYPEER => false,
-
- // Twitter is strict about accepting invalid "Expect" headers
-
- CURLOPT_HTTPHEADER => array('Expect:')
- );
+ $request = new HTTPClient($url, 'GET', array(
+ 'follow_redirects' => true,
+ 'connect_timeout' => 120,
+ 'timeout' => 120,
+ 'ssl_verifypeer' => false,
+ ));
+
+ // Twitter is strict about accepting invalid "Expect" headers
+ $request->setHeader('Expect', '');
if (isset($params)) {
- $options[CURLOPT_POST] = true;
- $options[CURLOPT_POSTFIELDS] = $params;
+ $request->setMethod('POST');
+ $request->addPostParameter($params);
}
if ($auth) {
- $options[CURLOPT_USERPWD] = $this->screen_name .
- ':' . $this->password;
+ $request->setAuth($this->screen_name, $this->password);
}
- $ch = curl_init($url);
- curl_setopt_array($ch, $options);
- $response = curl_exec($ch);
-
- if ($response === false) {
- $msg = curl_error($ch);
- $code = curl_errno($ch);
- throw new BasicAuthCurlException($msg, $code);
- }
-
- curl_close($ch);
-
- return $response;
+ $response = $request->send();
+ return $response->getBody();
}
}
diff --git a/plugins/WikiHashtagsPlugin.php b/plugins/WikiHashtagsPlugin.php
index 0c5649aa4..a9e675f5c 100644
--- a/plugins/WikiHashtagsPlugin.php
+++ b/plugins/WikiHashtagsPlugin.php
@@ -68,10 +68,8 @@ class WikiHashtagsPlugin extends Plugin
$editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit',
urlencode($tag));
- $context = stream_context_create(array('http' => array('method' => "GET",
- 'header' =>
- "User-Agent: " . $this->userAgent())));
- $html = @file_get_contents($url, false, $context);
+ $request = new HTTPClient($url);
+ $html = $request->get();
$action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section'));
@@ -100,10 +98,4 @@ class WikiHashtagsPlugin extends Plugin
return true;
}
-
- function userAgent()
- {
- return 'WikiHashtagsPlugin/'.WIKIHASHTAGSPLUGIN_VERSION .
- ' StatusNet/' . STATUSNET_VERSION;
- }
}
diff --git a/scripts/enjitqueuehandler.php b/scripts/enjitqueuehandler.php
index 08f733b07..214cc02b4 100755
--- a/scripts/enjitqueuehandler.php
+++ b/scripts/enjitqueuehandler.php
@@ -46,8 +46,8 @@ class EnjitQueueHandler extends QueueHandler
function start()
{
- $this->log(LOG_INFO, "Starting EnjitQueueHandler");
- $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
+ $this->log(LOG_INFO, "Starting EnjitQueueHandler");
+ $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
return true;
}
@@ -56,16 +56,16 @@ class EnjitQueueHandler extends QueueHandler
$profile = Profile::staticGet($notice->profile_id);
- $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
+ $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
- if ( ! $notice->is_local ) {
- $this->log(LOG_INFO, "Skipping remote notice");
- return "skipped";
- }
+ if ( ! $notice->is_local ) {
+ $this->log(LOG_INFO, "Skipping remote notice");
+ return "skipped";
+ }
- #
- # Build an Atom message from the notice
- #
+ #
+ # Build an Atom message from the notice
+ #
$noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
$msg = $profile->nickname . ': ' . $notice->content;
@@ -86,36 +86,20 @@ class EnjitQueueHandler extends QueueHandler
$atom .= "".common_date_w3dtf($notice->modified)."\n";
$atom .= "\n";
- $url = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
- $data = "msg=$atom";
-
- #
- # POST the message to $config['enjit']['apiurl']
- #
- $ch = curl_init();
-
- curl_setopt($ch, CURLOPT_URL, $url);
-
- curl_setopt($ch, CURLOPT_HEADER, 1);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1) ;
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
-
- # SSL and Debugging options
- #
- # curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
- # curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
- # curl_setopt($ch, CURLOPT_VERBOSE, 1);
-
- $result = curl_exec($ch);
-
- $code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
-
- $this->log(LOG_INFO, "Response Code: $code");
-
- curl_close($ch);
-
- return $code;
+ $url = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
+ $data = array(
+ 'msg' => $atom,
+ );
+
+ #
+ # POST the message to $config['enjit']['apiurl']
+ #
+ $request = new HTTPClient($url, HTTP_Request2::METHOD_POST);
+ $request->addPostFields($data);
+ $response = $request->send();
+
+ // @fixme handle_notice() is supposed to return true/false. Somethin' funky?
+ return $response->getStatus();
}
}
--
cgit v1.2.3-54-g00ecf
From b22fc5b74aecd505d4e2df01258171fc65d312cf Mon Sep 17 00:00:00 2001
From: Brion Vibber
Date: Mon, 2 Nov 2009 06:56:31 -0800
Subject: Revert "Rebuilt HTTPClient class as an extension of PEAR
HTTP_Request2 package, adding redirect handling and convenience functions."
Going to restructure a little more before finalizing this...
This reverts commit fa37967858c3c29000797e510e5f98aca8ab558f.
---
classes/File_redirection.php | 68 +-
extlib/HTTP/Request2.php | 844 ------------------
extlib/HTTP/Request2/Adapter.php | 152 ----
extlib/HTTP/Request2/Adapter/Curl.php | 383 --------
extlib/HTTP/Request2/Adapter/Mock.php | 171 ----
extlib/HTTP/Request2/Adapter/Socket.php | 971 ---------------------
extlib/HTTP/Request2/Exception.php | 62 --
extlib/HTTP/Request2/MultipartBody.php | 274 ------
extlib/HTTP/Request2/Observer/Log.php | 215 -----
extlib/HTTP/Request2/Response.php | 549 ------------
extlib/Net/URL2.php | 471 ++++------
install.php | 7 -
lib/Shorturl_api.php | 23 +-
lib/curlclient.php | 179 ++++
lib/default.php | 2 +
lib/httpclient.php | 180 +---
lib/oauthclient.php | 65 +-
lib/ping.php | 14 +-
lib/snapshot.php | 21 +-
plugins/BlogspamNetPlugin.php | 17 +-
plugins/LinkbackPlugin.php | 36 +-
plugins/SimpleUrl/SimpleUrlPlugin.php | 11 +-
.../TwitterBridge/daemons/synctwitterfriends.php | 4 +-
.../TwitterBridge/daemons/twitterstatusfetcher.php | 45 +-
plugins/TwitterBridge/twitter.php | 2 +-
plugins/TwitterBridge/twitterauthorization.php | 2 +-
plugins/TwitterBridge/twitterbasicauthclient.php | 66 +-
plugins/WikiHashtagsPlugin.php | 12 +-
scripts/enjitqueuehandler.php | 64 +-
29 files changed, 669 insertions(+), 4241 deletions(-)
delete mode 100644 extlib/HTTP/Request2.php
delete mode 100644 extlib/HTTP/Request2/Adapter.php
delete mode 100644 extlib/HTTP/Request2/Adapter/Curl.php
delete mode 100644 extlib/HTTP/Request2/Adapter/Mock.php
delete mode 100644 extlib/HTTP/Request2/Adapter/Socket.php
delete mode 100644 extlib/HTTP/Request2/Exception.php
delete mode 100644 extlib/HTTP/Request2/MultipartBody.php
delete mode 100644 extlib/HTTP/Request2/Observer/Log.php
delete mode 100644 extlib/HTTP/Request2/Response.php
create mode 100644 lib/curlclient.php
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/classes/File_redirection.php b/classes/File_redirection.php
index b7945699a..79052bf7d 100644
--- a/classes/File_redirection.php
+++ b/classes/File_redirection.php
@@ -47,15 +47,18 @@ class File_redirection extends Memcached_DataObject
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
- static function _commonHttp($url, $redirs) {
- $request = new HTTPClient($url);
- $request->setConfig(array(
- 'connect_timeout' => 10, // # seconds to wait
- 'max_redirs' => $redirs, // # max number of http redirections to follow
- 'follow_redirects' => true, // Follow redirects
- 'store_body' => false, // We won't need body content here.
- ));
- return $request;
+ function _commonCurl($url, $redirs) {
+ $curlh = curl_init();
+ curl_setopt($curlh, CURLOPT_URL, $url);
+ curl_setopt($curlh, CURLOPT_AUTOREFERER, true); // # setup referer header when folowing redirects
+ curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 10); // # seconds to wait
+ curl_setopt($curlh, CURLOPT_MAXREDIRS, $redirs); // # max number of http redirections to follow
+ curl_setopt($curlh, CURLOPT_USERAGENT, USER_AGENT);
+ curl_setopt($curlh, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
+ curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curlh, CURLOPT_FILETIME, true);
+ curl_setopt($curlh, CURLOPT_HEADER, true); // Include header in output
+ return $curlh;
}
function _redirectWhere_imp($short_url, $redirs = 10, $protected = false) {
@@ -79,39 +82,32 @@ class File_redirection extends Memcached_DataObject
if(strpos($short_url,'://') === false){
return $short_url;
}
- try {
- $request = self::_commonHttp($short_url, $redirs);
- // Don't include body in output
- $request->setMethod(HTTP_Request2::METHOD_HEAD);
- $response = $request->send();
-
- if (405 == $response->getCode()) {
- // Server doesn't support HEAD method? Can this really happen?
- // We'll try again as a GET and ignore the response data.
- $request = self::_commonHttp($short_url, $redirs);
- $response = $request->send();
- }
- } catch (Exception $e) {
- // Invalid URL or failure to reach server
- return $short_url;
+ $curlh = File_redirection::_commonCurl($short_url, $redirs);
+ // Don't include body in output
+ curl_setopt($curlh, CURLOPT_NOBODY, true);
+ curl_exec($curlh);
+ $info = curl_getinfo($curlh);
+ curl_close($curlh);
+
+ if (405 == $info['http_code']) {
+ $curlh = File_redirection::_commonCurl($short_url, $redirs);
+ curl_exec($curlh);
+ $info = curl_getinfo($curlh);
+ curl_close($curlh);
}
- if ($response->getRedirectCount() && File::isProtected($response->getUrl())) {
- // Bump back up the redirect chain until we find a non-protected URL
- return self::_redirectWhere_imp($short_url, $response->getRedirectCount() - 1, true);
+ if (!empty($info['redirect_count']) && File::isProtected($info['url'])) {
+ return File_redirection::_redirectWhere_imp($short_url, $info['redirect_count'] - 1, true);
}
- $ret = array('code' => $response->getCode()
- , 'redirects' => $response->getRedirectCount()
- , 'url' => $response->getUrl());
+ $ret = array('code' => $info['http_code']
+ , 'redirects' => $info['redirect_count']
+ , 'url' => $info['url']);
- $type = $response->getHeader('Content-Type');
- if ($type) $ret['type'] = $type;
+ if (!empty($info['content_type'])) $ret['type'] = $info['content_type'];
if ($protected) $ret['protected'] = true;
- $size = $request->getHeader('Content-Length'); // @fixme bytes?
- if ($size) $ret['size'] = $size;
- $time = $request->getHeader('Last-Modified');
- if ($time) $ret['time'] = strtotime($time);
+ if (!empty($info['download_content_length'])) $ret['size'] = $info['download_content_length'];
+ if (isset($info['filetime']) && ($info['filetime'] > 0)) $ret['time'] = $info['filetime'];
return $ret;
}
diff --git a/extlib/HTTP/Request2.php b/extlib/HTTP/Request2.php
deleted file mode 100644
index e06bb86bc..000000000
--- a/extlib/HTTP/Request2.php
+++ /dev/null
@@ -1,844 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Request2.php 278226 2009-04-03 21:32:48Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * A class representing an URL as per RFC 3986.
- */
-require_once 'Net/URL2.php';
-
-/**
- * Exception class for HTTP_Request2 package
- */
-require_once 'HTTP/Request2/Exception.php';
-
-/**
- * Class representing a HTTP request
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- * @link http://tools.ietf.org/html/rfc2616#section-5
- */
-class HTTP_Request2 implements SplSubject
-{
- /**#@+
- * Constants for HTTP request methods
- *
- * @link http://tools.ietf.org/html/rfc2616#section-5.1.1
- */
- const METHOD_OPTIONS = 'OPTIONS';
- const METHOD_GET = 'GET';
- const METHOD_HEAD = 'HEAD';
- const METHOD_POST = 'POST';
- const METHOD_PUT = 'PUT';
- const METHOD_DELETE = 'DELETE';
- const METHOD_TRACE = 'TRACE';
- const METHOD_CONNECT = 'CONNECT';
- /**#@-*/
-
- /**#@+
- * Constants for HTTP authentication schemes
- *
- * @link http://tools.ietf.org/html/rfc2617
- */
- const AUTH_BASIC = 'basic';
- const AUTH_DIGEST = 'digest';
- /**#@-*/
-
- /**
- * Regular expression used to check for invalid symbols in RFC 2616 tokens
- * @link http://pear.php.net/bugs/bug.php?id=15630
- */
- const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!';
-
- /**
- * Regular expression used to check for invalid symbols in cookie strings
- * @link http://pear.php.net/bugs/bug.php?id=15630
- * @link http://cgi.netscape.com/newsref/std/cookie_spec.html
- */
- const REGEXP_INVALID_COOKIE = '/[\s,;]/';
-
- /**
- * Fileinfo magic database resource
- * @var resource
- * @see detectMimeType()
- */
- private static $_fileinfoDb;
-
- /**
- * Observers attached to the request (instances of SplObserver)
- * @var array
- */
- protected $observers = array();
-
- /**
- * Request URL
- * @var Net_URL2
- */
- protected $url;
-
- /**
- * Request method
- * @var string
- */
- protected $method = self::METHOD_GET;
-
- /**
- * Authentication data
- * @var array
- * @see getAuth()
- */
- protected $auth;
-
- /**
- * Request headers
- * @var array
- */
- protected $headers = array();
-
- /**
- * Configuration parameters
- * @var array
- * @see setConfig()
- */
- protected $config = array(
- 'adapter' => 'HTTP_Request2_Adapter_Socket',
- 'connect_timeout' => 10,
- 'timeout' => 0,
- 'use_brackets' => true,
- 'protocol_version' => '1.1',
- 'buffer_size' => 16384,
- 'store_body' => true,
-
- 'proxy_host' => '',
- 'proxy_port' => '',
- 'proxy_user' => '',
- 'proxy_password' => '',
- 'proxy_auth_scheme' => self::AUTH_BASIC,
-
- 'ssl_verify_peer' => true,
- 'ssl_verify_host' => true,
- 'ssl_cafile' => null,
- 'ssl_capath' => null,
- 'ssl_local_cert' => null,
- 'ssl_passphrase' => null,
-
- 'digest_compat_ie' => false
- );
-
- /**
- * Last event in request / response handling, intended for observers
- * @var array
- * @see getLastEvent()
- */
- protected $lastEvent = array(
- 'name' => 'start',
- 'data' => null
- );
-
- /**
- * Request body
- * @var string|resource
- * @see setBody()
- */
- protected $body = '';
-
- /**
- * Array of POST parameters
- * @var array
- */
- protected $postParams = array();
-
- /**
- * Array of file uploads (for multipart/form-data POST requests)
- * @var array
- */
- protected $uploads = array();
-
- /**
- * Adapter used to perform actual HTTP request
- * @var HTTP_Request2_Adapter
- */
- protected $adapter;
-
-
- /**
- * Constructor. Can set request URL, method and configuration array.
- *
- * Also sets a default value for User-Agent header.
- *
- * @param string|Net_Url2 Request URL
- * @param string Request method
- * @param array Configuration for this Request instance
- */
- public function __construct($url = null, $method = self::METHOD_GET, array $config = array())
- {
- if (!empty($url)) {
- $this->setUrl($url);
- }
- if (!empty($method)) {
- $this->setMethod($method);
- }
- $this->setConfig($config);
- $this->setHeader('user-agent', 'HTTP_Request2/0.4.1 ' .
- '(http://pear.php.net/package/http_request2) ' .
- 'PHP/' . phpversion());
- }
-
- /**
- * Sets the URL for this request
- *
- * If the URL has userinfo part (username & password) these will be removed
- * and converted to auth data. If the URL does not have a path component,
- * that will be set to '/'.
- *
- * @param string|Net_URL2 Request URL
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception
- */
- public function setUrl($url)
- {
- if (is_string($url)) {
- $url = new Net_URL2($url);
- }
- if (!$url instanceof Net_URL2) {
- throw new HTTP_Request2_Exception('Parameter is not a valid HTTP URL');
- }
- // URL contains username / password?
- if ($url->getUserinfo()) {
- $username = $url->getUser();
- $password = $url->getPassword();
- $this->setAuth(rawurldecode($username), $password? rawurldecode($password): '');
- $url->setUserinfo('');
- }
- if ('' == $url->getPath()) {
- $url->setPath('/');
- }
- $this->url = $url;
-
- return $this;
- }
-
- /**
- * Returns the request URL
- *
- * @return Net_URL2
- */
- public function getUrl()
- {
- return $this->url;
- }
-
- /**
- * Sets the request method
- *
- * @param string
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception if the method name is invalid
- */
- public function setMethod($method)
- {
- // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1
- if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) {
- throw new HTTP_Request2_Exception("Invalid request method '{$method}'");
- }
- $this->method = $method;
-
- return $this;
- }
-
- /**
- * Returns the request method
- *
- * @return string
- */
- public function getMethod()
- {
- return $this->method;
- }
-
- /**
- * Sets the configuration parameter(s)
- *
- * The following parameters are available:
- *
- * - 'adapter' - adapter to use (string)
- * - 'connect_timeout' - Connection timeout in seconds (integer)
- * - 'timeout' - Total number of seconds a request can take.
- * Use 0 for no limit, should be greater than
- * 'connect_timeout' if set (integer)
- * - 'use_brackets' - Whether to append [] to array variable names (bool)
- * - 'protocol_version' - HTTP Version to use, '1.0' or '1.1' (string)
- * - 'buffer_size' - Buffer size to use for reading and writing (int)
- * - 'store_body' - Whether to store response body in response object.
- * Set to false if receiving a huge response and
- * using an Observer to save it (boolean)
- * - 'proxy_host' - Proxy server host (string)
- * - 'proxy_port' - Proxy server port (integer)
- * - 'proxy_user' - Proxy auth username (string)
- * - 'proxy_password' - Proxy auth password (string)
- * - 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)
- * - 'ssl_verify_peer' - Whether to verify peer's SSL certificate (bool)
- * - 'ssl_verify_host' - Whether to check that Common Name in SSL
- * certificate matches host name (bool)
- * - 'ssl_cafile' - Cerificate Authority file to verify the peer
- * with (use with 'ssl_verify_peer') (string)
- * - 'ssl_capath' - Directory holding multiple Certificate
- * Authority files (string)
- * - 'ssl_local_cert' - Name of a file containing local cerificate (string)
- * - 'ssl_passphrase' - Passphrase with which local certificate
- * was encoded (string)
- * - 'digest_compat_ie' - Whether to imitate behaviour of MSIE 5 and 6
- * in using URL without query string in digest
- * authentication (boolean)
- *
- *
- * @param string|array configuration parameter name or array
- * ('parameter name' => 'parameter value')
- * @param mixed parameter value if $nameOrConfig is not an array
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception If the parameter is unknown
- */
- public function setConfig($nameOrConfig, $value = null)
- {
- if (is_array($nameOrConfig)) {
- foreach ($nameOrConfig as $name => $value) {
- $this->setConfig($name, $value);
- }
-
- } else {
- if (!array_key_exists($nameOrConfig, $this->config)) {
- throw new HTTP_Request2_Exception(
- "Unknown configuration parameter '{$nameOrConfig}'"
- );
- }
- $this->config[$nameOrConfig] = $value;
- }
-
- return $this;
- }
-
- /**
- * Returns the value(s) of the configuration parameter(s)
- *
- * @param string parameter name
- * @return mixed value of $name parameter, array of all configuration
- * parameters if $name is not given
- * @throws HTTP_Request2_Exception If the parameter is unknown
- */
- public function getConfig($name = null)
- {
- if (null === $name) {
- return $this->config;
- } elseif (!array_key_exists($name, $this->config)) {
- throw new HTTP_Request2_Exception(
- "Unknown configuration parameter '{$name}'"
- );
- }
- return $this->config[$name];
- }
-
- /**
- * Sets the autentification data
- *
- * @param string user name
- * @param string password
- * @param string authentication scheme
- * @return HTTP_Request2
- */
- public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC)
- {
- if (empty($user)) {
- $this->auth = null;
- } else {
- $this->auth = array(
- 'user' => (string)$user,
- 'password' => (string)$password,
- 'scheme' => $scheme
- );
- }
-
- return $this;
- }
-
- /**
- * Returns the authentication data
- *
- * The array has the keys 'user', 'password' and 'scheme', where 'scheme'
- * is one of the HTTP_Request2::AUTH_* constants.
- *
- * @return array
- */
- public function getAuth()
- {
- return $this->auth;
- }
-
- /**
- * Sets request header(s)
- *
- * The first parameter may be either a full header string 'header: value' or
- * header name. In the former case $value parameter is ignored, in the latter
- * the header's value will either be set to $value or the header will be
- * removed if $value is null. The first parameter can also be an array of
- * headers, in that case method will be called recursively.
- *
- * Note that headers are treated case insensitively as per RFC 2616.
- *
- *
- * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar'
- * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz'
- * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux'
- * $req->setHeader('FOO'); // removes 'Foo' header from request
- *
- *
- * @param string|array header name, header string ('Header: value')
- * or an array of headers
- * @param string|null header value, header will be removed if null
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception
- */
- public function setHeader($name, $value = null)
- {
- if (is_array($name)) {
- foreach ($name as $k => $v) {
- if (is_string($k)) {
- $this->setHeader($k, $v);
- } else {
- $this->setHeader($v);
- }
- }
- } else {
- if (null === $value && strpos($name, ':')) {
- list($name, $value) = array_map('trim', explode(':', $name, 2));
- }
- // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2
- if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) {
- throw new HTTP_Request2_Exception("Invalid header name '{$name}'");
- }
- // Header names are case insensitive anyway
- $name = strtolower($name);
- if (null === $value) {
- unset($this->headers[$name]);
- } else {
- $this->headers[$name] = $value;
- }
- }
-
- return $this;
- }
-
- /**
- * Returns the request headers
- *
- * The array is of the form ('header name' => 'header value'), header names
- * are lowercased
- *
- * @return array
- */
- public function getHeaders()
- {
- return $this->headers;
- }
-
- /**
- * Appends a cookie to "Cookie:" header
- *
- * @param string cookie name
- * @param string cookie value
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception
- */
- public function addCookie($name, $value)
- {
- $cookie = $name . '=' . $value;
- if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
- throw new HTTP_Request2_Exception("Invalid cookie: '{$cookie}'");
- }
- $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
- $this->setHeader('cookie', $cookies . $cookie);
-
- return $this;
- }
-
- /**
- * Sets the request body
- *
- * @param string Either a string with the body or filename containing body
- * @param bool Whether first parameter is a filename
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception
- */
- public function setBody($body, $isFilename = false)
- {
- if (!$isFilename) {
- $this->body = (string)$body;
- } else {
- if (!($fp = @fopen($body, 'rb'))) {
- throw new HTTP_Request2_Exception("Cannot open file {$body}");
- }
- $this->body = $fp;
- if (empty($this->headers['content-type'])) {
- $this->setHeader('content-type', self::detectMimeType($body));
- }
- }
-
- return $this;
- }
-
- /**
- * Returns the request body
- *
- * @return string|resource|HTTP_Request2_MultipartBody
- */
- public function getBody()
- {
- if (self::METHOD_POST == $this->method &&
- (!empty($this->postParams) || !empty($this->uploads))
- ) {
- if ('application/x-www-form-urlencoded' == $this->headers['content-type']) {
- $body = http_build_query($this->postParams, '', '&');
- if (!$this->getConfig('use_brackets')) {
- $body = preg_replace('/%5B\d+%5D=/', '=', $body);
- }
- // support RFC 3986 by not encoding '~' symbol (request #15368)
- return str_replace('%7E', '~', $body);
-
- } elseif ('multipart/form-data' == $this->headers['content-type']) {
- require_once 'HTTP/Request2/MultipartBody.php';
- return new HTTP_Request2_MultipartBody(
- $this->postParams, $this->uploads, $this->getConfig('use_brackets')
- );
- }
- }
- return $this->body;
- }
-
- /**
- * Adds a file to form-based file upload
- *
- * Used to emulate file upload via a HTML form. The method also sets
- * Content-Type of HTTP request to 'multipart/form-data'.
- *
- * If you just want to send the contents of a file as the body of HTTP
- * request you should use setBody() method.
- *
- * @param string name of file-upload field
- * @param mixed full name of local file
- * @param string filename to send in the request
- * @param string content-type of file being uploaded
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception
- */
- public function addUpload($fieldName, $filename, $sendFilename = null,
- $contentType = null)
- {
- if (!is_array($filename)) {
- if (!($fp = @fopen($filename, 'rb'))) {
- throw new HTTP_Request2_Exception("Cannot open file {$filename}");
- }
- $this->uploads[$fieldName] = array(
- 'fp' => $fp,
- 'filename' => empty($sendFilename)? basename($filename): $sendFilename,
- 'size' => filesize($filename),
- 'type' => empty($contentType)? self::detectMimeType($filename): $contentType
- );
- } else {
- $fps = $names = $sizes = $types = array();
- foreach ($filename as $f) {
- if (!is_array($f)) {
- $f = array($f);
- }
- if (!($fp = @fopen($f[0], 'rb'))) {
- throw new HTTP_Request2_Exception("Cannot open file {$f[0]}");
- }
- $fps[] = $fp;
- $names[] = empty($f[1])? basename($f[0]): $f[1];
- $sizes[] = filesize($f[0]);
- $types[] = empty($f[2])? self::detectMimeType($f[0]): $f[2];
- }
- $this->uploads[$fieldName] = array(
- 'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types
- );
- }
- if (empty($this->headers['content-type']) ||
- 'application/x-www-form-urlencoded' == $this->headers['content-type']
- ) {
- $this->setHeader('content-type', 'multipart/form-data');
- }
-
- return $this;
- }
-
- /**
- * Adds POST parameter(s) to the request.
- *
- * @param string|array parameter name or array ('name' => 'value')
- * @param mixed parameter value (can be an array)
- * @return HTTP_Request2
- */
- public function addPostParameter($name, $value = null)
- {
- if (!is_array($name)) {
- $this->postParams[$name] = $value;
- } else {
- foreach ($name as $k => $v) {
- $this->addPostParameter($k, $v);
- }
- }
- if (empty($this->headers['content-type'])) {
- $this->setHeader('content-type', 'application/x-www-form-urlencoded');
- }
-
- return $this;
- }
-
- /**
- * Attaches a new observer
- *
- * @param SplObserver
- */
- public function attach(SplObserver $observer)
- {
- foreach ($this->observers as $attached) {
- if ($attached === $observer) {
- return;
- }
- }
- $this->observers[] = $observer;
- }
-
- /**
- * Detaches an existing observer
- *
- * @param SplObserver
- */
- public function detach(SplObserver $observer)
- {
- foreach ($this->observers as $key => $attached) {
- if ($attached === $observer) {
- unset($this->observers[$key]);
- return;
- }
- }
- }
-
- /**
- * Notifies all observers
- */
- public function notify()
- {
- foreach ($this->observers as $observer) {
- $observer->update($this);
- }
- }
-
- /**
- * Sets the last event
- *
- * Adapters should use this method to set the current state of the request
- * and notify the observers.
- *
- * @param string event name
- * @param mixed event data
- */
- public function setLastEvent($name, $data = null)
- {
- $this->lastEvent = array(
- 'name' => $name,
- 'data' => $data
- );
- $this->notify();
- }
-
- /**
- * Returns the last event
- *
- * Observers should use this method to access the last change in request.
- * The following event names are possible:
- *
- * - 'connect' - after connection to remote server,
- * data is the destination (string)
- * - 'disconnect' - after disconnection from server
- * - 'sentHeaders' - after sending the request headers,
- * data is the headers sent (string)
- * - 'sentBodyPart' - after sending a part of the request body,
- * data is the length of that part (int)
- * - 'receivedHeaders' - after receiving the response headers,
- * data is HTTP_Request2_Response object
- * - 'receivedBodyPart' - after receiving a part of the response
- * body, data is that part (string)
- * - 'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still
- * encoded by Content-Encoding
- * - 'receivedBody' - after receiving the complete response
- * body, data is HTTP_Request2_Response object
- *
- * Different adapters may not send all the event types. Mock adapter does
- * not send any events to the observers.
- *
- * @return array The array has two keys: 'name' and 'data'
- */
- public function getLastEvent()
- {
- return $this->lastEvent;
- }
-
- /**
- * Sets the adapter used to actually perform the request
- *
- * You can pass either an instance of a class implementing HTTP_Request2_Adapter
- * or a class name. The method will only try to include a file if the class
- * name starts with HTTP_Request2_Adapter_, it will also try to prepend this
- * prefix to the class name if it doesn't contain any underscores, so that
- *
- * $request->setAdapter('curl');
- *
- * will work.
- *
- * @param string|HTTP_Request2_Adapter
- * @return HTTP_Request2
- * @throws HTTP_Request2_Exception
- */
- public function setAdapter($adapter)
- {
- if (is_string($adapter)) {
- if (!class_exists($adapter, false)) {
- if (false === strpos($adapter, '_')) {
- $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter);
- }
- if (preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter)) {
- include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php';
- }
- if (!class_exists($adapter, false)) {
- throw new HTTP_Request2_Exception("Class {$adapter} not found");
- }
- }
- $adapter = new $adapter;
- }
- if (!$adapter instanceof HTTP_Request2_Adapter) {
- throw new HTTP_Request2_Exception('Parameter is not a HTTP request adapter');
- }
- $this->adapter = $adapter;
-
- return $this;
- }
-
- /**
- * Sends the request and returns the response
- *
- * @throws HTTP_Request2_Exception
- * @return HTTP_Request2_Response
- */
- public function send()
- {
- // Sanity check for URL
- if (!$this->url instanceof Net_URL2) {
- throw new HTTP_Request2_Exception('No URL given');
- } elseif (!$this->url->isAbsolute()) {
- throw new HTTP_Request2_Exception('Absolute URL required');
- } elseif (!in_array(strtolower($this->url->getScheme()), array('https', 'http'))) {
- throw new HTTP_Request2_Exception('Not a HTTP URL');
- }
- if (empty($this->adapter)) {
- $this->setAdapter($this->getConfig('adapter'));
- }
- // magic_quotes_runtime may break file uploads and chunked response
- // processing; see bug #4543
- if ($magicQuotes = ini_get('magic_quotes_runtime')) {
- ini_set('magic_quotes_runtime', false);
- }
- // force using single byte encoding if mbstring extension overloads
- // strlen() and substr(); see bug #1781, bug #10605
- if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
- $oldEncoding = mb_internal_encoding();
- mb_internal_encoding('iso-8859-1');
- }
-
- try {
- $response = $this->adapter->sendRequest($this);
- } catch (Exception $e) {
- }
- // cleanup in either case (poor man's "finally" clause)
- if ($magicQuotes) {
- ini_set('magic_quotes_runtime', true);
- }
- if (!empty($oldEncoding)) {
- mb_internal_encoding($oldEncoding);
- }
- // rethrow the exception
- if (!empty($e)) {
- throw $e;
- }
- return $response;
- }
-
- /**
- * Tries to detect MIME type of a file
- *
- * The method will try to use fileinfo extension if it is available,
- * deprecated mime_content_type() function in the other case. If neither
- * works, default 'application/octet-stream' MIME type is returned
- *
- * @param string filename
- * @return string file MIME type
- */
- protected static function detectMimeType($filename)
- {
- // finfo extension from PECL available
- if (function_exists('finfo_open')) {
- if (!isset(self::$_fileinfoDb)) {
- self::$_fileinfoDb = @finfo_open(FILEINFO_MIME);
- }
- if (self::$_fileinfoDb) {
- $info = finfo_file(self::$_fileinfoDb, $filename);
- }
- }
- // (deprecated) mime_content_type function available
- if (empty($info) && function_exists('mime_content_type')) {
- return mime_content_type($filename);
- }
- return empty($info)? 'application/octet-stream': $info;
- }
-}
-?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Adapter.php b/extlib/HTTP/Request2/Adapter.php
deleted file mode 100644
index 39b092b34..000000000
--- a/extlib/HTTP/Request2/Adapter.php
+++ /dev/null
@@ -1,152 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Adapter.php 274684 2009-01-26 23:07:27Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Class representing a HTTP response
- */
-require_once 'HTTP/Request2/Response.php';
-
-/**
- * Base class for HTTP_Request2 adapters
- *
- * HTTP_Request2 class itself only defines methods for aggregating the request
- * data, all actual work of sending the request to the remote server and
- * receiving its response is performed by adapters.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- */
-abstract class HTTP_Request2_Adapter
-{
- /**
- * A list of methods that MUST NOT have a request body, per RFC 2616
- * @var array
- */
- protected static $bodyDisallowed = array('TRACE');
-
- /**
- * Methods having defined semantics for request body
- *
- * Content-Length header (indicating that the body follows, section 4.3 of
- * RFC 2616) will be sent for these methods even if no body was added
- *
- * @var array
- * @link http://pear.php.net/bugs/bug.php?id=12900
- * @link http://pear.php.net/bugs/bug.php?id=14740
- */
- protected static $bodyRequired = array('POST', 'PUT');
-
- /**
- * Request being sent
- * @var HTTP_Request2
- */
- protected $request;
-
- /**
- * Request body
- * @var string|resource|HTTP_Request2_MultipartBody
- * @see HTTP_Request2::getBody()
- */
- protected $requestBody;
-
- /**
- * Length of the request body
- * @var integer
- */
- protected $contentLength;
-
- /**
- * Sends request to the remote server and returns its response
- *
- * @param HTTP_Request2
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- abstract public function sendRequest(HTTP_Request2 $request);
-
- /**
- * Calculates length of the request body, adds proper headers
- *
- * @param array associative array of request headers, this method will
- * add proper 'Content-Length' and 'Content-Type' headers
- * to this array (or remove them if not needed)
- */
- protected function calculateRequestLength(&$headers)
- {
- $this->requestBody = $this->request->getBody();
-
- if (is_string($this->requestBody)) {
- $this->contentLength = strlen($this->requestBody);
- } elseif (is_resource($this->requestBody)) {
- $stat = fstat($this->requestBody);
- $this->contentLength = $stat['size'];
- rewind($this->requestBody);
- } else {
- $this->contentLength = $this->requestBody->getLength();
- $headers['content-type'] = 'multipart/form-data; boundary=' .
- $this->requestBody->getBoundary();
- $this->requestBody->rewind();
- }
-
- if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
- 0 == $this->contentLength
- ) {
- unset($headers['content-type']);
- // No body: send a Content-Length header nonetheless (request #12900),
- // but do that only for methods that require a body (bug #14740)
- if (in_array($this->request->getMethod(), self::$bodyRequired)) {
- $headers['content-length'] = 0;
- } else {
- unset($headers['content-length']);
- }
- } else {
- if (empty($headers['content-type'])) {
- $headers['content-type'] = 'application/x-www-form-urlencoded';
- }
- $headers['content-length'] = $this->contentLength;
- }
- }
-}
-?>
diff --git a/extlib/HTTP/Request2/Adapter/Curl.php b/extlib/HTTP/Request2/Adapter/Curl.php
deleted file mode 100644
index 4d4de0dcc..000000000
--- a/extlib/HTTP/Request2/Adapter/Curl.php
+++ /dev/null
@@ -1,383 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Curl.php 278226 2009-04-03 21:32:48Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Base class for HTTP_Request2 adapters
- */
-require_once 'HTTP/Request2/Adapter.php';
-
-/**
- * Adapter for HTTP_Request2 wrapping around cURL extension
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- */
-class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
-{
- /**
- * Mapping of header names to cURL options
- * @var array
- */
- protected static $headerMap = array(
- 'accept-encoding' => CURLOPT_ENCODING,
- 'cookie' => CURLOPT_COOKIE,
- 'referer' => CURLOPT_REFERER,
- 'user-agent' => CURLOPT_USERAGENT
- );
-
- /**
- * Mapping of SSL context options to cURL options
- * @var array
- */
- protected static $sslContextMap = array(
- 'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
- 'ssl_cafile' => CURLOPT_CAINFO,
- 'ssl_capath' => CURLOPT_CAPATH,
- 'ssl_local_cert' => CURLOPT_SSLCERT,
- 'ssl_passphrase' => CURLOPT_SSLCERTPASSWD
- );
-
- /**
- * Response being received
- * @var HTTP_Request2_Response
- */
- protected $response;
-
- /**
- * Whether 'sentHeaders' event was sent to observers
- * @var boolean
- */
- protected $eventSentHeaders = false;
-
- /**
- * Whether 'receivedHeaders' event was sent to observers
- * @var boolean
- */
- protected $eventReceivedHeaders = false;
-
- /**
- * Position within request body
- * @var integer
- * @see callbackReadBody()
- */
- protected $position = 0;
-
- /**
- * Information about last transfer, as returned by curl_getinfo()
- * @var array
- */
- protected $lastInfo;
-
- /**
- * Sends request to the remote server and returns its response
- *
- * @param HTTP_Request2
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- public function sendRequest(HTTP_Request2 $request)
- {
- if (!extension_loaded('curl')) {
- throw new HTTP_Request2_Exception('cURL extension not available');
- }
-
- $this->request = $request;
- $this->response = null;
- $this->position = 0;
- $this->eventSentHeaders = false;
- $this->eventReceivedHeaders = false;
-
- try {
- if (false === curl_exec($ch = $this->createCurlHandle())) {
- $errorMessage = 'Error sending request: #' . curl_errno($ch) .
- ' ' . curl_error($ch);
- }
- } catch (Exception $e) {
- }
- $this->lastInfo = curl_getinfo($ch);
- curl_close($ch);
-
- if (!empty($e)) {
- throw $e;
- } elseif (!empty($errorMessage)) {
- throw new HTTP_Request2_Exception($errorMessage);
- }
-
- if (0 < $this->lastInfo['size_download']) {
- $this->request->setLastEvent('receivedBody', $this->response);
- }
- return $this->response;
- }
-
- /**
- * Returns information about last transfer
- *
- * @return array associative array as returned by curl_getinfo()
- */
- public function getInfo()
- {
- return $this->lastInfo;
- }
-
- /**
- * Creates a new cURL handle and populates it with data from the request
- *
- * @return resource a cURL handle, as created by curl_init()
- * @throws HTTP_Request2_Exception
- */
- protected function createCurlHandle()
- {
- $ch = curl_init();
-
- curl_setopt_array($ch, array(
- // setup callbacks
- CURLOPT_READFUNCTION => array($this, 'callbackReadBody'),
- CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
- CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'),
- // disallow redirects
- CURLOPT_FOLLOWLOCATION => false,
- // buffer size
- CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'),
- // connection timeout
- CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
- // save full outgoing headers, in case someone is interested
- CURLINFO_HEADER_OUT => true,
- // request url
- CURLOPT_URL => $this->request->getUrl()->getUrl()
- ));
-
- // request timeout
- if ($timeout = $this->request->getConfig('timeout')) {
- curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
- }
-
- // set HTTP version
- switch ($this->request->getConfig('protocol_version')) {
- case '1.0':
- curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- break;
- case '1.1':
- curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- }
-
- // set request method
- switch ($this->request->getMethod()) {
- case HTTP_Request2::METHOD_GET:
- curl_setopt($ch, CURLOPT_HTTPGET, true);
- break;
- case HTTP_Request2::METHOD_POST:
- curl_setopt($ch, CURLOPT_POST, true);
- break;
- default:
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
- }
-
- // set proxy, if needed
- if ($host = $this->request->getConfig('proxy_host')) {
- if (!($port = $this->request->getConfig('proxy_port'))) {
- throw new HTTP_Request2_Exception('Proxy port not provided');
- }
- curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
- if ($user = $this->request->getConfig('proxy_user')) {
- curl_setopt($ch, CURLOPT_PROXYUSERPWD, $user . ':' .
- $this->request->getConfig('proxy_password'));
- switch ($this->request->getConfig('proxy_auth_scheme')) {
- case HTTP_Request2::AUTH_BASIC:
- curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
- break;
- case HTTP_Request2::AUTH_DIGEST:
- curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
- }
- }
- }
-
- // set authentication data
- if ($auth = $this->request->getAuth()) {
- curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
- switch ($auth['scheme']) {
- case HTTP_Request2::AUTH_BASIC:
- curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
- break;
- case HTTP_Request2::AUTH_DIGEST:
- curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
- }
- }
-
- // set SSL options
- if (0 == strcasecmp($this->request->getUrl()->getScheme(), 'https')) {
- foreach ($this->request->getConfig() as $name => $value) {
- if ('ssl_verify_host' == $name && null !== $value) {
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
- } elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
- curl_setopt($ch, self::$sslContextMap[$name], $value);
- }
- }
- }
-
- $headers = $this->request->getHeaders();
- // make cURL automagically send proper header
- if (!isset($headers['accept-encoding'])) {
- $headers['accept-encoding'] = '';
- }
-
- // set headers having special cURL keys
- foreach (self::$headerMap as $name => $option) {
- if (isset($headers[$name])) {
- curl_setopt($ch, $option, $headers[$name]);
- unset($headers[$name]);
- }
- }
-
- $this->calculateRequestLength($headers);
-
- // set headers not having special keys
- $headersFmt = array();
- foreach ($headers as $name => $value) {
- $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
- $headersFmt[] = $canonicalName . ': ' . $value;
- }
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
-
- return $ch;
- }
-
- /**
- * Callback function called by cURL for reading the request body
- *
- * @param resource cURL handle
- * @param resource file descriptor (not used)
- * @param integer maximum length of data to return
- * @return string part of the request body, up to $length bytes
- */
- protected function callbackReadBody($ch, $fd, $length)
- {
- if (!$this->eventSentHeaders) {
- $this->request->setLastEvent(
- 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
- );
- $this->eventSentHeaders = true;
- }
- if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
- 0 == $this->contentLength || $this->position >= $this->contentLength
- ) {
- return '';
- }
- if (is_string($this->requestBody)) {
- $string = substr($this->requestBody, $this->position, $length);
- } elseif (is_resource($this->requestBody)) {
- $string = fread($this->requestBody, $length);
- } else {
- $string = $this->requestBody->read($length);
- }
- $this->request->setLastEvent('sentBodyPart', strlen($string));
- $this->position += strlen($string);
- return $string;
- }
-
- /**
- * Callback function called by cURL for saving the response headers
- *
- * @param resource cURL handle
- * @param string response header (with trailing CRLF)
- * @return integer number of bytes saved
- * @see HTTP_Request2_Response::parseHeaderLine()
- */
- protected function callbackWriteHeader($ch, $string)
- {
- // we may receive a second set of headers if doing e.g. digest auth
- if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
- // don't bother with 100-Continue responses (bug #15785)
- if (!$this->eventSentHeaders ||
- $this->response->getStatus() >= 200
- ) {
- $this->request->setLastEvent(
- 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
- );
- }
- $this->eventSentHeaders = true;
- // we'll need a new response object
- if ($this->eventReceivedHeaders) {
- $this->eventReceivedHeaders = false;
- $this->response = null;
- }
- }
- if (empty($this->response)) {
- $this->response = new HTTP_Request2_Response($string, false);
- } else {
- $this->response->parseHeaderLine($string);
- if ('' == trim($string)) {
- // don't bother with 100-Continue responses (bug #15785)
- if (200 <= $this->response->getStatus()) {
- $this->request->setLastEvent('receivedHeaders', $this->response);
- }
- $this->eventReceivedHeaders = true;
- }
- }
- return strlen($string);
- }
-
- /**
- * Callback function called by cURL for saving the response body
- *
- * @param resource cURL handle (not used)
- * @param string part of the response body
- * @return integer number of bytes saved
- * @see HTTP_Request2_Response::appendBody()
- */
- protected function callbackWriteBody($ch, $string)
- {
- // cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
- // response doesn't start with proper HTTP status line (see bug #15716)
- if (empty($this->response)) {
- throw new HTTP_Request2_Exception("Malformed response: {$string}");
- }
- if ($this->request->getConfig('store_body')) {
- $this->response->appendBody($string);
- }
- $this->request->setLastEvent('receivedBodyPart', $string);
- return strlen($string);
- }
-}
-?>
diff --git a/extlib/HTTP/Request2/Adapter/Mock.php b/extlib/HTTP/Request2/Adapter/Mock.php
deleted file mode 100644
index 89688003b..000000000
--- a/extlib/HTTP/Request2/Adapter/Mock.php
+++ /dev/null
@@ -1,171 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Mock.php 274406 2009-01-23 18:01:57Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Base class for HTTP_Request2 adapters
- */
-require_once 'HTTP/Request2/Adapter.php';
-
-/**
- * Mock adapter intended for testing
- *
- * Can be used to test applications depending on HTTP_Request2 package without
- * actually performing any HTTP requests. This adapter will return responses
- * previously added via addResponse()
- *
- * $mock = new HTTP_Request2_Adapter_Mock();
- * $mock->addResponse("HTTP/1.1 ... ");
- *
- * $request = new HTTP_Request2();
- * $request->setAdapter($mock);
- *
- * // This will return the response set above
- * $response = $req->send();
- *
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- */
-class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
-{
- /**
- * A queue of responses to be returned by sendRequest()
- * @var array
- */
- protected $responses = array();
-
- /**
- * Returns the next response from the queue built by addResponse()
- *
- * If the queue is empty will return default empty response with status 400,
- * if an Exception object was added to the queue it will be thrown.
- *
- * @param HTTP_Request2
- * @return HTTP_Request2_Response
- * @throws Exception
- */
- public function sendRequest(HTTP_Request2 $request)
- {
- if (count($this->responses) > 0) {
- $response = array_shift($this->responses);
- if ($response instanceof HTTP_Request2_Response) {
- return $response;
- } else {
- // rethrow the exception,
- $class = get_class($response);
- $message = $response->getMessage();
- $code = $response->getCode();
- throw new $class($message, $code);
- }
- } else {
- return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
- }
- }
-
- /**
- * Adds response to the queue
- *
- * @param mixed either a string, a pointer to an open file,
- * a HTTP_Request2_Response or Exception object
- * @throws HTTP_Request2_Exception
- */
- public function addResponse($response)
- {
- if (is_string($response)) {
- $response = self::createResponseFromString($response);
- } elseif (is_resource($response)) {
- $response = self::createResponseFromFile($response);
- } elseif (!$response instanceof HTTP_Request2_Response &&
- !$response instanceof Exception
- ) {
- throw new HTTP_Request2_Exception('Parameter is not a valid response');
- }
- $this->responses[] = $response;
- }
-
- /**
- * Creates a new HTTP_Request2_Response object from a string
- *
- * @param string
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- public static function createResponseFromString($str)
- {
- $parts = preg_split('!(\r?\n){2}!m', $str, 2);
- $headerLines = explode("\n", $parts[0]);
- $response = new HTTP_Request2_Response(array_shift($headerLines));
- foreach ($headerLines as $headerLine) {
- $response->parseHeaderLine($headerLine);
- }
- $response->parseHeaderLine('');
- if (isset($parts[1])) {
- $response->appendBody($parts[1]);
- }
- return $response;
- }
-
- /**
- * Creates a new HTTP_Request2_Response object from a file
- *
- * @param resource file pointer returned by fopen()
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- public static function createResponseFromFile($fp)
- {
- $response = new HTTP_Request2_Response(fgets($fp));
- do {
- $headerLine = fgets($fp);
- $response->parseHeaderLine($headerLine);
- } while ('' != trim($headerLine));
-
- while (!feof($fp)) {
- $response->appendBody(fread($fp, 8192));
- }
- return $response;
- }
-}
-?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Adapter/Socket.php b/extlib/HTTP/Request2/Adapter/Socket.php
deleted file mode 100644
index ff44d4959..000000000
--- a/extlib/HTTP/Request2/Adapter/Socket.php
+++ /dev/null
@@ -1,971 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Base class for HTTP_Request2 adapters
- */
-require_once 'HTTP/Request2/Adapter.php';
-
-/**
- * Socket-based adapter for HTTP_Request2
- *
- * This adapter uses only PHP sockets and will work on almost any PHP
- * environment. Code is based on original HTTP_Request PEAR package.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- */
-class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
-{
- /**
- * Regular expression for 'token' rule from RFC 2616
- */
- const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
-
- /**
- * Regular expression for 'quoted-string' rule from RFC 2616
- */
- const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
-
- /**
- * Connected sockets, needed for Keep-Alive support
- * @var array
- * @see connect()
- */
- protected static $sockets = array();
-
- /**
- * Data for digest authentication scheme
- *
- * The keys for the array are URL prefixes.
- *
- * The values are associative arrays with data (realm, nonce, nonce-count,
- * opaque...) needed for digest authentication. Stored here to prevent making
- * duplicate requests to digest-protected resources after we have already
- * received the challenge.
- *
- * @var array
- */
- protected static $challenges = array();
-
- /**
- * Connected socket
- * @var resource
- * @see connect()
- */
- protected $socket;
-
- /**
- * Challenge used for server digest authentication
- * @var array
- */
- protected $serverChallenge;
-
- /**
- * Challenge used for proxy digest authentication
- * @var array
- */
- protected $proxyChallenge;
-
- /**
- * Global timeout, exception will be raised if request continues past this time
- * @var integer
- */
- protected $timeout = null;
-
- /**
- * Remaining length of the current chunk, when reading chunked response
- * @var integer
- * @see readChunked()
- */
- protected $chunkLength = 0;
-
- /**
- * Sends request to the remote server and returns its response
- *
- * @param HTTP_Request2
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- public function sendRequest(HTTP_Request2 $request)
- {
- $this->request = $request;
- $keepAlive = $this->connect();
- $headers = $this->prepareHeaders();
-
- // Use global request timeout if given, see feature requests #5735, #8964
- if ($timeout = $request->getConfig('timeout')) {
- $this->timeout = time() + $timeout;
- } else {
- $this->timeout = null;
- }
-
- try {
- if (false === @fwrite($this->socket, $headers, strlen($headers))) {
- throw new HTTP_Request2_Exception('Error writing request');
- }
- // provide request headers to the observer, see request #7633
- $this->request->setLastEvent('sentHeaders', $headers);
- $this->writeBody();
-
- if ($this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $request->getConfig('timeout') . ' second(s)'
- );
- }
-
- $response = $this->readResponse();
-
- if (!$this->canKeepAlive($keepAlive, $response)) {
- $this->disconnect();
- }
-
- if ($this->shouldUseProxyDigestAuth($response)) {
- return $this->sendRequest($request);
- }
- if ($this->shouldUseServerDigestAuth($response)) {
- return $this->sendRequest($request);
- }
- if ($authInfo = $response->getHeader('authentication-info')) {
- $this->updateChallenge($this->serverChallenge, $authInfo);
- }
- if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
- $this->updateChallenge($this->proxyChallenge, $proxyInfo);
- }
-
- } catch (Exception $e) {
- $this->disconnect();
- throw $e;
- }
-
- return $response;
- }
-
- /**
- * Connects to the remote server
- *
- * @return bool whether the connection can be persistent
- * @throws HTTP_Request2_Exception
- */
- protected function connect()
- {
- $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
- $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
- $headers = $this->request->getHeaders();
- $reqHost = $this->request->getUrl()->getHost();
- if (!($reqPort = $this->request->getUrl()->getPort())) {
- $reqPort = $secure? 443: 80;
- }
-
- if ($host = $this->request->getConfig('proxy_host')) {
- if (!($port = $this->request->getConfig('proxy_port'))) {
- throw new HTTP_Request2_Exception('Proxy port not provided');
- }
- $proxy = true;
- } else {
- $host = $reqHost;
- $port = $reqPort;
- $proxy = false;
- }
-
- if ($tunnel && !$proxy) {
- throw new HTTP_Request2_Exception(
- "Trying to perform CONNECT request without proxy"
- );
- }
- if ($secure && !in_array('ssl', stream_get_transports())) {
- throw new HTTP_Request2_Exception(
- 'Need OpenSSL support for https:// requests'
- );
- }
-
- // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
- // connection token to a proxy server...
- if ($proxy && !$secure &&
- !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
- ) {
- $this->request->setHeader('connection');
- }
-
- $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
- empty($headers['connection'])) ||
- (!empty($headers['connection']) &&
- 'Keep-Alive' == $headers['connection']);
- $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
-
- $options = array();
- if ($secure || $tunnel) {
- foreach ($this->request->getConfig() as $name => $value) {
- if ('ssl_' == substr($name, 0, 4) && null !== $value) {
- if ('ssl_verify_host' == $name) {
- if ($value) {
- $options['CN_match'] = $reqHost;
- }
- } else {
- $options[substr($name, 4)] = $value;
- }
- }
- }
- ksort($options);
- }
-
- // Changing SSL context options after connection is established does *not*
- // work, we need a new connection if options change
- $remote = $host . ':' . $port;
- $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
- (empty($options)? '': ':' . serialize($options));
- unset($this->socket);
-
- // We use persistent connections and have a connected socket?
- // Ensure that the socket is still connected, see bug #16149
- if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
- !feof(self::$sockets[$socketKey])
- ) {
- $this->socket =& self::$sockets[$socketKey];
-
- } elseif ($secure && $proxy && !$tunnel) {
- $this->establishTunnel();
- $this->request->setLastEvent(
- 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
- );
- self::$sockets[$socketKey] =& $this->socket;
-
- } else {
- // Set SSL context options if doing HTTPS request or creating a tunnel
- $context = stream_context_create();
- foreach ($options as $name => $value) {
- if (!stream_context_set_option($context, 'ssl', $name, $value)) {
- throw new HTTP_Request2_Exception(
- "Error setting SSL context option '{$name}'"
- );
- }
- }
- $this->socket = @stream_socket_client(
- $remote, $errno, $errstr,
- $this->request->getConfig('connect_timeout'),
- STREAM_CLIENT_CONNECT, $context
- );
- if (!$this->socket) {
- throw new HTTP_Request2_Exception(
- "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
- );
- }
- $this->request->setLastEvent('connect', $remote);
- self::$sockets[$socketKey] =& $this->socket;
- }
- return $keepAlive;
- }
-
- /**
- * Establishes a tunnel to a secure remote server via HTTP CONNECT request
- *
- * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
- * sees that we are connected to a proxy server (duh!) rather than the server
- * that presents its certificate.
- *
- * @link http://tools.ietf.org/html/rfc2817#section-5.2
- * @throws HTTP_Request2_Exception
- */
- protected function establishTunnel()
- {
- $donor = new self;
- $connect = new HTTP_Request2(
- $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
- array_merge($this->request->getConfig(),
- array('adapter' => $donor))
- );
- $response = $connect->send();
- // Need any successful (2XX) response
- if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
- throw new HTTP_Request2_Exception(
- 'Failed to connect via HTTPS proxy. Proxy response: ' .
- $response->getStatus() . ' ' . $response->getReasonPhrase()
- );
- }
- $this->socket = $donor->socket;
-
- $modes = array(
- STREAM_CRYPTO_METHOD_TLS_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv2_CLIENT
- );
-
- foreach ($modes as $mode) {
- if (stream_socket_enable_crypto($this->socket, true, $mode)) {
- return;
- }
- }
- throw new HTTP_Request2_Exception(
- 'Failed to enable secure connection when connecting through proxy'
- );
- }
-
- /**
- * Checks whether current connection may be reused or should be closed
- *
- * @param boolean whether connection could be persistent
- * in the first place
- * @param HTTP_Request2_Response response object to check
- * @return boolean
- */
- protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
- {
- // Do not close socket on successful CONNECT request
- if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
- 200 <= $response->getStatus() && 300 > $response->getStatus()
- ) {
- return true;
- }
-
- $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
- null !== $response->getHeader('content-length');
- $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
- (null === $response->getHeader('connection') &&
- '1.1' == $response->getVersion());
- return $requestKeepAlive && $lengthKnown && $persistent;
- }
-
- /**
- * Disconnects from the remote server
- */
- protected function disconnect()
- {
- if (is_resource($this->socket)) {
- fclose($this->socket);
- $this->socket = null;
- $this->request->setLastEvent('disconnect');
- }
- }
-
- /**
- * Checks whether another request should be performed with server digest auth
- *
- * Several conditions should be satisfied for it to return true:
- * - response status should be 401
- * - auth credentials should be set in the request object
- * - response should contain WWW-Authenticate header with digest challenge
- * - there is either no challenge stored for this URL or new challenge
- * contains stale=true parameter (in other case we probably just failed
- * due to invalid username / password)
- *
- * The method stores challenge values in $challenges static property
- *
- * @param HTTP_Request2_Response response to check
- * @return boolean whether another request should be performed
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
- {
- // no sense repeating a request if we don't have credentials
- if (401 != $response->getStatus() || !$this->request->getAuth()) {
- return false;
- }
- if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
- return false;
- }
-
- $url = $this->request->getUrl();
- $scheme = $url->getScheme();
- $host = $scheme . '://' . $url->getHost();
- if ($port = $url->getPort()) {
- if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
- (0 == strcasecmp($scheme, 'https') && 443 != $port)
- ) {
- $host .= ':' . $port;
- }
- }
-
- if (!empty($challenge['domain'])) {
- $prefixes = array();
- foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
- // don't bother with different servers
- if ('/' == substr($prefix, 0, 1)) {
- $prefixes[] = $host . $prefix;
- }
- }
- }
- if (empty($prefixes)) {
- $prefixes = array($host . '/');
- }
-
- $ret = true;
- foreach ($prefixes as $prefix) {
- if (!empty(self::$challenges[$prefix]) &&
- (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
- ) {
- // probably credentials are invalid
- $ret = false;
- }
- self::$challenges[$prefix] =& $challenge;
- }
- return $ret;
- }
-
- /**
- * Checks whether another request should be performed with proxy digest auth
- *
- * Several conditions should be satisfied for it to return true:
- * - response status should be 407
- * - proxy auth credentials should be set in the request object
- * - response should contain Proxy-Authenticate header with digest challenge
- * - there is either no challenge stored for this proxy or new challenge
- * contains stale=true parameter (in other case we probably just failed
- * due to invalid username / password)
- *
- * The method stores challenge values in $challenges static property
- *
- * @param HTTP_Request2_Response response to check
- * @return boolean whether another request should be performed
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
- {
- if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
- return false;
- }
- if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
- return false;
- }
-
- $key = 'proxy://' . $this->request->getConfig('proxy_host') .
- ':' . $this->request->getConfig('proxy_port');
-
- if (!empty(self::$challenges[$key]) &&
- (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
- ) {
- $ret = false;
- } else {
- $ret = true;
- }
- self::$challenges[$key] = $challenge;
- return $ret;
- }
-
- /**
- * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
- *
- * There is a problem with implementation of RFC 2617: several of the parameters
- * here are defined as quoted-string and thus may contain backslash escaped
- * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
- * just value of quoted-string X without surrounding quotes, it doesn't speak
- * about removing backslash escaping.
- *
- * Now realm parameter is user-defined and human-readable, strange things
- * happen when it contains quotes:
- * - Apache allows quotes in realm, but apparently uses realm value without
- * backslashes for digest computation
- * - Squid allows (manually escaped) quotes there, but it is impossible to
- * authorize with either escaped or unescaped quotes used in digest,
- * probably it can't parse the response (?)
- * - Both IE and Firefox display realm value with backslashes in
- * the password popup and apparently use the same value for digest
- *
- * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
- * quoted-string handling, unfortunately that means failure to authorize
- * sometimes
- *
- * @param string value of WWW-Authenticate or Proxy-Authenticate header
- * @return mixed associative array with challenge parameters, false if
- * no challenge is present in header value
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function parseDigestChallenge($headerValue)
- {
- $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
- self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
- $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
- if (!preg_match($challenge, $headerValue, $matches)) {
- return false;
- }
-
- preg_match_all('!' . $authParam . '!', $matches[0], $params);
- $paramsAry = array();
- $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
- 'algorithm', 'qop');
- for ($i = 0; $i < count($params[0]); $i++) {
- // section 3.2.1: Any unrecognized directive MUST be ignored.
- if (in_array($params[1][$i], $knownParams)) {
- if ('"' == substr($params[2][$i], 0, 1)) {
- $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
- } else {
- $paramsAry[$params[1][$i]] = $params[2][$i];
- }
- }
- }
- // we only support qop=auth
- if (!empty($paramsAry['qop']) &&
- !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
- ) {
- throw new HTTP_Request2_Exception(
- "Only 'auth' qop is currently supported in digest authentication, " .
- "server requested '{$paramsAry['qop']}'"
- );
- }
- // we only support algorithm=MD5
- if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
- throw new HTTP_Request2_Exception(
- "Only 'MD5' algorithm is currently supported in digest authentication, " .
- "server requested '{$paramsAry['algorithm']}'"
- );
- }
-
- return $paramsAry;
- }
-
- /**
- * Parses [Proxy-]Authentication-Info header value and updates challenge
- *
- * @param array challenge to update
- * @param string value of [Proxy-]Authentication-Info header
- * @todo validate server rspauth response
- */
- protected function updateChallenge(&$challenge, $headerValue)
- {
- $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
- self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
- $paramsAry = array();
-
- preg_match_all($authParam, $headerValue, $params);
- for ($i = 0; $i < count($params[0]); $i++) {
- if ('"' == substr($params[2][$i], 0, 1)) {
- $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
- } else {
- $paramsAry[$params[1][$i]] = $params[2][$i];
- }
- }
- // for now, just update the nonce value
- if (!empty($paramsAry['nextnonce'])) {
- $challenge['nonce'] = $paramsAry['nextnonce'];
- $challenge['nc'] = 1;
- }
- }
-
- /**
- * Creates a value for [Proxy-]Authorization header when using digest authentication
- *
- * @param string user name
- * @param string password
- * @param string request URL
- * @param array digest challenge parameters
- * @return string value of [Proxy-]Authorization request header
- * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
- */
- protected function createDigestResponse($user, $password, $url, &$challenge)
- {
- if (false !== ($q = strpos($url, '?')) &&
- $this->request->getConfig('digest_compat_ie')
- ) {
- $url = substr($url, 0, $q);
- }
-
- $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
- $a2 = md5($this->request->getMethod() . ':' . $url);
-
- if (empty($challenge['qop'])) {
- $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
- } else {
- $challenge['cnonce'] = 'Req2.' . rand();
- if (empty($challenge['nc'])) {
- $challenge['nc'] = 1;
- }
- $nc = sprintf('%08x', $challenge['nc']++);
- $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
- $challenge['cnonce'] . ':auth:' . $a2);
- }
- return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
- 'realm="' . $challenge['realm'] . '", ' .
- 'nonce="' . $challenge['nonce'] . '", ' .
- 'uri="' . $url . '", ' .
- 'response="' . $digest . '"' .
- (!empty($challenge['opaque'])?
- ', opaque="' . $challenge['opaque'] . '"':
- '') .
- (!empty($challenge['qop'])?
- ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
- '');
- }
-
- /**
- * Adds 'Authorization' header (if needed) to request headers array
- *
- * @param array request headers
- * @param string request host (needed for digest authentication)
- * @param string request URL (needed for digest authentication)
- * @throws HTTP_Request2_Exception
- */
- protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
- {
- if (!($auth = $this->request->getAuth())) {
- return;
- }
- switch ($auth['scheme']) {
- case HTTP_Request2::AUTH_BASIC:
- $headers['authorization'] =
- 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
- break;
-
- case HTTP_Request2::AUTH_DIGEST:
- unset($this->serverChallenge);
- $fullUrl = ('/' == $requestUrl[0])?
- $this->request->getUrl()->getScheme() . '://' .
- $requestHost . $requestUrl:
- $requestUrl;
- foreach (array_keys(self::$challenges) as $key) {
- if ($key == substr($fullUrl, 0, strlen($key))) {
- $headers['authorization'] = $this->createDigestResponse(
- $auth['user'], $auth['password'],
- $requestUrl, self::$challenges[$key]
- );
- $this->serverChallenge =& self::$challenges[$key];
- break;
- }
- }
- break;
-
- default:
- throw new HTTP_Request2_Exception(
- "Unknown HTTP authentication scheme '{$auth['scheme']}'"
- );
- }
- }
-
- /**
- * Adds 'Proxy-Authorization' header (if needed) to request headers array
- *
- * @param array request headers
- * @param string request URL (needed for digest authentication)
- * @throws HTTP_Request2_Exception
- */
- protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
- {
- if (!$this->request->getConfig('proxy_host') ||
- !($user = $this->request->getConfig('proxy_user')) ||
- (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
- HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
- ) {
- return;
- }
-
- $password = $this->request->getConfig('proxy_password');
- switch ($this->request->getConfig('proxy_auth_scheme')) {
- case HTTP_Request2::AUTH_BASIC:
- $headers['proxy-authorization'] =
- 'Basic ' . base64_encode($user . ':' . $password);
- break;
-
- case HTTP_Request2::AUTH_DIGEST:
- unset($this->proxyChallenge);
- $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
- ':' . $this->request->getConfig('proxy_port');
- if (!empty(self::$challenges[$proxyUrl])) {
- $headers['proxy-authorization'] = $this->createDigestResponse(
- $user, $password,
- $requestUrl, self::$challenges[$proxyUrl]
- );
- $this->proxyChallenge =& self::$challenges[$proxyUrl];
- }
- break;
-
- default:
- throw new HTTP_Request2_Exception(
- "Unknown HTTP authentication scheme '" .
- $this->request->getConfig('proxy_auth_scheme') . "'"
- );
- }
- }
-
-
- /**
- * Creates the string with the Request-Line and request headers
- *
- * @return string
- * @throws HTTP_Request2_Exception
- */
- protected function prepareHeaders()
- {
- $headers = $this->request->getHeaders();
- $url = $this->request->getUrl();
- $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
- $host = $url->getHost();
-
- $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
- if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
- $host .= ':' . (empty($port)? $defaultPort: $port);
- }
- // Do not overwrite explicitly set 'Host' header, see bug #16146
- if (!isset($headers['host'])) {
- $headers['host'] = $host;
- }
-
- if ($connect) {
- $requestUrl = $host;
-
- } else {
- if (!$this->request->getConfig('proxy_host') ||
- 0 == strcasecmp($url->getScheme(), 'https')
- ) {
- $requestUrl = '';
- } else {
- $requestUrl = $url->getScheme() . '://' . $host;
- }
- $path = $url->getPath();
- $query = $url->getQuery();
- $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
- }
-
- if ('1.1' == $this->request->getConfig('protocol_version') &&
- extension_loaded('zlib') && !isset($headers['accept-encoding'])
- ) {
- $headers['accept-encoding'] = 'gzip, deflate';
- }
-
- $this->addAuthorizationHeader($headers, $host, $requestUrl);
- $this->addProxyAuthorizationHeader($headers, $requestUrl);
- $this->calculateRequestLength($headers);
-
- $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
- $this->request->getConfig('protocol_version') . "\r\n";
- foreach ($headers as $name => $value) {
- $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
- $headersStr .= $canonicalName . ': ' . $value . "\r\n";
- }
- return $headersStr . "\r\n";
- }
-
- /**
- * Sends the request body
- *
- * @throws HTTP_Request2_Exception
- */
- protected function writeBody()
- {
- if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
- 0 == $this->contentLength
- ) {
- return;
- }
-
- $position = 0;
- $bufferSize = $this->request->getConfig('buffer_size');
- while ($position < $this->contentLength) {
- if (is_string($this->requestBody)) {
- $str = substr($this->requestBody, $position, $bufferSize);
- } elseif (is_resource($this->requestBody)) {
- $str = fread($this->requestBody, $bufferSize);
- } else {
- $str = $this->requestBody->read($bufferSize);
- }
- if (false === @fwrite($this->socket, $str, strlen($str))) {
- throw new HTTP_Request2_Exception('Error writing request');
- }
- // Provide the length of written string to the observer, request #7630
- $this->request->setLastEvent('sentBodyPart', strlen($str));
- $position += strlen($str);
- }
- }
-
- /**
- * Reads the remote server's response
- *
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- protected function readResponse()
- {
- $bufferSize = $this->request->getConfig('buffer_size');
-
- do {
- $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
- do {
- $headerLine = $this->readLine($bufferSize);
- $response->parseHeaderLine($headerLine);
- } while ('' != $headerLine);
- } while (in_array($response->getStatus(), array(100, 101)));
-
- $this->request->setLastEvent('receivedHeaders', $response);
-
- // No body possible in such responses
- if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
- (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
- 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
- in_array($response->getStatus(), array(204, 304))
- ) {
- return $response;
- }
-
- $chunked = 'chunked' == $response->getHeader('transfer-encoding');
- $length = $response->getHeader('content-length');
- $hasBody = false;
- if ($chunked || null === $length || 0 < intval($length)) {
- // RFC 2616, section 4.4:
- // 3. ... If a message is received with both a
- // Transfer-Encoding header field and a Content-Length header field,
- // the latter MUST be ignored.
- $toRead = ($chunked || null === $length)? null: $length;
- $this->chunkLength = 0;
-
- while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
- if ($chunked) {
- $data = $this->readChunked($bufferSize);
- } elseif (is_null($toRead)) {
- $data = $this->fread($bufferSize);
- } else {
- $data = $this->fread(min($toRead, $bufferSize));
- $toRead -= strlen($data);
- }
- if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
- break;
- }
-
- $hasBody = true;
- if ($this->request->getConfig('store_body')) {
- $response->appendBody($data);
- }
- if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
- $this->request->setLastEvent('receivedEncodedBodyPart', $data);
- } else {
- $this->request->setLastEvent('receivedBodyPart', $data);
- }
- }
- }
-
- if ($hasBody) {
- $this->request->setLastEvent('receivedBody', $response);
- }
- return $response;
- }
-
- /**
- * Reads until either the end of the socket or a newline, whichever comes first
- *
- * Strips the trailing newline from the returned data, handles global
- * request timeout. Method idea borrowed from Net_Socket PEAR package.
- *
- * @param int buffer size to use for reading
- * @return Available data up to the newline (not including newline)
- * @throws HTTP_Request2_Exception In case of timeout
- */
- protected function readLine($bufferSize)
- {
- $line = '';
- while (!feof($this->socket)) {
- if ($this->timeout) {
- stream_set_timeout($this->socket, max($this->timeout - time(), 1));
- }
- $line .= @fgets($this->socket, $bufferSize);
- $info = stream_get_meta_data($this->socket);
- if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $this->request->getConfig('timeout') . ' second(s)'
- );
- }
- if (substr($line, -1) == "\n") {
- return rtrim($line, "\r\n");
- }
- }
- return $line;
- }
-
- /**
- * Wrapper around fread(), handles global request timeout
- *
- * @param int Reads up to this number of bytes
- * @return Data read from socket
- * @throws HTTP_Request2_Exception In case of timeout
- */
- protected function fread($length)
- {
- if ($this->timeout) {
- stream_set_timeout($this->socket, max($this->timeout - time(), 1));
- }
- $data = fread($this->socket, $length);
- $info = stream_get_meta_data($this->socket);
- if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $this->request->getConfig('timeout') . ' second(s)'
- );
- }
- return $data;
- }
-
- /**
- * Reads a part of response body encoded with chunked Transfer-Encoding
- *
- * @param int buffer size to use for reading
- * @return string
- * @throws HTTP_Request2_Exception
- */
- protected function readChunked($bufferSize)
- {
- // at start of the next chunk?
- if (0 == $this->chunkLength) {
- $line = $this->readLine($bufferSize);
- if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
- throw new HTTP_Request2_Exception(
- "Cannot decode chunked response, invalid chunk length '{$line}'"
- );
- } else {
- $this->chunkLength = hexdec($matches[1]);
- // Chunk with zero length indicates the end
- if (0 == $this->chunkLength) {
- $this->readLine($bufferSize);
- return '';
- }
- }
- }
- $data = $this->fread(min($this->chunkLength, $bufferSize));
- $this->chunkLength -= strlen($data);
- if (0 == $this->chunkLength) {
- $this->readLine($bufferSize); // Trailing CRLF
- }
- return $data;
- }
-}
-
-?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Exception.php b/extlib/HTTP/Request2/Exception.php
deleted file mode 100644
index bfef7d6c2..000000000
--- a/extlib/HTTP/Request2/Exception.php
+++ /dev/null
@@ -1,62 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Exception.php 273003 2009-01-07 19:28:22Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Base class for exceptions in PEAR
- */
-require_once 'PEAR/Exception.php';
-
-/**
- * Exception class for HTTP_Request2 package
- *
- * Such a class is required by the Exception RFC:
- * http://pear.php.net/pepr/pepr-proposal-show.php?id=132
- *
- * @category HTTP
- * @package HTTP_Request2
- * @version Release: 0.4.1
- */
-class HTTP_Request2_Exception extends PEAR_Exception
-{
-}
-?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/MultipartBody.php b/extlib/HTTP/Request2/MultipartBody.php
deleted file mode 100644
index d8afd8344..000000000
--- a/extlib/HTTP/Request2/MultipartBody.php
+++ /dev/null
@@ -1,274 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: MultipartBody.php 287306 2009-08-14 15:22:52Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Class for building multipart/form-data request body
- *
- * The class helps to reduce memory consumption by streaming large file uploads
- * from disk, it also allows monitoring of upload progress (see request #7630)
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- * @link http://tools.ietf.org/html/rfc1867
- */
-class HTTP_Request2_MultipartBody
-{
- /**
- * MIME boundary
- * @var string
- */
- private $_boundary;
-
- /**
- * Form parameters added via {@link HTTP_Request2::addPostParameter()}
- * @var array
- */
- private $_params = array();
-
- /**
- * File uploads added via {@link HTTP_Request2::addUpload()}
- * @var array
- */
- private $_uploads = array();
-
- /**
- * Header for parts with parameters
- * @var string
- */
- private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
-
- /**
- * Header for parts with uploads
- * @var string
- */
- private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
-
- /**
- * Current position in parameter and upload arrays
- *
- * First number is index of "current" part, second number is position within
- * "current" part
- *
- * @var array
- */
- private $_pos = array(0, 0);
-
-
- /**
- * Constructor. Sets the arrays with POST data.
- *
- * @param array values of form fields set via {@link HTTP_Request2::addPostParameter()}
- * @param array file uploads set via {@link HTTP_Request2::addUpload()}
- * @param bool whether to append brackets to array variable names
- */
- public function __construct(array $params, array $uploads, $useBrackets = true)
- {
- $this->_params = self::_flattenArray('', $params, $useBrackets);
- foreach ($uploads as $fieldName => $f) {
- if (!is_array($f['fp'])) {
- $this->_uploads[] = $f + array('name' => $fieldName);
- } else {
- for ($i = 0; $i < count($f['fp']); $i++) {
- $upload = array(
- 'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
- );
- foreach (array('fp', 'filename', 'size', 'type') as $key) {
- $upload[$key] = $f[$key][$i];
- }
- $this->_uploads[] = $upload;
- }
- }
- }
- }
-
- /**
- * Returns the length of the body to use in Content-Length header
- *
- * @return integer
- */
- public function getLength()
- {
- $boundaryLength = strlen($this->getBoundary());
- $headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
- $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
- $length = $boundaryLength + 6;
- foreach ($this->_params as $p) {
- $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
- }
- foreach ($this->_uploads as $u) {
- $length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
- strlen($u['filename']) + $u['size'] + 2;
- }
- return $length;
- }
-
- /**
- * Returns the boundary to use in Content-Type header
- *
- * @return string
- */
- public function getBoundary()
- {
- if (empty($this->_boundary)) {
- $this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
- }
- return $this->_boundary;
- }
-
- /**
- * Returns next chunk of request body
- *
- * @param integer Amount of bytes to read
- * @return string Up to $length bytes of data, empty string if at end
- */
- public function read($length)
- {
- $ret = '';
- $boundary = $this->getBoundary();
- $paramCount = count($this->_params);
- $uploadCount = count($this->_uploads);
- while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
- $oldLength = $length;
- if ($this->_pos[0] < $paramCount) {
- $param = sprintf($this->_headerParam, $boundary,
- $this->_params[$this->_pos[0]][0]) .
- $this->_params[$this->_pos[0]][1] . "\r\n";
- $ret .= substr($param, $this->_pos[1], $length);
- $length -= min(strlen($param) - $this->_pos[1], $length);
-
- } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
- $pos = $this->_pos[0] - $paramCount;
- $header = sprintf($this->_headerUpload, $boundary,
- $this->_uploads[$pos]['name'],
- $this->_uploads[$pos]['filename'],
- $this->_uploads[$pos]['type']);
- if ($this->_pos[1] < strlen($header)) {
- $ret .= substr($header, $this->_pos[1], $length);
- $length -= min(strlen($header) - $this->_pos[1], $length);
- }
- $filePos = max(0, $this->_pos[1] - strlen($header));
- if ($length > 0 && $filePos < $this->_uploads[$pos]['size']) {
- $ret .= fread($this->_uploads[$pos]['fp'], $length);
- $length -= min($length, $this->_uploads[$pos]['size'] - $filePos);
- }
- if ($length > 0) {
- $start = $this->_pos[1] + ($oldLength - $length) -
- strlen($header) - $this->_uploads[$pos]['size'];
- $ret .= substr("\r\n", $start, $length);
- $length -= min(2 - $start, $length);
- }
-
- } else {
- $closing = '--' . $boundary . "--\r\n";
- $ret .= substr($closing, $this->_pos[1], $length);
- $length -= min(strlen($closing) - $this->_pos[1], $length);
- }
- if ($length > 0) {
- $this->_pos = array($this->_pos[0] + 1, 0);
- } else {
- $this->_pos[1] += $oldLength;
- }
- }
- return $ret;
- }
-
- /**
- * Sets the current position to the start of the body
- *
- * This allows reusing the same body in another request
- */
- public function rewind()
- {
- $this->_pos = array(0, 0);
- foreach ($this->_uploads as $u) {
- rewind($u['fp']);
- }
- }
-
- /**
- * Returns the body as string
- *
- * Note that it reads all file uploads into memory so it is a good idea not
- * to use this method with large file uploads and rely on read() instead.
- *
- * @return string
- */
- public function __toString()
- {
- $this->rewind();
- return $this->read($this->getLength());
- }
-
-
- /**
- * Helper function to change the (probably multidimensional) associative array
- * into the simple one.
- *
- * @param string name for item
- * @param mixed item's values
- * @param bool whether to append [] to array variables' names
- * @return array array with the following items: array('item name', 'item value');
- */
- private static function _flattenArray($name, $values, $useBrackets)
- {
- if (!is_array($values)) {
- return array(array($name, $values));
- } else {
- $ret = array();
- foreach ($values as $k => $v) {
- if (empty($name)) {
- $newName = $k;
- } elseif ($useBrackets) {
- $newName = $name . '[' . $k . ']';
- } else {
- $newName = $name;
- }
- $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
- }
- return $ret;
- }
- }
-}
-?>
diff --git a/extlib/HTTP/Request2/Observer/Log.php b/extlib/HTTP/Request2/Observer/Log.php
deleted file mode 100644
index b1a055278..000000000
--- a/extlib/HTTP/Request2/Observer/Log.php
+++ /dev/null
@@ -1,215 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author David Jean Louis
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Log.php 272593 2009-01-02 16:27:14Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Exception class for HTTP_Request2 package
- */
-require_once 'HTTP/Request2/Exception.php';
-
-/**
- * A debug observer useful for debugging / testing.
- *
- * This observer logs to a log target data corresponding to the various request
- * and response events, it logs by default to php://output but can be configured
- * to log to a file or via the PEAR Log package.
- *
- * A simple example:
- *
- * require_once 'HTTP/Request2.php';
- * require_once 'HTTP/Request2/Observer/Log.php';
- *
- * $request = new HTTP_Request2('http://www.example.com');
- * $observer = new HTTP_Request2_Observer_Log();
- * $request->attach($observer);
- * $request->send();
- *
- *
- * A more complex example with PEAR Log:
- *
- * require_once 'HTTP/Request2.php';
- * require_once 'HTTP/Request2/Observer/Log.php';
- * require_once 'Log.php';
- *
- * $request = new HTTP_Request2('http://www.example.com');
- * // we want to log with PEAR log
- * $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
- *
- * // we only want to log received headers
- * $observer->events = array('receivedHeaders');
- *
- * $request->attach($observer);
- * $request->send();
- *
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author David Jean Louis
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 0.4.1
- * @link http://pear.php.net/package/HTTP_Request2
- */
-class HTTP_Request2_Observer_Log implements SplObserver
-{
- // properties {{{
-
- /**
- * The log target, it can be a a resource or a PEAR Log instance.
- *
- * @var resource|Log $target
- */
- protected $target = null;
-
- /**
- * The events to log.
- *
- * @var array $events
- */
- public $events = array(
- 'connect',
- 'sentHeaders',
- 'sentBodyPart',
- 'receivedHeaders',
- 'receivedBody',
- 'disconnect',
- );
-
- // }}}
- // __construct() {{{
-
- /**
- * Constructor.
- *
- * @param mixed $target Can be a file path (default: php://output), a resource,
- * or an instance of the PEAR Log class.
- * @param array $events Array of events to listen to (default: all events)
- *
- * @return void
- */
- public function __construct($target = 'php://output', array $events = array())
- {
- if (!empty($events)) {
- $this->events = $events;
- }
- if (is_resource($target) || $target instanceof Log) {
- $this->target = $target;
- } elseif (false === ($this->target = @fopen($target, 'w'))) {
- throw new HTTP_Request2_Exception("Unable to open '{$target}'");
- }
- }
-
- // }}}
- // update() {{{
-
- /**
- * Called when the request notify us of an event.
- *
- * @param HTTP_Request2 $subject The HTTP_Request2 instance
- *
- * @return void
- */
- public function update(SplSubject $subject)
- {
- $event = $subject->getLastEvent();
- if (!in_array($event['name'], $this->events)) {
- return;
- }
-
- switch ($event['name']) {
- case 'connect':
- $this->log('* Connected to ' . $event['data']);
- break;
- case 'sentHeaders':
- $headers = explode("\r\n", $event['data']);
- array_pop($headers);
- foreach ($headers as $header) {
- $this->log('> ' . $header);
- }
- break;
- case 'sentBodyPart':
- $this->log('> ' . $event['data']);
- break;
- case 'receivedHeaders':
- $this->log(sprintf('< HTTP/%s %s %s',
- $event['data']->getVersion(),
- $event['data']->getStatus(),
- $event['data']->getReasonPhrase()));
- $headers = $event['data']->getHeader();
- foreach ($headers as $key => $val) {
- $this->log('< ' . $key . ': ' . $val);
- }
- $this->log('< ');
- break;
- case 'receivedBody':
- $this->log($event['data']->getBody());
- break;
- case 'disconnect':
- $this->log('* Disconnected');
- break;
- }
- }
-
- // }}}
- // log() {{{
-
- /**
- * Log the given message to the configured target.
- *
- * @param string $message Message to display
- *
- * @return void
- */
- protected function log($message)
- {
- if ($this->target instanceof Log) {
- $this->target->debug($message);
- } elseif (is_resource($this->target)) {
- fwrite($this->target, $message . "\r\n");
- }
- }
-
- // }}}
-}
-
-?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Response.php b/extlib/HTTP/Request2/Response.php
deleted file mode 100644
index c7c1021fb..000000000
--- a/extlib/HTTP/Request2/Response.php
+++ /dev/null
@@ -1,549 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Response.php 287948 2009-09-01 17:12:18Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Exception class for HTTP_Request2 package
- */
-require_once 'HTTP/Request2/Exception.php';
-
-/**
- * Class representing a HTTP response
- *
- * The class is designed to be used in "streaming" scenario, building the
- * response as it is being received:
- *
- * $statusLine = read_status_line();
- * $response = new HTTP_Request2_Response($statusLine);
- * do {
- * $headerLine = read_header_line();
- * $response->parseHeaderLine($headerLine);
- * } while ($headerLine != '');
- *
- * while ($chunk = read_body()) {
- * $response->appendBody($chunk);
- * }
- *
- * var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
- *
- *
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- * @link http://tools.ietf.org/html/rfc2616#section-6
- */
-class HTTP_Request2_Response
-{
- /**
- * HTTP protocol version (e.g. 1.0, 1.1)
- * @var string
- */
- protected $version;
-
- /**
- * Status code
- * @var integer
- * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
- */
- protected $code;
-
- /**
- * Reason phrase
- * @var string
- * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
- */
- protected $reasonPhrase;
-
- /**
- * Associative array of response headers
- * @var array
- */
- protected $headers = array();
-
- /**
- * Cookies set in the response
- * @var array
- */
- protected $cookies = array();
-
- /**
- * Name of last header processed by parseHederLine()
- *
- * Used to handle the headers that span multiple lines
- *
- * @var string
- */
- protected $lastHeader = null;
-
- /**
- * Response body
- * @var string
- */
- protected $body = '';
-
- /**
- * Whether the body is still encoded by Content-Encoding
- *
- * cURL provides the decoded body to the callback; if we are reading from
- * socket the body is still gzipped / deflated
- *
- * @var bool
- */
- protected $bodyEncoded;
-
- /**
- * Associative array of HTTP status code / reason phrase.
- *
- * @var array
- * @link http://tools.ietf.org/html/rfc2616#section-10
- */
- protected static $phrases = array(
-
- // 1xx: Informational - Request received, continuing process
- 100 => 'Continue',
- 101 => 'Switching Protocols',
-
- // 2xx: Success - The action was successfully received, understood and
- // accepted
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
-
- // 3xx: Redirection - Further action must be taken in order to complete
- // the request
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found', // 1.1
- 303 => 'See Other',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
-
- // 4xx: Client Error - The request contains bad syntax or cannot be
- // fulfilled
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested Range Not Satisfiable',
- 417 => 'Expectation Failed',
-
- // 5xx: Server Error - The server failed to fulfill an apparently
- // valid request
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported',
- 509 => 'Bandwidth Limit Exceeded',
-
- );
-
- /**
- * Constructor, parses the response status line
- *
- * @param string Response status line (e.g. "HTTP/1.1 200 OK")
- * @param bool Whether body is still encoded by Content-Encoding
- * @throws HTTP_Request2_Exception if status line is invalid according to spec
- */
- public function __construct($statusLine, $bodyEncoded = true)
- {
- if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
- throw new HTTP_Request2_Exception("Malformed response: {$statusLine}");
- }
- $this->version = $m[1];
- $this->code = intval($m[2]);
- if (!empty($m[3])) {
- $this->reasonPhrase = trim($m[3]);
- } elseif (!empty(self::$phrases[$this->code])) {
- $this->reasonPhrase = self::$phrases[$this->code];
- }
- $this->bodyEncoded = (bool)$bodyEncoded;
- }
-
- /**
- * Parses the line from HTTP response filling $headers array
- *
- * The method should be called after reading the line from socket or receiving
- * it into cURL callback. Passing an empty string here indicates the end of
- * response headers and triggers additional processing, so be sure to pass an
- * empty string in the end.
- *
- * @param string Line from HTTP response
- */
- public function parseHeaderLine($headerLine)
- {
- $headerLine = trim($headerLine, "\r\n");
-
- // empty string signals the end of headers, process the received ones
- if ('' == $headerLine) {
- if (!empty($this->headers['set-cookie'])) {
- $cookies = is_array($this->headers['set-cookie'])?
- $this->headers['set-cookie']:
- array($this->headers['set-cookie']);
- foreach ($cookies as $cookieString) {
- $this->parseCookie($cookieString);
- }
- unset($this->headers['set-cookie']);
- }
- foreach (array_keys($this->headers) as $k) {
- if (is_array($this->headers[$k])) {
- $this->headers[$k] = implode(', ', $this->headers[$k]);
- }
- }
-
- // string of the form header-name: header value
- } elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
- $name = strtolower($m[1]);
- $value = trim($m[2]);
- if (empty($this->headers[$name])) {
- $this->headers[$name] = $value;
- } else {
- if (!is_array($this->headers[$name])) {
- $this->headers[$name] = array($this->headers[$name]);
- }
- $this->headers[$name][] = $value;
- }
- $this->lastHeader = $name;
-
- // string
- } elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
- if (!is_array($this->headers[$this->lastHeader])) {
- $this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
- } else {
- $key = count($this->headers[$this->lastHeader]) - 1;
- $this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
- }
- }
- }
-
- /**
- * Parses a Set-Cookie header to fill $cookies array
- *
- * @param string value of Set-Cookie header
- * @link http://cgi.netscape.com/newsref/std/cookie_spec.html
- */
- protected function parseCookie($cookieString)
- {
- $cookie = array(
- 'expires' => null,
- 'domain' => null,
- 'path' => null,
- 'secure' => false
- );
-
- // Only a name=value pair
- if (!strpos($cookieString, ';')) {
- $pos = strpos($cookieString, '=');
- $cookie['name'] = trim(substr($cookieString, 0, $pos));
- $cookie['value'] = trim(substr($cookieString, $pos + 1));
-
- // Some optional parameters are supplied
- } else {
- $elements = explode(';', $cookieString);
- $pos = strpos($elements[0], '=');
- $cookie['name'] = trim(substr($elements[0], 0, $pos));
- $cookie['value'] = trim(substr($elements[0], $pos + 1));
-
- for ($i = 1; $i < count($elements); $i++) {
- if (false === strpos($elements[$i], '=')) {
- $elName = trim($elements[$i]);
- $elValue = null;
- } else {
- list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
- }
- $elName = strtolower($elName);
- if ('secure' == $elName) {
- $cookie['secure'] = true;
- } elseif ('expires' == $elName) {
- $cookie['expires'] = str_replace('"', '', $elValue);
- } elseif ('path' == $elName || 'domain' == $elName) {
- $cookie[$elName] = urldecode($elValue);
- } else {
- $cookie[$elName] = $elValue;
- }
- }
- }
- $this->cookies[] = $cookie;
- }
-
- /**
- * Appends a string to the response body
- * @param string
- */
- public function appendBody($bodyChunk)
- {
- $this->body .= $bodyChunk;
- }
-
- /**
- * Returns the status code
- * @return integer
- */
- public function getStatus()
- {
- return $this->code;
- }
-
- /**
- * Returns the reason phrase
- * @return string
- */
- public function getReasonPhrase()
- {
- return $this->reasonPhrase;
- }
-
- /**
- * Returns either the named header or all response headers
- *
- * @param string Name of header to return
- * @return string|array Value of $headerName header (null if header is
- * not present), array of all response headers if
- * $headerName is null
- */
- public function getHeader($headerName = null)
- {
- if (null === $headerName) {
- return $this->headers;
- } else {
- $headerName = strtolower($headerName);
- return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
- }
- }
-
- /**
- * Returns cookies set in response
- *
- * @return array
- */
- public function getCookies()
- {
- return $this->cookies;
- }
-
- /**
- * Returns the body of the response
- *
- * @return string
- * @throws HTTP_Request2_Exception if body cannot be decoded
- */
- public function getBody()
- {
- if (!$this->bodyEncoded ||
- !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
- ) {
- return $this->body;
-
- } else {
- if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
- $oldEncoding = mb_internal_encoding();
- mb_internal_encoding('iso-8859-1');
- }
-
- try {
- switch (strtolower($this->getHeader('content-encoding'))) {
- case 'gzip':
- $decoded = self::decodeGzip($this->body);
- break;
- case 'deflate':
- $decoded = self::decodeDeflate($this->body);
- }
- } catch (Exception $e) {
- }
-
- if (!empty($oldEncoding)) {
- mb_internal_encoding($oldEncoding);
- }
- if (!empty($e)) {
- throw $e;
- }
- return $decoded;
- }
- }
-
- /**
- * Get the HTTP version of the response
- *
- * @return string
- */
- public function getVersion()
- {
- return $this->version;
- }
-
- /**
- * Decodes the message-body encoded by gzip
- *
- * The real decoding work is done by gzinflate() built-in function, this
- * method only parses the header and checks data for compliance with
- * RFC 1952
- *
- * @param string gzip-encoded data
- * @return string decoded data
- * @throws HTTP_Request2_Exception
- * @link http://tools.ietf.org/html/rfc1952
- */
- public static function decodeGzip($data)
- {
- $length = strlen($data);
- // If it doesn't look like gzip-encoded data, don't bother
- if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
- return $data;
- }
- if (!function_exists('gzinflate')) {
- throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
- }
- $method = ord(substr($data, 2, 1));
- if (8 != $method) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: unknown compression method');
- }
- $flags = ord(substr($data, 3, 1));
- if ($flags & 224) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: reserved bits are set');
- }
-
- // header is 10 bytes minimum. may be longer, though.
- $headerLength = 10;
- // extra fields, need to skip 'em
- if ($flags & 4) {
- if ($length - $headerLength - 2 < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $extraLength = unpack('v', substr($data, 10, 2));
- if ($length - $headerLength - 2 - $extraLength[1] < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $headerLength += $extraLength[1] + 2;
- }
- // file name, need to skip that
- if ($flags & 8) {
- if ($length - $headerLength - 1 < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $filenameLength = strpos(substr($data, $headerLength), chr(0));
- if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $headerLength += $filenameLength + 1;
- }
- // comment, need to skip that also
- if ($flags & 16) {
- if ($length - $headerLength - 1 < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $commentLength = strpos(substr($data, $headerLength), chr(0));
- if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $headerLength += $commentLength + 1;
- }
- // have a CRC for header. let's check
- if ($flags & 2) {
- if ($length - $headerLength - 2 < 8) {
- throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
- }
- $crcReal = 0xffff & crc32(substr($data, 0, $headerLength));
- $crcStored = unpack('v', substr($data, $headerLength, 2));
- if ($crcReal != $crcStored[1]) {
- throw new HTTP_Request2_Exception('Header CRC check failed');
- }
- $headerLength += 2;
- }
- // unpacked data CRC and size at the end of encoded data
- $tmp = unpack('V2', substr($data, -8));
- $dataCrc = $tmp[1];
- $dataSize = $tmp[2];
-
- // finally, call the gzinflate() function
- // don't pass $dataSize to gzinflate, see bugs #13135, #14370
- $unpacked = gzinflate(substr($data, $headerLength, -8));
- if (false === $unpacked) {
- throw new HTTP_Request2_Exception('gzinflate() call failed');
- } elseif ($dataSize != strlen($unpacked)) {
- throw new HTTP_Request2_Exception('Data size check failed');
- } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
- throw new HTTP_Request2_Exception('Data CRC check failed');
- }
- return $unpacked;
- }
-
- /**
- * Decodes the message-body encoded by deflate
- *
- * @param string deflate-encoded data
- * @return string decoded data
- * @throws HTTP_Request2_Exception
- */
- public static function decodeDeflate($data)
- {
- if (!function_exists('gzuncompress')) {
- throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
- }
- // RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
- // while many applications send raw deflate stream from RFC 1951.
- // We should check for presence of zlib header and use gzuncompress() or
- // gzinflate() as needed. See bug #15305
- $header = unpack('n', substr($data, 0, 2));
- return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
- }
-}
-?>
\ No newline at end of file
diff --git a/extlib/Net/URL2.php b/extlib/Net/URL2.php
index f7fbcd9ce..7a654aed8 100644
--- a/extlib/Net/URL2.php
+++ b/extlib/Net/URL2.php
@@ -1,58 +1,44 @@
|
+// +-----------------------------------------------------------------------+
+//
+// $Id: URL2.php,v 1.10 2008/04/26 21:57:08 schmidt Exp $
+//
+// Net_URL2 Class (PHP5 Only)
+
+// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php
/**
- * Net_URL2, a class representing a URL as per RFC 3986.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * Copyright (c) 2007-2009, Peytz & Co. A/S
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the distribution.
- * * Neither the name of the PHP_LexerGenerator nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category Networking
- * @package Net_URL2
- * @author Christian Schmidt
- * @copyright 2007-2008 Peytz & Co. A/S
- * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: URL2.php 286661 2009-08-02 12:50:54Z schmidt $
- * @link http://www.rfc-editor.org/rfc/rfc3986.txt
- */
-
-/**
- * Represents a URL as per RFC 3986.
- *
- * @category Networking
- * @package Net_URL2
- * @author Christian Schmidt
- * @copyright 2007-2008 Peytz & Co. ApS
- * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: @package_version@
- * @link http://pear.php.net/package/Net_URL2
+ * @license BSD License
*/
class Net_URL2
{
@@ -60,24 +46,24 @@ class Net_URL2
* Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
* is true.
*/
- const OPTION_STRICT = 'strict';
+ const OPTION_STRICT = 'strict';
/**
* Represent arrays in query using PHP's [] notation. Default is true.
*/
- const OPTION_USE_BRACKETS = 'use_brackets';
+ const OPTION_USE_BRACKETS = 'use_brackets';
/**
* URL-encode query variable keys. Default is true.
*/
- const OPTION_ENCODE_KEYS = 'encode_keys';
+ const OPTION_ENCODE_KEYS = 'encode_keys';
/**
* Query variable separators when parsing the query string. Every character
* is considered a separator. Default is specified by the
* arg_separator.input php.ini setting (this defaults to "&").
*/
- const OPTION_SEPARATOR_INPUT = 'input_separator';
+ const OPTION_SEPARATOR_INPUT = 'input_separator';
/**
* Query variable separator used when generating the query string. Default
@@ -89,7 +75,7 @@ class Net_URL2
/**
* Default options corresponds to how PHP handles $_GET.
*/
- private $_options = array(
+ private $options = array(
self::OPTION_STRICT => true,
self::OPTION_USE_BRACKETS => true,
self::OPTION_ENCODE_KEYS => true,
@@ -100,43 +86,41 @@ class Net_URL2
/**
* @var string|bool
*/
- private $_scheme = false;
+ private $scheme = false;
/**
* @var string|bool
*/
- private $_userinfo = false;
+ private $userinfo = false;
/**
* @var string|bool
*/
- private $_host = false;
+ private $host = false;
/**
* @var int|bool
*/
- private $_port = false;
+ private $port = false;
/**
* @var string
*/
- private $_path = '';
+ private $path = '';
/**
* @var string|bool
*/
- private $_query = false;
+ private $query = false;
/**
* @var string|bool
*/
- private $_fragment = false;
+ private $fragment = false;
/**
- * Constructor.
- *
* @param string $url an absolute or relative URL
- * @param array $options an array of OPTION_xxx constants
+ * @param array $options
*/
public function __construct($url, $options = null)
{
@@ -146,12 +130,12 @@ class Net_URL2
ini_get('arg_separator.output'));
if (is_array($options)) {
foreach ($options as $optionName => $value) {
- $this->setOption($optionName, $value);
+ $this->setOption($optionName);
}
}
if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
- $this->_scheme = $reg[1];
+ $this->scheme = $reg[1];
$url = substr($url, strlen($reg[0]));
}
@@ -161,58 +145,19 @@ class Net_URL2
}
$i = strcspn($url, '?#');
- $this->_path = substr($url, 0, $i);
+ $this->path = substr($url, 0, $i);
$url = substr($url, $i);
if (preg_match('@^\?([^#]*)@', $url, $reg)) {
- $this->_query = $reg[1];
+ $this->query = $reg[1];
$url = substr($url, strlen($reg[0]));
}
if ($url) {
- $this->_fragment = substr($url, 1);
+ $this->fragment = substr($url, 1);
}
}
- /**
- * Magic Setter.
- *
- * This method will magically set the value of a private variable ($var)
- * with the value passed as the args
- *
- * @param string $var The private variable to set.
- * @param mixed $arg An argument of any type.
- * @return void
- */
- public function __set($var, $arg)
- {
- $method = 'set' . $var;
- if (method_exists($this, $method)) {
- $this->$method($arg);
- }
- }
-
- /**
- * Magic Getter.
- *
- * This is the magic get method to retrieve the private variable
- * that was set by either __set() or it's setter...
- *
- * @param string $var The property name to retrieve.
- * @return mixed $this->$var Either a boolean false if the
- * property is not set or the value
- * of the private property.
- */
- public function __get($var)
- {
- $method = 'get' . $var;
- if (method_exists($this, $method)) {
- return $this->$method();
- }
-
- return false;
- }
-
/**
* Returns the scheme, e.g. "http" or "urn", or false if there is no
* scheme specified, i.e. if this is a relative URL.
@@ -221,23 +166,18 @@ class Net_URL2
*/
public function getScheme()
{
- return $this->_scheme;
+ return $this->scheme;
}
/**
- * Sets the scheme, e.g. "http" or "urn". Specify false if there is no
- * scheme specified, i.e. if this is a relative URL.
- *
- * @param string|bool $scheme e.g. "http" or "urn", or false if there is no
- * scheme specified, i.e. if this is a relative
- * URL
+ * @param string|bool $scheme
*
* @return void
* @see getScheme()
*/
public function setScheme($scheme)
{
- $this->_scheme = $scheme;
+ $this->scheme = $scheme;
}
/**
@@ -248,9 +188,7 @@ class Net_URL2
*/
public function getUser()
{
- return $this->_userinfo !== false
- ? preg_replace('@:.*$@', '', $this->_userinfo)
- : false;
+ return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false;
}
/**
@@ -263,9 +201,7 @@ class Net_URL2
*/
public function getPassword()
{
- return $this->_userinfo !== false
- ? substr(strstr($this->_userinfo, ':'), 1)
- : false;
+ return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false;
}
/**
@@ -276,7 +212,7 @@ class Net_URL2
*/
public function getUserinfo()
{
- return $this->_userinfo;
+ return $this->userinfo;
}
/**
@@ -284,15 +220,15 @@ class Net_URL2
* in the userinfo part as username ":" password.
*
* @param string|bool $userinfo userinfo or username
- * @param string|bool $password optional password, or false
+ * @param string|bool $password
*
* @return void
*/
public function setUserinfo($userinfo, $password = false)
{
- $this->_userinfo = $userinfo;
+ $this->userinfo = $userinfo;
if ($password !== false) {
- $this->_userinfo .= ':' . $password;
+ $this->userinfo .= ':' . $password;
}
}
@@ -300,24 +236,21 @@ class Net_URL2
* Returns the host part, or false if there is no authority part, e.g.
* relative URLs.
*
- * @return string|bool a hostname, an IP address, or false
+ * @return string|bool
*/
public function getHost()
{
- return $this->_host;
+ return $this->host;
}
/**
- * Sets the host part. Specify false if there is no authority part, e.g.
- * relative URLs.
- *
- * @param string|bool $host a hostname, an IP address, or false
+ * @param string|bool $host
*
* @return void
*/
public function setHost($host)
{
- $this->_host = $host;
+ $this->host = $host;
}
/**
@@ -328,72 +261,65 @@ class Net_URL2
*/
public function getPort()
{
- return $this->_port;
+ return $this->port;
}
/**
- * Sets the port number. Specify false if there is no port number specified,
- * i.e. if the default port is to be used.
- *
- * @param int|bool $port a port number, or false
+ * @param int|bool $port
*
* @return void
*/
public function setPort($port)
{
- $this->_port = intval($port);
+ $this->port = intval($port);
}
/**
* Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
- * false if there is no authority.
+ * false if there is no authority none.
*
* @return string|bool
*/
public function getAuthority()
{
- if (!$this->_host) {
+ if (!$this->host) {
return false;
}
$authority = '';
- if ($this->_userinfo !== false) {
- $authority .= $this->_userinfo . '@';
+ if ($this->userinfo !== false) {
+ $authority .= $this->userinfo . '@';
}
- $authority .= $this->_host;
+ $authority .= $this->host;
- if ($this->_port !== false) {
- $authority .= ':' . $this->_port;
+ if ($this->port !== false) {
+ $authority .= ':' . $this->port;
}
return $authority;
}
/**
- * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
- * false if there is no authority.
- *
- * @param string|false $authority a hostname or an IP addresse, possibly
- * with userinfo prefixed and port number
- * appended, e.g. "foo:bar@example.org:81".
+ * @param string|false $authority
*
* @return void
*/
public function setAuthority($authority)
{
- $this->_userinfo = false;
- $this->_host = false;
- $this->_port = false;
- if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
+ $this->user = false;
+ $this->pass = false;
+ $this->host = false;
+ $this->port = false;
+ if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
if ($reg[1]) {
- $this->_userinfo = $reg[2];
+ $this->userinfo = $reg[2];
}
- $this->_host = $reg[3];
+ $this->host = $reg[3];
if (isset($reg[5])) {
- $this->_port = intval($reg[5]);
+ $this->port = intval($reg[5]);
}
}
}
@@ -405,74 +331,65 @@ class Net_URL2
*/
public function getPath()
{
- return $this->_path;
+ return $this->path;
}
/**
- * Sets the path part (possibly an empty string).
- *
- * @param string $path a path
+ * @param string $path
*
* @return void
*/
public function setPath($path)
{
- $this->_path = $path;
+ $this->path = $path;
}
/**
* Returns the query string (excluding the leading "?"), or false if "?"
- * is not present in the URL.
+ * isn't present in the URL.
*
* @return string|bool
* @see self::getQueryVariables()
*/
public function getQuery()
{
- return $this->_query;
+ return $this->query;
}
/**
- * Sets the query string (excluding the leading "?"). Specify false if "?"
- * is not present in the URL.
- *
- * @param string|bool $query a query string, e.g. "foo=1&bar=2"
+ * @param string|bool $query
*
* @return void
* @see self::setQueryVariables()
*/
public function setQuery($query)
{
- $this->_query = $query;
+ $this->query = $query;
}
/**
- * Returns the fragment name, or false if "#" is not present in the URL.
+ * Returns the fragment name, or false if "#" isn't present in the URL.
*
* @return string|bool
*/
public function getFragment()
{
- return $this->_fragment;
+ return $this->fragment;
}
/**
- * Sets the fragment name. Specify false if "#" is not present in the URL.
- *
- * @param string|bool $fragment a fragment excluding the leading "#", or
- * false
+ * @param string|bool $fragment
*
* @return void
*/
public function setFragment($fragment)
{
- $this->_fragment = $fragment;
+ $this->fragment = $fragment;
}
/**
* Returns the query string like an array as the variables would appear in
- * $_GET in a PHP script. If the URL does not contain a "?", an empty array
- * is returned.
+ * $_GET in a PHP script.
*
* @return array
*/
@@ -481,7 +398,7 @@ class Net_URL2
$pattern = '/[' .
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
']/';
- $parts = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
+ $parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach ($parts as $part) {
@@ -528,8 +445,6 @@ class Net_URL2
}
/**
- * Sets the query string to the specified variable in the query string.
- *
* @param array $array (name => value) array
*
* @return void
@@ -537,11 +452,11 @@ class Net_URL2
public function setQueryVariables(array $array)
{
if (!$array) {
- $this->_query = false;
+ $this->query = false;
} else {
foreach ($array as $name => $value) {
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
- $name = self::urlencode($name);
+ $name = rawurlencode($name);
}
if (is_array($value)) {
@@ -551,21 +466,19 @@ class Net_URL2
: ($name . '=' . $v);
}
} elseif (!is_null($value)) {
- $parts[] = $name . '=' . self::urlencode($value);
+ $parts[] = $name . '=' . $value;
} else {
$parts[] = $name;
}
}
- $this->_query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
- $parts);
+ $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
+ $parts);
}
}
/**
- * Sets the specified variable in the query string.
- *
- * @param string $name variable name
- * @param mixed $value variable value
+ * @param string $name
+ * @param mixed $value
*
* @return array
*/
@@ -577,9 +490,7 @@ class Net_URL2
}
/**
- * Removes the specifed variable from the query string.
- *
- * @param string $name a query string variable, e.g. "foo" in "?foo=1"
+ * @param string $name
*
* @return void
*/
@@ -600,38 +511,27 @@ class Net_URL2
// See RFC 3986, section 5.3
$url = "";
- if ($this->_scheme !== false) {
- $url .= $this->_scheme . ':';
+ if ($this->scheme !== false) {
+ $url .= $this->scheme . ':';
}
$authority = $this->getAuthority();
if ($authority !== false) {
$url .= '//' . $authority;
}
- $url .= $this->_path;
+ $url .= $this->path;
- if ($this->_query !== false) {
- $url .= '?' . $this->_query;
+ if ($this->query !== false) {
+ $url .= '?' . $this->query;
}
- if ($this->_fragment !== false) {
- $url .= '#' . $this->_fragment;
+ if ($this->fragment !== false) {
+ $url .= '#' . $this->fragment;
}
return $url;
}
- /**
- * Returns a string representation of this URL.
- *
- * @return string
- * @see toString()
- */
- public function __toString()
- {
- return $this->getURL();
- }
-
/**
* Returns a normalized string representation of this URL. This is useful
* for comparison of URLs.
@@ -655,38 +555,36 @@ class Net_URL2
// See RFC 3886, section 6
// Schemes are case-insensitive
- if ($this->_scheme) {
- $this->_scheme = strtolower($this->_scheme);
+ if ($this->scheme) {
+ $this->scheme = strtolower($this->scheme);
}
// Hostnames are case-insensitive
- if ($this->_host) {
- $this->_host = strtolower($this->_host);
+ if ($this->host) {
+ $this->host = strtolower($this->host);
}
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
- if ($this->_port &&
- $this->_scheme &&
- $this->_port == getservbyname($this->_scheme, 'tcp')) {
+ if ($this->port &&
+ $this->scheme &&
+ $this->port == getservbyname($this->scheme, 'tcp')) {
- $this->_port = false;
+ $this->port = false;
}
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
- foreach (array('_userinfo', '_host', '_path') as $part) {
+ foreach (array('userinfo', 'host', 'path') as $part) {
if ($this->$part) {
- $this->$part = preg_replace('/%[0-9a-f]{2}/ie',
- 'strtoupper("\0")',
- $this->$part);
+ $this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part);
}
}
// Path segment normalization (RFC 3986, section 6.2.2.3)
- $this->_path = self::removeDotSegments($this->_path);
+ $this->path = self::removeDotSegments($this->path);
// Scheme based normalization (RFC 3986, section 6.2.3)
- if ($this->_host && !$this->_path) {
- $this->_path = '/';
+ if ($this->host && !$this->path) {
+ $this->path = '/';
}
}
@@ -697,7 +595,7 @@ class Net_URL2
*/
public function isAbsolute()
{
- return (bool) $this->_scheme;
+ return (bool) $this->scheme;
}
/**
@@ -710,7 +608,7 @@ class Net_URL2
*/
public function resolve($reference)
{
- if (!$reference instanceof Net_URL2) {
+ if (is_string($reference)) {
$reference = new self($reference);
}
if (!$this->isAbsolute()) {
@@ -719,54 +617,54 @@ class Net_URL2
// A non-strict parser may ignore a scheme in the reference if it is
// identical to the base URI's scheme.
- if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
- $reference->_scheme = false;
+ if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) {
+ $reference->scheme = false;
}
$target = new self('');
- if ($reference->_scheme !== false) {
- $target->_scheme = $reference->_scheme;
+ if ($reference->scheme !== false) {
+ $target->scheme = $reference->scheme;
$target->setAuthority($reference->getAuthority());
- $target->_path = self::removeDotSegments($reference->_path);
- $target->_query = $reference->_query;
+ $target->path = self::removeDotSegments($reference->path);
+ $target->query = $reference->query;
} else {
$authority = $reference->getAuthority();
if ($authority !== false) {
$target->setAuthority($authority);
- $target->_path = self::removeDotSegments($reference->_path);
- $target->_query = $reference->_query;
+ $target->path = self::removeDotSegments($reference->path);
+ $target->query = $reference->query;
} else {
- if ($reference->_path == '') {
- $target->_path = $this->_path;
- if ($reference->_query !== false) {
- $target->_query = $reference->_query;
+ if ($reference->path == '') {
+ $target->path = $this->path;
+ if ($reference->query !== false) {
+ $target->query = $reference->query;
} else {
- $target->_query = $this->_query;
+ $target->query = $this->query;
}
} else {
- if (substr($reference->_path, 0, 1) == '/') {
- $target->_path = self::removeDotSegments($reference->_path);
+ if (substr($reference->path, 0, 1) == '/') {
+ $target->path = self::removeDotSegments($reference->path);
} else {
// Merge paths (RFC 3986, section 5.2.3)
- if ($this->_host !== false && $this->_path == '') {
- $target->_path = '/' . $this->_path;
+ if ($this->host !== false && $this->path == '') {
+ $target->path = '/' . $this->path;
} else {
- $i = strrpos($this->_path, '/');
+ $i = strrpos($this->path, '/');
if ($i !== false) {
- $target->_path = substr($this->_path, 0, $i + 1);
+ $target->path = substr($this->path, 0, $i + 1);
}
- $target->_path .= $reference->_path;
+ $target->path .= $reference->path;
}
- $target->_path = self::removeDotSegments($target->_path);
+ $target->path = self::removeDotSegments($target->path);
}
- $target->_query = $reference->_query;
+ $target->query = $reference->query;
}
$target->setAuthority($this->getAuthority());
}
- $target->_scheme = $this->_scheme;
+ $target->scheme = $this->scheme;
}
- $target->_fragment = $reference->_fragment;
+ $target->fragment = $reference->fragment;
return $target;
}
@@ -779,7 +677,7 @@ class Net_URL2
*
* @return string a path
*/
- public static function removeDotSegments($path)
+ private static function removeDotSegments($path)
{
$output = '';
@@ -787,25 +685,28 @@ class Net_URL2
// method
$j = 0;
while ($path && $j++ < 100) {
+ // Step A
if (substr($path, 0, 2) == './') {
- // Step 2.A
$path = substr($path, 2);
} elseif (substr($path, 0, 3) == '../') {
- // Step 2.A
$path = substr($path, 3);
+
+ // Step B
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
- // Step 2.B
$path = '/' . substr($path, 3);
+
+ // Step C
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
- // Step 2.C
- $path = '/' . substr($path, 4);
- $i = strrpos($output, '/');
+ $path = '/' . substr($path, 4);
+ $i = strrpos($output, '/');
$output = $i === false ? '' : substr($output, 0, $i);
+
+ // Step D
} elseif ($path == '.' || $path == '..') {
- // Step 2.D
$path = '';
+
+ // Step E
} else {
- // Step 2.E
$i = strpos($path, '/');
if ($i === 0) {
$i = strpos($path, '/', 1);
@@ -821,22 +722,6 @@ class Net_URL2
return $output;
}
- /**
- * Percent-encodes all non-alphanumeric characters except these: _ . - ~
- * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
- * 5.2.x and earlier.
- *
- * @param $raw the string to encode
- * @return string
- */
- public static function urlencode($string)
- {
- $encoded = rawurlencode($string);
- // This is only necessary in PHP < 5.3.
- $encoded = str_replace('%7E', '~', $encoded);
- return $encoded;
- }
-
/**
* Returns a Net_URL2 instance representing the canonical URL of the
* currently executing PHP script.
@@ -852,13 +737,13 @@ class Net_URL2
// Begin with a relative URL
$url = new self($_SERVER['PHP_SELF']);
- $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
- $url->_host = $_SERVER['SERVER_NAME'];
+ $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $url->host = $_SERVER['SERVER_NAME'];
$port = intval($_SERVER['SERVER_PORT']);
- if ($url->_scheme == 'http' && $port != 80 ||
- $url->_scheme == 'https' && $port != 443) {
+ if ($url->scheme == 'http' && $port != 80 ||
+ $url->scheme == 'https' && $port != 443) {
- $url->_port = $port;
+ $url->port = $port;
}
return $url;
}
@@ -888,7 +773,7 @@ class Net_URL2
// Begin with a relative URL
$url = new self($_SERVER['REQUEST_URI']);
- $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
// Set host and possibly port
$url->setAuthority($_SERVER['HTTP_HOST']);
return $url;
@@ -907,10 +792,10 @@ class Net_URL2
*/
function setOption($optionName, $value)
{
- if (!array_key_exists($optionName, $this->_options)) {
+ if (!array_key_exists($optionName, $this->options)) {
return false;
}
- $this->_options[$optionName] = $value;
+ $this->options[$optionName] = $value;
}
/**
@@ -922,7 +807,7 @@ class Net_URL2
*/
function getOption($optionName)
{
- return isset($this->_options[$optionName])
- ? $this->_options[$optionName] : false;
+ return isset($this->options[$optionName])
+ ? $this->options[$optionName] : false;
}
}
diff --git a/install.php b/install.php
index d34e92dab..6bfc4c2e2 100644
--- a/install.php
+++ b/install.php
@@ -93,13 +93,6 @@ $external_libraries=array(
'include'=>'HTTP/Request.php',
'check_class'=>'HTTP_Request'
),
- array(
- 'name'=>'HTTP_Request2',
- 'pear'=>'HTTP_Request2',
- 'url'=>'http://pear.php.net/package/HTTP_Request2',
- 'include'=>'HTTP/Request2.php',
- 'check_class'=>'HTTP_Request2'
- ),
array(
'name'=>'Mail',
'pear'=>'Mail',
diff --git a/lib/Shorturl_api.php b/lib/Shorturl_api.php
index ef0d8dda4..18ae7719b 100644
--- a/lib/Shorturl_api.php
+++ b/lib/Shorturl_api.php
@@ -41,17 +41,22 @@ abstract class ShortUrlApi
return strlen($url) >= common_config('site', 'shorturllength');
}
- protected function http_post($data)
- {
- $request = new HTTPClient($this->service_url);
- return $request->post($data);
+ protected function http_post($data) {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $this->service_url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+ $response = curl_exec($ch);
+ $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ curl_close($ch);
+ if (($code < 200) || ($code >= 400)) return false;
+ return $response;
}
- protected function http_get($url)
- {
- $service = $this->service_url . urlencode($url);
- $request = new HTTPClient($service);
- return $request->get();
+ protected function http_get($url) {
+ $encoded_url = urlencode($url);
+ return file_get_contents("{$this->service_url}$encoded_url");
}
protected function tidy($response) {
diff --git a/lib/curlclient.php b/lib/curlclient.php
new file mode 100644
index 000000000..c307c2984
--- /dev/null
+++ b/lib/curlclient.php
@@ -0,0 +1,179 @@
+.
+ *
+ * @category HTTP
+ * @package StatusNet
+ * @author Evan Prodromou
+ * @copyright 2009 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/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+define(CURLCLIENT_VERSION, "0.1");
+
+/**
+ * Wrapper for Curl
+ *
+ * Makes Curl HTTP client calls within our HTTPClient framework
+ *
+ * @category HTTP
+ * @package StatusNet
+ * @author Evan Prodromou
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class CurlClient extends HTTPClient
+{
+ function __construct()
+ {
+ }
+
+ function head($url, $headers=null)
+ {
+ $ch = curl_init($url);
+
+ $this->setup($ch);
+
+ curl_setopt_array($ch,
+ array(CURLOPT_NOBODY => true));
+
+ if (!is_null($headers)) {
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ }
+
+ $result = curl_exec($ch);
+
+ curl_close($ch);
+
+ return $this->parseResults($result);
+ }
+
+ function get($url, $headers=null)
+ {
+ $ch = curl_init($url);
+
+ $this->setup($ch);
+
+ if (!is_null($headers)) {
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ }
+
+ $result = curl_exec($ch);
+
+ curl_close($ch);
+
+ return $this->parseResults($result);
+ }
+
+ function post($url, $headers=null, $body=null)
+ {
+ $ch = curl_init($url);
+
+ $this->setup($ch);
+
+ curl_setopt($ch, CURLOPT_POST, true);
+
+ if (!is_null($body)) {
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+ }
+
+ if (!is_null($headers)) {
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ }
+
+ $result = curl_exec($ch);
+
+ curl_close($ch);
+
+ return $this->parseResults($result);
+ }
+
+ function setup($ch)
+ {
+ curl_setopt_array($ch,
+ array(CURLOPT_USERAGENT => $this->userAgent(),
+ CURLOPT_HEADER => true,
+ CURLOPT_RETURNTRANSFER => true));
+ }
+
+ function userAgent()
+ {
+ $version = curl_version();
+ return parent::userAgent() . " CurlClient/".CURLCLIENT_VERSION . " cURL/" . $version['version'];
+ }
+
+ function parseResults($results)
+ {
+ $resp = new HTTPResponse();
+
+ $lines = explode("\r\n", $results);
+
+ if (preg_match("#^HTTP/1.[01] (\d\d\d) .+$#", $lines[0], $match)) {
+ $resp->code = $match[1];
+ } else {
+ throw Exception("Bad format: initial line is not HTTP status line");
+ }
+
+ $lastk = null;
+
+ for ($i = 1; $i < count($lines); $i++) {
+ $l =& $lines[$i];
+ if (mb_strlen($l) == 0) {
+ $resp->body = implode("\r\n", array_slice($lines, $i + 1));
+ break;
+ }
+ if (preg_match("#^(\S+):\s+(.*)$#", $l, $match)) {
+ $k = $match[1];
+ $v = $match[2];
+
+ if (array_key_exists($k, $resp->headers)) {
+ if (is_array($resp->headers[$k])) {
+ $resp->headers[$k][] = $v;
+ } else {
+ $resp->headers[$k] = array($resp->headers[$k], $v);
+ }
+ } else {
+ $resp->headers[$k] = $v;
+ }
+ $lastk = $k;
+ } else if (preg_match("#^\s+(.*)$#", $l, $match)) {
+ // continuation line
+ if (is_null($lastk)) {
+ throw Exception("Bad format: initial whitespace in headers");
+ }
+ $h =& $resp->headers[$lastk];
+ if (is_array($h)) {
+ $n = count($h);
+ $h[$n-1] .= $match[1];
+ } else {
+ $h .= $match[1];
+ }
+ }
+ }
+
+ return $resp;
+ }
+}
diff --git a/lib/default.php b/lib/default.php
index f6cc4b725..7ec8558b0 100644
--- a/lib/default.php
+++ b/lib/default.php
@@ -228,6 +228,8 @@ $default =
array('contentlimit' => null),
'message' =>
array('contentlimit' => null),
+ 'http' =>
+ array('client' => 'curl'), // XXX: should this be the default?
'location' =>
array('namespace' => 1), // 1 = geonames, 2 = Yahoo Where on Earth
);
diff --git a/lib/httpclient.php b/lib/httpclient.php
index ee894e983..f16e31e10 100644
--- a/lib/httpclient.php
+++ b/lib/httpclient.php
@@ -31,9 +31,6 @@ if (!defined('STATUSNET')) {
exit(1);
}
-require_once 'HTTP/Request2.php';
-require_once 'HTTP/Request2/Response.php';
-
/**
* Useful structure for HTTP responses
*
@@ -41,42 +38,18 @@ require_once 'HTTP/Request2/Response.php';
* ways of doing them. This class hides the specifics of what underlying
* library (curl or PHP-HTTP or whatever) that's used.
*
- * This extends the HTTP_Request2_Response class with methods to get info
- * about any followed redirects.
- *
* @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @author Brion Vibber
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
+ * @package StatusNet
+ * @author Evan Prodromou
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
*/
-class HTTPResponse extends HTTP_Request2_Response
-{
- function __construct(HTTP_Request2_Response $response, $url, $redirects=0)
- {
- foreach (get_object_vars($response) as $key => $val) {
- $this->$key = $val;
- }
- $this->url = strval($url);
- $this->redirectCount = intval($redirects);
- }
-
- /**
- * Get the count of redirects that have been followed, if any.
- * @return int
- */
- function getRedirectCount() {
- return $this->redirectCount;
- }
- /**
- * Gets the final target URL, after any redirects have been followed.
- * @return string URL
- */
- function getUrl() {
- return $this->url;
- }
+class HTTPResponse
+{
+ public $code = null;
+ public $headers = array();
+ public $body = null;
}
/**
@@ -86,133 +59,64 @@ class HTTPResponse extends HTTP_Request2_Response
* ways of doing them. This class hides the specifics of what underlying
* library (curl or PHP-HTTP or whatever) that's used.
*
- * This extends the PEAR HTTP_Request2 package:
- * - sends StatusNet-specific User-Agent header
- * - 'follow_redirects' config option, defaulting off
- * - 'max_redirs' config option, defaulting to 10
- * - extended response class adds getRedirectCount() and getUrl() methods
- * - get() and post() convenience functions return body content directly
- *
* @category HTTP
* @package StatusNet
* @author Evan Prodromou
- * @author Brion Vibber
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
-class HTTPClient extends HTTP_Request2
+class HTTPClient
{
+ static $_client = null;
- function __construct($url=null, $method=self::METHOD_GET, $config=array())
+ static function start()
{
- $this->config['max_redirs'] = 10;
- $this->config['follow_redirects'] = false;
- parent::__construct($url, $method, $config);
- $this->setHeader('User-Agent', $this->userAgent());
+ if (!is_null(self::$_client)) {
+ return self::$_client;
+ }
+
+ $type = common_config('http', 'client');
+
+ switch ($type) {
+ case 'curl':
+ self::$_client = new CurlClient();
+ break;
+ default:
+ throw new Exception("Unknown HTTP client type '$type'");
+ break;
+ }
+
+ return self::$_client;
}
- /**
- * Convenience function to run a get request and return the response body.
- * Use when you don't need to get into details of the response.
- *
- * @return mixed string on success, false on failure
- */
- function get()
+ function head($url, $headers)
{
- $this->setMethod(self::METHOD_GET);
- return $this->doRequest();
+ throw new Exception("HEAD method unimplemented");
}
- /**
- * Convenience function to post form data and return the response body.
- * Use when you don't need to get into details of the response.
- *
- * @param array associative array of form data to submit
- * @return mixed string on success, false on failure
- */
- public function post($data=array())
+ function get($url, $headers)
{
- $this->setMethod(self::METHOD_POST);
- if ($data) {
- $this->addPostParameter($data);
- }
- return $this->doRequest();
+ throw new Exception("GET method unimplemented");
}
- /**
- * @return mixed string on success, false on failure
- */
- protected function doRequest()
+ function post($url, $headers, $body)
{
- try {
- $response = $this->send();
- $code = $response->getStatus();
- if (($code < 200) || ($code >= 400)) {
- return false;
- }
- return $response->getBody();
- } catch (HTTP_Request2_Exception $e) {
- $this->log(LOG_ERR, $e->getMessage());
- return false;
- }
+ throw new Exception("POST method unimplemented");
}
-
- protected function log($level, $detail) {
- $method = $this->getMethod();
- $url = $this->getUrl();
- common_log($level, __CLASS__ . ": HTTP $method $url - $detail");
+
+ function put($url, $headers, $body)
+ {
+ throw new Exception("PUT method unimplemented");
}
- /**
- * Pulls up StatusNet's customized user-agent string, so services
- * we hit can track down the responsible software.
- */
- function userAgent()
+ function delete($url, $headers)
{
- return "StatusNet/".STATUSNET_VERSION." (".STATUSNET_CODENAME.")";
+ throw new Exception("DELETE method unimplemented");
}
- function send()
+ function userAgent()
{
- $maxRedirs = intval($this->config['max_redirs']);
- if (empty($this->config['follow_redirects'])) {
- $maxRedirs = 0;
- }
- $redirs = 0;
- do {
- try {
- $response = parent::send();
- } catch (HTTP_Request2_Exception $e) {
- $this->log(LOG_ERR, $e->getMessage());
- throw $e;
- }
- $code = $response->getStatus();
- if ($code >= 200 && $code < 300) {
- $reason = $response->getReasonPhrase();
- $this->log(LOG_INFO, "$code $reason");
- } elseif ($code >= 300 && $code < 400) {
- $url = $this->getUrl();
- $target = $response->getHeader('Location');
-
- if (++$redirs >= $maxRedirs) {
- common_log(LOG_ERR, __CLASS__ . ": Too many redirects: skipping $code redirect from $url to $target");
- break;
- }
- try {
- $this->setUrl($target);
- $this->setHeader('Referer', $url);
- common_log(LOG_INFO, __CLASS__ . ": Following $code redirect from $url to $target");
- continue;
- } catch (HTTP_Request2_Exception $e) {
- common_log(LOG_ERR, __CLASS__ . ": Invalid $code redirect from $url to $target");
- }
- } else {
- $reason = $response->getReasonPhrase();
- $this->log(LOG_ERR, "$code $reason");
- }
- break;
- } while ($maxRedirs);
- return new HTTPResponse($response, $this->getUrl(), $redirs);
+ return "StatusNet/".STATUSNET_VERSION." (".STATUSNET_CODENAME.")";
}
}
diff --git a/lib/oauthclient.php b/lib/oauthclient.php
index 1a86e2460..f1827726e 100644
--- a/lib/oauthclient.php
+++ b/lib/oauthclient.php
@@ -43,7 +43,7 @@ require_once 'OAuth.php';
* @link http://status.net/
*
*/
-class OAuthClientException extends Exception
+class OAuthClientCurlException extends Exception
{
}
@@ -97,14 +97,9 @@ class OAuthClient
function getRequestToken($url)
{
$response = $this->oAuthGet($url);
- $arr = array();
- parse_str($response, $arr);
- if (isset($arr['oauth_token']) && isset($arr['oauth_token_secret'])) {
- $token = new OAuthToken($arr['oauth_token'], @$arr['oauth_token_secret']);
- return $token;
- } else {
- throw new OAuthClientException();
- }
+ parse_str($response);
+ $token = new OAuthToken($oauth_token, $oauth_token_secret);
+ return $token;
}
/**
@@ -182,7 +177,7 @@ class OAuthClient
}
/**
- * Make a HTTP request.
+ * Make a HTTP request using cURL.
*
* @param string $url Where to make the
* @param array $params post parameters
@@ -191,32 +186,40 @@ class OAuthClient
*/
function httpRequest($url, $params = null)
{
- $request = new HTTPClient($url);
- $request->setConfig(array(
- 'connect_timeout' => 120,
- 'timeout' => 120,
- 'follow_redirects' => true,
- 'ssl_verify_peer' => false,
- ));
-
- // Twitter is strict about accepting invalid "Expect" headers
- $request->setHeader('Expect', '');
+ $options = array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FAILONERROR => true,
+ CURLOPT_HEADER => false,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_USERAGENT => 'StatusNet',
+ CURLOPT_CONNECTTIMEOUT => 120,
+ CURLOPT_TIMEOUT => 120,
+ CURLOPT_HTTPAUTH => CURLAUTH_ANY,
+ CURLOPT_SSL_VERIFYPEER => false,
+
+ // Twitter is strict about accepting invalid "Expect" headers
+
+ CURLOPT_HTTPHEADER => array('Expect:')
+ );
if (isset($params)) {
- $request->setMethod(HTTP_Request2::METHOD_POST);
- $request->setBody($params);
+ $options[CURLOPT_POST] = true;
+ $options[CURLOPT_POSTFIELDS] = $params;
}
- try {
- $response = $request->send();
- $code = $response->getStatus();
- if ($code < 200 || $code >= 400) {
- throw new OAuthClientException($response->getBody(), $code);
- }
- return $response->getBody();
- } catch (Exception $e) {
- throw new OAuthClientException($e->getMessage(), $e->getCode());
+ $ch = curl_init($url);
+ curl_setopt_array($ch, $options);
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $msg = curl_error($ch);
+ $code = curl_errno($ch);
+ throw new OAuthClientCurlException($msg, $code);
}
+
+ curl_close($ch);
+
+ return $response;
}
}
diff --git a/lib/ping.php b/lib/ping.php
index 2797c1b2d..175bf8440 100644
--- a/lib/ping.php
+++ b/lib/ping.php
@@ -44,18 +44,20 @@ function ping_broadcast_notice($notice) {
array('nickname' => $profile->nickname)),
$tags));
- $request = new HTTPClient($notify_url, HTTP_Request2::METHOD_POST);
- $request->setHeader('Content-Type', 'text/xml');
- $request->setBody($req);
- $httpResponse = $request->send();
+ $context = stream_context_create(array('http' => array('method' => "POST",
+ 'header' =>
+ "Content-Type: text/xml\r\n".
+ "User-Agent: StatusNet/".STATUSNET_VERSION."\r\n",
+ 'content' => $req)));
+ $file = file_get_contents($notify_url, false, $context);
- if (!$httpResponse || mb_strlen($httpResponse->getBody()) == 0) {
+ if ($file === false || mb_strlen($file) == 0) {
common_log(LOG_WARNING,
"XML-RPC empty results for ping ($notify_url, $notice->id) ");
continue;
}
- $response = xmlrpc_decode($httpResponse->getBody());
+ $response = xmlrpc_decode($file);
if (is_array($response) && xmlrpc_is_fault($response)) {
common_log(LOG_WARNING,
diff --git a/lib/snapshot.php b/lib/snapshot.php
index 6829e8a75..ede846e5b 100644
--- a/lib/snapshot.php
+++ b/lib/snapshot.php
@@ -172,11 +172,26 @@ class Snapshot
{
// XXX: Use OICU2 and OAuth to make authorized requests
+ $postdata = http_build_query($this->stats);
+
+ $opts =
+ array('http' =>
+ array(
+ 'method' => 'POST',
+ 'header' => 'Content-type: '.
+ 'application/x-www-form-urlencoded',
+ 'content' => $postdata,
+ 'user_agent' => 'StatusNet/'.STATUSNET_VERSION
+ )
+ );
+
+ $context = stream_context_create($opts);
+
$reporturl = common_config('snapshot', 'reporturl');
- $request = new HTTPClient($reporturl, HTTP_Request2::METHOD_POST);
- $request->addPostParameter($this->stats);
- $request->send();
+ $result = @file_get_contents($reporturl, false, $context);
+
+ return $result;
}
/**
diff --git a/plugins/BlogspamNetPlugin.php b/plugins/BlogspamNetPlugin.php
index 3bdc73556..c14569746 100644
--- a/plugins/BlogspamNetPlugin.php
+++ b/plugins/BlogspamNetPlugin.php
@@ -22,7 +22,6 @@
* @category Plugin
* @package StatusNet
* @author Evan Prodromou
- * @author Brion Vibber
* @copyright 2009 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/
@@ -70,14 +69,14 @@ class BlogspamNetPlugin extends Plugin
{
$args = $this->testArgs($notice);
common_debug("Blogspamnet args = " . print_r($args, TRUE));
- $requestBody = xmlrpc_encode_request('testComment', array($args));
-
- $request = new HTTPClient($this->baseUrl, HTTP_Request2::METHOD_POST);
- $request->addHeader('Content-Type: text/xml');
- $request->setBody($requestBody);
- $httpResponse = $request->send();
-
- $response = xmlrpc_decode($httpResponse->getBody());
+ $request = xmlrpc_encode_request('testComment', array($args));
+ $context = stream_context_create(array('http' => array('method' => "POST",
+ 'header' =>
+ "Content-Type: text/xml\r\n".
+ "User-Agent: " . $this->userAgent(),
+ 'content' => $request)));
+ $file = file_get_contents($this->baseUrl, false, $context);
+ $response = xmlrpc_decode($file);
if (xmlrpc_is_fault($response)) {
throw new ServerException("$response[faultString] ($response[faultCode])", 500);
} else {
diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php
index 0513687e9..60f7a60c7 100644
--- a/plugins/LinkbackPlugin.php
+++ b/plugins/LinkbackPlugin.php
@@ -129,25 +129,27 @@ class LinkbackPlugin extends Plugin
}
}
- $request = new HTTPClient($endpoint, 'POST');
- $request->setHeader('User-Agent', $this->userAgent());
- $request->setHeader('Content-Type', 'text/xml');
- $request->setBody(xmlrpc_encode_request('pingback.ping', $args));
- try {
- $response = $request->send();
- } catch (HTTP_Request2_Exception $e) {
+ $request = xmlrpc_encode_request('pingback.ping', $args);
+ $context = stream_context_create(array('http' => array('method' => "POST",
+ 'header' =>
+ "Content-Type: text/xml\r\n".
+ "User-Agent: " . $this->userAgent(),
+ 'content' => $request)));
+ $file = file_get_contents($endpoint, false, $context);
+ if (!$file) {
common_log(LOG_WARNING,
- "Pingback request failed for '$url' ($endpoint)");
- }
- $response = xmlrpc_decode($response->getBody());
- if (xmlrpc_is_fault($response)) {
- common_log(LOG_WARNING,
- "Pingback error for '$url' ($endpoint): ".
- "$response[faultString] ($response[faultCode])");
+ "Pingback request failed for '$url' ($endpoint)");
} else {
- common_log(LOG_INFO,
- "Pingback success for '$url' ($endpoint): ".
- "'$response'");
+ $response = xmlrpc_decode($file);
+ if (xmlrpc_is_fault($response)) {
+ common_log(LOG_WARNING,
+ "Pingback error for '$url' ($endpoint): ".
+ "$response[faultString] ($response[faultCode])");
+ } else {
+ common_log(LOG_INFO,
+ "Pingback success for '$url' ($endpoint): ".
+ "'$response'");
+ }
}
}
diff --git a/plugins/SimpleUrl/SimpleUrlPlugin.php b/plugins/SimpleUrl/SimpleUrlPlugin.php
index d59d63e47..82d772048 100644
--- a/plugins/SimpleUrl/SimpleUrlPlugin.php
+++ b/plugins/SimpleUrl/SimpleUrlPlugin.php
@@ -65,6 +65,15 @@ class SimpleUrlPlugin extends Plugin
class SimpleUrl extends ShortUrlApi
{
protected function shorten_imp($url) {
- return $this->http_get($url);
+ $curlh = curl_init();
+ curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
+ curl_setopt($curlh, CURLOPT_USERAGENT, 'StatusNet');
+ curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
+
+ curl_setopt($curlh, CURLOPT_URL, $this->service_url.urlencode($url));
+ $short_url = curl_exec($curlh);
+
+ curl_close($curlh);
+ return $short_url;
}
}
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index 671e3c7af..ed2bf48a2 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -152,8 +152,8 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
$friends_ids = $client->friendsIds();
} catch (Exception $e) {
common_log(LOG_WARNING, $this->name() .
- ' - error getting friend ids: ' .
- $e->getMessage());
+ ' - cURL error getting friend ids ' .
+ $e->getCode() . ' - ' . $e->getMessage());
return $friends;
}
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index 6c91b2860..81bbbc7c5 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -109,16 +109,12 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$flink->find();
$flinks = array();
- common_log(LOG_INFO, "hello");
while ($flink->fetch()) {
if (($flink->noticesync & FOREIGN_NOTICE_RECV) ==
FOREIGN_NOTICE_RECV) {
$flinks[] = clone($flink);
- common_log(LOG_INFO, "sync: foreign id $flink->foreign_id");
- } else {
- common_log(LOG_INFO, "nothing to sync");
}
}
@@ -519,34 +515,31 @@ class TwitterStatusFetcher extends ParallelizingDaemon
return $id;
}
- /**
- * Fetch a remote avatar image and save to local storage.
- *
- * @param string $url avatar source URL
- * @param string $filename bare local filename for download
- * @return bool true on success, false on failure
- */
function fetchAvatar($url, $filename)
{
- common_debug($this->name() . " - Fetching Twitter avatar: $url");
+ $avatarfile = Avatar::path($filename);
- $request = new HTTPClient($url, 'GET', array(
- 'follow_redirects' => true,
- ));
- $data = $request->get();
- if ($data) {
- $avatarfile = Avatar::path($filename);
- $ok = file_put_contents($avatarfile, $data);
- if (!$ok) {
- common_log(LOG_WARNING, $this->name() .
- " - Couldn't open file $filename");
- return false;
- }
- } else {
+ $out = fopen($avatarfile, 'wb');
+ if (!$out) {
+ common_log(LOG_WARNING, $this->name() .
+ " - Couldn't open file $filename");
return false;
}
- return true;
+ common_debug($this->name() . " - Fetching Twitter avatar: $url");
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_FILE, $out);
+ curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
+ $result = curl_exec($ch);
+ curl_close($ch);
+
+ fclose($out);
+
+ return $result;
}
}
diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php
index 3c6803e49..1a5248a9b 100644
--- a/plugins/TwitterBridge/twitter.php
+++ b/plugins/TwitterBridge/twitter.php
@@ -215,7 +215,7 @@ function broadcast_basicauth($notice, $flink)
try {
$status = $client->statusesUpdate($statustxt);
- } catch (HTTP_Request2_Exception $e) {
+ } catch (BasicAuthCurlException $e) {
return process_error($e, $flink);
}
diff --git a/plugins/TwitterBridge/twitterauthorization.php b/plugins/TwitterBridge/twitterauthorization.php
index f1daefab1..2a93ff13e 100644
--- a/plugins/TwitterBridge/twitterauthorization.php
+++ b/plugins/TwitterBridge/twitterauthorization.php
@@ -125,7 +125,7 @@ class TwitterauthorizationAction extends Action
$auth_link = $client->getAuthorizeLink($req_tok);
- } catch (OAuthClientException $e) {
+ } catch (TwitterOAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage());
$this->serverError(_('Couldn\'t link your Twitter account.'));
diff --git a/plugins/TwitterBridge/twitterbasicauthclient.php b/plugins/TwitterBridge/twitterbasicauthclient.php
index e4cae7373..1040d72fb 100644
--- a/plugins/TwitterBridge/twitterbasicauthclient.php
+++ b/plugins/TwitterBridge/twitterbasicauthclient.php
@@ -31,6 +31,26 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
+/**
+ * Exception wrapper for cURL errors
+ *
+ * @category Integration
+ * @package StatusNet
+ * @author Adrian Lang
+ * @author Brenda Wallace
+ * @author Craig Andrews
+ * @author Dan Moore
+ * @author Evan Prodromou
+ * @author mEDI
+ * @author Sarven Capadisli
+ * @author Zach Copley * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ */
+class BasicAuthCurlException extends Exception
+{
+}
+
/**
* Class for talking to the Twitter API with HTTP Basic Auth.
*
@@ -178,27 +198,45 @@ class TwitterBasicAuthClient
*/
function httpRequest($url, $params = null, $auth = true)
{
- $request = new HTTPClient($url, 'GET', array(
- 'follow_redirects' => true,
- 'connect_timeout' => 120,
- 'timeout' => 120,
- 'ssl_verifypeer' => false,
- ));
-
- // Twitter is strict about accepting invalid "Expect" headers
- $request->setHeader('Expect', '');
+ $options = array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FAILONERROR => true,
+ CURLOPT_HEADER => false,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_USERAGENT => 'StatusNet',
+ CURLOPT_CONNECTTIMEOUT => 120,
+ CURLOPT_TIMEOUT => 120,
+ CURLOPT_HTTPAUTH => CURLAUTH_ANY,
+ CURLOPT_SSL_VERIFYPEER => false,
+
+ // Twitter is strict about accepting invalid "Expect" headers
+
+ CURLOPT_HTTPHEADER => array('Expect:')
+ );
if (isset($params)) {
- $request->setMethod('POST');
- $request->addPostParameter($params);
+ $options[CURLOPT_POST] = true;
+ $options[CURLOPT_POSTFIELDS] = $params;
}
if ($auth) {
- $request->setAuth($this->screen_name, $this->password);
+ $options[CURLOPT_USERPWD] = $this->screen_name .
+ ':' . $this->password;
}
- $response = $request->send();
- return $response->getBody();
+ $ch = curl_init($url);
+ curl_setopt_array($ch, $options);
+ $response = curl_exec($ch);
+
+ if ($response === false) {
+ $msg = curl_error($ch);
+ $code = curl_errno($ch);
+ throw new BasicAuthCurlException($msg, $code);
+ }
+
+ curl_close($ch);
+
+ return $response;
}
}
diff --git a/plugins/WikiHashtagsPlugin.php b/plugins/WikiHashtagsPlugin.php
index a9e675f5c..0c5649aa4 100644
--- a/plugins/WikiHashtagsPlugin.php
+++ b/plugins/WikiHashtagsPlugin.php
@@ -68,8 +68,10 @@ class WikiHashtagsPlugin extends Plugin
$editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit',
urlencode($tag));
- $request = new HTTPClient($url);
- $html = $request->get();
+ $context = stream_context_create(array('http' => array('method' => "GET",
+ 'header' =>
+ "User-Agent: " . $this->userAgent())));
+ $html = @file_get_contents($url, false, $context);
$action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section'));
@@ -98,4 +100,10 @@ class WikiHashtagsPlugin extends Plugin
return true;
}
+
+ function userAgent()
+ {
+ return 'WikiHashtagsPlugin/'.WIKIHASHTAGSPLUGIN_VERSION .
+ ' StatusNet/' . STATUSNET_VERSION;
+ }
}
diff --git a/scripts/enjitqueuehandler.php b/scripts/enjitqueuehandler.php
index 214cc02b4..08f733b07 100755
--- a/scripts/enjitqueuehandler.php
+++ b/scripts/enjitqueuehandler.php
@@ -46,8 +46,8 @@ class EnjitQueueHandler extends QueueHandler
function start()
{
- $this->log(LOG_INFO, "Starting EnjitQueueHandler");
- $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
+ $this->log(LOG_INFO, "Starting EnjitQueueHandler");
+ $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
return true;
}
@@ -56,16 +56,16 @@ class EnjitQueueHandler extends QueueHandler
$profile = Profile::staticGet($notice->profile_id);
- $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
+ $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
- if ( ! $notice->is_local ) {
- $this->log(LOG_INFO, "Skipping remote notice");
- return "skipped";
- }
+ if ( ! $notice->is_local ) {
+ $this->log(LOG_INFO, "Skipping remote notice");
+ return "skipped";
+ }
- #
- # Build an Atom message from the notice
- #
+ #
+ # Build an Atom message from the notice
+ #
$noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
$msg = $profile->nickname . ': ' . $notice->content;
@@ -86,20 +86,36 @@ class EnjitQueueHandler extends QueueHandler
$atom .= "".common_date_w3dtf($notice->modified)."\n";
$atom .= "\n";
- $url = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
- $data = array(
- 'msg' => $atom,
- );
-
- #
- # POST the message to $config['enjit']['apiurl']
- #
- $request = new HTTPClient($url, HTTP_Request2::METHOD_POST);
- $request->addPostFields($data);
- $response = $request->send();
-
- // @fixme handle_notice() is supposed to return true/false. Somethin' funky?
- return $response->getStatus();
+ $url = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
+ $data = "msg=$atom";
+
+ #
+ # POST the message to $config['enjit']['apiurl']
+ #
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, $url);
+
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POST, 1) ;
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+
+ # SSL and Debugging options
+ #
+ # curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
+ # curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+ # curl_setopt($ch, CURLOPT_VERBOSE, 1);
+
+ $result = curl_exec($ch);
+
+ $code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
+
+ $this->log(LOG_INFO, "Response Code: $code");
+
+ curl_close($ch);
+
+ return $code;
}
}
--
cgit v1.2.3-54-g00ecf
From 5581143bee602dbd5417f532f2b483e58d0a4269 Mon Sep 17 00:00:00 2001
From: Brion Vibber
Date: Wed, 28 Oct 2009 15:29:20 -0400
Subject: Rebuilt HTTPClient class as an extension of PEAR HTTP_Request2
package, adding redirect handling and convenience functions. Caching support
will be added in future work after unit tests have been added.
* extlib: add PEAR HTTP_Request2 0.4.1 alpha
* extlib: update PEAR Net_URL2 to 0.3.0 beta for HTTP_Request2 compatibility
* moved direct usage of CURL and file_get_contents to HTTPClient class, excluding external-sourced libraries
* adapted GeonamesPlugin for new HTTPResponse interface
Note some plugins haven't been fully tested yet.
---
classes/File_redirection.php | 68 +-
extlib/HTTP/Request2.php | 844 ++++++++++++++++++
extlib/HTTP/Request2/Adapter.php | 152 ++++
extlib/HTTP/Request2/Adapter/Curl.php | 383 ++++++++
extlib/HTTP/Request2/Adapter/Mock.php | 171 ++++
extlib/HTTP/Request2/Adapter/Socket.php | 971 +++++++++++++++++++++
extlib/HTTP/Request2/Exception.php | 62 ++
extlib/HTTP/Request2/MultipartBody.php | 274 ++++++
extlib/HTTP/Request2/Observer/Log.php | 215 +++++
extlib/HTTP/Request2/Response.php | 549 ++++++++++++
extlib/Net/URL2.php | 471 ++++++----
install.php | 7 +
lib/Shorturl_api.php | 24 +-
lib/curlclient.php | 179 ----
lib/default.php | 2 -
lib/httpclient.php | 213 ++++-
lib/oauthclient.php | 65 +-
lib/ping.php | 12 +-
lib/snapshot.php | 21 +-
plugins/BlogspamNetPlugin.php | 15 +-
plugins/GeonamesPlugin.php | 16 +-
plugins/LilUrl/LilUrlPlugin.php | 5 +-
plugins/LinkbackPlugin.php | 21 +-
plugins/SimpleUrl/SimpleUrlPlugin.php | 11 +-
.../TwitterBridge/daemons/synctwitterfriends.php | 4 +-
.../TwitterBridge/daemons/twitterstatusfetcher.php | 43 +-
plugins/TwitterBridge/twitter.php | 2 +-
plugins/TwitterBridge/twitterauthorization.php | 2 +-
plugins/TwitterBridge/twitterbasicauthclient.php | 68 +-
plugins/WikiHashtagsPlugin.php | 15 +-
scripts/enjitqueuehandler.php | 58 +-
31 files changed, 4275 insertions(+), 668 deletions(-)
create mode 100644 extlib/HTTP/Request2.php
create mode 100644 extlib/HTTP/Request2/Adapter.php
create mode 100644 extlib/HTTP/Request2/Adapter/Curl.php
create mode 100644 extlib/HTTP/Request2/Adapter/Mock.php
create mode 100644 extlib/HTTP/Request2/Adapter/Socket.php
create mode 100644 extlib/HTTP/Request2/Exception.php
create mode 100644 extlib/HTTP/Request2/MultipartBody.php
create mode 100644 extlib/HTTP/Request2/Observer/Log.php
create mode 100644 extlib/HTTP/Request2/Response.php
delete mode 100644 lib/curlclient.php
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/classes/File_redirection.php b/classes/File_redirection.php
index 79052bf7d..08a6e8d8b 100644
--- a/classes/File_redirection.php
+++ b/classes/File_redirection.php
@@ -47,18 +47,15 @@ class File_redirection extends Memcached_DataObject
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
- function _commonCurl($url, $redirs) {
- $curlh = curl_init();
- curl_setopt($curlh, CURLOPT_URL, $url);
- curl_setopt($curlh, CURLOPT_AUTOREFERER, true); // # setup referer header when folowing redirects
- curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 10); // # seconds to wait
- curl_setopt($curlh, CURLOPT_MAXREDIRS, $redirs); // # max number of http redirections to follow
- curl_setopt($curlh, CURLOPT_USERAGENT, USER_AGENT);
- curl_setopt($curlh, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
- curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curlh, CURLOPT_FILETIME, true);
- curl_setopt($curlh, CURLOPT_HEADER, true); // Include header in output
- return $curlh;
+ static function _commonHttp($url, $redirs) {
+ $request = new HTTPClient($url);
+ $request->setConfig(array(
+ 'connect_timeout' => 10, // # seconds to wait
+ 'max_redirs' => $redirs, // # max number of http redirections to follow
+ 'follow_redirects' => true, // Follow redirects
+ 'store_body' => false, // We won't need body content here.
+ ));
+ return $request;
}
function _redirectWhere_imp($short_url, $redirs = 10, $protected = false) {
@@ -82,32 +79,39 @@ class File_redirection extends Memcached_DataObject
if(strpos($short_url,'://') === false){
return $short_url;
}
- $curlh = File_redirection::_commonCurl($short_url, $redirs);
- // Don't include body in output
- curl_setopt($curlh, CURLOPT_NOBODY, true);
- curl_exec($curlh);
- $info = curl_getinfo($curlh);
- curl_close($curlh);
-
- if (405 == $info['http_code']) {
- $curlh = File_redirection::_commonCurl($short_url, $redirs);
- curl_exec($curlh);
- $info = curl_getinfo($curlh);
- curl_close($curlh);
+ try {
+ $request = self::_commonHttp($short_url, $redirs);
+ // Don't include body in output
+ $request->setMethod(HTTP_Request2::METHOD_HEAD);
+ $response = $request->send();
+
+ if (405 == $response->getStatus()) {
+ // Server doesn't support HEAD method? Can this really happen?
+ // We'll try again as a GET and ignore the response data.
+ $request = self::_commonHttp($short_url, $redirs);
+ $response = $request->send();
+ }
+ } catch (Exception $e) {
+ // Invalid URL or failure to reach server
+ return $short_url;
}
- if (!empty($info['redirect_count']) && File::isProtected($info['url'])) {
- return File_redirection::_redirectWhere_imp($short_url, $info['redirect_count'] - 1, true);
+ if ($response->getRedirectCount() && File::isProtected($response->getUrl())) {
+ // Bump back up the redirect chain until we find a non-protected URL
+ return self::_redirectWhere_imp($short_url, $response->getRedirectCount() - 1, true);
}
- $ret = array('code' => $info['http_code']
- , 'redirects' => $info['redirect_count']
- , 'url' => $info['url']);
+ $ret = array('code' => $response->getStatus()
+ , 'redirects' => $response->getRedirectCount()
+ , 'url' => $response->getUrl());
- if (!empty($info['content_type'])) $ret['type'] = $info['content_type'];
+ $type = $response->getHeader('Content-Type');
+ if ($type) $ret['type'] = $type;
if ($protected) $ret['protected'] = true;
- if (!empty($info['download_content_length'])) $ret['size'] = $info['download_content_length'];
- if (isset($info['filetime']) && ($info['filetime'] > 0)) $ret['time'] = $info['filetime'];
+ $size = $response->getHeader('Content-Length'); // @fixme bytes?
+ if ($size) $ret['size'] = $size;
+ $time = $response->getHeader('Last-Modified');
+ if ($time) $ret['time'] = strtotime($time);
return $ret;
}
diff --git a/extlib/HTTP/Request2.php b/extlib/HTTP/Request2.php
new file mode 100644
index 000000000..e06bb86bc
--- /dev/null
+++ b/extlib/HTTP/Request2.php
@@ -0,0 +1,844 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Request2.php 278226 2009-04-03 21:32:48Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * A class representing an URL as per RFC 3986.
+ */
+require_once 'Net/URL2.php';
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * Class representing a HTTP request
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ * @link http://tools.ietf.org/html/rfc2616#section-5
+ */
+class HTTP_Request2 implements SplSubject
+{
+ /**#@+
+ * Constants for HTTP request methods
+ *
+ * @link http://tools.ietf.org/html/rfc2616#section-5.1.1
+ */
+ const METHOD_OPTIONS = 'OPTIONS';
+ const METHOD_GET = 'GET';
+ const METHOD_HEAD = 'HEAD';
+ const METHOD_POST = 'POST';
+ const METHOD_PUT = 'PUT';
+ const METHOD_DELETE = 'DELETE';
+ const METHOD_TRACE = 'TRACE';
+ const METHOD_CONNECT = 'CONNECT';
+ /**#@-*/
+
+ /**#@+
+ * Constants for HTTP authentication schemes
+ *
+ * @link http://tools.ietf.org/html/rfc2617
+ */
+ const AUTH_BASIC = 'basic';
+ const AUTH_DIGEST = 'digest';
+ /**#@-*/
+
+ /**
+ * Regular expression used to check for invalid symbols in RFC 2616 tokens
+ * @link http://pear.php.net/bugs/bug.php?id=15630
+ */
+ const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!';
+
+ /**
+ * Regular expression used to check for invalid symbols in cookie strings
+ * @link http://pear.php.net/bugs/bug.php?id=15630
+ * @link http://cgi.netscape.com/newsref/std/cookie_spec.html
+ */
+ const REGEXP_INVALID_COOKIE = '/[\s,;]/';
+
+ /**
+ * Fileinfo magic database resource
+ * @var resource
+ * @see detectMimeType()
+ */
+ private static $_fileinfoDb;
+
+ /**
+ * Observers attached to the request (instances of SplObserver)
+ * @var array
+ */
+ protected $observers = array();
+
+ /**
+ * Request URL
+ * @var Net_URL2
+ */
+ protected $url;
+
+ /**
+ * Request method
+ * @var string
+ */
+ protected $method = self::METHOD_GET;
+
+ /**
+ * Authentication data
+ * @var array
+ * @see getAuth()
+ */
+ protected $auth;
+
+ /**
+ * Request headers
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * Configuration parameters
+ * @var array
+ * @see setConfig()
+ */
+ protected $config = array(
+ 'adapter' => 'HTTP_Request2_Adapter_Socket',
+ 'connect_timeout' => 10,
+ 'timeout' => 0,
+ 'use_brackets' => true,
+ 'protocol_version' => '1.1',
+ 'buffer_size' => 16384,
+ 'store_body' => true,
+
+ 'proxy_host' => '',
+ 'proxy_port' => '',
+ 'proxy_user' => '',
+ 'proxy_password' => '',
+ 'proxy_auth_scheme' => self::AUTH_BASIC,
+
+ 'ssl_verify_peer' => true,
+ 'ssl_verify_host' => true,
+ 'ssl_cafile' => null,
+ 'ssl_capath' => null,
+ 'ssl_local_cert' => null,
+ 'ssl_passphrase' => null,
+
+ 'digest_compat_ie' => false
+ );
+
+ /**
+ * Last event in request / response handling, intended for observers
+ * @var array
+ * @see getLastEvent()
+ */
+ protected $lastEvent = array(
+ 'name' => 'start',
+ 'data' => null
+ );
+
+ /**
+ * Request body
+ * @var string|resource
+ * @see setBody()
+ */
+ protected $body = '';
+
+ /**
+ * Array of POST parameters
+ * @var array
+ */
+ protected $postParams = array();
+
+ /**
+ * Array of file uploads (for multipart/form-data POST requests)
+ * @var array
+ */
+ protected $uploads = array();
+
+ /**
+ * Adapter used to perform actual HTTP request
+ * @var HTTP_Request2_Adapter
+ */
+ protected $adapter;
+
+
+ /**
+ * Constructor. Can set request URL, method and configuration array.
+ *
+ * Also sets a default value for User-Agent header.
+ *
+ * @param string|Net_Url2 Request URL
+ * @param string Request method
+ * @param array Configuration for this Request instance
+ */
+ public function __construct($url = null, $method = self::METHOD_GET, array $config = array())
+ {
+ if (!empty($url)) {
+ $this->setUrl($url);
+ }
+ if (!empty($method)) {
+ $this->setMethod($method);
+ }
+ $this->setConfig($config);
+ $this->setHeader('user-agent', 'HTTP_Request2/0.4.1 ' .
+ '(http://pear.php.net/package/http_request2) ' .
+ 'PHP/' . phpversion());
+ }
+
+ /**
+ * Sets the URL for this request
+ *
+ * If the URL has userinfo part (username & password) these will be removed
+ * and converted to auth data. If the URL does not have a path component,
+ * that will be set to '/'.
+ *
+ * @param string|Net_URL2 Request URL
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setUrl($url)
+ {
+ if (is_string($url)) {
+ $url = new Net_URL2($url);
+ }
+ if (!$url instanceof Net_URL2) {
+ throw new HTTP_Request2_Exception('Parameter is not a valid HTTP URL');
+ }
+ // URL contains username / password?
+ if ($url->getUserinfo()) {
+ $username = $url->getUser();
+ $password = $url->getPassword();
+ $this->setAuth(rawurldecode($username), $password? rawurldecode($password): '');
+ $url->setUserinfo('');
+ }
+ if ('' == $url->getPath()) {
+ $url->setPath('/');
+ }
+ $this->url = $url;
+
+ return $this;
+ }
+
+ /**
+ * Returns the request URL
+ *
+ * @return Net_URL2
+ */
+ public function getUrl()
+ {
+ return $this->url;
+ }
+
+ /**
+ * Sets the request method
+ *
+ * @param string
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception if the method name is invalid
+ */
+ public function setMethod($method)
+ {
+ // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1
+ if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) {
+ throw new HTTP_Request2_Exception("Invalid request method '{$method}'");
+ }
+ $this->method = $method;
+
+ return $this;
+ }
+
+ /**
+ * Returns the request method
+ *
+ * @return string
+ */
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ /**
+ * Sets the configuration parameter(s)
+ *
+ * The following parameters are available:
+ *
+ * - 'adapter' - adapter to use (string)
+ * - 'connect_timeout' - Connection timeout in seconds (integer)
+ * - 'timeout' - Total number of seconds a request can take.
+ * Use 0 for no limit, should be greater than
+ * 'connect_timeout' if set (integer)
+ * - 'use_brackets' - Whether to append [] to array variable names (bool)
+ * - 'protocol_version' - HTTP Version to use, '1.0' or '1.1' (string)
+ * - 'buffer_size' - Buffer size to use for reading and writing (int)
+ * - 'store_body' - Whether to store response body in response object.
+ * Set to false if receiving a huge response and
+ * using an Observer to save it (boolean)
+ * - 'proxy_host' - Proxy server host (string)
+ * - 'proxy_port' - Proxy server port (integer)
+ * - 'proxy_user' - Proxy auth username (string)
+ * - 'proxy_password' - Proxy auth password (string)
+ * - 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)
+ * - 'ssl_verify_peer' - Whether to verify peer's SSL certificate (bool)
+ * - 'ssl_verify_host' - Whether to check that Common Name in SSL
+ * certificate matches host name (bool)
+ * - 'ssl_cafile' - Cerificate Authority file to verify the peer
+ * with (use with 'ssl_verify_peer') (string)
+ * - 'ssl_capath' - Directory holding multiple Certificate
+ * Authority files (string)
+ * - 'ssl_local_cert' - Name of a file containing local cerificate (string)
+ * - 'ssl_passphrase' - Passphrase with which local certificate
+ * was encoded (string)
+ * - 'digest_compat_ie' - Whether to imitate behaviour of MSIE 5 and 6
+ * in using URL without query string in digest
+ * authentication (boolean)
+ *
+ *
+ * @param string|array configuration parameter name or array
+ * ('parameter name' => 'parameter value')
+ * @param mixed parameter value if $nameOrConfig is not an array
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception If the parameter is unknown
+ */
+ public function setConfig($nameOrConfig, $value = null)
+ {
+ if (is_array($nameOrConfig)) {
+ foreach ($nameOrConfig as $name => $value) {
+ $this->setConfig($name, $value);
+ }
+
+ } else {
+ if (!array_key_exists($nameOrConfig, $this->config)) {
+ throw new HTTP_Request2_Exception(
+ "Unknown configuration parameter '{$nameOrConfig}'"
+ );
+ }
+ $this->config[$nameOrConfig] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the value(s) of the configuration parameter(s)
+ *
+ * @param string parameter name
+ * @return mixed value of $name parameter, array of all configuration
+ * parameters if $name is not given
+ * @throws HTTP_Request2_Exception If the parameter is unknown
+ */
+ public function getConfig($name = null)
+ {
+ if (null === $name) {
+ return $this->config;
+ } elseif (!array_key_exists($name, $this->config)) {
+ throw new HTTP_Request2_Exception(
+ "Unknown configuration parameter '{$name}'"
+ );
+ }
+ return $this->config[$name];
+ }
+
+ /**
+ * Sets the autentification data
+ *
+ * @param string user name
+ * @param string password
+ * @param string authentication scheme
+ * @return HTTP_Request2
+ */
+ public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC)
+ {
+ if (empty($user)) {
+ $this->auth = null;
+ } else {
+ $this->auth = array(
+ 'user' => (string)$user,
+ 'password' => (string)$password,
+ 'scheme' => $scheme
+ );
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the authentication data
+ *
+ * The array has the keys 'user', 'password' and 'scheme', where 'scheme'
+ * is one of the HTTP_Request2::AUTH_* constants.
+ *
+ * @return array
+ */
+ public function getAuth()
+ {
+ return $this->auth;
+ }
+
+ /**
+ * Sets request header(s)
+ *
+ * The first parameter may be either a full header string 'header: value' or
+ * header name. In the former case $value parameter is ignored, in the latter
+ * the header's value will either be set to $value or the header will be
+ * removed if $value is null. The first parameter can also be an array of
+ * headers, in that case method will be called recursively.
+ *
+ * Note that headers are treated case insensitively as per RFC 2616.
+ *
+ *
+ * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar'
+ * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz'
+ * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux'
+ * $req->setHeader('FOO'); // removes 'Foo' header from request
+ *
+ *
+ * @param string|array header name, header string ('Header: value')
+ * or an array of headers
+ * @param string|null header value, header will be removed if null
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setHeader($name, $value = null)
+ {
+ if (is_array($name)) {
+ foreach ($name as $k => $v) {
+ if (is_string($k)) {
+ $this->setHeader($k, $v);
+ } else {
+ $this->setHeader($v);
+ }
+ }
+ } else {
+ if (null === $value && strpos($name, ':')) {
+ list($name, $value) = array_map('trim', explode(':', $name, 2));
+ }
+ // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2
+ if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) {
+ throw new HTTP_Request2_Exception("Invalid header name '{$name}'");
+ }
+ // Header names are case insensitive anyway
+ $name = strtolower($name);
+ if (null === $value) {
+ unset($this->headers[$name]);
+ } else {
+ $this->headers[$name] = $value;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the request headers
+ *
+ * The array is of the form ('header name' => 'header value'), header names
+ * are lowercased
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * Appends a cookie to "Cookie:" header
+ *
+ * @param string cookie name
+ * @param string cookie value
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function addCookie($name, $value)
+ {
+ $cookie = $name . '=' . $value;
+ if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
+ throw new HTTP_Request2_Exception("Invalid cookie: '{$cookie}'");
+ }
+ $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
+ $this->setHeader('cookie', $cookies . $cookie);
+
+ return $this;
+ }
+
+ /**
+ * Sets the request body
+ *
+ * @param string Either a string with the body or filename containing body
+ * @param bool Whether first parameter is a filename
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setBody($body, $isFilename = false)
+ {
+ if (!$isFilename) {
+ $this->body = (string)$body;
+ } else {
+ if (!($fp = @fopen($body, 'rb'))) {
+ throw new HTTP_Request2_Exception("Cannot open file {$body}");
+ }
+ $this->body = $fp;
+ if (empty($this->headers['content-type'])) {
+ $this->setHeader('content-type', self::detectMimeType($body));
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the request body
+ *
+ * @return string|resource|HTTP_Request2_MultipartBody
+ */
+ public function getBody()
+ {
+ if (self::METHOD_POST == $this->method &&
+ (!empty($this->postParams) || !empty($this->uploads))
+ ) {
+ if ('application/x-www-form-urlencoded' == $this->headers['content-type']) {
+ $body = http_build_query($this->postParams, '', '&');
+ if (!$this->getConfig('use_brackets')) {
+ $body = preg_replace('/%5B\d+%5D=/', '=', $body);
+ }
+ // support RFC 3986 by not encoding '~' symbol (request #15368)
+ return str_replace('%7E', '~', $body);
+
+ } elseif ('multipart/form-data' == $this->headers['content-type']) {
+ require_once 'HTTP/Request2/MultipartBody.php';
+ return new HTTP_Request2_MultipartBody(
+ $this->postParams, $this->uploads, $this->getConfig('use_brackets')
+ );
+ }
+ }
+ return $this->body;
+ }
+
+ /**
+ * Adds a file to form-based file upload
+ *
+ * Used to emulate file upload via a HTML form. The method also sets
+ * Content-Type of HTTP request to 'multipart/form-data'.
+ *
+ * If you just want to send the contents of a file as the body of HTTP
+ * request you should use setBody() method.
+ *
+ * @param string name of file-upload field
+ * @param mixed full name of local file
+ * @param string filename to send in the request
+ * @param string content-type of file being uploaded
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function addUpload($fieldName, $filename, $sendFilename = null,
+ $contentType = null)
+ {
+ if (!is_array($filename)) {
+ if (!($fp = @fopen($filename, 'rb'))) {
+ throw new HTTP_Request2_Exception("Cannot open file {$filename}");
+ }
+ $this->uploads[$fieldName] = array(
+ 'fp' => $fp,
+ 'filename' => empty($sendFilename)? basename($filename): $sendFilename,
+ 'size' => filesize($filename),
+ 'type' => empty($contentType)? self::detectMimeType($filename): $contentType
+ );
+ } else {
+ $fps = $names = $sizes = $types = array();
+ foreach ($filename as $f) {
+ if (!is_array($f)) {
+ $f = array($f);
+ }
+ if (!($fp = @fopen($f[0], 'rb'))) {
+ throw new HTTP_Request2_Exception("Cannot open file {$f[0]}");
+ }
+ $fps[] = $fp;
+ $names[] = empty($f[1])? basename($f[0]): $f[1];
+ $sizes[] = filesize($f[0]);
+ $types[] = empty($f[2])? self::detectMimeType($f[0]): $f[2];
+ }
+ $this->uploads[$fieldName] = array(
+ 'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types
+ );
+ }
+ if (empty($this->headers['content-type']) ||
+ 'application/x-www-form-urlencoded' == $this->headers['content-type']
+ ) {
+ $this->setHeader('content-type', 'multipart/form-data');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds POST parameter(s) to the request.
+ *
+ * @param string|array parameter name or array ('name' => 'value')
+ * @param mixed parameter value (can be an array)
+ * @return HTTP_Request2
+ */
+ public function addPostParameter($name, $value = null)
+ {
+ if (!is_array($name)) {
+ $this->postParams[$name] = $value;
+ } else {
+ foreach ($name as $k => $v) {
+ $this->addPostParameter($k, $v);
+ }
+ }
+ if (empty($this->headers['content-type'])) {
+ $this->setHeader('content-type', 'application/x-www-form-urlencoded');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Attaches a new observer
+ *
+ * @param SplObserver
+ */
+ public function attach(SplObserver $observer)
+ {
+ foreach ($this->observers as $attached) {
+ if ($attached === $observer) {
+ return;
+ }
+ }
+ $this->observers[] = $observer;
+ }
+
+ /**
+ * Detaches an existing observer
+ *
+ * @param SplObserver
+ */
+ public function detach(SplObserver $observer)
+ {
+ foreach ($this->observers as $key => $attached) {
+ if ($attached === $observer) {
+ unset($this->observers[$key]);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Notifies all observers
+ */
+ public function notify()
+ {
+ foreach ($this->observers as $observer) {
+ $observer->update($this);
+ }
+ }
+
+ /**
+ * Sets the last event
+ *
+ * Adapters should use this method to set the current state of the request
+ * and notify the observers.
+ *
+ * @param string event name
+ * @param mixed event data
+ */
+ public function setLastEvent($name, $data = null)
+ {
+ $this->lastEvent = array(
+ 'name' => $name,
+ 'data' => $data
+ );
+ $this->notify();
+ }
+
+ /**
+ * Returns the last event
+ *
+ * Observers should use this method to access the last change in request.
+ * The following event names are possible:
+ *
+ * - 'connect' - after connection to remote server,
+ * data is the destination (string)
+ * - 'disconnect' - after disconnection from server
+ * - 'sentHeaders' - after sending the request headers,
+ * data is the headers sent (string)
+ * - 'sentBodyPart' - after sending a part of the request body,
+ * data is the length of that part (int)
+ * - 'receivedHeaders' - after receiving the response headers,
+ * data is HTTP_Request2_Response object
+ * - 'receivedBodyPart' - after receiving a part of the response
+ * body, data is that part (string)
+ * - 'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still
+ * encoded by Content-Encoding
+ * - 'receivedBody' - after receiving the complete response
+ * body, data is HTTP_Request2_Response object
+ *
+ * Different adapters may not send all the event types. Mock adapter does
+ * not send any events to the observers.
+ *
+ * @return array The array has two keys: 'name' and 'data'
+ */
+ public function getLastEvent()
+ {
+ return $this->lastEvent;
+ }
+
+ /**
+ * Sets the adapter used to actually perform the request
+ *
+ * You can pass either an instance of a class implementing HTTP_Request2_Adapter
+ * or a class name. The method will only try to include a file if the class
+ * name starts with HTTP_Request2_Adapter_, it will also try to prepend this
+ * prefix to the class name if it doesn't contain any underscores, so that
+ *
+ * $request->setAdapter('curl');
+ *
+ * will work.
+ *
+ * @param string|HTTP_Request2_Adapter
+ * @return HTTP_Request2
+ * @throws HTTP_Request2_Exception
+ */
+ public function setAdapter($adapter)
+ {
+ if (is_string($adapter)) {
+ if (!class_exists($adapter, false)) {
+ if (false === strpos($adapter, '_')) {
+ $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter);
+ }
+ if (preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter)) {
+ include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php';
+ }
+ if (!class_exists($adapter, false)) {
+ throw new HTTP_Request2_Exception("Class {$adapter} not found");
+ }
+ }
+ $adapter = new $adapter;
+ }
+ if (!$adapter instanceof HTTP_Request2_Adapter) {
+ throw new HTTP_Request2_Exception('Parameter is not a HTTP request adapter');
+ }
+ $this->adapter = $adapter;
+
+ return $this;
+ }
+
+ /**
+ * Sends the request and returns the response
+ *
+ * @throws HTTP_Request2_Exception
+ * @return HTTP_Request2_Response
+ */
+ public function send()
+ {
+ // Sanity check for URL
+ if (!$this->url instanceof Net_URL2) {
+ throw new HTTP_Request2_Exception('No URL given');
+ } elseif (!$this->url->isAbsolute()) {
+ throw new HTTP_Request2_Exception('Absolute URL required');
+ } elseif (!in_array(strtolower($this->url->getScheme()), array('https', 'http'))) {
+ throw new HTTP_Request2_Exception('Not a HTTP URL');
+ }
+ if (empty($this->adapter)) {
+ $this->setAdapter($this->getConfig('adapter'));
+ }
+ // magic_quotes_runtime may break file uploads and chunked response
+ // processing; see bug #4543
+ if ($magicQuotes = ini_get('magic_quotes_runtime')) {
+ ini_set('magic_quotes_runtime', false);
+ }
+ // force using single byte encoding if mbstring extension overloads
+ // strlen() and substr(); see bug #1781, bug #10605
+ if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
+ $oldEncoding = mb_internal_encoding();
+ mb_internal_encoding('iso-8859-1');
+ }
+
+ try {
+ $response = $this->adapter->sendRequest($this);
+ } catch (Exception $e) {
+ }
+ // cleanup in either case (poor man's "finally" clause)
+ if ($magicQuotes) {
+ ini_set('magic_quotes_runtime', true);
+ }
+ if (!empty($oldEncoding)) {
+ mb_internal_encoding($oldEncoding);
+ }
+ // rethrow the exception
+ if (!empty($e)) {
+ throw $e;
+ }
+ return $response;
+ }
+
+ /**
+ * Tries to detect MIME type of a file
+ *
+ * The method will try to use fileinfo extension if it is available,
+ * deprecated mime_content_type() function in the other case. If neither
+ * works, default 'application/octet-stream' MIME type is returned
+ *
+ * @param string filename
+ * @return string file MIME type
+ */
+ protected static function detectMimeType($filename)
+ {
+ // finfo extension from PECL available
+ if (function_exists('finfo_open')) {
+ if (!isset(self::$_fileinfoDb)) {
+ self::$_fileinfoDb = @finfo_open(FILEINFO_MIME);
+ }
+ if (self::$_fileinfoDb) {
+ $info = finfo_file(self::$_fileinfoDb, $filename);
+ }
+ }
+ // (deprecated) mime_content_type function available
+ if (empty($info) && function_exists('mime_content_type')) {
+ return mime_content_type($filename);
+ }
+ return empty($info)? 'application/octet-stream': $info;
+ }
+}
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Adapter.php b/extlib/HTTP/Request2/Adapter.php
new file mode 100644
index 000000000..39b092b34
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter.php
@@ -0,0 +1,152 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Adapter.php 274684 2009-01-26 23:07:27Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP response
+ */
+require_once 'HTTP/Request2/Response.php';
+
+/**
+ * Base class for HTTP_Request2 adapters
+ *
+ * HTTP_Request2 class itself only defines methods for aggregating the request
+ * data, all actual work of sending the request to the remote server and
+ * receiving its response is performed by adapters.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+abstract class HTTP_Request2_Adapter
+{
+ /**
+ * A list of methods that MUST NOT have a request body, per RFC 2616
+ * @var array
+ */
+ protected static $bodyDisallowed = array('TRACE');
+
+ /**
+ * Methods having defined semantics for request body
+ *
+ * Content-Length header (indicating that the body follows, section 4.3 of
+ * RFC 2616) will be sent for these methods even if no body was added
+ *
+ * @var array
+ * @link http://pear.php.net/bugs/bug.php?id=12900
+ * @link http://pear.php.net/bugs/bug.php?id=14740
+ */
+ protected static $bodyRequired = array('POST', 'PUT');
+
+ /**
+ * Request being sent
+ * @var HTTP_Request2
+ */
+ protected $request;
+
+ /**
+ * Request body
+ * @var string|resource|HTTP_Request2_MultipartBody
+ * @see HTTP_Request2::getBody()
+ */
+ protected $requestBody;
+
+ /**
+ * Length of the request body
+ * @var integer
+ */
+ protected $contentLength;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ abstract public function sendRequest(HTTP_Request2 $request);
+
+ /**
+ * Calculates length of the request body, adds proper headers
+ *
+ * @param array associative array of request headers, this method will
+ * add proper 'Content-Length' and 'Content-Type' headers
+ * to this array (or remove them if not needed)
+ */
+ protected function calculateRequestLength(&$headers)
+ {
+ $this->requestBody = $this->request->getBody();
+
+ if (is_string($this->requestBody)) {
+ $this->contentLength = strlen($this->requestBody);
+ } elseif (is_resource($this->requestBody)) {
+ $stat = fstat($this->requestBody);
+ $this->contentLength = $stat['size'];
+ rewind($this->requestBody);
+ } else {
+ $this->contentLength = $this->requestBody->getLength();
+ $headers['content-type'] = 'multipart/form-data; boundary=' .
+ $this->requestBody->getBoundary();
+ $this->requestBody->rewind();
+ }
+
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength
+ ) {
+ unset($headers['content-type']);
+ // No body: send a Content-Length header nonetheless (request #12900),
+ // but do that only for methods that require a body (bug #14740)
+ if (in_array($this->request->getMethod(), self::$bodyRequired)) {
+ $headers['content-length'] = 0;
+ } else {
+ unset($headers['content-length']);
+ }
+ } else {
+ if (empty($headers['content-type'])) {
+ $headers['content-type'] = 'application/x-www-form-urlencoded';
+ }
+ $headers['content-length'] = $this->contentLength;
+ }
+ }
+}
+?>
diff --git a/extlib/HTTP/Request2/Adapter/Curl.php b/extlib/HTTP/Request2/Adapter/Curl.php
new file mode 100644
index 000000000..4d4de0dcc
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter/Curl.php
@@ -0,0 +1,383 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Curl.php 278226 2009-04-03 21:32:48Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Adapter for HTTP_Request2 wrapping around cURL extension
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
+{
+ /**
+ * Mapping of header names to cURL options
+ * @var array
+ */
+ protected static $headerMap = array(
+ 'accept-encoding' => CURLOPT_ENCODING,
+ 'cookie' => CURLOPT_COOKIE,
+ 'referer' => CURLOPT_REFERER,
+ 'user-agent' => CURLOPT_USERAGENT
+ );
+
+ /**
+ * Mapping of SSL context options to cURL options
+ * @var array
+ */
+ protected static $sslContextMap = array(
+ 'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
+ 'ssl_cafile' => CURLOPT_CAINFO,
+ 'ssl_capath' => CURLOPT_CAPATH,
+ 'ssl_local_cert' => CURLOPT_SSLCERT,
+ 'ssl_passphrase' => CURLOPT_SSLCERTPASSWD
+ );
+
+ /**
+ * Response being received
+ * @var HTTP_Request2_Response
+ */
+ protected $response;
+
+ /**
+ * Whether 'sentHeaders' event was sent to observers
+ * @var boolean
+ */
+ protected $eventSentHeaders = false;
+
+ /**
+ * Whether 'receivedHeaders' event was sent to observers
+ * @var boolean
+ */
+ protected $eventReceivedHeaders = false;
+
+ /**
+ * Position within request body
+ * @var integer
+ * @see callbackReadBody()
+ */
+ protected $position = 0;
+
+ /**
+ * Information about last transfer, as returned by curl_getinfo()
+ * @var array
+ */
+ protected $lastInfo;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ if (!extension_loaded('curl')) {
+ throw new HTTP_Request2_Exception('cURL extension not available');
+ }
+
+ $this->request = $request;
+ $this->response = null;
+ $this->position = 0;
+ $this->eventSentHeaders = false;
+ $this->eventReceivedHeaders = false;
+
+ try {
+ if (false === curl_exec($ch = $this->createCurlHandle())) {
+ $errorMessage = 'Error sending request: #' . curl_errno($ch) .
+ ' ' . curl_error($ch);
+ }
+ } catch (Exception $e) {
+ }
+ $this->lastInfo = curl_getinfo($ch);
+ curl_close($ch);
+
+ if (!empty($e)) {
+ throw $e;
+ } elseif (!empty($errorMessage)) {
+ throw new HTTP_Request2_Exception($errorMessage);
+ }
+
+ if (0 < $this->lastInfo['size_download']) {
+ $this->request->setLastEvent('receivedBody', $this->response);
+ }
+ return $this->response;
+ }
+
+ /**
+ * Returns information about last transfer
+ *
+ * @return array associative array as returned by curl_getinfo()
+ */
+ public function getInfo()
+ {
+ return $this->lastInfo;
+ }
+
+ /**
+ * Creates a new cURL handle and populates it with data from the request
+ *
+ * @return resource a cURL handle, as created by curl_init()
+ * @throws HTTP_Request2_Exception
+ */
+ protected function createCurlHandle()
+ {
+ $ch = curl_init();
+
+ curl_setopt_array($ch, array(
+ // setup callbacks
+ CURLOPT_READFUNCTION => array($this, 'callbackReadBody'),
+ CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
+ CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'),
+ // disallow redirects
+ CURLOPT_FOLLOWLOCATION => false,
+ // buffer size
+ CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'),
+ // connection timeout
+ CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
+ // save full outgoing headers, in case someone is interested
+ CURLINFO_HEADER_OUT => true,
+ // request url
+ CURLOPT_URL => $this->request->getUrl()->getUrl()
+ ));
+
+ // request timeout
+ if ($timeout = $this->request->getConfig('timeout')) {
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ }
+
+ // set HTTP version
+ switch ($this->request->getConfig('protocol_version')) {
+ case '1.0':
+ curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ break;
+ case '1.1':
+ curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ }
+
+ // set request method
+ switch ($this->request->getMethod()) {
+ case HTTP_Request2::METHOD_GET:
+ curl_setopt($ch, CURLOPT_HTTPGET, true);
+ break;
+ case HTTP_Request2::METHOD_POST:
+ curl_setopt($ch, CURLOPT_POST, true);
+ break;
+ default:
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
+ }
+
+ // set proxy, if needed
+ if ($host = $this->request->getConfig('proxy_host')) {
+ if (!($port = $this->request->getConfig('proxy_port'))) {
+ throw new HTTP_Request2_Exception('Proxy port not provided');
+ }
+ curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
+ if ($user = $this->request->getConfig('proxy_user')) {
+ curl_setopt($ch, CURLOPT_PROXYUSERPWD, $user . ':' .
+ $this->request->getConfig('proxy_password'));
+ switch ($this->request->getConfig('proxy_auth_scheme')) {
+ case HTTP_Request2::AUTH_BASIC:
+ curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+ break;
+ case HTTP_Request2::AUTH_DIGEST:
+ curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
+ }
+ }
+ }
+
+ // set authentication data
+ if ($auth = $this->request->getAuth()) {
+ curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
+ switch ($auth['scheme']) {
+ case HTTP_Request2::AUTH_BASIC:
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ break;
+ case HTTP_Request2::AUTH_DIGEST:
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+ }
+ }
+
+ // set SSL options
+ if (0 == strcasecmp($this->request->getUrl()->getScheme(), 'https')) {
+ foreach ($this->request->getConfig() as $name => $value) {
+ if ('ssl_verify_host' == $name && null !== $value) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
+ } elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
+ curl_setopt($ch, self::$sslContextMap[$name], $value);
+ }
+ }
+ }
+
+ $headers = $this->request->getHeaders();
+ // make cURL automagically send proper header
+ if (!isset($headers['accept-encoding'])) {
+ $headers['accept-encoding'] = '';
+ }
+
+ // set headers having special cURL keys
+ foreach (self::$headerMap as $name => $option) {
+ if (isset($headers[$name])) {
+ curl_setopt($ch, $option, $headers[$name]);
+ unset($headers[$name]);
+ }
+ }
+
+ $this->calculateRequestLength($headers);
+
+ // set headers not having special keys
+ $headersFmt = array();
+ foreach ($headers as $name => $value) {
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $headersFmt[] = $canonicalName . ': ' . $value;
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
+
+ return $ch;
+ }
+
+ /**
+ * Callback function called by cURL for reading the request body
+ *
+ * @param resource cURL handle
+ * @param resource file descriptor (not used)
+ * @param integer maximum length of data to return
+ * @return string part of the request body, up to $length bytes
+ */
+ protected function callbackReadBody($ch, $fd, $length)
+ {
+ if (!$this->eventSentHeaders) {
+ $this->request->setLastEvent(
+ 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
+ );
+ $this->eventSentHeaders = true;
+ }
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength || $this->position >= $this->contentLength
+ ) {
+ return '';
+ }
+ if (is_string($this->requestBody)) {
+ $string = substr($this->requestBody, $this->position, $length);
+ } elseif (is_resource($this->requestBody)) {
+ $string = fread($this->requestBody, $length);
+ } else {
+ $string = $this->requestBody->read($length);
+ }
+ $this->request->setLastEvent('sentBodyPart', strlen($string));
+ $this->position += strlen($string);
+ return $string;
+ }
+
+ /**
+ * Callback function called by cURL for saving the response headers
+ *
+ * @param resource cURL handle
+ * @param string response header (with trailing CRLF)
+ * @return integer number of bytes saved
+ * @see HTTP_Request2_Response::parseHeaderLine()
+ */
+ protected function callbackWriteHeader($ch, $string)
+ {
+ // we may receive a second set of headers if doing e.g. digest auth
+ if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
+ // don't bother with 100-Continue responses (bug #15785)
+ if (!$this->eventSentHeaders ||
+ $this->response->getStatus() >= 200
+ ) {
+ $this->request->setLastEvent(
+ 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
+ );
+ }
+ $this->eventSentHeaders = true;
+ // we'll need a new response object
+ if ($this->eventReceivedHeaders) {
+ $this->eventReceivedHeaders = false;
+ $this->response = null;
+ }
+ }
+ if (empty($this->response)) {
+ $this->response = new HTTP_Request2_Response($string, false);
+ } else {
+ $this->response->parseHeaderLine($string);
+ if ('' == trim($string)) {
+ // don't bother with 100-Continue responses (bug #15785)
+ if (200 <= $this->response->getStatus()) {
+ $this->request->setLastEvent('receivedHeaders', $this->response);
+ }
+ $this->eventReceivedHeaders = true;
+ }
+ }
+ return strlen($string);
+ }
+
+ /**
+ * Callback function called by cURL for saving the response body
+ *
+ * @param resource cURL handle (not used)
+ * @param string part of the response body
+ * @return integer number of bytes saved
+ * @see HTTP_Request2_Response::appendBody()
+ */
+ protected function callbackWriteBody($ch, $string)
+ {
+ // cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
+ // response doesn't start with proper HTTP status line (see bug #15716)
+ if (empty($this->response)) {
+ throw new HTTP_Request2_Exception("Malformed response: {$string}");
+ }
+ if ($this->request->getConfig('store_body')) {
+ $this->response->appendBody($string);
+ }
+ $this->request->setLastEvent('receivedBodyPart', $string);
+ return strlen($string);
+ }
+}
+?>
diff --git a/extlib/HTTP/Request2/Adapter/Mock.php b/extlib/HTTP/Request2/Adapter/Mock.php
new file mode 100644
index 000000000..89688003b
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter/Mock.php
@@ -0,0 +1,171 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Mock.php 274406 2009-01-23 18:01:57Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Mock adapter intended for testing
+ *
+ * Can be used to test applications depending on HTTP_Request2 package without
+ * actually performing any HTTP requests. This adapter will return responses
+ * previously added via addResponse()
+ *
+ * $mock = new HTTP_Request2_Adapter_Mock();
+ * $mock->addResponse("HTTP/1.1 ... ");
+ *
+ * $request = new HTTP_Request2();
+ * $request->setAdapter($mock);
+ *
+ * // This will return the response set above
+ * $response = $req->send();
+ *
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
+{
+ /**
+ * A queue of responses to be returned by sendRequest()
+ * @var array
+ */
+ protected $responses = array();
+
+ /**
+ * Returns the next response from the queue built by addResponse()
+ *
+ * If the queue is empty will return default empty response with status 400,
+ * if an Exception object was added to the queue it will be thrown.
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ if (count($this->responses) > 0) {
+ $response = array_shift($this->responses);
+ if ($response instanceof HTTP_Request2_Response) {
+ return $response;
+ } else {
+ // rethrow the exception,
+ $class = get_class($response);
+ $message = $response->getMessage();
+ $code = $response->getCode();
+ throw new $class($message, $code);
+ }
+ } else {
+ return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
+ }
+ }
+
+ /**
+ * Adds response to the queue
+ *
+ * @param mixed either a string, a pointer to an open file,
+ * a HTTP_Request2_Response or Exception object
+ * @throws HTTP_Request2_Exception
+ */
+ public function addResponse($response)
+ {
+ if (is_string($response)) {
+ $response = self::createResponseFromString($response);
+ } elseif (is_resource($response)) {
+ $response = self::createResponseFromFile($response);
+ } elseif (!$response instanceof HTTP_Request2_Response &&
+ !$response instanceof Exception
+ ) {
+ throw new HTTP_Request2_Exception('Parameter is not a valid response');
+ }
+ $this->responses[] = $response;
+ }
+
+ /**
+ * Creates a new HTTP_Request2_Response object from a string
+ *
+ * @param string
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public static function createResponseFromString($str)
+ {
+ $parts = preg_split('!(\r?\n){2}!m', $str, 2);
+ $headerLines = explode("\n", $parts[0]);
+ $response = new HTTP_Request2_Response(array_shift($headerLines));
+ foreach ($headerLines as $headerLine) {
+ $response->parseHeaderLine($headerLine);
+ }
+ $response->parseHeaderLine('');
+ if (isset($parts[1])) {
+ $response->appendBody($parts[1]);
+ }
+ return $response;
+ }
+
+ /**
+ * Creates a new HTTP_Request2_Response object from a file
+ *
+ * @param resource file pointer returned by fopen()
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public static function createResponseFromFile($fp)
+ {
+ $response = new HTTP_Request2_Response(fgets($fp));
+ do {
+ $headerLine = fgets($fp);
+ $response->parseHeaderLine($headerLine);
+ } while ('' != trim($headerLine));
+
+ while (!feof($fp)) {
+ $response->appendBody(fread($fp, 8192));
+ }
+ return $response;
+ }
+}
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Adapter/Socket.php b/extlib/HTTP/Request2/Adapter/Socket.php
new file mode 100644
index 000000000..ff44d4959
--- /dev/null
+++ b/extlib/HTTP/Request2/Adapter/Socket.php
@@ -0,0 +1,971 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * This adapter uses only PHP sockets and will work on almost any PHP
+ * environment. Code is based on original HTTP_Request PEAR package.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
+{
+ /**
+ * Regular expression for 'token' rule from RFC 2616
+ */
+ const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
+
+ /**
+ * Regular expression for 'quoted-string' rule from RFC 2616
+ */
+ const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
+
+ /**
+ * Connected sockets, needed for Keep-Alive support
+ * @var array
+ * @see connect()
+ */
+ protected static $sockets = array();
+
+ /**
+ * Data for digest authentication scheme
+ *
+ * The keys for the array are URL prefixes.
+ *
+ * The values are associative arrays with data (realm, nonce, nonce-count,
+ * opaque...) needed for digest authentication. Stored here to prevent making
+ * duplicate requests to digest-protected resources after we have already
+ * received the challenge.
+ *
+ * @var array
+ */
+ protected static $challenges = array();
+
+ /**
+ * Connected socket
+ * @var resource
+ * @see connect()
+ */
+ protected $socket;
+
+ /**
+ * Challenge used for server digest authentication
+ * @var array
+ */
+ protected $serverChallenge;
+
+ /**
+ * Challenge used for proxy digest authentication
+ * @var array
+ */
+ protected $proxyChallenge;
+
+ /**
+ * Global timeout, exception will be raised if request continues past this time
+ * @var integer
+ */
+ protected $timeout = null;
+
+ /**
+ * Remaining length of the current chunk, when reading chunked response
+ * @var integer
+ * @see readChunked()
+ */
+ protected $chunkLength = 0;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ $this->request = $request;
+ $keepAlive = $this->connect();
+ $headers = $this->prepareHeaders();
+
+ // Use global request timeout if given, see feature requests #5735, #8964
+ if ($timeout = $request->getConfig('timeout')) {
+ $this->timeout = time() + $timeout;
+ } else {
+ $this->timeout = null;
+ }
+
+ try {
+ if (false === @fwrite($this->socket, $headers, strlen($headers))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // provide request headers to the observer, see request #7633
+ $this->request->setLastEvent('sentHeaders', $headers);
+ $this->writeBody();
+
+ if ($this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $request->getConfig('timeout') . ' second(s)'
+ );
+ }
+
+ $response = $this->readResponse();
+
+ if (!$this->canKeepAlive($keepAlive, $response)) {
+ $this->disconnect();
+ }
+
+ if ($this->shouldUseProxyDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($this->shouldUseServerDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($authInfo = $response->getHeader('authentication-info')) {
+ $this->updateChallenge($this->serverChallenge, $authInfo);
+ }
+ if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
+ $this->updateChallenge($this->proxyChallenge, $proxyInfo);
+ }
+
+ } catch (Exception $e) {
+ $this->disconnect();
+ throw $e;
+ }
+
+ return $response;
+ }
+
+ /**
+ * Connects to the remote server
+ *
+ * @return bool whether the connection can be persistent
+ * @throws HTTP_Request2_Exception
+ */
+ protected function connect()
+ {
+ $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
+ $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $headers = $this->request->getHeaders();
+ $reqHost = $this->request->getUrl()->getHost();
+ if (!($reqPort = $this->request->getUrl()->getPort())) {
+ $reqPort = $secure? 443: 80;
+ }
+
+ if ($host = $this->request->getConfig('proxy_host')) {
+ if (!($port = $this->request->getConfig('proxy_port'))) {
+ throw new HTTP_Request2_Exception('Proxy port not provided');
+ }
+ $proxy = true;
+ } else {
+ $host = $reqHost;
+ $port = $reqPort;
+ $proxy = false;
+ }
+
+ if ($tunnel && !$proxy) {
+ throw new HTTP_Request2_Exception(
+ "Trying to perform CONNECT request without proxy"
+ );
+ }
+ if ($secure && !in_array('ssl', stream_get_transports())) {
+ throw new HTTP_Request2_Exception(
+ 'Need OpenSSL support for https:// requests'
+ );
+ }
+
+ // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+ // connection token to a proxy server...
+ if ($proxy && !$secure &&
+ !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
+ ) {
+ $this->request->setHeader('connection');
+ }
+
+ $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
+ empty($headers['connection'])) ||
+ (!empty($headers['connection']) &&
+ 'Keep-Alive' == $headers['connection']);
+ $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
+
+ $options = array();
+ if ($secure || $tunnel) {
+ foreach ($this->request->getConfig() as $name => $value) {
+ if ('ssl_' == substr($name, 0, 4) && null !== $value) {
+ if ('ssl_verify_host' == $name) {
+ if ($value) {
+ $options['CN_match'] = $reqHost;
+ }
+ } else {
+ $options[substr($name, 4)] = $value;
+ }
+ }
+ }
+ ksort($options);
+ }
+
+ // Changing SSL context options after connection is established does *not*
+ // work, we need a new connection if options change
+ $remote = $host . ':' . $port;
+ $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
+ (empty($options)? '': ':' . serialize($options));
+ unset($this->socket);
+
+ // We use persistent connections and have a connected socket?
+ // Ensure that the socket is still connected, see bug #16149
+ if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
+ !feof(self::$sockets[$socketKey])
+ ) {
+ $this->socket =& self::$sockets[$socketKey];
+
+ } elseif ($secure && $proxy && !$tunnel) {
+ $this->establishTunnel();
+ $this->request->setLastEvent(
+ 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
+ );
+ self::$sockets[$socketKey] =& $this->socket;
+
+ } else {
+ // Set SSL context options if doing HTTPS request or creating a tunnel
+ $context = stream_context_create();
+ foreach ($options as $name => $value) {
+ if (!stream_context_set_option($context, 'ssl', $name, $value)) {
+ throw new HTTP_Request2_Exception(
+ "Error setting SSL context option '{$name}'"
+ );
+ }
+ }
+ $this->socket = @stream_socket_client(
+ $remote, $errno, $errstr,
+ $this->request->getConfig('connect_timeout'),
+ STREAM_CLIENT_CONNECT, $context
+ );
+ if (!$this->socket) {
+ throw new HTTP_Request2_Exception(
+ "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
+ );
+ }
+ $this->request->setLastEvent('connect', $remote);
+ self::$sockets[$socketKey] =& $this->socket;
+ }
+ return $keepAlive;
+ }
+
+ /**
+ * Establishes a tunnel to a secure remote server via HTTP CONNECT request
+ *
+ * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
+ * sees that we are connected to a proxy server (duh!) rather than the server
+ * that presents its certificate.
+ *
+ * @link http://tools.ietf.org/html/rfc2817#section-5.2
+ * @throws HTTP_Request2_Exception
+ */
+ protected function establishTunnel()
+ {
+ $donor = new self;
+ $connect = new HTTP_Request2(
+ $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
+ array_merge($this->request->getConfig(),
+ array('adapter' => $donor))
+ );
+ $response = $connect->send();
+ // Need any successful (2XX) response
+ if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
+ throw new HTTP_Request2_Exception(
+ 'Failed to connect via HTTPS proxy. Proxy response: ' .
+ $response->getStatus() . ' ' . $response->getReasonPhrase()
+ );
+ }
+ $this->socket = $donor->socket;
+
+ $modes = array(
+ STREAM_CRYPTO_METHOD_TLS_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv2_CLIENT
+ );
+
+ foreach ($modes as $mode) {
+ if (stream_socket_enable_crypto($this->socket, true, $mode)) {
+ return;
+ }
+ }
+ throw new HTTP_Request2_Exception(
+ 'Failed to enable secure connection when connecting through proxy'
+ );
+ }
+
+ /**
+ * Checks whether current connection may be reused or should be closed
+ *
+ * @param boolean whether connection could be persistent
+ * in the first place
+ * @param HTTP_Request2_Response response object to check
+ * @return boolean
+ */
+ protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
+ {
+ // Do not close socket on successful CONNECT request
+ if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()
+ ) {
+ return true;
+ }
+
+ $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
+ null !== $response->getHeader('content-length');
+ $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
+ (null === $response->getHeader('connection') &&
+ '1.1' == $response->getVersion());
+ return $requestKeepAlive && $lengthKnown && $persistent;
+ }
+
+ /**
+ * Disconnects from the remote server
+ */
+ protected function disconnect()
+ {
+ if (is_resource($this->socket)) {
+ fclose($this->socket);
+ $this->socket = null;
+ $this->request->setLastEvent('disconnect');
+ }
+ }
+
+ /**
+ * Checks whether another request should be performed with server digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 401
+ * - auth credentials should be set in the request object
+ * - response should contain WWW-Authenticate header with digest challenge
+ * - there is either no challenge stored for this URL or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
+ {
+ // no sense repeating a request if we don't have credentials
+ if (401 != $response->getStatus() || !$this->request->getAuth()) {
+ return false;
+ }
+ if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
+ return false;
+ }
+
+ $url = $this->request->getUrl();
+ $scheme = $url->getScheme();
+ $host = $scheme . '://' . $url->getHost();
+ if ($port = $url->getPort()) {
+ if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
+ (0 == strcasecmp($scheme, 'https') && 443 != $port)
+ ) {
+ $host .= ':' . $port;
+ }
+ }
+
+ if (!empty($challenge['domain'])) {
+ $prefixes = array();
+ foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
+ // don't bother with different servers
+ if ('/' == substr($prefix, 0, 1)) {
+ $prefixes[] = $host . $prefix;
+ }
+ }
+ }
+ if (empty($prefixes)) {
+ $prefixes = array($host . '/');
+ }
+
+ $ret = true;
+ foreach ($prefixes as $prefix) {
+ if (!empty(self::$challenges[$prefix]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ // probably credentials are invalid
+ $ret = false;
+ }
+ self::$challenges[$prefix] =& $challenge;
+ }
+ return $ret;
+ }
+
+ /**
+ * Checks whether another request should be performed with proxy digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 407
+ * - proxy auth credentials should be set in the request object
+ * - response should contain Proxy-Authenticate header with digest challenge
+ * - there is either no challenge stored for this proxy or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
+ {
+ if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
+ return false;
+ }
+ if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
+ return false;
+ }
+
+ $key = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+
+ if (!empty(self::$challenges[$key]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ $ret = false;
+ } else {
+ $ret = true;
+ }
+ self::$challenges[$key] = $challenge;
+ return $ret;
+ }
+
+ /**
+ * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
+ *
+ * There is a problem with implementation of RFC 2617: several of the parameters
+ * here are defined as quoted-string and thus may contain backslash escaped
+ * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
+ * just value of quoted-string X without surrounding quotes, it doesn't speak
+ * about removing backslash escaping.
+ *
+ * Now realm parameter is user-defined and human-readable, strange things
+ * happen when it contains quotes:
+ * - Apache allows quotes in realm, but apparently uses realm value without
+ * backslashes for digest computation
+ * - Squid allows (manually escaped) quotes there, but it is impossible to
+ * authorize with either escaped or unescaped quotes used in digest,
+ * probably it can't parse the response (?)
+ * - Both IE and Firefox display realm value with backslashes in
+ * the password popup and apparently use the same value for digest
+ *
+ * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
+ * quoted-string handling, unfortunately that means failure to authorize
+ * sometimes
+ *
+ * @param string value of WWW-Authenticate or Proxy-Authenticate header
+ * @return mixed associative array with challenge parameters, false if
+ * no challenge is present in header value
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function parseDigestChallenge($headerValue)
+ {
+ $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
+ $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
+ if (!preg_match($challenge, $headerValue, $matches)) {
+ return false;
+ }
+
+ preg_match_all('!' . $authParam . '!', $matches[0], $params);
+ $paramsAry = array();
+ $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
+ 'algorithm', 'qop');
+ for ($i = 0; $i < count($params[0]); $i++) {
+ // section 3.2.1: Any unrecognized directive MUST be ignored.
+ if (in_array($params[1][$i], $knownParams)) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ }
+ // we only support qop=auth
+ if (!empty($paramsAry['qop']) &&
+ !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
+ ) {
+ throw new HTTP_Request2_Exception(
+ "Only 'auth' qop is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['qop']}'"
+ );
+ }
+ // we only support algorithm=MD5
+ if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
+ throw new HTTP_Request2_Exception(
+ "Only 'MD5' algorithm is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['algorithm']}'"
+ );
+ }
+
+ return $paramsAry;
+ }
+
+ /**
+ * Parses [Proxy-]Authentication-Info header value and updates challenge
+ *
+ * @param array challenge to update
+ * @param string value of [Proxy-]Authentication-Info header
+ * @todo validate server rspauth response
+ */
+ protected function updateChallenge(&$challenge, $headerValue)
+ {
+ $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
+ $paramsAry = array();
+
+ preg_match_all($authParam, $headerValue, $params);
+ for ($i = 0; $i < count($params[0]); $i++) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ // for now, just update the nonce value
+ if (!empty($paramsAry['nextnonce'])) {
+ $challenge['nonce'] = $paramsAry['nextnonce'];
+ $challenge['nc'] = 1;
+ }
+ }
+
+ /**
+ * Creates a value for [Proxy-]Authorization header when using digest authentication
+ *
+ * @param string user name
+ * @param string password
+ * @param string request URL
+ * @param array digest challenge parameters
+ * @return string value of [Proxy-]Authorization request header
+ * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
+ */
+ protected function createDigestResponse($user, $password, $url, &$challenge)
+ {
+ if (false !== ($q = strpos($url, '?')) &&
+ $this->request->getConfig('digest_compat_ie')
+ ) {
+ $url = substr($url, 0, $q);
+ }
+
+ $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
+ $a2 = md5($this->request->getMethod() . ':' . $url);
+
+ if (empty($challenge['qop'])) {
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
+ } else {
+ $challenge['cnonce'] = 'Req2.' . rand();
+ if (empty($challenge['nc'])) {
+ $challenge['nc'] = 1;
+ }
+ $nc = sprintf('%08x', $challenge['nc']++);
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
+ $challenge['cnonce'] . ':auth:' . $a2);
+ }
+ return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
+ 'realm="' . $challenge['realm'] . '", ' .
+ 'nonce="' . $challenge['nonce'] . '", ' .
+ 'uri="' . $url . '", ' .
+ 'response="' . $digest . '"' .
+ (!empty($challenge['opaque'])?
+ ', opaque="' . $challenge['opaque'] . '"':
+ '') .
+ (!empty($challenge['qop'])?
+ ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
+ '');
+ }
+
+ /**
+ * Adds 'Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request host (needed for digest authentication)
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
+ {
+ if (!($auth = $this->request->getAuth())) {
+ return;
+ }
+ switch ($auth['scheme']) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['authorization'] =
+ 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->serverChallenge);
+ $fullUrl = ('/' == $requestUrl[0])?
+ $this->request->getUrl()->getScheme() . '://' .
+ $requestHost . $requestUrl:
+ $requestUrl;
+ foreach (array_keys(self::$challenges) as $key) {
+ if ($key == substr($fullUrl, 0, strlen($key))) {
+ $headers['authorization'] = $this->createDigestResponse(
+ $auth['user'], $auth['password'],
+ $requestUrl, self::$challenges[$key]
+ );
+ $this->serverChallenge =& self::$challenges[$key];
+ break;
+ }
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '{$auth['scheme']}'"
+ );
+ }
+ }
+
+ /**
+ * Adds 'Proxy-Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
+ {
+ if (!$this->request->getConfig('proxy_host') ||
+ !($user = $this->request->getConfig('proxy_user')) ||
+ (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
+ HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
+ ) {
+ return;
+ }
+
+ $password = $this->request->getConfig('proxy_password');
+ switch ($this->request->getConfig('proxy_auth_scheme')) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['proxy-authorization'] =
+ 'Basic ' . base64_encode($user . ':' . $password);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->proxyChallenge);
+ $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+ if (!empty(self::$challenges[$proxyUrl])) {
+ $headers['proxy-authorization'] = $this->createDigestResponse(
+ $user, $password,
+ $requestUrl, self::$challenges[$proxyUrl]
+ );
+ $this->proxyChallenge =& self::$challenges[$proxyUrl];
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '" .
+ $this->request->getConfig('proxy_auth_scheme') . "'"
+ );
+ }
+ }
+
+
+ /**
+ * Creates the string with the Request-Line and request headers
+ *
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function prepareHeaders()
+ {
+ $headers = $this->request->getHeaders();
+ $url = $this->request->getUrl();
+ $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $host = $url->getHost();
+
+ $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
+ if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
+ $host .= ':' . (empty($port)? $defaultPort: $port);
+ }
+ // Do not overwrite explicitly set 'Host' header, see bug #16146
+ if (!isset($headers['host'])) {
+ $headers['host'] = $host;
+ }
+
+ if ($connect) {
+ $requestUrl = $host;
+
+ } else {
+ if (!$this->request->getConfig('proxy_host') ||
+ 0 == strcasecmp($url->getScheme(), 'https')
+ ) {
+ $requestUrl = '';
+ } else {
+ $requestUrl = $url->getScheme() . '://' . $host;
+ }
+ $path = $url->getPath();
+ $query = $url->getQuery();
+ $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
+ }
+
+ if ('1.1' == $this->request->getConfig('protocol_version') &&
+ extension_loaded('zlib') && !isset($headers['accept-encoding'])
+ ) {
+ $headers['accept-encoding'] = 'gzip, deflate';
+ }
+
+ $this->addAuthorizationHeader($headers, $host, $requestUrl);
+ $this->addProxyAuthorizationHeader($headers, $requestUrl);
+ $this->calculateRequestLength($headers);
+
+ $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
+ $this->request->getConfig('protocol_version') . "\r\n";
+ foreach ($headers as $name => $value) {
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $headersStr .= $canonicalName . ': ' . $value . "\r\n";
+ }
+ return $headersStr . "\r\n";
+ }
+
+ /**
+ * Sends the request body
+ *
+ * @throws HTTP_Request2_Exception
+ */
+ protected function writeBody()
+ {
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength
+ ) {
+ return;
+ }
+
+ $position = 0;
+ $bufferSize = $this->request->getConfig('buffer_size');
+ while ($position < $this->contentLength) {
+ if (is_string($this->requestBody)) {
+ $str = substr($this->requestBody, $position, $bufferSize);
+ } elseif (is_resource($this->requestBody)) {
+ $str = fread($this->requestBody, $bufferSize);
+ } else {
+ $str = $this->requestBody->read($bufferSize);
+ }
+ if (false === @fwrite($this->socket, $str, strlen($str))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // Provide the length of written string to the observer, request #7630
+ $this->request->setLastEvent('sentBodyPart', strlen($str));
+ $position += strlen($str);
+ }
+ }
+
+ /**
+ * Reads the remote server's response
+ *
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readResponse()
+ {
+ $bufferSize = $this->request->getConfig('buffer_size');
+
+ do {
+ $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
+ do {
+ $headerLine = $this->readLine($bufferSize);
+ $response->parseHeaderLine($headerLine);
+ } while ('' != $headerLine);
+ } while (in_array($response->getStatus(), array(100, 101)));
+
+ $this->request->setLastEvent('receivedHeaders', $response);
+
+ // No body possible in such responses
+ if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
+ (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
+ in_array($response->getStatus(), array(204, 304))
+ ) {
+ return $response;
+ }
+
+ $chunked = 'chunked' == $response->getHeader('transfer-encoding');
+ $length = $response->getHeader('content-length');
+ $hasBody = false;
+ if ($chunked || null === $length || 0 < intval($length)) {
+ // RFC 2616, section 4.4:
+ // 3. ... If a message is received with both a
+ // Transfer-Encoding header field and a Content-Length header field,
+ // the latter MUST be ignored.
+ $toRead = ($chunked || null === $length)? null: $length;
+ $this->chunkLength = 0;
+
+ while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
+ if ($chunked) {
+ $data = $this->readChunked($bufferSize);
+ } elseif (is_null($toRead)) {
+ $data = $this->fread($bufferSize);
+ } else {
+ $data = $this->fread(min($toRead, $bufferSize));
+ $toRead -= strlen($data);
+ }
+ if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
+ break;
+ }
+
+ $hasBody = true;
+ if ($this->request->getConfig('store_body')) {
+ $response->appendBody($data);
+ }
+ if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
+ $this->request->setLastEvent('receivedEncodedBodyPart', $data);
+ } else {
+ $this->request->setLastEvent('receivedBodyPart', $data);
+ }
+ }
+ }
+
+ if ($hasBody) {
+ $this->request->setLastEvent('receivedBody', $response);
+ }
+ return $response;
+ }
+
+ /**
+ * Reads until either the end of the socket or a newline, whichever comes first
+ *
+ * Strips the trailing newline from the returned data, handles global
+ * request timeout. Method idea borrowed from Net_Socket PEAR package.
+ *
+ * @param int buffer size to use for reading
+ * @return Available data up to the newline (not including newline)
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function readLine($bufferSize)
+ {
+ $line = '';
+ while (!feof($this->socket)) {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $line .= @fgets($this->socket, $bufferSize);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ if (substr($line, -1) == "\n") {
+ return rtrim($line, "\r\n");
+ }
+ }
+ return $line;
+ }
+
+ /**
+ * Wrapper around fread(), handles global request timeout
+ *
+ * @param int Reads up to this number of bytes
+ * @return Data read from socket
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function fread($length)
+ {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $data = fread($this->socket, $length);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ return $data;
+ }
+
+ /**
+ * Reads a part of response body encoded with chunked Transfer-Encoding
+ *
+ * @param int buffer size to use for reading
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readChunked($bufferSize)
+ {
+ // at start of the next chunk?
+ if (0 == $this->chunkLength) {
+ $line = $this->readLine($bufferSize);
+ if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
+ throw new HTTP_Request2_Exception(
+ "Cannot decode chunked response, invalid chunk length '{$line}'"
+ );
+ } else {
+ $this->chunkLength = hexdec($matches[1]);
+ // Chunk with zero length indicates the end
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize);
+ return '';
+ }
+ }
+ }
+ $data = $this->fread(min($this->chunkLength, $bufferSize));
+ $this->chunkLength -= strlen($data);
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize); // Trailing CRLF
+ }
+ return $data;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Exception.php b/extlib/HTTP/Request2/Exception.php
new file mode 100644
index 000000000..bfef7d6c2
--- /dev/null
+++ b/extlib/HTTP/Request2/Exception.php
@@ -0,0 +1,62 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Exception.php 273003 2009-01-07 19:28:22Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for exceptions in PEAR
+ */
+require_once 'PEAR/Exception.php';
+
+/**
+ * Exception class for HTTP_Request2 package
+ *
+ * Such a class is required by the Exception RFC:
+ * http://pear.php.net/pepr/pepr-proposal-show.php?id=132
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Exception extends PEAR_Exception
+{
+}
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/MultipartBody.php b/extlib/HTTP/Request2/MultipartBody.php
new file mode 100644
index 000000000..d8afd8344
--- /dev/null
+++ b/extlib/HTTP/Request2/MultipartBody.php
@@ -0,0 +1,274 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: MultipartBody.php 287306 2009-08-14 15:22:52Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class for building multipart/form-data request body
+ *
+ * The class helps to reduce memory consumption by streaming large file uploads
+ * from disk, it also allows monitoring of upload progress (see request #7630)
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ * @link http://tools.ietf.org/html/rfc1867
+ */
+class HTTP_Request2_MultipartBody
+{
+ /**
+ * MIME boundary
+ * @var string
+ */
+ private $_boundary;
+
+ /**
+ * Form parameters added via {@link HTTP_Request2::addPostParameter()}
+ * @var array
+ */
+ private $_params = array();
+
+ /**
+ * File uploads added via {@link HTTP_Request2::addUpload()}
+ * @var array
+ */
+ private $_uploads = array();
+
+ /**
+ * Header for parts with parameters
+ * @var string
+ */
+ private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
+
+ /**
+ * Header for parts with uploads
+ * @var string
+ */
+ private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
+
+ /**
+ * Current position in parameter and upload arrays
+ *
+ * First number is index of "current" part, second number is position within
+ * "current" part
+ *
+ * @var array
+ */
+ private $_pos = array(0, 0);
+
+
+ /**
+ * Constructor. Sets the arrays with POST data.
+ *
+ * @param array values of form fields set via {@link HTTP_Request2::addPostParameter()}
+ * @param array file uploads set via {@link HTTP_Request2::addUpload()}
+ * @param bool whether to append brackets to array variable names
+ */
+ public function __construct(array $params, array $uploads, $useBrackets = true)
+ {
+ $this->_params = self::_flattenArray('', $params, $useBrackets);
+ foreach ($uploads as $fieldName => $f) {
+ if (!is_array($f['fp'])) {
+ $this->_uploads[] = $f + array('name' => $fieldName);
+ } else {
+ for ($i = 0; $i < count($f['fp']); $i++) {
+ $upload = array(
+ 'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
+ );
+ foreach (array('fp', 'filename', 'size', 'type') as $key) {
+ $upload[$key] = $f[$key][$i];
+ }
+ $this->_uploads[] = $upload;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the length of the body to use in Content-Length header
+ *
+ * @return integer
+ */
+ public function getLength()
+ {
+ $boundaryLength = strlen($this->getBoundary());
+ $headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
+ $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
+ $length = $boundaryLength + 6;
+ foreach ($this->_params as $p) {
+ $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
+ }
+ foreach ($this->_uploads as $u) {
+ $length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
+ strlen($u['filename']) + $u['size'] + 2;
+ }
+ return $length;
+ }
+
+ /**
+ * Returns the boundary to use in Content-Type header
+ *
+ * @return string
+ */
+ public function getBoundary()
+ {
+ if (empty($this->_boundary)) {
+ $this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
+ }
+ return $this->_boundary;
+ }
+
+ /**
+ * Returns next chunk of request body
+ *
+ * @param integer Amount of bytes to read
+ * @return string Up to $length bytes of data, empty string if at end
+ */
+ public function read($length)
+ {
+ $ret = '';
+ $boundary = $this->getBoundary();
+ $paramCount = count($this->_params);
+ $uploadCount = count($this->_uploads);
+ while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
+ $oldLength = $length;
+ if ($this->_pos[0] < $paramCount) {
+ $param = sprintf($this->_headerParam, $boundary,
+ $this->_params[$this->_pos[0]][0]) .
+ $this->_params[$this->_pos[0]][1] . "\r\n";
+ $ret .= substr($param, $this->_pos[1], $length);
+ $length -= min(strlen($param) - $this->_pos[1], $length);
+
+ } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
+ $pos = $this->_pos[0] - $paramCount;
+ $header = sprintf($this->_headerUpload, $boundary,
+ $this->_uploads[$pos]['name'],
+ $this->_uploads[$pos]['filename'],
+ $this->_uploads[$pos]['type']);
+ if ($this->_pos[1] < strlen($header)) {
+ $ret .= substr($header, $this->_pos[1], $length);
+ $length -= min(strlen($header) - $this->_pos[1], $length);
+ }
+ $filePos = max(0, $this->_pos[1] - strlen($header));
+ if ($length > 0 && $filePos < $this->_uploads[$pos]['size']) {
+ $ret .= fread($this->_uploads[$pos]['fp'], $length);
+ $length -= min($length, $this->_uploads[$pos]['size'] - $filePos);
+ }
+ if ($length > 0) {
+ $start = $this->_pos[1] + ($oldLength - $length) -
+ strlen($header) - $this->_uploads[$pos]['size'];
+ $ret .= substr("\r\n", $start, $length);
+ $length -= min(2 - $start, $length);
+ }
+
+ } else {
+ $closing = '--' . $boundary . "--\r\n";
+ $ret .= substr($closing, $this->_pos[1], $length);
+ $length -= min(strlen($closing) - $this->_pos[1], $length);
+ }
+ if ($length > 0) {
+ $this->_pos = array($this->_pos[0] + 1, 0);
+ } else {
+ $this->_pos[1] += $oldLength;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Sets the current position to the start of the body
+ *
+ * This allows reusing the same body in another request
+ */
+ public function rewind()
+ {
+ $this->_pos = array(0, 0);
+ foreach ($this->_uploads as $u) {
+ rewind($u['fp']);
+ }
+ }
+
+ /**
+ * Returns the body as string
+ *
+ * Note that it reads all file uploads into memory so it is a good idea not
+ * to use this method with large file uploads and rely on read() instead.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $this->rewind();
+ return $this->read($this->getLength());
+ }
+
+
+ /**
+ * Helper function to change the (probably multidimensional) associative array
+ * into the simple one.
+ *
+ * @param string name for item
+ * @param mixed item's values
+ * @param bool whether to append [] to array variables' names
+ * @return array array with the following items: array('item name', 'item value');
+ */
+ private static function _flattenArray($name, $values, $useBrackets)
+ {
+ if (!is_array($values)) {
+ return array(array($name, $values));
+ } else {
+ $ret = array();
+ foreach ($values as $k => $v) {
+ if (empty($name)) {
+ $newName = $k;
+ } elseif ($useBrackets) {
+ $newName = $name . '[' . $k . ']';
+ } else {
+ $newName = $name;
+ }
+ $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
+ }
+ return $ret;
+ }
+ }
+}
+?>
diff --git a/extlib/HTTP/Request2/Observer/Log.php b/extlib/HTTP/Request2/Observer/Log.php
new file mode 100644
index 000000000..b1a055278
--- /dev/null
+++ b/extlib/HTTP/Request2/Observer/Log.php
@@ -0,0 +1,215 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author David Jean Louis
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Log.php 272593 2009-01-02 16:27:14Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * A debug observer useful for debugging / testing.
+ *
+ * This observer logs to a log target data corresponding to the various request
+ * and response events, it logs by default to php://output but can be configured
+ * to log to a file or via the PEAR Log package.
+ *
+ * A simple example:
+ *
+ * require_once 'HTTP/Request2.php';
+ * require_once 'HTTP/Request2/Observer/Log.php';
+ *
+ * $request = new HTTP_Request2('http://www.example.com');
+ * $observer = new HTTP_Request2_Observer_Log();
+ * $request->attach($observer);
+ * $request->send();
+ *
+ *
+ * A more complex example with PEAR Log:
+ *
+ * require_once 'HTTP/Request2.php';
+ * require_once 'HTTP/Request2/Observer/Log.php';
+ * require_once 'Log.php';
+ *
+ * $request = new HTTP_Request2('http://www.example.com');
+ * // we want to log with PEAR log
+ * $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
+ *
+ * // we only want to log received headers
+ * $observer->events = array('receivedHeaders');
+ *
+ * $request->attach($observer);
+ * $request->send();
+ *
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author David Jean Louis
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: 0.4.1
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+class HTTP_Request2_Observer_Log implements SplObserver
+{
+ // properties {{{
+
+ /**
+ * The log target, it can be a a resource or a PEAR Log instance.
+ *
+ * @var resource|Log $target
+ */
+ protected $target = null;
+
+ /**
+ * The events to log.
+ *
+ * @var array $events
+ */
+ public $events = array(
+ 'connect',
+ 'sentHeaders',
+ 'sentBodyPart',
+ 'receivedHeaders',
+ 'receivedBody',
+ 'disconnect',
+ );
+
+ // }}}
+ // __construct() {{{
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $target Can be a file path (default: php://output), a resource,
+ * or an instance of the PEAR Log class.
+ * @param array $events Array of events to listen to (default: all events)
+ *
+ * @return void
+ */
+ public function __construct($target = 'php://output', array $events = array())
+ {
+ if (!empty($events)) {
+ $this->events = $events;
+ }
+ if (is_resource($target) || $target instanceof Log) {
+ $this->target = $target;
+ } elseif (false === ($this->target = @fopen($target, 'w'))) {
+ throw new HTTP_Request2_Exception("Unable to open '{$target}'");
+ }
+ }
+
+ // }}}
+ // update() {{{
+
+ /**
+ * Called when the request notify us of an event.
+ *
+ * @param HTTP_Request2 $subject The HTTP_Request2 instance
+ *
+ * @return void
+ */
+ public function update(SplSubject $subject)
+ {
+ $event = $subject->getLastEvent();
+ if (!in_array($event['name'], $this->events)) {
+ return;
+ }
+
+ switch ($event['name']) {
+ case 'connect':
+ $this->log('* Connected to ' . $event['data']);
+ break;
+ case 'sentHeaders':
+ $headers = explode("\r\n", $event['data']);
+ array_pop($headers);
+ foreach ($headers as $header) {
+ $this->log('> ' . $header);
+ }
+ break;
+ case 'sentBodyPart':
+ $this->log('> ' . $event['data']);
+ break;
+ case 'receivedHeaders':
+ $this->log(sprintf('< HTTP/%s %s %s',
+ $event['data']->getVersion(),
+ $event['data']->getStatus(),
+ $event['data']->getReasonPhrase()));
+ $headers = $event['data']->getHeader();
+ foreach ($headers as $key => $val) {
+ $this->log('< ' . $key . ': ' . $val);
+ }
+ $this->log('< ');
+ break;
+ case 'receivedBody':
+ $this->log($event['data']->getBody());
+ break;
+ case 'disconnect':
+ $this->log('* Disconnected');
+ break;
+ }
+ }
+
+ // }}}
+ // log() {{{
+
+ /**
+ * Log the given message to the configured target.
+ *
+ * @param string $message Message to display
+ *
+ * @return void
+ */
+ protected function log($message)
+ {
+ if ($this->target instanceof Log) {
+ $this->target->debug($message);
+ } elseif (is_resource($this->target)) {
+ fwrite($this->target, $message . "\r\n");
+ }
+ }
+
+ // }}}
+}
+
+?>
\ No newline at end of file
diff --git a/extlib/HTTP/Request2/Response.php b/extlib/HTTP/Request2/Response.php
new file mode 100644
index 000000000..c7c1021fb
--- /dev/null
+++ b/extlib/HTTP/Request2/Response.php
@@ -0,0 +1,549 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Response.php 287948 2009-09-01 17:12:18Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * Class representing a HTTP response
+ *
+ * The class is designed to be used in "streaming" scenario, building the
+ * response as it is being received:
+ *
+ * $statusLine = read_status_line();
+ * $response = new HTTP_Request2_Response($statusLine);
+ * do {
+ * $headerLine = read_header_line();
+ * $response->parseHeaderLine($headerLine);
+ * } while ($headerLine != '');
+ *
+ * while ($chunk = read_body()) {
+ * $response->appendBody($chunk);
+ * }
+ *
+ * var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
+ *
+ *
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ * @link http://tools.ietf.org/html/rfc2616#section-6
+ */
+class HTTP_Request2_Response
+{
+ /**
+ * HTTP protocol version (e.g. 1.0, 1.1)
+ * @var string
+ */
+ protected $version;
+
+ /**
+ * Status code
+ * @var integer
+ * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
+ */
+ protected $code;
+
+ /**
+ * Reason phrase
+ * @var string
+ * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
+ */
+ protected $reasonPhrase;
+
+ /**
+ * Associative array of response headers
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * Cookies set in the response
+ * @var array
+ */
+ protected $cookies = array();
+
+ /**
+ * Name of last header processed by parseHederLine()
+ *
+ * Used to handle the headers that span multiple lines
+ *
+ * @var string
+ */
+ protected $lastHeader = null;
+
+ /**
+ * Response body
+ * @var string
+ */
+ protected $body = '';
+
+ /**
+ * Whether the body is still encoded by Content-Encoding
+ *
+ * cURL provides the decoded body to the callback; if we are reading from
+ * socket the body is still gzipped / deflated
+ *
+ * @var bool
+ */
+ protected $bodyEncoded;
+
+ /**
+ * Associative array of HTTP status code / reason phrase.
+ *
+ * @var array
+ * @link http://tools.ietf.org/html/rfc2616#section-10
+ */
+ protected static $phrases = array(
+
+ // 1xx: Informational - Request received, continuing process
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+
+ // 2xx: Success - The action was successfully received, understood and
+ // accepted
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+
+ // 3xx: Redirection - Further action must be taken in order to complete
+ // the request
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found', // 1.1
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+
+ // 4xx: Client Error - The request contains bad syntax or cannot be
+ // fulfilled
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+
+ // 5xx: Server Error - The server failed to fulfill an apparently
+ // valid request
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 509 => 'Bandwidth Limit Exceeded',
+
+ );
+
+ /**
+ * Constructor, parses the response status line
+ *
+ * @param string Response status line (e.g. "HTTP/1.1 200 OK")
+ * @param bool Whether body is still encoded by Content-Encoding
+ * @throws HTTP_Request2_Exception if status line is invalid according to spec
+ */
+ public function __construct($statusLine, $bodyEncoded = true)
+ {
+ if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
+ throw new HTTP_Request2_Exception("Malformed response: {$statusLine}");
+ }
+ $this->version = $m[1];
+ $this->code = intval($m[2]);
+ if (!empty($m[3])) {
+ $this->reasonPhrase = trim($m[3]);
+ } elseif (!empty(self::$phrases[$this->code])) {
+ $this->reasonPhrase = self::$phrases[$this->code];
+ }
+ $this->bodyEncoded = (bool)$bodyEncoded;
+ }
+
+ /**
+ * Parses the line from HTTP response filling $headers array
+ *
+ * The method should be called after reading the line from socket or receiving
+ * it into cURL callback. Passing an empty string here indicates the end of
+ * response headers and triggers additional processing, so be sure to pass an
+ * empty string in the end.
+ *
+ * @param string Line from HTTP response
+ */
+ public function parseHeaderLine($headerLine)
+ {
+ $headerLine = trim($headerLine, "\r\n");
+
+ // empty string signals the end of headers, process the received ones
+ if ('' == $headerLine) {
+ if (!empty($this->headers['set-cookie'])) {
+ $cookies = is_array($this->headers['set-cookie'])?
+ $this->headers['set-cookie']:
+ array($this->headers['set-cookie']);
+ foreach ($cookies as $cookieString) {
+ $this->parseCookie($cookieString);
+ }
+ unset($this->headers['set-cookie']);
+ }
+ foreach (array_keys($this->headers) as $k) {
+ if (is_array($this->headers[$k])) {
+ $this->headers[$k] = implode(', ', $this->headers[$k]);
+ }
+ }
+
+ // string of the form header-name: header value
+ } elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
+ $name = strtolower($m[1]);
+ $value = trim($m[2]);
+ if (empty($this->headers[$name])) {
+ $this->headers[$name] = $value;
+ } else {
+ if (!is_array($this->headers[$name])) {
+ $this->headers[$name] = array($this->headers[$name]);
+ }
+ $this->headers[$name][] = $value;
+ }
+ $this->lastHeader = $name;
+
+ // string
+ } elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
+ if (!is_array($this->headers[$this->lastHeader])) {
+ $this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
+ } else {
+ $key = count($this->headers[$this->lastHeader]) - 1;
+ $this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
+ }
+ }
+ }
+
+ /**
+ * Parses a Set-Cookie header to fill $cookies array
+ *
+ * @param string value of Set-Cookie header
+ * @link http://cgi.netscape.com/newsref/std/cookie_spec.html
+ */
+ protected function parseCookie($cookieString)
+ {
+ $cookie = array(
+ 'expires' => null,
+ 'domain' => null,
+ 'path' => null,
+ 'secure' => false
+ );
+
+ // Only a name=value pair
+ if (!strpos($cookieString, ';')) {
+ $pos = strpos($cookieString, '=');
+ $cookie['name'] = trim(substr($cookieString, 0, $pos));
+ $cookie['value'] = trim(substr($cookieString, $pos + 1));
+
+ // Some optional parameters are supplied
+ } else {
+ $elements = explode(';', $cookieString);
+ $pos = strpos($elements[0], '=');
+ $cookie['name'] = trim(substr($elements[0], 0, $pos));
+ $cookie['value'] = trim(substr($elements[0], $pos + 1));
+
+ for ($i = 1; $i < count($elements); $i++) {
+ if (false === strpos($elements[$i], '=')) {
+ $elName = trim($elements[$i]);
+ $elValue = null;
+ } else {
+ list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
+ }
+ $elName = strtolower($elName);
+ if ('secure' == $elName) {
+ $cookie['secure'] = true;
+ } elseif ('expires' == $elName) {
+ $cookie['expires'] = str_replace('"', '', $elValue);
+ } elseif ('path' == $elName || 'domain' == $elName) {
+ $cookie[$elName] = urldecode($elValue);
+ } else {
+ $cookie[$elName] = $elValue;
+ }
+ }
+ }
+ $this->cookies[] = $cookie;
+ }
+
+ /**
+ * Appends a string to the response body
+ * @param string
+ */
+ public function appendBody($bodyChunk)
+ {
+ $this->body .= $bodyChunk;
+ }
+
+ /**
+ * Returns the status code
+ * @return integer
+ */
+ public function getStatus()
+ {
+ return $this->code;
+ }
+
+ /**
+ * Returns the reason phrase
+ * @return string
+ */
+ public function getReasonPhrase()
+ {
+ return $this->reasonPhrase;
+ }
+
+ /**
+ * Returns either the named header or all response headers
+ *
+ * @param string Name of header to return
+ * @return string|array Value of $headerName header (null if header is
+ * not present), array of all response headers if
+ * $headerName is null
+ */
+ public function getHeader($headerName = null)
+ {
+ if (null === $headerName) {
+ return $this->headers;
+ } else {
+ $headerName = strtolower($headerName);
+ return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
+ }
+ }
+
+ /**
+ * Returns cookies set in response
+ *
+ * @return array
+ */
+ public function getCookies()
+ {
+ return $this->cookies;
+ }
+
+ /**
+ * Returns the body of the response
+ *
+ * @return string
+ * @throws HTTP_Request2_Exception if body cannot be decoded
+ */
+ public function getBody()
+ {
+ if (!$this->bodyEncoded ||
+ !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
+ ) {
+ return $this->body;
+
+ } else {
+ if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
+ $oldEncoding = mb_internal_encoding();
+ mb_internal_encoding('iso-8859-1');
+ }
+
+ try {
+ switch (strtolower($this->getHeader('content-encoding'))) {
+ case 'gzip':
+ $decoded = self::decodeGzip($this->body);
+ break;
+ case 'deflate':
+ $decoded = self::decodeDeflate($this->body);
+ }
+ } catch (Exception $e) {
+ }
+
+ if (!empty($oldEncoding)) {
+ mb_internal_encoding($oldEncoding);
+ }
+ if (!empty($e)) {
+ throw $e;
+ }
+ return $decoded;
+ }
+ }
+
+ /**
+ * Get the HTTP version of the response
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Decodes the message-body encoded by gzip
+ *
+ * The real decoding work is done by gzinflate() built-in function, this
+ * method only parses the header and checks data for compliance with
+ * RFC 1952
+ *
+ * @param string gzip-encoded data
+ * @return string decoded data
+ * @throws HTTP_Request2_Exception
+ * @link http://tools.ietf.org/html/rfc1952
+ */
+ public static function decodeGzip($data)
+ {
+ $length = strlen($data);
+ // If it doesn't look like gzip-encoded data, don't bother
+ if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
+ return $data;
+ }
+ if (!function_exists('gzinflate')) {
+ throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
+ }
+ $method = ord(substr($data, 2, 1));
+ if (8 != $method) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: unknown compression method');
+ }
+ $flags = ord(substr($data, 3, 1));
+ if ($flags & 224) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: reserved bits are set');
+ }
+
+ // header is 10 bytes minimum. may be longer, though.
+ $headerLength = 10;
+ // extra fields, need to skip 'em
+ if ($flags & 4) {
+ if ($length - $headerLength - 2 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $extraLength = unpack('v', substr($data, 10, 2));
+ if ($length - $headerLength - 2 - $extraLength[1] < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $headerLength += $extraLength[1] + 2;
+ }
+ // file name, need to skip that
+ if ($flags & 8) {
+ if ($length - $headerLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $filenameLength = strpos(substr($data, $headerLength), chr(0));
+ if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $headerLength += $filenameLength + 1;
+ }
+ // comment, need to skip that also
+ if ($flags & 16) {
+ if ($length - $headerLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $commentLength = strpos(substr($data, $headerLength), chr(0));
+ if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $headerLength += $commentLength + 1;
+ }
+ // have a CRC for header. let's check
+ if ($flags & 2) {
+ if ($length - $headerLength - 2 < 8) {
+ throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+ }
+ $crcReal = 0xffff & crc32(substr($data, 0, $headerLength));
+ $crcStored = unpack('v', substr($data, $headerLength, 2));
+ if ($crcReal != $crcStored[1]) {
+ throw new HTTP_Request2_Exception('Header CRC check failed');
+ }
+ $headerLength += 2;
+ }
+ // unpacked data CRC and size at the end of encoded data
+ $tmp = unpack('V2', substr($data, -8));
+ $dataCrc = $tmp[1];
+ $dataSize = $tmp[2];
+
+ // finally, call the gzinflate() function
+ // don't pass $dataSize to gzinflate, see bugs #13135, #14370
+ $unpacked = gzinflate(substr($data, $headerLength, -8));
+ if (false === $unpacked) {
+ throw new HTTP_Request2_Exception('gzinflate() call failed');
+ } elseif ($dataSize != strlen($unpacked)) {
+ throw new HTTP_Request2_Exception('Data size check failed');
+ } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
+ throw new HTTP_Request2_Exception('Data CRC check failed');
+ }
+ return $unpacked;
+ }
+
+ /**
+ * Decodes the message-body encoded by deflate
+ *
+ * @param string deflate-encoded data
+ * @return string decoded data
+ * @throws HTTP_Request2_Exception
+ */
+ public static function decodeDeflate($data)
+ {
+ if (!function_exists('gzuncompress')) {
+ throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
+ }
+ // RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
+ // while many applications send raw deflate stream from RFC 1951.
+ // We should check for presence of zlib header and use gzuncompress() or
+ // gzinflate() as needed. See bug #15305
+ $header = unpack('n', substr($data, 0, 2));
+ return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
+ }
+}
+?>
\ No newline at end of file
diff --git a/extlib/Net/URL2.php b/extlib/Net/URL2.php
index 7a654aed8..f7fbcd9ce 100644
--- a/extlib/Net/URL2.php
+++ b/extlib/Net/URL2.php
@@ -1,44 +1,58 @@
|
-// +-----------------------------------------------------------------------+
-//
-// $Id: URL2.php,v 1.10 2008/04/26 21:57:08 schmidt Exp $
-//
-// Net_URL2 Class (PHP5 Only)
-
-// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php
/**
- * @license BSD License
+ * Net_URL2, a class representing a URL as per RFC 3986.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2007-2009, Peytz & Co. A/S
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_LexerGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Networking
+ * @package Net_URL2
+ * @author Christian Schmidt
+ * @copyright 2007-2008 Peytz & Co. A/S
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: URL2.php 286661 2009-08-02 12:50:54Z schmidt $
+ * @link http://www.rfc-editor.org/rfc/rfc3986.txt
+ */
+
+/**
+ * Represents a URL as per RFC 3986.
+ *
+ * @category Networking
+ * @package Net_URL2
+ * @author Christian Schmidt
+ * @copyright 2007-2008 Peytz & Co. ApS
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/Net_URL2
*/
class Net_URL2
{
@@ -46,24 +60,24 @@ class Net_URL2
* Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
* is true.
*/
- const OPTION_STRICT = 'strict';
+ const OPTION_STRICT = 'strict';
/**
* Represent arrays in query using PHP's [] notation. Default is true.
*/
- const OPTION_USE_BRACKETS = 'use_brackets';
+ const OPTION_USE_BRACKETS = 'use_brackets';
/**
* URL-encode query variable keys. Default is true.
*/
- const OPTION_ENCODE_KEYS = 'encode_keys';
+ const OPTION_ENCODE_KEYS = 'encode_keys';
/**
* Query variable separators when parsing the query string. Every character
* is considered a separator. Default is specified by the
* arg_separator.input php.ini setting (this defaults to "&").
*/
- const OPTION_SEPARATOR_INPUT = 'input_separator';
+ const OPTION_SEPARATOR_INPUT = 'input_separator';
/**
* Query variable separator used when generating the query string. Default
@@ -75,7 +89,7 @@ class Net_URL2
/**
* Default options corresponds to how PHP handles $_GET.
*/
- private $options = array(
+ private $_options = array(
self::OPTION_STRICT => true,
self::OPTION_USE_BRACKETS => true,
self::OPTION_ENCODE_KEYS => true,
@@ -86,41 +100,43 @@ class Net_URL2
/**
* @var string|bool
*/
- private $scheme = false;
+ private $_scheme = false;
/**
* @var string|bool
*/
- private $userinfo = false;
+ private $_userinfo = false;
/**
* @var string|bool
*/
- private $host = false;
+ private $_host = false;
/**
* @var int|bool
*/
- private $port = false;
+ private $_port = false;
/**
* @var string
*/
- private $path = '';
+ private $_path = '';
/**
* @var string|bool
*/
- private $query = false;
+ private $_query = false;
/**
* @var string|bool
*/
- private $fragment = false;
+ private $_fragment = false;
/**
+ * Constructor.
+ *
* @param string $url an absolute or relative URL
- * @param array $options
+ * @param array $options an array of OPTION_xxx constants
*/
public function __construct($url, $options = null)
{
@@ -130,12 +146,12 @@ class Net_URL2
ini_get('arg_separator.output'));
if (is_array($options)) {
foreach ($options as $optionName => $value) {
- $this->setOption($optionName);
+ $this->setOption($optionName, $value);
}
}
if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
- $this->scheme = $reg[1];
+ $this->_scheme = $reg[1];
$url = substr($url, strlen($reg[0]));
}
@@ -145,19 +161,58 @@ class Net_URL2
}
$i = strcspn($url, '?#');
- $this->path = substr($url, 0, $i);
+ $this->_path = substr($url, 0, $i);
$url = substr($url, $i);
if (preg_match('@^\?([^#]*)@', $url, $reg)) {
- $this->query = $reg[1];
+ $this->_query = $reg[1];
$url = substr($url, strlen($reg[0]));
}
if ($url) {
- $this->fragment = substr($url, 1);
+ $this->_fragment = substr($url, 1);
}
}
+ /**
+ * Magic Setter.
+ *
+ * This method will magically set the value of a private variable ($var)
+ * with the value passed as the args
+ *
+ * @param string $var The private variable to set.
+ * @param mixed $arg An argument of any type.
+ * @return void
+ */
+ public function __set($var, $arg)
+ {
+ $method = 'set' . $var;
+ if (method_exists($this, $method)) {
+ $this->$method($arg);
+ }
+ }
+
+ /**
+ * Magic Getter.
+ *
+ * This is the magic get method to retrieve the private variable
+ * that was set by either __set() or it's setter...
+ *
+ * @param string $var The property name to retrieve.
+ * @return mixed $this->$var Either a boolean false if the
+ * property is not set or the value
+ * of the private property.
+ */
+ public function __get($var)
+ {
+ $method = 'get' . $var;
+ if (method_exists($this, $method)) {
+ return $this->$method();
+ }
+
+ return false;
+ }
+
/**
* Returns the scheme, e.g. "http" or "urn", or false if there is no
* scheme specified, i.e. if this is a relative URL.
@@ -166,18 +221,23 @@ class Net_URL2
*/
public function getScheme()
{
- return $this->scheme;
+ return $this->_scheme;
}
/**
- * @param string|bool $scheme
+ * Sets the scheme, e.g. "http" or "urn". Specify false if there is no
+ * scheme specified, i.e. if this is a relative URL.
+ *
+ * @param string|bool $scheme e.g. "http" or "urn", or false if there is no
+ * scheme specified, i.e. if this is a relative
+ * URL
*
* @return void
* @see getScheme()
*/
public function setScheme($scheme)
{
- $this->scheme = $scheme;
+ $this->_scheme = $scheme;
}
/**
@@ -188,7 +248,9 @@ class Net_URL2
*/
public function getUser()
{
- return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false;
+ return $this->_userinfo !== false
+ ? preg_replace('@:.*$@', '', $this->_userinfo)
+ : false;
}
/**
@@ -201,7 +263,9 @@ class Net_URL2
*/
public function getPassword()
{
- return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false;
+ return $this->_userinfo !== false
+ ? substr(strstr($this->_userinfo, ':'), 1)
+ : false;
}
/**
@@ -212,7 +276,7 @@ class Net_URL2
*/
public function getUserinfo()
{
- return $this->userinfo;
+ return $this->_userinfo;
}
/**
@@ -220,15 +284,15 @@ class Net_URL2
* in the userinfo part as username ":" password.
*
* @param string|bool $userinfo userinfo or username
- * @param string|bool $password
+ * @param string|bool $password optional password, or false
*
* @return void
*/
public function setUserinfo($userinfo, $password = false)
{
- $this->userinfo = $userinfo;
+ $this->_userinfo = $userinfo;
if ($password !== false) {
- $this->userinfo .= ':' . $password;
+ $this->_userinfo .= ':' . $password;
}
}
@@ -236,21 +300,24 @@ class Net_URL2
* Returns the host part, or false if there is no authority part, e.g.
* relative URLs.
*
- * @return string|bool
+ * @return string|bool a hostname, an IP address, or false
*/
public function getHost()
{
- return $this->host;
+ return $this->_host;
}
/**
- * @param string|bool $host
+ * Sets the host part. Specify false if there is no authority part, e.g.
+ * relative URLs.
+ *
+ * @param string|bool $host a hostname, an IP address, or false
*
* @return void
*/
public function setHost($host)
{
- $this->host = $host;
+ $this->_host = $host;
}
/**
@@ -261,65 +328,72 @@ class Net_URL2
*/
public function getPort()
{
- return $this->port;
+ return $this->_port;
}
/**
- * @param int|bool $port
+ * Sets the port number. Specify false if there is no port number specified,
+ * i.e. if the default port is to be used.
+ *
+ * @param int|bool $port a port number, or false
*
* @return void
*/
public function setPort($port)
{
- $this->port = intval($port);
+ $this->_port = intval($port);
}
/**
* Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
- * false if there is no authority none.
+ * false if there is no authority.
*
* @return string|bool
*/
public function getAuthority()
{
- if (!$this->host) {
+ if (!$this->_host) {
return false;
}
$authority = '';
- if ($this->userinfo !== false) {
- $authority .= $this->userinfo . '@';
+ if ($this->_userinfo !== false) {
+ $authority .= $this->_userinfo . '@';
}
- $authority .= $this->host;
+ $authority .= $this->_host;
- if ($this->port !== false) {
- $authority .= ':' . $this->port;
+ if ($this->_port !== false) {
+ $authority .= ':' . $this->_port;
}
return $authority;
}
/**
- * @param string|false $authority
+ * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
+ * false if there is no authority.
+ *
+ * @param string|false $authority a hostname or an IP addresse, possibly
+ * with userinfo prefixed and port number
+ * appended, e.g. "foo:bar@example.org:81".
*
* @return void
*/
public function setAuthority($authority)
{
- $this->user = false;
- $this->pass = false;
- $this->host = false;
- $this->port = false;
- if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
+ $this->_userinfo = false;
+ $this->_host = false;
+ $this->_port = false;
+ if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
if ($reg[1]) {
- $this->userinfo = $reg[2];
+ $this->_userinfo = $reg[2];
}
- $this->host = $reg[3];
+ $this->_host = $reg[3];
if (isset($reg[5])) {
- $this->port = intval($reg[5]);
+ $this->_port = intval($reg[5]);
}
}
}
@@ -331,65 +405,74 @@ class Net_URL2
*/
public function getPath()
{
- return $this->path;
+ return $this->_path;
}
/**
- * @param string $path
+ * Sets the path part (possibly an empty string).
+ *
+ * @param string $path a path
*
* @return void
*/
public function setPath($path)
{
- $this->path = $path;
+ $this->_path = $path;
}
/**
* Returns the query string (excluding the leading "?"), or false if "?"
- * isn't present in the URL.
+ * is not present in the URL.
*
* @return string|bool
* @see self::getQueryVariables()
*/
public function getQuery()
{
- return $this->query;
+ return $this->_query;
}
/**
- * @param string|bool $query
+ * Sets the query string (excluding the leading "?"). Specify false if "?"
+ * is not present in the URL.
+ *
+ * @param string|bool $query a query string, e.g. "foo=1&bar=2"
*
* @return void
* @see self::setQueryVariables()
*/
public function setQuery($query)
{
- $this->query = $query;
+ $this->_query = $query;
}
/**
- * Returns the fragment name, or false if "#" isn't present in the URL.
+ * Returns the fragment name, or false if "#" is not present in the URL.
*
* @return string|bool
*/
public function getFragment()
{
- return $this->fragment;
+ return $this->_fragment;
}
/**
- * @param string|bool $fragment
+ * Sets the fragment name. Specify false if "#" is not present in the URL.
+ *
+ * @param string|bool $fragment a fragment excluding the leading "#", or
+ * false
*
* @return void
*/
public function setFragment($fragment)
{
- $this->fragment = $fragment;
+ $this->_fragment = $fragment;
}
/**
* Returns the query string like an array as the variables would appear in
- * $_GET in a PHP script.
+ * $_GET in a PHP script. If the URL does not contain a "?", an empty array
+ * is returned.
*
* @return array
*/
@@ -398,7 +481,7 @@ class Net_URL2
$pattern = '/[' .
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
']/';
- $parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY);
+ $parts = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach ($parts as $part) {
@@ -445,6 +528,8 @@ class Net_URL2
}
/**
+ * Sets the query string to the specified variable in the query string.
+ *
* @param array $array (name => value) array
*
* @return void
@@ -452,11 +537,11 @@ class Net_URL2
public function setQueryVariables(array $array)
{
if (!$array) {
- $this->query = false;
+ $this->_query = false;
} else {
foreach ($array as $name => $value) {
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
- $name = rawurlencode($name);
+ $name = self::urlencode($name);
}
if (is_array($value)) {
@@ -466,19 +551,21 @@ class Net_URL2
: ($name . '=' . $v);
}
} elseif (!is_null($value)) {
- $parts[] = $name . '=' . $value;
+ $parts[] = $name . '=' . self::urlencode($value);
} else {
$parts[] = $name;
}
}
- $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
- $parts);
+ $this->_query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
+ $parts);
}
}
/**
- * @param string $name
- * @param mixed $value
+ * Sets the specified variable in the query string.
+ *
+ * @param string $name variable name
+ * @param mixed $value variable value
*
* @return array
*/
@@ -490,7 +577,9 @@ class Net_URL2
}
/**
- * @param string $name
+ * Removes the specifed variable from the query string.
+ *
+ * @param string $name a query string variable, e.g. "foo" in "?foo=1"
*
* @return void
*/
@@ -511,27 +600,38 @@ class Net_URL2
// See RFC 3986, section 5.3
$url = "";
- if ($this->scheme !== false) {
- $url .= $this->scheme . ':';
+ if ($this->_scheme !== false) {
+ $url .= $this->_scheme . ':';
}
$authority = $this->getAuthority();
if ($authority !== false) {
$url .= '//' . $authority;
}
- $url .= $this->path;
+ $url .= $this->_path;
- if ($this->query !== false) {
- $url .= '?' . $this->query;
+ if ($this->_query !== false) {
+ $url .= '?' . $this->_query;
}
- if ($this->fragment !== false) {
- $url .= '#' . $this->fragment;
+ if ($this->_fragment !== false) {
+ $url .= '#' . $this->_fragment;
}
return $url;
}
+ /**
+ * Returns a string representation of this URL.
+ *
+ * @return string
+ * @see toString()
+ */
+ public function __toString()
+ {
+ return $this->getURL();
+ }
+
/**
* Returns a normalized string representation of this URL. This is useful
* for comparison of URLs.
@@ -555,36 +655,38 @@ class Net_URL2
// See RFC 3886, section 6
// Schemes are case-insensitive
- if ($this->scheme) {
- $this->scheme = strtolower($this->scheme);
+ if ($this->_scheme) {
+ $this->_scheme = strtolower($this->_scheme);
}
// Hostnames are case-insensitive
- if ($this->host) {
- $this->host = strtolower($this->host);
+ if ($this->_host) {
+ $this->_host = strtolower($this->_host);
}
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
- if ($this->port &&
- $this->scheme &&
- $this->port == getservbyname($this->scheme, 'tcp')) {
+ if ($this->_port &&
+ $this->_scheme &&
+ $this->_port == getservbyname($this->_scheme, 'tcp')) {
- $this->port = false;
+ $this->_port = false;
}
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
- foreach (array('userinfo', 'host', 'path') as $part) {
+ foreach (array('_userinfo', '_host', '_path') as $part) {
if ($this->$part) {
- $this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part);
+ $this->$part = preg_replace('/%[0-9a-f]{2}/ie',
+ 'strtoupper("\0")',
+ $this->$part);
}
}
// Path segment normalization (RFC 3986, section 6.2.2.3)
- $this->path = self::removeDotSegments($this->path);
+ $this->_path = self::removeDotSegments($this->_path);
// Scheme based normalization (RFC 3986, section 6.2.3)
- if ($this->host && !$this->path) {
- $this->path = '/';
+ if ($this->_host && !$this->_path) {
+ $this->_path = '/';
}
}
@@ -595,7 +697,7 @@ class Net_URL2
*/
public function isAbsolute()
{
- return (bool) $this->scheme;
+ return (bool) $this->_scheme;
}
/**
@@ -608,7 +710,7 @@ class Net_URL2
*/
public function resolve($reference)
{
- if (is_string($reference)) {
+ if (!$reference instanceof Net_URL2) {
$reference = new self($reference);
}
if (!$this->isAbsolute()) {
@@ -617,54 +719,54 @@ class Net_URL2
// A non-strict parser may ignore a scheme in the reference if it is
// identical to the base URI's scheme.
- if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) {
- $reference->scheme = false;
+ if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
+ $reference->_scheme = false;
}
$target = new self('');
- if ($reference->scheme !== false) {
- $target->scheme = $reference->scheme;
+ if ($reference->_scheme !== false) {
+ $target->_scheme = $reference->_scheme;
$target->setAuthority($reference->getAuthority());
- $target->path = self::removeDotSegments($reference->path);
- $target->query = $reference->query;
+ $target->_path = self::removeDotSegments($reference->_path);
+ $target->_query = $reference->_query;
} else {
$authority = $reference->getAuthority();
if ($authority !== false) {
$target->setAuthority($authority);
- $target->path = self::removeDotSegments($reference->path);
- $target->query = $reference->query;
+ $target->_path = self::removeDotSegments($reference->_path);
+ $target->_query = $reference->_query;
} else {
- if ($reference->path == '') {
- $target->path = $this->path;
- if ($reference->query !== false) {
- $target->query = $reference->query;
+ if ($reference->_path == '') {
+ $target->_path = $this->_path;
+ if ($reference->_query !== false) {
+ $target->_query = $reference->_query;
} else {
- $target->query = $this->query;
+ $target->_query = $this->_query;
}
} else {
- if (substr($reference->path, 0, 1) == '/') {
- $target->path = self::removeDotSegments($reference->path);
+ if (substr($reference->_path, 0, 1) == '/') {
+ $target->_path = self::removeDotSegments($reference->_path);
} else {
// Merge paths (RFC 3986, section 5.2.3)
- if ($this->host !== false && $this->path == '') {
- $target->path = '/' . $this->path;
+ if ($this->_host !== false && $this->_path == '') {
+ $target->_path = '/' . $this->_path;
} else {
- $i = strrpos($this->path, '/');
+ $i = strrpos($this->_path, '/');
if ($i !== false) {
- $target->path = substr($this->path, 0, $i + 1);
+ $target->_path = substr($this->_path, 0, $i + 1);
}
- $target->path .= $reference->path;
+ $target->_path .= $reference->_path;
}
- $target->path = self::removeDotSegments($target->path);
+ $target->_path = self::removeDotSegments($target->_path);
}
- $target->query = $reference->query;
+ $target->_query = $reference->_query;
}
$target->setAuthority($this->getAuthority());
}
- $target->scheme = $this->scheme;
+ $target->_scheme = $this->_scheme;
}
- $target->fragment = $reference->fragment;
+ $target->_fragment = $reference->_fragment;
return $target;
}
@@ -677,7 +779,7 @@ class Net_URL2
*
* @return string a path
*/
- private static function removeDotSegments($path)
+ public static function removeDotSegments($path)
{
$output = '';
@@ -685,28 +787,25 @@ class Net_URL2
// method
$j = 0;
while ($path && $j++ < 100) {
- // Step A
if (substr($path, 0, 2) == './') {
+ // Step 2.A
$path = substr($path, 2);
} elseif (substr($path, 0, 3) == '../') {
+ // Step 2.A
$path = substr($path, 3);
-
- // Step B
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
+ // Step 2.B
$path = '/' . substr($path, 3);
-
- // Step C
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
- $path = '/' . substr($path, 4);
- $i = strrpos($output, '/');
+ // Step 2.C
+ $path = '/' . substr($path, 4);
+ $i = strrpos($output, '/');
$output = $i === false ? '' : substr($output, 0, $i);
-
- // Step D
} elseif ($path == '.' || $path == '..') {
+ // Step 2.D
$path = '';
-
- // Step E
} else {
+ // Step 2.E
$i = strpos($path, '/');
if ($i === 0) {
$i = strpos($path, '/', 1);
@@ -722,6 +821,22 @@ class Net_URL2
return $output;
}
+ /**
+ * Percent-encodes all non-alphanumeric characters except these: _ . - ~
+ * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
+ * 5.2.x and earlier.
+ *
+ * @param $raw the string to encode
+ * @return string
+ */
+ public static function urlencode($string)
+ {
+ $encoded = rawurlencode($string);
+ // This is only necessary in PHP < 5.3.
+ $encoded = str_replace('%7E', '~', $encoded);
+ return $encoded;
+ }
+
/**
* Returns a Net_URL2 instance representing the canonical URL of the
* currently executing PHP script.
@@ -737,13 +852,13 @@ class Net_URL2
// Begin with a relative URL
$url = new self($_SERVER['PHP_SELF']);
- $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
- $url->host = $_SERVER['SERVER_NAME'];
+ $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $url->_host = $_SERVER['SERVER_NAME'];
$port = intval($_SERVER['SERVER_PORT']);
- if ($url->scheme == 'http' && $port != 80 ||
- $url->scheme == 'https' && $port != 443) {
+ if ($url->_scheme == 'http' && $port != 80 ||
+ $url->_scheme == 'https' && $port != 443) {
- $url->port = $port;
+ $url->_port = $port;
}
return $url;
}
@@ -773,7 +888,7 @@ class Net_URL2
// Begin with a relative URL
$url = new self($_SERVER['REQUEST_URI']);
- $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
// Set host and possibly port
$url->setAuthority($_SERVER['HTTP_HOST']);
return $url;
@@ -792,10 +907,10 @@ class Net_URL2
*/
function setOption($optionName, $value)
{
- if (!array_key_exists($optionName, $this->options)) {
+ if (!array_key_exists($optionName, $this->_options)) {
return false;
}
- $this->options[$optionName] = $value;
+ $this->_options[$optionName] = $value;
}
/**
@@ -807,7 +922,7 @@ class Net_URL2
*/
function getOption($optionName)
{
- return isset($this->options[$optionName])
- ? $this->options[$optionName] : false;
+ return isset($this->_options[$optionName])
+ ? $this->_options[$optionName] : false;
}
}
diff --git a/install.php b/install.php
index 6bfc4c2e2..d34e92dab 100644
--- a/install.php
+++ b/install.php
@@ -93,6 +93,13 @@ $external_libraries=array(
'include'=>'HTTP/Request.php',
'check_class'=>'HTTP_Request'
),
+ array(
+ 'name'=>'HTTP_Request2',
+ 'pear'=>'HTTP_Request2',
+ 'url'=>'http://pear.php.net/package/HTTP_Request2',
+ 'include'=>'HTTP/Request2.php',
+ 'check_class'=>'HTTP_Request2'
+ ),
array(
'name'=>'Mail',
'pear'=>'Mail',
diff --git a/lib/Shorturl_api.php b/lib/Shorturl_api.php
index 18ae7719b..de4d55012 100644
--- a/lib/Shorturl_api.php
+++ b/lib/Shorturl_api.php
@@ -41,22 +41,18 @@ abstract class ShortUrlApi
return strlen($url) >= common_config('site', 'shorturllength');
}
- protected function http_post($data) {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $this->service_url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
- $response = curl_exec($ch);
- $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- curl_close($ch);
- if (($code < 200) || ($code >= 400)) return false;
- return $response;
+ protected function http_post($data)
+ {
+ $request = HTTPClient::start();
+ $response = $request->post($this->service_url, null, $data);
+ return $response->getBody();
}
- protected function http_get($url) {
- $encoded_url = urlencode($url);
- return file_get_contents("{$this->service_url}$encoded_url");
+ protected function http_get($url)
+ {
+ $request = HTTPClient::start();
+ $response = $request->get($this->service_url . urlencode($url));
+ return $response->getBody();
}
protected function tidy($response) {
diff --git a/lib/curlclient.php b/lib/curlclient.php
deleted file mode 100644
index c307c2984..000000000
--- a/lib/curlclient.php
+++ /dev/null
@@ -1,179 +0,0 @@
-.
- *
- * @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @copyright 2009 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/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-define(CURLCLIENT_VERSION, "0.1");
-
-/**
- * Wrapper for Curl
- *
- * Makes Curl HTTP client calls within our HTTPClient framework
- *
- * @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class CurlClient extends HTTPClient
-{
- function __construct()
- {
- }
-
- function head($url, $headers=null)
- {
- $ch = curl_init($url);
-
- $this->setup($ch);
-
- curl_setopt_array($ch,
- array(CURLOPT_NOBODY => true));
-
- if (!is_null($headers)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- return $this->parseResults($result);
- }
-
- function get($url, $headers=null)
- {
- $ch = curl_init($url);
-
- $this->setup($ch);
-
- if (!is_null($headers)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- return $this->parseResults($result);
- }
-
- function post($url, $headers=null, $body=null)
- {
- $ch = curl_init($url);
-
- $this->setup($ch);
-
- curl_setopt($ch, CURLOPT_POST, true);
-
- if (!is_null($body)) {
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
-
- if (!is_null($headers)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- return $this->parseResults($result);
- }
-
- function setup($ch)
- {
- curl_setopt_array($ch,
- array(CURLOPT_USERAGENT => $this->userAgent(),
- CURLOPT_HEADER => true,
- CURLOPT_RETURNTRANSFER => true));
- }
-
- function userAgent()
- {
- $version = curl_version();
- return parent::userAgent() . " CurlClient/".CURLCLIENT_VERSION . " cURL/" . $version['version'];
- }
-
- function parseResults($results)
- {
- $resp = new HTTPResponse();
-
- $lines = explode("\r\n", $results);
-
- if (preg_match("#^HTTP/1.[01] (\d\d\d) .+$#", $lines[0], $match)) {
- $resp->code = $match[1];
- } else {
- throw Exception("Bad format: initial line is not HTTP status line");
- }
-
- $lastk = null;
-
- for ($i = 1; $i < count($lines); $i++) {
- $l =& $lines[$i];
- if (mb_strlen($l) == 0) {
- $resp->body = implode("\r\n", array_slice($lines, $i + 1));
- break;
- }
- if (preg_match("#^(\S+):\s+(.*)$#", $l, $match)) {
- $k = $match[1];
- $v = $match[2];
-
- if (array_key_exists($k, $resp->headers)) {
- if (is_array($resp->headers[$k])) {
- $resp->headers[$k][] = $v;
- } else {
- $resp->headers[$k] = array($resp->headers[$k], $v);
- }
- } else {
- $resp->headers[$k] = $v;
- }
- $lastk = $k;
- } else if (preg_match("#^\s+(.*)$#", $l, $match)) {
- // continuation line
- if (is_null($lastk)) {
- throw Exception("Bad format: initial whitespace in headers");
- }
- $h =& $resp->headers[$lastk];
- if (is_array($h)) {
- $n = count($h);
- $h[$n-1] .= $match[1];
- } else {
- $h .= $match[1];
- }
- }
- }
-
- return $resp;
- }
-}
diff --git a/lib/default.php b/lib/default.php
index 7ec8558b0..f6cc4b725 100644
--- a/lib/default.php
+++ b/lib/default.php
@@ -228,8 +228,6 @@ $default =
array('contentlimit' => null),
'message' =>
array('contentlimit' => null),
- 'http' =>
- array('client' => 'curl'), // XXX: should this be the default?
'location' =>
array('namespace' => 1), // 1 = geonames, 2 = Yahoo Where on Earth
);
diff --git a/lib/httpclient.php b/lib/httpclient.php
index f16e31e10..3f8262076 100644
--- a/lib/httpclient.php
+++ b/lib/httpclient.php
@@ -31,6 +31,9 @@ if (!defined('STATUSNET')) {
exit(1);
}
+require_once 'HTTP/Request2.php';
+require_once 'HTTP/Request2/Response.php';
+
/**
* Useful structure for HTTP responses
*
@@ -38,18 +41,53 @@ if (!defined('STATUSNET')) {
* ways of doing them. This class hides the specifics of what underlying
* library (curl or PHP-HTTP or whatever) that's used.
*
+ * This extends the HTTP_Request2_Response class with methods to get info
+ * about any followed redirects.
+ *
* @category HTTP
- * @package StatusNet
- * @author Evan Prodromou
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
+ * @package StatusNet
+ * @author Evan Prodromou
+ * @author Brion Vibber
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
*/
-
-class HTTPResponse
+class HTTPResponse extends HTTP_Request2_Response
{
- public $code = null;
- public $headers = array();
- public $body = null;
+ function __construct(HTTP_Request2_Response $response, $url, $redirects=0)
+ {
+ foreach (get_object_vars($response) as $key => $val) {
+ $this->$key = $val;
+ }
+ $this->url = strval($url);
+ $this->redirectCount = intval($redirects);
+ }
+
+ /**
+ * Get the count of redirects that have been followed, if any.
+ * @return int
+ */
+ function getRedirectCount()
+ {
+ return $this->redirectCount;
+ }
+
+ /**
+ * Gets the final target URL, after any redirects have been followed.
+ * @return string URL
+ */
+ function getUrl()
+ {
+ return $this->url;
+ }
+
+ /**
+ * Check if the response is OK, generally a 200 status code.
+ * @return bool
+ */
+ function isOk()
+ {
+ return ($this->getStatus() == 200);
+ }
}
/**
@@ -59,64 +97,163 @@ class HTTPResponse
* ways of doing them. This class hides the specifics of what underlying
* library (curl or PHP-HTTP or whatever) that's used.
*
+ * This extends the PEAR HTTP_Request2 package:
+ * - sends StatusNet-specific User-Agent header
+ * - 'follow_redirects' config option, defaulting off
+ * - 'max_redirs' config option, defaulting to 10
+ * - extended response class adds getRedirectCount() and getUrl() methods
+ * - get() and post() convenience functions return body content directly
+ *
* @category HTTP
* @package StatusNet
* @author Evan Prodromou
+ * @author Brion Vibber
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
-class HTTPClient
+class HTTPClient extends HTTP_Request2
{
- static $_client = null;
- static function start()
+ function __construct($url=null, $method=self::METHOD_GET, $config=array())
{
- if (!is_null(self::$_client)) {
- return self::$_client;
- }
-
- $type = common_config('http', 'client');
-
- switch ($type) {
- case 'curl':
- self::$_client = new CurlClient();
- break;
- default:
- throw new Exception("Unknown HTTP client type '$type'");
- break;
- }
-
- return self::$_client;
+ $this->config['max_redirs'] = 10;
+ $this->config['follow_redirects'] = true;
+ parent::__construct($url, $method, $config);
+ $this->setHeader('User-Agent', $this->userAgent());
}
- function head($url, $headers)
+ /**
+ * Convenience/back-compat instantiator
+ * @return HTTPClient
+ */
+ public static function start()
{
- throw new Exception("HEAD method unimplemented");
+ return new HTTPClient();
}
- function get($url, $headers)
+ /**
+ * Convenience function to run a GET request.
+ *
+ * @return HTTPResponse
+ * @throws HTTP_Request2_Exception
+ */
+ public function get($url, $headers=array())
{
- throw new Exception("GET method unimplemented");
+ return $this->doRequest($url, self::METHOD_GET, $headers);
}
- function post($url, $headers, $body)
+ /**
+ * Convenience function to run a HEAD request.
+ *
+ * @return HTTPResponse
+ * @throws HTTP_Request2_Exception
+ */
+ public function head($url, $headers=array())
{
- throw new Exception("POST method unimplemented");
+ return $this->doRequest($url, self::METHOD_HEAD, $headers);
}
- function put($url, $headers, $body)
+ /**
+ * Convenience function to POST form data.
+ *
+ * @param string $url
+ * @param array $headers optional associative array of HTTP headers
+ * @param array $data optional associative array or blob of form data to submit
+ * @return HTTPResponse
+ * @throws HTTP_Request2_Exception
+ */
+ public function post($url, $headers=array(), $data=array())
{
- throw new Exception("PUT method unimplemented");
+ if ($data) {
+ $this->addPostParameter($data);
+ }
+ return $this->doRequest($url, self::METHOD_POST, $headers);
}
- function delete($url, $headers)
+ /**
+ * @return HTTPResponse
+ * @throws HTTP_Request2_Exception
+ */
+ protected function doRequest($url, $method, $headers)
{
- throw new Exception("DELETE method unimplemented");
+ $this->setUrl($url);
+ $this->setMethod($method);
+ if ($headers) {
+ foreach ($headers as $header) {
+ $this->setHeader($header);
+ }
+ }
+ $response = $this->send();
+ return $response;
+ }
+
+ protected function log($level, $detail) {
+ $method = $this->getMethod();
+ $url = $this->getUrl();
+ common_log($level, __CLASS__ . ": HTTP $method $url - $detail");
}
+ /**
+ * Pulls up StatusNet's customized user-agent string, so services
+ * we hit can track down the responsible software.
+ *
+ * @return string
+ */
function userAgent()
{
return "StatusNet/".STATUSNET_VERSION." (".STATUSNET_CODENAME.")";
}
+
+ /**
+ * Actually performs the HTTP request and returns an HTTPResponse object
+ * with response body and header info.
+ *
+ * Wraps around parent send() to add logging and redirection processing.
+ *
+ * @return HTTPResponse
+ * @throw HTTP_Request2_Exception
+ */
+ public function send()
+ {
+ $maxRedirs = intval($this->config['max_redirs']);
+ if (empty($this->config['follow_redirects'])) {
+ $maxRedirs = 0;
+ }
+ $redirs = 0;
+ do {
+ try {
+ $response = parent::send();
+ } catch (HTTP_Request2_Exception $e) {
+ $this->log(LOG_ERR, $e->getMessage());
+ throw $e;
+ }
+ $code = $response->getStatus();
+ if ($code >= 200 && $code < 300) {
+ $reason = $response->getReasonPhrase();
+ $this->log(LOG_INFO, "$code $reason");
+ } elseif ($code >= 300 && $code < 400) {
+ $url = $this->getUrl();
+ $target = $response->getHeader('Location');
+
+ if (++$redirs >= $maxRedirs) {
+ common_log(LOG_ERR, __CLASS__ . ": Too many redirects: skipping $code redirect from $url to $target");
+ break;
+ }
+ try {
+ $this->setUrl($target);
+ $this->setHeader('Referer', $url);
+ common_log(LOG_INFO, __CLASS__ . ": Following $code redirect from $url to $target");
+ continue;
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_ERR, __CLASS__ . ": Invalid $code redirect from $url to $target");
+ }
+ } else {
+ $reason = $response->getReasonPhrase();
+ $this->log(LOG_ERR, "$code $reason");
+ }
+ break;
+ } while ($maxRedirs);
+ return new HTTPResponse($response, $this->getUrl(), $redirs);
+ }
}
diff --git a/lib/oauthclient.php b/lib/oauthclient.php
index f1827726e..1a86e2460 100644
--- a/lib/oauthclient.php
+++ b/lib/oauthclient.php
@@ -43,7 +43,7 @@ require_once 'OAuth.php';
* @link http://status.net/
*
*/
-class OAuthClientCurlException extends Exception
+class OAuthClientException extends Exception
{
}
@@ -97,9 +97,14 @@ class OAuthClient
function getRequestToken($url)
{
$response = $this->oAuthGet($url);
- parse_str($response);
- $token = new OAuthToken($oauth_token, $oauth_token_secret);
- return $token;
+ $arr = array();
+ parse_str($response, $arr);
+ if (isset($arr['oauth_token']) && isset($arr['oauth_token_secret'])) {
+ $token = new OAuthToken($arr['oauth_token'], @$arr['oauth_token_secret']);
+ return $token;
+ } else {
+ throw new OAuthClientException();
+ }
}
/**
@@ -177,7 +182,7 @@ class OAuthClient
}
/**
- * Make a HTTP request using cURL.
+ * Make a HTTP request.
*
* @param string $url Where to make the
* @param array $params post parameters
@@ -186,40 +191,32 @@ class OAuthClient
*/
function httpRequest($url, $params = null)
{
- $options = array(
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FAILONERROR => true,
- CURLOPT_HEADER => false,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_USERAGENT => 'StatusNet',
- CURLOPT_CONNECTTIMEOUT => 120,
- CURLOPT_TIMEOUT => 120,
- CURLOPT_HTTPAUTH => CURLAUTH_ANY,
- CURLOPT_SSL_VERIFYPEER => false,
-
- // Twitter is strict about accepting invalid "Expect" headers
-
- CURLOPT_HTTPHEADER => array('Expect:')
- );
+ $request = new HTTPClient($url);
+ $request->setConfig(array(
+ 'connect_timeout' => 120,
+ 'timeout' => 120,
+ 'follow_redirects' => true,
+ 'ssl_verify_peer' => false,
+ ));
+
+ // Twitter is strict about accepting invalid "Expect" headers
+ $request->setHeader('Expect', '');
if (isset($params)) {
- $options[CURLOPT_POST] = true;
- $options[CURLOPT_POSTFIELDS] = $params;
+ $request->setMethod(HTTP_Request2::METHOD_POST);
+ $request->setBody($params);
}
- $ch = curl_init($url);
- curl_setopt_array($ch, $options);
- $response = curl_exec($ch);
-
- if ($response === false) {
- $msg = curl_error($ch);
- $code = curl_errno($ch);
- throw new OAuthClientCurlException($msg, $code);
+ try {
+ $response = $request->send();
+ $code = $response->getStatus();
+ if ($code < 200 || $code >= 400) {
+ throw new OAuthClientException($response->getBody(), $code);
+ }
+ return $response->getBody();
+ } catch (Exception $e) {
+ throw new OAuthClientException($e->getMessage(), $e->getCode());
}
-
- curl_close($ch);
-
- return $response;
}
}
diff --git a/lib/ping.php b/lib/ping.php
index 175bf8440..5698c4038 100644
--- a/lib/ping.php
+++ b/lib/ping.php
@@ -44,20 +44,16 @@ function ping_broadcast_notice($notice) {
array('nickname' => $profile->nickname)),
$tags));
- $context = stream_context_create(array('http' => array('method' => "POST",
- 'header' =>
- "Content-Type: text/xml\r\n".
- "User-Agent: StatusNet/".STATUSNET_VERSION."\r\n",
- 'content' => $req)));
- $file = file_get_contents($notify_url, false, $context);
+ $request = HTTPClient::start();
+ $httpResponse = $request->post($notify_url, array('Content-Type: text/xml'), $req);
- if ($file === false || mb_strlen($file) == 0) {
+ if (!$httpResponse || mb_strlen($httpResponse->getBody()) == 0) {
common_log(LOG_WARNING,
"XML-RPC empty results for ping ($notify_url, $notice->id) ");
continue;
}
- $response = xmlrpc_decode($file);
+ $response = xmlrpc_decode($httpResponse->getBody());
if (is_array($response) && xmlrpc_is_fault($response)) {
common_log(LOG_WARNING,
diff --git a/lib/snapshot.php b/lib/snapshot.php
index ede846e5b..2a10c6b93 100644
--- a/lib/snapshot.php
+++ b/lib/snapshot.php
@@ -172,26 +172,9 @@ class Snapshot
{
// XXX: Use OICU2 and OAuth to make authorized requests
- $postdata = http_build_query($this->stats);
-
- $opts =
- array('http' =>
- array(
- 'method' => 'POST',
- 'header' => 'Content-type: '.
- 'application/x-www-form-urlencoded',
- 'content' => $postdata,
- 'user_agent' => 'StatusNet/'.STATUSNET_VERSION
- )
- );
-
- $context = stream_context_create($opts);
-
$reporturl = common_config('snapshot', 'reporturl');
-
- $result = @file_get_contents($reporturl, false, $context);
-
- return $result;
+ $request = HTTPClient::start();
+ $request->post($reporturl, null, $this->stats);
}
/**
diff --git a/plugins/BlogspamNetPlugin.php b/plugins/BlogspamNetPlugin.php
index c14569746..51236001a 100644
--- a/plugins/BlogspamNetPlugin.php
+++ b/plugins/BlogspamNetPlugin.php
@@ -22,6 +22,7 @@
* @category Plugin
* @package StatusNet
* @author Evan Prodromou
+ * @author Brion Vibber
* @copyright 2009 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/
@@ -69,14 +70,12 @@ class BlogspamNetPlugin extends Plugin
{
$args = $this->testArgs($notice);
common_debug("Blogspamnet args = " . print_r($args, TRUE));
- $request = xmlrpc_encode_request('testComment', array($args));
- $context = stream_context_create(array('http' => array('method' => "POST",
- 'header' =>
- "Content-Type: text/xml\r\n".
- "User-Agent: " . $this->userAgent(),
- 'content' => $request)));
- $file = file_get_contents($this->baseUrl, false, $context);
- $response = xmlrpc_decode($file);
+ $requestBody = xmlrpc_encode_request('testComment', array($args));
+
+ $request = HTTPClient::start();
+ $httpResponse = $request->post($this->baseUrl, array('Content-Type: text/xml'), $requestBody);
+
+ $response = xmlrpc_decode($httpResponse->getBody());
if (xmlrpc_is_fault($response)) {
throw new ServerException("$response[faultString] ($response[faultCode])", 500);
} else {
diff --git a/plugins/GeonamesPlugin.php b/plugins/GeonamesPlugin.php
index 80ef44cc9..e18957c36 100644
--- a/plugins/GeonamesPlugin.php
+++ b/plugins/GeonamesPlugin.php
@@ -74,8 +74,8 @@ class GeonamesPlugin extends Plugin
$result = $client->get('http://ws.geonames.org/search?'.$str);
- if ($result->code == "200") {
- $rj = json_decode($result->body);
+ if ($result->isOk()) {
+ $rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
$n = $rj->geonames[0];
@@ -121,9 +121,9 @@ class GeonamesPlugin extends Plugin
$result = $client->get('http://ws.geonames.org/hierarchyJSON?'.$str);
- if ($result->code == "200") {
+ if ($result->isOk()) {
- $rj = json_decode($result->body);
+ $rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
@@ -182,9 +182,9 @@ class GeonamesPlugin extends Plugin
$result =
$client->get('http://ws.geonames.org/findNearbyPlaceNameJSON?'.$str);
- if ($result->code == "200") {
+ if ($result->isOk()) {
- $rj = json_decode($result->body);
+ $rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
@@ -249,9 +249,9 @@ class GeonamesPlugin extends Plugin
$result = $client->get('http://ws.geonames.org/hierarchyJSON?'.$str);
- if ($result->code == "200") {
+ if ($result->isOk()) {
- $rj = json_decode($result->body);
+ $rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
diff --git a/plugins/LilUrl/LilUrlPlugin.php b/plugins/LilUrl/LilUrlPlugin.php
index 7665b6c1e..852253b02 100644
--- a/plugins/LilUrl/LilUrlPlugin.php
+++ b/plugins/LilUrl/LilUrlPlugin.php
@@ -58,7 +58,10 @@ class LilUrl extends ShortUrlApi
$y = @simplexml_load_string($response);
if (!isset($y->body)) return $url;
$x = $y->body->p[0]->a->attributes();
- if (isset($x['href'])) return $x['href'];
+ if (isset($x['href'])) {
+ common_log(LOG_INFO, __CLASS__ . ": shortened $url to $x[href]");
+ return $x['href'];
+ }
return $url;
}
}
diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php
index 60f7a60c7..915d15c07 100644
--- a/plugins/LinkbackPlugin.php
+++ b/plugins/LinkbackPlugin.php
@@ -129,18 +129,12 @@ class LinkbackPlugin extends Plugin
}
}
- $request = xmlrpc_encode_request('pingback.ping', $args);
- $context = stream_context_create(array('http' => array('method' => "POST",
- 'header' =>
- "Content-Type: text/xml\r\n".
- "User-Agent: " . $this->userAgent(),
- 'content' => $request)));
- $file = file_get_contents($endpoint, false, $context);
- if (!$file) {
- common_log(LOG_WARNING,
- "Pingback request failed for '$url' ($endpoint)");
- } else {
- $response = xmlrpc_decode($file);
+ $request = HTTPClient::start();
+ try {
+ $response = $request->post($endpoint,
+ array('Content-Type: text/xml'),
+ xmlrpc_encode_request('pingback.ping', $args));
+ $response = xmlrpc_decode($response->getBody());
if (xmlrpc_is_fault($response)) {
common_log(LOG_WARNING,
"Pingback error for '$url' ($endpoint): ".
@@ -150,6 +144,9 @@ class LinkbackPlugin extends Plugin
"Pingback success for '$url' ($endpoint): ".
"'$response'");
}
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_WARNING,
+ "Pingback request failed for '$url' ($endpoint)");
}
}
diff --git a/plugins/SimpleUrl/SimpleUrlPlugin.php b/plugins/SimpleUrl/SimpleUrlPlugin.php
index 82d772048..d59d63e47 100644
--- a/plugins/SimpleUrl/SimpleUrlPlugin.php
+++ b/plugins/SimpleUrl/SimpleUrlPlugin.php
@@ -65,15 +65,6 @@ class SimpleUrlPlugin extends Plugin
class SimpleUrl extends ShortUrlApi
{
protected function shorten_imp($url) {
- $curlh = curl_init();
- curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
- curl_setopt($curlh, CURLOPT_USERAGENT, 'StatusNet');
- curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
-
- curl_setopt($curlh, CURLOPT_URL, $this->service_url.urlencode($url));
- $short_url = curl_exec($curlh);
-
- curl_close($curlh);
- return $short_url;
+ return $this->http_get($url);
}
}
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index ed2bf48a2..671e3c7af 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -152,8 +152,8 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
$friends_ids = $client->friendsIds();
} catch (Exception $e) {
common_log(LOG_WARNING, $this->name() .
- ' - cURL error getting friend ids ' .
- $e->getCode() . ' - ' . $e->getMessage());
+ ' - error getting friend ids: ' .
+ $e->getMessage());
return $friends;
}
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index 81bbbc7c5..b5428316b 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -109,12 +109,16 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$flink->find();
$flinks = array();
+ common_log(LOG_INFO, "hello");
while ($flink->fetch()) {
if (($flink->noticesync & FOREIGN_NOTICE_RECV) ==
FOREIGN_NOTICE_RECV) {
$flinks[] = clone($flink);
+ common_log(LOG_INFO, "sync: foreign id $flink->foreign_id");
+ } else {
+ common_log(LOG_INFO, "nothing to sync");
}
}
@@ -515,31 +519,32 @@ class TwitterStatusFetcher extends ParallelizingDaemon
return $id;
}
+ /**
+ * Fetch a remote avatar image and save to local storage.
+ *
+ * @param string $url avatar source URL
+ * @param string $filename bare local filename for download
+ * @return bool true on success, false on failure
+ */
function fetchAvatar($url, $filename)
{
- $avatarfile = Avatar::path($filename);
+ common_debug($this->name() . " - Fetching Twitter avatar: $url");
- $out = fopen($avatarfile, 'wb');
- if (!$out) {
- common_log(LOG_WARNING, $this->name() .
- " - Couldn't open file $filename");
+ $request = HTTPClient::start();
+ $response = $request->get($url);
+ if ($response->isOk()) {
+ $avatarfile = Avatar::path($filename);
+ $ok = file_put_contents($avatarfile, $response->getBody());
+ if (!$ok) {
+ common_log(LOG_WARNING, $this->name() .
+ " - Couldn't open file $filename");
+ return false;
+ }
+ } else {
return false;
}
- common_debug($this->name() . " - Fetching Twitter avatar: $url");
-
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_FILE, $out);
- curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
- $result = curl_exec($ch);
- curl_close($ch);
-
- fclose($out);
-
- return $result;
+ return true;
}
}
diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php
index 1a5248a9b..3c6803e49 100644
--- a/plugins/TwitterBridge/twitter.php
+++ b/plugins/TwitterBridge/twitter.php
@@ -215,7 +215,7 @@ function broadcast_basicauth($notice, $flink)
try {
$status = $client->statusesUpdate($statustxt);
- } catch (BasicAuthCurlException $e) {
+ } catch (HTTP_Request2_Exception $e) {
return process_error($e, $flink);
}
diff --git a/plugins/TwitterBridge/twitterauthorization.php b/plugins/TwitterBridge/twitterauthorization.php
index 2a93ff13e..f1daefab1 100644
--- a/plugins/TwitterBridge/twitterauthorization.php
+++ b/plugins/TwitterBridge/twitterauthorization.php
@@ -125,7 +125,7 @@ class TwitterauthorizationAction extends Action
$auth_link = $client->getAuthorizeLink($req_tok);
- } catch (TwitterOAuthClientException $e) {
+ } catch (OAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage());
$this->serverError(_('Couldn\'t link your Twitter account.'));
diff --git a/plugins/TwitterBridge/twitterbasicauthclient.php b/plugins/TwitterBridge/twitterbasicauthclient.php
index 1040d72fb..d1cf45aec 100644
--- a/plugins/TwitterBridge/twitterbasicauthclient.php
+++ b/plugins/TwitterBridge/twitterbasicauthclient.php
@@ -31,26 +31,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
-/**
- * Exception wrapper for cURL errors
- *
- * @category Integration
- * @package StatusNet
- * @author Adrian Lang
- * @author Brenda Wallace
- * @author Craig Andrews
- * @author Dan Moore
- * @author Evan Prodromou
- * @author mEDI
- * @author Sarven Capadisli
- * @author Zach Copley * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- */
-class BasicAuthCurlException extends Exception
-{
-}
-
/**
* Class for talking to the Twitter API with HTTP Basic Auth.
*
@@ -198,45 +178,27 @@ class TwitterBasicAuthClient
*/
function httpRequest($url, $params = null, $auth = true)
{
- $options = array(
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FAILONERROR => true,
- CURLOPT_HEADER => false,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_USERAGENT => 'StatusNet',
- CURLOPT_CONNECTTIMEOUT => 120,
- CURLOPT_TIMEOUT => 120,
- CURLOPT_HTTPAUTH => CURLAUTH_ANY,
- CURLOPT_SSL_VERIFYPEER => false,
-
- // Twitter is strict about accepting invalid "Expect" headers
-
- CURLOPT_HTTPHEADER => array('Expect:')
- );
-
- if (isset($params)) {
- $options[CURLOPT_POST] = true;
- $options[CURLOPT_POSTFIELDS] = $params;
- }
+ $request = HTTPClient::start();
+ $request->setConfig(array(
+ 'follow_redirects' => true,
+ 'connect_timeout' => 120,
+ 'timeout' => 120,
+ 'ssl_verifypeer' => false,
+ ));
if ($auth) {
- $options[CURLOPT_USERPWD] = $this->screen_name .
- ':' . $this->password;
+ $request->setAuth($this->screen_name, $this->password);
}
- $ch = curl_init($url);
- curl_setopt_array($ch, $options);
- $response = curl_exec($ch);
-
- if ($response === false) {
- $msg = curl_error($ch);
- $code = curl_errno($ch);
- throw new BasicAuthCurlException($msg, $code);
+ if (isset($params)) {
+ // Twitter is strict about accepting invalid "Expect" headers
+ $headers = array('Expect:');
+ $response = $request->post($url, $headers, $params);
+ } else {
+ $response = $request->get($url);
}
- curl_close($ch);
-
- return $response;
+ return $response->getBody();
}
}
diff --git a/plugins/WikiHashtagsPlugin.php b/plugins/WikiHashtagsPlugin.php
index 0c5649aa4..334fc13ba 100644
--- a/plugins/WikiHashtagsPlugin.php
+++ b/plugins/WikiHashtagsPlugin.php
@@ -68,14 +68,13 @@ class WikiHashtagsPlugin extends Plugin
$editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit',
urlencode($tag));
- $context = stream_context_create(array('http' => array('method' => "GET",
- 'header' =>
- "User-Agent: " . $this->userAgent())));
- $html = @file_get_contents($url, false, $context);
+ $request = HTTPClient::start();
+ $response = $request->get($url);
+ $html = $response->getBody();
$action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section'));
- if (!empty($html)) {
+ if ($response->isOk() && !empty($html)) {
$action->element('style', null,
"span.editsection { display: none }\n".
"table.toc { display: none }");
@@ -100,10 +99,4 @@ class WikiHashtagsPlugin extends Plugin
return true;
}
-
- function userAgent()
- {
- return 'WikiHashtagsPlugin/'.WIKIHASHTAGSPLUGIN_VERSION .
- ' StatusNet/' . STATUSNET_VERSION;
- }
}
diff --git a/scripts/enjitqueuehandler.php b/scripts/enjitqueuehandler.php
index 08f733b07..afcac539a 100755
--- a/scripts/enjitqueuehandler.php
+++ b/scripts/enjitqueuehandler.php
@@ -46,8 +46,8 @@ class EnjitQueueHandler extends QueueHandler
function start()
{
- $this->log(LOG_INFO, "Starting EnjitQueueHandler");
- $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
+ $this->log(LOG_INFO, "Starting EnjitQueueHandler");
+ $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
return true;
}
@@ -56,16 +56,16 @@ class EnjitQueueHandler extends QueueHandler
$profile = Profile::staticGet($notice->profile_id);
- $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
+ $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
- if ( ! $notice->is_local ) {
- $this->log(LOG_INFO, "Skipping remote notice");
- return "skipped";
- }
+ if ( ! $notice->is_local ) {
+ $this->log(LOG_INFO, "Skipping remote notice");
+ return "skipped";
+ }
- #
- # Build an Atom message from the notice
- #
+ #
+ # Build an Atom message from the notice
+ #
$noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
$msg = $profile->nickname . ': ' . $notice->content;
@@ -86,36 +86,18 @@ class EnjitQueueHandler extends QueueHandler
$atom .= "".common_date_w3dtf($notice->modified)."\n";
$atom .= "\n";
- $url = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
- $data = "msg=$atom";
+ $url = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
+ $data = array(
+ 'msg' => $atom,
+ );
- #
- # POST the message to $config['enjit']['apiurl']
- #
- $ch = curl_init();
+ #
+ # POST the message to $config['enjit']['apiurl']
+ #
+ $request = HTTPClient::start();
+ $response = $request->post($url, null, $data);
- curl_setopt($ch, CURLOPT_URL, $url);
-
- curl_setopt($ch, CURLOPT_HEADER, 1);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1) ;
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
-
- # SSL and Debugging options
- #
- # curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
- # curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
- # curl_setopt($ch, CURLOPT_VERBOSE, 1);
-
- $result = curl_exec($ch);
-
- $code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
-
- $this->log(LOG_INFO, "Response Code: $code");
-
- curl_close($ch);
-
- return $code;
+ return $response->isOk();
}
}
--
cgit v1.2.3-54-g00ecf
From 0ab17f382b9993ada3d12d4cdace72cca53fb545 Mon Sep 17 00:00:00 2001
From: Siebrand Mazeland
Date: Sun, 8 Nov 2009 23:22:38 +0100
Subject: * [Cc]an't -> [Cc]annot * [Cc]ould't -> [Cc]ould not
---
actions/emailsettings.php | 4 +-
actions/smssettings.php | 2 +-
classes/File.php | 2 +-
classes/Notice.php | 4 +-
extlib/Auth/OpenID/Consumer.php | 2 +-
extlib/Auth/OpenID/Discover.php | 4 +-
extlib/Auth/OpenID/FileStore.php | 2 +-
extlib/DB.php | 2 +-
extlib/DB/DataObject/Generator.php | 4 +-
extlib/DB/dbase.php | 6 +-
extlib/DB/fbsql.php | 8 +-
extlib/DB/ibase.php | 6 +-
extlib/DB/ifx.php | 12 +-
extlib/DB/msql.php | 8 +-
extlib/DB/mssql.php | 10 +-
extlib/DB/mysql.php | 14 +-
extlib/DB/mysqli.php | 14 +-
extlib/DB/oci8.php | 10 +-
extlib/DB/odbc.php | 8 +-
extlib/DB/pgsql.php | 10 +-
extlib/DB/sqlite.php | 8 +-
extlib/DB/sybase.php | 12 +-
extlib/HTTP/Request2/Adapter/Socket.php | 1940 ++---
extlib/MIME/Type.php | 4 +-
extlib/MIME/Type/Extension.php | 4 +-
extlib/Mail/mail.php | 2 +-
extlib/Mail/sendmail.php | 2 +-
extlib/Net/LDAP2/Entry.php | 2 +-
extlib/Net/LDAP2/Filter.php | 2 +-
extlib/System/Command.php | 2 +-
extlib/markdown.php | 2 +-
install.php | 16 +-
lib/attachmentlist.php | 2 +-
lib/noticelist.php | 2 +-
lib/profilelist.php | 2 +-
lib/serverexception.php | 2 +-
lib/settingsaction.php | 2 +-
lib/util.php | 2 +-
lib/xmppqueuehandler.php | 2 +-
locale/statusnet.po | 7814 +++++++-------------
.../Facebook/facebook/facebookapi_php5_restlib.php | 2 +-
.../Facebook/facebook/jsonwrapper/JSON/JSON.php | 2 +-
plugins/Facebook/facebookaction.php | 2 +-
plugins/Facebook/facebookhome.php | 2 +-
plugins/LinkbackPlugin.php | 2 +-
plugins/Meteor/MeteorPlugin.php | 2 +-
plugins/OpenID/openid.php | 4 +-
.../TwitterBridge/daemons/synctwitterfriends.php | 8 +-
.../TwitterBridge/daemons/twitterstatusfetcher.php | 8 +-
plugins/UserFlag/flagprofile.php | 2 +-
scripts/console.php | 2 +-
scripts/createsim.php | 4 +-
scripts/deleteuser.php | 4 +-
scripts/fixup_utf8.php | 2 +-
scripts/makegroupadmin.php | 4 +-
scripts/registeruser.php | 4 +-
scripts/showcache.php | 2 +-
scripts/sitemap.php | 4 +-
scripts/update_translations.php | 2 +-
59 files changed, 3575 insertions(+), 6443 deletions(-)
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/actions/emailsettings.php b/actions/emailsettings.php
index 67b991cdc..715457eab 100644
--- a/actions/emailsettings.php
+++ b/actions/emailsettings.php
@@ -452,7 +452,7 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
- $this->serverError(_("Couldn't update user record."));
+ $this->serverError(_("Could not update user record."));
}
$this->showForm(_('Incoming email address removed.'), true);
@@ -474,7 +474,7 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
- $this->serverError(_("Couldn't update user record."));
+ $this->serverError(_("Could not update user record."));
}
$this->showForm(_('New incoming email address added.'), true);
diff --git a/actions/smssettings.php b/actions/smssettings.php
index 9fa7f62fb..4debe1967 100644
--- a/actions/smssettings.php
+++ b/actions/smssettings.php
@@ -525,7 +525,7 @@ class SmssettingsAction extends ConnectSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
- $this->serverError(_("Couldn't update user record."));
+ $this->serverError(_("Could not update user record."));
}
$this->showForm(_('Incoming email address removed.'), true);
diff --git a/classes/File.php b/classes/File.php
index e04a9d525..dd0c3227e 100644
--- a/classes/File.php
+++ b/classes/File.php
@@ -99,7 +99,7 @@ class File extends Memcached_DataObject
} elseif (is_string($redir_data)) {
$redir_url = $redir_data;
} else {
- throw new ServerException("Can't process url '$given_url'");
+ throw new ServerException("Cannot process url '$given_url'");
}
// TODO: max field length
if ($redir_url === $given_url || strlen($redir_url) > 255) {
diff --git a/classes/Notice.php b/classes/Notice.php
index 9886875cb..862d4c762 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -680,7 +680,7 @@ class Notice extends Memcached_DataObject
return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null);
}
- # Get the cache; if we can't, just go to the DB
+ # Get the cache; if we cannot, just go to the DB
$cache = common_memcache();
@@ -1364,7 +1364,7 @@ class Notice extends Memcached_DataObject
}
}
- // If it's not a "low bandwidth" source (one where you can't set
+ // If it's not a "low bandwidth" source (one where you cannot set
// a reply_to argument), we return. This is mostly web and API
// clients.
diff --git a/extlib/Auth/OpenID/Consumer.php b/extlib/Auth/OpenID/Consumer.php
index 500890b65..c75ef4c06 100644
--- a/extlib/Auth/OpenID/Consumer.php
+++ b/extlib/Auth/OpenID/Consumer.php
@@ -1059,7 +1059,7 @@ class Auth_OpenID_GenericConsumer {
}
}
- // Fragments do not influence discovery, so we can't compare a
+ // Fragments do not influence discovery, so we cannot compare a
// claimed identifier with a fragment to discovered
// information.
list($defragged_claimed_id, $_) =
diff --git a/extlib/Auth/OpenID/Discover.php b/extlib/Auth/OpenID/Discover.php
index 62aeb1d2b..9bb3ee357 100644
--- a/extlib/Auth/OpenID/Discover.php
+++ b/extlib/Auth/OpenID/Discover.php
@@ -515,7 +515,7 @@ function Auth_OpenID_discoverXRI($iname, &$fetcher)
function Auth_OpenID_discover($uri, &$fetcher)
{
- // If the fetcher (i.e., PHP) doesn't support SSL, we can't do
+ // If the fetcher (i.e., PHP) doesn't support SSL, we cannot do
// discovery on an HTTPS URL.
if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) {
return array($uri, array());
@@ -527,7 +527,7 @@ function Auth_OpenID_discover($uri, &$fetcher)
$result = Auth_OpenID_discoverURI($uri, $fetcher);
}
- // If the fetcher doesn't support SSL, we can't interact with
+ // If the fetcher doesn't support SSL, we cannot interact with
// HTTPS server URLs; remove those endpoints from the list.
if (!$fetcher->supportsSSL()) {
$http_endpoints = array();
diff --git a/extlib/Auth/OpenID/FileStore.php b/extlib/Auth/OpenID/FileStore.php
index 29d8d20e7..d9962e153 100644
--- a/extlib/Auth/OpenID/FileStore.php
+++ b/extlib/Auth/OpenID/FileStore.php
@@ -496,7 +496,7 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
return true;
} else {
- // Couldn't open directory.
+ // Could not open directory.
return false;
}
}
diff --git a/extlib/DB.php b/extlib/DB.php
index a511979e6..4ef66f66f 100644
--- a/extlib/DB.php
+++ b/extlib/DB.php
@@ -1341,7 +1341,7 @@ class DB_result
* returning the total number of rows that would have been returned,
* rather than the real number. As a result, we'll just do the limit
* calculations for fbsql in the same way as a database with emulated
- * limits. Unfortunately, we can't just do this in DB_fbsql::numRows()
+ * limits. Unfortunately, we cannot just do this in DB_fbsql::numRows()
* because that only gets the result resource, rather than the full
* DB_Result object. */
if (($this->dbh->features['limit'] === 'emulate'
diff --git a/extlib/DB/DataObject/Generator.php b/extlib/DB/DataObject/Generator.php
index ff6e42c7d..e14e3ef7f 100644
--- a/extlib/DB/DataObject/Generator.php
+++ b/extlib/DB/DataObject/Generator.php
@@ -632,7 +632,7 @@ class DB_DataObject_Generator extends DB_DataObject
echo "*****************************************************************\n".
"** WARNING COLUMN NAME UNUSABLE **\n".
"** Found column '{$t->name}', of type '{$t->type}' **\n".
- "** Since this column name can't be converted to a php variable **\n".
+ "** Since this column name cannot be converted to a php variable **\n".
"** name, and the whole idea of mapping would result in a mess **\n".
"** This column has been ignored... **\n".
"*****************************************************************\n";
@@ -910,7 +910,7 @@ class DB_DataObject_Generator extends DB_DataObject
echo "*****************************************************************\n".
"** WARNING COLUMN NAME UNUSABLE **\n".
"** Found column '{$t->name}', of type '{$t->type}' **\n".
- "** Since this column name can't be converted to a php variable **\n".
+ "** Since this column name cannot be converted to a php variable **\n".
"** name, and the whole idea of mapping would result in a mess **\n".
"** This column has been ignored... **\n".
"*****************************************************************\n";
diff --git a/extlib/DB/dbase.php b/extlib/DB/dbase.php
index 67afc897d..15d259c4d 100644
--- a/extlib/DB/dbase.php
+++ b/extlib/DB/dbase.php
@@ -287,7 +287,7 @@ class DB_dbase extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -352,7 +352,7 @@ class DB_dbase extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -373,7 +373,7 @@ class DB_dbase extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/fbsql.php b/extlib/DB/fbsql.php
index 4de4078f7..48ff705cf 100644
--- a/extlib/DB/fbsql.php
+++ b/extlib/DB/fbsql.php
@@ -262,7 +262,7 @@ class DB_fbsql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -309,7 +309,7 @@ class DB_fbsql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -376,7 +376,7 @@ class DB_fbsql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -401,7 +401,7 @@ class DB_fbsql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/ibase.php b/extlib/DB/ibase.php
index ee19c5589..1e444d634 100644
--- a/extlib/DB/ibase.php
+++ b/extlib/DB/ibase.php
@@ -353,7 +353,7 @@ class DB_ibase extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -402,7 +402,7 @@ class DB_ibase extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -449,7 +449,7 @@ class DB_ibase extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/ifx.php b/extlib/DB/ifx.php
index baa6f2867..dcb3dbd3e 100644
--- a/extlib/DB/ifx.php
+++ b/extlib/DB/ifx.php
@@ -147,7 +147,7 @@ class DB_ifx extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it can't actually be designated
+ * {@internal While this is private, it cannot actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -328,7 +328,7 @@ class DB_ifx extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -387,7 +387,7 @@ class DB_ifx extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -411,7 +411,7 @@ class DB_ifx extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -555,7 +555,7 @@ class DB_ifx extends DB_common
*
* If analyzing a query result and the result has duplicate field names,
* an error will be raised saying
- * can't distinguish duplicate field names.
+ * cannot distinguish duplicate field names.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
@@ -604,7 +604,7 @@ class DB_ifx extends DB_common
$count = @ifx_num_fields($id);
if (count($flds) != $count) {
- return $this->raiseError("can't distinguish duplicate field names");
+ return $this->raiseError("cannot distinguish duplicate field names");
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
diff --git a/extlib/DB/msql.php b/extlib/DB/msql.php
index 34854f472..ee64f932f 100644
--- a/extlib/DB/msql.php
+++ b/extlib/DB/msql.php
@@ -288,7 +288,7 @@ class DB_msql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
@@ -339,7 +339,7 @@ class DB_msql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -360,7 +360,7 @@ class DB_msql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -385,7 +385,7 @@ class DB_msql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/mssql.php b/extlib/DB/mssql.php
index 511a2b686..1aad75671 100644
--- a/extlib/DB/mssql.php
+++ b/extlib/DB/mssql.php
@@ -156,7 +156,7 @@ class DB_mssql extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it can't actually be designated
+ * {@internal While this is private, it cannot actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -324,7 +324,7 @@ class DB_mssql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -371,7 +371,7 @@ class DB_mssql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -392,7 +392,7 @@ class DB_mssql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -417,7 +417,7 @@ class DB_mssql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/mysql.php b/extlib/DB/mysql.php
index c67254520..bfe34dbe8 100644
--- a/extlib/DB/mysql.php
+++ b/extlib/DB/mysql.php
@@ -139,7 +139,7 @@ class DB_mysql extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it can't actually be designated
+ * {@internal While this is private, it cannot actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -359,7 +359,7 @@ class DB_mysql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -411,7 +411,7 @@ class DB_mysql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -432,7 +432,7 @@ class DB_mysql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -457,7 +457,7 @@ class DB_mysql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -722,7 +722,7 @@ class DB_mysql extends DB_common
return $result;
}
if ($result == 0) {
- // Failed to get the lock, can't do the conversion, bail
+ // Failed to get the lock, cannot do the conversion, bail
// with a DB_ERROR_NOT_LOCKED error
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
}
@@ -757,7 +757,7 @@ class DB_mysql extends DB_common
* Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
- * WARNING: Older versions of MySQL can't handle the backtick
+ * WARNING: Older versions of MySQL cannot handle the backtick
* character (`) in table or column names.
*
* @param string $str identifier name to be quoted
diff --git a/extlib/DB/mysqli.php b/extlib/DB/mysqli.php
index c6941b170..b6196dfcc 100644
--- a/extlib/DB/mysqli.php
+++ b/extlib/DB/mysqli.php
@@ -142,7 +142,7 @@ class DB_mysqli extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it can't actually be designated
+ * {@internal While this is private, it cannot actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -434,7 +434,7 @@ class DB_mysqli extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -486,7 +486,7 @@ class DB_mysqli extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -507,7 +507,7 @@ class DB_mysqli extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -532,7 +532,7 @@ class DB_mysqli extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -796,7 +796,7 @@ class DB_mysqli extends DB_common
return $result;
}
if ($result == 0) {
- // Failed to get the lock, can't do the conversion, bail
+ // Failed to get the lock, cannot do the conversion, bail
// with a DB_ERROR_NOT_LOCKED error
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
}
@@ -832,7 +832,7 @@ class DB_mysqli extends DB_common
* Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
- * WARNING: Older versions of MySQL can't handle the backtick
+ * WARNING: Older versions of MySQL cannot handle the backtick
* character (`) in table or column names.
*
* @param string $str identifier name to be quoted
diff --git a/extlib/DB/oci8.php b/extlib/DB/oci8.php
index d30794871..6ad36643a 100644
--- a/extlib/DB/oci8.php
+++ b/extlib/DB/oci8.php
@@ -251,7 +251,7 @@ class DB_oci8 extends DB_common
$char);
$error = OCIError();
if (!empty($error) && $error['code'] == 12541) {
- // Couldn't find TNS listener. Try direct connection.
+ // Could not find TNS listener. Try direct connection.
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
null,
@@ -368,7 +368,7 @@ class DB_oci8 extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -415,7 +415,7 @@ class DB_oci8 extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -468,7 +468,7 @@ class DB_oci8 extends DB_common
* is turned on.
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -511,7 +511,7 @@ class DB_oci8 extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/odbc.php b/extlib/DB/odbc.php
index eba43659a..b0dc83ab5 100644
--- a/extlib/DB/odbc.php
+++ b/extlib/DB/odbc.php
@@ -301,7 +301,7 @@ class DB_odbc extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -356,7 +356,7 @@ class DB_odbc extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -377,7 +377,7 @@ class DB_odbc extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -427,7 +427,7 @@ class DB_odbc extends DB_common
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/pgsql.php b/extlib/DB/pgsql.php
index 6030bb4c1..498ef8ade 100644
--- a/extlib/DB/pgsql.php
+++ b/extlib/DB/pgsql.php
@@ -115,7 +115,7 @@ class DB_pgsql extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it can't actually be designated
+ * {@internal While this is private, it cannot actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -397,7 +397,7 @@ class DB_pgsql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -445,7 +445,7 @@ class DB_pgsql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -535,7 +535,7 @@ class DB_pgsql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -560,7 +560,7 @@ class DB_pgsql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/sqlite.php b/extlib/DB/sqlite.php
index 5c4b396e5..96d5c934a 100644
--- a/extlib/DB/sqlite.php
+++ b/extlib/DB/sqlite.php
@@ -334,7 +334,7 @@ class DB_sqlite extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -396,7 +396,7 @@ class DB_sqlite extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -422,7 +422,7 @@ class DB_sqlite extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -447,7 +447,7 @@ class DB_sqlite extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/sybase.php b/extlib/DB/sybase.php
index 3befbf6ea..97ab41a22 100644
--- a/extlib/DB/sybase.php
+++ b/extlib/DB/sybase.php
@@ -118,7 +118,7 @@ class DB_sybase extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it can't actually be designated
+ * {@internal While this is private, it cannot actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -302,7 +302,7 @@ class DB_sybase extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It can't be declared "protected"
+ * DB_result::fetchInto() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -359,7 +359,7 @@ class DB_sybase extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It can't be declared "protected"
+ * DB_result::free() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -380,7 +380,7 @@ class DB_sybase extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It can't be declared "protected"
+ * DB_result::numCols() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -405,7 +405,7 @@ class DB_sybase extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It can't be declared "protected"
+ * DB_result::numRows() instead. It cannot be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -835,7 +835,7 @@ class DB_sybase extends DB_common
$tableName = $table;
/* We're running sp_helpindex directly because it doesn't exist in
- * older versions of ASE -- unfortunately, we can't just use
+ * older versions of ASE -- unfortunately, we cannot just use
* DB::isError() because the user may be using callback error
* handling. */
$res = @sybase_query("sp_helpindex $table", $this->connection);
diff --git a/extlib/HTTP/Request2/Adapter/Socket.php b/extlib/HTTP/Request2/Adapter/Socket.php
index ff44d4959..13cd6136f 100644
--- a/extlib/HTTP/Request2/Adapter/Socket.php
+++ b/extlib/HTTP/Request2/Adapter/Socket.php
@@ -1,971 +1,971 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Base class for HTTP_Request2 adapters
- */
-require_once 'HTTP/Request2/Adapter.php';
-
-/**
- * Socket-based adapter for HTTP_Request2
- *
- * This adapter uses only PHP sockets and will work on almost any PHP
- * environment. Code is based on original HTTP_Request PEAR package.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- */
-class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
-{
- /**
- * Regular expression for 'token' rule from RFC 2616
- */
- const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
-
- /**
- * Regular expression for 'quoted-string' rule from RFC 2616
- */
- const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
-
- /**
- * Connected sockets, needed for Keep-Alive support
- * @var array
- * @see connect()
- */
- protected static $sockets = array();
-
- /**
- * Data for digest authentication scheme
- *
- * The keys for the array are URL prefixes.
- *
- * The values are associative arrays with data (realm, nonce, nonce-count,
- * opaque...) needed for digest authentication. Stored here to prevent making
- * duplicate requests to digest-protected resources after we have already
- * received the challenge.
- *
- * @var array
- */
- protected static $challenges = array();
-
- /**
- * Connected socket
- * @var resource
- * @see connect()
- */
- protected $socket;
-
- /**
- * Challenge used for server digest authentication
- * @var array
- */
- protected $serverChallenge;
-
- /**
- * Challenge used for proxy digest authentication
- * @var array
- */
- protected $proxyChallenge;
-
- /**
- * Global timeout, exception will be raised if request continues past this time
- * @var integer
- */
- protected $timeout = null;
-
- /**
- * Remaining length of the current chunk, when reading chunked response
- * @var integer
- * @see readChunked()
- */
- protected $chunkLength = 0;
-
- /**
- * Sends request to the remote server and returns its response
- *
- * @param HTTP_Request2
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- public function sendRequest(HTTP_Request2 $request)
- {
- $this->request = $request;
- $keepAlive = $this->connect();
- $headers = $this->prepareHeaders();
-
- // Use global request timeout if given, see feature requests #5735, #8964
- if ($timeout = $request->getConfig('timeout')) {
- $this->timeout = time() + $timeout;
- } else {
- $this->timeout = null;
- }
-
- try {
- if (false === @fwrite($this->socket, $headers, strlen($headers))) {
- throw new HTTP_Request2_Exception('Error writing request');
- }
- // provide request headers to the observer, see request #7633
- $this->request->setLastEvent('sentHeaders', $headers);
- $this->writeBody();
-
- if ($this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $request->getConfig('timeout') . ' second(s)'
- );
- }
-
- $response = $this->readResponse();
-
- if (!$this->canKeepAlive($keepAlive, $response)) {
- $this->disconnect();
- }
-
- if ($this->shouldUseProxyDigestAuth($response)) {
- return $this->sendRequest($request);
- }
- if ($this->shouldUseServerDigestAuth($response)) {
- return $this->sendRequest($request);
- }
- if ($authInfo = $response->getHeader('authentication-info')) {
- $this->updateChallenge($this->serverChallenge, $authInfo);
- }
- if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
- $this->updateChallenge($this->proxyChallenge, $proxyInfo);
- }
-
- } catch (Exception $e) {
- $this->disconnect();
- throw $e;
- }
-
- return $response;
- }
-
- /**
- * Connects to the remote server
- *
- * @return bool whether the connection can be persistent
- * @throws HTTP_Request2_Exception
- */
- protected function connect()
- {
- $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
- $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
- $headers = $this->request->getHeaders();
- $reqHost = $this->request->getUrl()->getHost();
- if (!($reqPort = $this->request->getUrl()->getPort())) {
- $reqPort = $secure? 443: 80;
- }
-
- if ($host = $this->request->getConfig('proxy_host')) {
- if (!($port = $this->request->getConfig('proxy_port'))) {
- throw new HTTP_Request2_Exception('Proxy port not provided');
- }
- $proxy = true;
- } else {
- $host = $reqHost;
- $port = $reqPort;
- $proxy = false;
- }
-
- if ($tunnel && !$proxy) {
- throw new HTTP_Request2_Exception(
- "Trying to perform CONNECT request without proxy"
- );
- }
- if ($secure && !in_array('ssl', stream_get_transports())) {
- throw new HTTP_Request2_Exception(
- 'Need OpenSSL support for https:// requests'
- );
- }
-
- // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
- // connection token to a proxy server...
- if ($proxy && !$secure &&
- !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
- ) {
- $this->request->setHeader('connection');
- }
-
- $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
- empty($headers['connection'])) ||
- (!empty($headers['connection']) &&
- 'Keep-Alive' == $headers['connection']);
- $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
-
- $options = array();
- if ($secure || $tunnel) {
- foreach ($this->request->getConfig() as $name => $value) {
- if ('ssl_' == substr($name, 0, 4) && null !== $value) {
- if ('ssl_verify_host' == $name) {
- if ($value) {
- $options['CN_match'] = $reqHost;
- }
- } else {
- $options[substr($name, 4)] = $value;
- }
- }
- }
- ksort($options);
- }
-
- // Changing SSL context options after connection is established does *not*
- // work, we need a new connection if options change
- $remote = $host . ':' . $port;
- $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
- (empty($options)? '': ':' . serialize($options));
- unset($this->socket);
-
- // We use persistent connections and have a connected socket?
- // Ensure that the socket is still connected, see bug #16149
- if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
- !feof(self::$sockets[$socketKey])
- ) {
- $this->socket =& self::$sockets[$socketKey];
-
- } elseif ($secure && $proxy && !$tunnel) {
- $this->establishTunnel();
- $this->request->setLastEvent(
- 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
- );
- self::$sockets[$socketKey] =& $this->socket;
-
- } else {
- // Set SSL context options if doing HTTPS request or creating a tunnel
- $context = stream_context_create();
- foreach ($options as $name => $value) {
- if (!stream_context_set_option($context, 'ssl', $name, $value)) {
- throw new HTTP_Request2_Exception(
- "Error setting SSL context option '{$name}'"
- );
- }
- }
- $this->socket = @stream_socket_client(
- $remote, $errno, $errstr,
- $this->request->getConfig('connect_timeout'),
- STREAM_CLIENT_CONNECT, $context
- );
- if (!$this->socket) {
- throw new HTTP_Request2_Exception(
- "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
- );
- }
- $this->request->setLastEvent('connect', $remote);
- self::$sockets[$socketKey] =& $this->socket;
- }
- return $keepAlive;
- }
-
- /**
- * Establishes a tunnel to a secure remote server via HTTP CONNECT request
- *
- * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
- * sees that we are connected to a proxy server (duh!) rather than the server
- * that presents its certificate.
- *
- * @link http://tools.ietf.org/html/rfc2817#section-5.2
- * @throws HTTP_Request2_Exception
- */
- protected function establishTunnel()
- {
- $donor = new self;
- $connect = new HTTP_Request2(
- $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
- array_merge($this->request->getConfig(),
- array('adapter' => $donor))
- );
- $response = $connect->send();
- // Need any successful (2XX) response
- if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
- throw new HTTP_Request2_Exception(
- 'Failed to connect via HTTPS proxy. Proxy response: ' .
- $response->getStatus() . ' ' . $response->getReasonPhrase()
- );
- }
- $this->socket = $donor->socket;
-
- $modes = array(
- STREAM_CRYPTO_METHOD_TLS_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv2_CLIENT
- );
-
- foreach ($modes as $mode) {
- if (stream_socket_enable_crypto($this->socket, true, $mode)) {
- return;
- }
- }
- throw new HTTP_Request2_Exception(
- 'Failed to enable secure connection when connecting through proxy'
- );
- }
-
- /**
- * Checks whether current connection may be reused or should be closed
- *
- * @param boolean whether connection could be persistent
- * in the first place
- * @param HTTP_Request2_Response response object to check
- * @return boolean
- */
- protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
- {
- // Do not close socket on successful CONNECT request
- if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
- 200 <= $response->getStatus() && 300 > $response->getStatus()
- ) {
- return true;
- }
-
- $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
- null !== $response->getHeader('content-length');
- $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
- (null === $response->getHeader('connection') &&
- '1.1' == $response->getVersion());
- return $requestKeepAlive && $lengthKnown && $persistent;
- }
-
- /**
- * Disconnects from the remote server
- */
- protected function disconnect()
- {
- if (is_resource($this->socket)) {
- fclose($this->socket);
- $this->socket = null;
- $this->request->setLastEvent('disconnect');
- }
- }
-
- /**
- * Checks whether another request should be performed with server digest auth
- *
- * Several conditions should be satisfied for it to return true:
- * - response status should be 401
- * - auth credentials should be set in the request object
- * - response should contain WWW-Authenticate header with digest challenge
- * - there is either no challenge stored for this URL or new challenge
- * contains stale=true parameter (in other case we probably just failed
- * due to invalid username / password)
- *
- * The method stores challenge values in $challenges static property
- *
- * @param HTTP_Request2_Response response to check
- * @return boolean whether another request should be performed
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
- {
- // no sense repeating a request if we don't have credentials
- if (401 != $response->getStatus() || !$this->request->getAuth()) {
- return false;
- }
- if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
- return false;
- }
-
- $url = $this->request->getUrl();
- $scheme = $url->getScheme();
- $host = $scheme . '://' . $url->getHost();
- if ($port = $url->getPort()) {
- if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
- (0 == strcasecmp($scheme, 'https') && 443 != $port)
- ) {
- $host .= ':' . $port;
- }
- }
-
- if (!empty($challenge['domain'])) {
- $prefixes = array();
- foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
- // don't bother with different servers
- if ('/' == substr($prefix, 0, 1)) {
- $prefixes[] = $host . $prefix;
- }
- }
- }
- if (empty($prefixes)) {
- $prefixes = array($host . '/');
- }
-
- $ret = true;
- foreach ($prefixes as $prefix) {
- if (!empty(self::$challenges[$prefix]) &&
- (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
- ) {
- // probably credentials are invalid
- $ret = false;
- }
- self::$challenges[$prefix] =& $challenge;
- }
- return $ret;
- }
-
- /**
- * Checks whether another request should be performed with proxy digest auth
- *
- * Several conditions should be satisfied for it to return true:
- * - response status should be 407
- * - proxy auth credentials should be set in the request object
- * - response should contain Proxy-Authenticate header with digest challenge
- * - there is either no challenge stored for this proxy or new challenge
- * contains stale=true parameter (in other case we probably just failed
- * due to invalid username / password)
- *
- * The method stores challenge values in $challenges static property
- *
- * @param HTTP_Request2_Response response to check
- * @return boolean whether another request should be performed
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
- {
- if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
- return false;
- }
- if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
- return false;
- }
-
- $key = 'proxy://' . $this->request->getConfig('proxy_host') .
- ':' . $this->request->getConfig('proxy_port');
-
- if (!empty(self::$challenges[$key]) &&
- (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
- ) {
- $ret = false;
- } else {
- $ret = true;
- }
- self::$challenges[$key] = $challenge;
- return $ret;
- }
-
- /**
- * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
- *
- * There is a problem with implementation of RFC 2617: several of the parameters
- * here are defined as quoted-string and thus may contain backslash escaped
- * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
- * just value of quoted-string X without surrounding quotes, it doesn't speak
- * about removing backslash escaping.
- *
- * Now realm parameter is user-defined and human-readable, strange things
- * happen when it contains quotes:
- * - Apache allows quotes in realm, but apparently uses realm value without
- * backslashes for digest computation
- * - Squid allows (manually escaped) quotes there, but it is impossible to
- * authorize with either escaped or unescaped quotes used in digest,
- * probably it can't parse the response (?)
- * - Both IE and Firefox display realm value with backslashes in
- * the password popup and apparently use the same value for digest
- *
- * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
- * quoted-string handling, unfortunately that means failure to authorize
- * sometimes
- *
- * @param string value of WWW-Authenticate or Proxy-Authenticate header
- * @return mixed associative array with challenge parameters, false if
- * no challenge is present in header value
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function parseDigestChallenge($headerValue)
- {
- $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
- self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
- $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
- if (!preg_match($challenge, $headerValue, $matches)) {
- return false;
- }
-
- preg_match_all('!' . $authParam . '!', $matches[0], $params);
- $paramsAry = array();
- $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
- 'algorithm', 'qop');
- for ($i = 0; $i < count($params[0]); $i++) {
- // section 3.2.1: Any unrecognized directive MUST be ignored.
- if (in_array($params[1][$i], $knownParams)) {
- if ('"' == substr($params[2][$i], 0, 1)) {
- $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
- } else {
- $paramsAry[$params[1][$i]] = $params[2][$i];
- }
- }
- }
- // we only support qop=auth
- if (!empty($paramsAry['qop']) &&
- !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
- ) {
- throw new HTTP_Request2_Exception(
- "Only 'auth' qop is currently supported in digest authentication, " .
- "server requested '{$paramsAry['qop']}'"
- );
- }
- // we only support algorithm=MD5
- if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
- throw new HTTP_Request2_Exception(
- "Only 'MD5' algorithm is currently supported in digest authentication, " .
- "server requested '{$paramsAry['algorithm']}'"
- );
- }
-
- return $paramsAry;
- }
-
- /**
- * Parses [Proxy-]Authentication-Info header value and updates challenge
- *
- * @param array challenge to update
- * @param string value of [Proxy-]Authentication-Info header
- * @todo validate server rspauth response
- */
- protected function updateChallenge(&$challenge, $headerValue)
- {
- $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
- self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
- $paramsAry = array();
-
- preg_match_all($authParam, $headerValue, $params);
- for ($i = 0; $i < count($params[0]); $i++) {
- if ('"' == substr($params[2][$i], 0, 1)) {
- $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
- } else {
- $paramsAry[$params[1][$i]] = $params[2][$i];
- }
- }
- // for now, just update the nonce value
- if (!empty($paramsAry['nextnonce'])) {
- $challenge['nonce'] = $paramsAry['nextnonce'];
- $challenge['nc'] = 1;
- }
- }
-
- /**
- * Creates a value for [Proxy-]Authorization header when using digest authentication
- *
- * @param string user name
- * @param string password
- * @param string request URL
- * @param array digest challenge parameters
- * @return string value of [Proxy-]Authorization request header
- * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
- */
- protected function createDigestResponse($user, $password, $url, &$challenge)
- {
- if (false !== ($q = strpos($url, '?')) &&
- $this->request->getConfig('digest_compat_ie')
- ) {
- $url = substr($url, 0, $q);
- }
-
- $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
- $a2 = md5($this->request->getMethod() . ':' . $url);
-
- if (empty($challenge['qop'])) {
- $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
- } else {
- $challenge['cnonce'] = 'Req2.' . rand();
- if (empty($challenge['nc'])) {
- $challenge['nc'] = 1;
- }
- $nc = sprintf('%08x', $challenge['nc']++);
- $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
- $challenge['cnonce'] . ':auth:' . $a2);
- }
- return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
- 'realm="' . $challenge['realm'] . '", ' .
- 'nonce="' . $challenge['nonce'] . '", ' .
- 'uri="' . $url . '", ' .
- 'response="' . $digest . '"' .
- (!empty($challenge['opaque'])?
- ', opaque="' . $challenge['opaque'] . '"':
- '') .
- (!empty($challenge['qop'])?
- ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
- '');
- }
-
- /**
- * Adds 'Authorization' header (if needed) to request headers array
- *
- * @param array request headers
- * @param string request host (needed for digest authentication)
- * @param string request URL (needed for digest authentication)
- * @throws HTTP_Request2_Exception
- */
- protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
- {
- if (!($auth = $this->request->getAuth())) {
- return;
- }
- switch ($auth['scheme']) {
- case HTTP_Request2::AUTH_BASIC:
- $headers['authorization'] =
- 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
- break;
-
- case HTTP_Request2::AUTH_DIGEST:
- unset($this->serverChallenge);
- $fullUrl = ('/' == $requestUrl[0])?
- $this->request->getUrl()->getScheme() . '://' .
- $requestHost . $requestUrl:
- $requestUrl;
- foreach (array_keys(self::$challenges) as $key) {
- if ($key == substr($fullUrl, 0, strlen($key))) {
- $headers['authorization'] = $this->createDigestResponse(
- $auth['user'], $auth['password'],
- $requestUrl, self::$challenges[$key]
- );
- $this->serverChallenge =& self::$challenges[$key];
- break;
- }
- }
- break;
-
- default:
- throw new HTTP_Request2_Exception(
- "Unknown HTTP authentication scheme '{$auth['scheme']}'"
- );
- }
- }
-
- /**
- * Adds 'Proxy-Authorization' header (if needed) to request headers array
- *
- * @param array request headers
- * @param string request URL (needed for digest authentication)
- * @throws HTTP_Request2_Exception
- */
- protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
- {
- if (!$this->request->getConfig('proxy_host') ||
- !($user = $this->request->getConfig('proxy_user')) ||
- (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
- HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
- ) {
- return;
- }
-
- $password = $this->request->getConfig('proxy_password');
- switch ($this->request->getConfig('proxy_auth_scheme')) {
- case HTTP_Request2::AUTH_BASIC:
- $headers['proxy-authorization'] =
- 'Basic ' . base64_encode($user . ':' . $password);
- break;
-
- case HTTP_Request2::AUTH_DIGEST:
- unset($this->proxyChallenge);
- $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
- ':' . $this->request->getConfig('proxy_port');
- if (!empty(self::$challenges[$proxyUrl])) {
- $headers['proxy-authorization'] = $this->createDigestResponse(
- $user, $password,
- $requestUrl, self::$challenges[$proxyUrl]
- );
- $this->proxyChallenge =& self::$challenges[$proxyUrl];
- }
- break;
-
- default:
- throw new HTTP_Request2_Exception(
- "Unknown HTTP authentication scheme '" .
- $this->request->getConfig('proxy_auth_scheme') . "'"
- );
- }
- }
-
-
- /**
- * Creates the string with the Request-Line and request headers
- *
- * @return string
- * @throws HTTP_Request2_Exception
- */
- protected function prepareHeaders()
- {
- $headers = $this->request->getHeaders();
- $url = $this->request->getUrl();
- $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
- $host = $url->getHost();
-
- $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
- if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
- $host .= ':' . (empty($port)? $defaultPort: $port);
- }
- // Do not overwrite explicitly set 'Host' header, see bug #16146
- if (!isset($headers['host'])) {
- $headers['host'] = $host;
- }
-
- if ($connect) {
- $requestUrl = $host;
-
- } else {
- if (!$this->request->getConfig('proxy_host') ||
- 0 == strcasecmp($url->getScheme(), 'https')
- ) {
- $requestUrl = '';
- } else {
- $requestUrl = $url->getScheme() . '://' . $host;
- }
- $path = $url->getPath();
- $query = $url->getQuery();
- $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
- }
-
- if ('1.1' == $this->request->getConfig('protocol_version') &&
- extension_loaded('zlib') && !isset($headers['accept-encoding'])
- ) {
- $headers['accept-encoding'] = 'gzip, deflate';
- }
-
- $this->addAuthorizationHeader($headers, $host, $requestUrl);
- $this->addProxyAuthorizationHeader($headers, $requestUrl);
- $this->calculateRequestLength($headers);
-
- $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
- $this->request->getConfig('protocol_version') . "\r\n";
- foreach ($headers as $name => $value) {
- $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
- $headersStr .= $canonicalName . ': ' . $value . "\r\n";
- }
- return $headersStr . "\r\n";
- }
-
- /**
- * Sends the request body
- *
- * @throws HTTP_Request2_Exception
- */
- protected function writeBody()
- {
- if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
- 0 == $this->contentLength
- ) {
- return;
- }
-
- $position = 0;
- $bufferSize = $this->request->getConfig('buffer_size');
- while ($position < $this->contentLength) {
- if (is_string($this->requestBody)) {
- $str = substr($this->requestBody, $position, $bufferSize);
- } elseif (is_resource($this->requestBody)) {
- $str = fread($this->requestBody, $bufferSize);
- } else {
- $str = $this->requestBody->read($bufferSize);
- }
- if (false === @fwrite($this->socket, $str, strlen($str))) {
- throw new HTTP_Request2_Exception('Error writing request');
- }
- // Provide the length of written string to the observer, request #7630
- $this->request->setLastEvent('sentBodyPart', strlen($str));
- $position += strlen($str);
- }
- }
-
- /**
- * Reads the remote server's response
- *
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- protected function readResponse()
- {
- $bufferSize = $this->request->getConfig('buffer_size');
-
- do {
- $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
- do {
- $headerLine = $this->readLine($bufferSize);
- $response->parseHeaderLine($headerLine);
- } while ('' != $headerLine);
- } while (in_array($response->getStatus(), array(100, 101)));
-
- $this->request->setLastEvent('receivedHeaders', $response);
-
- // No body possible in such responses
- if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
- (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
- 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
- in_array($response->getStatus(), array(204, 304))
- ) {
- return $response;
- }
-
- $chunked = 'chunked' == $response->getHeader('transfer-encoding');
- $length = $response->getHeader('content-length');
- $hasBody = false;
- if ($chunked || null === $length || 0 < intval($length)) {
- // RFC 2616, section 4.4:
- // 3. ... If a message is received with both a
- // Transfer-Encoding header field and a Content-Length header field,
- // the latter MUST be ignored.
- $toRead = ($chunked || null === $length)? null: $length;
- $this->chunkLength = 0;
-
- while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
- if ($chunked) {
- $data = $this->readChunked($bufferSize);
- } elseif (is_null($toRead)) {
- $data = $this->fread($bufferSize);
- } else {
- $data = $this->fread(min($toRead, $bufferSize));
- $toRead -= strlen($data);
- }
- if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
- break;
- }
-
- $hasBody = true;
- if ($this->request->getConfig('store_body')) {
- $response->appendBody($data);
- }
- if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
- $this->request->setLastEvent('receivedEncodedBodyPart', $data);
- } else {
- $this->request->setLastEvent('receivedBodyPart', $data);
- }
- }
- }
-
- if ($hasBody) {
- $this->request->setLastEvent('receivedBody', $response);
- }
- return $response;
- }
-
- /**
- * Reads until either the end of the socket or a newline, whichever comes first
- *
- * Strips the trailing newline from the returned data, handles global
- * request timeout. Method idea borrowed from Net_Socket PEAR package.
- *
- * @param int buffer size to use for reading
- * @return Available data up to the newline (not including newline)
- * @throws HTTP_Request2_Exception In case of timeout
- */
- protected function readLine($bufferSize)
- {
- $line = '';
- while (!feof($this->socket)) {
- if ($this->timeout) {
- stream_set_timeout($this->socket, max($this->timeout - time(), 1));
- }
- $line .= @fgets($this->socket, $bufferSize);
- $info = stream_get_meta_data($this->socket);
- if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $this->request->getConfig('timeout') . ' second(s)'
- );
- }
- if (substr($line, -1) == "\n") {
- return rtrim($line, "\r\n");
- }
- }
- return $line;
- }
-
- /**
- * Wrapper around fread(), handles global request timeout
- *
- * @param int Reads up to this number of bytes
- * @return Data read from socket
- * @throws HTTP_Request2_Exception In case of timeout
- */
- protected function fread($length)
- {
- if ($this->timeout) {
- stream_set_timeout($this->socket, max($this->timeout - time(), 1));
- }
- $data = fread($this->socket, $length);
- $info = stream_get_meta_data($this->socket);
- if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $this->request->getConfig('timeout') . ' second(s)'
- );
- }
- return $data;
- }
-
- /**
- * Reads a part of response body encoded with chunked Transfer-Encoding
- *
- * @param int buffer size to use for reading
- * @return string
- * @throws HTTP_Request2_Exception
- */
- protected function readChunked($bufferSize)
- {
- // at start of the next chunk?
- if (0 == $this->chunkLength) {
- $line = $this->readLine($bufferSize);
- if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
- throw new HTTP_Request2_Exception(
- "Cannot decode chunked response, invalid chunk length '{$line}'"
- );
- } else {
- $this->chunkLength = hexdec($matches[1]);
- // Chunk with zero length indicates the end
- if (0 == $this->chunkLength) {
- $this->readLine($bufferSize);
- return '';
- }
- }
- }
- $data = $this->fread(min($this->chunkLength, $bufferSize));
- $this->chunkLength -= strlen($data);
- if (0 == $this->chunkLength) {
- $this->readLine($bufferSize); // Trailing CRLF
- }
- return $data;
- }
-}
-
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * This adapter uses only PHP sockets and will work on almost any PHP
+ * environment. Code is based on original HTTP_Request PEAR package.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
+{
+ /**
+ * Regular expression for 'token' rule from RFC 2616
+ */
+ const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
+
+ /**
+ * Regular expression for 'quoted-string' rule from RFC 2616
+ */
+ const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
+
+ /**
+ * Connected sockets, needed for Keep-Alive support
+ * @var array
+ * @see connect()
+ */
+ protected static $sockets = array();
+
+ /**
+ * Data for digest authentication scheme
+ *
+ * The keys for the array are URL prefixes.
+ *
+ * The values are associative arrays with data (realm, nonce, nonce-count,
+ * opaque...) needed for digest authentication. Stored here to prevent making
+ * duplicate requests to digest-protected resources after we have already
+ * received the challenge.
+ *
+ * @var array
+ */
+ protected static $challenges = array();
+
+ /**
+ * Connected socket
+ * @var resource
+ * @see connect()
+ */
+ protected $socket;
+
+ /**
+ * Challenge used for server digest authentication
+ * @var array
+ */
+ protected $serverChallenge;
+
+ /**
+ * Challenge used for proxy digest authentication
+ * @var array
+ */
+ protected $proxyChallenge;
+
+ /**
+ * Global timeout, exception will be raised if request continues past this time
+ * @var integer
+ */
+ protected $timeout = null;
+
+ /**
+ * Remaining length of the current chunk, when reading chunked response
+ * @var integer
+ * @see readChunked()
+ */
+ protected $chunkLength = 0;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ $this->request = $request;
+ $keepAlive = $this->connect();
+ $headers = $this->prepareHeaders();
+
+ // Use global request timeout if given, see feature requests #5735, #8964
+ if ($timeout = $request->getConfig('timeout')) {
+ $this->timeout = time() + $timeout;
+ } else {
+ $this->timeout = null;
+ }
+
+ try {
+ if (false === @fwrite($this->socket, $headers, strlen($headers))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // provide request headers to the observer, see request #7633
+ $this->request->setLastEvent('sentHeaders', $headers);
+ $this->writeBody();
+
+ if ($this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $request->getConfig('timeout') . ' second(s)'
+ );
+ }
+
+ $response = $this->readResponse();
+
+ if (!$this->canKeepAlive($keepAlive, $response)) {
+ $this->disconnect();
+ }
+
+ if ($this->shouldUseProxyDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($this->shouldUseServerDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($authInfo = $response->getHeader('authentication-info')) {
+ $this->updateChallenge($this->serverChallenge, $authInfo);
+ }
+ if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
+ $this->updateChallenge($this->proxyChallenge, $proxyInfo);
+ }
+
+ } catch (Exception $e) {
+ $this->disconnect();
+ throw $e;
+ }
+
+ return $response;
+ }
+
+ /**
+ * Connects to the remote server
+ *
+ * @return bool whether the connection can be persistent
+ * @throws HTTP_Request2_Exception
+ */
+ protected function connect()
+ {
+ $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
+ $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $headers = $this->request->getHeaders();
+ $reqHost = $this->request->getUrl()->getHost();
+ if (!($reqPort = $this->request->getUrl()->getPort())) {
+ $reqPort = $secure? 443: 80;
+ }
+
+ if ($host = $this->request->getConfig('proxy_host')) {
+ if (!($port = $this->request->getConfig('proxy_port'))) {
+ throw new HTTP_Request2_Exception('Proxy port not provided');
+ }
+ $proxy = true;
+ } else {
+ $host = $reqHost;
+ $port = $reqPort;
+ $proxy = false;
+ }
+
+ if ($tunnel && !$proxy) {
+ throw new HTTP_Request2_Exception(
+ "Trying to perform CONNECT request without proxy"
+ );
+ }
+ if ($secure && !in_array('ssl', stream_get_transports())) {
+ throw new HTTP_Request2_Exception(
+ 'Need OpenSSL support for https:// requests'
+ );
+ }
+
+ // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+ // connection token to a proxy server...
+ if ($proxy && !$secure &&
+ !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
+ ) {
+ $this->request->setHeader('connection');
+ }
+
+ $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
+ empty($headers['connection'])) ||
+ (!empty($headers['connection']) &&
+ 'Keep-Alive' == $headers['connection']);
+ $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
+
+ $options = array();
+ if ($secure || $tunnel) {
+ foreach ($this->request->getConfig() as $name => $value) {
+ if ('ssl_' == substr($name, 0, 4) && null !== $value) {
+ if ('ssl_verify_host' == $name) {
+ if ($value) {
+ $options['CN_match'] = $reqHost;
+ }
+ } else {
+ $options[substr($name, 4)] = $value;
+ }
+ }
+ }
+ ksort($options);
+ }
+
+ // Changing SSL context options after connection is established does *not*
+ // work, we need a new connection if options change
+ $remote = $host . ':' . $port;
+ $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
+ (empty($options)? '': ':' . serialize($options));
+ unset($this->socket);
+
+ // We use persistent connections and have a connected socket?
+ // Ensure that the socket is still connected, see bug #16149
+ if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
+ !feof(self::$sockets[$socketKey])
+ ) {
+ $this->socket =& self::$sockets[$socketKey];
+
+ } elseif ($secure && $proxy && !$tunnel) {
+ $this->establishTunnel();
+ $this->request->setLastEvent(
+ 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
+ );
+ self::$sockets[$socketKey] =& $this->socket;
+
+ } else {
+ // Set SSL context options if doing HTTPS request or creating a tunnel
+ $context = stream_context_create();
+ foreach ($options as $name => $value) {
+ if (!stream_context_set_option($context, 'ssl', $name, $value)) {
+ throw new HTTP_Request2_Exception(
+ "Error setting SSL context option '{$name}'"
+ );
+ }
+ }
+ $this->socket = @stream_socket_client(
+ $remote, $errno, $errstr,
+ $this->request->getConfig('connect_timeout'),
+ STREAM_CLIENT_CONNECT, $context
+ );
+ if (!$this->socket) {
+ throw new HTTP_Request2_Exception(
+ "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
+ );
+ }
+ $this->request->setLastEvent('connect', $remote);
+ self::$sockets[$socketKey] =& $this->socket;
+ }
+ return $keepAlive;
+ }
+
+ /**
+ * Establishes a tunnel to a secure remote server via HTTP CONNECT request
+ *
+ * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
+ * sees that we are connected to a proxy server (duh!) rather than the server
+ * that presents its certificate.
+ *
+ * @link http://tools.ietf.org/html/rfc2817#section-5.2
+ * @throws HTTP_Request2_Exception
+ */
+ protected function establishTunnel()
+ {
+ $donor = new self;
+ $connect = new HTTP_Request2(
+ $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
+ array_merge($this->request->getConfig(),
+ array('adapter' => $donor))
+ );
+ $response = $connect->send();
+ // Need any successful (2XX) response
+ if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
+ throw new HTTP_Request2_Exception(
+ 'Failed to connect via HTTPS proxy. Proxy response: ' .
+ $response->getStatus() . ' ' . $response->getReasonPhrase()
+ );
+ }
+ $this->socket = $donor->socket;
+
+ $modes = array(
+ STREAM_CRYPTO_METHOD_TLS_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv2_CLIENT
+ );
+
+ foreach ($modes as $mode) {
+ if (stream_socket_enable_crypto($this->socket, true, $mode)) {
+ return;
+ }
+ }
+ throw new HTTP_Request2_Exception(
+ 'Failed to enable secure connection when connecting through proxy'
+ );
+ }
+
+ /**
+ * Checks whether current connection may be reused or should be closed
+ *
+ * @param boolean whether connection could be persistent
+ * in the first place
+ * @param HTTP_Request2_Response response object to check
+ * @return boolean
+ */
+ protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
+ {
+ // Do not close socket on successful CONNECT request
+ if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()
+ ) {
+ return true;
+ }
+
+ $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
+ null !== $response->getHeader('content-length');
+ $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
+ (null === $response->getHeader('connection') &&
+ '1.1' == $response->getVersion());
+ return $requestKeepAlive && $lengthKnown && $persistent;
+ }
+
+ /**
+ * Disconnects from the remote server
+ */
+ protected function disconnect()
+ {
+ if (is_resource($this->socket)) {
+ fclose($this->socket);
+ $this->socket = null;
+ $this->request->setLastEvent('disconnect');
+ }
+ }
+
+ /**
+ * Checks whether another request should be performed with server digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 401
+ * - auth credentials should be set in the request object
+ * - response should contain WWW-Authenticate header with digest challenge
+ * - there is either no challenge stored for this URL or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
+ {
+ // no sense repeating a request if we don't have credentials
+ if (401 != $response->getStatus() || !$this->request->getAuth()) {
+ return false;
+ }
+ if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
+ return false;
+ }
+
+ $url = $this->request->getUrl();
+ $scheme = $url->getScheme();
+ $host = $scheme . '://' . $url->getHost();
+ if ($port = $url->getPort()) {
+ if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
+ (0 == strcasecmp($scheme, 'https') && 443 != $port)
+ ) {
+ $host .= ':' . $port;
+ }
+ }
+
+ if (!empty($challenge['domain'])) {
+ $prefixes = array();
+ foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
+ // don't bother with different servers
+ if ('/' == substr($prefix, 0, 1)) {
+ $prefixes[] = $host . $prefix;
+ }
+ }
+ }
+ if (empty($prefixes)) {
+ $prefixes = array($host . '/');
+ }
+
+ $ret = true;
+ foreach ($prefixes as $prefix) {
+ if (!empty(self::$challenges[$prefix]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ // probably credentials are invalid
+ $ret = false;
+ }
+ self::$challenges[$prefix] =& $challenge;
+ }
+ return $ret;
+ }
+
+ /**
+ * Checks whether another request should be performed with proxy digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 407
+ * - proxy auth credentials should be set in the request object
+ * - response should contain Proxy-Authenticate header with digest challenge
+ * - there is either no challenge stored for this proxy or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
+ {
+ if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
+ return false;
+ }
+ if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
+ return false;
+ }
+
+ $key = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+
+ if (!empty(self::$challenges[$key]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ $ret = false;
+ } else {
+ $ret = true;
+ }
+ self::$challenges[$key] = $challenge;
+ return $ret;
+ }
+
+ /**
+ * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
+ *
+ * There is a problem with implementation of RFC 2617: several of the parameters
+ * here are defined as quoted-string and thus may contain backslash escaped
+ * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
+ * just value of quoted-string X without surrounding quotes, it doesn't speak
+ * about removing backslash escaping.
+ *
+ * Now realm parameter is user-defined and human-readable, strange things
+ * happen when it contains quotes:
+ * - Apache allows quotes in realm, but apparently uses realm value without
+ * backslashes for digest computation
+ * - Squid allows (manually escaped) quotes there, but it is impossible to
+ * authorize with either escaped or unescaped quotes used in digest,
+ * probably it cannot parse the response (?)
+ * - Both IE and Firefox display realm value with backslashes in
+ * the password popup and apparently use the same value for digest
+ *
+ * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
+ * quoted-string handling, unfortunately that means failure to authorize
+ * sometimes
+ *
+ * @param string value of WWW-Authenticate or Proxy-Authenticate header
+ * @return mixed associative array with challenge parameters, false if
+ * no challenge is present in header value
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function parseDigestChallenge($headerValue)
+ {
+ $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
+ $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
+ if (!preg_match($challenge, $headerValue, $matches)) {
+ return false;
+ }
+
+ preg_match_all('!' . $authParam . '!', $matches[0], $params);
+ $paramsAry = array();
+ $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
+ 'algorithm', 'qop');
+ for ($i = 0; $i < count($params[0]); $i++) {
+ // section 3.2.1: Any unrecognized directive MUST be ignored.
+ if (in_array($params[1][$i], $knownParams)) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ }
+ // we only support qop=auth
+ if (!empty($paramsAry['qop']) &&
+ !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
+ ) {
+ throw new HTTP_Request2_Exception(
+ "Only 'auth' qop is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['qop']}'"
+ );
+ }
+ // we only support algorithm=MD5
+ if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
+ throw new HTTP_Request2_Exception(
+ "Only 'MD5' algorithm is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['algorithm']}'"
+ );
+ }
+
+ return $paramsAry;
+ }
+
+ /**
+ * Parses [Proxy-]Authentication-Info header value and updates challenge
+ *
+ * @param array challenge to update
+ * @param string value of [Proxy-]Authentication-Info header
+ * @todo validate server rspauth response
+ */
+ protected function updateChallenge(&$challenge, $headerValue)
+ {
+ $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
+ $paramsAry = array();
+
+ preg_match_all($authParam, $headerValue, $params);
+ for ($i = 0; $i < count($params[0]); $i++) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ // for now, just update the nonce value
+ if (!empty($paramsAry['nextnonce'])) {
+ $challenge['nonce'] = $paramsAry['nextnonce'];
+ $challenge['nc'] = 1;
+ }
+ }
+
+ /**
+ * Creates a value for [Proxy-]Authorization header when using digest authentication
+ *
+ * @param string user name
+ * @param string password
+ * @param string request URL
+ * @param array digest challenge parameters
+ * @return string value of [Proxy-]Authorization request header
+ * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
+ */
+ protected function createDigestResponse($user, $password, $url, &$challenge)
+ {
+ if (false !== ($q = strpos($url, '?')) &&
+ $this->request->getConfig('digest_compat_ie')
+ ) {
+ $url = substr($url, 0, $q);
+ }
+
+ $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
+ $a2 = md5($this->request->getMethod() . ':' . $url);
+
+ if (empty($challenge['qop'])) {
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
+ } else {
+ $challenge['cnonce'] = 'Req2.' . rand();
+ if (empty($challenge['nc'])) {
+ $challenge['nc'] = 1;
+ }
+ $nc = sprintf('%08x', $challenge['nc']++);
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
+ $challenge['cnonce'] . ':auth:' . $a2);
+ }
+ return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
+ 'realm="' . $challenge['realm'] . '", ' .
+ 'nonce="' . $challenge['nonce'] . '", ' .
+ 'uri="' . $url . '", ' .
+ 'response="' . $digest . '"' .
+ (!empty($challenge['opaque'])?
+ ', opaque="' . $challenge['opaque'] . '"':
+ '') .
+ (!empty($challenge['qop'])?
+ ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
+ '');
+ }
+
+ /**
+ * Adds 'Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request host (needed for digest authentication)
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
+ {
+ if (!($auth = $this->request->getAuth())) {
+ return;
+ }
+ switch ($auth['scheme']) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['authorization'] =
+ 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->serverChallenge);
+ $fullUrl = ('/' == $requestUrl[0])?
+ $this->request->getUrl()->getScheme() . '://' .
+ $requestHost . $requestUrl:
+ $requestUrl;
+ foreach (array_keys(self::$challenges) as $key) {
+ if ($key == substr($fullUrl, 0, strlen($key))) {
+ $headers['authorization'] = $this->createDigestResponse(
+ $auth['user'], $auth['password'],
+ $requestUrl, self::$challenges[$key]
+ );
+ $this->serverChallenge =& self::$challenges[$key];
+ break;
+ }
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '{$auth['scheme']}'"
+ );
+ }
+ }
+
+ /**
+ * Adds 'Proxy-Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
+ {
+ if (!$this->request->getConfig('proxy_host') ||
+ !($user = $this->request->getConfig('proxy_user')) ||
+ (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
+ HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
+ ) {
+ return;
+ }
+
+ $password = $this->request->getConfig('proxy_password');
+ switch ($this->request->getConfig('proxy_auth_scheme')) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['proxy-authorization'] =
+ 'Basic ' . base64_encode($user . ':' . $password);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->proxyChallenge);
+ $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+ if (!empty(self::$challenges[$proxyUrl])) {
+ $headers['proxy-authorization'] = $this->createDigestResponse(
+ $user, $password,
+ $requestUrl, self::$challenges[$proxyUrl]
+ );
+ $this->proxyChallenge =& self::$challenges[$proxyUrl];
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '" .
+ $this->request->getConfig('proxy_auth_scheme') . "'"
+ );
+ }
+ }
+
+
+ /**
+ * Creates the string with the Request-Line and request headers
+ *
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function prepareHeaders()
+ {
+ $headers = $this->request->getHeaders();
+ $url = $this->request->getUrl();
+ $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $host = $url->getHost();
+
+ $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
+ if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
+ $host .= ':' . (empty($port)? $defaultPort: $port);
+ }
+ // Do not overwrite explicitly set 'Host' header, see bug #16146
+ if (!isset($headers['host'])) {
+ $headers['host'] = $host;
+ }
+
+ if ($connect) {
+ $requestUrl = $host;
+
+ } else {
+ if (!$this->request->getConfig('proxy_host') ||
+ 0 == strcasecmp($url->getScheme(), 'https')
+ ) {
+ $requestUrl = '';
+ } else {
+ $requestUrl = $url->getScheme() . '://' . $host;
+ }
+ $path = $url->getPath();
+ $query = $url->getQuery();
+ $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
+ }
+
+ if ('1.1' == $this->request->getConfig('protocol_version') &&
+ extension_loaded('zlib') && !isset($headers['accept-encoding'])
+ ) {
+ $headers['accept-encoding'] = 'gzip, deflate';
+ }
+
+ $this->addAuthorizationHeader($headers, $host, $requestUrl);
+ $this->addProxyAuthorizationHeader($headers, $requestUrl);
+ $this->calculateRequestLength($headers);
+
+ $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
+ $this->request->getConfig('protocol_version') . "\r\n";
+ foreach ($headers as $name => $value) {
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $headersStr .= $canonicalName . ': ' . $value . "\r\n";
+ }
+ return $headersStr . "\r\n";
+ }
+
+ /**
+ * Sends the request body
+ *
+ * @throws HTTP_Request2_Exception
+ */
+ protected function writeBody()
+ {
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength
+ ) {
+ return;
+ }
+
+ $position = 0;
+ $bufferSize = $this->request->getConfig('buffer_size');
+ while ($position < $this->contentLength) {
+ if (is_string($this->requestBody)) {
+ $str = substr($this->requestBody, $position, $bufferSize);
+ } elseif (is_resource($this->requestBody)) {
+ $str = fread($this->requestBody, $bufferSize);
+ } else {
+ $str = $this->requestBody->read($bufferSize);
+ }
+ if (false === @fwrite($this->socket, $str, strlen($str))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // Provide the length of written string to the observer, request #7630
+ $this->request->setLastEvent('sentBodyPart', strlen($str));
+ $position += strlen($str);
+ }
+ }
+
+ /**
+ * Reads the remote server's response
+ *
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readResponse()
+ {
+ $bufferSize = $this->request->getConfig('buffer_size');
+
+ do {
+ $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
+ do {
+ $headerLine = $this->readLine($bufferSize);
+ $response->parseHeaderLine($headerLine);
+ } while ('' != $headerLine);
+ } while (in_array($response->getStatus(), array(100, 101)));
+
+ $this->request->setLastEvent('receivedHeaders', $response);
+
+ // No body possible in such responses
+ if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
+ (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
+ in_array($response->getStatus(), array(204, 304))
+ ) {
+ return $response;
+ }
+
+ $chunked = 'chunked' == $response->getHeader('transfer-encoding');
+ $length = $response->getHeader('content-length');
+ $hasBody = false;
+ if ($chunked || null === $length || 0 < intval($length)) {
+ // RFC 2616, section 4.4:
+ // 3. ... If a message is received with both a
+ // Transfer-Encoding header field and a Content-Length header field,
+ // the latter MUST be ignored.
+ $toRead = ($chunked || null === $length)? null: $length;
+ $this->chunkLength = 0;
+
+ while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
+ if ($chunked) {
+ $data = $this->readChunked($bufferSize);
+ } elseif (is_null($toRead)) {
+ $data = $this->fread($bufferSize);
+ } else {
+ $data = $this->fread(min($toRead, $bufferSize));
+ $toRead -= strlen($data);
+ }
+ if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
+ break;
+ }
+
+ $hasBody = true;
+ if ($this->request->getConfig('store_body')) {
+ $response->appendBody($data);
+ }
+ if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
+ $this->request->setLastEvent('receivedEncodedBodyPart', $data);
+ } else {
+ $this->request->setLastEvent('receivedBodyPart', $data);
+ }
+ }
+ }
+
+ if ($hasBody) {
+ $this->request->setLastEvent('receivedBody', $response);
+ }
+ return $response;
+ }
+
+ /**
+ * Reads until either the end of the socket or a newline, whichever comes first
+ *
+ * Strips the trailing newline from the returned data, handles global
+ * request timeout. Method idea borrowed from Net_Socket PEAR package.
+ *
+ * @param int buffer size to use for reading
+ * @return Available data up to the newline (not including newline)
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function readLine($bufferSize)
+ {
+ $line = '';
+ while (!feof($this->socket)) {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $line .= @fgets($this->socket, $bufferSize);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ if (substr($line, -1) == "\n") {
+ return rtrim($line, "\r\n");
+ }
+ }
+ return $line;
+ }
+
+ /**
+ * Wrapper around fread(), handles global request timeout
+ *
+ * @param int Reads up to this number of bytes
+ * @return Data read from socket
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function fread($length)
+ {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $data = fread($this->socket, $length);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ return $data;
+ }
+
+ /**
+ * Reads a part of response body encoded with chunked Transfer-Encoding
+ *
+ * @param int buffer size to use for reading
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readChunked($bufferSize)
+ {
+ // at start of the next chunk?
+ if (0 == $this->chunkLength) {
+ $line = $this->readLine($bufferSize);
+ if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
+ throw new HTTP_Request2_Exception(
+ "Cannot decode chunked response, invalid chunk length '{$line}'"
+ );
+ } else {
+ $this->chunkLength = hexdec($matches[1]);
+ // Chunk with zero length indicates the end
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize);
+ return '';
+ }
+ }
+ }
+ $data = $this->fread(min($this->chunkLength, $bufferSize));
+ $this->chunkLength -= strlen($data);
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize); // Trailing CRLF
+ }
+ return $data;
+ }
+}
+
?>
\ No newline at end of file
diff --git a/extlib/MIME/Type.php b/extlib/MIME/Type.php
index c335f8d92..8653362d3 100644
--- a/extlib/MIME/Type.php
+++ b/extlib/MIME/Type.php
@@ -478,7 +478,7 @@ class MIME_Type
// Don't return an empty string
if (!$type || !strlen($type)) {
- return PEAR::raiseError("Sorry, couldn't determine file type.");
+ return PEAR::raiseError("Sorry. Could not determine file type.");
}
// Strip parameters if present & requested
@@ -510,7 +510,7 @@ class MIME_Type
$fileCmd = PEAR::getStaticProperty('MIME_Type', 'fileCmd');
if (!$cmd->which($fileCmd)) {
unset($cmd);
- return PEAR::raiseError("Can't find file command \"{$fileCmd}\"");
+ return PEAR::raiseError("Cannot find file command \"{$fileCmd}\"");
}
$cmd->pushCommand($fileCmd, "-bi " . escapeshellarg($file));
diff --git a/extlib/MIME/Type/Extension.php b/extlib/MIME/Type/Extension.php
index 1987e2a10..2ffdee9a9 100644
--- a/extlib/MIME/Type/Extension.php
+++ b/extlib/MIME/Type/Extension.php
@@ -265,7 +265,7 @@ class MIME_Type_Extension
}
if (!isset($this->extensionToType[$extension])) {
- return PEAR::raiseError("Sorry, couldn't determine file type.");
+ return PEAR::raiseError("Sorry. Could not determine file type.");
}
return $this->extensionToType[$extension];
@@ -288,7 +288,7 @@ class MIME_Type_Extension
$extension = array_search($type, $this->extensionToType);
if ($extension === false) {
- return PEAR::raiseError("Sorry, couldn't determine extension.");
+ return PEAR::raiseError("Sorry. Could not determine extension.");
}
return $extension;
}
diff --git a/extlib/Mail/mail.php b/extlib/Mail/mail.php
index b13d69565..112ff940c 100644
--- a/extlib/Mail/mail.php
+++ b/extlib/Mail/mail.php
@@ -51,7 +51,7 @@ class Mail_mail extends Mail {
}
/* Because the mail() function may pass headers as command
- * line arguments, we can't guarantee the use of the standard
+ * line arguments, we cannot guarantee the use of the standard
* "\r\n" separator. Instead, we use the system's native line
* separator. */
if (defined('PHP_EOL')) {
diff --git a/extlib/Mail/sendmail.php b/extlib/Mail/sendmail.php
index cd248e61d..aea52081a 100644
--- a/extlib/Mail/sendmail.php
+++ b/extlib/Mail/sendmail.php
@@ -67,7 +67,7 @@ class Mail_sendmail extends Mail {
/*
* Because we need to pass message headers to the sendmail program on
- * the commandline, we can't guarantee the use of the standard "\r\n"
+ * the commandline, we cannot guarantee the use of the standard "\r\n"
* separator. Instead, we use the system's native line separator.
*/
if (defined('PHP_EOL')) {
diff --git a/extlib/Net/LDAP2/Entry.php b/extlib/Net/LDAP2/Entry.php
index 66de96678..5531bfa13 100644
--- a/extlib/Net/LDAP2/Entry.php
+++ b/extlib/Net/LDAP2/Entry.php
@@ -665,7 +665,7 @@ class Net_LDAP2_Entry extends PEAR
* To force replace mode instead of add, you can set $force to true.
*
* @param array $attr Attributes to replace
- * @param bool $force Force replacing mode in case we can't read the attr value but are allowed to replace it
+ * @param bool $force Force replacing mode in case we cannot read the attr value but are allowed to replace it
*
* @access public
* @return true|Net_LDAP2_Error
diff --git a/extlib/Net/LDAP2/Filter.php b/extlib/Net/LDAP2/Filter.php
index 0723edab2..bd13d1ee4 100644
--- a/extlib/Net/LDAP2/Filter.php
+++ b/extlib/Net/LDAP2/Filter.php
@@ -439,7 +439,7 @@ class Net_LDAP2_Filter extends PEAR
*
* This method is only for compatibility to the perl interface.
* However, the original method was called "print" but due to PHP language restrictions,
- * we can't have a print() method.
+ * we cannot have a print() method.
*
* @param resource $FH (optional) A filehandle resource
*
diff --git a/extlib/System/Command.php b/extlib/System/Command.php
index f5c3ec6b9..d2001a975 100644
--- a/extlib/System/Command.php
+++ b/extlib/System/Command.php
@@ -376,7 +376,7 @@ class System_Command {
return $this->_initError;
}
- // if the command is empty or if the last element was a control operator, we can't continue
+ // if the command is empty or if the last element was a control operator, we cannot continue
if (is_null($this->previousElement) || $this->commandStatus == -1 || in_array($this->previousElement, $this->controlOperators)) {
return PEAR::raiseError(null, SYSTEM_COMMAND_INVALID_COMMAND, null, E_USER_WARNING, $this->systemCommand, 'System_Command_Error', true);
}
diff --git a/extlib/markdown.php b/extlib/markdown.php
index 8179b568b..1bb1b6ce4 100644
--- a/extlib/markdown.php
+++ b/extlib/markdown.php
@@ -1348,7 +1348,7 @@ class Markdown_Parser {
// {
// list(, $div_open, , $div_content, $div_close) = $matches;
//
-// # We can't call Markdown(), because that resets the hash;
+// # We cannot call Markdown(), because that resets the hash;
// # that initialization code should be pulled into its own sub, though.
// $div_content = $this->hashHTMLBlocks($div_content);
//
diff --git a/install.php b/install.php
index e7f7cf318..78a4b8763 100644
--- a/install.php
+++ b/install.php
@@ -391,7 +391,7 @@ function showLibs()
libraries instead, as they tend to provide security updates faster, and may offer improved performance.
On Debian based distributions, such as Ubuntu, use a package manager (such as "aptitude", "apt-get", and "synaptic") to install the package listed.
On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as "yum", "apt-rpm", and "up2date") to install the package listed.
- On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run "pear install <name>".
+ On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP PEAR to install the library. Simply run "pear install <name>".
Absent Libraries
@@ -570,7 +570,7 @@ STR;
$res = writeConf($sitename, $server, $path, $fancy, $db);
if (!$res) {
- updateStatus("Can't write config file.", true);
+ updateStatus("Cannot write config file.", true);
showForm();
return;
}
@@ -616,7 +616,7 @@ function Pgsql_Db_installer($host, $database, $username, $password)
$res = runDbScript(INSTALLDIR.'/db/statusnet_pg.sql', $conn, 'pgsql');
if ($res === false) {
- updateStatus("Can't run database script.", true);
+ updateStatus("Cannot run database script.", true);
showForm();
return false;
}
@@ -627,7 +627,7 @@ function Pgsql_Db_installer($host, $database, $username, $password)
updateStatus(sprintf("Adding %s data to database...", $name));
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn, 'pgsql');
if ($res === false) {
- updateStatus(sprintf("Can't run %d script.", $name), true);
+ updateStatus(sprintf("Cannot run %d script.", $name), true);
showForm();
return false;
}
@@ -652,21 +652,21 @@ function Mysql_Db_installer($host, $database, $username, $password)
$conn = mysql_connect($host, $username, $password);
if (!$conn) {
- updateStatus("Can't connect to server '$host' as '$username'.", true);
+ updateStatus("Cannot connect to server '$host' as '$username'.", true);
showForm();
return false;
}
updateStatus("Changing to database...");
$res = mysql_select_db($database, $conn);
if (!$res) {
- updateStatus("Can't change to database.", true);
+ updateStatus("Cannot change to database.", true);
showForm();
return false;
}
updateStatus("Running database script...");
$res = runDbScript(INSTALLDIR.'/db/statusnet.sql', $conn);
if ($res === false) {
- updateStatus("Can't run database script.", true);
+ updateStatus("Cannot run database script.", true);
showForm();
return false;
}
@@ -677,7 +677,7 @@ function Mysql_Db_installer($host, $database, $username, $password)
updateStatus(sprintf("Adding %s data to database...", $name));
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
if ($res === false) {
- updateStatus(sprintf("Can't run %d script.", $name), true);
+ updateStatus(sprintf("Cannot run %d script.", $name), true);
showForm();
return false;
}
diff --git a/lib/attachmentlist.php b/lib/attachmentlist.php
index 51ceca857..60095dace 100644
--- a/lib/attachmentlist.php
+++ b/lib/attachmentlist.php
@@ -71,7 +71,7 @@ class AttachmentList extends Widget
/**
* show the list of notices
*
- * "Uses up" the stream by looping through it. So, probably can't
+ * "Uses up" the stream by looping through it. So, probably cannot
* be called twice on the same list.
*
* @return int count of notices listed.
diff --git a/lib/noticelist.php b/lib/noticelist.php
index 8b3015cc3..385da37e9 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -75,7 +75,7 @@ class NoticeList extends Widget
/**
* show the list of notices
*
- * "Uses up" the stream by looping through it. So, probably can't
+ * "Uses up" the stream by looping through it. So, probably cannot
* be called twice on the same list.
*
* @return int count of notices listed.
diff --git a/lib/profilelist.php b/lib/profilelist.php
index bbb722701..f3eb66658 100644
--- a/lib/profilelist.php
+++ b/lib/profilelist.php
@@ -269,7 +269,7 @@ class ProfileListItem extends Widget
$usf = new UnsubscribeForm($this->out, $this->profile);
$usf->show();
} else {
- // Is it a local user? can't remote sub from a list
+ // Is it a local user? cannot remote sub from a list
// XXX: make that possible!
$other = User::staticGet('id', $this->profile->id);
if (!empty($other)) {
diff --git a/lib/serverexception.php b/lib/serverexception.php
index 7dc9765ad..6b2d55a0b 100644
--- a/lib/serverexception.php
+++ b/lib/serverexception.php
@@ -34,7 +34,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
/**
* Class for server exceptions
*
- * Subclass of PHP Exception for server errors. The user typically can't fix these.
+ * Subclass of PHP Exception for server errors. The user typically cannot fix these.
*
* @category Exception
* @package StatusNet
diff --git a/lib/settingsaction.php b/lib/settingsaction.php
index c3669868d..4193ea521 100644
--- a/lib/settingsaction.php
+++ b/lib/settingsaction.php
@@ -72,7 +72,7 @@ class SettingsAction extends CurrentUserDesignAction
$this->clientError(_('Not logged in.'));
return;
} else if (!common_is_real_login()) {
- // Cookie theft means that automatic logins can't
+ // Cookie theft means that automatic logins cannot
// change important settings or see private info, and
// _all_ our settings are important
common_set_returnto($this->selfUrl());
diff --git a/lib/util.php b/lib/util.php
index a4865c46c..dde3fb48f 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -576,7 +576,7 @@ function common_linkify($url) {
} elseif (is_string($longurl_data)) {
$longurl = $longurl_data;
} else {
- throw new ServerException("Can't linkify url '$url'");
+ throw new ServerException("Cannot linkify url '$url'");
}
}
$attrs = array('href' => $canon, 'title' => $longurl, 'rel' => 'external');
diff --git a/lib/xmppqueuehandler.php b/lib/xmppqueuehandler.php
index f28fc9088..8acdcafe7 100644
--- a/lib/xmppqueuehandler.php
+++ b/lib/xmppqueuehandler.php
@@ -43,7 +43,7 @@ class XmppQueueHandler extends QueueHandler
$this->conn = jabber_connect($this->_id.$this->transport());
if (empty($this->conn)) {
- $this->log(LOG_ERR, "Couldn't connect to server.");
+ $this->log(LOG_ERR, "Could not connect to server.");
return false;
}
diff --git a/locale/statusnet.po b/locale/statusnet.po
index 4331b906e..3ea314f34 100644
--- a/locale/statusnet.po
+++ b/locale/statusnet.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-11-08 11:53+0000\n"
+"POT-Creation-Date: 2009-11-08 22:12+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -16,7310 +16,4442 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../actions/noticesearchrss.php:64 actions/noticesearchrss.php:68
-#: actions/noticesearchrss.php:88 actions/noticesearchrss.php:89
-#, php-format
-msgid " Search Stream for \"%s\""
+#: actions/all.php:63 actions/public.php:97 actions/replies.php:92
+#: actions/showfavorites.php:137 actions/tag.php:51
+msgid "No such page"
msgstr ""
-#: ../actions/finishopenidlogin.php:82 ../actions/register.php:191
-#: actions/finishopenidlogin.php:88 actions/register.php:205
-#: actions/finishopenidlogin.php:110 actions/finishopenidlogin.php:109
-msgid ""
-" except this private data: password, email address, IM address, phone number."
+#: actions/all.php:74 actions/allrss.php:68 actions/avatarbynickname.php:75
+#: actions/favoritesrss.php:74 actions/foaf.php:40 actions/foaf.php:58
+#: actions/remotesubscribe.php:145 actions/replies.php:73
+#: actions/repliesrss.php:38 actions/showfavorites.php:105
+#: actions/userbyid.php:74 actions/usergroups.php:91 actions/userrss.php:38
+#: actions/xrds.php:71 lib/command.php:163 lib/command.php:311
+#: lib/command.php:364 lib/command.php:411 lib/command.php:466
+#: lib/galleryaction.php:59 lib/mailbox.php:82 lib/profileaction.php:77
+#: lib/subs.php:34 lib/subs.php:112
+msgid "No such user."
msgstr ""
-#: ../actions/showstream.php:400 ../lib/stream.php:109
-#: actions/showstream.php:418 lib/mailbox.php:164 lib/stream.php:76
-msgid " from "
+#: actions/all.php:84
+#, php-format
+msgid "%s and friends, page %d"
msgstr ""
-#: ../actions/twitapistatuses.php:478 actions/twitapistatuses.php:412
-#: actions/twitapistatuses.php:347 actions/twitapistatuses.php:363
+#: actions/all.php:86 actions/all.php:167 actions/allrss.php:115
+#: actions/apitimelinefriends.php:114 lib/personalgroupnav.php:100
#, php-format
-msgid "%1$s / Updates replying to %2$s"
+msgid "%s and friends"
msgstr ""
-#: ../actions/invite.php:168 actions/invite.php:176 actions/invite.php:211
-#: actions/invite.php:218 actions/invite.php:220 actions/invite.php:226
+#: actions/all.php:99
#, php-format
-msgid "%1$s has invited you to join them on %2$s"
+msgid "Feed for friends of %s (RSS 1.0)"
msgstr ""
-#: ../actions/invite.php:170 actions/invite.php:220 actions/invite.php:222
-#: actions/invite.php:228
+#: actions/all.php:107
#, php-format
-msgid ""
-"%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. It's also great for meeting new people who "
-"share your interests.\n"
-"\n"
-"%1$s said:\n"
-"\n"
-"%4$s\n"
-"\n"
-"You can see %1$s's profile page on %2$s here:\n"
-"\n"
-"%5$s\n"
-"\n"
-"If you'd like to try the service, click on the link below to accept the "
-"invitation.\n"
-"\n"
-"%6$s\n"
-"\n"
-"If not, you can ignore this message. Thanks for your patience and your "
-"time.\n"
-"\n"
-"Sincerely, %2$s\n"
+msgid "Feed for friends of %s (RSS 2.0)"
msgstr ""
-#: ../lib/mail.php:124 lib/mail.php:124 lib/mail.php:126 lib/mail.php:241
-#: lib/mail.php:236 lib/mail.php:235
+#: actions/all.php:115
#, php-format
-msgid "%1$s is now listening to your notices on %2$s."
+msgid "Feed for friends of %s (Atom)"
msgstr ""
-#: ../lib/mail.php:126
+#: actions/all.php:127
#, php-format
msgid ""
-"%1$s is now listening to your notices on %2$s.\n"
-"\n"
-"\t%3$s\n"
-"\n"
-"Faithfully yours,\n"
-"%4$s.\n"
+"This is the timeline for %s and friends but no one has posted anything yet."
msgstr ""
-#: ../actions/twitapistatuses.php:482 actions/twitapistatuses.php:415
-#: actions/twitapistatuses.php:350 actions/twitapistatuses.php:367
-#: actions/twitapistatuses.php:328 actions/apitimelinementions.php:126
+#: actions/all.php:132
#, php-format
-msgid "%1$s updates that reply to updates from %2$s / %3$s."
+msgid ""
+"Try subscribing to more users, [join a group](%%action.groups%%) or post "
+"something yourself."
msgstr ""
-#: ../actions/shownotice.php:45 actions/shownotice.php:45
-#: actions/shownotice.php:161 actions/shownotice.php:174 actions/oembed.php:86
-#: actions/shownotice.php:180
+#: actions/all.php:134
#, php-format
-msgid "%1$s's status on %2$s"
+msgid ""
+"You can try to [nudge %s](../%s) from his profile or [post something to his "
+"or her attention](%%%%action.newnotice%%%%?status_textarea=%s)."
msgstr ""
-#: ../actions/invite.php:84 ../actions/invite.php:92 actions/invite.php:91
-#: actions/invite.php:99 actions/invite.php:123 actions/invite.php:131
-#: actions/invite.php:125 actions/invite.php:133 actions/invite.php:139
+#: actions/all.php:137 actions/replies.php:209 actions/showstream.php:202
#, php-format
-msgid "%s (%s)"
+msgid ""
+"Why not [register an account](%%%%action.register%%%%) and then nudge %s or "
+"post a notice to his or her attention."
msgstr ""
-#: ../actions/publicrss.php:62 actions/publicrss.php:48
-#: actions/publicrss.php:90 actions/publicrss.php:89
-#, php-format
-msgid "%s Public Stream"
+#: actions/all.php:165
+msgid "You and friends"
msgstr ""
-#: ../actions/all.php:47 ../actions/allrss.php:60
-#: ../actions/twitapistatuses.php:238 ../lib/stream.php:51 actions/all.php:47
-#: actions/allrss.php:60 actions/twitapistatuses.php:155 lib/personal.php:51
-#: actions/all.php:65 actions/allrss.php:103 actions/facebookhome.php:164
-#: actions/twitapistatuses.php:126 lib/personalgroupnav.php:99
-#: actions/all.php:68 actions/all.php:114 actions/allrss.php:106
-#: actions/facebookhome.php:163 actions/twitapistatuses.php:130
-#: actions/all.php:50 actions/all.php:127 actions/allrss.php:114
-#: actions/facebookhome.php:158 actions/twitapistatuses.php:89
-#: lib/personalgroupnav.php:100 actions/all.php:86 actions/all.php:167
-#: actions/allrss.php:115 actions/apitimelinefriends.php:114
+#: actions/allrss.php:119 actions/apitimelinefriends.php:121
#, php-format
-msgid "%s and friends"
+msgid "Updates from %1$s and friends on %2$s!"
msgstr ""
-#: ../actions/twitapistatuses.php:49 actions/twitapistatuses.php:49
-#: actions/twitapistatuses.php:33 actions/twitapistatuses.php:32
-#: actions/twitapistatuses.php:37 actions/apitimelinepublic.php:106
-#: actions/publicrss.php:103
-#, php-format
-msgid "%s public timeline"
+#: actions/apiaccountratelimitstatus.php:70 actions/apidirectmessage.php:156
+#: actions/apifavoritecreate.php:99 actions/apifavoritedestroy.php:100
+#: actions/apifriendshipscreate.php:100 actions/apifriendshipsdestroy.php:100
+#: actions/apifriendshipsshow.php:129 actions/apigroupcreate.php:184
+#: actions/apigroupismember.php:114 actions/apigroupjoin.php:155
+#: actions/apigroupleave.php:141 actions/apigrouplistall.php:120
+#: actions/apigrouplist.php:132 actions/apigroupmembership.php:101
+#: actions/apigroupshow.php:105 actions/apihelptest.php:88
+#: actions/apistatusesdestroy.php:102 actions/apistatusesshow.php:108
+#: actions/apistatusnetconfig.php:133 actions/apistatusnetversion.php:93
+#: actions/apisubscriptions.php:111 actions/apitimelinefavorites.php:144
+#: actions/apitimelinefriends.php:154 actions/apitimelinegroup.php:141
+#: actions/apitimelinementions.php:149 actions/apitimelinepublic.php:130
+#: actions/apitimelinetag.php:139 actions/apitimelineuser.php:163
+#: actions/apiusershow.php:101
+msgid "API method not found!"
msgstr ""
-#: ../lib/mail.php:206 lib/mail.php:212 lib/mail.php:411 lib/mail.php:412
-#, php-format
-msgid "%s status"
+#: actions/apiaccountupdateprofileimage.php:84 actions/apiblockcreate.php:89
+#: actions/apiblockdestroy.php:88 actions/apidirectmessagenew.php:117
+#: actions/apifavoritecreate.php:90 actions/apifavoritedestroy.php:91
+#: actions/apifriendshipscreate.php:91 actions/apifriendshipsdestroy.php:91
+#: actions/apigroupcreate.php:104 actions/apigroupjoin.php:91
+#: actions/apigroupleave.php:91 actions/apistatusesupdate.php:109
+msgid "This method requires a POST."
msgstr ""
-#: ../actions/twitapistatuses.php:338 actions/twitapistatuses.php:265
-#: actions/twitapistatuses.php:199 actions/twitapistatuses.php:209
-#: actions/twitapigroups.php:69 actions/twitapistatuses.php:154
-#: actions/apitimelinegroup.php:102 actions/apitimelineuser.php:117
-#: actions/grouprss.php:131 actions/userrss.php:90
+#: actions/apiaccountupdateprofileimage.php:97
+#: actions/apistatusesupdate.php:122 actions/avatarsettings.php:254
+#: actions/newnotice.php:94 lib/designsettings.php:283
#, php-format
-msgid "%s timeline"
+msgid ""
+"The server was unable to handle that much POST data (%s bytes) due to its "
+"current configuration."
msgstr ""
-#: ../actions/twitapistatuses.php:52 actions/twitapistatuses.php:52
-#: actions/twitapistatuses.php:36 actions/twitapistatuses.php:38
-#: actions/twitapistatuses.php:41 actions/apitimelinepublic.php:110
-#: actions/publicrss.php:105
-#, php-format
-msgid "%s updates from everyone!"
+#: actions/apiaccountupdateprofileimage.php:105 actions/apiblockcreate.php:97
+#: actions/apiblockdestroy.php:96 actions/apidirectmessagenew.php:75
+#: actions/apidirectmessage.php:77 actions/apigroupcreate.php:112
+#: actions/apigroupismember.php:90 actions/apigroupjoin.php:99
+#: actions/apigroupleave.php:99 actions/apigrouplist.php:90
+#: actions/apistatusesupdate.php:139 actions/apisubscriptions.php:87
+#: actions/apitimelinefavorites.php:70 actions/apitimelinefriends.php:79
+#: actions/apitimelinementions.php:79 actions/apitimelineuser.php:81
+msgid "No such user!"
msgstr ""
-#: ../actions/register.php:213 actions/register.php:497
-#: actions/register.php:545 actions/register.php:555 actions/register.php:561
-msgid ""
-"(You should receive a message by email momentarily, with instructions on how "
-"to confirm your email address.)"
+#: actions/apiaccountupdateprofileimage.php:130 actions/apiusershow.php:108
+#: actions/avatarbynickname.php:80 actions/foaf.php:65 actions/replies.php:80
+#: actions/usergroups.php:98 lib/galleryaction.php:66 lib/profileaction.php:84
+msgid "User has no profile."
msgstr ""
-#: ../lib/util.php:257 lib/util.php:273 lib/action.php:605 lib/action.php:702
-#: lib/action.php:752 lib/action.php:767
-#, php-format
-msgid ""
-"**%%site.name%%** is a microblogging service brought to you by [%%site."
-"broughtby%%](%%site.broughtbyurl%%). "
+#: actions/apiblockcreate.php:108
+msgid "Block user failed."
msgstr ""
-#: ../lib/util.php:259 lib/util.php:275 lib/action.php:607 lib/action.php:704
-#: lib/action.php:754 lib/action.php:769
-#, php-format
-msgid "**%%site.name%%** is a microblogging service. "
+#: actions/apiblockdestroy.php:107
+msgid "Unblock user failed."
msgstr ""
-#: ../actions/finishopenidlogin.php:73 ../actions/profilesettings.php:43
-#: actions/finishopenidlogin.php:79 actions/profilesettings.php:76
-#: actions/finishopenidlogin.php:101 actions/profilesettings.php:100
-#: lib/groupeditform.php:139 actions/finishopenidlogin.php:100
-#: lib/groupeditform.php:154 actions/profilesettings.php:108
-msgid "1-64 lowercase letters or numbers, no punctuation or spaces"
+#: actions/apidirectmessagenew.php:126
+msgid "No message text!"
msgstr ""
-#: ../actions/register.php:152 actions/register.php:166
-#: actions/register.php:368 actions/register.php:414 actions/register.php:418
-#: actions/register.php:424
-msgid "1-64 lowercase letters or numbers, no punctuation or spaces. Required."
+#: actions/apidirectmessagenew.php:135 actions/newmessage.php:150
+#, php-format
+msgid "That's too long. Max message size is %d chars."
msgstr ""
-#: ../actions/password.php:42 actions/profilesettings.php:181
-#: actions/passwordsettings.php:102 actions/passwordsettings.php:108
-msgid "6 or more characters"
+#: actions/apidirectmessagenew.php:146
+msgid "Recipient user not found."
msgstr ""
-#: ../actions/recoverpassword.php:180 actions/recoverpassword.php:186
-#: actions/recoverpassword.php:220 actions/recoverpassword.php:233
-#: actions/recoverpassword.php:236
-msgid "6 or more characters, and don't forget it!"
+#: actions/apidirectmessagenew.php:150
+msgid "Can't send direct messages to users who aren't your friend."
msgstr ""
-#: ../actions/register.php:154 actions/register.php:168
-#: actions/register.php:373 actions/register.php:419 actions/register.php:423
-#: actions/register.php:429
-msgid "6 or more characters. Required."
+#: actions/apidirectmessage.php:89
+#, php-format
+msgid "Direct messages from %s"
msgstr ""
-#: ../actions/imsettings.php:197 actions/imsettings.php:205
-#: actions/imsettings.php:321 actions/imsettings.php:327
+#: actions/apidirectmessage.php:93
#, php-format
-msgid ""
-"A confirmation code was sent to the IM address you added. You must approve %"
-"s for sending messages to you."
+msgid "All the direct messages sent from %s"
msgstr ""
-#: ../actions/emailsettings.php:213 actions/emailsettings.php:231
-#: actions/emailsettings.php:350 actions/emailsettings.php:358
-msgid ""
-"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."
+#: actions/apidirectmessage.php:101
+#, php-format
+msgid "Direct messages to %s"
msgstr ""
-#: ../actions/smssettings.php:216 actions/smssettings.php:224
-msgid ""
-"A confirmation code was sent to the phone number you added. Check your inbox "
-"(and spam box!) for the code and instructions on how to use it."
-msgstr ""
-
-#: ../actions/twitapiaccount.php:49 ../actions/twitapihelp.php:45
-#: ../actions/twitapistatuses.php:88 ../actions/twitapistatuses.php:259
-#: ../actions/twitapistatuses.php:370 ../actions/twitapistatuses.php:532
-#: ../actions/twitapiusers.php:122 actions/twitapiaccount.php:49
-#: actions/twitapidirect_messages.php:104 actions/twitapifavorites.php:111
-#: actions/twitapifavorites.php:120 actions/twitapifriendships.php:156
-#: actions/twitapihelp.php:46 actions/twitapistatuses.php:93
-#: actions/twitapistatuses.php:176 actions/twitapistatuses.php:288
-#: actions/twitapistatuses.php:298 actions/twitapistatuses.php:454
-#: actions/twitapistatuses.php:463 actions/twitapistatuses.php:504
-#: actions/twitapiusers.php:55 actions/twitapiaccount.php:37
-#: actions/twitapidirect_messages.php:111 actions/twitapifavorites.php:85
-#: actions/twitapifavorites.php:102 actions/twitapifriendships.php:121
-#: actions/twitapihelp.php:44 actions/twitapistatusnet.php:82
-#: actions/twitapistatusnet.php:151 actions/twitapistatuses.php:79
-#: actions/twitapistatuses.php:147 actions/twitapistatuses.php:228
-#: actions/twitapistatuses.php:239 actions/twitapistatuses.php:392
-#: actions/twitapistatuses.php:402 actions/twitapistatuses.php:429
-#: actions/twitapiusers.php:32 actions/twitapidirect_messages.php:120
-#: actions/twitapifavorites.php:91 actions/twitapifavorites.php:108
-#: actions/twitapistatuses.php:82 actions/twitapistatuses.php:159
-#: actions/twitapistatuses.php:246 actions/twitapistatuses.php:257
-#: actions/twitapistatuses.php:416 actions/twitapistatuses.php:426
-#: actions/twitapistatuses.php:453 actions/twitapidirect_messages.php:113
-#: actions/twitapifavorites.php:92 actions/twitapifavorites.php:109
-#: actions/twitapifavorites.php:160 actions/twitapifriendships.php:128
-#: actions/twitapifriendships.php:168 actions/twitapigroups.php:110
-#: actions/twitapistatuses.php:68 actions/twitapistatuses.php:134
-#: actions/twitapistatuses.php:201 actions/twitapistatuses.php:211
-#: actions/twitapistatuses.php:357 actions/twitapistatuses.php:372
-#: actions/twitapistatuses.php:409 actions/twitapitags.php:110
-#: actions/twitapiusers.php:34 actions/apiaccountratelimitstatus.php:70
-#: actions/apidirectmessage.php:156 actions/apifavoritecreate.php:99
-#: actions/apifavoritedestroy.php:100 actions/apifriendshipscreate.php:100
-#: actions/apifriendshipsdestroy.php:100 actions/apifriendshipsshow.php:129
-#: actions/apigroupcreate.php:184 actions/apigroupismember.php:114
-#: actions/apigroupjoin.php:155 actions/apigroupleave.php:141
-#: actions/apigrouplist.php:132 actions/apigrouplistall.php:120
-#: actions/apigroupmembership.php:101 actions/apigroupshow.php:105
-#: actions/apihelptest.php:88 actions/apistatusesdestroy.php:102
-#: actions/apistatusesshow.php:108 actions/apistatusnetconfig.php:133
-#: actions/apistatusnetversion.php:93 actions/apisubscriptions.php:111
-#: actions/apitimelinefavorites.php:144 actions/apitimelinefriends.php:154
-#: actions/apitimelinegroup.php:141 actions/apitimelinementions.php:149
-#: actions/apitimelinepublic.php:130 actions/apitimelinetag.php:139
-#: actions/apitimelineuser.php:163 actions/apiusershow.php:101
-msgid "API method not found!"
+#: actions/apidirectmessage.php:105
+#, php-format
+msgid "All the direct messages sent to %s"
msgstr ""
-#: ../actions/twitapiaccount.php:57 ../actions/twitapiaccount.php:113
-#: ../actions/twitapiaccount.php:119 ../actions/twitapiblocks.php:28
-#: ../actions/twitapiblocks.php:34 ../actions/twitapidirect_messages.php:43
-#: ../actions/twitapidirect_messages.php:49
-#: ../actions/twitapidirect_messages.php:56
-#: ../actions/twitapidirect_messages.php:62 ../actions/twitapifavorites.php:41
-#: ../actions/twitapifavorites.php:47 ../actions/twitapifavorites.php:53
-#: ../actions/twitapihelp.php:52 ../actions/twitapinotifications.php:29
-#: ../actions/twitapinotifications.php:35 ../actions/twitapistatuses.php:768
-#: actions/twitapiaccount.php:56 actions/twitapiaccount.php:109
-#: actions/twitapiaccount.php:114 actions/twitapiblocks.php:28
-#: actions/twitapiblocks.php:33 actions/twitapidirect_messages.php:170
-#: actions/twitapifavorites.php:168 actions/twitapihelp.php:53
-#: actions/twitapinotifications.php:29 actions/twitapinotifications.php:34
-#: actions/twitapistatuses.php:690 actions/twitapiaccount.php:45
-#: actions/twitapiaccount.php:97 actions/twitapiaccount.php:103
-#: actions/twitapidirect_messages.php:184 actions/twitapifavorites.php:143
-#: actions/twitapihelp.php:52 actions/twitapistatusnet.php:172
-#: actions/twitapinotifications.php:31 actions/twitapinotifications.php:37
-#: actions/twitapistatuses.php:562 actions/twitapiaccount.php:46
-#: actions/twitapiaccount.php:98 actions/twitapiaccount.php:104
-#: actions/twitapidirect_messages.php:193 actions/twitapifavorites.php:149
-#: actions/twitapistatuses.php:625 actions/twitapitrends.php:87
-#: actions/twitapiaccount.php:48 actions/twitapidirect_messages.php:189
-#: actions/twitapihelp.php:54 actions/twitapistatuses.php:582
-msgid "API method under construction."
+#: actions/apifavoritecreate.php:108 actions/apifavoritedestroy.php:109
+#: actions/apistatusesdestroy.php:113
+msgid "No status found with that ID."
msgstr ""
-#: ../lib/util.php:324 lib/util.php:340 lib/action.php:568 lib/action.php:661
-#: lib/action.php:706 lib/action.php:721
-msgid "About"
+#: actions/apifavoritecreate.php:119
+msgid "This status is already a favorite!"
msgstr ""
-#: ../actions/userauthorization.php:119 actions/userauthorization.php:126
-#: actions/userauthorization.php:143 actions/userauthorization.php:178
-#: actions/userauthorization.php:209
-msgid "Accept"
+#: actions/apifavoritecreate.php:130 actions/favor.php:84 lib/command.php:176
+msgid "Could not create favorite."
msgstr ""
-#: ../actions/emailsettings.php:62 ../actions/imsettings.php:63
-#: ../actions/openidsettings.php:57 ../actions/smssettings.php:71
-#: actions/emailsettings.php:63 actions/imsettings.php:64
-#: actions/openidsettings.php:58 actions/smssettings.php:71
-#: actions/twittersettings.php:85 actions/emailsettings.php:120
-#: actions/imsettings.php:127 actions/openidsettings.php:111
-#: actions/smssettings.php:133 actions/twittersettings.php:163
-#: actions/twittersettings.php:166 actions/twittersettings.php:182
-#: actions/emailsettings.php:126 actions/imsettings.php:133
-#: actions/smssettings.php:145
-msgid "Add"
+#: actions/apifavoritedestroy.php:122
+msgid "That status is not a favorite!"
msgstr ""
-#: ../actions/openidsettings.php:43 actions/openidsettings.php:44
-#: actions/openidsettings.php:93
-msgid "Add OpenID"
+#: actions/apifavoritedestroy.php:134 actions/disfavor.php:87
+msgid "Could not delete favorite."
msgstr ""
-#: ../lib/settingsaction.php:97 lib/settingsaction.php:91
-#: lib/accountsettingsaction.php:117
-msgid "Add or remove OpenIDs"
+#: actions/apifriendshipscreate.php:109
+msgid "Could not follow user: User not found."
msgstr ""
-#: ../actions/emailsettings.php:38 ../actions/imsettings.php:39
-#: ../actions/smssettings.php:39 actions/emailsettings.php:39
-#: actions/imsettings.php:40 actions/smssettings.php:39
-#: actions/emailsettings.php:94 actions/imsettings.php:94
-#: actions/smssettings.php:92 actions/emailsettings.php:100
-#: actions/imsettings.php:100 actions/smssettings.php:104
-msgid "Address"
+#: actions/apifriendshipscreate.php:118
+#, php-format
+msgid "Could not follow user: %s is already on your list."
msgstr ""
-#: ../actions/invite.php:131 actions/invite.php:139 actions/invite.php:176
-#: actions/invite.php:181 actions/invite.php:183 actions/invite.php:189
-msgid "Addresses of friends to invite (one per line)"
+#: actions/apifriendshipsdestroy.php:109
+msgid "Could not unfollow user: User not found."
msgstr ""
-#: ../actions/showstream.php:273 actions/showstream.php:288
-#: actions/showstream.php:422 lib/profileaction.php:126
-msgid "All subscriptions"
+#: actions/apifriendshipsdestroy.php:120
+msgid "You cannot unfollow yourself!"
msgstr ""
-#: ../actions/publicrss.php:64 actions/publicrss.php:50
-#: actions/publicrss.php:92 actions/publicrss.php:91
-#, php-format
-msgid "All updates for %s"
+#: actions/apifriendshipsexists.php:94
+msgid "Two user ids or screen_names must be supplied."
msgstr ""
-#: ../actions/noticesearchrss.php:66 actions/noticesearchrss.php:70
-#: actions/noticesearchrss.php:90 actions/noticesearchrss.php:91
-#, php-format
-msgid "All updates matching search term \"%s\""
+#: actions/apifriendshipsshow.php:135
+msgid "Could not determine source user."
msgstr ""
-#: ../actions/finishopenidlogin.php:29 ../actions/login.php:31
-#: ../actions/openidlogin.php:29 ../actions/register.php:30
-#: actions/finishopenidlogin.php:29 actions/login.php:31
-#: actions/openidlogin.php:29 actions/register.php:30
-#: actions/finishopenidlogin.php:34 actions/login.php:77
-#: actions/openidlogin.php:30 actions/register.php:92 actions/register.php:131
-#: actions/login.php:79 actions/register.php:137
-msgid "Already logged in."
+#: actions/apifriendshipsshow.php:143
+msgid "Could not find target user."
msgstr ""
-#: ../lib/subs.php:42 lib/subs.php:42 lib/subs.php:49 lib/subs.php:48
-msgid "Already subscribed!."
+#: actions/apigroupcreate.php:136 actions/newgroup.php:204
+msgid "Could not create group."
msgstr ""
-#: ../actions/deletenotice.php:54 actions/deletenotice.php:55
-#: actions/deletenotice.php:113 actions/deletenotice.php:114
-#: actions/deletenotice.php:144
-msgid "Are you sure you want to delete this notice?"
+#: actions/apigroupcreate.php:147 actions/editgroup.php:259
+#: actions/newgroup.php:210
+msgid "Could not create aliases."
msgstr ""
-#: ../actions/userauthorization.php:77 actions/userauthorization.php:83
-#: actions/userauthorization.php:81 actions/userauthorization.php:76
-#: actions/userauthorization.php:105
-msgid "Authorize subscription"
+#: actions/apigroupcreate.php:166 actions/newgroup.php:224
+msgid "Could not set group membership."
msgstr ""
-#: ../actions/login.php:104 ../actions/register.php:178
-#: actions/register.php:192 actions/login.php:218 actions/openidlogin.php:117
-#: actions/register.php:416 actions/register.php:463 actions/login.php:226
-#: actions/register.php:473 actions/login.php:253 actions/register.php:479
-msgid "Automatically login in the future; not for shared computers!"
+#: actions/apigroupcreate.php:212 actions/editgroup.php:182
+#: actions/newgroup.php:126 actions/profilesettings.php:208
+#: actions/register.php:205
+msgid "Nickname must have only lowercase letters and numbers and no spaces."
msgstr ""
-#: ../actions/profilesettings.php:65 actions/profilesettings.php:98
-#: actions/profilesettings.php:144 actions/profilesettings.php:145
-#: actions/profilesettings.php:160
-msgid ""
-"Automatically subscribe to whoever subscribes to me (best for non-humans)"
+#: actions/apigroupcreate.php:221 actions/editgroup.php:186
+#: actions/newgroup.php:130 actions/profilesettings.php:231
+#: actions/register.php:208
+msgid "Nickname already in use. Try another one."
msgstr ""
-#: ../actions/avatar.php:32 ../lib/settingsaction.php:90
-#: actions/profilesettings.php:34 actions/avatarsettings.php:65
-#: actions/showgroup.php:209 lib/accountsettingsaction.php:107
-#: actions/avatarsettings.php:67 actions/showgroup.php:211
-#: actions/showgroup.php:216 actions/showgroup.php:221
-#: lib/accountsettingsaction.php:111
-msgid "Avatar"
+#: actions/apigroupcreate.php:228 actions/editgroup.php:189
+#: actions/newgroup.php:133 actions/profilesettings.php:211
+#: actions/register.php:210
+msgid "Not a valid nickname."
msgstr ""
-#: ../actions/avatar.php:113 actions/profilesettings.php:350
-#: actions/avatarsettings.php:395 actions/avatarsettings.php:346
-#: actions/avatarsettings.php:360
-msgid "Avatar updated."
+#: actions/apigroupcreate.php:244 actions/editgroup.php:195
+#: actions/newgroup.php:139 actions/profilesettings.php:215
+#: actions/register.php:217
+msgid "Homepage is not a valid URL."
msgstr ""
-#: ../actions/imsettings.php:55 actions/imsettings.php:56
-#: actions/imsettings.php:108 actions/imsettings.php:114
-#, php-format
-msgid ""
-"Awaiting confirmation on this address. Check your Jabber/GTalk account for a "
-"message with further instructions. (Did you add %s to your buddy list?)"
+#: actions/apigroupcreate.php:253 actions/editgroup.php:198
+#: actions/newgroup.php:142 actions/profilesettings.php:218
+#: actions/register.php:220
+msgid "Full name is too long (max 255 chars)."
msgstr ""
-#: ../actions/emailsettings.php:54 actions/emailsettings.php:55
-#: actions/emailsettings.php:107 actions/emailsettings.php:113
-msgid ""
-"Awaiting confirmation on this address. Check your inbox (and spam box!) for "
-"a message with further instructions."
+#: actions/apigroupcreate.php:261
+#, php-format
+msgid "Description is too long (max %d chars)."
msgstr ""
-#: ../actions/smssettings.php:58 actions/smssettings.php:58
-#: actions/smssettings.php:111 actions/smssettings.php:123
-msgid "Awaiting confirmation on this phone number."
+#: actions/apigroupcreate.php:272 actions/editgroup.php:204
+#: actions/newgroup.php:148 actions/profilesettings.php:225
+#: actions/register.php:227
+msgid "Location is too long (max 255 chars)."
msgstr ""
-#: ../lib/util.php:1318 lib/util.php:1452
-msgid "Before »"
+#: actions/apigroupcreate.php:291 actions/editgroup.php:215
+#: actions/newgroup.php:159
+#, php-format
+msgid "Too many aliases! Maximum %d."
msgstr ""
-#: ../actions/profilesettings.php:49 ../actions/register.php:170
-#: actions/profilesettings.php:82 actions/register.php:184
-#: actions/profilesettings.php:112 actions/register.php:402
-#: actions/register.php:448 actions/profilesettings.php:127
-#: actions/register.php:459 actions/register.php:465
-msgid "Bio"
+#: actions/apigroupcreate.php:312 actions/editgroup.php:224
+#: actions/newgroup.php:168
+#, php-format
+msgid "Invalid alias: \"%s\""
msgstr ""
-#: ../actions/profilesettings.php:101 ../actions/register.php:82
-#: ../actions/updateprofile.php:103 actions/profilesettings.php:216
-#: actions/register.php:89 actions/updateprofile.php:104
-#: actions/profilesettings.php:205 actions/register.php:174
-#: actions/updateprofile.php:107 actions/updateprofile.php:109
-#: actions/profilesettings.php:206 actions/register.php:211
-msgid "Bio is too long (max 140 chars)."
+#: actions/apigroupcreate.php:321 actions/editgroup.php:228
+#: actions/newgroup.php:172
+#, php-format
+msgid "Alias \"%s\" already in use. Try another one."
msgstr ""
-#: ../lib/deleteaction.php:41 lib/deleteaction.php:41 lib/deleteaction.php:69
-#: actions/deletenotice.php:71
-msgid "Can't delete this notice."
+#: actions/apigroupcreate.php:334 actions/editgroup.php:234
+#: actions/newgroup.php:178
+msgid "Alias can't be the same as nickname."
msgstr ""
-#: ../actions/updateprofile.php:119 actions/updateprofile.php:120
-#: actions/updateprofile.php:123 actions/updateprofile.php:125
-#, php-format
-msgid "Can't read avatar URL '%s'"
+#: actions/apigroupjoin.php:110
+msgid "You are already a member of that group."
msgstr ""
-#: ../actions/password.php:85 ../actions/recoverpassword.php:300
-#: actions/profilesettings.php:404 actions/recoverpassword.php:313
-#: actions/passwordsettings.php:169 actions/recoverpassword.php:347
-#: actions/passwordsettings.php:174 actions/recoverpassword.php:365
-#: actions/passwordsettings.php:180 actions/recoverpassword.php:368
-#: actions/passwordsettings.php:185
-msgid "Can't save new password."
+#: actions/apigroupjoin.php:119 actions/joingroup.php:95 lib/command.php:221
+msgid "You have been blocked from that group by the admin."
msgstr ""
-#: ../actions/emailsettings.php:57 ../actions/imsettings.php:58
-#: ../actions/smssettings.php:62 actions/emailsettings.php:58
-#: actions/imsettings.php:59 actions/smssettings.php:62
-#: actions/emailsettings.php:111 actions/imsettings.php:114
-#: actions/smssettings.php:114 actions/emailsettings.php:117
-#: actions/imsettings.php:120 actions/smssettings.php:126
-msgid "Cancel"
+#: actions/apigroupjoin.php:138
+#, php-format
+msgid "Could not join user %s to group %s."
msgstr ""
-#: ../lib/openid.php:121 lib/openid.php:121 lib/openid.php:130
-#: lib/openid.php:133
-msgid "Cannot instantiate OpenID consumer object."
+#: actions/apigroupleave.php:114
+msgid "You are not a member of this group."
msgstr ""
-#: ../actions/imsettings.php:163 actions/imsettings.php:171
-#: actions/imsettings.php:286 actions/imsettings.php:292
-msgid "Cannot normalize that Jabber ID"
+#: actions/apigroupleave.php:124
+#, php-format
+msgid "Could not remove user %s to group %s."
msgstr ""
-#: ../actions/emailsettings.php:181 actions/emailsettings.php:199
-#: actions/emailsettings.php:311 actions/emailsettings.php:318
-#: actions/emailsettings.php:326
-msgid "Cannot normalize that email address"
+#: actions/apigrouplistall.php:90 actions/usergroups.php:62
+#, php-format
+msgid "%s groups"
msgstr ""
-#: ../actions/password.php:45 actions/profilesettings.php:184
-#: actions/passwordsettings.php:110 actions/passwordsettings.php:116
-msgid "Change"
+#: actions/apigrouplistall.php:94
+#, php-format
+msgid "groups on %s"
msgstr ""
-#: ../lib/settingsaction.php:88 lib/settingsaction.php:88
-#: lib/accountsettingsaction.php:114 lib/accountsettingsaction.php:118
-msgid "Change email handling"
+#: actions/apigrouplist.php:95
+#, php-format
+msgid "%s's groups"
msgstr ""
-#: ../actions/password.php:32 actions/profilesettings.php:36
-#: actions/passwordsettings.php:58
-msgid "Change password"
+#: actions/apigrouplist.php:103
+#, php-format
+msgid "Groups %s is a member of on %s."
msgstr ""
-#: ../lib/settingsaction.php:94 lib/accountsettingsaction.php:111
-#: lib/accountsettingsaction.php:115
-msgid "Change your password"
-msgstr ""
-
-#: ../lib/settingsaction.php:85 lib/settingsaction.php:85
-#: lib/accountsettingsaction.php:105 lib/accountsettingsaction.php:109
-msgid "Change your profile settings"
+#: actions/apistatusesdestroy.php:107
+msgid "This method requires a POST or DELETE."
msgstr ""
-#: ../actions/password.php:43 ../actions/recoverpassword.php:181
-#: ../actions/register.php:155 ../actions/smssettings.php:65
-#: actions/profilesettings.php:182 actions/recoverpassword.php:187
-#: actions/register.php:169 actions/smssettings.php:65
-#: actions/passwordsettings.php:105 actions/recoverpassword.php:221
-#: actions/register.php:376 actions/smssettings.php:122
-#: actions/recoverpassword.php:236 actions/register.php:422
-#: actions/passwordsettings.php:111 actions/recoverpassword.php:239
-#: actions/register.php:426 actions/smssettings.php:134
-#: actions/register.php:432
-msgid "Confirm"
+#: actions/apistatusesdestroy.php:130
+msgid "You may not delete another user's status."
msgstr ""
-#: ../actions/confirmaddress.php:90 actions/confirmaddress.php:90
-#: actions/confirmaddress.php:144
-msgid "Confirm Address"
+#: actions/apistatusesshow.php:138
+msgid "Status deleted."
msgstr ""
-#: ../actions/emailsettings.php:238 ../actions/imsettings.php:222
-#: ../actions/smssettings.php:245 actions/emailsettings.php:256
-#: actions/imsettings.php:230 actions/smssettings.php:253
-#: actions/emailsettings.php:379 actions/imsettings.php:361
-#: actions/smssettings.php:374 actions/emailsettings.php:386
-#: actions/emailsettings.php:394 actions/imsettings.php:367
-#: actions/smssettings.php:386
-msgid "Confirmation cancelled."
+#: actions/apistatusesshow.php:144
+msgid "No status with that ID found."
msgstr ""
-#: ../actions/smssettings.php:63 actions/smssettings.php:63
-#: actions/smssettings.php:118 actions/smssettings.php:130
-msgid "Confirmation code"
+#: actions/apistatusesupdate.php:152 actions/newnotice.php:155
+#: scripts/maildaemon.php:71
+#, php-format
+msgid "That's too long. Max notice size is %d chars."
msgstr ""
-#: ../actions/confirmaddress.php:38 actions/confirmaddress.php:38
-#: actions/confirmaddress.php:80
-msgid "Confirmation code not found."
+#: actions/apistatusesupdate.php:193
+msgid "Not found"
msgstr ""
-#: ../actions/register.php:202 actions/register.php:473
-#: actions/register.php:521 actions/register.php:531 actions/register.php:537
+#: actions/apistatusesupdate.php:216 actions/newnotice.php:178
#, php-format
-msgid ""
-"Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may "
-"want to...\n"
-"\n"
-"* Go to [your profile](%s) and post your first message.\n"
-"* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send "
-"notices through instant messages.\n"
-"* [Search for people](%%%%action.peoplesearch%%%%) that you may know or that "
-"share your interests. \n"
-"* Update your [profile settings](%%%%action.profilesettings%%%%) to tell "
-"others more about you. \n"
-"* Read over the [online docs](%%%%doc.help%%%%) for features you may have "
-"missed. \n"
-"\n"
-"Thanks for signing up and we hope you enjoy using this service."
-msgstr ""
-
-#: ../actions/finishopenidlogin.php:91 actions/finishopenidlogin.php:97
-#: actions/finishopenidlogin.php:119 lib/action.php:330 lib/action.php:403
-#: lib/action.php:406 actions/finishopenidlogin.php:118 lib/action.php:422
-#: lib/action.php:425 lib/action.php:435
-msgid "Connect"
+msgid "Max notice size is %d chars, including attachment URL."
msgstr ""
-#: ../actions/finishopenidlogin.php:86 actions/finishopenidlogin.php:92
-#: actions/finishopenidlogin.php:114 actions/finishopenidlogin.php:113
-msgid "Connect existing account"
+#: actions/apisubscriptions.php:231 actions/apisubscriptions.php:261
+msgid "Unsupported format."
msgstr ""
-#: ../lib/util.php:332 lib/util.php:348 lib/action.php:576 lib/action.php:669
-#: lib/action.php:719 lib/action.php:734
-msgid "Contact"
+#: actions/apitimelinefavorites.php:107
+#, php-format
+msgid "%s / Favorites from %s"
msgstr ""
-#: ../lib/openid.php:178 lib/openid.php:178 lib/openid.php:187
-#: lib/openid.php:190
+#: actions/apitimelinefavorites.php:119
#, php-format
-msgid "Could not create OpenID form: %s"
+msgid "%s updates favorited by %s / %s."
msgstr ""
-#: ../actions/twitapifriendships.php:60 ../actions/twitapifriendships.php:76
-#: actions/twitapifriendships.php:60 actions/twitapifriendships.php:76
-#: actions/twitapifriendships.php:48 actions/twitapifriendships.php:64
-#: actions/twitapifriendships.php:51 actions/twitapifriendships.php:68
-#: actions/apifriendshipscreate.php:118
+#: actions/apitimelinegroup.php:102 actions/apitimelineuser.php:117
+#: actions/grouprss.php:131 actions/userrss.php:90
#, php-format
-msgid "Could not follow user: %s is already on your list."
+msgid "%s timeline"
msgstr ""
-#: ../actions/twitapifriendships.php:53 actions/twitapifriendships.php:53
-#: actions/twitapifriendships.php:41 actions/twitapifriendships.php:43
-#: actions/apifriendshipscreate.php:109
-msgid "Could not follow user: User not found."
+#: actions/apitimelinegroup.php:110 actions/apitimelineuser.php:125
+#: actions/userrss.php:92
+#, php-format
+msgid "Updates from %1$s on %2$s!"
msgstr ""
-#: ../lib/openid.php:160 lib/openid.php:160 lib/openid.php:169
-#: lib/openid.php:172
+#: actions/apitimelinementions.php:116
#, php-format
-msgid "Could not redirect to server: %s"
+msgid "%1$s / Updates mentioning %2$s"
msgstr ""
-#: ../actions/updateprofile.php:162 actions/updateprofile.php:163
-#: actions/updateprofile.php:166 actions/updateprofile.php:176
-msgid "Could not save avatar info"
+#: actions/apitimelinementions.php:126
+#, php-format
+msgid "%1$s updates that reply to updates from %2$s / %3$s."
msgstr ""
-#: ../actions/updateprofile.php:155 actions/updateprofile.php:156
-#: actions/updateprofile.php:159 actions/updateprofile.php:163
-msgid "Could not save new profile info"
+#: actions/apitimelinepublic.php:106 actions/publicrss.php:103
+#, php-format
+msgid "%s public timeline"
msgstr ""
-#: ../lib/subs.php:54 lib/subs.php:61 lib/subs.php:72 lib/subs.php:75
-msgid "Could not subscribe other to you."
+#: actions/apitimelinepublic.php:110 actions/publicrss.php:105
+#, php-format
+msgid "%s updates from everyone!"
msgstr ""
-#: ../lib/subs.php:46 lib/subs.php:46 lib/subs.php:57 lib/subs.php:56
-msgid "Could not subscribe."
+#: actions/apitimelinetag.php:101 actions/tag.php:66
+#, php-format
+msgid "Notices tagged with %s"
msgstr ""
-#: ../actions/recoverpassword.php:102 actions/recoverpassword.php:105
-#: actions/recoverpassword.php:111
-msgid "Could not update user with confirmed email address."
+#: actions/apitimelinetag.php:107 actions/tagrss.php:64
+#, php-format
+msgid "Updates tagged with %1$s on %2$s!"
msgstr ""
-#: ../actions/finishremotesubscribe.php:99
-#: actions/finishremotesubscribe.php:101 actions/finishremotesubscribe.php:114
-msgid "Couldn't convert request tokens to access tokens."
+#: actions/apiusershow.php:96
+msgid "Not found."
msgstr ""
-#: ../actions/confirmaddress.php:84 ../actions/emailsettings.php:234
-#: ../actions/imsettings.php:218 ../actions/smssettings.php:241
-#: actions/confirmaddress.php:84 actions/emailsettings.php:252
-#: actions/imsettings.php:226 actions/smssettings.php:249
-#: actions/confirmaddress.php:126 actions/emailsettings.php:375
-#: actions/imsettings.php:357 actions/smssettings.php:370
-#: actions/emailsettings.php:382 actions/emailsettings.php:390
-#: actions/imsettings.php:363 actions/smssettings.php:382
-msgid "Couldn't delete email confirmation."
+#: actions/attachment.php:73
+msgid "No such attachment."
msgstr ""
-#: ../lib/subs.php:103 lib/subs.php:116 lib/subs.php:134 lib/subs.php:136
-msgid "Couldn't delete subscription."
+#: actions/avatarbynickname.php:59 actions/leavegroup.php:76
+msgid "No nickname."
msgstr ""
-#: ../actions/twitapistatuses.php:93 actions/twitapistatuses.php:98
-#: actions/twitapistatuses.php:84 actions/twitapistatuses.php:87
-msgid "Couldn't find any statuses."
+#: actions/avatarbynickname.php:64
+msgid "No size."
msgstr ""
-#: ../actions/remotesubscribe.php:127 actions/remotesubscribe.php:136
-#: actions/remotesubscribe.php:178
-msgid "Couldn't get a request token."
+#: actions/avatarbynickname.php:69
+msgid "Invalid size."
msgstr ""
-#: ../actions/emailsettings.php:205 ../actions/imsettings.php:187
-#: ../actions/smssettings.php:206 actions/emailsettings.php:223
-#: actions/imsettings.php:195 actions/smssettings.php:214
-#: actions/emailsettings.php:337 actions/imsettings.php:311
-#: actions/smssettings.php:325 actions/emailsettings.php:344
-#: actions/emailsettings.php:352 actions/imsettings.php:317
-#: actions/smssettings.php:337
-msgid "Couldn't insert confirmation code."
+#: actions/avatarsettings.php:67 actions/showgroup.php:221
+#: lib/accountsettingsaction.php:111
+msgid "Avatar"
msgstr ""
-#: ../actions/finishremotesubscribe.php:180
-#: actions/finishremotesubscribe.php:182 actions/finishremotesubscribe.php:218
-#: lib/oauthstore.php:487
-msgid "Couldn't insert new subscription."
+#: actions/avatarsettings.php:78
+#, php-format
+msgid "You can upload your personal avatar. The maximum file size is %s."
msgstr ""
-#: ../actions/profilesettings.php:184 ../actions/twitapiaccount.php:96
-#: actions/profilesettings.php:299 actions/twitapiaccount.php:94
-#: actions/profilesettings.php:302 actions/twitapiaccount.php:81
-#: actions/twitapiaccount.php:82 actions/profilesettings.php:328
-msgid "Couldn't save profile."
+#: actions/avatarsettings.php:106 actions/avatarsettings.php:182
+#: actions/grouplogo.php:178 actions/remotesubscribe.php:191
+#: actions/userauthorization.php:72 actions/userrss.php:103
+msgid "User without matching profile"
msgstr ""
-#: ../actions/profilesettings.php:161 actions/profilesettings.php:276
-#: actions/profilesettings.php:279 actions/profilesettings.php:295
-msgid "Couldn't update user for autosubscribe."
+#: actions/avatarsettings.php:119 actions/avatarsettings.php:194
+#: actions/grouplogo.php:251
+msgid "Avatar settings"
msgstr ""
-#: ../actions/emailsettings.php:280 ../actions/emailsettings.php:294
-#: actions/emailsettings.php:298 actions/emailsettings.php:312
-#: actions/emailsettings.php:440 actions/emailsettings.php:462
-#: actions/emailsettings.php:447 actions/emailsettings.php:469
-#: actions/smssettings.php:515 actions/smssettings.php:539
-#: actions/smssettings.php:516 actions/smssettings.php:540
-#: actions/emailsettings.php:455 actions/emailsettings.php:477
-#: actions/smssettings.php:528 actions/smssettings.php:552
-msgid "Couldn't update user record."
+#: actions/avatarsettings.php:126 actions/avatarsettings.php:202
+#: actions/grouplogo.php:199 actions/grouplogo.php:259
+msgid "Original"
msgstr ""
-#: ../actions/confirmaddress.php:72 ../actions/emailsettings.php:156
-#: ../actions/emailsettings.php:259 ../actions/imsettings.php:138
-#: ../actions/imsettings.php:243 ../actions/profilesettings.php:141
-#: ../actions/smssettings.php:157 ../actions/smssettings.php:269
-#: actions/confirmaddress.php:72 actions/emailsettings.php:174
-#: actions/emailsettings.php:277 actions/imsettings.php:146
-#: actions/imsettings.php:251 actions/profilesettings.php:256
-#: actions/smssettings.php:165 actions/smssettings.php:277
-#: actions/confirmaddress.php:114 actions/emailsettings.php:280
-#: actions/emailsettings.php:411 actions/imsettings.php:252
-#: actions/imsettings.php:395 actions/othersettings.php:162
-#: actions/profilesettings.php:259 actions/smssettings.php:266
-#: actions/smssettings.php:408 actions/emailsettings.php:287
-#: actions/emailsettings.php:418 actions/othersettings.php:167
-#: actions/profilesettings.php:260 actions/emailsettings.php:295
-#: actions/emailsettings.php:426 actions/imsettings.php:258
-#: actions/imsettings.php:401 actions/othersettings.php:174
-#: actions/profilesettings.php:276 actions/smssettings.php:278
-#: actions/smssettings.php:420
-msgid "Couldn't update user."
+#: actions/avatarsettings.php:141 actions/avatarsettings.php:214
+#: actions/grouplogo.php:210 actions/grouplogo.php:271
+msgid "Preview"
msgstr ""
-#: ../actions/finishopenidlogin.php:84 actions/finishopenidlogin.php:90
-#: actions/finishopenidlogin.php:112 actions/finishopenidlogin.php:111
-msgid "Create"
+#: actions/avatarsettings.php:148 lib/noticelist.php:522
+msgid "Delete"
msgstr ""
-#: ../actions/finishopenidlogin.php:70 actions/finishopenidlogin.php:76
-#: actions/finishopenidlogin.php:98 actions/finishopenidlogin.php:97
-msgid "Create a new user with this nickname."
+#: actions/avatarsettings.php:165 actions/grouplogo.php:233
+msgid "Upload"
msgstr ""
-#: ../actions/finishopenidlogin.php:68 actions/finishopenidlogin.php:74
-#: actions/finishopenidlogin.php:96 actions/finishopenidlogin.php:95
-msgid "Create new account"
+#: actions/avatarsettings.php:228 actions/grouplogo.php:286
+msgid "Crop"
msgstr ""
-#: ../actions/finishopenidlogin.php:191 actions/finishopenidlogin.php:197
-#: actions/finishopenidlogin.php:231 actions/finishopenidlogin.php:247
-msgid "Creating new account for OpenID that already has a user."
+#: actions/avatarsettings.php:265 actions/block.php:64 actions/disfavor.php:74
+#: actions/emailsettings.php:237 actions/favor.php:75
+#: actions/groupblock.php:66 actions/grouplogo.php:309
+#: actions/groupunblock.php:66 actions/imsettings.php:206
+#: actions/invite.php:56 actions/login.php:131 actions/makeadmin.php:66
+#: actions/newmessage.php:135 actions/newnotice.php:103 actions/nudge.php:80
+#: actions/othersettings.php:145 actions/passwordsettings.php:137
+#: actions/profilesettings.php:187 actions/recoverpassword.php:337
+#: actions/register.php:165 actions/remotesubscribe.php:77
+#: actions/smssettings.php:228 actions/subedit.php:38 actions/subscribe.php:46
+#: actions/tagother.php:166 actions/unblock.php:65 actions/unsubscribe.php:69
+#: actions/userauthorization.php:52 lib/designsettings.php:294
+msgid "There was a problem with your session token. Try again, please."
msgstr ""
-#: ../actions/imsettings.php:45 actions/imsettings.php:46
-#: actions/imsettings.php:100 actions/imsettings.php:106
-msgid "Current confirmed Jabber/GTalk address."
+#: actions/avatarsettings.php:277 actions/emailsettings.php:255
+#: actions/grouplogo.php:319 actions/imsettings.php:220
+#: actions/recoverpassword.php:44 actions/smssettings.php:248
+#: lib/designsettings.php:304
+msgid "Unexpected form submission."
msgstr ""
-#: ../actions/smssettings.php:46 actions/smssettings.php:46
-#: actions/smssettings.php:100 actions/smssettings.php:112
-msgid "Current confirmed SMS-enabled phone number."
+#: actions/avatarsettings.php:322
+msgid "Pick a square area of the image to be your avatar"
msgstr ""
-#: ../actions/emailsettings.php:44 actions/emailsettings.php:45
-#: actions/emailsettings.php:99 actions/emailsettings.php:105
-msgid "Current confirmed email address."
+#: actions/avatarsettings.php:337 actions/grouplogo.php:377
+msgid "Lost our file data."
msgstr ""
-#: ../classes/Notice.php:72 classes/Notice.php:86 classes/Notice.php:91
-#: classes/Notice.php:114 classes/Notice.php:124 classes/Notice.php:164
-#, php-format
-msgid "DB error inserting hashtag: %s"
+#: actions/avatarsettings.php:360
+msgid "Avatar updated."
msgstr ""
-#: ../lib/util.php:1061 lib/util.php:1110 classes/Notice.php:698
-#: classes/Notice.php:757 classes/Notice.php:1042 classes/Notice.php:1117
-#: classes/Notice.php:1120
-#, php-format
-msgid "DB error inserting reply: %s"
+#: actions/avatarsettings.php:363
+msgid "Failed updating avatar."
msgstr ""
-#: ../actions/deletenotice.php:41 actions/deletenotice.php:41
-#: actions/deletenotice.php:79 actions/deletenotice.php:111
-#: actions/deletenotice.php:109 actions/deletenotice.php:141
-msgid "Delete notice"
+#: actions/avatarsettings.php:387
+msgid "Avatar deleted."
msgstr ""
-#: ../actions/profilesettings.php:51 ../actions/register.php:172
-#: actions/profilesettings.php:84 actions/register.php:186
-#: actions/profilesettings.php:114 actions/register.php:404
-#: actions/register.php:450
-msgid "Describe yourself and your interests in 140 chars"
+#: actions/blockedfromgroup.php:73 actions/editgroup.php:84
+#: actions/groupdesignsettings.php:84 actions/grouplogo.php:86
+#: actions/groupmembers.php:76 actions/grouprss.php:91
+#: actions/joingroup.php:76 actions/showgroup.php:121
+msgid "No nickname"
msgstr ""
-#: ../actions/register.php:158 ../actions/register.php:161
-#: ../lib/settingsaction.php:87 actions/register.php:172
-#: actions/register.php:175 lib/settingsaction.php:87 actions/register.php:381
-#: actions/register.php:385 lib/accountsettingsaction.php:113
-#: actions/register.php:427 actions/register.php:431 actions/register.php:435
-#: lib/accountsettingsaction.php:117 actions/register.php:437
-#: actions/register.php:441
-msgid "Email"
+#: actions/blockedfromgroup.php:80 actions/editgroup.php:96
+#: actions/groupbyid.php:83 actions/groupdesignsettings.php:97
+#: actions/grouplogo.php:99 actions/groupmembers.php:83
+#: actions/grouprss.php:98 actions/joingroup.php:83 actions/showgroup.php:137
+msgid "No such group"
msgstr ""
-#: ../actions/emailsettings.php:59 actions/emailsettings.php:60
-#: actions/emailsettings.php:115 actions/emailsettings.php:121
-msgid "Email Address"
+#: actions/blockedfromgroup.php:90
+#, php-format
+msgid "%s blocked profiles"
msgstr ""
-#: ../actions/emailsettings.php:32 actions/emailsettings.php:32
-#: actions/emailsettings.php:60
-msgid "Email Settings"
+#: actions/blockedfromgroup.php:93
+#, php-format
+msgid "%s blocked profiles, page %d"
msgstr ""
-#: ../actions/register.php:73 actions/register.php:80 actions/register.php:163
-#: actions/register.php:200 actions/register.php:206 actions/register.php:212
-msgid "Email address already exists."
+#: actions/blockedfromgroup.php:108
+msgid "A list of the users blocked from joining this group."
msgstr ""
-#: ../lib/mail.php:90 lib/mail.php:90 lib/mail.php:173 lib/mail.php:172
-msgid "Email address confirmation"
+#: actions/blockedfromgroup.php:281
+msgid "Unblock user from group"
msgstr ""
-#: ../actions/emailsettings.php:61 actions/emailsettings.php:62
-#: actions/emailsettings.php:117 actions/emailsettings.php:123
-msgid "Email address, like \"UserName@example.org\""
+#: actions/blockedfromgroup.php:313 lib/unblockform.php:150
+msgid "Unblock"
msgstr ""
-#: ../actions/invite.php:129 actions/invite.php:137 actions/invite.php:174
-#: actions/invite.php:179 actions/invite.php:181 actions/invite.php:187
-msgid "Email addresses"
+#: actions/blockedfromgroup.php:313 lib/unblockform.php:120
+#: lib/unblockform.php:150
+msgid "Unblock this user"
msgstr ""
-#: ../actions/recoverpassword.php:191 actions/recoverpassword.php:197
-#: actions/recoverpassword.php:231 actions/recoverpassword.php:249
-#: actions/recoverpassword.php:252
-msgid "Enter a nickname or email address."
+#: actions/block.php:59 actions/deletenotice.php:67 actions/disfavor.php:61
+#: actions/favor.php:62 actions/groupblock.php:61 actions/groupunblock.php:61
+#: actions/logout.php:69 actions/makeadmin.php:61 actions/newmessage.php:87
+#: actions/newnotice.php:89 actions/nudge.php:63 actions/subedit.php:31
+#: actions/subscribe.php:30 actions/unblock.php:60 actions/unsubscribe.php:52
+#: lib/settingsaction.php:72
+msgid "Not logged in."
msgstr ""
-#: ../actions/smssettings.php:64 actions/smssettings.php:64
-#: actions/smssettings.php:119 actions/smssettings.php:131
-msgid "Enter the code you received on your phone."
+#: actions/block.php:69 actions/groupblock.php:71 actions/groupunblock.php:71
+#: actions/makeadmin.php:71 actions/subedit.php:46 actions/unblock.php:70
+msgid "No profile specified."
msgstr ""
-#: ../actions/userauthorization.php:137 actions/userauthorization.php:144
-#: actions/userauthorization.php:161 actions/userauthorization.php:200
-msgid "Error authorizing token"
+#: actions/block.php:74 actions/groupblock.php:76 actions/groupunblock.php:76
+#: actions/makeadmin.php:76 actions/subedit.php:53 actions/tagother.php:46
+#: actions/unblock.php:75
+msgid "No profile with that ID."
msgstr ""
-#: ../actions/finishopenidlogin.php:253 actions/finishopenidlogin.php:259
-#: actions/finishopenidlogin.php:297 actions/finishopenidlogin.php:302
-#: actions/finishopenidlogin.php:325
-msgid "Error connecting user to OpenID."
+#: actions/block.php:111 actions/block.php:134
+msgid "Block user"
msgstr ""
-#: ../actions/finishaddopenid.php:78 actions/finishaddopenid.php:78
-#: actions/finishaddopenid.php:126
-msgid "Error connecting user."
+#: actions/block.php:136
+msgid ""
+"Are you sure you want to block this user? Afterwards, they will be "
+"unsubscribed from you, unable to subscribe to you in the future, and you "
+"will not be notified of any @-replies from them."
msgstr ""
-#: ../actions/finishremotesubscribe.php:151
-#: actions/finishremotesubscribe.php:153 actions/finishremotesubscribe.php:166
-#: lib/oauthstore.php:291
-msgid "Error inserting avatar"
+#: actions/block.php:149 actions/deletenotice.php:145
+#: actions/groupblock.php:176
+msgid "No"
msgstr ""
-#: ../actions/finishremotesubscribe.php:143
-#: actions/finishremotesubscribe.php:145 actions/finishremotesubscribe.php:158
-#: lib/oauthstore.php:283
-msgid "Error inserting new profile"
+#: actions/block.php:149
+msgid "Do not block this user from this group"
msgstr ""
-#: ../actions/finishremotesubscribe.php:167
-#: actions/finishremotesubscribe.php:169 actions/finishremotesubscribe.php:182
-#: lib/oauthstore.php:311
-msgid "Error inserting remote profile"
+#: actions/block.php:150 actions/deletenotice.php:146
+#: actions/groupblock.php:177
+msgid "Yes"
msgstr ""
-#: ../actions/recoverpassword.php:240 actions/recoverpassword.php:246
-#: actions/recoverpassword.php:280 actions/recoverpassword.php:298
-#: actions/recoverpassword.php:301
-msgid "Error saving address confirmation."
+#: actions/block.php:150
+msgid "Block this user from this group"
msgstr ""
-#: ../actions/userauthorization.php:140 actions/userauthorization.php:147
-#: actions/userauthorization.php:164 actions/userauthorization.php:203
-msgid "Error saving remote profile"
+#: actions/block.php:165
+msgid "You have already blocked this user."
msgstr ""
-#: ../lib/openid.php:226 lib/openid.php:226 lib/openid.php:235
-#: lib/openid.php:238
-msgid "Error saving the profile."
+#: actions/block.php:170
+msgid "Failed to save block information."
msgstr ""
-#: ../lib/openid.php:237 lib/openid.php:237 lib/openid.php:246
-#: lib/openid.php:249
-msgid "Error saving the user."
+#: actions/bookmarklet.php:50
+msgid "Post to "
msgstr ""
-#: ../actions/password.php:80 actions/profilesettings.php:399
-#: actions/passwordsettings.php:164 actions/passwordsettings.php:169
-#: actions/passwordsettings.php:175 actions/passwordsettings.php:180
-msgid "Error saving user; invalid."
+#: actions/confirmaddress.php:75
+msgid "No confirmation code."
msgstr ""
-#: ../actions/login.php:47 ../actions/login.php:73
-#: ../actions/recoverpassword.php:307 ../actions/register.php:98
-#: actions/login.php:47 actions/login.php:73 actions/recoverpassword.php:320
-#: actions/register.php:108 actions/login.php:112 actions/login.php:138
-#: actions/recoverpassword.php:354 actions/register.php:198
-#: actions/login.php:120 actions/recoverpassword.php:372
-#: actions/register.php:235 actions/login.php:122
-#: actions/recoverpassword.php:375 actions/register.php:242
-#: actions/login.php:149 actions/register.php:248
-msgid "Error setting user."
+#: actions/confirmaddress.php:80
+msgid "Confirmation code not found."
msgstr ""
-#: ../actions/finishaddopenid.php:83 actions/finishaddopenid.php:83
-#: actions/finishaddopenid.php:131
-msgid "Error updating profile"
+#: actions/confirmaddress.php:85
+msgid "That confirmation code is not for you!"
msgstr ""
-#: ../actions/finishremotesubscribe.php:161
-#: actions/finishremotesubscribe.php:163 actions/finishremotesubscribe.php:176
-#: actions/finishremotesubscribe.php:133 lib/oauthstore.php:306
-msgid "Error updating remote profile"
+#: actions/confirmaddress.php:90
+#, php-format
+msgid "Unrecognized address type %s"
msgstr ""
-#: ../actions/recoverpassword.php:80 actions/recoverpassword.php:80
-#: actions/recoverpassword.php:86
-msgid "Error with confirmation code."
+#: actions/confirmaddress.php:94
+msgid "That address has already been confirmed."
msgstr ""
-#: ../actions/finishopenidlogin.php:89 actions/finishopenidlogin.php:95
-#: actions/finishopenidlogin.php:117 actions/finishopenidlogin.php:116
-msgid "Existing nickname"
+#: actions/confirmaddress.php:114 actions/emailsettings.php:295
+#: actions/emailsettings.php:426 actions/imsettings.php:258
+#: actions/imsettings.php:401 actions/othersettings.php:174
+#: actions/profilesettings.php:276 actions/smssettings.php:278
+#: actions/smssettings.php:420
+msgid "Couldn't update user."
msgstr ""
-#: ../lib/util.php:326 lib/util.php:342 lib/action.php:570 lib/action.php:663
-#: lib/action.php:708 lib/action.php:723
-msgid "FAQ"
+#: actions/confirmaddress.php:126 actions/emailsettings.php:390
+#: actions/imsettings.php:363 actions/smssettings.php:382
+msgid "Couldn't delete email confirmation."
msgstr ""
-#: ../actions/avatar.php:115 actions/profilesettings.php:352
-#: actions/avatarsettings.php:397 actions/avatarsettings.php:349
-#: actions/avatarsettings.php:363
-msgid "Failed updating avatar."
+#: actions/confirmaddress.php:144
+msgid "Confirm Address"
msgstr ""
-#: ../actions/all.php:61 ../actions/allrss.php:64 actions/all.php:61
-#: actions/allrss.php:64 actions/all.php:75 actions/allrss.php:107
-#: actions/allrss.php:110 actions/allrss.php:118
+#: actions/confirmaddress.php:159
#, php-format
-msgid "Feed for friends of %s"
+msgid "The address \"%s\" has been confirmed for your account."
msgstr ""
-#: ../actions/replies.php:65 ../actions/repliesrss.php:80
-#: actions/replies.php:65 actions/repliesrss.php:66 actions/replies.php:134
-#: actions/repliesrss.php:71 actions/replies.php:136 actions/replies.php:135
-#, php-format
-msgid "Feed for replies to %s"
+#: actions/conversation.php:99
+msgid "Conversation"
msgstr ""
-#: ../actions/tag.php:55 actions/tag.php:55 actions/tag.php:61
-#: actions/tag.php:68
-#, php-format
-msgid "Feed for tag %s"
+#: actions/conversation.php:154 lib/mailbox.php:116 lib/noticelist.php:87
+#: lib/profileaction.php:206
+msgid "Notices"
msgstr ""
-#: ../lib/searchaction.php:105 lib/searchaction.php:105
-#: lib/searchgroupnav.php:83
-msgid "Find content of notices"
+#: actions/deletenotice.php:52 actions/shownotice.php:92
+msgid "No such notice."
msgstr ""
-#: ../lib/searchaction.php:101 lib/searchaction.php:101
-#: lib/searchgroupnav.php:81
-msgid "Find people on this site"
+#: actions/deletenotice.php:71
+msgid "Can't delete this notice."
msgstr ""
-#: ../actions/login.php:122 actions/login.php:247 actions/login.php:255
-#: actions/login.php:282
+#: actions/deletenotice.php:103
msgid ""
-"For security reasons, please re-enter your user name and password before "
-"changing your settings."
+"You are about to permanently delete a notice. Once this is done, it cannot "
+"be undone."
msgstr ""
-#: ../actions/profilesettings.php:44 ../actions/register.php:164
-#: actions/profilesettings.php:77 actions/register.php:178
-#: actions/profilesettings.php:103 actions/register.php:391
-#: actions/showgroup.php:235 actions/showstream.php:262
-#: actions/tagother.php:105 lib/groupeditform.php:142
-#: actions/showgroup.php:237 actions/showstream.php:255
-#: actions/tagother.php:104 actions/register.php:437 actions/showgroup.php:242
-#: actions/showstream.php:220 lib/groupeditform.php:157
-#: actions/profilesettings.php:111 actions/register.php:441
-#: actions/showgroup.php:247 actions/showstream.php:267
-#: actions/register.php:447 lib/userprofile.php:149
-msgid "Full name"
+#: actions/deletenotice.php:109 actions/deletenotice.php:141
+msgid "Delete notice"
msgstr ""
-#: ../actions/profilesettings.php:98 ../actions/register.php:79
-#: ../actions/updateprofile.php:93 actions/profilesettings.php:213
-#: actions/register.php:86 actions/updateprofile.php:94
-#: actions/editgroup.php:195 actions/newgroup.php:146
-#: actions/profilesettings.php:202 actions/register.php:171
-#: actions/updateprofile.php:97 actions/updateprofile.php:99
-#: actions/editgroup.php:197 actions/newgroup.php:147
-#: actions/profilesettings.php:203 actions/register.php:208
-#: actions/apigroupcreate.php:253 actions/editgroup.php:198
-#: actions/newgroup.php:142 actions/profilesettings.php:218
-#: actions/register.php:214 actions/register.php:220
-msgid "Full name is too long (max 255 chars)."
+#: actions/deletenotice.php:144
+msgid "Are you sure you want to delete this notice?"
msgstr ""
-#: ../lib/util.php:322 lib/util.php:338 lib/action.php:344 lib/action.php:566
-#: lib/action.php:421 lib/action.php:659 lib/action.php:446 lib/action.php:704
-#: lib/action.php:456 lib/action.php:719
-msgid "Help"
+#: actions/deletenotice.php:145
+msgid "Do not delete this notice"
msgstr ""
-#: ../lib/util.php:298 lib/util.php:314 lib/action.php:322
-#: lib/facebookaction.php:200 lib/action.php:393 lib/facebookaction.php:213
-#: lib/action.php:417 lib/action.php:430
-msgid "Home"
+#: actions/deletenotice.php:146 lib/noticelist.php:522
+msgid "Delete this notice"
msgstr ""
-#: ../actions/profilesettings.php:46 ../actions/register.php:167
-#: actions/profilesettings.php:79 actions/register.php:181
-#: actions/profilesettings.php:107 actions/register.php:396
-#: lib/groupeditform.php:146 actions/register.php:442
-#: lib/groupeditform.php:161 actions/profilesettings.php:115
-#: actions/register.php:446 actions/register.php:452
-msgid "Homepage"
+#: actions/deletenotice.php:157
+msgid "There was a problem with your session token. Try again, please."
msgstr ""
-#: ../actions/profilesettings.php:95 ../actions/register.php:76
-#: actions/profilesettings.php:210 actions/register.php:83
-#: actions/editgroup.php:192 actions/newgroup.php:143
-#: actions/profilesettings.php:199 actions/register.php:168
-#: actions/editgroup.php:194 actions/newgroup.php:144
-#: actions/profilesettings.php:200 actions/register.php:205
-#: actions/apigroupcreate.php:244 actions/editgroup.php:195
-#: actions/newgroup.php:139 actions/profilesettings.php:215
-#: actions/register.php:211 actions/register.php:217
-msgid "Homepage is not a valid URL."
+#: actions/disfavor.php:81
+msgid "This notice is not a favorite!"
msgstr ""
-#: ../actions/emailsettings.php:91 actions/emailsettings.php:98
-#: actions/emailsettings.php:173 actions/emailsettings.php:178
-#: actions/emailsettings.php:185
-msgid "I want to post notices by email."
+#: actions/disfavor.php:94
+msgid "Add to favorites"
msgstr ""
-#: ../lib/settingsaction.php:102 lib/settingsaction.php:96
-#: lib/connectsettingsaction.php:104 lib/connectsettingsaction.php:110
-msgid "IM"
+#: actions/doc.php:69
+msgid "No such document."
msgstr ""
-#: ../actions/imsettings.php:60 actions/imsettings.php:61
-#: actions/imsettings.php:118 actions/imsettings.php:124
-msgid "IM Address"
+#: actions/editgroup.php:56
+#, php-format
+msgid "Edit %s group"
msgstr ""
-#: ../actions/imsettings.php:33 actions/imsettings.php:33
-#: actions/imsettings.php:59
-msgid "IM Settings"
+#: actions/editgroup.php:68 actions/grouplogo.php:70 actions/newgroup.php:65
+msgid "You must be logged in to create a group."
msgstr ""
-#: ../actions/finishopenidlogin.php:88 actions/finishopenidlogin.php:94
-#: actions/finishopenidlogin.php:116 actions/finishopenidlogin.php:115
-msgid ""
-"If you already have an account, login with your username and password to "
-"connect it to your OpenID."
+#: actions/editgroup.php:103 actions/editgroup.php:168
+#: actions/groupdesignsettings.php:104 actions/grouplogo.php:106
+msgid "You must be an admin to edit the group"
msgstr ""
-#: ../actions/openidsettings.php:45 actions/openidsettings.php:96
-msgid ""
-"If you want to add an OpenID to your account, enter it in the box below and "
-"click \"Add\"."
+#: actions/editgroup.php:154
+msgid "Use this form to edit the group."
msgstr ""
-#: ../actions/emailsettings.php:67 ../actions/smssettings.php:76
-#: actions/emailsettings.php:68 actions/smssettings.php:76
-#: actions/emailsettings.php:127 actions/smssettings.php:140
-#: actions/emailsettings.php:133 actions/smssettings.php:152
-msgid "Incoming email"
+#: actions/editgroup.php:201 actions/newgroup.php:145
+#, php-format
+msgid "description is too long (max %d chars)."
msgstr ""
-#: ../actions/emailsettings.php:283 actions/emailsettings.php:301
-#: actions/emailsettings.php:443 actions/emailsettings.php:450
-#: actions/smssettings.php:518 actions/smssettings.php:519
-#: actions/emailsettings.php:458 actions/smssettings.php:531
-msgid "Incoming email address removed."
+#: actions/editgroup.php:253
+msgid "Could not update group."
msgstr ""
-#: ../actions/password.php:69 actions/profilesettings.php:388
-#: actions/passwordsettings.php:153 actions/passwordsettings.php:158
-#: actions/passwordsettings.php:164
-msgid "Incorrect old password"
+#: actions/editgroup.php:269
+msgid "Options saved."
msgstr ""
-#: ../actions/login.php:67 actions/login.php:67 actions/facebookhome.php:131
-#: actions/login.php:132 actions/facebookhome.php:130 actions/login.php:114
-#: actions/facebookhome.php:129 actions/login.php:116 actions/login.php:143
-msgid "Incorrect username or password."
+#: actions/emailsettings.php:60
+msgid "Email Settings"
msgstr ""
-#: ../actions/recoverpassword.php:265 actions/recoverpassword.php:304
-#: actions/recoverpassword.php:322 actions/recoverpassword.php:325
-msgid ""
-"Instructions for recovering your password have been sent to the email "
-"address registered to your account."
+#: actions/emailsettings.php:71
+#, php-format
+msgid "Manage how you get email from %%site.name%%."
msgstr ""
-#: ../actions/updateprofile.php:114 actions/updateprofile.php:115
-#: actions/updateprofile.php:118 actions/updateprofile.php:120
-#, php-format
-msgid "Invalid avatar URL '%s'"
+#: actions/emailsettings.php:100
+msgid "Address"
msgstr ""
-#: ../actions/invite.php:55 actions/invite.php:62 actions/invite.php:70
-#: actions/invite.php:72
-#, php-format
-msgid "Invalid email address: %s"
+#: actions/emailsettings.php:105
+msgid "Current confirmed email address."
msgstr ""
-#: ../actions/updateprofile.php:98 actions/updateprofile.php:99
-#: actions/updateprofile.php:102 actions/updateprofile.php:104
-#, php-format
-msgid "Invalid homepage '%s'"
+#: actions/emailsettings.php:107 actions/emailsettings.php:140
+#: actions/imsettings.php:108 actions/smssettings.php:115
+#: actions/smssettings.php:158
+msgid "Remove"
msgstr ""
-#: ../actions/updateprofile.php:82 actions/updateprofile.php:83
-#: actions/updateprofile.php:86 actions/updateprofile.php:88
-#, php-format
-msgid "Invalid license URL '%s'"
+#: actions/emailsettings.php:113
+msgid ""
+"Awaiting confirmation on this address. Check your inbox (and spam box!) for "
+"a message with further instructions."
msgstr ""
-#: ../actions/postnotice.php:61 actions/postnotice.php:62
-#: actions/postnotice.php:66 actions/postnotice.php:84
-msgid "Invalid notice content"
+#: actions/emailsettings.php:117 actions/imsettings.php:120
+#: actions/smssettings.php:126
+msgid "Cancel"
msgstr ""
-#: ../actions/postnotice.php:67 actions/postnotice.php:68
-#: actions/postnotice.php:72
-msgid "Invalid notice uri"
+#: actions/emailsettings.php:121
+msgid "Email Address"
msgstr ""
-#: ../actions/postnotice.php:72 actions/postnotice.php:73
-#: actions/postnotice.php:77
-msgid "Invalid notice url"
+#: actions/emailsettings.php:123
+msgid "Email address, like \"UserName@example.org\""
msgstr ""
-#: ../actions/updateprofile.php:87 actions/updateprofile.php:88
-#: actions/updateprofile.php:91 actions/updateprofile.php:93
-#, php-format
-msgid "Invalid profile URL '%s'."
+#: actions/emailsettings.php:126 actions/imsettings.php:133
+#: actions/smssettings.php:145
+msgid "Add"
msgstr ""
-#: ../actions/remotesubscribe.php:96 actions/remotesubscribe.php:105
-#: actions/remotesubscribe.php:135 actions/remotesubscribe.php:159
-msgid "Invalid profile URL (bad format)"
+#: actions/emailsettings.php:133 actions/smssettings.php:152
+msgid "Incoming email"
msgstr ""
-#: ../actions/finishremotesubscribe.php:77
-#: actions/finishremotesubscribe.php:79 actions/finishremotesubscribe.php:80
-msgid "Invalid profile URL returned by server."
+#: actions/emailsettings.php:138 actions/smssettings.php:157
+msgid "Send email to this address to post new notices."
msgstr ""
-#: ../actions/avatarbynickname.php:37 actions/avatarbynickname.php:37
-#: actions/avatarbynickname.php:69
-msgid "Invalid size."
+#: actions/emailsettings.php:145 actions/smssettings.php:162
+msgid "Make a new email address for posting to; cancels the old one."
msgstr ""
-#: ../actions/finishopenidlogin.php:235 ../actions/register.php:93
-#: ../actions/register.php:111 actions/finishopenidlogin.php:241
-#: actions/register.php:103 actions/register.php:121
-#: actions/finishopenidlogin.php:279 actions/register.php:193
-#: actions/register.php:211 actions/finishopenidlogin.php:284
-#: actions/finishopenidlogin.php:307 actions/register.php:230
-#: actions/register.php:251 actions/register.php:237 actions/register.php:258
-#: actions/register.php:243 actions/register.php:264
-msgid "Invalid username or password."
+#: actions/emailsettings.php:148 actions/smssettings.php:164
+msgid "New"
msgstr ""
-#: ../actions/invite.php:79 actions/invite.php:86 actions/invite.php:102
-#: actions/invite.php:104 actions/invite.php:110
-msgid "Invitation(s) sent"
+#: actions/emailsettings.php:153 actions/imsettings.php:139
+#: actions/smssettings.php:169
+msgid "Preferences"
msgstr ""
-#: ../actions/invite.php:97 actions/invite.php:104 actions/invite.php:136
-#: actions/invite.php:138 actions/invite.php:144
-msgid "Invitation(s) sent to the following people:"
+#: actions/emailsettings.php:158
+msgid "Send me notices of new subscriptions through email."
msgstr ""
-#: ../lib/util.php:306 lib/util.php:322 lib/facebookaction.php:207
-#: lib/subgroupnav.php:103 lib/facebookaction.php:220 lib/action.php:429
-#: lib/facebookaction.php:221 lib/subgroupnav.php:105 lib/action.php:439
-msgid "Invite"
+#: actions/emailsettings.php:163
+msgid "Send me email when someone adds my notice as a favorite."
msgstr ""
-#: ../actions/invite.php:123 actions/invite.php:130 actions/invite.php:104
-#: actions/invite.php:106 actions/invite.php:112
-msgid "Invite new users"
+#: actions/emailsettings.php:169
+msgid "Send me email when someone sends me a private message."
msgstr ""
-#: ../lib/util.php:261 lib/util.php:277 lib/action.php:609 lib/action.php:706
-#: lib/action.php:756 lib/action.php:771
-#, php-format
-msgid ""
-"It runs the [StatusNet](http://status.net/) microblogging software, version %"
-"s, available under the [GNU Affero General Public License](http://www.fsf."
-"org/licensing/licenses/agpl-3.0.html)."
+#: actions/emailsettings.php:174
+msgid "Send me email when someone sends me an \"@-reply\"."
msgstr ""
-#: ../actions/imsettings.php:173 actions/imsettings.php:181
-#: actions/imsettings.php:296 actions/imsettings.php:302
-msgid "Jabber ID already belongs to another user."
+#: actions/emailsettings.php:179
+msgid "Allow friends to nudge me and send me an email."
msgstr ""
-#: ../actions/imsettings.php:62 actions/imsettings.php:63
-#: actions/imsettings.php:120 actions/imsettings.php:126
-#, php-format
-msgid ""
-"Jabber or GTalk address, like \"UserName@example.org\". First, make sure to "
-"add %s to your buddy list in your IM client or on GTalk."
+#: actions/emailsettings.php:185
+msgid "I want to post notices by email."
msgstr ""
-#: ../actions/profilesettings.php:57 actions/profilesettings.php:90
-#: actions/profilesettings.php:128 actions/profilesettings.php:129
-#: actions/profilesettings.php:144
-msgid "Language"
+#: actions/emailsettings.php:191
+msgid "Publish a MicroID for my email address."
msgstr ""
-#: ../actions/profilesettings.php:113 actions/profilesettings.php:228
-#: actions/profilesettings.php:217 actions/profilesettings.php:218
-#: actions/profilesettings.php:234
-msgid "Language is too long (max 50 chars)."
+#: actions/emailsettings.php:195 actions/imsettings.php:163
+#: actions/othersettings.php:126 actions/profilesettings.php:167
+#: actions/smssettings.php:181 actions/subscriptions.php:203
+#: actions/tagother.php:154 lib/designsettings.php:256
+#: lib/groupeditform.php:202
+msgid "Save"
msgstr ""
-#: ../actions/profilesettings.php:52 ../actions/register.php:173
-#: actions/profilesettings.php:85 actions/register.php:187
-#: actions/profilesettings.php:117 actions/register.php:408
-#: actions/showgroup.php:244 actions/showstream.php:271
-#: actions/tagother.php:113 lib/groupeditform.php:156 lib/grouplist.php:126
-#: lib/profilelist.php:125 actions/showgroup.php:246
-#: actions/showstream.php:264 actions/tagother.php:112 lib/profilelist.php:123
-#: actions/register.php:454 actions/showgroup.php:251
-#: actions/showstream.php:229 actions/userauthorization.php:128
-#: lib/groupeditform.php:171 lib/profilelist.php:185
-#: actions/profilesettings.php:132 actions/register.php:464
-#: actions/showgroup.php:256 actions/showstream.php:282
-#: actions/userauthorization.php:158 lib/groupeditform.php:177
-#: lib/profilelist.php:218 actions/register.php:470 lib/userprofile.php:164
-msgid "Location"
+#: actions/emailsettings.php:301 actions/imsettings.php:264
+#: actions/othersettings.php:180 actions/smssettings.php:284
+msgid "Preferences saved."
msgstr ""
-#: ../actions/profilesettings.php:104 ../actions/register.php:85
-#: ../actions/updateprofile.php:108 actions/profilesettings.php:219
-#: actions/register.php:92 actions/updateprofile.php:109
-#: actions/editgroup.php:201 actions/newgroup.php:152
-#: actions/profilesettings.php:208 actions/register.php:177
-#: actions/updateprofile.php:112 actions/updateprofile.php:114
-#: actions/editgroup.php:203 actions/newgroup.php:153
-#: actions/profilesettings.php:209 actions/register.php:214
-#: actions/apigroupcreate.php:272 actions/editgroup.php:204
-#: actions/newgroup.php:148 actions/profilesettings.php:225
-#: actions/register.php:221 actions/register.php:227
-msgid "Location is too long (max 255 chars)."
+#: actions/emailsettings.php:319
+msgid "No email address."
msgstr ""
-#: ../actions/login.php:97 ../actions/login.php:106
-#: ../actions/openidlogin.php:68 ../lib/util.php:310 actions/login.php:97
-#: actions/login.php:106 actions/openidlogin.php:77 lib/util.php:326
-#: actions/facebooklogin.php:93 actions/login.php:186 actions/login.php:239
-#: actions/openidlogin.php:112 lib/action.php:335 lib/facebookaction.php:288
-#: lib/facebookaction.php:315 lib/logingroupnav.php:75 actions/login.php:169
-#: actions/login.php:222 actions/openidlogin.php:121 lib/action.php:412
-#: lib/facebookaction.php:293 lib/facebookaction.php:319 lib/action.php:443
-#: lib/facebookaction.php:295 lib/facebookaction.php:321 actions/login.php:177
-#: actions/login.php:230 lib/action.php:453 lib/logingroupnav.php:79
-#: actions/login.php:204 actions/login.php:257
-#, php-format
-msgid "Login"
+#: actions/emailsettings.php:326
+msgid "Cannot normalize that email address"
msgstr ""
-#: ../actions/openidlogin.php:44 actions/openidlogin.php:52
-#: actions/openidlogin.php:62 actions/openidlogin.php:70
-#, php-format
-msgid "Login with an [OpenID](%%doc.openid%%) account."
+#: actions/emailsettings.php:330
+msgid "Not a valid email address"
msgstr ""
-#: ../actions/login.php:126 actions/login.php:251
-#, php-format
-msgid ""
-"Login with your username and password. Don't have a username yet? [Register]"
-"(%%action.register%%) a new account, or try [OpenID](%%action.openidlogin%"
-"%). "
+#: actions/emailsettings.php:333
+msgid "That is already your email address."
msgstr ""
-#: ../lib/util.php:308 lib/util.php:324 lib/action.php:332 lib/action.php:409
-#: lib/action.php:435 lib/action.php:445
-msgid "Logout"
+#: actions/emailsettings.php:336
+msgid "That email address already belongs to another user."
msgstr ""
-#: ../actions/register.php:166 actions/register.php:180
-#: actions/register.php:393 actions/register.php:439 actions/register.php:443
-#: actions/register.php:449
-msgid "Longer name, preferably your \"real\" name"
+#: actions/emailsettings.php:352 actions/imsettings.php:317
+#: actions/smssettings.php:337
+msgid "Couldn't insert confirmation code."
msgstr ""
-#: ../actions/login.php:110 actions/login.php:110 actions/login.php:245
-#: lib/facebookaction.php:320 actions/login.php:228 lib/facebookaction.php:325
-#: lib/facebookaction.php:327 actions/login.php:236 actions/login.php:263
-msgid "Lost or forgotten password?"
+#: actions/emailsettings.php:358
+msgid ""
+"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."
msgstr ""
-#: ../actions/emailsettings.php:80 ../actions/smssettings.php:89
-#: actions/emailsettings.php:81 actions/smssettings.php:89
-#: actions/emailsettings.php:139 actions/smssettings.php:150
-#: actions/emailsettings.php:145 actions/smssettings.php:162
-msgid "Make a new email address for posting to; cancels the old one."
+#: actions/emailsettings.php:378 actions/imsettings.php:351
+#: actions/smssettings.php:370
+msgid "No pending confirmation to cancel."
msgstr ""
-#: ../actions/emailsettings.php:27 actions/emailsettings.php:27
-#: actions/emailsettings.php:71
-#, php-format
-msgid "Manage how you get email from %%site.name%%."
+#: actions/emailsettings.php:382 actions/imsettings.php:355
+msgid "That is the wrong IM address."
msgstr ""
-#: ../actions/showstream.php:300 actions/showstream.php:315
-#: actions/showstream.php:480 lib/profileaction.php:182
-msgid "Member since"
+#: actions/emailsettings.php:394 actions/imsettings.php:367
+#: actions/smssettings.php:386
+msgid "Confirmation cancelled."
msgstr ""
-#: ../actions/userrss.php:70 actions/userrss.php:67 actions/userrss.php:72
-#: actions/userrss.php:93
-#, php-format
-msgid "Microblog by %s"
+#: actions/emailsettings.php:412
+msgid "That is not your email address."
msgstr ""
-#: ../actions/smssettings.php:304 actions/smssettings.php:464
-#: actions/smssettings.php:476
-#, php-format
-msgid ""
-"Mobile carrier for your phone. If you know a carrier that accepts SMS over "
-"email but isn't listed here, send email to let us know at %s."
+#: actions/emailsettings.php:431 actions/imsettings.php:408
+#: actions/smssettings.php:425
+msgid "The address was removed."
msgstr ""
-#: ../actions/finishopenidlogin.php:79 ../actions/register.php:188
-#: actions/finishopenidlogin.php:85 actions/register.php:202
-#: actions/finishopenidlogin.php:107 actions/register.php:429
-#: actions/register.php:430 actions/finishopenidlogin.php:106
-#: actions/register.php:477 actions/register.php:487 actions/register.php:493
-msgid "My text and files are available under "
+#: actions/emailsettings.php:445 actions/smssettings.php:518
+msgid "No incoming email address."
msgstr ""
-#: ../actions/emailsettings.php:82 ../actions/smssettings.php:91
-#: actions/emailsettings.php:83 actions/smssettings.php:91
-#: actions/emailsettings.php:142 actions/smssettings.php:152
-#: actions/emailsettings.php:148 actions/smssettings.php:164
-msgid "New"
+#: actions/emailsettings.php:455 actions/emailsettings.php:477
+#: actions/smssettings.php:528 actions/smssettings.php:552
+msgid "Couldn't update user record."
msgstr ""
-#: ../lib/mail.php:144 lib/mail.php:144 lib/mail.php:286 lib/mail.php:285
-#, php-format
-msgid "New email address for posting to %s"
+#: actions/emailsettings.php:458 actions/smssettings.php:531
+msgid "Incoming email address removed."
msgstr ""
-#: ../actions/emailsettings.php:297 actions/emailsettings.php:315
-#: actions/emailsettings.php:465 actions/emailsettings.php:472
-#: actions/smssettings.php:542 actions/smssettings.php:543
#: actions/emailsettings.php:480 actions/smssettings.php:555
msgid "New incoming email address added."
msgstr ""
-#: ../actions/finishopenidlogin.php:71 actions/finishopenidlogin.php:77
-#: actions/finishopenidlogin.php:99 actions/finishopenidlogin.php:98
-msgid "New nickname"
+#: actions/favorited.php:65 lib/popularnoticesection.php:87
+#: lib/publicgroupnav.php:93
+msgid "Popular notices"
msgstr ""
-#: ../actions/newnotice.php:87 actions/newnotice.php:96
-#: actions/newnotice.php:68 actions/newnotice.php:69
-msgid "New notice"
+#: actions/favorited.php:67
+#, php-format
+msgid "Popular notices, page %d"
msgstr ""
-#: ../actions/password.php:41 ../actions/recoverpassword.php:179
-#: actions/profilesettings.php:180 actions/recoverpassword.php:185
-#: actions/passwordsettings.php:101 actions/recoverpassword.php:219
-#: actions/recoverpassword.php:232 actions/passwordsettings.php:107
-#: actions/recoverpassword.php:235
-msgid "New password"
+#: actions/favorited.php:79
+msgid "The most popular notices on the site right now."
msgstr ""
-#: ../actions/recoverpassword.php:314 actions/recoverpassword.php:361
-#: actions/recoverpassword.php:379 actions/recoverpassword.php:382
-msgid "New password successfully saved. You are now logged in."
+#: actions/favorited.php:150
+msgid "Favorite notices appear on this page but no one has favorited one yet."
msgstr ""
-#: ../actions/login.php:101 ../actions/profilesettings.php:41
-#: ../actions/register.php:151 actions/login.php:101
-#: actions/profilesettings.php:74 actions/register.php:165
-#: actions/login.php:228 actions/profilesettings.php:98
-#: actions/register.php:367 actions/showgroup.php:224
-#: actions/showstream.php:251 actions/tagother.php:95
-#: lib/facebookaction.php:308 lib/groupeditform.php:137 actions/login.php:211
-#: actions/showgroup.php:226 actions/showstream.php:244
-#: actions/tagother.php:94 lib/facebookaction.php:312 actions/register.php:413
-#: actions/showgroup.php:231 actions/showstream.php:209
-#: lib/facebookaction.php:314 lib/groupeditform.php:152 actions/login.php:219
-#: actions/profilesettings.php:106 actions/register.php:417
-#: actions/showgroup.php:236 actions/showstream.php:249 actions/login.php:246
-#: actions/register.php:423 lib/userprofile.php:131
-msgid "Nickname"
+#: actions/favorited.php:153
+msgid ""
+"Be the first to add a notice to your favorites by clicking the fave button "
+"next to any notice you like."
msgstr ""
-#: ../actions/finishopenidlogin.php:175 ../actions/profilesettings.php:110
-#: ../actions/register.php:69 actions/finishopenidlogin.php:181
-#: actions/profilesettings.php:225 actions/register.php:76
-#: actions/editgroup.php:183 actions/finishopenidlogin.php:215
-#: actions/newgroup.php:134 actions/profilesettings.php:214
-#: actions/register.php:159 actions/editgroup.php:185
-#: actions/finishopenidlogin.php:231 actions/newgroup.php:135
-#: actions/profilesettings.php:215 actions/register.php:196
-#: actions/apigroupcreate.php:221 actions/editgroup.php:186
-#: actions/newgroup.php:130 actions/profilesettings.php:231
-#: actions/register.php:202 actions/register.php:208
-msgid "Nickname already in use. Try another one."
+#: actions/favorited.php:156
+#, php-format
+msgid ""
+"Why not [register an account](%%action.register%%) and be the first to add a "
+"notice to your favorites!"
msgstr ""
-#: ../actions/finishopenidlogin.php:165 ../actions/profilesettings.php:88
-#: ../actions/register.php:67 ../actions/updateprofile.php:77
-#: actions/finishopenidlogin.php:171 actions/profilesettings.php:203
-#: actions/register.php:74 actions/updateprofile.php:78
-#: actions/finishopenidlogin.php:205 actions/profilesettings.php:192
-#: actions/updateprofile.php:81 actions/editgroup.php:179
-#: actions/newgroup.php:130 actions/register.php:156
-#: actions/updateprofile.php:83 actions/editgroup.php:181
-#: actions/finishopenidlogin.php:221 actions/newgroup.php:131
-#: actions/profilesettings.php:193 actions/register.php:193
-#: actions/apigroupcreate.php:212 actions/editgroup.php:182
-#: actions/newgroup.php:126 actions/profilesettings.php:208
-#: actions/register.php:199 actions/register.php:205
-msgid "Nickname must have only lowercase letters and numbers and no spaces."
+#: actions/favoritesrss.php:111 actions/showfavorites.php:77
+#: lib/personalgroupnav.php:115
+#, php-format
+msgid "%s's favorite notices"
msgstr ""
-#: ../actions/finishopenidlogin.php:170 actions/finishopenidlogin.php:176
-#: actions/finishopenidlogin.php:210 actions/finishopenidlogin.php:226
-msgid "Nickname not allowed."
+#: actions/favoritesrss.php:115
+#, php-format
+msgid "Updates favored by %1$s on %2$s!"
msgstr ""
-#: ../actions/remotesubscribe.php:72 actions/remotesubscribe.php:81
-#: actions/remotesubscribe.php:106 actions/remotesubscribe.php:130
-msgid "Nickname of the user you want to follow"
+#: actions/favor.php:79
+msgid "This notice is already a favorite!"
msgstr ""
-#: ../actions/recoverpassword.php:162 actions/recoverpassword.php:167
-#: actions/recoverpassword.php:186 actions/recoverpassword.php:191
-msgid "Nickname or email"
+#: actions/favor.php:92 lib/disfavorform.php:140
+msgid "Disfavor favorite"
msgstr ""
-#: ../actions/deletenotice.php:59 actions/deletenotice.php:60
-#: actions/block.php:147 actions/deletenotice.php:118
-#: actions/deletenotice.php:116 actions/block.php:149
-#: actions/deletenotice.php:115 actions/groupblock.php:176
-#: actions/deletenotice.php:145
-msgid "No"
+#: actions/featured.php:69 lib/featureduserssection.php:87
+#: lib/publicgroupnav.php:89
+msgid "Featured users"
msgstr ""
-#: ../actions/imsettings.php:156 actions/imsettings.php:164
-#: actions/imsettings.php:279 actions/imsettings.php:285
-msgid "No Jabber ID."
+#: actions/featured.php:71
+#, php-format
+msgid "Featured users, page %d"
msgstr ""
-#: ../actions/userauthorization.php:129 actions/userauthorization.php:136
-#: actions/userauthorization.php:153 actions/userauthorization.php:192
-#: actions/userauthorization.php:225
-msgid "No authorization request!"
+#: actions/featured.php:99
+#, php-format
+msgid "A selection of some of the great users on %s"
msgstr ""
-#: ../actions/smssettings.php:181 actions/smssettings.php:189
-#: actions/smssettings.php:299 actions/smssettings.php:311
-msgid "No carrier selected."
+#: actions/file.php:34
+msgid "No notice id"
msgstr ""
-#: ../actions/smssettings.php:316 actions/smssettings.php:324
-#: actions/smssettings.php:486 actions/smssettings.php:498
-msgid "No code entered"
+#: actions/file.php:38
+msgid "No notice"
msgstr ""
-#: ../actions/confirmaddress.php:33 actions/confirmaddress.php:33
-#: actions/confirmaddress.php:75
-msgid "No confirmation code."
+#: actions/file.php:42
+msgid "No attachments"
msgstr ""
-#: ../actions/newnotice.php:44 actions/newmessage.php:53
-#: actions/newnotice.php:44 classes/Command.php:197 actions/newmessage.php:109
-#: actions/newnotice.php:126 classes/Command.php:223
-#: actions/newmessage.php:142 actions/newnotice.php:131 lib/command.php:223
-#: actions/newnotice.php:162 lib/command.php:216 actions/newmessage.php:144
-#: actions/newnotice.php:136 lib/command.php:351 lib/command.php:424
-msgid "No content!"
+#: actions/file.php:51
+msgid "No uploaded attachments"
msgstr ""
-#: ../actions/emailsettings.php:174 actions/emailsettings.php:192
-#: actions/emailsettings.php:304 actions/emailsettings.php:311
-#: actions/emailsettings.php:319
-msgid "No email address."
+#: actions/finishremotesubscribe.php:69
+msgid "Not expecting this response!"
msgstr ""
-#: ../actions/userbyid.php:32 actions/userbyid.php:32 actions/userbyid.php:70
-msgid "No id."
+#: actions/finishremotesubscribe.php:80
+msgid "User being listened to does not exist."
msgstr ""
-#: ../actions/emailsettings.php:271 actions/emailsettings.php:289
-#: actions/emailsettings.php:430 actions/emailsettings.php:437
-#: actions/smssettings.php:505 actions/smssettings.php:506
-#: actions/emailsettings.php:445 actions/smssettings.php:518
-msgid "No incoming email address."
+#: actions/finishremotesubscribe.php:87 actions/remotesubscribe.php:59
+msgid "You can use the local subscription!"
msgstr ""
-#: ../actions/finishremotesubscribe.php:65
-#: actions/finishremotesubscribe.php:67 actions/finishremotesubscribe.php:68
-msgid "No nickname provided by remote server."
+#: actions/finishremotesubscribe.php:96
+msgid "That user has blocked you from subscribing."
msgstr ""
-#: ../actions/avatarbynickname.php:27 actions/avatarbynickname.php:27
-#: actions/avatarbynickname.php:59 actions/leavegroup.php:81
-#: actions/leavegroup.php:76
-msgid "No nickname."
-msgstr ""
+#: actions/finishremotesubscribe.php:106
+msgid "You are not authorized."
+msgstr ""
-#: ../actions/emailsettings.php:222 ../actions/imsettings.php:206
-#: ../actions/smssettings.php:229 actions/emailsettings.php:240
-#: actions/imsettings.php:214 actions/smssettings.php:237
-#: actions/emailsettings.php:363 actions/imsettings.php:345
-#: actions/smssettings.php:358 actions/emailsettings.php:370
-#: actions/emailsettings.php:378 actions/imsettings.php:351
-#: actions/smssettings.php:370
-msgid "No pending confirmation to cancel."
+#: actions/finishremotesubscribe.php:109
+msgid "Could not convert request token to access token."
msgstr ""
-#: ../actions/smssettings.php:176 actions/smssettings.php:184
-#: actions/smssettings.php:294 actions/smssettings.php:306
-msgid "No phone number."
+#: actions/finishremotesubscribe.php:114
+msgid "Remote service uses unknown version of OMB protocol."
msgstr ""
-#: ../actions/finishremotesubscribe.php:72
-#: actions/finishremotesubscribe.php:74 actions/finishremotesubscribe.php:75
-msgid "No profile URL returned by server."
+#: actions/finishremotesubscribe.php:133 lib/oauthstore.php:306
+msgid "Error updating remote profile"
msgstr ""
-#: ../actions/recoverpassword.php:226 actions/recoverpassword.php:232
-#: actions/recoverpassword.php:266 actions/recoverpassword.php:284
-#: actions/recoverpassword.php:287
-msgid "No registered email address for that user."
+#: actions/foafgroup.php:44 actions/foafgroup.php:62 actions/groupblock.php:86
+#: actions/groupunblock.php:86 actions/leavegroup.php:83
+#: actions/makeadmin.php:86 lib/command.php:212 lib/command.php:263
+msgid "No such group."
msgstr ""
-#: ../actions/userauthorization.php:49 actions/userauthorization.php:55
-#: actions/userauthorization.php:57
-msgid "No request found!"
+#: actions/getfile.php:75
+msgid "No such file."
msgstr ""
-#: ../actions/noticesearch.php:64 ../actions/peoplesearch.php:64
-#: actions/noticesearch.php:69 actions/peoplesearch.php:69
-#: actions/groupsearch.php:81 actions/noticesearch.php:104
-#: actions/peoplesearch.php:85 actions/noticesearch.php:117
-msgid "No results"
+#: actions/getfile.php:79
+msgid "Cannot read file."
msgstr ""
-#: ../actions/avatarbynickname.php:32 actions/avatarbynickname.php:32
-#: actions/avatarbynickname.php:64
-msgid "No size."
+#: actions/groupblock.php:81 actions/groupunblock.php:81
+#: actions/makeadmin.php:81
+msgid "No group specified."
msgstr ""
-#: ../actions/twitapistatuses.php:595 actions/twitapifavorites.php:136
-#: actions/twitapistatuses.php:520 actions/twitapifavorites.php:112
-#: actions/twitapistatuses.php:446 actions/twitapifavorites.php:118
-#: actions/twitapistatuses.php:470 actions/twitapifavorites.php:169
-#: actions/twitapistatuses.php:426 actions/apifavoritecreate.php:108
-#: actions/apifavoritedestroy.php:109 actions/apistatusesdestroy.php:113
-msgid "No status found with that ID."
+#: actions/groupblock.php:91
+msgid "Only an admin can block group members."
msgstr ""
-#: ../actions/twitapistatuses.php:555 actions/twitapistatuses.php:478
-#: actions/twitapistatuses.php:418 actions/twitapistatuses.php:442
-#: actions/twitapistatuses.php:399 actions/apistatusesshow.php:144
-msgid "No status with that ID found."
+#: actions/groupblock.php:95
+msgid "User is already blocked from group."
msgstr ""
-#: ../actions/openidsettings.php:135 actions/openidsettings.php:144
-#: actions/openidsettings.php:222
-msgid "No such OpenID."
+#: actions/groupblock.php:100
+msgid "User is not a member of group."
msgstr ""
-#: ../actions/doc.php:29 actions/doc.php:29 actions/doc.php:64
-#: actions/doc.php:69
-msgid "No such document."
+#: actions/groupblock.php:136 actions/groupmembers.php:314
+msgid "Block user from group"
msgstr ""
-#: ../actions/shownotice.php:32 ../actions/shownotice.php:83
-#: ../lib/deleteaction.php:30 actions/shownotice.php:32
-#: actions/shownotice.php:83 lib/deleteaction.php:30 actions/shownotice.php:87
-#: lib/deleteaction.php:51 actions/deletenotice.php:52
-#: actions/shownotice.php:92
-msgid "No such notice."
+#: actions/groupblock.php:155
+#, php-format
+msgid ""
+"Are you sure you want to block user \"%s\" from the group \"%s\"? They will "
+"be removed from the group, unable to post, and unable to subscribe to the "
+"group in the future."
msgstr ""
-#: ../actions/recoverpassword.php:56 actions/recoverpassword.php:56
-#: actions/recoverpassword.php:62
-msgid "No such recovery code."
+#: actions/groupblock.php:193
+msgid "Database error blocking user from group."
msgstr ""
-#: ../actions/postnotice.php:56 actions/postnotice.php:57
-#: actions/postnotice.php:60
-msgid "No such subscription"
-msgstr ""
-
-#: ../actions/all.php:34 ../actions/allrss.php:35
-#: ../actions/avatarbynickname.php:43 ../actions/foaf.php:40
-#: ../actions/remotesubscribe.php:84 ../actions/remotesubscribe.php:91
-#: ../actions/replies.php:57 ../actions/repliesrss.php:35
-#: ../actions/showstream.php:110 ../actions/userbyid.php:36
-#: ../actions/userrss.php:35 ../actions/xrds.php:35 ../lib/gallery.php:57
-#: ../lib/subs.php:33 ../lib/subs.php:82 actions/all.php:34
-#: actions/allrss.php:35 actions/avatarbynickname.php:43
-#: actions/favoritesrss.php:35 actions/foaf.php:40 actions/ical.php:31
-#: actions/remotesubscribe.php:93 actions/remotesubscribe.php:100
-#: actions/replies.php:57 actions/repliesrss.php:35
-#: actions/showfavorites.php:34 actions/showstream.php:110
-#: actions/userbyid.php:36 actions/userrss.php:35 actions/xrds.php:35
-#: classes/Command.php:120 classes/Command.php:162 classes/Command.php:203
-#: classes/Command.php:237 lib/gallery.php:62 lib/mailbox.php:36
-#: lib/subs.php:33 lib/subs.php:95 actions/all.php:53 actions/allrss.php:66
-#: actions/avatarbynickname.php:75 actions/favoritesrss.php:64
-#: actions/foaf.php:41 actions/remotesubscribe.php:123
-#: actions/remotesubscribe.php:130 actions/replies.php:73
-#: actions/repliesrss.php:38 actions/showfavorites.php:105
-#: actions/showstream.php:100 actions/userbyid.php:74
-#: actions/usergroups.php:92 actions/userrss.php:38 actions/xrds.php:73
-#: classes/Command.php:140 classes/Command.php:185 classes/Command.php:234
-#: classes/Command.php:271 lib/galleryaction.php:60 lib/mailbox.php:82
-#: lib/subs.php:34 lib/subs.php:109 actions/all.php:56 actions/allrss.php:68
-#: actions/favoritesrss.php:74 lib/command.php:140 lib/command.php:185
-#: lib/command.php:234 lib/command.php:271 lib/mailbox.php:84
-#: actions/all.php:38 actions/foaf.php:58 actions/replies.php:72
-#: actions/usergroups.php:91 actions/userrss.php:39 lib/command.php:133
-#: lib/command.php:178 lib/command.php:227 lib/command.php:264
-#: lib/galleryaction.php:59 lib/profileaction.php:77 lib/subs.php:112
-#: actions/all.php:74 actions/remotesubscribe.php:145 actions/xrds.php:71
-#: lib/command.php:163 lib/command.php:311 lib/command.php:364
-#: lib/command.php:411 lib/command.php:466
-msgid "No such user."
+#: actions/groupbyid.php:74
+msgid "No ID"
msgstr ""
-#: ../actions/recoverpassword.php:211 actions/recoverpassword.php:217
-#: actions/recoverpassword.php:251 actions/recoverpassword.php:269
-#: actions/recoverpassword.php:272
-msgid "No user with that email address or username."
+#: actions/groupdesignsettings.php:68
+msgid "You must be logged in to edit a group."
msgstr ""
-#: ../lib/gallery.php:80 lib/gallery.php:85
-msgid "Nobody to show!"
+#: actions/groupdesignsettings.php:141
+msgid "Group design"
msgstr ""
-#: ../actions/recoverpassword.php:60 actions/recoverpassword.php:60
-#: actions/recoverpassword.php:66
-msgid "Not a recovery code."
+#: actions/groupdesignsettings.php:152
+msgid ""
+"Customize the way your group looks with a background image and a colour "
+"palette of your choice."
msgstr ""
-#: ../scripts/maildaemon.php:50 scripts/maildaemon.php:50
-#: scripts/maildaemon.php:53 scripts/maildaemon.php:52
-msgid "Not a registered user."
+#: actions/groupdesignsettings.php:262 actions/userdesignsettings.php:186
+#: lib/designsettings.php:434 lib/designsettings.php:464
+msgid "Couldn't update your design."
msgstr ""
-#: ../lib/twitterapi.php:226 ../lib/twitterapi.php:247
-#: ../lib/twitterapi.php:332 lib/twitterapi.php:391 lib/twitterapi.php:418
-#: lib/twitterapi.php:502 lib/twitterapi.php:448 lib/twitterapi.php:476
-#: lib/twitterapi.php:566 lib/twitterapi.php:483 lib/twitterapi.php:511
-#: lib/twitterapi.php:601 lib/twitterapi.php:620 lib/twitterapi.php:648
-#: lib/twitterapi.php:741 actions/oembed.php:181 actions/oembed.php:200
-#: lib/api.php:954 lib/api.php:982 lib/api.php:1092 lib/api.php:963
-#: lib/api.php:991 lib/api.php:1101
-msgid "Not a supported data format."
+#: actions/groupdesignsettings.php:286 actions/groupdesignsettings.php:296
+#: actions/userdesignsettings.php:210 actions/userdesignsettings.php:220
+#: actions/userdesignsettings.php:263 actions/userdesignsettings.php:273
+msgid "Unable to save your design settings!"
msgstr ""
-#: ../actions/imsettings.php:167 actions/imsettings.php:175
-#: actions/imsettings.php:290 actions/imsettings.php:296
-msgid "Not a valid Jabber ID"
+#: actions/groupdesignsettings.php:307 actions/userdesignsettings.php:231
+msgid "Design preferences saved."
msgstr ""
-#: ../lib/openid.php:131 lib/openid.php:131 lib/openid.php:140
-#: lib/openid.php:143
-msgid "Not a valid OpenID."
+#: actions/grouplogo.php:139 actions/grouplogo.php:192
+msgid "Group logo"
msgstr ""
-#: ../actions/emailsettings.php:185 actions/emailsettings.php:203
-#: actions/emailsettings.php:315 actions/emailsettings.php:322
-#: actions/emailsettings.php:330
-msgid "Not a valid email address"
+#: actions/grouplogo.php:150
+#, php-format
+msgid ""
+"You can upload a logo image for your group. The maximum file size is %s."
msgstr ""
-#: ../actions/register.php:63 actions/register.php:70 actions/register.php:152
-#: actions/register.php:189 actions/register.php:195 actions/register.php:201
-msgid "Not a valid email address."
+#: actions/grouplogo.php:362
+msgid "Pick a square area of the image to be the logo."
msgstr ""
-#: ../actions/profilesettings.php:91 ../actions/register.php:71
-#: actions/profilesettings.php:206 actions/register.php:78
-#: actions/editgroup.php:186 actions/newgroup.php:137
-#: actions/profilesettings.php:195 actions/register.php:161
-#: actions/editgroup.php:188 actions/newgroup.php:138
-#: actions/profilesettings.php:196 actions/register.php:198
-#: actions/apigroupcreate.php:228 actions/editgroup.php:189
-#: actions/newgroup.php:133 actions/profilesettings.php:211
-#: actions/register.php:204 actions/register.php:210
-msgid "Not a valid nickname."
+#: actions/grouplogo.php:396
+msgid "Logo updated."
msgstr ""
-#: ../actions/remotesubscribe.php:120 actions/remotesubscribe.php:129
-#: actions/remotesubscribe.php:159
-msgid "Not a valid profile URL (incorrect services)."
+#: actions/grouplogo.php:398
+msgid "Failed updating logo."
msgstr ""
-#: ../actions/remotesubscribe.php:113 actions/remotesubscribe.php:122
-#: actions/remotesubscribe.php:152
-msgid "Not a valid profile URL (no XRDS defined)."
+#: actions/groupmembers.php:93 lib/groupnav.php:91
+#, php-format
+msgid "%s group members"
msgstr ""
-#: ../actions/remotesubscribe.php:104 actions/remotesubscribe.php:113
-#: actions/remotesubscribe.php:143
-msgid "Not a valid profile URL (no YADIS document)."
+#: actions/groupmembers.php:96
+#, php-format
+msgid "%s group members, page %d"
msgstr ""
-#: ../actions/avatar.php:95 actions/profilesettings.php:332
-#: lib/imagefile.php:87 lib/imagefile.php:90 lib/imagefile.php:91
-#: lib/imagefile.php:96
-msgid "Not an image or corrupt file."
+#: actions/groupmembers.php:111
+msgid "A list of the users in this group."
msgstr ""
-#: ../actions/finishremotesubscribe.php:51
-#: actions/finishremotesubscribe.php:53 actions/finishremotesubscribe.php:54
-msgid "Not authorized."
+#: actions/groupmembers.php:175 lib/groupnav.php:106
+msgid "Admin"
msgstr ""
-#: ../actions/finishremotesubscribe.php:38
-#: actions/finishremotesubscribe.php:38 actions/finishremotesubscribe.php:40
-#: actions/finishremotesubscribe.php:69
-msgid "Not expecting this response!"
+#: actions/groupmembers.php:346 lib/blockform.php:153
+msgid "Block"
msgstr ""
-#: ../actions/twitapistatuses.php:422 actions/twitapistatuses.php:361
-#: actions/twitapistatuses.php:309 actions/twitapistatuses.php:327
-#: actions/twitapistatuses.php:284 actions/apistatusesupdate.php:186
-#: actions/apistatusesupdate.php:193
-msgid "Not found"
+#: actions/groupmembers.php:346 lib/blockform.php:123 lib/blockform.php:153
+msgid "Block this user"
msgstr ""
-#: ../actions/finishaddopenid.php:29 ../actions/logout.php:33
-#: ../actions/newnotice.php:29 ../actions/subscribe.php:28
-#: ../actions/unsubscribe.php:25 ../lib/deleteaction.php:38
-#: ../lib/settingsaction.php:27 actions/disfavor.php:29 actions/favor.php:30
-#: actions/finishaddopenid.php:29 actions/logout.php:33
-#: actions/newmessage.php:28 actions/newnotice.php:29 actions/subscribe.php:28
-#: actions/unsubscribe.php:25 lib/deleteaction.php:38
-#: lib/settingsaction.php:27 actions/block.php:59 actions/disfavor.php:61
-#: actions/favor.php:64 actions/finishaddopenid.php:67 actions/logout.php:71
-#: actions/newmessage.php:83 actions/newnotice.php:90 actions/nudge.php:63
-#: actions/subedit.php:31 actions/subscribe.php:30 actions/unblock.php:60
-#: actions/unsubscribe.php:27 lib/deleteaction.php:66
-#: lib/settingsaction.php:72 actions/newmessage.php:87 actions/favor.php:62
-#: actions/groupblock.php:61 actions/groupunblock.php:61
-#: actions/makeadmin.php:61 actions/newnotice.php:88
-#: actions/deletenotice.php:67 actions/logout.php:69 actions/newnotice.php:89
-#: actions/unsubscribe.php:52
-msgid "Not logged in."
+#: actions/groupmembers.php:441
+msgid "Make user an admin of the group"
msgstr ""
-#: ../lib/subs.php:91 lib/subs.php:104 lib/subs.php:122 lib/subs.php:124
-msgid "Not subscribed!."
+#: actions/groupmembers.php:473
+msgid "Make Admin"
msgstr ""
-#: ../actions/opensearch.php:35 actions/opensearch.php:35
-#: actions/opensearch.php:67
-msgid "Notice Search"
+#: actions/groupmembers.php:473
+msgid "Make this user an admin"
+msgstr ""
+
+#: actions/grouprss.php:133
+#, php-format
+msgid "Updates from members of %1$s on %2$s!"
msgstr ""
-#: ../actions/showstream.php:82 actions/showstream.php:82
-#: actions/showstream.php:180 actions/showstream.php:187
-#: actions/showstream.php:192
+#: actions/groupsearch.php:52
#, php-format
-msgid "Notice feed for %s"
+msgid ""
+"Search for groups on %%site.name%% by their name, location, or description. "
+"Separate the terms by spaces; they must be 3 characters or more."
msgstr ""
-#: ../actions/shownotice.php:39 actions/shownotice.php:39
-#: actions/shownotice.php:94 actions/oembed.php:79 actions/shownotice.php:100
-msgid "Notice has no profile"
+#: actions/groupsearch.php:58
+msgid "Group search"
msgstr ""
-#: ../actions/showstream.php:316 actions/showstream.php:331
-#: actions/showstream.php:504 lib/facebookaction.php:477 lib/mailbox.php:116
-#: lib/noticelist.php:87 lib/facebookaction.php:581 lib/mailbox.php:118
-#: actions/conversation.php:149 lib/facebookaction.php:572
-#: lib/profileaction.php:206 actions/conversation.php:154
-msgid "Notices"
+#: actions/groupsearch.php:79 actions/noticesearch.php:117
+#: actions/peoplesearch.php:83
+msgid "No results."
msgstr ""
-#: ../actions/tag.php:35 ../actions/tag.php:81 actions/tag.php:35
-#: actions/tag.php:81 actions/tag.php:41 actions/tag.php:49 actions/tag.php:57
-#: actions/twitapitags.php:69 actions/apitimelinetag.php:101
-#: actions/tag.php:66
+#: actions/groupsearch.php:82
#, php-format
-msgid "Notices tagged with %s"
+msgid ""
+"If you can't find the group you're looking for, you can [create it](%%action."
+"newgroup%%) yourself."
msgstr ""
-#: ../actions/password.php:39 actions/profilesettings.php:178
-#: actions/passwordsettings.php:97 actions/passwordsettings.php:103
-msgid "Old password"
+#: actions/groupsearch.php:85
+#, php-format
+msgid ""
+"Why not [register an account](%%action.register%%) and [create the group](%%"
+"action.newgroup%%) yourself!"
msgstr ""
-#: ../lib/settingsaction.php:96 ../lib/util.php:314 lib/settingsaction.php:90
-#: lib/util.php:330 lib/accountsettingsaction.php:116 lib/action.php:341
-#: lib/logingroupnav.php:81 lib/action.php:418
-msgid "OpenID"
+#: actions/groups.php:62 lib/profileaction.php:220 lib/publicgroupnav.php:81
+#: lib/subgroupnav.php:98
+msgid "Groups"
msgstr ""
-#: ../actions/finishopenidlogin.php:61 actions/finishopenidlogin.php:66
-#: actions/finishopenidlogin.php:73 actions/finishopenidlogin.php:72
-msgid "OpenID Account Setup"
+#: actions/groups.php:64
+#, php-format
+msgid "Groups, page %d"
msgstr ""
-#: ../lib/openid.php:180 lib/openid.php:180 lib/openid.php:266
-#: lib/openid.php:269
-msgid "OpenID Auto-Submit"
+#: actions/groups.php:90
+#, php-format
+msgid ""
+"%%%%site.name%%%% groups let you find and talk with users of similar "
+"interests. After you join a group you can send messages to all other members "
+"using the syntax \"!groupname\". Are you not seeing any groups you like? Try "
+"[searching for one](%%%%action.groupsearch%%%%) or [start your own](%%%%"
+"action.newgroup%%%%)!"
msgstr ""
-#: ../actions/finishaddopenid.php:99 ../actions/finishopenidlogin.php:140
-#: ../actions/openidlogin.php:60 actions/finishaddopenid.php:99
-#: actions/finishopenidlogin.php:146 actions/openidlogin.php:68
-#: actions/finishaddopenid.php:170 actions/openidlogin.php:80
-#: actions/openidlogin.php:89
-msgid "OpenID Login"
+#: actions/groups.php:108 actions/usergroups.php:124 lib/groupeditform.php:122
+msgid "Create a new group"
msgstr ""
-#: ../actions/openidlogin.php:65 ../actions/openidsettings.php:49
-#: actions/openidlogin.php:74 actions/openidsettings.php:50
-#: actions/openidlogin.php:102 actions/openidsettings.php:101
-#: actions/openidlogin.php:111
-msgid "OpenID URL"
+#: actions/groupunblock.php:91
+msgid "Only an admin can unblock group members."
msgstr ""
-#: ../actions/finishaddopenid.php:42 ../actions/finishopenidlogin.php:103
-#: actions/finishaddopenid.php:42 actions/finishopenidlogin.php:109
-#: actions/finishaddopenid.php:88 actions/finishopenidlogin.php:130
-#: actions/finishopenidlogin.php:129
-msgid "OpenID authentication cancelled."
+#: actions/groupunblock.php:95
+msgid "User is not blocked from group."
msgstr ""
-#: ../actions/finishaddopenid.php:46 ../actions/finishopenidlogin.php:107
-#: actions/finishaddopenid.php:46 actions/finishopenidlogin.php:113
-#: actions/finishaddopenid.php:92 actions/finishopenidlogin.php:134
-#: actions/finishopenidlogin.php:133
-#, php-format
-msgid "OpenID authentication failed: %s"
+#: actions/groupunblock.php:128 actions/unblock.php:108
+msgid "Error removing the block."
msgstr ""
-#: ../lib/openid.php:133 lib/openid.php:133 lib/openid.php:142
-#: lib/openid.php:145
-#, php-format
-msgid "OpenID failure: %s"
+#: actions/imsettings.php:59
+msgid "IM Settings"
msgstr ""
-#: ../actions/openidsettings.php:144 actions/openidsettings.php:153
-#: actions/openidsettings.php:231
-msgid "OpenID removed."
+#: actions/imsettings.php:70
+#, php-format
+msgid ""
+"You can send and receive notices through Jabber/GTalk [instant messages](%%"
+"doc.im%%). Configure your instant messages address and settings below."
msgstr ""
-#: ../actions/openidsettings.php:37 actions/openidsettings.php:37
-#: actions/openidsettings.php:59
-msgid "OpenID settings"
+#: actions/imsettings.php:89
+msgid "IM is not available."
msgstr ""
-#: ../actions/invite.php:135 actions/invite.php:143 actions/invite.php:180
-#: actions/invite.php:186 actions/invite.php:188 actions/invite.php:194
-msgid "Optionally add a personal message to the invitation."
+#: actions/imsettings.php:100
+msgid "IM address"
msgstr ""
-#: ../actions/avatar.php:84 actions/profilesettings.php:321
-#: lib/imagefile.php:75 lib/imagefile.php:79 lib/imagefile.php:80
-msgid "Partial upload."
+#: actions/imsettings.php:106
+msgid "Current confirmed Jabber/GTalk address."
msgstr ""
-#: ../actions/finishopenidlogin.php:90 ../actions/login.php:102
-#: ../actions/register.php:153 ../lib/settingsaction.php:93
-#: actions/finishopenidlogin.php:96 actions/login.php:102
-#: actions/register.php:167 actions/finishopenidlogin.php:118
-#: actions/login.php:231 actions/register.php:372
-#: lib/accountsettingsaction.php:110 lib/facebookaction.php:311
-#: actions/login.php:214 lib/facebookaction.php:315
-#: actions/finishopenidlogin.php:117 actions/register.php:418
-#: lib/facebookaction.php:317 actions/login.php:222 actions/register.php:422
-#: lib/accountsettingsaction.php:114 actions/login.php:249
-#: actions/register.php:428
-msgid "Password"
+#: actions/imsettings.php:114
+#, php-format
+msgid ""
+"Awaiting confirmation on this IM address. Check your Jabber/GTalk account "
+"for a message with further instructions. (Did you add %s to your buddy list?)"
msgstr ""
-#: ../actions/recoverpassword.php:288 actions/recoverpassword.php:301
-#: actions/recoverpassword.php:335 actions/recoverpassword.php:353
-#: actions/recoverpassword.php:356
-msgid "Password and confirmation do not match."
+#: actions/imsettings.php:124
+msgid "IM Address"
msgstr ""
-#: ../actions/recoverpassword.php:284 actions/recoverpassword.php:297
-#: actions/recoverpassword.php:331 actions/recoverpassword.php:349
-#: actions/recoverpassword.php:352
-msgid "Password must be 6 chars or more."
+#: actions/imsettings.php:126
+#, php-format
+msgid ""
+"Jabber or GTalk address, like \"UserName@example.org\". First, make sure to "
+"add %s to your buddy list in your IM client or on GTalk."
msgstr ""
-#: ../actions/recoverpassword.php:261 ../actions/recoverpassword.php:263
-#: actions/recoverpassword.php:267 actions/recoverpassword.php:269
-#: actions/recoverpassword.php:199 actions/recoverpassword.php:301
-#: actions/recoverpassword.php:207 actions/recoverpassword.php:319
-#: actions/recoverpassword.php:210 actions/recoverpassword.php:322
-msgid "Password recovery requested"
+#: actions/imsettings.php:143
+msgid "Send me notices through Jabber/GTalk."
msgstr ""
-#: ../actions/password.php:89 ../actions/recoverpassword.php:313
-#: actions/profilesettings.php:408 actions/recoverpassword.php:326
-#: actions/passwordsettings.php:173 actions/recoverpassword.php:200
-#: actions/passwordsettings.php:178 actions/recoverpassword.php:208
-#: actions/passwordsettings.php:184 actions/recoverpassword.php:211
-#: actions/passwordsettings.php:191
-msgid "Password saved."
+#: actions/imsettings.php:148
+msgid "Post a notice when my Jabber/GTalk status changes."
msgstr ""
-#: ../actions/password.php:61 ../actions/register.php:88
-#: actions/profilesettings.php:380 actions/register.php:98
-#: actions/passwordsettings.php:145 actions/register.php:183
-#: actions/passwordsettings.php:150 actions/register.php:220
-#: actions/passwordsettings.php:156 actions/register.php:227
-#: actions/register.php:233
-msgid "Passwords don't match."
+#: actions/imsettings.php:153
+msgid "Send me replies through Jabber/GTalk from users I am not subscribed to."
msgstr ""
-#: ../lib/searchaction.php:100 lib/searchaction.php:100
-#: lib/searchgroupnav.php:80
-msgid "People"
+#: actions/imsettings.php:159
+msgid "Publish a MicroID for my Jabber/GTalk address."
msgstr ""
-#: ../actions/opensearch.php:33 actions/opensearch.php:33
-#: actions/opensearch.php:64
-msgid "People Search"
+#: actions/imsettings.php:285
+msgid "No Jabber ID."
msgstr ""
-#: ../actions/peoplesearch.php:33 actions/peoplesearch.php:33
-#: actions/peoplesearch.php:58
-msgid "People search"
+#: actions/imsettings.php:292
+msgid "Cannot normalize that Jabber ID"
msgstr ""
-#: ../lib/stream.php:50 lib/personal.php:50 lib/personalgroupnav.php:98
-#: lib/personalgroupnav.php:99
-msgid "Personal"
+#: actions/imsettings.php:296
+msgid "Not a valid Jabber ID"
msgstr ""
-#: ../actions/invite.php:133 actions/invite.php:141 actions/invite.php:178
-#: actions/invite.php:184 actions/invite.php:186 actions/invite.php:192
-msgid "Personal message"
+#: actions/imsettings.php:299
+msgid "That is already your Jabber ID."
msgstr ""
-#: ../actions/smssettings.php:69 actions/smssettings.php:69
-#: actions/smssettings.php:128 actions/smssettings.php:140
-msgid "Phone number, no punctuation or spaces, with area code"
+#: actions/imsettings.php:302
+msgid "Jabber ID already belongs to another user."
msgstr ""
-#: ../actions/userauthorization.php:78
+#: actions/imsettings.php:327
+#, php-format
msgid ""
-"Please check these details to make sure that you want to subscribe to this "
-"user's notices. If you didn't just ask to subscribe to someone's notices, "
-"click \"Cancel\"."
+"A confirmation code was sent to the IM address you added. You must approve %"
+"s for sending messages to you."
msgstr ""
-#: ../actions/imsettings.php:73 actions/imsettings.php:74
-#: actions/imsettings.php:142 actions/imsettings.php:148
-msgid "Post a notice when my Jabber/GTalk status changes."
+#: actions/imsettings.php:387
+msgid "That is not your Jabber ID."
msgstr ""
-#: ../actions/emailsettings.php:85 ../actions/imsettings.php:67
-#: ../actions/smssettings.php:94 actions/emailsettings.php:86
-#: actions/imsettings.php:68 actions/smssettings.php:94
-#: actions/twittersettings.php:70 actions/emailsettings.php:147
-#: actions/imsettings.php:133 actions/smssettings.php:157
-#: actions/twittersettings.php:134 actions/twittersettings.php:137
-#: actions/emailsettings.php:153 actions/imsettings.php:139
-#: actions/smssettings.php:169
-msgid "Preferences"
+#: actions/inbox.php:59
+#, php-format
+msgid "Inbox for %s - page %d"
msgstr ""
-#: ../actions/emailsettings.php:162 ../actions/imsettings.php:144
-#: ../actions/smssettings.php:163 actions/emailsettings.php:180
-#: actions/imsettings.php:152 actions/smssettings.php:171
-#: actions/emailsettings.php:286 actions/imsettings.php:258
-#: actions/othersettings.php:168 actions/smssettings.php:272
-#: actions/emailsettings.php:293 actions/othersettings.php:173
-#: actions/emailsettings.php:301 actions/imsettings.php:264
-#: actions/othersettings.php:180 actions/smssettings.php:284
-msgid "Preferences saved."
+#: actions/inbox.php:62
+#, php-format
+msgid "Inbox for %s"
msgstr ""
-#: ../actions/profilesettings.php:57 actions/profilesettings.php:90
-#: actions/profilesettings.php:129 actions/profilesettings.php:130
-#: actions/profilesettings.php:145
-msgid "Preferred language"
+#: actions/inbox.php:115
+msgid "This is your inbox, which lists your incoming private messages."
msgstr ""
-#: ../lib/util.php:328 lib/util.php:344 lib/action.php:572 lib/action.php:665
-#: lib/action.php:715 lib/action.php:730
-msgid "Privacy"
+#: actions/invite.php:39
+msgid "Invites have been disabled."
msgstr ""
-#: ../classes/Notice.php:95 ../classes/Notice.php:106 classes/Notice.php:109
-#: classes/Notice.php:119 classes/Notice.php:145 classes/Notice.php:155
-#: classes/Notice.php:178 classes/Notice.php:188 classes/Notice.php:206
-#: classes/Notice.php:216 classes/Notice.php:232 classes/Notice.php:268
-#: classes/Notice.php:293
-msgid "Problem saving notice."
+#: actions/invite.php:41
+#, php-format
+msgid "You must be logged in to invite other users to use %s"
msgstr ""
-#: ../lib/settingsaction.php:84 ../lib/stream.php:60 lib/personal.php:60
-#: lib/settingsaction.php:84 lib/accountsettingsaction.php:104
-#: lib/personalgroupnav.php:108 lib/personalgroupnav.php:109
-#: lib/accountsettingsaction.php:108
-msgid "Profile"
+#: actions/invite.php:72
+#, php-format
+msgid "Invalid email address: %s"
msgstr ""
-#: ../actions/remotesubscribe.php:73 actions/remotesubscribe.php:82
-#: actions/remotesubscribe.php:109 actions/remotesubscribe.php:133
-msgid "Profile URL"
+#: actions/invite.php:110
+msgid "Invitation(s) sent"
msgstr ""
-#: ../actions/profilesettings.php:34 actions/profilesettings.php:32
-#: actions/profilesettings.php:58 actions/profilesettings.php:60
-msgid "Profile settings"
+#: actions/invite.php:112
+msgid "Invite new users"
msgstr ""
-#: ../actions/postnotice.php:51 ../actions/updateprofile.php:52
-#: actions/postnotice.php:52 actions/updateprofile.php:53
-#: actions/postnotice.php:55 actions/updateprofile.php:56
-#: actions/updateprofile.php:58
-msgid "Profile unknown"
+#: actions/invite.php:128
+msgid "You are already subscribed to these users:"
msgstr ""
-#: ../actions/public.php:54 actions/public.php:54 actions/public.php:124
-msgid "Public Stream Feed"
+#: actions/invite.php:131 actions/invite.php:139
+#, php-format
+msgid "%s (%s)"
msgstr ""
-#: ../actions/public.php:33 actions/public.php:33 actions/public.php:109
-#: lib/publicgroupnav.php:77 actions/public.php:112 lib/publicgroupnav.php:79
-#: actions/public.php:120 actions/public.php:131
-msgid "Public timeline"
+#: actions/invite.php:136
+msgid "These are already users and you were automatically subscribed to them:"
msgstr ""
-#: ../actions/imsettings.php:79 actions/imsettings.php:80
-#: actions/imsettings.php:153 actions/imsettings.php:159
-msgid "Publish a MicroID for my Jabber/GTalk address."
+#: actions/invite.php:144
+msgid "Invitation(s) sent to the following e-mail addresses:"
msgstr ""
-#: ../actions/emailsettings.php:94 actions/emailsettings.php:101
-#: actions/emailsettings.php:178 actions/emailsettings.php:183
-#: actions/emailsettings.php:191
-msgid "Publish a MicroID for my email address."
+#: actions/invite.php:150
+msgid ""
+"You will be notified when your invitees accept the invitation and register "
+"on the site. Thanks for growing the community!"
msgstr ""
-#: ../actions/tag.php:75 ../actions/tag.php:76 actions/tag.php:75
-#: actions/tag.php:76
-msgid "Recent Tags"
+#: actions/invite.php:162
+msgid ""
+"Use this form to invite your friends and colleagues to use this service."
msgstr ""
-#: ../actions/recoverpassword.php:166 actions/recoverpassword.php:171
-#: actions/recoverpassword.php:190 actions/recoverpassword.php:197
-#: actions/recoverpassword.php:199 actions/recoverpassword.php:200
-msgid "Recover"
+#: actions/invite.php:187
+msgid "Email addresses"
msgstr ""
-#: ../actions/recoverpassword.php:156 actions/recoverpassword.php:161
-#: actions/recoverpassword.php:198 actions/recoverpassword.php:206
-#: actions/recoverpassword.php:209
-msgid "Recover password"
+#: actions/invite.php:189
+msgid "Addresses of friends to invite (one per line)"
msgstr ""
-#: ../actions/recoverpassword.php:67 actions/recoverpassword.php:67
-#: actions/recoverpassword.php:73
-msgid "Recovery code for unknown user."
+#: actions/invite.php:192
+msgid "Personal message"
msgstr ""
-#: ../actions/register.php:142 ../actions/register.php:193 ../lib/util.php:312
-#: actions/register.php:152 actions/register.php:207 lib/util.php:328
-#: actions/register.php:69 actions/register.php:436 lib/action.php:338
-#: lib/facebookaction.php:277 lib/logingroupnav.php:78
-#: actions/register.php:438 lib/action.php:415 lib/facebookaction.php:279
-#: actions/register.php:108 actions/register.php:486 lib/action.php:440
-#: lib/facebookaction.php:281 actions/register.php:496 lib/action.php:450
-#: lib/logingroupnav.php:85 actions/register.php:114 actions/register.php:502
-msgid "Register"
+#: actions/invite.php:194
+msgid "Optionally add a personal message to the invitation."
msgstr ""
-#: ../actions/register.php:28 actions/register.php:28
-#: actions/finishopenidlogin.php:196 actions/register.php:90
-#: actions/finishopenidlogin.php:195 actions/finishopenidlogin.php:204
-#: actions/register.php:129 actions/register.php:135
-msgid "Registration not allowed."
+#: actions/invite.php:197 lib/messageform.php:181 lib/noticeform.php:208
+msgid "Send"
msgstr ""
-#: ../actions/register.php:200 actions/register.php:214
-#: actions/register.php:67 actions/register.php:106 actions/register.php:112
-msgid "Registration successful"
+#: actions/invite.php:226
+#, php-format
+msgid "%1$s has invited you to join them on %2$s"
msgstr ""
-#: ../actions/userauthorization.php:120 actions/userauthorization.php:127
-#: actions/userauthorization.php:144 actions/userauthorization.php:179
-#: actions/userauthorization.php:211
-msgid "Reject"
+#: actions/invite.php:228
+#, php-format
+msgid ""
+"%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 those "
+"you know and those who interest you.\n"
+"\n"
+"You can also share news about yourself, your thoughts, or your life online "
+"with users who know about you. It is also great for meeting others who share "
+"your interests.\n"
+"\n"
+"%1$s said:\n"
+"\n"
+"%4$s\n"
+"\n"
+"You can see %1$s's profile page on %2$s here:\n"
+"\n"
+"%5$s\n"
+"\n"
+"If you'd like to try the service, click on the link below to accept the "
+"invitation.\n"
+"\n"
+"%6$s\n"
+"\n"
+"If not, you can ignore this message. Thanks for your patience and your "
+"time.\n"
+"\n"
+"Sincerely, %2$s\n"
msgstr ""
-#: ../actions/login.php:103 ../actions/register.php:176 actions/login.php:103
-#: actions/register.php:190 actions/login.php:234 actions/openidlogin.php:107
-#: actions/register.php:414 actions/login.php:217 actions/openidlogin.php:116
-#: actions/register.php:461 actions/login.php:225 actions/register.php:471
-#: actions/login.php:252 actions/register.php:477
-msgid "Remember me"
+#: actions/joingroup.php:60
+msgid "You must be logged in to join a group."
msgstr ""
-#: ../actions/updateprofile.php:70 actions/updateprofile.php:71
-#: actions/updateprofile.php:74 actions/updateprofile.php:76
-msgid "Remote profile with no matching profile"
+#: actions/joingroup.php:90 lib/command.php:217
+msgid "You are already a member of that group"
msgstr ""
-#: ../actions/remotesubscribe.php:65 actions/remotesubscribe.php:73
-#: actions/remotesubscribe.php:88 actions/remotesubscribe.php:112
-msgid "Remote subscribe"
+#: actions/joingroup.php:128 lib/command.php:234
+#, php-format
+msgid "Could not join user %s to group %s"
msgstr ""
-#: ../actions/emailsettings.php:47 ../actions/emailsettings.php:75
-#: ../actions/imsettings.php:48 ../actions/openidsettings.php:106
-#: ../actions/smssettings.php:50 ../actions/smssettings.php:84
-#: actions/emailsettings.php:48 actions/emailsettings.php:76
-#: actions/imsettings.php:49 actions/openidsettings.php:108
-#: actions/smssettings.php:50 actions/smssettings.php:84
-#: actions/twittersettings.php:59 actions/emailsettings.php:101
-#: actions/emailsettings.php:134 actions/imsettings.php:102
-#: actions/openidsettings.php:166 actions/smssettings.php:103
-#: actions/smssettings.php:146 actions/twittersettings.php:115
-#: actions/twittersettings.php:118 actions/emailsettings.php:107
-#: actions/emailsettings.php:140 actions/imsettings.php:108
-#: actions/smssettings.php:115 actions/smssettings.php:158
-msgid "Remove"
+#: actions/joingroup.php:135 lib/command.php:239
+#, php-format
+msgid "%s joined group %s"
msgstr ""
-#: ../actions/openidsettings.php:68 actions/openidsettings.php:69
-#: actions/openidsettings.php:123
-msgid "Remove OpenID"
+#: actions/leavegroup.php:60
+msgid "You must be logged in to leave a group."
msgstr ""
-#: ../actions/openidsettings.php:73 actions/openidsettings.php:128
-msgid ""
-"Removing your only OpenID would make it impossible to log in! If you need to "
-"remove it, add another OpenID first."
+#: actions/leavegroup.php:90 lib/command.php:268
+msgid "You are not a member of that group."
msgstr ""
-#: ../lib/stream.php:55 lib/personal.php:55 lib/personalgroupnav.php:103
-#: lib/personalgroupnav.php:104
-msgid "Replies"
+#: actions/leavegroup.php:119 lib/command.php:278
+msgid "Could not find membership record."
msgstr ""
-#: ../actions/replies.php:47 ../actions/repliesrss.php:76 ../lib/stream.php:56
-#: actions/replies.php:47 actions/repliesrss.php:62 lib/personal.php:56
-#: actions/replies.php:116 actions/repliesrss.php:67
-#: lib/personalgroupnav.php:104 actions/replies.php:118
-#: actions/replies.php:117 lib/personalgroupnav.php:105
-#: actions/replies.php:125 actions/repliesrss.php:68
+#: actions/leavegroup.php:127 lib/command.php:284
#, php-format
-msgid "Replies to %s"
+msgid "Could not remove user %s to group %s"
msgstr ""
-#: ../actions/recoverpassword.php:183 actions/recoverpassword.php:189
-#: actions/recoverpassword.php:223 actions/recoverpassword.php:240
-#: actions/recoverpassword.php:243
-msgid "Reset"
+#: actions/leavegroup.php:134 lib/command.php:289
+#, php-format
+msgid "%s left group %s"
msgstr ""
-#: ../actions/recoverpassword.php:173 actions/recoverpassword.php:178
-#: actions/recoverpassword.php:197 actions/recoverpassword.php:205
-#: actions/recoverpassword.php:208
-msgid "Reset password"
+#: actions/login.php:79 actions/register.php:137
+msgid "Already logged in."
msgstr ""
-#: ../lib/settingsaction.php:99 lib/settingsaction.php:93
-#: actions/subscriptions.php:123 lib/connectsettingsaction.php:107
-#: actions/subscriptions.php:125 actions/subscriptions.php:184
-#: actions/subscriptions.php:199 lib/connectsettingsaction.php:115
-msgid "SMS"
+#: actions/login.php:110 actions/login.php:120
+msgid "Invalid or expired token."
msgstr ""
-#: ../actions/smssettings.php:67 actions/smssettings.php:67
-#: actions/smssettings.php:126 actions/smssettings.php:138
-msgid "SMS Phone number"
+#: actions/login.php:143
+msgid "Incorrect username or password."
msgstr ""
-#: ../actions/smssettings.php:33 actions/smssettings.php:33
-#: actions/smssettings.php:58
-msgid "SMS Settings"
+#: actions/login.php:149 actions/recoverpassword.php:375
+#: actions/register.php:248
+msgid "Error setting user."
msgstr ""
-#: ../lib/mail.php:219 lib/mail.php:225 lib/mail.php:437 lib/mail.php:438
-msgid "SMS confirmation"
+#: actions/login.php:204 actions/login.php:257 lib/action.php:453
+#: lib/logingroupnav.php:79
+msgid "Login"
msgstr ""
-#: ../actions/recoverpassword.php:182 actions/recoverpassword.php:188
-#: actions/recoverpassword.php:222 actions/recoverpassword.php:237
-#: actions/recoverpassword.php:240
-msgid "Same as password above"
+#: actions/login.php:243
+msgid "Login to site"
msgstr ""
-#: ../actions/register.php:156 actions/register.php:170
-#: actions/register.php:377 actions/register.php:423 actions/register.php:427
-#: actions/register.php:433
-msgid "Same as password above. Required."
+#: actions/login.php:246 actions/profilesettings.php:106
+#: actions/register.php:423 actions/showgroup.php:236 actions/tagother.php:94
+#: lib/groupeditform.php:152 lib/userprofile.php:131
+msgid "Nickname"
msgstr ""
-#: ../actions/emailsettings.php:97 ../actions/imsettings.php:81
-#: ../actions/profilesettings.php:67 ../actions/smssettings.php:100
-#: actions/emailsettings.php:104 actions/imsettings.php:82
-#: actions/profilesettings.php:101 actions/smssettings.php:100
-#: actions/twittersettings.php:83 actions/emailsettings.php:182
-#: actions/facebooksettings.php:114 actions/imsettings.php:157
-#: actions/othersettings.php:117 actions/profilesettings.php:150
-#: actions/smssettings.php:169 actions/subscriptions.php:124
-#: actions/tagother.php:152 actions/twittersettings.php:161
-#: lib/groupeditform.php:171 actions/emailsettings.php:187
-#: actions/subscriptions.php:126 actions/tagother.php:154
-#: actions/twittersettings.php:164 actions/othersettings.php:119
-#: actions/profilesettings.php:152 actions/subscriptions.php:185
-#: actions/twittersettings.php:180 lib/designsettings.php:256
-#: lib/groupeditform.php:196 actions/emailsettings.php:195
-#: actions/imsettings.php:163 actions/othersettings.php:126
-#: actions/profilesettings.php:167 actions/smssettings.php:181
-#: actions/subscriptions.php:203 lib/groupeditform.php:202
-msgid "Save"
+#: actions/login.php:249 actions/register.php:428
+#: lib/accountsettingsaction.php:114
+msgid "Password"
msgstr ""
-#: ../lib/searchaction.php:84 ../lib/util.php:300 lib/searchaction.php:84
-#: lib/util.php:316 lib/action.php:325 lib/action.php:396 lib/action.php:448
-#: lib/action.php:459
-msgid "Search"
+#: actions/login.php:252 actions/register.php:477
+msgid "Remember me"
+msgstr ""
+
+#: actions/login.php:253 actions/register.php:479
+msgid "Automatically login in the future; not for shared computers!"
msgstr ""
-#: ../actions/noticesearch.php:80 actions/noticesearch.php:85
-#: actions/noticesearch.php:127
-msgid "Search Stream Feed"
+#: actions/login.php:263
+msgid "Lost or forgotten password?"
msgstr ""
-#: ../actions/noticesearch.php:30 actions/noticesearch.php:30
-#: actions/noticesearch.php:57 actions/noticesearch.php:68
-#, php-format
+#: actions/login.php:282
msgid ""
-"Search for notices on %%site.name%% by their contents. Separate search terms "
-"by spaces; they must be 3 characters or more."
+"For security reasons, please re-enter your user name and password before "
+"changing your settings."
msgstr ""
-#: ../actions/peoplesearch.php:28 actions/peoplesearch.php:52
+#: actions/login.php:286
#, php-format
msgid ""
-"Search for people on %%site.name%% by their name, location, or interests. "
-"Separate the terms by spaces; they must be 3 characters or more."
+"Login with your username and password. Don't have a username yet? [Register]"
+"(%%action.register%%) a new account."
msgstr ""
-#: ../actions/smssettings.php:296 actions/smssettings.php:304
-#: actions/smssettings.php:457 actions/smssettings.php:469
-msgid "Select a carrier"
+#: actions/makeadmin.php:91
+msgid "Only an admin can make another user an admin."
msgstr ""
-#: ../actions/invite.php:137 ../lib/util.php:1172 actions/invite.php:145
-#: lib/util.php:1306 lib/util.php:1731 actions/invite.php:182
-#: lib/messageform.php:167 lib/noticeform.php:177 actions/invite.php:189
-#: lib/messageform.php:165 actions/invite.php:191 lib/messageform.php:157
-#: lib/noticeform.php:179 actions/invite.php:197 lib/messageform.php:181
-#: lib/noticeform.php:208
-msgid "Send"
+#: actions/makeadmin.php:95
+#, php-format
+msgid "%s is already an admin for group \"%s\"."
msgstr ""
-#: ../actions/emailsettings.php:73 ../actions/smssettings.php:82
-#: actions/emailsettings.php:74 actions/smssettings.php:82
-#: actions/emailsettings.php:132 actions/smssettings.php:145
-#: actions/emailsettings.php:138 actions/smssettings.php:157
-msgid "Send email to this address to post new notices."
+#: actions/makeadmin.php:132
+#, php-format
+msgid "Can't get membership record for %s in group %s"
msgstr ""
-#: ../actions/emailsettings.php:88 actions/emailsettings.php:89
-#: actions/emailsettings.php:152 actions/emailsettings.php:158
-msgid "Send me notices of new subscriptions through email."
+#: actions/makeadmin.php:145
+#, php-format
+msgid "Can't make %s an admin for group %s"
msgstr ""
-#: ../actions/imsettings.php:70 actions/imsettings.php:71
-#: actions/imsettings.php:137 actions/imsettings.php:143
-msgid "Send me notices through Jabber/GTalk."
+#: actions/microsummary.php:62 actions/newmessage.php:116
+#: actions/remotesubscribe.php:154
+msgid "No such user"
msgstr ""
-#: ../actions/smssettings.php:97 actions/smssettings.php:97
-#: actions/smssettings.php:162 actions/smssettings.php:174
-msgid ""
-"Send me notices through SMS; I understand I may incur exorbitant charges "
-"from my carrier."
+#: actions/microsummary.php:69
+msgid "No current status"
msgstr ""
-#: ../actions/imsettings.php:76 actions/imsettings.php:77
-#: actions/imsettings.php:147 actions/imsettings.php:153
-msgid "Send me replies through Jabber/GTalk from people I'm not subscribed to."
+#: actions/newgroup.php:53
+msgid "New group"
msgstr ""
-#: ../lib/util.php:304 lib/util.php:320 lib/facebookaction.php:215
-#: lib/facebookaction.php:228 lib/facebookaction.php:230
-msgid "Settings"
+#: actions/newgroup.php:110
+msgid "Use this form to create a new group."
msgstr ""
-#: ../actions/profilesettings.php:192 actions/profilesettings.php:307
-#: actions/profilesettings.php:319 actions/profilesettings.php:318
-#: actions/profilesettings.php:344
-msgid "Settings saved."
+#: actions/newmessage.php:71 actions/newmessage.php:231
+msgid "New message"
msgstr ""
-#: ../actions/tag.php:60 actions/tag.php:60
-msgid "Showing most popular tags from the last week"
+#: actions/newmessage.php:121 actions/newmessage.php:161 lib/command.php:367
+msgid "You can't send a message to this user."
msgstr ""
-#: ../actions/finishaddopenid.php:66 actions/finishaddopenid.php:66
-#: actions/finishaddopenid.php:114
-msgid "Someone else already has this OpenID."
+#: actions/newmessage.php:144 actions/newnotice.php:136 lib/command.php:351
+#: lib/command.php:424
+msgid "No content!"
msgstr ""
-#: ../actions/finishopenidlogin.php:42 ../actions/openidsettings.php:126
-#: actions/finishopenidlogin.php:47 actions/openidsettings.php:135
-#: actions/finishopenidlogin.php:52 actions/openidsettings.php:202
-msgid "Something weird happened."
+#: actions/newmessage.php:158
+msgid "No recipient specified."
msgstr ""
-#: ../scripts/maildaemon.php:58 scripts/maildaemon.php:58
-#: scripts/maildaemon.php:61 scripts/maildaemon.php:60
-msgid "Sorry, no incoming email allowed."
+#: actions/newmessage.php:164 lib/command.php:370
+msgid ""
+"Don't send a message to yourself; just say it to yourself quietly instead."
msgstr ""
-#: ../scripts/maildaemon.php:54 scripts/maildaemon.php:54
-#: scripts/maildaemon.php:57 scripts/maildaemon.php:56
-msgid "Sorry, that is not your incoming email address."
+#: actions/newmessage.php:181
+msgid "Message sent"
msgstr ""
-#: ../lib/util.php:330 lib/util.php:346 lib/action.php:574 lib/action.php:667
-#: lib/action.php:717 lib/action.php:732
-msgid "Source"
+#: actions/newmessage.php:185 lib/command.php:375
+#, php-format
+msgid "Direct message to %s sent"
msgstr ""
-#: ../actions/showstream.php:296 actions/showstream.php:311
-#: actions/showstream.php:476 actions/showgroup.php:375
-#: actions/showgroup.php:421 lib/profileaction.php:173
-#: actions/showgroup.php:429
-msgid "Statistics"
+#: actions/newmessage.php:210 actions/newnotice.php:233 lib/channel.php:170
+msgid "Ajax Error"
msgstr ""
-#: ../actions/finishopenidlogin.php:182 ../actions/finishopenidlogin.php:246
-#: actions/finishopenidlogin.php:188 actions/finishopenidlogin.php:252
-#: actions/finishopenidlogin.php:222 actions/finishopenidlogin.php:290
-#: actions/finishopenidlogin.php:295 actions/finishopenidlogin.php:238
-#: actions/finishopenidlogin.php:318
-msgid "Stored OpenID not found."
+#: actions/newnotice.php:69
+msgid "New notice"
msgstr ""
-#: ../actions/remotesubscribe.php:75 ../actions/showstream.php:188
-#: ../actions/showstream.php:197 actions/remotesubscribe.php:84
-#: actions/showstream.php:197 actions/showstream.php:206
-#: actions/remotesubscribe.php:113 actions/showstream.php:376
-#: lib/subscribeform.php:139 actions/showstream.php:345
-#: actions/remotesubscribe.php:137 actions/showstream.php:439
-#: lib/userprofile.php:321
-msgid "Subscribe"
+#: actions/newnotice.php:199
+msgid "Notice posted"
msgstr ""
-#: ../actions/showstream.php:313 ../actions/subscribers.php:27
-#: actions/showstream.php:328 actions/subscribers.php:27
-#: actions/showstream.php:436 actions/showstream.php:498
-#: lib/subgroupnav.php:88 lib/profileaction.php:140 lib/profileaction.php:200
-#: lib/subgroupnav.php:90
-msgid "Subscribers"
+#: actions/noticesearch.php:68
+#, php-format
+msgid ""
+"Search for notices on %%site.name%% by their contents. Separate search terms "
+"by spaces; they must be 3 characters or more."
msgstr ""
-#: ../actions/userauthorization.php:310 actions/userauthorization.php:322
-#: actions/userauthorization.php:338 actions/userauthorization.php:344
-#: actions/userauthorization.php:378 actions/userauthorization.php:247
-msgid "Subscription authorized"
+#: actions/noticesearch.php:78
+msgid "Text search"
msgstr ""
-#: ../actions/userauthorization.php:320 actions/userauthorization.php:332
-#: actions/userauthorization.php:349 actions/userauthorization.php:355
-#: actions/userauthorization.php:389 actions/userauthorization.php:259
-msgid "Subscription rejected"
+#: actions/noticesearch.php:91
+#, php-format
+msgid "Search results for \"%s\" on %s"
msgstr ""
-#: ../actions/showstream.php:230 ../actions/showstream.php:307
-#: ../actions/subscriptions.php:27 actions/showstream.php:240
-#: actions/showstream.php:322 actions/subscriptions.php:27
-#: actions/showstream.php:407 actions/showstream.php:489
-#: lib/subgroupnav.php:80 lib/profileaction.php:109 lib/profileaction.php:191
-#: lib/subgroupnav.php:82
-msgid "Subscriptions"
+#: actions/noticesearch.php:121
+#, php-format
+msgid ""
+"Be the first to [post on this topic](%%%%action.newnotice%%%%?"
+"status_textarea=%s)!"
msgstr ""
-#: ../actions/avatar.php:87 actions/profilesettings.php:324
-#: lib/imagefile.php:78 lib/imagefile.php:82 lib/imagefile.php:83
-#: lib/imagefile.php:88 lib/mediafile.php:170
-msgid "System error uploading file."
+#: actions/noticesearch.php:124
+#, php-format
+msgid ""
+"Why not [register an account](%%%%action.register%%%%) and be the first to "
+"[post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!"
msgstr ""
-#: ../actions/tag.php:41 ../lib/util.php:301 actions/tag.php:41
-#: lib/util.php:317 actions/profilesettings.php:122 actions/showstream.php:297
-#: actions/tagother.php:147 actions/tagother.php:207 lib/profilelist.php:162
-#: lib/profilelist.php:164 actions/showstream.php:290 actions/tagother.php:149
-#: actions/tagother.php:209 lib/profilelist.php:160
-#: actions/profilesettings.php:123 actions/showstream.php:255
-#: lib/subscriptionlist.php:106 lib/subscriptionlist.php:108
-#: actions/profilesettings.php:138 actions/showstream.php:327
-#: lib/userprofile.php:209
-msgid "Tags"
+#: actions/noticesearchrss.php:89
+#, php-format
+msgid "Updates with \"%s\""
msgstr ""
-#: ../lib/searchaction.php:104 lib/searchaction.php:104
-#: lib/designsettings.php:217
-msgid "Text"
+#: actions/noticesearchrss.php:91
+#, php-format
+msgid "Updates matching search term \"%1$s\" on %2$s!"
msgstr ""
-#: ../actions/noticesearch.php:34 actions/noticesearch.php:34
-#: actions/noticesearch.php:67 actions/noticesearch.php:78
-msgid "Text search"
+#: actions/nudge.php:85
+msgid ""
+"This user doesn't allow nudges or hasn't confirmed or set his email yet."
msgstr ""
-#: ../actions/openidsettings.php:140 actions/openidsettings.php:149
-#: actions/openidsettings.php:227
-msgid "That OpenID does not belong to you."
+#: actions/nudge.php:94
+msgid "Nudge sent"
msgstr ""
-#: ../actions/confirmaddress.php:52 actions/confirmaddress.php:52
-#: actions/confirmaddress.php:94
-msgid "That address has already been confirmed."
+#: actions/nudge.php:97
+msgid "Nudge sent!"
msgstr ""
-#: ../actions/confirmaddress.php:43 actions/confirmaddress.php:43
-#: actions/confirmaddress.php:85
-msgid "That confirmation code is not for you!"
+#: actions/oembed.php:79 actions/shownotice.php:100
+msgid "Notice has no profile"
msgstr ""
-#: ../actions/emailsettings.php:191 actions/emailsettings.php:209
-#: actions/emailsettings.php:328 actions/emailsettings.php:336
-msgid "That email address already belongs to another user."
+#: actions/oembed.php:86 actions/shownotice.php:180
+#, php-format
+msgid "%1$s's status on %2$s"
msgstr ""
-#: ../actions/avatar.php:80 actions/profilesettings.php:317
-#: lib/imagefile.php:71
-msgid "That file is too big."
+#: actions/oembed.php:157
+msgid "content type "
msgstr ""
-#: ../actions/imsettings.php:170 actions/imsettings.php:178
-#: actions/imsettings.php:293 actions/imsettings.php:299
-msgid "That is already your Jabber ID."
+#: actions/oembed.php:160
+msgid "Only "
msgstr ""
-#: ../actions/emailsettings.php:188 actions/emailsettings.php:206
-#: actions/emailsettings.php:318 actions/emailsettings.php:325
-#: actions/emailsettings.php:333
-msgid "That is already your email address."
+#: actions/oembed.php:181 actions/oembed.php:200 lib/api.php:963
+#: lib/api.php:991 lib/api.php:1101
+msgid "Not a supported data format."
msgstr ""
-#: ../actions/smssettings.php:188 actions/smssettings.php:196
-#: actions/smssettings.php:306 actions/smssettings.php:318
-msgid "That is already your phone number."
+#: actions/opensearch.php:64
+msgid "User Search"
msgstr ""
-#: ../actions/imsettings.php:233 actions/imsettings.php:241
-#: actions/imsettings.php:381 actions/imsettings.php:387
-msgid "That is not your Jabber ID."
+#: actions/opensearch.php:67
+msgid "Notice Search"
msgstr ""
-#: ../actions/emailsettings.php:249 actions/emailsettings.php:267
-#: actions/emailsettings.php:397 actions/emailsettings.php:404
-#: actions/emailsettings.php:412
-msgid "That is not your email address."
+#: actions/othersettings.php:60
+msgid "Other Settings"
msgstr ""
-#: ../actions/smssettings.php:257 actions/smssettings.php:265
-#: actions/smssettings.php:393 actions/smssettings.php:405
-msgid "That is not your phone number."
+#: actions/othersettings.php:71
+msgid "Manage various other options."
msgstr ""
-#: ../actions/emailsettings.php:226 ../actions/imsettings.php:210
-#: actions/emailsettings.php:244 actions/imsettings.php:218
-#: actions/emailsettings.php:367 actions/imsettings.php:349
-#: actions/emailsettings.php:374 actions/emailsettings.php:382
-#: actions/imsettings.php:355
-msgid "That is the wrong IM address."
+#: actions/othersettings.php:117
+msgid "Shorten URLs with"
msgstr ""
-#: ../actions/smssettings.php:233 actions/smssettings.php:241
-#: actions/smssettings.php:362 actions/smssettings.php:374
-msgid "That is the wrong confirmation number."
+#: actions/othersettings.php:118
+msgid "Automatic shortening service to use."
msgstr ""
-#: ../actions/smssettings.php:191 actions/smssettings.php:199
-#: actions/smssettings.php:309 actions/smssettings.php:321
-msgid "That phone number already belongs to another user."
+#: actions/othersettings.php:122
+msgid "View profile designs"
msgstr ""
-#: ../actions/newnotice.php:49 ../actions/twitapistatuses.php:408
-#: actions/newnotice.php:49 actions/twitapistatuses.php:330
-#: actions/facebookhome.php:243 actions/twitapistatuses.php:276
-#: actions/newnotice.php:136 actions/twitapistatuses.php:294
-#: lib/facebookaction.php:485 actions/newnotice.php:166
-#: actions/twitapistatuses.php:251 lib/facebookaction.php:477
-#: scripts/maildaemon.php:70
-msgid "That's too long. Max notice size is 140 chars."
+#: actions/othersettings.php:123
+msgid "Show or hide profile designs."
msgstr ""
-#: ../actions/twitapiaccount.php:74 actions/twitapiaccount.php:72
-#: actions/twitapiaccount.php:62 actions/twitapiaccount.php:63
-#: actions/twitapiaccount.php:66
-msgid "That's too long. Max notice size is 255 chars."
+#: actions/othersettings.php:153
+msgid "URL shortening service is too long (max 50 chars)."
msgstr ""
-#: ../actions/confirmaddress.php:92 actions/confirmaddress.php:92
-#: actions/confirmaddress.php:159
+#: actions/outbox.php:58
#, php-format
-msgid "The address \"%s\" has been confirmed for your account."
+msgid "Outbox for %s - page %d"
msgstr ""
-#: ../actions/emailsettings.php:264 ../actions/imsettings.php:250
-#: ../actions/smssettings.php:274 actions/emailsettings.php:282
-#: actions/imsettings.php:258 actions/smssettings.php:282
-#: actions/emailsettings.php:416 actions/imsettings.php:402
-#: actions/smssettings.php:413 actions/emailsettings.php:423
-#: actions/emailsettings.php:431 actions/imsettings.php:408
-#: actions/smssettings.php:425
-msgid "The address was removed."
+#: actions/outbox.php:61
+#, php-format
+msgid "Outbox for %s"
msgstr ""
-#: ../actions/userauthorization.php:312 actions/userauthorization.php:346
-#: actions/userauthorization.php:380
-msgid ""
-"The subscription has been authorized, but no callback URL was passed. Check "
-"with the site's instructions for details on how to authorize the "
-"subscription. Your subscription token is:"
+#: actions/outbox.php:116
+msgid "This is your outbox, which lists private messages you have sent."
msgstr ""
-#: ../actions/userauthorization.php:322 actions/userauthorization.php:357
-#: actions/userauthorization.php:391
-msgid ""
-"The subscription has been rejected, but no callback URL was passed. Check "
-"with the site's instructions for details on how to fully reject the "
-"subscription."
+#: actions/passwordsettings.php:58
+msgid "Change password"
msgstr ""
-#: ../actions/subscribers.php:35 actions/subscribers.php:35
-#: actions/subscribers.php:67
-#, php-format
-msgid "These are the people who listen to %s's notices."
+#: actions/passwordsettings.php:69
+msgid "Change your password."
msgstr ""
-#: ../actions/subscribers.php:33 actions/subscribers.php:33
-#: actions/subscribers.php:63
-msgid "These are the people who listen to your notices."
+#: actions/passwordsettings.php:95 actions/recoverpassword.php:231
+msgid "Password change"
msgstr ""
-#: ../actions/subscriptions.php:35 actions/subscriptions.php:35
-#: actions/subscriptions.php:69
-#, php-format
-msgid "These are the people whose notices %s listens to."
+#: actions/passwordsettings.php:103
+msgid "Old password"
msgstr ""
-#: ../actions/subscriptions.php:33 actions/subscriptions.php:33
-#: actions/subscriptions.php:65
-msgid "These are the people whose notices you listen to."
+#: actions/passwordsettings.php:107 actions/recoverpassword.php:235
+msgid "New password"
msgstr ""
-#: ../actions/invite.php:89 actions/invite.php:96 actions/invite.php:128
-#: actions/invite.php:130 actions/invite.php:136
-msgid ""
-"These people are already users and you were automatically subscribed to them:"
+#: actions/passwordsettings.php:108
+msgid "6 or more characters"
msgstr ""
-#: ../actions/recoverpassword.php:88 actions/recoverpassword.php:97
-msgid "This confirmation code is too old. Please start again."
+#: actions/passwordsettings.php:111 actions/recoverpassword.php:239
+#: actions/register.php:432 actions/smssettings.php:134
+msgid "Confirm"
msgstr ""
-#: ../lib/openid.php:195 lib/openid.php:206
-msgid ""
-"This form should automatically submit itself. If not, click the submit "
-"button to go to your OpenID provider."
+#: actions/passwordsettings.php:112
+msgid "same as password above"
msgstr ""
-#: ../actions/finishopenidlogin.php:56 actions/finishopenidlogin.php:61
-#: actions/finishopenidlogin.php:67 actions/finishopenidlogin.php:66
-#, php-format
-msgid ""
-"This is the first time you've logged into %s so we must connect your OpenID "
-"to a local account. You can either create a new account, or connect with "
-"your existing account, if you have one."
-msgstr ""
-
-#: ../actions/twitapifriendships.php:108 ../actions/twitapistatuses.php:586
-#: actions/twitapifavorites.php:127 actions/twitapifriendships.php:108
-#: actions/twitapistatuses.php:511 actions/twitapifavorites.php:97
-#: actions/twitapifriendships.php:85 actions/twitapistatuses.php:436
-#: actions/twitapifavorites.php:103 actions/twitapistatuses.php:460
-#: actions/twitapifavorites.php:154 actions/twitapifriendships.php:90
-#: actions/twitapistatuses.php:416 actions/apistatusesdestroy.php:107
-msgid "This method requires a POST or DELETE."
+#: actions/passwordsettings.php:116
+msgid "Change"
msgstr ""
-#: ../actions/twitapiaccount.php:65 ../actions/twitapifriendships.php:44
-#: ../actions/twitapistatuses.php:381 actions/twitapiaccount.php:63
-#: actions/twitapidirect_messages.php:114 actions/twitapifriendships.php:44
-#: actions/twitapistatuses.php:303 actions/twitapiaccount.php:53
-#: actions/twitapidirect_messages.php:122 actions/twitapifriendships.php:32
-#: actions/twitapistatuses.php:244 actions/twitapiaccount.php:54
-#: actions/twitapidirect_messages.php:131 actions/twitapistatuses.php:262
-#: actions/twitapiaccount.php:56 actions/twitapidirect_messages.php:124
-#: actions/twitapifriendships.php:34 actions/twitapistatuses.php:216
-#: actions/apiblockcreate.php:89 actions/apiblockdestroy.php:88
-#: actions/apidirectmessagenew.php:117 actions/apifavoritecreate.php:90
-#: actions/apifavoritedestroy.php:91 actions/apifriendshipscreate.php:91
-#: actions/apifriendshipsdestroy.php:91 actions/apigroupcreate.php:104
-#: actions/apigroupjoin.php:91 actions/apigroupleave.php:91
-#: actions/apistatusesupdate.php:109
-#: actions/apiaccountupdateprofileimage.php:84
-msgid "This method requires a POST."
+#: actions/passwordsettings.php:153 actions/register.php:230
+msgid "Password must be 6 or more characters."
msgstr ""
-#: ../lib/util.php:164 lib/util.php:246 lib/htmloutputter.php:104
-msgid "This page is not available in a media type you accept"
+#: actions/passwordsettings.php:156 actions/register.php:233
+msgid "Passwords don't match."
msgstr ""
-#: ../actions/profilesettings.php:63 actions/profilesettings.php:96
-#: actions/profilesettings.php:138 actions/profilesettings.php:139
-#: actions/profilesettings.php:154
-msgid "Timezone"
+#: actions/passwordsettings.php:164
+msgid "Incorrect old password"
msgstr ""
-#: ../actions/profilesettings.php:107 actions/profilesettings.php:222
-#: actions/profilesettings.php:211 actions/profilesettings.php:212
-#: actions/profilesettings.php:228
-msgid "Timezone not selected."
+#: actions/passwordsettings.php:180
+msgid "Error saving user; invalid."
msgstr ""
-#: ../actions/remotesubscribe.php:43 actions/remotesubscribe.php:74
-#: actions/remotesubscribe.php:98
-#, php-format
-msgid ""
-"To subscribe, you can [login](%%action.login%%), or [register](%%action."
-"register%%) a new account. If you already have an account on a [compatible "
-"microblogging site](%%doc.openmublog%%), enter your profile URL below."
+#: actions/passwordsettings.php:185 actions/recoverpassword.php:368
+msgid "Can't save new password."
msgstr ""
-#: ../actions/twitapifriendships.php:163 actions/twitapifriendships.php:167
-#: actions/twitapifriendships.php:132 actions/twitapifriendships.php:139
-#: actions/apifriendshipsexists.php:103 actions/apifriendshipsexists.php:94
-msgid "Two user ids or screen_names must be supplied."
+#: actions/passwordsettings.php:191 actions/recoverpassword.php:211
+msgid "Password saved."
msgstr ""
-#: ../actions/profilesettings.php:48 ../actions/register.php:169
-#: actions/profilesettings.php:81 actions/register.php:183
-#: actions/profilesettings.php:109 actions/register.php:398
-#: actions/register.php:444 actions/profilesettings.php:117
-#: actions/register.php:448 actions/register.php:454
-msgid "URL of your homepage, blog, or profile on another site"
+#: actions/peoplesearch.php:52
+#, php-format
+msgid ""
+"Search for users on %%site.name%% by their name, location, or interests. "
+"Separate the terms by spaces; they must be 3 characters or more."
msgstr ""
-#: ../actions/remotesubscribe.php:74 actions/remotesubscribe.php:83
-#: actions/remotesubscribe.php:110 actions/remotesubscribe.php:134
-msgid "URL of your profile on another compatible microblogging service"
+#: actions/peoplesearch.php:58
+msgid "People search"
msgstr ""
-#: ../actions/emailsettings.php:130 ../actions/imsettings.php:110
-#: ../actions/recoverpassword.php:39 ../actions/smssettings.php:135
-#: actions/emailsettings.php:144 actions/imsettings.php:118
-#: actions/recoverpassword.php:39 actions/smssettings.php:143
-#: actions/twittersettings.php:108 actions/avatarsettings.php:258
-#: actions/emailsettings.php:242 actions/grouplogo.php:317
-#: actions/imsettings.php:214 actions/recoverpassword.php:44
-#: actions/smssettings.php:236 actions/twittersettings.php:302
-#: actions/avatarsettings.php:263 actions/emailsettings.php:247
-#: actions/grouplogo.php:324 actions/twittersettings.php:306
-#: actions/twittersettings.php:322 lib/designsettings.php:301
-#: actions/emailsettings.php:255 actions/grouplogo.php:319
-#: actions/imsettings.php:220 actions/smssettings.php:248
-#: actions/avatarsettings.php:277 lib/designsettings.php:304
-msgid "Unexpected form submission."
+#: actions/peopletag.php:70
+#, php-format
+msgid "Not a valid user tag: %s"
msgstr ""
-#: ../actions/recoverpassword.php:276 actions/recoverpassword.php:289
-#: actions/recoverpassword.php:323 actions/recoverpassword.php:341
-#: actions/recoverpassword.php:344
-msgid "Unexpected password reset."
+#: actions/peopletag.php:144
+#, php-format
+msgid "Users self-tagged with %s - page %d"
msgstr ""
-#: ../index.php:57 index.php:57 actions/recoverpassword.php:202
-#: actions/recoverpassword.php:210 actions/recoverpassword.php:213
-msgid "Unknown action"
+#: actions/postnotice.php:84
+msgid "Invalid notice content"
msgstr ""
-#: ../actions/finishremotesubscribe.php:58
-#: actions/finishremotesubscribe.php:60 actions/finishremotesubscribe.php:61
-msgid "Unknown version of OMB protocol."
+#: actions/postnotice.php:90
+#, php-format
+msgid "Notice license ‘%s’ is not compatible with site license ‘%s’."
msgstr ""
-#: ../lib/util.php:269 lib/util.php:285
-msgid ""
-"Unless otherwise specified, contents of this site are copyright by the "
-"contributors and available under the "
+#: actions/profilesettings.php:60
+msgid "Profile settings"
msgstr ""
-#: ../actions/confirmaddress.php:48 actions/confirmaddress.php:48
-#: actions/confirmaddress.php:90
-#, php-format
-msgid "Unrecognized address type %s"
+#: actions/profilesettings.php:71
+msgid ""
+"You can update your personal profile info here so readers know more about "
+"you."
msgstr ""
-#: ../actions/showstream.php:209 actions/showstream.php:219
-#: lib/unsubscribeform.php:137
-msgid "Unsubscribe"
+#: actions/profilesettings.php:99
+msgid "Profile information"
msgstr ""
-#: ../actions/postnotice.php:44 ../actions/updateprofile.php:45
-#: actions/postnotice.php:45 actions/updateprofile.php:46
-#: actions/postnotice.php:48 actions/updateprofile.php:49
-#: actions/updateprofile.php:51
-msgid "Unsupported OMB version"
+#: actions/profilesettings.php:108 lib/groupeditform.php:154
+msgid "1-64 lowercase letters or numbers, no punctuation or spaces"
msgstr ""
-#: ../actions/avatar.php:105 actions/profilesettings.php:342
-#: lib/imagefile.php:102 lib/imagefile.php:99 lib/imagefile.php:100
-#: lib/imagefile.php:105
-msgid "Unsupported image file format."
+#: actions/profilesettings.php:111 actions/register.php:447
+#: actions/showgroup.php:247 actions/tagother.php:104
+#: lib/groupeditform.php:157 lib/userprofile.php:149
+msgid "Full name"
msgstr ""
-#: ../lib/settingsaction.php:100 lib/settingsaction.php:94
-#: lib/connectsettingsaction.php:108 lib/connectsettingsaction.php:116
-msgid "Updates by SMS"
+#: actions/profilesettings.php:115 actions/register.php:452
+#: lib/groupeditform.php:161
+msgid "Homepage"
msgstr ""
-#: ../lib/settingsaction.php:103 lib/settingsaction.php:97
-#: lib/connectsettingsaction.php:105 lib/connectsettingsaction.php:111
-msgid "Updates by instant messenger (IM)"
+#: actions/profilesettings.php:117 actions/register.php:454
+msgid "URL of your homepage, blog, or profile on another site"
msgstr ""
-#: ../actions/twitapistatuses.php:241 actions/twitapistatuses.php:158
-#: actions/twitapistatuses.php:129 actions/twitapistatuses.php:134
-#: actions/twitapistatuses.php:94 actions/allrss.php:119
-#: actions/apitimelinefriends.php:121
+#: actions/profilesettings.php:122 actions/register.php:460
#, php-format
-msgid "Updates from %1$s and friends on %2$s!"
+msgid "Describe yourself and your interests in %d chars"
msgstr ""
-#: ../actions/twitapistatuses.php:341 actions/twitapistatuses.php:268
-#: actions/twitapistatuses.php:202 actions/twitapistatuses.php:213
-#: actions/twitapigroups.php:74 actions/twitapistatuses.php:159
-#: actions/apitimelinegroup.php:110 actions/apitimelineuser.php:125
-#: actions/userrss.php:92
-#, php-format
-msgid "Updates from %1$s on %2$s!"
+#: actions/profilesettings.php:125 actions/register.php:463
+msgid "Describe yourself and your interests"
msgstr ""
-#: ../actions/avatar.php:68 actions/profilesettings.php:161
-#: actions/avatarsettings.php:162 actions/grouplogo.php:232
-#: actions/avatarsettings.php:165 actions/grouplogo.php:238
-#: actions/grouplogo.php:233
-msgid "Upload"
+#: actions/profilesettings.php:127 actions/register.php:465
+msgid "Bio"
msgstr ""
-#: ../actions/avatar.php:27
-msgid ""
-"Upload a new \"avatar\" (user image) here. You can't edit the picture after "
-"you upload it, so make sure it's more or less square. It must be under the "
-"site license, also. Use a picture that belongs to you and that you want to "
-"share."
+#: actions/profilesettings.php:132 actions/register.php:470
+#: actions/showgroup.php:256 actions/tagother.php:112
+#: actions/userauthorization.php:158 lib/groupeditform.php:177
+#: lib/userprofile.php:164
+msgid "Location"
msgstr ""
-#: ../lib/settingsaction.php:91
-msgid "Upload a new profile image"
+#: actions/profilesettings.php:134 actions/register.php:472
+msgid "Where you are, like \"City, State (or Region), Country\""
msgstr ""
-#: ../actions/invite.php:114 actions/invite.php:121 actions/invite.php:154
-#: actions/invite.php:156 actions/invite.php:162
-msgid ""
-"Use this form to invite your friends and colleagues to use this service."
+#: actions/profilesettings.php:138 actions/tagother.php:149
+#: actions/tagother.php:209 lib/subscriptionlist.php:106
+#: lib/subscriptionlist.php:108 lib/userprofile.php:209
+msgid "Tags"
msgstr ""
-#: ../actions/register.php:159 ../actions/register.php:162
-#: actions/register.php:173 actions/register.php:176 actions/register.php:382
-#: actions/register.php:386 actions/register.php:428 actions/register.php:432
-#: actions/register.php:436 actions/register.php:438 actions/register.php:442
-msgid "Used only for updates, announcements, and password recovery"
+#: actions/profilesettings.php:140
+msgid ""
+"Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated"
msgstr ""
-#: ../actions/finishremotesubscribe.php:86
-#: actions/finishremotesubscribe.php:88 actions/finishremotesubscribe.php:94
-msgid "User being listened to doesn't exist."
-msgstr ""
-
-#: ../actions/all.php:41 ../actions/avatarbynickname.php:48
-#: ../actions/foaf.php:47 ../actions/replies.php:41
-#: ../actions/showstream.php:44 ../actions/twitapiaccount.php:82
-#: ../actions/twitapistatuses.php:319 ../actions/twitapistatuses.php:685
-#: ../actions/twitapiusers.php:82 actions/all.php:41
-#: actions/avatarbynickname.php:48 actions/foaf.php:47 actions/replies.php:41
-#: actions/showfavorites.php:41 actions/showstream.php:44
-#: actions/twitapiaccount.php:80 actions/twitapifavorites.php:68
-#: actions/twitapistatuses.php:235 actions/twitapistatuses.php:609
-#: actions/twitapiusers.php:87 lib/mailbox.php:50
-#: actions/avatarbynickname.php:80 actions/foaf.php:48 actions/replies.php:80
-#: actions/showstream.php:107 actions/twitapiaccount.php:70
-#: actions/twitapifavorites.php:42 actions/twitapistatuses.php:167
-#: actions/twitapistatuses.php:503 actions/twitapiusers.php:55
-#: actions/usergroups.php:99 lib/galleryaction.php:67 lib/twitterapi.php:626
-#: actions/twitapiaccount.php:71 actions/twitapistatuses.php:179
-#: actions/twitapistatuses.php:535 actions/twitapiusers.php:59
-#: actions/foaf.php:65 actions/replies.php:79 actions/twitapiusers.php:57
-#: actions/usergroups.php:98 lib/galleryaction.php:66 lib/profileaction.php:84
-#: actions/apiusershow.php:108 actions/apiaccountupdateprofileimage.php:124
-#: actions/apiaccountupdateprofileimage.php:130
-msgid "User has no profile."
+#: actions/profilesettings.php:144
+msgid "Language"
msgstr ""
-#: ../actions/remotesubscribe.php:71 actions/remotesubscribe.php:80
-#: actions/remotesubscribe.php:105 actions/remotesubscribe.php:129
-msgid "User nickname"
+#: actions/profilesettings.php:145
+msgid "Preferred language"
msgstr ""
-#: ../actions/twitapiusers.php:75 actions/twitapiusers.php:80
-msgid "User not found."
+#: actions/profilesettings.php:154
+msgid "Timezone"
msgstr ""
-#: ../actions/profilesettings.php:63 actions/profilesettings.php:96
-#: actions/profilesettings.php:139 actions/profilesettings.php:140
#: actions/profilesettings.php:155
msgid "What timezone are you normally in?"
msgstr ""
-#: ../lib/util.php:1159 lib/util.php:1293 lib/noticeform.php:141
-#: lib/noticeform.php:158
-#, php-format
-msgid "What's up, %s?"
-msgstr ""
-
-#: ../actions/profilesettings.php:54 ../actions/register.php:175
-#: actions/profilesettings.php:87 actions/register.php:189
-#: actions/profilesettings.php:119 actions/register.php:410
-#: actions/register.php:456 actions/profilesettings.php:134
-#: actions/register.php:466 actions/register.php:472
-msgid "Where you are, like \"City, State (or Region), Country\""
-msgstr ""
-
-#: ../actions/updateprofile.php:128 actions/updateprofile.php:129
-#: actions/updateprofile.php:132 actions/updateprofile.php:134
-#, php-format
-msgid "Wrong image type for '%s'"
+#: actions/profilesettings.php:160
+msgid ""
+"Automatically subscribe to whoever subscribes to me (best for non-humans)"
msgstr ""
-#: ../actions/updateprofile.php:123 actions/updateprofile.php:124
-#: actions/updateprofile.php:127 actions/updateprofile.php:129
+#: actions/profilesettings.php:221 actions/register.php:223
#, php-format
-msgid "Wrong size image at '%s'"
-msgstr ""
-
-#: ../actions/deletenotice.php:63 ../actions/deletenotice.php:72
-#: actions/deletenotice.php:64 actions/deletenotice.php:79
-#: actions/block.php:148 actions/deletenotice.php:122
-#: actions/deletenotice.php:141 actions/deletenotice.php:115
-#: actions/block.php:150 actions/deletenotice.php:116
-#: actions/groupblock.php:177 actions/deletenotice.php:146
-msgid "Yes"
+msgid "Bio is too long (max %d chars)."
msgstr ""
-#: ../actions/finishaddopenid.php:64 actions/finishaddopenid.php:64
-#: actions/finishaddopenid.php:112
-msgid "You already have this OpenID!"
+#: actions/profilesettings.php:228
+msgid "Timezone not selected."
msgstr ""
-#: ../actions/deletenotice.php:37 actions/deletenotice.php:37
-msgid ""
-"You are about to permanently delete a notice. Once this is done, it cannot "
-"be undone."
+#: actions/profilesettings.php:234
+msgid "Language is too long (max 50 chars)."
msgstr ""
-#: ../actions/recoverpassword.php:31 actions/recoverpassword.php:31
-#: actions/recoverpassword.php:36
-msgid "You are already logged in!"
+#: actions/profilesettings.php:246 actions/tagother.php:178
+#, php-format
+msgid "Invalid tag: \"%s\""
msgstr ""
-#: ../actions/invite.php:81 actions/invite.php:88 actions/invite.php:120
-#: actions/invite.php:122 actions/invite.php:128
-msgid "You are already subscribed to these users:"
+#: actions/profilesettings.php:295
+msgid "Couldn't update user for autosubscribe."
msgstr ""
-#: ../actions/twitapifriendships.php:128 actions/twitapifriendships.php:128
-#: actions/twitapifriendships.php:105 actions/twitapifriendships.php:111
-msgid "You are not friends with the specified user."
+#: actions/profilesettings.php:328
+msgid "Couldn't save profile."
msgstr ""
-#: ../actions/password.php:27
-msgid "You can change your password here. Choose a good one!"
+#: actions/profilesettings.php:336
+msgid "Couldn't save tags."
msgstr ""
-#: ../actions/register.php:135 actions/register.php:145
-msgid "You can create a new account to start posting notices."
+#: actions/profilesettings.php:344
+msgid "Settings saved."
msgstr ""
-#: ../actions/smssettings.php:28 actions/smssettings.php:28
-#: actions/smssettings.php:69
+#: actions/public.php:83
#, php-format
-msgid "You can receive SMS messages through email from %%site.name%%."
+msgid "Beyond the page limit (%s)"
msgstr ""
-#: ../actions/openidsettings.php:86 actions/openidsettings.php:143
-msgid ""
-"You can remove an OpenID from your account by clicking the button marked "
-"\"Remove\"."
+#: actions/public.php:92
+msgid "Could not retrieve public stream."
msgstr ""
-#: ../actions/imsettings.php:28 actions/imsettings.php:28
-#: actions/imsettings.php:70
+#: actions/public.php:129
#, php-format
-msgid ""
-"You can send and receive notices through Jabber/GTalk [instant messages](%%"
-"doc.im%%). Configure your address and settings below."
+msgid "Public timeline, page %d"
msgstr ""
-#: ../actions/profilesettings.php:27 actions/profilesettings.php:69
-#: actions/profilesettings.php:71
-msgid ""
-"You can update your personal profile info here so people know more about you."
+#: actions/public.php:131 lib/publicgroupnav.php:79
+msgid "Public timeline"
msgstr ""
-#: ../actions/finishremotesubscribe.php:31 ../actions/remotesubscribe.php:31
-#: actions/finishremotesubscribe.php:31 actions/remotesubscribe.php:31
-#: actions/finishremotesubscribe.php:33 actions/finishremotesubscribe.php:85
-#: actions/finishremotesubscribe.php:101 actions/remotesubscribe.php:35
-#: actions/finishremotesubscribe.php:87 actions/remotesubscribe.php:59
-msgid "You can use the local subscription!"
+#: actions/public.php:151
+msgid "Public Stream Feed (RSS 1.0)"
msgstr ""
-#: ../actions/finishopenidlogin.php:33 ../actions/register.php:61
-#: actions/finishopenidlogin.php:38 actions/register.php:68
-#: actions/finishopenidlogin.php:43 actions/register.php:149
-#: actions/register.php:186 actions/register.php:192 actions/register.php:198
-msgid "You can't register if you don't agree to the license."
+#: actions/public.php:155
+msgid "Public Stream Feed (RSS 2.0)"
msgstr ""
-#: ../actions/updateprofile.php:63 actions/updateprofile.php:64
-#: actions/updateprofile.php:67 actions/updateprofile.php:69
-msgid "You did not send us that profile"
+#: actions/public.php:159
+msgid "Public Stream Feed (Atom)"
msgstr ""
-#: ../lib/mail.php:147 lib/mail.php:289 lib/mail.php:288
+#: actions/public.php:179
#, php-format
msgid ""
-"You have a new posting address on %1$s.\n"
-"\n"
-"Send email to %2$s to post new messages.\n"
-"\n"
-"More email instructions at %3$s.\n"
-"\n"
-"Faithfully yours,\n"
-"%4$s"
+"This is the public timeline for %%site.name%% but no one has posted anything "
+"yet."
msgstr ""
-#: ../actions/twitapistatuses.php:612 actions/twitapistatuses.php:537
-#: actions/twitapistatuses.php:463 actions/twitapistatuses.php:486
-#: actions/twitapistatuses.php:443 actions/apistatusesdestroy.php:130
-msgid "You may not delete another user's status."
+#: actions/public.php:182
+msgid "Be the first to post!"
msgstr ""
-#: ../actions/invite.php:31 actions/invite.php:31 actions/invite.php:39
-#: actions/invite.php:41
+#: actions/public.php:186
#, php-format
-msgid "You must be logged in to invite other users to use %s"
-msgstr ""
-
-#: ../actions/invite.php:103 actions/invite.php:110 actions/invite.php:142
-#: actions/invite.php:144 actions/invite.php:150
msgid ""
-"You will be notified when your invitees accept the invitation and register "
-"on the site. Thanks for growing the community!"
-msgstr ""
-
-#: ../actions/recoverpassword.php:149 actions/recoverpassword.php:158
-msgid "You've been identified. Enter a new password below. "
-msgstr ""
-
-#: ../actions/openidlogin.php:67 actions/openidlogin.php:76
-#: actions/openidlogin.php:104 actions/openidlogin.php:113
-msgid "Your OpenID URL"
+"Why not [register an account](%%action.register%%) and be the first to post!"
msgstr ""
-#: ../actions/recoverpassword.php:164 actions/recoverpassword.php:188
-#: actions/recoverpassword.php:193
-msgid "Your nickname on this server, or your registered email address."
+#: actions/public.php:233
+#, php-format
+msgid ""
+"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
+"blogging) service based on the Free Software [StatusNet](http://status.net/) "
+"tool. [Join now](%%action.register%%) to share notices about yourself with "
+"friends, family, and colleagues! ([Read more](%%doc.help%%))"
msgstr ""
-#: ../actions/openidsettings.php:28 actions/openidsettings.php:70
+#: actions/public.php:238
#, php-format
msgid ""
-"[OpenID](%%doc.openid%%) lets you log into many sites with the same user "
-"account. Manage your associated OpenIDs from here."
+"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
+"blogging) service based on the Free Software [StatusNet](http://status.net/) "
+"tool."
msgstr ""
-#: ../lib/util.php:943 lib/util.php:992 lib/util.php:945 lib/util.php:756
-#: lib/util.php:770 lib/util.php:816 lib/util.php:844
-msgid "a few seconds ago"
+#: actions/publictagcloud.php:57
+msgid "Public tag cloud"
msgstr ""
-#: ../lib/util.php:955 lib/util.php:1004 lib/util.php:957 lib/util.php:768
-#: lib/util.php:782 lib/util.php:828 lib/util.php:856
+#: actions/publictagcloud.php:63
#, php-format
-msgid "about %d days ago"
+msgid "These are most popular recent tags on %s "
msgstr ""
-#: ../lib/util.php:951 lib/util.php:1000 lib/util.php:953 lib/util.php:764
-#: lib/util.php:778 lib/util.php:824 lib/util.php:852
+#: actions/publictagcloud.php:69
#, php-format
-msgid "about %d hours ago"
+msgid "No one has posted a notice with a [hashtag](%%doc.tags%%) yet."
msgstr ""
-#: ../lib/util.php:947 lib/util.php:996 lib/util.php:949 lib/util.php:760
-#: lib/util.php:774 lib/util.php:820 lib/util.php:848
-#, php-format
-msgid "about %d minutes ago"
+#: actions/publictagcloud.php:72
+msgid "Be the first to post one!"
msgstr ""
-#: ../lib/util.php:959 lib/util.php:1008 lib/util.php:961 lib/util.php:772
-#: lib/util.php:786 lib/util.php:832 lib/util.php:860
+#: actions/publictagcloud.php:75
#, php-format
-msgid "about %d months ago"
+msgid ""
+"Why not [register an account](%%action.register%%) and be the first to post "
+"one!"
msgstr ""
-#: ../lib/util.php:953 lib/util.php:1002 lib/util.php:955 lib/util.php:766
-#: lib/util.php:780 lib/util.php:826 lib/util.php:854
-msgid "about a day ago"
+#: actions/publictagcloud.php:135
+msgid "Tag cloud"
msgstr ""
-#: ../lib/util.php:945 lib/util.php:994 lib/util.php:947 lib/util.php:758
-#: lib/util.php:772 lib/util.php:818 lib/util.php:846
-msgid "about a minute ago"
+#: actions/recoverpassword.php:36
+msgid "You are already logged in!"
msgstr ""
-#: ../lib/util.php:957 lib/util.php:1006 lib/util.php:959 lib/util.php:770
-#: lib/util.php:784 lib/util.php:830 lib/util.php:858
-msgid "about a month ago"
+#: actions/recoverpassword.php:62
+msgid "No such recovery code."
msgstr ""
-#: ../lib/util.php:961 lib/util.php:1010 lib/util.php:963 lib/util.php:774
-#: lib/util.php:788 lib/util.php:834 lib/util.php:862
-msgid "about a year ago"
+#: actions/recoverpassword.php:66
+msgid "Not a recovery code."
msgstr ""
-#: ../lib/util.php:949 lib/util.php:998 lib/util.php:951 lib/util.php:762
-#: lib/util.php:776 lib/util.php:822 lib/util.php:850
-msgid "about an hour ago"
+#: actions/recoverpassword.php:73
+msgid "Recovery code for unknown user."
msgstr ""
-#: ../actions/showstream.php:423 ../lib/stream.php:132
-#: actions/showstream.php:441 lib/stream.php:99
-msgid "delete"
+#: actions/recoverpassword.php:86
+msgid "Error with confirmation code."
msgstr ""
-#: ../actions/noticesearch.php:130 ../actions/showstream.php:408
-#: ../lib/stream.php:117 actions/noticesearch.php:136
-#: actions/showstream.php:426 lib/stream.php:84 actions/noticesearch.php:187
-msgid "in reply to..."
+#: actions/recoverpassword.php:97
+msgid "This confirmation code is too old. Please start again."
msgstr ""
-#: ../actions/noticesearch.php:137 ../actions/showstream.php:415
-#: ../lib/stream.php:124 actions/noticesearch.php:143
-#: actions/showstream.php:433 lib/stream.php:91 actions/noticesearch.php:194
-msgid "reply"
+#: actions/recoverpassword.php:111
+msgid "Could not update user with confirmed email address."
msgstr ""
-#: ../actions/password.php:44 actions/profilesettings.php:183
-#: actions/passwordsettings.php:106 actions/passwordsettings.php:112
-msgid "same as password above"
+#: actions/recoverpassword.php:152
+msgid ""
+"If you have forgotten or lost your password, you can get a new one sent to "
+"the email address you have stored in your account."
msgstr ""
-#: ../actions/twitapistatuses.php:755 actions/twitapistatuses.php:678
-#: actions/twitapistatuses.php:555 actions/twitapistatuses.php:596
-#: actions/twitapistatuses.php:618 actions/twitapistatuses.php:553
-#: actions/twitapistatuses.php:575
-msgid "unsupported file type"
-msgstr ""
-
-#: ../lib/util.php:1309 lib/util.php:1443
-msgid "« After"
-msgstr ""
-
-#: actions/deletenotice.php:74 actions/disfavor.php:43
-#: actions/emailsettings.php:127 actions/favor.php:45
-#: actions/finishopenidlogin.php:33 actions/imsettings.php:105
-#: actions/invite.php:46 actions/newmessage.php:45 actions/openidlogin.php:36
-#: actions/openidsettings.php:123 actions/profilesettings.php:47
-#: actions/recoverpassword.php:282 actions/register.php:42
-#: actions/remotesubscribe.php:40 actions/smssettings.php:124
-#: actions/subscribe.php:44 actions/twittersettings.php:97
-#: actions/unsubscribe.php:41 actions/userauthorization.php:35
-#: actions/block.php:64 actions/disfavor.php:74 actions/favor.php:77
-#: actions/finishopenidlogin.php:38 actions/invite.php:54 actions/nudge.php:80
-#: actions/openidlogin.php:37 actions/recoverpassword.php:316
-#: actions/subscribe.php:46 actions/unblock.php:65 actions/unsubscribe.php:43
-#: actions/avatarsettings.php:251 actions/emailsettings.php:229
-#: actions/grouplogo.php:314 actions/imsettings.php:200 actions/login.php:103
-#: actions/newmessage.php:133 actions/newnotice.php:96
-#: actions/openidsettings.php:188 actions/othersettings.php:136
-#: actions/passwordsettings.php:131 actions/profilesettings.php:172
-#: actions/register.php:113 actions/remotesubscribe.php:53
-#: actions/smssettings.php:216 actions/subedit.php:38 actions/tagother.php:166
-#: actions/twittersettings.php:294 actions/userauthorization.php:39
-#: actions/favor.php:75 actions/groupblock.php:66 actions/groupunblock.php:66
-#: actions/invite.php:56 actions/makeadmin.php:66 actions/newnotice.php:102
-#: actions/othersettings.php:138 actions/recoverpassword.php:334
-#: actions/register.php:153 actions/twittersettings.php:310
-#: lib/designsettings.php:291 actions/emailsettings.php:237
-#: actions/grouplogo.php:309 actions/imsettings.php:206 actions/login.php:105
-#: actions/newmessage.php:135 actions/newnotice.php:103
-#: actions/othersettings.php:145 actions/passwordsettings.php:137
-#: actions/profilesettings.php:187 actions/recoverpassword.php:337
-#: actions/register.php:159 actions/remotesubscribe.php:77
-#: actions/smssettings.php:228 actions/unsubscribe.php:69
-#: actions/userauthorization.php:52 actions/login.php:131
-#: actions/register.php:165 actions/avatarsettings.php:265
-#: lib/designsettings.php:294
-msgid "There was a problem with your session token. Try again, please."
+#: actions/recoverpassword.php:158
+msgid "You have been identified. Enter a new password below. "
msgstr ""
-#: actions/disfavor.php:55 actions/disfavor.php:81
-msgid "This notice is not a favorite!"
+#: actions/recoverpassword.php:188
+msgid "Password recovery"
msgstr ""
-#: actions/disfavor.php:63 actions/disfavor.php:87
-#: actions/twitapifavorites.php:188 actions/apifavoritedestroy.php:134
-msgid "Could not delete favorite."
+#: actions/recoverpassword.php:191
+msgid "Nickname or email address"
msgstr ""
-#: actions/disfavor.php:72 lib/favorform.php:140
-msgid "Favor"
+#: actions/recoverpassword.php:193
+msgid "Your nickname on this server, or your registered email address."
msgstr ""
-#: actions/emailsettings.php:92 actions/emailsettings.php:157
-#: actions/emailsettings.php:163
-msgid "Send me email when someone adds my notice as a favorite."
+#: actions/recoverpassword.php:199 actions/recoverpassword.php:200
+msgid "Recover"
msgstr ""
-#: actions/emailsettings.php:95 actions/emailsettings.php:163
-#: actions/emailsettings.php:169
-msgid "Send me email when someone sends me a private message."
+#: actions/recoverpassword.php:208
+msgid "Reset password"
msgstr ""
-#: actions/favor.php:53 actions/twitapifavorites.php:142 actions/favor.php:81
-#: actions/twitapifavorites.php:118 actions/twitapifavorites.php:124
-#: actions/favor.php:79
-msgid "This notice is already a favorite!"
+#: actions/recoverpassword.php:209
+msgid "Recover password"
msgstr ""
-#: actions/favor.php:60 actions/twitapifavorites.php:151
-#: classes/Command.php:132 actions/favor.php:86
-#: actions/twitapifavorites.php:125 classes/Command.php:152
-#: actions/twitapifavorites.php:131 lib/command.php:152 actions/favor.php:84
-#: actions/twitapifavorites.php:133 lib/command.php:145
-#: actions/apifavoritecreate.php:130 lib/command.php:176
-msgid "Could not create favorite."
+#: actions/recoverpassword.php:210 actions/recoverpassword.php:322
+msgid "Password recovery requested"
msgstr ""
-#: actions/favor.php:70
-msgid "Disfavor"
+#: actions/recoverpassword.php:213
+msgid "Unknown action"
msgstr ""
-#: actions/favoritesrss.php:60 actions/showfavorites.php:47
-#: actions/favoritesrss.php:100 actions/showfavorites.php:77
-#: actions/favoritesrss.php:110
-#, php-format
-msgid "%s favorite notices"
+#: actions/recoverpassword.php:236
+msgid "6 or more characters, and don't forget it!"
msgstr ""
-#: actions/favoritesrss.php:64 actions/favoritesrss.php:104
-#: actions/favoritesrss.php:114
-#, php-format
-msgid "Feed of favorite notices of %s"
+#: actions/recoverpassword.php:240
+msgid "Same as password above"
msgstr ""
-#: actions/inbox.php:28 actions/inbox.php:59
-#, php-format
-msgid "Inbox for %s - page %d"
-msgstr ""
-
-#: actions/inbox.php:30 actions/inbox.php:62
-#, php-format
-msgid "Inbox for %s"
-msgstr ""
-
-#: actions/inbox.php:53 actions/inbox.php:115
-msgid "This is your inbox, which lists your incoming private messages."
+#: actions/recoverpassword.php:243
+msgid "Reset"
msgstr ""
-#: actions/invite.php:178 actions/invite.php:213
-#, php-format
-msgid ""
-"%1$s has invited you to join them on %2$s (%3$s).\n"
-"\n"
+#: actions/recoverpassword.php:252
+msgid "Enter a nickname or email address."
msgstr ""
-#: actions/login.php:104 actions/login.php:235 actions/openidlogin.php:108
-#: actions/register.php:416
-msgid "Automatically login in the future; "
+#: actions/recoverpassword.php:272
+msgid "No user with that email address or username."
msgstr ""
-#: actions/login.php:122 actions/login.php:264
-msgid "For security reasons, please re-enter your "
+#: actions/recoverpassword.php:287
+msgid "No registered email address for that user."
msgstr ""
-#: actions/login.php:126 actions/login.php:268
-msgid "Login with your username and password. "
+#: actions/recoverpassword.php:301
+msgid "Error saving address confirmation."
msgstr ""
-#: actions/newmessage.php:58 actions/twitapidirect_messages.php:130
-#: actions/twitapidirect_messages.php:141 actions/newmessage.php:148
-#: actions/twitapidirect_messages.php:150
-#: actions/twitapidirect_messages.php:145
-msgid "That's too long. Max message size is 140 chars."
+#: actions/recoverpassword.php:325
+msgid ""
+"Instructions for recovering your password have been sent to the email "
+"address registered to your account."
msgstr ""
-#: actions/newmessage.php:65 actions/newmessage.php:128
-#: actions/newmessage.php:155 actions/newmessage.php:158
-msgid "No recipient specified."
+#: actions/recoverpassword.php:344
+msgid "Unexpected password reset."
msgstr ""
-#: actions/newmessage.php:68 actions/newmessage.php:113
-#: classes/Command.php:206 actions/newmessage.php:131
-#: actions/newmessage.php:168 classes/Command.php:237
-#: actions/newmessage.php:119 actions/newmessage.php:158 lib/command.php:237
-#: lib/command.php:230 actions/newmessage.php:121 actions/newmessage.php:161
-#: lib/command.php:367
-msgid "You can't send a message to this user."
+#: actions/recoverpassword.php:352
+msgid "Password must be 6 chars or more."
msgstr ""
-#: actions/newmessage.php:71 actions/twitapidirect_messages.php:146
-#: classes/Command.php:209 actions/twitapidirect_messages.php:158
-#: classes/Command.php:240 actions/newmessage.php:161
-#: actions/twitapidirect_messages.php:167 lib/command.php:240
-#: actions/twitapidirect_messages.php:163 lib/command.php:233
-#: actions/newmessage.php:164 lib/command.php:370
-msgid ""
-"Don't send a message to yourself; just say it to yourself quietly instead."
+#: actions/recoverpassword.php:356
+msgid "Password and confirmation do not match."
msgstr ""
-#: actions/newmessage.php:108 actions/microsummary.php:62
-#: actions/newmessage.php:163 actions/newmessage.php:114
-#: actions/newmessage.php:116 actions/remotesubscribe.php:154
-msgid "No such user"
+#: actions/recoverpassword.php:382
+msgid "New password successfully saved. You are now logged in."
msgstr ""
-#: actions/newmessage.php:117 actions/newmessage.php:67
-#: actions/newmessage.php:71 actions/newmessage.php:231
-msgid "New message"
+#: actions/register.php:85 actions/register.php:189 actions/register.php:404
+msgid "Sorry. Only those invited can register."
msgstr ""
-#: actions/noticesearch.php:95 actions/noticesearch.php:146
-msgid "Notice without matching profile"
+#: actions/register.php:92
+msgid "Sorry. This is an invalid invitation code."
msgstr ""
-#: actions/openidsettings.php:28 actions/openidsettings.php:70
-#, php-format
-msgid "[OpenID](%%doc.openid%%) lets you log into many sites "
+#: actions/register.php:112
+msgid "Registration successful"
msgstr ""
-#: actions/openidsettings.php:46 actions/openidsettings.php:96
-msgid "If you want to add an OpenID to your account, "
+#: actions/register.php:114 actions/register.php:502 lib/action.php:450
+#: lib/logingroupnav.php:85
+msgid "Register"
msgstr ""
-#: actions/openidsettings.php:74
-msgid "Removing your only OpenID would make it impossible to log in! "
+#: actions/register.php:135
+msgid "Registration not allowed."
msgstr ""
-#: actions/openidsettings.php:87 actions/openidsettings.php:143
-msgid "You can remove an OpenID from your account "
+#: actions/register.php:198
+msgid "You can't register if you don't agree to the license."
msgstr ""
-#: actions/outbox.php:28 actions/outbox.php:58
-#, php-format
-msgid "Outbox for %s - page %d"
+#: actions/register.php:201
+msgid "Not a valid email address."
msgstr ""
-#: actions/outbox.php:30 actions/outbox.php:61
-#, php-format
-msgid "Outbox for %s"
+#: actions/register.php:212
+msgid "Email address already exists."
msgstr ""
-#: actions/outbox.php:53 actions/outbox.php:116
-msgid "This is your outbox, which lists private messages you have sent."
+#: actions/register.php:243 actions/register.php:264
+msgid "Invalid username or password."
msgstr ""
-#: actions/peoplesearch.php:28 actions/peoplesearch.php:52
-#, php-format
+#: actions/register.php:342
msgid ""
-"Search for people on %%site.name%% by their name, location, or interests. "
+"With this form you can create a new account. You can then post notices and "
+"link up to friends and colleagues. "
msgstr ""
-#: actions/profilesettings.php:27 actions/profilesettings.php:69
-msgid "You can update your personal profile info here "
+#: actions/register.php:424
+msgid "1-64 lowercase letters or numbers, no punctuation or spaces. Required."
msgstr ""
-#: actions/profilesettings.php:115 actions/remotesubscribe.php:320
-#: actions/userauthorization.php:159 actions/userrss.php:76
-#: actions/avatarsettings.php:104 actions/avatarsettings.php:179
-#: actions/grouplogo.php:177 actions/remotesubscribe.php:367
-#: actions/userauthorization.php:176 actions/userrss.php:82
-#: actions/avatarsettings.php:106 actions/avatarsettings.php:182
-#: actions/grouplogo.php:183 actions/remotesubscribe.php:366
-#: actions/remotesubscribe.php:364 actions/userauthorization.php:215
-#: actions/userrss.php:103 actions/grouplogo.php:178
-#: actions/remotesubscribe.php:191 actions/userauthorization.php:72
-msgid "User without matching profile"
+#: actions/register.php:429
+msgid "6 or more characters. Required."
msgstr ""
-#: actions/recoverpassword.php:91 actions/recoverpassword.php:97
-msgid "This confirmation code is too old. "
+#: actions/register.php:433
+msgid "Same as password above. Required."
msgstr ""
-#: actions/recoverpassword.php:141 actions/recoverpassword.php:152
-msgid "If you've forgotten or lost your"
+#: actions/register.php:437 actions/register.php:441
+#: lib/accountsettingsaction.php:117
+msgid "Email"
msgstr ""
-#: actions/recoverpassword.php:154 actions/recoverpassword.php:158
-msgid "You've been identified. Enter a "
+#: actions/register.php:438 actions/register.php:442
+msgid "Used only for updates, announcements, and password recovery"
msgstr ""
-#: actions/recoverpassword.php:169 actions/recoverpassword.php:188
-msgid "Your nickname on this server, "
+#: actions/register.php:449
+msgid "Longer name, preferably your \"real\" name"
msgstr ""
-#: actions/recoverpassword.php:271 actions/recoverpassword.php:304
-msgid "Instructions for recovering your password "
+#: actions/register.php:493
+msgid "My text and files are available under "
msgstr ""
-#: actions/recoverpassword.php:327 actions/recoverpassword.php:361
-msgid "New password successfully saved. "
+#: actions/register.php:495
+msgid "Creative Commons Attribution 3.0"
msgstr ""
-#: actions/register.php:95 actions/register.php:180
-#: actions/passwordsettings.php:147 actions/register.php:217
-#: actions/passwordsettings.php:153 actions/register.php:224
-#: actions/register.php:230
-msgid "Password must be 6 or more characters."
+#: actions/register.php:496
+msgid ""
+" except this private data: password, email address, IM address, and phone "
+"number."
msgstr ""
-#: actions/register.php:216
+#: actions/register.php:537
#, php-format
msgid ""
"Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may "
-"want to..."
+"want to...\n"
+"\n"
+"* Go to [your profile](%s) and post your first message.\n"
+"* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send "
+"notices through instant messages.\n"
+"* [Search for users](%%%%action.peoplesearch%%%%) that you may know or that "
+"share your interests. \n"
+"* Update your [profile settings](%%%%action.profilesettings%%%%) to tell "
+"others more about you. \n"
+"* Read over the [online docs](%%%%doc.help%%%%) for features you may have "
+"missed. \n"
+"\n"
+"Thanks for signing up and we hope you enjoy using this service."
msgstr ""
-#: actions/register.php:227
-msgid "(You should receive a message by email momentarily, with "
+#: actions/register.php:561
+msgid ""
+"(You should receive a message by email momentarily, with instructions on how "
+"to confirm your email address.)"
msgstr ""
-#: actions/remotesubscribe.php:51 actions/remotesubscribe.php:74
+#: actions/remotesubscribe.php:98
#, php-format
-msgid "To subscribe, you can [login](%%action.login%%),"
+msgid ""
+"To subscribe, you can [login](%%action.login%%), or [register](%%action."
+"register%%) a new account. If you already have an account on a [compatible "
+"microblogging site](%%doc.openmublog%%), enter your profile URL below."
msgstr ""
-#: actions/showfavorites.php:61 actions/showfavorites.php:145
-#: actions/showfavorites.php:147
-#, php-format
-msgid "Feed for favorites of %s"
+#: actions/remotesubscribe.php:112
+msgid "Remote subscribe"
msgstr ""
-#: actions/showfavorites.php:84 actions/twitapifavorites.php:85
-#: actions/showfavorites.php:202 actions/twitapifavorites.php:59
-#: actions/showfavorites.php:179 actions/showfavorites.php:209
-#: actions/showfavorites.php:132
-msgid "Could not retrieve favorite notices."
+#: actions/remotesubscribe.php:124
+msgid "Subscribe to a remote user"
msgstr ""
-#: actions/showmessage.php:33 actions/showmessage.php:81
-msgid "No such message."
+#: actions/remotesubscribe.php:129
+msgid "User nickname"
msgstr ""
-#: actions/showmessage.php:42 actions/showmessage.php:98
-msgid "Only the sender and recipient may read this message."
+#: actions/remotesubscribe.php:130
+msgid "Nickname of the user you want to follow"
msgstr ""
-#: actions/showmessage.php:61 actions/showmessage.php:108
-#, php-format
-msgid "Message to %1$s on %2$s"
+#: actions/remotesubscribe.php:133
+msgid "Profile URL"
msgstr ""
-#: actions/showmessage.php:66 actions/showmessage.php:113
-#, php-format
-msgid "Message from %1$s on %2$s"
+#: actions/remotesubscribe.php:134
+msgid "URL of your profile on another compatible microblogging service"
msgstr ""
-#: actions/showstream.php:154
-msgid "Send a message"
+#: actions/remotesubscribe.php:137 lib/subscribeform.php:139
+#: lib/userprofile.php:321
+msgid "Subscribe"
msgstr ""
-#: actions/smssettings.php:312 actions/smssettings.php:464
-#, php-format
-msgid "Mobile carrier for your phone. "
+#: actions/remotesubscribe.php:159
+msgid "Invalid profile URL (bad format)"
msgstr ""
-#: actions/twitapidirect_messages.php:76 actions/twitapidirect_messages.php:68
-#: actions/twitapidirect_messages.php:67 actions/twitapidirect_messages.php:53
-#: actions/apidirectmessage.php:101
-#, php-format
-msgid "Direct messages to %s"
+#: actions/remotesubscribe.php:168
+msgid ""
+"Not a valid profile URL (no YADIS document or no or invalid XRDS defined)."
msgstr ""
-#: actions/twitapidirect_messages.php:77 actions/twitapidirect_messages.php:69
-#: actions/twitapidirect_messages.php:68 actions/twitapidirect_messages.php:54
-#: actions/apidirectmessage.php:105
-#, php-format
-msgid "All the direct messages sent to %s"
+#: actions/remotesubscribe.php:176
+msgid "That’s a local profile! Login to subscribe."
msgstr ""
-#: actions/twitapidirect_messages.php:81 actions/twitapidirect_messages.php:73
-#: actions/twitapidirect_messages.php:72 actions/twitapidirect_messages.php:59
-msgid "Direct Messages You've Sent"
+#: actions/remotesubscribe.php:183
+msgid "Couldn’t get a request token."
msgstr ""
-#: actions/twitapidirect_messages.php:82 actions/twitapidirect_messages.php:74
-#: actions/twitapidirect_messages.php:73 actions/twitapidirect_messages.php:60
-#: actions/apidirectmessage.php:93
+#: actions/replies.php:125 actions/repliesrss.php:68
+#: lib/personalgroupnav.php:105
#, php-format
-msgid "All the direct messages sent from %s"
-msgstr ""
-
-#: actions/twitapidirect_messages.php:128
-#: actions/twitapidirect_messages.php:137
-#: actions/twitapidirect_messages.php:146
-#: actions/twitapidirect_messages.php:140 actions/apidirectmessagenew.php:126
-msgid "No message text!"
+msgid "Replies to %s"
msgstr ""
-#: actions/twitapidirect_messages.php:138
-#: actions/twitapidirect_messages.php:150
-#: actions/twitapidirect_messages.php:159
-#: actions/twitapidirect_messages.php:154 actions/apidirectmessagenew.php:146
-msgid "Recipient user not found."
+#: actions/replies.php:127
+#, php-format
+msgid "Replies to %s, page %d"
msgstr ""
-#: actions/twitapidirect_messages.php:141
-#: actions/twitapidirect_messages.php:153
-#: actions/twitapidirect_messages.php:162
-#: actions/twitapidirect_messages.php:158 actions/apidirectmessagenew.php:150
-msgid "Can't send direct messages to users who aren't your friend."
+#: actions/replies.php:144
+#, php-format
+msgid "Replies feed for %s (RSS 1.0)"
msgstr ""
-#: actions/twitapifavorites.php:92 actions/twitapifavorites.php:66
-#: actions/twitapifavorites.php:64 actions/twitapifavorites.php:49
-#: actions/apitimelinefavorites.php:107
+#: actions/replies.php:151
#, php-format
-msgid "%s / Favorites from %s"
+msgid "Replies feed for %s (RSS 2.0)"
msgstr ""
-#: actions/twitapifavorites.php:95 actions/twitapifavorites.php:69
-#: actions/twitapifavorites.php:68 actions/twitapifavorites.php:55
-#: actions/apitimelinefavorites.php:119
+#: actions/replies.php:158
#, php-format
-msgid "%s updates favorited by %s / %s."
+msgid "Replies feed for %s (Atom)"
msgstr ""
-#: actions/twitapifavorites.php:187 lib/mail.php:275
-#: actions/twitapifavorites.php:164 lib/mail.php:553
-#: actions/twitapifavorites.php:170 lib/mail.php:554
-#: actions/twitapifavorites.php:221
+#: actions/replies.php:198
#, php-format
-msgid "%s added your notice as a favorite"
+msgid ""
+"This is the timeline showing replies to %s but %s has not received a notice "
+"to his attention yet."
msgstr ""
-#: actions/twitapifavorites.php:188 lib/mail.php:276
-#: actions/twitapifavorites.php:165
+#: actions/replies.php:203
#, php-format
msgid ""
-"%1$s just added your notice from %2$s as one of their favorites.\n"
-"\n"
+"You can engage other users in a conversation, subscribe to more users or "
+"[join groups](%%action.groups%%)."
msgstr ""
-#: actions/twittersettings.php:27
+#: actions/replies.php:205
+#, php-format
msgid ""
-"Add your Twitter account to automatically send your notices to Twitter, "
+"You can try to [nudge %s](../%s) or [post something to his or her attention]"
+"(%%%%action.newnotice%%%%?status_textarea=%s)."
msgstr ""
-#: actions/twittersettings.php:41 actions/twittersettings.php:60
-#: actions/twittersettings.php:61
-msgid "Twitter settings"
+#: actions/repliesrss.php:72
+#, php-format
+msgid "Replies to %1$s on %2$s!"
msgstr ""
-#: actions/twittersettings.php:48 actions/twittersettings.php:105
-#: actions/twittersettings.php:106
-msgid "Twitter Account"
+#: actions/showfavorites.php:79
+#, php-format
+msgid "%s's favorite notices, page %d"
msgstr ""
-#: actions/twittersettings.php:56 actions/twittersettings.php:113
-#: actions/twittersettings.php:114
-msgid "Current verified Twitter account."
+#: actions/showfavorites.php:132
+msgid "Could not retrieve favorite notices."
msgstr ""
-#: actions/twittersettings.php:63
-msgid "Twitter Username"
+#: actions/showfavorites.php:170
+#, php-format
+msgid "Feed for favorites of %s (RSS 1.0)"
msgstr ""
-#: actions/twittersettings.php:65 actions/twittersettings.php:123
-#: actions/twittersettings.php:126
-msgid "No spaces, please."
+#: actions/showfavorites.php:177
+#, php-format
+msgid "Feed for favorites of %s (RSS 2.0)"
msgstr ""
-#: actions/twittersettings.php:67
-msgid "Twitter Password"
+#: actions/showfavorites.php:184
+#, php-format
+msgid "Feed for favorites of %s (Atom)"
msgstr ""
-#: actions/twittersettings.php:72 actions/twittersettings.php:139
-#: actions/twittersettings.php:142
-msgid "Automatically send my notices to Twitter."
+#: actions/showfavorites.php:205
+msgid ""
+"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."
msgstr ""
-#: actions/twittersettings.php:75 actions/twittersettings.php:146
-#: actions/twittersettings.php:149
-msgid "Send local \"@\" replies to Twitter."
+#: actions/showfavorites.php:207
+#, php-format
+msgid ""
+"%s hasn't added any notices to his favorites yet. Post something interesting "
+"they would add to their favorites :)"
msgstr ""
-#: actions/twittersettings.php:78 actions/twittersettings.php:153
-#: actions/twittersettings.php:156
-msgid "Subscribe to my Twitter friends here."
+#: actions/showfavorites.php:211
+#, php-format
+msgid ""
+"%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 :)"
msgstr ""
-#: actions/twittersettings.php:122 actions/twittersettings.php:331
-#: actions/twittersettings.php:348
-msgid ""
-"Username must have only numbers, upper- and lowercase letters, and "
-"underscore (_). 15 chars max."
+#: actions/showfavorites.php:242
+msgid "This is a way to share what you like."
msgstr ""
-#: actions/twittersettings.php:128 actions/twittersettings.php:334
-#: actions/twittersettings.php:338 actions/twittersettings.php:355
-msgid "Could not verify your Twitter credentials!"
+#: actions/showgroup.php:82 lib/groupnav.php:85
+#, php-format
+msgid "%s group"
msgstr ""
-#: actions/twittersettings.php:137
+#: actions/showgroup.php:84
#, php-format
-msgid "Unable to retrieve account information for \"%s\" from Twitter."
+msgid "%s group, page %d"
msgstr ""
-#: actions/twittersettings.php:151 actions/twittersettings.php:170
-#: actions/twittersettings.php:348 actions/twittersettings.php:368
-#: actions/twittersettings.php:352 actions/twittersettings.php:372
-#: actions/twittersettings.php:369 actions/twittersettings.php:389
-msgid "Unable to save your Twitter settings!"
+#: actions/showgroup.php:218
+msgid "Group profile"
msgstr ""
-#: actions/twittersettings.php:174 actions/twittersettings.php:376
-#: actions/twittersettings.php:380 actions/twittersettings.php:399
-msgid "Twitter settings saved."
+#: actions/showgroup.php:263 actions/tagother.php:118
+#: actions/userauthorization.php:167 lib/userprofile.php:177
+msgid "URL"
msgstr ""
-#: actions/twittersettings.php:192 actions/twittersettings.php:395
-#: actions/twittersettings.php:399 actions/twittersettings.php:418
-msgid "That is not your Twitter account."
+#: actions/showgroup.php:274 actions/tagother.php:128
+#: actions/userauthorization.php:179 lib/userprofile.php:194
+msgid "Note"
msgstr ""
-#: actions/twittersettings.php:200 actions/twittersettings.php:208
-#: actions/twittersettings.php:403 actions/twittersettings.php:407
-#: actions/twittersettings.php:426
-msgid "Couldn't remove Twitter user."
+#: actions/showgroup.php:284 lib/groupeditform.php:184
+msgid "Aliases"
msgstr ""
-#: actions/twittersettings.php:212 actions/twittersettings.php:407
-#: actions/twittersettings.php:411 actions/twittersettings.php:430
-msgid "Twitter account removed."
+#: actions/showgroup.php:293
+msgid "Group actions"
msgstr ""
-#: actions/twittersettings.php:225 actions/twittersettings.php:239
-#: actions/twittersettings.php:428 actions/twittersettings.php:439
-#: actions/twittersettings.php:453 actions/twittersettings.php:432
-#: actions/twittersettings.php:443 actions/twittersettings.php:457
-#: actions/twittersettings.php:452 actions/twittersettings.php:463
-#: actions/twittersettings.php:477
-msgid "Couldn't save Twitter preferences."
+#: actions/showgroup.php:328
+#, php-format
+msgid "Notice feed for %s group (RSS 1.0)"
msgstr ""
-#: actions/twittersettings.php:245 actions/twittersettings.php:461
-#: actions/twittersettings.php:465 actions/twittersettings.php:485
-msgid "Twitter preferences saved."
+#: actions/showgroup.php:334
+#, php-format
+msgid "Notice feed for %s group (RSS 2.0)"
msgstr ""
-#: actions/userauthorization.php:84 actions/userauthorization.php:86
-msgid "Please check these details to make sure "
+#: actions/showgroup.php:340
+#, php-format
+msgid "Notice feed for %s group (Atom)"
msgstr ""
-#: actions/userauthorization.php:324 actions/userauthorization.php:340
-msgid "The subscription has been authorized, but no "
+#: actions/showgroup.php:345
+#, php-format
+msgid "FOAF for %s group"
msgstr ""
-#: actions/userauthorization.php:334 actions/userauthorization.php:351
-msgid "The subscription has been rejected, but no "
+#: actions/showgroup.php:381 actions/showgroup.php:438 lib/groupnav.php:90
+msgid "Members"
msgstr ""
-#: classes/Channel.php:113 classes/Channel.php:132 classes/Channel.php:151
-#: lib/channel.php:138 lib/channel.php:158
-msgid "Command results"
+#: actions/showgroup.php:386 lib/profileaction.php:117
+#: lib/profileaction.php:148 lib/profileaction.php:226 lib/section.php:95
+#: lib/tagcloudsection.php:71
+msgid "(None)"
msgstr ""
-#: classes/Channel.php:148 classes/Channel.php:204 lib/channel.php:210
-msgid "Command complete"
+#: actions/showgroup.php:392
+msgid "All members"
msgstr ""
-#: classes/Channel.php:158 classes/Channel.php:215 lib/channel.php:221
-msgid "Command failed"
+#: actions/showgroup.php:429 lib/profileaction.php:173
+msgid "Statistics"
msgstr ""
-#: classes/Command.php:39 classes/Command.php:44 lib/command.php:44
-msgid "Sorry, this command is not yet implemented."
+#: actions/showgroup.php:432
+msgid "Created"
msgstr ""
-#: classes/Command.php:96 classes/Command.php:113
+#: actions/showgroup.php:448
#, php-format
-msgid "Subscriptions: %1$s\n"
+msgid ""
+"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. Its members share short messages about "
+"their life and interests. [Join now](%%%%action.register%%%%) to become part "
+"of this group and many more! ([Read more](%%%%doc.help%%%%))"
msgstr ""
-#: classes/Command.php:125 classes/Command.php:242 classes/Command.php:145
-#: classes/Command.php:276 lib/command.php:145 lib/command.php:276
-#: lib/command.php:138 lib/command.php:269 lib/command.php:168
-#: lib/command.php:416 lib/command.php:471
-msgid "User has no last notice"
+#: actions/showgroup.php:454
+#, php-format
+msgid ""
+"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. Its members share short messages about "
+"their life and interests. "
msgstr ""
-#: classes/Command.php:146 classes/Command.php:166 lib/command.php:166
-#: lib/command.php:159 lib/command.php:190
-msgid "Notice marked as fave."
+#: actions/showgroup.php:482
+msgid "Admins"
msgstr ""
-#: classes/Command.php:166 classes/Command.php:189 lib/command.php:189
-#: lib/command.php:182 lib/command.php:315
-#, php-format
-msgid "%1$s (%2$s)"
+#: actions/showmessage.php:81
+msgid "No such message."
msgstr ""
-#: classes/Command.php:169 classes/Command.php:192 lib/command.php:192
-#: lib/command.php:185 lib/command.php:318
-#, php-format
-msgid "Fullname: %s"
+#: actions/showmessage.php:98
+msgid "Only the sender and recipient may read this message."
msgstr ""
-#: classes/Command.php:172 classes/Command.php:195 lib/command.php:195
-#: lib/command.php:188 lib/command.php:321
+#: actions/showmessage.php:108
#, php-format
-msgid "Location: %s"
+msgid "Message to %1$s on %2$s"
msgstr ""
-#: classes/Command.php:175 classes/Command.php:198 lib/command.php:198
-#: lib/command.php:191 lib/command.php:324
+#: actions/showmessage.php:113
#, php-format
-msgid "Homepage: %s"
+msgid "Message from %1$s on %2$s"
msgstr ""
-#: classes/Command.php:178 classes/Command.php:201 lib/command.php:201
-#: lib/command.php:194 lib/command.php:327
-#, php-format
-msgid "About: %s"
+#: actions/shownotice.php:90
+msgid "Notice deleted."
msgstr ""
-#: classes/Command.php:200 classes/Command.php:228 lib/command.php:228
-#: lib/command.php:221
+#: actions/showstream.php:73
#, php-format
-msgid "Message too long - maximum is 140 characters, you sent %d"
+msgid " tagged %s"
msgstr ""
-#: classes/Command.php:214 classes/Command.php:245 lib/command.php:245
-#: actions/newmessage.php:182 lib/command.php:238 actions/newmessage.php:185
-#: lib/command.php:375
+#: actions/showstream.php:79
#, php-format
-msgid "Direct message to %s sent"
-msgstr ""
-
-#: classes/Command.php:216 classes/Command.php:247 lib/command.php:247
-#: lib/command.php:240 lib/command.php:377
-msgid "Error sending direct message."
-msgstr ""
-
-#: classes/Command.php:263 classes/Command.php:300 lib/command.php:300
-#: lib/command.php:293 lib/command.php:495
-msgid "Specify the name of the user to subscribe to"
+msgid "%s, page %d"
msgstr ""
-#: classes/Command.php:270 classes/Command.php:307 lib/command.php:307
-#: lib/command.php:300 lib/command.php:502
+#: actions/showstream.php:122
#, php-format
-msgid "Subscribed to %s"
-msgstr ""
-
-#: classes/Command.php:288 classes/Command.php:328 lib/command.php:328
-#: lib/command.php:321 lib/command.php:523
-msgid "Specify the name of the user to unsubscribe from"
+msgid "Notice feed for %s tagged %s (RSS 1.0)"
msgstr ""
-#: classes/Command.php:295 classes/Command.php:335 lib/command.php:335
-#: lib/command.php:328 lib/command.php:530
+#: actions/showstream.php:129
#, php-format
-msgid "Unsubscribed from %s"
-msgstr ""
-
-#: classes/Command.php:310 classes/Command.php:330 classes/Command.php:353
-#: classes/Command.php:376 lib/command.php:353 lib/command.php:376
-#: lib/command.php:346 lib/command.php:369 lib/command.php:548
-#: lib/command.php:571
-msgid "Command not yet implemented."
-msgstr ""
-
-#: classes/Command.php:313 classes/Command.php:356 lib/command.php:356
-#: lib/command.php:349 lib/command.php:551
-msgid "Notification off."
-msgstr ""
-
-#: classes/Command.php:315 classes/Command.php:358 lib/command.php:358
-#: lib/command.php:351 lib/command.php:553
-msgid "Can't turn off notification."
-msgstr ""
-
-#: classes/Command.php:333 classes/Command.php:379 lib/command.php:379
-#: lib/command.php:372 lib/command.php:574
-msgid "Notification on."
+msgid "Notice feed for %s (RSS 1.0)"
msgstr ""
-#: classes/Command.php:335 classes/Command.php:381 lib/command.php:381
-#: lib/command.php:374 lib/command.php:576
-msgid "Can't turn on notification."
+#: actions/showstream.php:136
+#, php-format
+msgid "Notice feed for %s (RSS 2.0)"
msgstr ""
-#: classes/Command.php:344 classes/Command.php:392
-msgid "Commands:\n"
+#: actions/showstream.php:143
+#, php-format
+msgid "Notice feed for %s (Atom)"
msgstr ""
-#: classes/Message.php:53 classes/Message.php:56 classes/Message.php:55
-msgid "Could not insert message."
+#: actions/showstream.php:148
+#, php-format
+msgid "FOAF for %s"
msgstr ""
-#: classes/Message.php:63 classes/Message.php:66 classes/Message.php:65
-msgid "Could not update message with new URI."
+#: actions/showstream.php:191
+#, php-format
+msgid "This is the timeline for %s but %s hasn't posted anything yet."
msgstr ""
-#: lib/gallery.php:46
-msgid "User without matching profile in system."
+#: actions/showstream.php:196
+msgid ""
+"Seen anything interesting recently? You haven't posted any notices yet, now "
+"would be a good time to start :)"
msgstr ""
-#: lib/mail.php:147 lib/mail.php:289
+#: actions/showstream.php:198
#, php-format
msgid ""
-"You have a new posting address on %1$s.\n"
-"\n"
+"You can try to nudge %s or [post something to his or her attention](%%%%"
+"action.newnotice%%%%?status_textarea=%s)."
msgstr ""
-#: lib/mail.php:249 lib/mail.php:508 lib/mail.php:509
+#: actions/showstream.php:234
#, php-format
-msgid "New private message from %s"
+msgid ""
+"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. [Join now](%%%%action.register%%%%) to "
+"follow **%s**'s notices and many more! ([Read more](%%%%doc.help%%%%))"
msgstr ""
-#: lib/mail.php:253 lib/mail.php:512
+#: actions/showstream.php:239
#, php-format
msgid ""
-"%1$s (%2$s) sent you a private message:\n"
-"\n"
-msgstr ""
-
-#: lib/mailbox.php:43 lib/mailbox.php:89 lib/mailbox.php:91
-msgid "Only the user can read their own mailboxes."
+"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. "
msgstr ""
-#: lib/openid.php:195 lib/openid.php:203
-msgid "This form should automatically submit itself. "
+#: actions/smssettings.php:58
+msgid "SMS Settings"
msgstr ""
-#: lib/personal.php:65 lib/personalgroupnav.php:113
-#: lib/personalgroupnav.php:114
-msgid "Favorites"
+#: actions/smssettings.php:69
+#, php-format
+msgid "You can receive SMS messages through email from %%site.name%%."
msgstr ""
-#: lib/personal.php:66 lib/personalgroupnav.php:114
-#: actions/favoritesrss.php:110 actions/showfavorites.php:77
-#: lib/personalgroupnav.php:115 actions/favoritesrss.php:111
-#, php-format
-msgid "%s's favorite notices"
+#: actions/smssettings.php:91
+msgid "SMS is not available."
msgstr ""
-#: lib/personal.php:66 lib/personalgroupnav.php:114
-#: lib/personalgroupnav.php:115
-msgid "User"
+#: actions/smssettings.php:104
+msgid "SMS address"
msgstr ""
-#: lib/personal.php:75 lib/personalgroupnav.php:123
-#: lib/personalgroupnav.php:124
-msgid "Inbox"
+#: actions/smssettings.php:112
+msgid "Current confirmed SMS-enabled phone number."
msgstr ""
-#: lib/personal.php:76 lib/personalgroupnav.php:124
-#: lib/personalgroupnav.php:125
-msgid "Your incoming messages"
+#: actions/smssettings.php:123
+msgid "Awaiting confirmation on this phone number."
msgstr ""
-#: lib/personal.php:80 lib/personalgroupnav.php:128
-#: lib/personalgroupnav.php:129
-msgid "Outbox"
+#: actions/smssettings.php:130
+msgid "Confirmation code"
msgstr ""
-#: lib/personal.php:81 lib/personalgroupnav.php:129
-#: lib/personalgroupnav.php:130
-msgid "Your sent messages"
+#: actions/smssettings.php:131
+msgid "Enter the code you received on your phone."
msgstr ""
-#: lib/settingsaction.php:99 lib/connectsettingsaction.php:110
-msgid "Twitter"
+#: actions/smssettings.php:138
+msgid "SMS Phone number"
msgstr ""
-#: lib/settingsaction.php:100 lib/connectsettingsaction.php:111
-msgid "Twitter integration options"
+#: actions/smssettings.php:140
+msgid "Phone number, no punctuation or spaces, with area code"
msgstr ""
-#: lib/util.php:1718 lib/messageform.php:139 lib/noticelist.php:422
-#: lib/messageform.php:137 lib/noticelist.php:425 lib/messageform.php:135
-#: lib/noticelist.php:433 lib/messageform.php:146
-msgid "To"
+#: actions/smssettings.php:174
+msgid ""
+"Send me notices through SMS; I understand I may incur exorbitant charges "
+"from my carrier."
msgstr ""
-#: scripts/maildaemon.php:45 scripts/maildaemon.php:48
-#: scripts/maildaemon.php:47
-msgid "Could not parse message."
+#: actions/smssettings.php:306
+msgid "No phone number."
msgstr ""
-#: actions/all.php:63 actions/facebookhome.php:162 actions/all.php:66
-#: actions/facebookhome.php:161 actions/all.php:48
-#: actions/facebookhome.php:156 actions/all.php:84
-#, php-format
-msgid "%s and friends, page %d"
+#: actions/smssettings.php:311
+msgid "No carrier selected."
msgstr ""
-#: actions/avatarsettings.php:76
-msgid "You can upload your personal avatar."
+#: actions/smssettings.php:318
+msgid "That is already your phone number."
msgstr ""
-#: actions/avatarsettings.php:117 actions/avatarsettings.php:191
-#: actions/grouplogo.php:250 actions/avatarsettings.php:119
-#: actions/avatarsettings.php:194 actions/grouplogo.php:256
-#: actions/grouplogo.php:251
-msgid "Avatar settings"
+#: actions/smssettings.php:321
+msgid "That phone number already belongs to another user."
msgstr ""
-#: actions/avatarsettings.php:124 actions/avatarsettings.php:199
-#: actions/grouplogo.php:198 actions/grouplogo.php:258
-#: actions/avatarsettings.php:126 actions/avatarsettings.php:202
-#: actions/grouplogo.php:204 actions/grouplogo.php:264
-#: actions/grouplogo.php:199 actions/grouplogo.php:259
-msgid "Original"
+#: actions/smssettings.php:347
+msgid ""
+"A confirmation code was sent to the phone number you added. Check your phone "
+"for the code and instructions on how to use it."
msgstr ""
-#: actions/avatarsettings.php:139 actions/avatarsettings.php:211
-#: actions/grouplogo.php:209 actions/grouplogo.php:270
-#: actions/avatarsettings.php:141 actions/avatarsettings.php:214
-#: actions/grouplogo.php:215 actions/grouplogo.php:276
-#: actions/grouplogo.php:210 actions/grouplogo.php:271
-msgid "Preview"
+#: actions/smssettings.php:374
+msgid "That is the wrong confirmation number."
msgstr ""
-#: actions/avatarsettings.php:225 actions/grouplogo.php:284
-#: actions/avatarsettings.php:228 actions/grouplogo.php:291
-#: actions/grouplogo.php:286
-msgid "Crop"
+#: actions/smssettings.php:405
+msgid "That is not your phone number."
msgstr ""
-#: actions/avatarsettings.php:248 actions/deletenotice.php:133
-#: actions/emailsettings.php:224 actions/grouplogo.php:307
-#: actions/imsettings.php:200 actions/login.php:102 actions/newmessage.php:100
-#: actions/newnotice.php:96 actions/openidsettings.php:188
-#: actions/othersettings.php:136 actions/passwordsettings.php:131
-#: actions/profilesettings.php:172 actions/register.php:113
-#: actions/remotesubscribe.php:53 actions/smssettings.php:216
-#: actions/subedit.php:38 actions/twittersettings.php:290
-#: actions/userauthorization.php:39
-msgid "There was a problem with your session token. "
+#: actions/smssettings.php:465
+msgid "Mobile carrier"
msgstr ""
-#: actions/avatarsettings.php:303 actions/grouplogo.php:360
-#: actions/avatarsettings.php:308 actions/avatarsettings.php:322
-msgid "Pick a square area of the image to be your avatar"
+#: actions/smssettings.php:469
+msgid "Select a carrier"
msgstr ""
-#: actions/avatarsettings.php:327 actions/grouplogo.php:384
-#: actions/avatarsettings.php:323 actions/grouplogo.php:382
-#: actions/grouplogo.php:377 actions/avatarsettings.php:337
-msgid "Lost our file data."
+#: actions/smssettings.php:476
+#, php-format
+msgid ""
+"Mobile carrier for your phone. If you know a carrier that accepts SMS over "
+"email but isn't listed here, send email to let us know at %s."
msgstr ""
-#: actions/avatarsettings.php:334 actions/grouplogo.php:391
-#: classes/User_group.php:112 lib/imagefile.php:112 lib/imagefile.php:113
-#: lib/imagefile.php:118
-msgid "Lost our file."
+#: actions/smssettings.php:498
+msgid "No code entered"
msgstr ""
-#: actions/avatarsettings.php:349 actions/avatarsettings.php:383
-#: actions/grouplogo.php:406 actions/grouplogo.php:440
-#: classes/User_group.php:129 classes/User_group.php:161 lib/imagefile.php:144
-#: lib/imagefile.php:191 lib/imagefile.php:145 lib/imagefile.php:192
-#: lib/imagefile.php:150 lib/imagefile.php:197
-msgid "Unknown file type"
+#: actions/subedit.php:70
+msgid "You are not subscribed to that profile."
msgstr ""
-#: actions/block.php:69 actions/subedit.php:46 actions/unblock.php:70
-#: actions/groupblock.php:71 actions/groupunblock.php:71
-#: actions/makeadmin.php:71
-msgid "No profile specified."
+#: actions/subedit.php:83
+msgid "Could not save subscription."
msgstr ""
-#: actions/block.php:74 actions/subedit.php:53 actions/tagother.php:46
-#: actions/unblock.php:75 actions/groupblock.php:76
-#: actions/groupunblock.php:76 actions/makeadmin.php:76
-msgid "No profile with that ID."
+#: actions/subscribe.php:55
+msgid "Not a local user."
msgstr ""
-#: actions/block.php:111 actions/block.php:134
-msgid "Block user"
+#: actions/subscribe.php:69
+msgid "Subscribed"
msgstr ""
-#: actions/block.php:129
-msgid "Are you sure you want to block this user? "
+#: actions/subscribers.php:50
+#, php-format
+msgid "%s subscribers"
msgstr ""
-#: actions/block.php:162 actions/block.php:165
-msgid "You have already blocked this user."
+#: actions/subscribers.php:52
+#, php-format
+msgid "%s subscribers, page %d"
msgstr ""
-#: actions/block.php:167 actions/block.php:170
-msgid "Failed to save block information."
+#: actions/subscribers.php:63
+msgid "These are the users who have subscribed to your notices."
msgstr ""
-#: actions/confirmaddress.php:159
+#: actions/subscribers.php:67
#, php-format
-msgid "The address \"%s\" has been "
+msgid "These are the users who have subscribed to %s's notices."
msgstr ""
-#: actions/deletenotice.php:73
-msgid "You are about to permanently delete a notice. "
+#: actions/subscribers.php:108
+msgid ""
+"You have no subscribers. Try subscribing to users you know and they might "
+"return the favor"
msgstr ""
-#: actions/disfavor.php:94
-msgid "Add to favorites"
+#: actions/subscribers.php:110
+#, php-format
+msgid "%s has no subscribers. Want to be the first?"
msgstr ""
-#: actions/editgroup.php:54 actions/editgroup.php:56
+#: actions/subscribers.php:114
#, php-format
-msgid "Edit %s group"
+msgid ""
+"%s has no subscribers. Why not [register an account](%%%%action.register%%%"
+"%) and be the first?"
msgstr ""
-#: actions/editgroup.php:66 actions/groupbyid.php:72 actions/grouplogo.php:66
-#: actions/joingroup.php:60 actions/newgroup.php:65 actions/showgroup.php:100
-#: actions/grouplogo.php:70 actions/grouprss.php:80 actions/editgroup.php:68
-#: actions/groupdesignsettings.php:68 actions/showgroup.php:105
-msgid "Inboxes must be enabled for groups to work"
+#: actions/subscriptions.php:52
+#, php-format
+msgid "%s subscriptions"
msgstr ""
-#: actions/editgroup.php:71 actions/grouplogo.php:71 actions/newgroup.php:70
-#: actions/grouplogo.php:75 actions/editgroup.php:73 actions/editgroup.php:68
-#: actions/grouplogo.php:70 actions/newgroup.php:65
-msgid "You must be logged in to create a group."
+#: actions/subscriptions.php:54
+#, php-format
+msgid "%s subscriptions, page %d"
msgstr ""
-#: actions/editgroup.php:87 actions/grouplogo.php:87
-#: actions/groupmembers.php:76 actions/joingroup.php:81
-#: actions/showgroup.php:121 actions/grouplogo.php:91 actions/grouprss.php:96
-#: actions/blockedfromgroup.php:73 actions/editgroup.php:89
-#: actions/groupdesignsettings.php:89 actions/showgroup.php:126
-#: actions/editgroup.php:84 actions/groupdesignsettings.php:84
-#: actions/grouplogo.php:86 actions/grouprss.php:91 actions/joingroup.php:76
-msgid "No nickname"
+#: actions/subscriptions.php:65
+msgid "These are the users whose notices you have subscribed to."
msgstr ""
-#: actions/editgroup.php:99 actions/groupbyid.php:88 actions/grouplogo.php:100
-#: actions/groupmembers.php:83 actions/joingroup.php:88
-#: actions/showgroup.php:128 actions/grouplogo.php:104
-#: actions/grouprss.php:103 actions/blockedfromgroup.php:80
-#: actions/editgroup.php:101 actions/groupdesignsettings.php:102
-#: actions/showgroup.php:133 actions/editgroup.php:96 actions/groupbyid.php:83
-#: actions/groupdesignsettings.php:97 actions/grouplogo.php:99
-#: actions/grouprss.php:98 actions/joingroup.php:83 actions/showgroup.php:137
-msgid "No such group"
+#: actions/subscriptions.php:69
+#, php-format
+msgid "These are the users whose notices %s has subscribed to."
msgstr ""
-#: actions/editgroup.php:106 actions/editgroup.php:165
-#: actions/grouplogo.php:107 actions/grouplogo.php:111
-#: actions/editgroup.php:108 actions/editgroup.php:167
-#: actions/groupdesignsettings.php:109 actions/editgroup.php:103
-#: actions/editgroup.php:168 actions/groupdesignsettings.php:104
-#: actions/grouplogo.php:106
-msgid "You must be an admin to edit the group"
+#: actions/subscriptions.php:121
+#, php-format
+msgid ""
+"You have not subscribed to anyone's notices right now. Try subscribing to "
+"users you know. Try [user search](%%action.peoplesearch%%), look for members "
+"in groups you're interested in and in our [featured users](%%action.featured%"
+"%). If you are a [Twitter user](%%action.twittersettings%%), you can "
+"automatically subscribe to users you already follow there."
msgstr ""
-#: actions/editgroup.php:157 actions/editgroup.php:159
-#: actions/editgroup.php:154
-msgid "Use this form to edit the group."
+#: actions/subscriptions.php:123 actions/subscriptions.php:127
+#, php-format
+msgid "%s is not listening to anyone."
msgstr ""
-#: actions/editgroup.php:179 actions/newgroup.php:130 actions/register.php:156
-msgid "Nickname must have only lowercase letters "
+#: actions/subscriptions.php:194
+msgid "Jabber"
msgstr ""
-#: actions/editgroup.php:198 actions/newgroup.php:149
-#: actions/editgroup.php:200 actions/newgroup.php:150
-msgid "description is too long (max 140 chars)."
+#: actions/subscriptions.php:199 lib/connectsettingsaction.php:115
+msgid "SMS"
msgstr ""
-#: actions/editgroup.php:218 actions/editgroup.php:253
-msgid "Could not update group."
+#: actions/tagother.php:33
+msgid "Not logged in"
msgstr ""
-#: actions/editgroup.php:226 actions/editgroup.php:269
-msgid "Options saved."
+#: actions/tagother.php:39
+msgid "No id argument."
msgstr ""
-#: actions/emailsettings.php:107 actions/imsettings.php:108
+#: actions/tagother.php:65
#, php-format
-msgid "Awaiting confirmation on this address. "
+msgid "Tag %s"
msgstr ""
-#: actions/emailsettings.php:139 actions/smssettings.php:150
-msgid "Make a new email address for posting to; "
+#: actions/tagother.php:77 lib/userprofile.php:75
+msgid "User profile"
msgstr ""
-#: actions/emailsettings.php:157
-msgid "Send me email when someone "
+#: actions/tagother.php:81 lib/userprofile.php:102
+msgid "Photo"
msgstr ""
-#: actions/emailsettings.php:168 actions/emailsettings.php:173
-#: actions/emailsettings.php:179
-msgid "Allow friends to nudge me and send me an email."
+#: actions/tagother.php:141
+msgid "Tag user"
msgstr ""
-#: actions/emailsettings.php:321
-msgid "That email address already belongs "
+#: actions/tagother.php:151
+msgid ""
+"Tags for this user (letters, numbers, -, ., and _), comma- or space- "
+"separated"
msgstr ""
-#: actions/emailsettings.php:343
-msgid "A confirmation code was sent to the email address you added. "
+#: actions/tagother.php:193
+msgid ""
+"You can only tag users you are subscribed to or who are subscribed to you."
msgstr ""
-#: actions/facebookhome.php:110 actions/facebookhome.php:109
-msgid "Server error - couldn't get user!"
+#: actions/tagother.php:200
+msgid "Could not save tags."
msgstr ""
-#: actions/facebookhome.php:196
-#, php-format
-msgid "If you would like the %s app to automatically update "
+#: actions/tagother.php:236
+msgid "Use this form to add tags to your subscribers or subscriptions."
msgstr ""
-#: actions/facebookhome.php:213 actions/facebooksettings.php:137
+#: actions/tag.php:68
#, php-format
-msgid "Allow %s to update my Facebook status"
+msgid "Notices tagged with %s, page %d"
msgstr ""
-#: actions/facebookhome.php:218 actions/facebookhome.php:223
-#: actions/facebookhome.php:217
-msgid "Skip"
+#: actions/tag.php:86
+#, php-format
+msgid "Notice feed for tag %s (RSS 1.0)"
msgstr ""
-#: actions/facebookhome.php:235 lib/facebookaction.php:479
-#: lib/facebookaction.php:471
-msgid "No notice content!"
+#: actions/tag.php:92
+#, php-format
+msgid "Notice feed for tag %s (RSS 2.0)"
msgstr ""
-#: actions/facebookhome.php:295 lib/action.php:870 lib/facebookaction.php:399
-#: actions/facebookhome.php:253 lib/action.php:973 lib/facebookaction.php:433
-#: actions/facebookhome.php:247 lib/action.php:1037 lib/facebookaction.php:435
-#: lib/action.php:1053
-msgid "Pagination"
+#: actions/tag.php:98
+#, php-format
+msgid "Notice feed for tag %s (Atom)"
msgstr ""
-#: actions/facebookhome.php:304 lib/action.php:879 lib/facebookaction.php:408
-#: actions/facebookhome.php:262 lib/action.php:982 lib/facebookaction.php:442
-#: actions/facebookhome.php:256 lib/action.php:1046 lib/facebookaction.php:444
-#: lib/action.php:1062
-msgid "After"
+#: actions/tagrss.php:35
+msgid "No such tag."
msgstr ""
-#: actions/facebookhome.php:312 lib/action.php:887 lib/facebookaction.php:416
-#: actions/facebookhome.php:270 lib/action.php:990 lib/facebookaction.php:450
-#: actions/facebookhome.php:264 lib/action.php:1054 lib/facebookaction.php:452
-#: lib/action.php:1070
-msgid "Before"
+#: actions/twitapitrends.php:87
+msgid "API method under construction."
msgstr ""
-#: actions/facebookinvite.php:70 actions/facebookinvite.php:72
-#, php-format
-msgid "Thanks for inviting your friends to use %s"
+#: actions/unsubscribe.php:77
+msgid "No profile id in request."
msgstr ""
-#: actions/facebookinvite.php:72 actions/facebookinvite.php:74
-msgid "Invitations have been sent to the following users:"
+#: actions/unsubscribe.php:84
+msgid "No profile with that id."
msgstr ""
-#: actions/facebookinvite.php:96 actions/facebookinvite.php:102
-#: actions/facebookinvite.php:94
-#, php-format
-msgid "You have been invited to %s"
+#: actions/unsubscribe.php:98
+msgid "Unsubscribed"
msgstr ""
-#: actions/facebookinvite.php:105 actions/facebookinvite.php:111
-#: actions/facebookinvite.php:103
+#: actions/updateprofile.php:62 actions/userauthorization.php:330
#, php-format
-msgid "Invite your friends to use %s"
+msgid "Listenee stream license ‘%s’ is not compatible with site license ‘%s’."
msgstr ""
-#: actions/facebookinvite.php:113 actions/facebookinvite.php:126
-#: actions/facebookinvite.php:124
-#, php-format
-msgid "Friends already using %s:"
+#: actions/userauthorization.php:105
+msgid "Authorize subscription"
msgstr ""
-#: actions/facebookinvite.php:130 actions/facebookinvite.php:143
-#: actions/facebookinvite.php:142
-#, php-format
-msgid "Send invitations"
+#: actions/userauthorization.php:110
+msgid ""
+"Please check these details to make sure that you want to subscribe to this "
+"user’s notices. If you didn’t just ask to subscribe to someone’s notices, "
+"click “Reject”."
msgstr ""
-#: actions/facebookremove.php:56
-msgid "Couldn't remove Facebook user."
+#: actions/userauthorization.php:188
+msgid "License"
msgstr ""
-#: actions/facebooksettings.php:65
-msgid "There was a problem saving your sync preferences!"
+#: actions/userauthorization.php:209
+msgid "Accept"
msgstr ""
-#: actions/facebooksettings.php:67
-msgid "Sync preferences saved."
+#: actions/userauthorization.php:210 lib/subscribeform.php:115
+#: lib/subscribeform.php:139
+msgid "Subscribe to this user"
msgstr ""
-#: actions/facebooksettings.php:90
-msgid "Automatically update my Facebook status with my notices."
+#: actions/userauthorization.php:211
+msgid "Reject"
msgstr ""
-#: actions/facebooksettings.php:97
-msgid "Send \"@\" replies to Facebook."
+#: actions/userauthorization.php:212
+msgid "Reject this subscription"
msgstr ""
-#: actions/facebooksettings.php:106
-msgid "Prefix"
-msgstr ""
-
-#: actions/facebooksettings.php:108
-msgid "A string to prefix notices with."
+#: actions/userauthorization.php:225
+msgid "No authorization request!"
msgstr ""
-#: actions/facebooksettings.php:124
-#, php-format
-msgid "If you would like %s to automatically update "
+#: actions/userauthorization.php:247
+msgid "Subscription authorized"
msgstr ""
-#: actions/facebooksettings.php:147
-msgid "Sync preferences"
+#: actions/userauthorization.php:249
+msgid ""
+"The subscription has been authorized, but no callback URL was passed. Check "
+"with the site’s instructions for details on how to authorize the "
+"subscription. Your subscription token is:"
msgstr ""
-#: actions/favor.php:94 lib/disfavorform.php:140 actions/favor.php:92
-msgid "Disfavor favorite"
+#: actions/userauthorization.php:259
+msgid "Subscription rejected"
msgstr ""
-#: actions/favorited.php:65 lib/popularnoticesection.php:76
-#: lib/publicgroupnav.php:91 lib/popularnoticesection.php:82
-#: lib/publicgroupnav.php:93 lib/popularnoticesection.php:91
-#: lib/popularnoticesection.php:87
-msgid "Popular notices"
+#: actions/userauthorization.php:261
+msgid ""
+"The subscription has been rejected, but no callback URL was passed. Check "
+"with the site’s instructions for details on how to fully reject the "
+"subscription."
msgstr ""
-#: actions/favorited.php:67
+#: actions/userauthorization.php:296
#, php-format
-msgid "Popular notices, page %d"
-msgstr ""
-
-#: actions/favorited.php:79
-msgid "The most popular notices on the site right now."
+msgid "Listener URI ‘%s’ not found here"
msgstr ""
-#: actions/featured.php:69 lib/featureduserssection.php:82
-#: lib/publicgroupnav.php:87 lib/publicgroupnav.php:89
-#: lib/featureduserssection.php:87
-msgid "Featured users"
+#: actions/userauthorization.php:301
+#, php-format
+msgid "Listenee URI ‘%s’ is too long."
msgstr ""
-#: actions/featured.php:71
+#: actions/userauthorization.php:307
#, php-format
-msgid "Featured users, page %d"
+msgid "Listenee URI ‘%s’ is a local user."
msgstr ""
-#: actions/featured.php:99
+#: actions/userauthorization.php:322
#, php-format
-msgid "A selection of some of the great users on %s"
+msgid "Profile URL ‘%s’ is for a local user."
msgstr ""
-#: actions/finishremotesubscribe.php:188 actions/finishremotesubscribe.php:96
-msgid "That user has blocked you from subscribing."
+#: actions/userauthorization.php:338
+#, php-format
+msgid "Avatar URL ‘%s’ is not valid."
msgstr ""
-#: actions/groupbyid.php:79 actions/groupbyid.php:74
-msgid "No ID"
+#: actions/userauthorization.php:343
+#, php-format
+msgid "Can’t read avatar URL ‘%s’."
msgstr ""
-#: actions/grouplogo.php:138 actions/grouplogo.php:191
-#: actions/grouplogo.php:144 actions/grouplogo.php:197
-#: actions/grouplogo.php:139 actions/grouplogo.php:192
-msgid "Group logo"
+#: actions/userauthorization.php:348
+#, php-format
+msgid "Wrong image type for avatar URL ‘%s’."
msgstr ""
-#: actions/grouplogo.php:149
-msgid "You can upload a logo image for your group."
+#: actions/userbyid.php:70
+msgid "No id."
msgstr ""
-#: actions/grouplogo.php:448 actions/grouplogo.php:401
-#: actions/grouplogo.php:396
-msgid "Logo updated."
+#: actions/userdesignsettings.php:76 lib/designsettings.php:65
+msgid "Profile design"
msgstr ""
-#: actions/grouplogo.php:450 actions/grouplogo.php:403
-#: actions/grouplogo.php:398
-msgid "Failed updating logo."
+#: actions/userdesignsettings.php:87 lib/designsettings.php:76
+msgid ""
+"Customize the way your profile looks with a background image and a colour "
+"palette of your choice."
msgstr ""
-#: actions/groupmembers.php:93 lib/groupnav.php:91
-#, php-format
-msgid "%s group members"
+#: actions/userdesignsettings.php:282
+msgid "Enjoy your hotdog!"
msgstr ""
-#: actions/groupmembers.php:96
+#: actions/usergroups.php:64
#, php-format
-msgid "%s group members, page %d"
+msgid "%s groups, page %d"
msgstr ""
-#: actions/groupmembers.php:111
-msgid "A list of the users in this group."
+#: actions/usergroups.php:130
+msgid "Search for more groups"
msgstr ""
-#: actions/groups.php:62 actions/showstream.php:518 lib/publicgroupnav.php:79
-#: lib/subgroupnav.php:96 lib/publicgroupnav.php:81 lib/profileaction.php:220
-#: lib/subgroupnav.php:98
-msgid "Groups"
+#: actions/usergroups.php:153
+#, php-format
+msgid "%s is not a member of any group."
msgstr ""
-#: actions/groups.php:64
+#: actions/usergroups.php:158
#, php-format
-msgid "Groups, page %d"
+msgid "Try [searching for groups](%%action.groupsearch%%) and joining them."
msgstr ""
-#: actions/groups.php:90
+#: classes/File.php:137
#, php-format
-msgid "%%%%site.name%%%% groups let you find and talk with "
+msgid ""
+"No file may be larger than %d bytes and the file you sent was %d bytes. Try "
+"to upload a smaller version."
msgstr ""
-#: actions/groups.php:106 actions/usergroups.php:124 lib/groupeditform.php:123
-#: actions/usergroups.php:125 actions/groups.php:107 lib/groupeditform.php:122
-msgid "Create a new group"
+#: classes/File.php:147
+#, php-format
+msgid "A file this large would exceed your user quota of %d bytes."
msgstr ""
-#: actions/groupsearch.php:57
+#: classes/File.php:154
#, php-format
-msgid ""
-"Search for groups on %%site.name%% by their name, location, or description. "
+msgid "A file this large would exceed your monthly quota of %d bytes."
msgstr ""
-#: actions/groupsearch.php:63 actions/groupsearch.php:58
-msgid "Group search"
+#: classes/Message.php:55
+msgid "Could not insert message."
msgstr ""
-#: actions/imsettings.php:70
-msgid "You can send and receive notices through "
+#: classes/Message.php:65
+msgid "Could not update message with new URI."
msgstr ""
-#: actions/imsettings.php:120
+#: classes/Notice.php:164
#, php-format
-msgid "Jabber or GTalk address, "
+msgid "DB error inserting hashtag: %s"
msgstr ""
-#: actions/imsettings.php:147
-msgid "Send me replies through Jabber/GTalk "
+#: classes/Notice.php:179
+msgid "Problem saving notice. Too long."
msgstr ""
-#: actions/imsettings.php:321
-#, php-format
-msgid "A confirmation code was sent "
+#: classes/Notice.php:183
+msgid "Problem saving notice. Unknown user."
msgstr ""
-#: actions/joingroup.php:65 actions/joingroup.php:60
-msgid "You must be logged in to join a group."
+#: classes/Notice.php:188
+msgid ""
+"Too many notices too fast; take a breather and post again in a few minutes."
msgstr ""
-#: actions/joingroup.php:95 actions/joingroup.php:90 lib/command.php:217
-msgid "You are already a member of that group"
+#: classes/Notice.php:194
+msgid ""
+"Too many duplicate messages too quickly; take a breather and post again in a "
+"few minutes."
msgstr ""
-#: actions/joingroup.php:128 actions/joingroup.php:133 lib/command.php:234
-#, php-format
-msgid "Could not join user %s to group %s"
+#: classes/Notice.php:202
+msgid "You are banned from posting notices on this site."
+msgstr ""
+
+#: classes/Notice.php:268 classes/Notice.php:293
+msgid "Problem saving notice."
msgstr ""
-#: actions/joingroup.php:135 actions/joingroup.php:140 lib/command.php:239
+#: classes/Notice.php:1120
#, php-format
-msgid "%s joined group %s"
+msgid "DB error inserting reply: %s"
msgstr ""
-#: actions/leavegroup.php:60
-msgid "Inboxes must be enabled for groups to work."
+#: classes/User.php:333
+#, php-format
+msgid "Welcome to %1$s, @%2$s!"
msgstr ""
-#: actions/leavegroup.php:65 actions/leavegroup.php:60
-msgid "You must be logged in to leave a group."
+#: lib/accountsettingsaction.php:108 lib/personalgroupnav.php:109
+msgid "Profile"
msgstr ""
-#: actions/leavegroup.php:88 actions/groupblock.php:86
-#: actions/groupunblock.php:86 actions/makeadmin.php:86
-#: actions/foafgroup.php:44 actions/foafgroup.php:62 actions/leavegroup.php:83
-#: lib/command.php:212 lib/command.php:263
-msgid "No such group."
+#: lib/accountsettingsaction.php:109
+msgid "Change your profile settings"
msgstr ""
-#: actions/leavegroup.php:95 actions/leavegroup.php:90 lib/command.php:268
-msgid "You are not a member of that group."
+#: lib/accountsettingsaction.php:112
+msgid "Upload an avatar"
msgstr ""
-#: actions/leavegroup.php:100
-msgid "You may not leave a group while you are its administrator."
+#: lib/accountsettingsaction.php:115
+msgid "Change your password"
msgstr ""
-#: actions/leavegroup.php:130 actions/leavegroup.php:124
-#: actions/leavegroup.php:119 lib/command.php:278
-msgid "Could not find membership record."
+#: lib/accountsettingsaction.php:118
+msgid "Change email handling"
msgstr ""
-#: actions/leavegroup.php:138 actions/leavegroup.php:132
-#: actions/leavegroup.php:127 lib/command.php:284
-#, php-format
-msgid "Could not remove user %s to group %s"
+#: lib/accountsettingsaction.php:120 lib/groupnav.php:118
+msgid "Design"
msgstr ""
-#: actions/leavegroup.php:145 actions/leavegroup.php:139
-#: actions/leavegroup.php:134 lib/command.php:289
-#, php-format
-msgid "%s left group %s"
+#: lib/accountsettingsaction.php:121
+msgid "Design your profile"
msgstr ""
-#: actions/login.php:225 lib/facebookaction.php:304 actions/login.php:208
-#: actions/login.php:216 actions/login.php:243
-msgid "Login to site"
+#: lib/accountsettingsaction.php:123
+msgid "Other"
msgstr ""
-#: actions/microsummary.php:69
-msgid "No current status"
+#: lib/accountsettingsaction.php:124
+msgid "Other options"
msgstr ""
-#: actions/newgroup.php:53
-msgid "New group"
+#: lib/action.php:144
+#, php-format
+msgid "%s - %s"
msgstr ""
-#: actions/newgroup.php:115 actions/newgroup.php:110
-msgid "Use this form to create a new group."
+#: lib/action.php:159
+msgid "Untitled page"
msgstr ""
-#: actions/newgroup.php:177 actions/newgroup.php:209
-#: actions/apigroupcreate.php:136 actions/newgroup.php:204
-msgid "Could not create group."
+#: lib/action.php:424
+msgid "Primary site navigation"
msgstr ""
-#: actions/newgroup.php:191 actions/newgroup.php:229
-#: actions/apigroupcreate.php:166 actions/newgroup.php:224
-msgid "Could not set group membership."
+#: lib/action.php:430
+msgid "Home"
msgstr ""
-#: actions/newmessage.php:119 actions/newnotice.php:132
-msgid "That's too long. "
+#: lib/action.php:430
+msgid "Personal profile and friends timeline"
msgstr ""
-#: actions/newmessage.php:134
-msgid "Don't send a message to yourself; "
+#: lib/action.php:432
+msgid "Account"
msgstr ""
-#: actions/newnotice.php:166 actions/newnotice.php:174
-#: actions/newnotice.php:272 actions/newnotice.php:199
-msgid "Notice posted"
+#: lib/action.php:432
+msgid "Change your email, avatar, password, profile"
msgstr ""
-#: actions/newnotice.php:200 classes/Channel.php:163 actions/newnotice.php:208
-#: lib/channel.php:170 actions/newmessage.php:207 actions/newnotice.php:387
-#: actions/newmessage.php:210 actions/newnotice.php:233
-msgid "Ajax Error"
+#: lib/action.php:435
+msgid "Connect"
msgstr ""
-#: actions/nudge.php:85
-msgid ""
-"This user doesn't allow nudges or hasn't confirmed or set his email yet."
+#: lib/action.php:435
+msgid "Connect to services"
msgstr ""
-#: actions/nudge.php:94
-msgid "Nudge sent"
+#: lib/action.php:439 lib/subgroupnav.php:105
+msgid "Invite"
msgstr ""
-#: actions/nudge.php:97
-msgid "Nudge sent!"
+#: lib/action.php:440 lib/subgroupnav.php:106
+#, php-format
+msgid "Invite friends and colleagues to join you on %s"
msgstr ""
-#: actions/openidlogin.php:97 actions/openidlogin.php:106
-msgid "OpenID login"
+#: lib/action.php:445
+msgid "Logout"
msgstr ""
-#: actions/openidsettings.php:128
-msgid "Removing your only OpenID "
+#: lib/action.php:445
+msgid "Logout from the site"
msgstr ""
-#: actions/othersettings.php:60
-msgid "Other Settings"
+#: lib/action.php:450
+msgid "Create an account"
msgstr ""
-#: actions/othersettings.php:71
-msgid "Manage various other options."
+#: lib/action.php:453
+msgid "Login to the site"
msgstr ""
-#: actions/othersettings.php:93
-msgid "URL Auto-shortening"
+#: lib/action.php:456 lib/action.php:719
+msgid "Help"
msgstr ""
-#: actions/othersettings.php:112
-msgid "Service"
+#: lib/action.php:456
+msgid "Help me!"
msgstr ""
-#: actions/othersettings.php:113 actions/othersettings.php:111
-#: actions/othersettings.php:118
-msgid "Automatic shortening service to use."
+#: lib/action.php:459
+msgid "Search"
msgstr ""
-#: actions/othersettings.php:144 actions/othersettings.php:146
-#: actions/othersettings.php:153
-msgid "URL shortening service is too long (max 50 chars)."
+#: lib/action.php:459
+msgid "Search for users or text"
msgstr ""
-#: actions/passwordsettings.php:69
-msgid "Change your password."
+#: lib/action.php:480
+msgid "Site notice"
msgstr ""
-#: actions/passwordsettings.php:89 actions/recoverpassword.php:228
-#: actions/passwordsettings.php:95 actions/recoverpassword.php:231
-msgid "Password change"
+#: lib/action.php:546
+msgid "Local views"
msgstr ""
-#: actions/peopletag.php:35 actions/peopletag.php:70
-#, php-format
-msgid "Not a valid people tag: %s"
+#: lib/action.php:612
+msgid "Page notice"
msgstr ""
-#: actions/peopletag.php:47 actions/peopletag.php:144
-#, php-format
-msgid "Users self-tagged with %s - page %d"
+#: lib/action.php:714
+msgid "Secondary site navigation"
msgstr ""
-#: actions/peopletag.php:91
-#, php-format
-msgid "These are users who have tagged themselves \"%s\" "
+#: lib/action.php:721
+msgid "About"
msgstr ""
-#: actions/profilesettings.php:91 actions/profilesettings.php:99
-msgid "Profile information"
+#: lib/action.php:723
+msgid "FAQ"
msgstr ""
-#: actions/profilesettings.php:124 actions/profilesettings.php:125
-#: actions/profilesettings.php:140
-msgid ""
-"Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated"
+#: lib/action.php:727
+msgid "TOS"
msgstr ""
-#: actions/profilesettings.php:144
-msgid "Automatically subscribe to whoever "
+#: lib/action.php:730
+msgid "Privacy"
msgstr ""
-#: actions/profilesettings.php:229 actions/tagother.php:176
-#: actions/tagother.php:178 actions/profilesettings.php:230
-#: actions/profilesettings.php:246
-#, php-format
-msgid "Invalid tag: \"%s\""
+#: lib/action.php:732
+msgid "Source"
msgstr ""
-#: actions/profilesettings.php:311 actions/profilesettings.php:310
-#: actions/profilesettings.php:336
-msgid "Couldn't save tags."
+#: lib/action.php:734
+msgid "Contact"
msgstr ""
-#: actions/public.php:107 actions/public.php:110 actions/public.php:118
-#: actions/public.php:129
-#, php-format
-msgid "Public timeline, page %d"
+#: lib/action.php:736
+msgid "Badge"
msgstr ""
-#: actions/public.php:173 actions/public.php:184 actions/public.php:210
-#: actions/public.php:92
-msgid "Could not retrieve public stream."
+#: lib/action.php:764
+msgid "StatusNet software license"
msgstr ""
-#: actions/public.php:220
+#: lib/action.php:767
#, php-format
msgid ""
-"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
-"blogging) service "
+"**%%site.name%%** is a microblogging service brought to you by [%%site."
+"broughtby%%](%%site.broughtbyurl%%). "
msgstr ""
-#: actions/publictagcloud.php:57
-msgid "Public tag cloud"
+#: lib/action.php:769
+#, php-format
+msgid "**%%site.name%%** is a microblogging service. "
msgstr ""
-#: actions/publictagcloud.php:63
+#: lib/action.php:771
#, php-format
-msgid "These are most popular recent tags on %s "
+msgid ""
+"It runs the [StatusNet](http://status.net/) microblogging software, version %"
+"s, available under the [GNU Affero General Public License](http://www.fsf."
+"org/licensing/licenses/agpl-3.0.html)."
msgstr ""
-#: actions/publictagcloud.php:119 actions/publictagcloud.php:135
-msgid "Tag cloud"
+#: lib/action.php:785
+msgid "Site content license"
msgstr ""
-#: actions/register.php:139 actions/register.php:349 actions/register.php:79
-#: actions/register.php:177 actions/register.php:394 actions/register.php:183
-#: actions/register.php:398 actions/register.php:85 actions/register.php:189
-#: actions/register.php:404
-msgid "Sorry, only invited people can register."
+#: lib/action.php:794
+msgid "All "
msgstr ""
-#: actions/register.php:149
-msgid "You can't register if you don't "
+#: lib/action.php:799
+msgid "license."
msgstr ""
-#: actions/register.php:286
-msgid "With this form you can create "
+#: lib/action.php:1053
+msgid "Pagination"
msgstr ""
-#: actions/register.php:368
-msgid "1-64 lowercase letters or numbers, "
+#: lib/action.php:1062
+msgid "After"
msgstr ""
-#: actions/register.php:382 actions/register.php:386
-msgid "Used only for updates, announcements, "
+#: lib/action.php:1070
+msgid "Before"
msgstr ""
-#: actions/register.php:398
-msgid "URL of your homepage, blog, "
-msgstr ""
-
-#: actions/register.php:404
-msgid "Describe yourself and your "
+#: lib/attachmentlist.php:87
+msgid "Attachments"
msgstr ""
-#: actions/register.php:410
-msgid "Where you are, like \"City, "
+#: lib/attachmentlist.php:265
+msgid "Author"
msgstr ""
-#: actions/register.php:432
-msgid " except this private data: password, "
+#: lib/attachmentlist.php:278
+msgid "Provider"
msgstr ""
-#: actions/register.php:471
-#, php-format
-msgid "Congratulations, %s! And welcome to %%%%site.name%%%%. "
+#: lib/attachmentnoticesection.php:67
+msgid "Notices where this attachment appears"
msgstr ""
-#: actions/register.php:495
-msgid "(You should receive a message by email "
+#: lib/attachmenttagcloudsection.php:48
+msgid "Tags for this attachment"
msgstr ""
-#: actions/remotesubscribe.php:166 actions/remotesubscribe.php:171
-msgid "That's a local profile! Login to subscribe."
+#: lib/channel.php:138 lib/channel.php:158
+msgid "Command results"
msgstr ""
-#: actions/replies.php:118 actions/replies.php:120 actions/replies.php:119
-#: actions/replies.php:127
-#, php-format
-msgid "Replies to %s, page %d"
+#: lib/channel.php:210
+msgid "Command complete"
msgstr ""
-#: actions/showfavorites.php:79
-#, php-format
-msgid "%s favorite notices, page %d"
+#: lib/channel.php:221
+msgid "Command failed"
msgstr ""
-#: actions/showgroup.php:77 lib/groupnav.php:85 actions/showgroup.php:82
-#, php-format
-msgid "%s group"
+#: lib/command.php:44
+msgid "Sorry, this command is not yet implemented."
msgstr ""
-#: actions/showgroup.php:79 actions/showgroup.php:84
+#: lib/command.php:88
#, php-format
-msgid "%s group, page %d"
-msgstr ""
-
-#: actions/showgroup.php:206 actions/showgroup.php:208
-#: actions/showgroup.php:213 actions/showgroup.php:218
-msgid "Group profile"
-msgstr ""
-
-#: actions/showgroup.php:251 actions/showstream.php:278
-#: actions/tagother.php:119 lib/grouplist.php:134 lib/profilelist.php:133
-#: actions/showgroup.php:253 actions/showstream.php:271
-#: actions/tagother.php:118 lib/profilelist.php:131 actions/showgroup.php:258
-#: actions/showstream.php:236 actions/userauthorization.php:137
-#: lib/profilelist.php:197 actions/showgroup.php:263
-#: actions/showstream.php:295 actions/userauthorization.php:167
-#: lib/profilelist.php:230 lib/userprofile.php:177
-msgid "URL"
+msgid "Could not find a user with nickname %s"
msgstr ""
-#: actions/showgroup.php:262 actions/showstream.php:289
-#: actions/tagother.php:129 lib/grouplist.php:145 lib/profilelist.php:144
-#: actions/showgroup.php:264 actions/showstream.php:282
-#: actions/tagother.php:128 lib/profilelist.php:142 actions/showgroup.php:269
-#: actions/showstream.php:247 actions/userauthorization.php:149
-#: lib/profilelist.php:212 actions/showgroup.php:274
-#: actions/showstream.php:312 actions/userauthorization.php:179
-#: lib/profilelist.php:245 lib/userprofile.php:194
-msgid "Note"
+#: lib/command.php:92
+msgid "It does not make a lot of sense to nudge yourself!"
msgstr ""
-#: actions/showgroup.php:270 actions/showgroup.php:272
-#: actions/showgroup.php:288 actions/showgroup.php:293
-msgid "Group actions"
+#: lib/command.php:99
+#, php-format
+msgid "Nudge sent to %s"
msgstr ""
-#: actions/showgroup.php:323 actions/showgroup.php:304
+#: lib/command.php:126
#, php-format
-msgid "Notice feed for %s group"
+msgid ""
+"Subscriptions: %1$s\n"
+"Subscribers: %2$s\n"
+"Notices: %3$s"
msgstr ""
-#: actions/showgroup.php:357 lib/groupnav.php:90 actions/showgroup.php:339
-#: actions/showgroup.php:384 actions/showgroup.php:373
-#: actions/showgroup.php:430 actions/showgroup.php:381
-#: actions/showgroup.php:438
-msgid "Members"
+#: lib/command.php:152 lib/command.php:400
+msgid "Notice with that id does not exist"
msgstr ""
-#: actions/showgroup.php:363 actions/showstream.php:413
-#: actions/showstream.php:442 actions/showstream.php:524 lib/section.php:95
-#: lib/tagcloudsection.php:71 actions/showgroup.php:344
-#: actions/showgroup.php:378 lib/profileaction.php:117
-#: lib/profileaction.php:148 lib/profileaction.php:226
-#: actions/showgroup.php:386
-msgid "(None)"
+#: lib/command.php:168 lib/command.php:416 lib/command.php:471
+msgid "User has no last notice"
msgstr ""
-#: actions/showgroup.php:370 actions/showgroup.php:350
-#: actions/showgroup.php:384 actions/showgroup.php:392
-msgid "All members"
+#: lib/command.php:190
+msgid "Notice marked as fave."
msgstr ""
-#: actions/showgroup.php:378
+#: lib/command.php:315
#, php-format
-msgid ""
-"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service "
+msgid "%1$s (%2$s)"
msgstr ""
-#: actions/showmessage.php:98
-msgid "Only the sender and recipient "
+#: lib/command.php:318
+#, php-format
+msgid "Fullname: %s"
msgstr ""
-#: actions/showstream.php:73 actions/showstream.php:78
-#: actions/showstream.php:79
+#: lib/command.php:321
#, php-format
-msgid "%s, page %d"
+msgid "Location: %s"
msgstr ""
-#: actions/showstream.php:143
-msgid "'s profile"
+#: lib/command.php:324
+#, php-format
+msgid "Homepage: %s"
msgstr ""
-#: actions/showstream.php:236 actions/tagother.php:77
-#: actions/showstream.php:220 actions/showstream.php:185
-#: actions/showstream.php:193 lib/userprofile.php:75
-msgid "User profile"
+#: lib/command.php:327
+#, php-format
+msgid "About: %s"
msgstr ""
-#: actions/showstream.php:240 actions/tagother.php:81
-#: actions/showstream.php:224 actions/showstream.php:189
-#: actions/showstream.php:220 lib/userprofile.php:102
-msgid "Photo"
+#: lib/command.php:358 scripts/xmppdaemon.php:321
+#, php-format
+msgid "Message too long - maximum is %d characters, you sent %d"
msgstr ""
-#: actions/showstream.php:317 actions/showstream.php:309
-#: actions/showstream.php:274 actions/showstream.php:354
-#: lib/userprofile.php:236
-msgid "User actions"
+#: lib/command.php:377
+msgid "Error sending direct message."
msgstr ""
-#: actions/showstream.php:342 actions/showstream.php:307
-#: actions/showstream.php:390 lib/userprofile.php:272
-msgid "Send a direct message to this user"
+#: lib/command.php:431
+#, php-format
+msgid "Notice too long - maximum is %d characters, you sent %d"
msgstr ""
-#: actions/showstream.php:343 actions/showstream.php:308
-#: actions/showstream.php:391 lib/userprofile.php:273
-msgid "Message"
+#: lib/command.php:439
+#, php-format
+msgid "Reply to %s sent"
msgstr ""
-#: actions/showstream.php:451 lib/profileaction.php:157
-msgid "All subscribers"
+#: lib/command.php:441
+msgid "Error saving notice."
msgstr ""
-#: actions/showstream.php:533 lib/profileaction.php:235
-msgid "All groups"
+#: lib/command.php:495
+msgid "Specify the name of the user to subscribe to"
msgstr ""
-#: actions/showstream.php:542
+#: lib/command.php:502
#, php-format
-msgid ""
-"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service "
+msgid "Subscribed to %s"
msgstr ""
-#: actions/smssettings.php:128
-msgid "Phone number, no punctuation or spaces, "
+#: lib/command.php:523
+msgid "Specify the name of the user to unsubscribe from"
msgstr ""
-#: actions/smssettings.php:162
-msgid "Send me notices through SMS; "
+#: lib/command.php:530
+#, php-format
+msgid "Unsubscribed from %s"
msgstr ""
-#: actions/smssettings.php:335
-msgid "A confirmation code was sent to the phone number you added. "
+#: lib/command.php:548 lib/command.php:571
+msgid "Command not yet implemented."
msgstr ""
-#: actions/smssettings.php:453 actions/smssettings.php:465
-msgid "Mobile carrier"
+#: lib/command.php:551
+msgid "Notification off."
msgstr ""
-#: actions/subedit.php:70
-msgid "You are not subscribed to that profile."
+#: lib/command.php:553
+msgid "Can't turn off notification."
msgstr ""
-#: actions/subedit.php:83
-msgid "Could not save subscription."
+#: lib/command.php:574
+msgid "Notification on."
msgstr ""
-#: actions/subscribe.php:55
-msgid "Not a local user."
+#: lib/command.php:576
+msgid "Can't turn on notification."
msgstr ""
-#: actions/subscribe.php:69
-msgid "Subscribed"
+#: lib/command.php:597
+#, php-format
+msgid "Could not create login token for %s"
msgstr ""
-#: actions/subscribers.php:50
+#: lib/command.php:602
#, php-format
-msgid "%s subscribers"
+msgid "This link is useable only once, and is good for only 2 minutes: %s"
msgstr ""
-#: actions/subscribers.php:52
-#, php-format
-msgid "%s subscribers, page %d"
+#: lib/command.php:613
+msgid ""
+"Commands:\n"
+"on - turn on notifications\n"
+"off - turn off notifications\n"
+"help - show this help\n"
+"follow - subscribe to user\n"
+"leave - unsubscribe from user\n"
+"d - direct message to user\n"
+"get - get last notice from user\n"
+"whois - get profile info on user\n"
+"fav - add user's last notice as a 'fave'\n"
+"fav # - add notice with the given id as a 'fave'\n"
+"reply # - reply to notice with a given id\n"
+"reply - reply to the last notice from user\n"
+"join - join group\n"
+"login - Get a link to login to the web interface\n"
+"drop - leave group\n"
+"stats - get your stats\n"
+"stop - same as 'off'\n"
+"quit - same as 'off'\n"
+"sub - same as 'follow'\n"
+"unsub - same as 'leave'\n"
+"last - same as 'get'\n"
+"on - not yet implemented.\n"
+"off - not yet implemented.\n"
+"nudge - remind a user to update.\n"
+"invite - not yet implemented.\n"
+"track - not yet implemented.\n"
+"untrack - not yet implemented.\n"
+"track off - not yet implemented.\n"
+"untrack all - not yet implemented.\n"
+"tracks - not yet implemented.\n"
+"tracking - not yet implemented.\n"
msgstr ""
-#: actions/subscribers.php:63
-msgid "These are the people who listen to "
+#: lib/common.php:191
+msgid "No configuration file found. "
msgstr ""
-#: actions/subscribers.php:67
-#, php-format
-msgid "These are the people who "
+#: lib/common.php:192
+msgid "I looked for configuration files in the following places: "
msgstr ""
-#: actions/subscriptions.php:52
-#, php-format
-msgid "%s subscriptions"
+#: lib/common.php:193
+msgid "You may wish to run the installer to fix this."
msgstr ""
-#: actions/subscriptions.php:54
-#, php-format
-msgid "%s subscriptions, page %d"
+#: lib/common.php:194
+msgid "Go to the installer."
msgstr ""
-#: actions/subscriptions.php:65
-msgid "These are the people whose notices "
+#: lib/connectsettingsaction.php:110
+msgid "IM"
msgstr ""
-#: actions/subscriptions.php:69
-#, php-format
-msgid "These are the people whose "
+#: lib/connectsettingsaction.php:111
+msgid "Updates by instant messenger (IM)"
msgstr ""
-#: actions/subscriptions.php:122 actions/subscriptions.php:124
-#: actions/subscriptions.php:183 actions/subscriptions.php:194
-msgid "Jabber"
+#: lib/connectsettingsaction.php:116
+msgid "Updates by SMS"
msgstr ""
-#: actions/tag.php:43 actions/tag.php:51 actions/tag.php:59 actions/tag.php:68
-#, php-format
-msgid "Notices tagged with %s, page %d"
+#: lib/dberroraction.php:60
+msgid "Database error"
msgstr ""
-#: actions/tag.php:66 actions/tag.php:73
-#, php-format
-msgid "Messages tagged \"%s\", most recent first"
+#: lib/designsettings.php:101
+msgid "Change background image"
msgstr ""
-#: actions/tagother.php:33
-msgid "Not logged in"
+#: lib/designsettings.php:105
+msgid "Upload file"
msgstr ""
-#: actions/tagother.php:39
-msgid "No id argument."
+#: lib/designsettings.php:109
+msgid ""
+"You can upload your personal background image. The maximum file size is 2Mb."
msgstr ""
-#: actions/tagother.php:65
-#, php-format
-msgid "Tag %s"
+#: lib/designsettings.php:139
+msgid "On"
msgstr ""
-#: actions/tagother.php:141
-msgid "Tag user"
+#: lib/designsettings.php:155
+msgid "Off"
msgstr ""
-#: actions/tagother.php:149 actions/tagother.php:151
-msgid ""
-"Tags for this user (letters, numbers, -, ., and _), comma- or space- "
-"separated"
+#: lib/designsettings.php:156
+msgid "Turn background image on or off."
msgstr ""
-#: actions/tagother.php:164
-msgid "There was a problem with your session token."
+#: lib/designsettings.php:161
+msgid "Tile background image"
msgstr ""
-#: actions/tagother.php:191 actions/tagother.php:193
-msgid ""
-"You can only tag people you are subscribed to or who are subscribed to you."
+#: lib/designsettings.php:170
+msgid "Change colours"
msgstr ""
-#: actions/tagother.php:198 actions/tagother.php:200
-msgid "Could not save tags."
+#: lib/designsettings.php:178
+msgid "Background"
msgstr ""
-#: actions/tagother.php:233 actions/tagother.php:235 actions/tagother.php:236
-msgid "Use this form to add tags to your subscribers or subscriptions."
+#: lib/designsettings.php:191
+msgid "Content"
msgstr ""
-#: actions/tagrss.php:35
-msgid "No such tag."
+#: lib/designsettings.php:204
+msgid "Sidebar"
msgstr ""
-#: actions/tagrss.php:66 actions/tagrss.php:64
-#, php-format
-msgid "Microblog tagged with %s"
+#: lib/designsettings.php:217
+msgid "Text"
msgstr ""
-#: actions/twitapiblocks.php:47 actions/twitapiblocks.php:49
-#: actions/apiblockcreate.php:108
-msgid "Block user failed."
+#: lib/designsettings.php:230
+msgid "Links"
msgstr ""
-#: actions/twitapiblocks.php:69 actions/twitapiblocks.php:71
-#: actions/apiblockdestroy.php:107
-msgid "Unblock user failed."
+#: lib/designsettings.php:247
+msgid "Use defaults"
msgstr ""
-#: actions/twitapiusers.php:48 actions/twitapiusers.php:52
-#: actions/twitapiusers.php:50 actions/apiusershow.php:96
-msgid "Not found."
+#: lib/designsettings.php:248
+msgid "Restore default designs"
msgstr ""
-#: actions/twittersettings.php:71
-msgid "Add your Twitter account to automatically send "
+#: lib/designsettings.php:254
+msgid "Reset back to default"
msgstr ""
-#: actions/twittersettings.php:119 actions/twittersettings.php:122
-msgid "Twitter user name"
+#: lib/designsettings.php:257
+msgid "Save design"
msgstr ""
-#: actions/twittersettings.php:126 actions/twittersettings.php:129
-msgid "Twitter password"
+#: lib/designsettings.php:372
+msgid "Bad default color settings: "
msgstr ""
-#: actions/twittersettings.php:228 actions/twittersettings.php:232
-#: actions/twittersettings.php:248
-msgid "Twitter Friends"
+#: lib/designsettings.php:468
+msgid "Design defaults restored."
msgstr ""
-#: actions/twittersettings.php:327
-msgid "Username must have only numbers, "
+#: lib/disfavorform.php:114 lib/disfavorform.php:140
+msgid "Disfavor this notice"
msgstr ""
-#: actions/twittersettings.php:341
-#, php-format
-msgid "Unable to retrieve account information "
+#: lib/favorform.php:114 lib/favorform.php:140
+msgid "Favor this notice"
msgstr ""
-#: actions/unblock.php:108 actions/groupunblock.php:128
-msgid "Error removing the block."
+#: lib/favorform.php:140
+msgid "Favor"
msgstr ""
-#: actions/unsubscribe.php:50 actions/unsubscribe.php:77
-msgid "No profile id in request."
+#: lib/feedlist.php:64
+msgid "Export data"
msgstr ""
-#: actions/unsubscribe.php:57 actions/unsubscribe.php:84
-msgid "No profile with that id."
+#: lib/feed.php:85
+msgid "RSS 1.0"
msgstr ""
-#: actions/unsubscribe.php:71 actions/unsubscribe.php:98
-msgid "Unsubscribed"
-msgstr ""
-
-#: actions/usergroups.php:63 actions/usergroups.php:62
-#: actions/apigrouplistall.php:90
-#, php-format
-msgid "%s groups"
-msgstr ""
-
-#: actions/usergroups.php:65 actions/usergroups.php:64
-#, php-format
-msgid "%s groups, page %d"
-msgstr ""
-
-#: classes/Notice.php:104 classes/Notice.php:128 classes/Notice.php:144
-#: classes/Notice.php:183
-msgid "Problem saving notice. Unknown user."
-msgstr ""
-
-#: classes/Notice.php:109 classes/Notice.php:133 classes/Notice.php:149
-#: classes/Notice.php:188
-msgid ""
-"Too many notices too fast; take a breather and post again in a few minutes."
-msgstr ""
-
-#: classes/Notice.php:116 classes/Notice.php:145 classes/Notice.php:161
-#: classes/Notice.php:202
-msgid "You are banned from posting notices on this site."
-msgstr ""
-
-#: lib/accountsettingsaction.php:108 lib/accountsettingsaction.php:112
-msgid "Upload an avatar"
+#: lib/feed.php:87
+msgid "RSS 2.0"
msgstr ""
-#: lib/accountsettingsaction.php:119 lib/accountsettingsaction.php:122
-#: lib/accountsettingsaction.php:123
-msgid "Other"
+#: lib/feed.php:89
+msgid "Atom"
msgstr ""
-#: lib/accountsettingsaction.php:120 lib/accountsettingsaction.php:123
-#: lib/accountsettingsaction.php:124
-msgid "Other options"
+#: lib/feed.php:91
+msgid "FOAF"
msgstr ""
-#: lib/action.php:130 lib/action.php:132 lib/action.php:142 lib/action.php:144
-#, php-format
-msgid "%s - %s"
+#: lib/galleryaction.php:121
+msgid "Filter tags"
msgstr ""
-#: lib/action.php:145 lib/action.php:147 lib/action.php:157 lib/action.php:159
-msgid "Untitled page"
+#: lib/galleryaction.php:131
+msgid "All"
msgstr ""
-#: lib/action.php:316 lib/action.php:387 lib/action.php:411 lib/action.php:424
-msgid "Primary site navigation"
+#: lib/galleryaction.php:139
+msgid "Select tag to filter"
msgstr ""
-#: lib/action.php:322 lib/action.php:393 lib/action.php:417 lib/action.php:430
-msgid "Personal profile and friends timeline"
+#: lib/galleryaction.php:140
+msgid "Tag"
msgstr ""
-#: lib/action.php:325 lib/action.php:396 lib/action.php:448 lib/action.php:459
-msgid "Search for people or text"
+#: lib/galleryaction.php:141
+msgid "Choose a tag to narrow list"
msgstr ""
-#: lib/action.php:328 lib/action.php:399 lib/action.php:419 lib/action.php:432
-msgid "Account"
+#: lib/galleryaction.php:143
+msgid "Go"
msgstr ""
-#: lib/action.php:328 lib/action.php:399 lib/action.php:419 lib/action.php:432
-msgid "Change your email, avatar, password, profile"
+#: lib/groupeditform.php:163
+msgid "URL of the homepage or blog of the group or topic"
msgstr ""
-#: lib/action.php:330 lib/action.php:403 lib/action.php:422
-msgid "Connect to IM, SMS, Twitter"
+#: lib/groupeditform.php:168
+msgid "Describe the group or topic"
msgstr ""
-#: lib/action.php:332 lib/action.php:409 lib/action.php:435 lib/action.php:445
-msgid "Logout from the site"
+#: lib/groupeditform.php:170
+#, php-format
+msgid "Describe the group or topic in %d characters"
msgstr ""
-#: lib/action.php:335 lib/action.php:412 lib/action.php:443 lib/action.php:453
-msgid "Login to the site"
+#: lib/groupeditform.php:172
+msgid "Description"
msgstr ""
-#: lib/action.php:338 lib/action.php:415 lib/action.php:440 lib/action.php:450
-msgid "Create an account"
+#: lib/groupeditform.php:179
+msgid ""
+"Location for the group, if any, like \"City, State (or Region), Country\""
msgstr ""
-#: lib/action.php:341 lib/action.php:418
-msgid "Login with OpenID"
+#: lib/groupeditform.php:187
+#, php-format
+msgid "Extra nicknames for the group, comma- or space- separated, max %d"
msgstr ""
-#: lib/action.php:344 lib/action.php:421 lib/action.php:446 lib/action.php:456
-msgid "Help me!"
+#: lib/groupnav.php:84 lib/searchgroupnav.php:84
+msgid "Group"
msgstr ""
-#: lib/action.php:362 lib/action.php:441 lib/action.php:468 lib/action.php:480
-msgid "Site notice"
+#: lib/groupnav.php:100
+msgid "Blocked"
msgstr ""
-#: lib/action.php:417 lib/action.php:504 lib/action.php:531 lib/action.php:546
-msgid "Local views"
+#: lib/groupnav.php:101
+#, php-format
+msgid "%s blocked users"
msgstr ""
-#: lib/action.php:472 lib/action.php:559 lib/action.php:597 lib/action.php:612
-msgid "Page notice"
+#: lib/groupnav.php:107
+#, php-format
+msgid "Edit %s group properties"
msgstr ""
-#: lib/action.php:562 lib/action.php:654 lib/action.php:699 lib/action.php:714
-msgid "Secondary site navigation"
+#: lib/groupnav.php:112
+msgid "Logo"
msgstr ""
-#: lib/action.php:602 lib/action.php:623 lib/action.php:699 lib/action.php:720
-#: lib/action.php:749 lib/action.php:770 lib/action.php:764
-msgid "StatusNet software license"
+#: lib/groupnav.php:113
+#, php-format
+msgid "Add or edit %s logo"
msgstr ""
-#: lib/action.php:630 lib/action.php:727 lib/action.php:779 lib/action.php:794
-msgid "All "
+#: lib/groupnav.php:119
+#, php-format
+msgid "Add or edit %s design"
msgstr ""
-#: lib/action.php:635 lib/action.php:732 lib/action.php:784 lib/action.php:799
-msgid "license."
+#: lib/groupsbymemberssection.php:71
+msgid "Groups with most members"
msgstr ""
-#: lib/blockform.php:123 lib/blockform.php:153 actions/groupmembers.php:343
-#: actions/groupmembers.php:346
-msgid "Block this user"
+#: lib/groupsbypostssection.php:71
+msgid "Groups with most posts"
msgstr ""
-#: lib/blockform.php:153 actions/groupmembers.php:343
-#: actions/groupmembers.php:346
-msgid "Block"
+#: lib/grouptagcloudsection.php:56
+#, php-format
+msgid "Tags in %s group's notices"
msgstr ""
-#: lib/disfavorform.php:114 lib/disfavorform.php:140
-msgid "Disfavor this notice"
+#: lib/htmloutputter.php:104
+msgid "This page is not available in a media type you accept"
msgstr ""
-#: lib/facebookaction.php:268
+#: lib/imagefile.php:75
#, php-format
-msgid "To use the %s Facebook Application you need to login "
+msgid "That file is too big. The maximum file size is %s."
msgstr ""
-#: lib/facebookaction.php:271 lib/facebookaction.php:273
-#: lib/facebookaction.php:275
-msgid " a new account."
+#: lib/imagefile.php:80
+msgid "Partial upload."
msgstr ""
-#: lib/facebookaction.php:557 lib/mailbox.php:214 lib/noticelist.php:354
-#: lib/facebookaction.php:675 lib/mailbox.php:216 lib/noticelist.php:357
-#: lib/mailbox.php:217 lib/noticelist.php:361
-msgid "Published"
+#: lib/imagefile.php:88 lib/mediafile.php:170
+msgid "System error uploading file."
msgstr ""
-#: lib/favorform.php:114 lib/favorform.php:140
-msgid "Favor this notice"
+#: lib/imagefile.php:96
+msgid "Not an image or corrupt file."
msgstr ""
-#: lib/feedlist.php:64
-msgid "Export data"
+#: lib/imagefile.php:105
+msgid "Unsupported image file format."
msgstr ""
-#: lib/galleryaction.php:121
-msgid "Filter tags"
+#: lib/imagefile.php:118
+msgid "Lost our file."
msgstr ""
-#: lib/galleryaction.php:131
-msgid "All"
+#: lib/imagefile.php:150 lib/imagefile.php:197
+msgid "Unknown file type"
msgstr ""
-#: lib/galleryaction.php:137 lib/galleryaction.php:138
-#: lib/galleryaction.php:140
-msgid "Tag"
+#: lib/jabber.php:192
+#, php-format
+msgid "notice id: %s"
msgstr ""
-#: lib/galleryaction.php:138 lib/galleryaction.php:139
-#: lib/galleryaction.php:141
-msgid "Choose a tag to narrow list"
+#: lib/joinform.php:114
+msgid "Join"
msgstr ""
-#: lib/galleryaction.php:139 lib/galleryaction.php:141
-#: lib/galleryaction.php:143
-msgid "Go"
+#: lib/leaveform.php:114
+msgid "Leave"
msgstr ""
-#: lib/groupeditform.php:148 lib/groupeditform.php:163
-msgid "URL of the homepage or blog of the group or topic"
+#: lib/logingroupnav.php:80
+msgid "Login with a username and password"
msgstr ""
-#: lib/groupeditform.php:151 lib/groupeditform.php:166
-#: lib/groupeditform.php:172
-msgid "Description"
+#: lib/logingroupnav.php:86
+msgid "Sign up for a new account"
msgstr ""
-#: lib/groupeditform.php:153 lib/groupeditform.php:168
-msgid "Describe the group or topic in 140 chars"
+#: lib/mailbox.php:89
+msgid "Only the user can read their own mailboxes."
msgstr ""
-#: lib/groupeditform.php:158 lib/groupeditform.php:173
-#: lib/groupeditform.php:179
+#: lib/mailbox.php:139
msgid ""
-"Location for the group, if any, like \"City, State (or Region), Country\""
-msgstr ""
-
-#: lib/groupnav.php:84 lib/searchgroupnav.php:84
-msgid "Group"
-msgstr ""
-
-#: lib/groupnav.php:100 actions/groupmembers.php:175 lib/groupnav.php:106
-msgid "Admin"
+"You have no private messages. You can send private message to engage other "
+"users in conversation. People can send you messages for your eyes only."
msgstr ""
-#: lib/groupnav.php:101 lib/groupnav.php:107
-#, php-format
-msgid "Edit %s group properties"
+#: lib/mailbox.php:227 lib/noticelist.php:424
+msgid "from"
msgstr ""
-#: lib/groupnav.php:106 lib/groupnav.php:112
-msgid "Logo"
+#: lib/mail.php:172
+msgid "Email address confirmation"
msgstr ""
-#: lib/groupnav.php:107 lib/groupnav.php:113
+#: lib/mail.php:174
#, php-format
-msgid "Add or edit %s logo"
-msgstr ""
-
-#: lib/groupsbymemberssection.php:71
-msgid "Groups with most members"
-msgstr ""
-
-#: lib/groupsbypostssection.php:71
-msgid "Groups with most posts"
+msgid ""
+"Hey, %s.\n"
+"\n"
+"Someone just entered this email address on %s.\n"
+"\n"
+"If it was you, and you want to confirm your entry, use the URL below:\n"
+"\n"
+"\t%s\n"
+"\n"
+"If not, just ignore this message.\n"
+"\n"
+"Thanks for your time, \n"
+"%s\n"
msgstr ""
-#: lib/grouptagcloudsection.php:56
+#: lib/mail.php:235
#, php-format
-msgid "Tags in %s group's notices"
-msgstr ""
-
-#: lib/htmloutputter.php:104
-msgid "This page is not available in a "
-msgstr ""
-
-#: lib/joinform.php:114
-msgid "Join"
-msgstr ""
-
-#: lib/leaveform.php:114
-msgid "Leave"
-msgstr ""
-
-#: lib/logingroupnav.php:76 lib/logingroupnav.php:80
-msgid "Login with a username and password"
-msgstr ""
-
-#: lib/logingroupnav.php:79 lib/logingroupnav.php:86
-msgid "Sign up for a new account"
-msgstr ""
-
-#: lib/logingroupnav.php:82
-msgid "Login or register with OpenID"
+msgid "%1$s is now listening to your notices on %2$s."
msgstr ""
-#: lib/mail.php:175
+#: lib/mail.php:240
#, php-format
msgid ""
-"Hey, %s.\n"
+"%1$s is now listening to your notices on %2$s.\n"
"\n"
+"\t%3$s\n"
+"\n"
+"%4$s%5$s%6$s\n"
+"Faithfully yours,\n"
+"%7$s.\n"
+"\n"
+"----\n"
+"Change your email address or notification options at %8$s\n"
msgstr ""
-#: lib/mail.php:236
-#, php-format
-msgid "%1$s is now listening to "
-msgstr ""
-
-#: lib/mail.php:254 lib/mail.php:253
+#: lib/mail.php:253
#, php-format
msgid "Location: %s\n"
msgstr ""
-#: lib/mail.php:256 lib/mail.php:255
+#: lib/mail.php:255
#, php-format
msgid "Homepage: %s\n"
msgstr ""
-#: lib/mail.php:258 lib/mail.php:257
+#: lib/mail.php:257
#, php-format
msgid ""
"Bio: %s\n"
"\n"
msgstr ""
-#: lib/mail.php:461 lib/mail.php:462
+#: lib/mail.php:285
#, php-format
-msgid "You've been nudged by %s"
+msgid "New email address for posting to %s"
msgstr ""
-#: lib/mail.php:465
+#: lib/mail.php:288
#, php-format
-msgid "%1$s (%2$s) is wondering what you are up to "
+msgid ""
+"You have a new posting address on %1$s.\n"
+"\n"
+"Send email to %2$s to post new messages.\n"
+"\n"
+"More email instructions at %3$s.\n"
+"\n"
+"Faithfully yours,\n"
+"%4$s"
msgstr ""
-#: lib/mail.php:555
+#: lib/mail.php:412
#, php-format
-msgid "%1$s just added your notice from %2$s"
+msgid "%s status"
msgstr ""
-#: lib/mailbox.php:229 lib/noticelist.php:380 lib/mailbox.php:231
-#: lib/noticelist.php:383 lib/mailbox.php:232 lib/noticelist.php:388
-msgid "From"
+#: lib/mail.php:438
+msgid "SMS confirmation"
msgstr ""
-#: lib/messageform.php:110 lib/messageform.php:109 lib/messageform.php:120
-msgid "Send a direct notice"
+#: lib/mail.php:462
+#, php-format
+msgid "You've been nudged by %s"
msgstr ""
-#: lib/noticeform.php:125 lib/noticeform.php:128 lib/noticeform.php:145
-msgid "Send a notice"
+#: lib/mail.php:466
+#, php-format
+msgid ""
+"%1$s (%2$s) is wondering what you are up to these days and is inviting you "
+"to post some news.\n"
+"\n"
+"So let's hear from you :)\n"
+"\n"
+"%3$s\n"
+"\n"
+"Don't reply to this email; it won't get to them.\n"
+"\n"
+"With kind regards,\n"
+"%4$s\n"
msgstr ""
-#: lib/noticeform.php:152 lib/noticeform.php:149 lib/messageform.php:162
-#: lib/noticeform.php:173
-msgid "Available characters"
+#: lib/mail.php:509
+#, php-format
+msgid "New private message from %s"
msgstr ""
-#: lib/noticelist.php:426 lib/noticelist.php:429
-msgid "in reply to"
-msgstr ""
-
-#: lib/noticelist.php:447 lib/noticelist.php:450 lib/noticelist.php:451
-#: lib/noticelist.php:454 lib/noticelist.php:458 lib/noticelist.php:461
-#: lib/noticelist.php:498
-msgid "Reply to this notice"
-msgstr ""
-
-#: lib/noticelist.php:451 lib/noticelist.php:455 lib/noticelist.php:462
-#: lib/noticelist.php:499
-msgid "Reply"
-msgstr ""
-
-#: lib/noticelist.php:471 lib/noticelist.php:474 lib/noticelist.php:476
-#: lib/noticelist.php:479 actions/deletenotice.php:116 lib/noticelist.php:483
-#: lib/noticelist.php:486 actions/deletenotice.php:146 lib/noticelist.php:522
-msgid "Delete this notice"
+#: lib/mail.php:513
+#, php-format
+msgid ""
+"%1$s (%2$s) sent you a private message:\n"
+"\n"
+"------------------------------------------------------\n"
+"%3$s\n"
+"------------------------------------------------------\n"
+"\n"
+"You can reply to their message here:\n"
+"\n"
+"%4$s\n"
+"\n"
+"Don't reply to this email; it won't get to them.\n"
+"\n"
+"With kind regards,\n"
+"%5$s\n"
msgstr ""
-#: lib/noticelist.php:474 actions/avatarsettings.php:148
-#: lib/noticelist.php:479 lib/noticelist.php:486 lib/noticelist.php:522
-msgid "Delete"
+#: lib/mail.php:554
+#, php-format
+msgid "%s (@%s) added your notice as a favorite"
msgstr ""
-#: lib/nudgeform.php:116
-msgid "Nudge this user"
+#: lib/mail.php:556
+#, php-format
+msgid ""
+"%1$s (@%7$s) just added your notice from %2$s as one of their favorites.\n"
+"\n"
+"The URL of your notice is:\n"
+"\n"
+"%3$s\n"
+"\n"
+"The text of your notice is:\n"
+"\n"
+"%4$s\n"
+"\n"
+"You can see the list of %1$s's favorites here:\n"
+"\n"
+"%5$s\n"
+"\n"
+"Faithfully yours,\n"
+"%6$s\n"
msgstr ""
-#: lib/nudgeform.php:128
-msgid "Nudge"
+#: lib/mail.php:611
+#, php-format
+msgid "%s (@%s) sent a notice to your attention"
msgstr ""
-#: lib/nudgeform.php:128
-msgid "Send a nudge to this user"
+#: lib/mail.php:613
+#, php-format
+msgid ""
+"%1$s (@%9$s) just sent a notice to your attention (an '@-reply') on %2$s.\n"
+"\n"
+"The notice is here:\n"
+"\n"
+"\t%3$s\n"
+"\n"
+"It reads:\n"
+"\n"
+"\t%4$s\n"
+"\n"
msgstr ""
-#: lib/personaltagcloudsection.php:56
-#, php-format
-msgid "Tags in %s's notices"
+#: lib/mediafile.php:98 lib/mediafile.php:123
+msgid "There was a database error while saving your file. Please try again."
msgstr ""
-#: lib/profilelist.php:182 lib/profilelist.php:180
-#: lib/subscriptionlist.php:126
-msgid "(none)"
+#: lib/mediafile.php:142
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini."
msgstr ""
-#: lib/publicgroupnav.php:76 lib/publicgroupnav.php:78
-msgid "Public"
+#: lib/mediafile.php:147
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form."
msgstr ""
-#: lib/publicgroupnav.php:80 lib/publicgroupnav.php:82
-msgid "User groups"
+#: lib/mediafile.php:152
+msgid "The uploaded file was only partially uploaded."
msgstr ""
-#: lib/publicgroupnav.php:82 lib/publicgroupnav.php:83
-#: lib/publicgroupnav.php:84 lib/publicgroupnav.php:85
-msgid "Recent tags"
+#: lib/mediafile.php:159
+msgid "Missing a temporary folder."
msgstr ""
-#: lib/publicgroupnav.php:86 lib/publicgroupnav.php:88
-msgid "Featured"
+#: lib/mediafile.php:162
+msgid "Failed to write file to disk."
msgstr ""
-#: lib/publicgroupnav.php:90 lib/publicgroupnav.php:92
-msgid "Popular"
+#: lib/mediafile.php:165
+msgid "File upload stopped by extension."
msgstr ""
-#: lib/searchgroupnav.php:82
-msgid "Notice"
+#: lib/mediafile.php:179 lib/mediafile.php:216
+msgid "File exceeds user's quota!"
msgstr ""
-#: lib/searchgroupnav.php:85
-msgid "Find groups on this site"
+#: lib/mediafile.php:196 lib/mediafile.php:233
+msgid "File could not be moved to destination directory."
msgstr ""
-#: lib/section.php:89
-msgid "Untitled section"
+#: lib/mediafile.php:201 lib/mediafile.php:237
+msgid "Could not determine file's mime-type!"
msgstr ""
-#: lib/subgroupnav.php:81 lib/subgroupnav.php:83
+#: lib/mediafile.php:270
#, php-format
-msgid "People %s subscribes to"
+msgid " Try using another %s format."
msgstr ""
-#: lib/subgroupnav.php:89 lib/subgroupnav.php:91
+#: lib/mediafile.php:275
#, php-format
-msgid "People subscribed to %s"
+msgid "%s is not a supported filetype on this server."
msgstr ""
-#: lib/subgroupnav.php:97 lib/subgroupnav.php:99
-#, php-format
-msgid "Groups %s is a member of"
+#: lib/messageform.php:120
+msgid "Send a direct notice"
msgstr ""
-#: lib/subgroupnav.php:104 lib/action.php:430 lib/subgroupnav.php:106
-#: lib/action.php:440
-#, php-format
-msgid "Invite friends and colleagues to join you on %s"
+#: lib/messageform.php:146
+msgid "To"
msgstr ""
-#: lib/subs.php:53 lib/subs.php:52
-msgid "User has blocked you."
+#: lib/messageform.php:162 lib/noticeform.php:173
+msgid "Available characters"
msgstr ""
-#: lib/subscribeform.php:115 lib/subscribeform.php:139
-#: actions/userauthorization.php:178 actions/userauthorization.php:210
-msgid "Subscribe to this user"
+#: lib/noticeform.php:145
+msgid "Send a notice"
msgstr ""
-#: lib/tagcloudsection.php:56
-msgid "None"
+#: lib/noticeform.php:158
+#, php-format
+msgid "What's up, %s?"
msgstr ""
-#: lib/topposterssection.php:74
-msgid "Top posters"
+#: lib/noticeform.php:180
+msgid "Attach"
msgstr ""
-#: lib/unblockform.php:120 lib/unblockform.php:150
-#: actions/blockedfromgroup.php:313
-msgid "Unblock this user"
+#: lib/noticeform.php:184
+msgid "Attach a file"
msgstr ""
-#: lib/unblockform.php:150 actions/blockedfromgroup.php:313
-msgid "Unblock"
+#: lib/noticelist.php:478
+msgid "in context"
msgstr ""
-#: lib/unsubscribeform.php:113 lib/unsubscribeform.php:137
-msgid "Unsubscribe from this user"
+#: lib/noticelist.php:498
+msgid "Reply to this notice"
msgstr ""
-#: actions/all.php:77 actions/all.php:59 actions/all.php:99
-#, php-format
-msgid "Feed for friends of %s (RSS 1.0)"
+#: lib/noticelist.php:499
+msgid "Reply"
msgstr ""
-#: actions/all.php:82 actions/all.php:64 actions/all.php:107
-#, php-format
-msgid "Feed for friends of %s (RSS 2.0)"
+#: lib/nudgeform.php:116
+msgid "Nudge this user"
msgstr ""
-#: actions/all.php:87 actions/all.php:69 actions/all.php:115
-#, php-format
-msgid "Feed for friends of %s (Atom)"
+#: lib/nudgeform.php:128
+msgid "Nudge"
msgstr ""
-#: actions/all.php:112 actions/all.php:125 actions/all.php:165
-msgid "You and friends"
+#: lib/nudgeform.php:128
+msgid "Send a nudge to this user"
msgstr ""
-#: actions/avatarsettings.php:78
-#, php-format
-msgid "You can upload your personal avatar. The maximum file size is %s."
+#: lib/oauthstore.php:283
+msgid "Error inserting new profile"
msgstr ""
-#: actions/avatarsettings.php:373 actions/avatarsettings.php:387
-msgid "Avatar deleted."
+#: lib/oauthstore.php:291
+msgid "Error inserting avatar"
msgstr ""
-#: actions/block.php:129 actions/block.php:136
-msgid ""
-"Are you sure you want to block this user? Afterwards, they will be "
-"unsubscribed from you, unable to subscribe to you in the future, and you "
-"will not be notified of any @-replies from them."
+#: lib/oauthstore.php:311
+msgid "Error inserting remote profile"
msgstr ""
-#: actions/deletenotice.php:73 actions/deletenotice.php:103
-msgid ""
-"You are about to permanently delete a notice. Once this is done, it cannot "
-"be undone."
+#: lib/oauthstore.php:345
+msgid "Duplicate notice"
msgstr ""
-#: actions/deletenotice.php:127 actions/deletenotice.php:157
-msgid "There was a problem with your session token. Try again, please."
+#: lib/oauthstore.php:487
+msgid "Couldn't insert new subscription."
msgstr ""
-#: actions/emailsettings.php:168 actions/emailsettings.php:174
-msgid "Send me email when someone sends me an \"@-reply\"."
+#: lib/personalgroupnav.php:99
+msgid "Personal"
msgstr ""
-#: actions/facebookhome.php:193 actions/facebookhome.php:187
-#, php-format
-msgid ""
-"If you would like the %s app to automatically update your Facebook status "
-"with your latest notice, you need to give it permission."
+#: lib/personalgroupnav.php:104
+msgid "Replies"
msgstr ""
-#: actions/facebookhome.php:217 actions/facebookhome.php:211
-#, php-format
-msgid "Okay, do it!"
+#: lib/personalgroupnav.php:114
+msgid "Favorites"
msgstr ""
-#: actions/facebooksettings.php:124
-#, php-format
-msgid ""
-"If you would like %s to automatically update your Facebook status with your "
-"latest notice, you need to give it permission."
+#: lib/personalgroupnav.php:115
+msgid "User"
msgstr ""
-#: actions/grouplogo.php:155 actions/grouplogo.php:150
-#, php-format
-msgid ""
-"You can upload a logo image for your group. The maximum file size is %s."
+#: lib/personalgroupnav.php:124
+msgid "Inbox"
msgstr ""
-#: actions/grouplogo.php:367 actions/grouplogo.php:362
-msgid "Pick a square area of the image to be the logo."
+#: lib/personalgroupnav.php:125
+msgid "Your incoming messages"
msgstr ""
-#: actions/grouprss.php:136 actions/grouprss.php:137
-#, php-format
-msgid "Microblog by %s group"
+#: lib/personalgroupnav.php:129
+msgid "Outbox"
msgstr ""
-#: actions/groupsearch.php:57 actions/groupsearch.php:52
-#, php-format
-msgid ""
-"Search for groups on %%site.name%% by their name, location, or description. "
-"Separate the terms by spaces; they must be 3 characters or more."
+#: lib/personalgroupnav.php:130
+msgid "Your sent messages"
msgstr ""
-#: actions/groups.php:90
+#: lib/personaltagcloudsection.php:56
#, php-format
-msgid ""
-"%%%%site.name%%%% groups let you find and talk with people of similar "
-"interests. After you join a group you can send messages to all other members "
-"using the syntax \"!groupname\". Don't see a group you like? Try [searching "
-"for one](%%%%action.groupsearch%%%%) or [start your own!](%%%%action.newgroup"
-"%%%%)"
+msgid "Tags in %s's notices"
msgstr ""
-#: actions/newmessage.php:102
-msgid "Only logged-in users can send direct messages."
+#: lib/profileaction.php:109 lib/profileaction.php:191 lib/subgroupnav.php:82
+msgid "Subscriptions"
msgstr ""
-#: actions/noticesearch.php:91
-#, php-format
-msgid "Search results for \"%s\" on %s"
+#: lib/profileaction.php:126
+msgid "All subscriptions"
msgstr ""
-#: actions/openidlogin.php:66
-#, php-format
-msgid ""
-"For security reasons, please re-login with your [OpenID](%%doc.openid%%) "
-"before changing your settings."
+#: lib/profileaction.php:140 lib/profileaction.php:200 lib/subgroupnav.php:90
+msgid "Subscribers"
msgstr ""
-#: actions/public.php:125 actions/public.php:133 actions/public.php:151
-msgid "Public Stream Feed (RSS 1.0)"
+#: lib/profileaction.php:157
+msgid "All subscribers"
msgstr ""
-#: actions/public.php:130 actions/public.php:138 actions/public.php:155
-msgid "Public Stream Feed (RSS 2.0)"
+#: lib/profileaction.php:177
+msgid "User ID"
msgstr ""
-#: actions/public.php:135 actions/public.php:143 actions/public.php:159
-msgid "Public Stream Feed (Atom)"
+#: lib/profileaction.php:182
+msgid "Member since"
msgstr ""
-#: actions/public.php:210 actions/public.php:241 actions/public.php:233
-#, php-format
-msgid ""
-"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
-"blogging) service based on the Free Software [StatusNet](http://status.net/) "
-"tool. [Join now](%%action.register%%) to share notices about yourself with "
-"friends, family, and colleagues! ([Read more](%%doc.help%%))"
+#: lib/profileaction.php:235
+msgid "All groups"
msgstr ""
-#: actions/register.php:286 actions/register.php:329
-#, php-format
-msgid ""
-"With this form you can create a new account. You can then post notices and "
-"link up to friends and colleagues. (Have an [OpenID](http://openid.net/)? "
-"Try our [OpenID registration](%%action.openidlogin%%)!)"
+#: lib/publicgroupnav.php:78
+msgid "Public"
msgstr ""
-#: actions/register.php:432 actions/register.php:479 actions/register.php:489
-#: actions/register.php:495
-msgid "Creative Commons Attribution 3.0"
+#: lib/publicgroupnav.php:82
+msgid "User groups"
msgstr ""
-#: actions/register.php:433 actions/register.php:480 actions/register.php:490
-#: actions/register.php:496
-msgid ""
-" except this private data: password, email address, IM address, and phone "
-"number."
+#: lib/publicgroupnav.php:84 lib/publicgroupnav.php:85
+msgid "Recent tags"
msgstr ""
-#: actions/showgroup.php:378 actions/showgroup.php:424
-#: actions/showgroup.php:432
-msgid "Created"
+#: lib/publicgroupnav.php:88
+msgid "Featured"
msgstr ""
-#: actions/showgroup.php:393 actions/showgroup.php:440
-#: actions/showgroup.php:448
-#, php-format
-msgid ""
-"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. Its members share short messages about "
-"their life and interests. [Join now](%%%%action.register%%%%) to become part "
-"of this group and many more! ([Read more](%%%%doc.help%%%%))"
+#: lib/publicgroupnav.php:92
+msgid "Popular"
msgstr ""
-#: actions/showstream.php:147
-msgid "Your profile"
+#: lib/searchaction.php:120
+msgid "Search site"
msgstr ""
-#: actions/showstream.php:149
-#, php-format
-msgid "%s's profile"
+#: lib/searchaction.php:162
+msgid "Search help"
msgstr ""
-#: actions/showstream.php:163 actions/showstream.php:128
-#: actions/showstream.php:129
-#, php-format
-msgid "Notice feed for %s (RSS 1.0)"
+#: lib/searchgroupnav.php:80
+msgid "People"
msgstr ""
-#: actions/showstream.php:170 actions/showstream.php:135
-#: actions/showstream.php:136
-#, php-format
-msgid "Notice feed for %s (RSS 2.0)"
+#: lib/searchgroupnav.php:81
+msgid "Find people on this site"
msgstr ""
-#: actions/showstream.php:177 actions/showstream.php:142
-#: actions/showstream.php:143
-#, php-format
-msgid "Notice feed for %s (Atom)"
+#: lib/searchgroupnav.php:82
+msgid "Notice"
msgstr ""
-#: actions/showstream.php:182 actions/showstream.php:147
-#: actions/showstream.php:148
-#, php-format
-msgid "FOAF for %s"
+#: lib/searchgroupnav.php:83
+msgid "Find content of notices"
msgstr ""
-#: actions/showstream.php:237 actions/showstream.php:202
-#: actions/showstream.php:234 lib/userprofile.php:116
-msgid "Edit Avatar"
+#: lib/searchgroupnav.php:85
+msgid "Find groups on this site"
msgstr ""
-#: actions/showstream.php:316 actions/showstream.php:281
-#: actions/showstream.php:366 lib/userprofile.php:248
-msgid "Edit profile settings"
+#: lib/section.php:89
+msgid "Untitled section"
msgstr ""
-#: actions/showstream.php:317 actions/showstream.php:282
-#: actions/showstream.php:367 lib/userprofile.php:249
-msgid "Edit"
+#: lib/section.php:106
+msgid "More..."
msgstr ""
-#: actions/showstream.php:542 actions/showstream.php:388
-#: actions/showstream.php:487 actions/showstream.php:234
+#: lib/subgroupnav.php:83
#, php-format
-msgid ""
-"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. [Join now](%%%%action.register%%%%) to "
-"follow **%s**'s notices and many more! ([Read more](%%%%doc.help%%%%))"
+msgid "People %s subscribes to"
msgstr ""
-#: actions/smssettings.php:335 actions/smssettings.php:347
-msgid ""
-"A confirmation code was sent to the phone number you added. Check your phone "
-"for the code and instructions on how to use it."
+#: lib/subgroupnav.php:91
+#, php-format
+msgid "People subscribed to %s"
msgstr ""
-#: actions/twitapifavorites.php:171 lib/mail.php:556
-#: actions/twitapifavorites.php:222
+#: lib/subgroupnav.php:99
#, php-format
-msgid ""
-"%1$s just added your notice from %2$s as one of their favorites.\n"
-"\n"
-"In case you forgot, you can see the text of your notice here:\n"
-"\n"
-"%3$s\n"
-"\n"
-"You can see the list of %1$s's favorites here:\n"
-"\n"
-"%4$s\n"
-"\n"
-"Faithfully yours,\n"
-"%5$s\n"
+msgid "Groups %s is a member of"
msgstr ""
-#: actions/twitapistatuses.php:124 actions/twitapistatuses.php:82
-#: actions/twitapistatuses.php:314 actions/apiblockcreate.php:97
-#: actions/apiblockdestroy.php:96 actions/apidirectmessage.php:77
-#: actions/apidirectmessagenew.php:75 actions/apigroupcreate.php:112
-#: actions/apigroupismember.php:90 actions/apigroupjoin.php:99
-#: actions/apigroupleave.php:99 actions/apigrouplist.php:90
-#: actions/apistatusesupdate.php:125 actions/apisubscriptions.php:87
-#: actions/apitimelinefavorites.php:70 actions/apitimelinefriends.php:79
-#: actions/apitimelinementions.php:79 actions/apitimelineuser.php:81
-#: actions/apiaccountupdateprofileimage.php:91
-#: actions/apiaccountupdateprofileimage.php:105
-#: actions/apistatusesupdate.php:139
-msgid "No such user!"
+#: lib/subscriberspeopleselftagcloudsection.php:48
+#: lib/subscriptionspeopleselftagcloudsection.php:48
+msgid "People Tagcloud as self-tagged"
msgstr ""
-#: actions/twittersettings.php:72
-msgid ""
-"Add your Twitter account to automatically send your notices to Twitter, and "
-"subscribe to Twitter friends already here."
+#: lib/subscriberspeopletagcloudsection.php:48
+#: lib/subscriptionspeopletagcloudsection.php:48
+msgid "People Tagcloud as tagged"
msgstr ""
-#: actions/twittersettings.php:345 actions/twittersettings.php:362
-#, php-format
-msgid "Unable to retrieve account information For \"%s\" from Twitter."
+#: lib/subscriptionlist.php:126
+msgid "(none)"
msgstr ""
-#: actions/userauthorization.php:86 actions/userauthorization.php:81
-msgid ""
-"Please check these details to make sure that you want to subscribe to this "
-"user's notices. If you didn't just ask to subscribe to someone's notices, "
-"click \"Reject\"."
+#: lib/subs.php:48
+msgid "Already subscribed!"
msgstr ""
-#: actions/usergroups.php:131 actions/usergroups.php:130
-msgid "Search for more groups"
+#: lib/subs.php:52
+msgid "User has blocked you."
msgstr ""
-#: classes/Notice.php:138 classes/Notice.php:154 classes/Notice.php:194
-msgid ""
-"Too many duplicate messages too quickly; take a breather and post again in a "
-"few minutes."
+#: lib/subs.php:56
+msgid "Could not subscribe."
msgstr ""
-#: lib/action.php:406 lib/action.php:425
-msgid "Connect to SMS, Twitter"
+#: lib/subs.php:75
+msgid "Could not subscribe other to you."
msgstr ""
-#: lib/action.php:671 lib/action.php:721 lib/action.php:736
-msgid "Badge"
+#: lib/subs.php:124
+msgid "Not subscribed!."
msgstr ""
-#: lib/command.php:113 lib/command.php:106 lib/command.php:126
-#, php-format
-msgid ""
-"Subscriptions: %1$s\n"
-"Subscribers: %2$s\n"
-"Notices: %3$s"
+#: lib/subs.php:136
+msgid "Couldn't delete subscription."
msgstr ""
-#: lib/dberroraction.php:60
-msgid "Database error"
+#: lib/tagcloudsection.php:56
+msgid "None"
msgstr ""
-#: lib/facebookaction.php:271 lib/facebookaction.php:273
-#, php-format
-msgid ""
-"To use the %s Facebook Application you need to login with your username and "
-"password. Don't have a username yet? "
+#: lib/topposterssection.php:74
+msgid "Top posters"
msgstr ""
-#: lib/feed.php:85
-msgid "RSS 1.0"
+#: lib/unsubscribeform.php:113 lib/unsubscribeform.php:137
+msgid "Unsubscribe from this user"
msgstr ""
-#: lib/feed.php:87
-msgid "RSS 2.0"
+#: lib/unsubscribeform.php:137
+msgid "Unsubscribe"
msgstr ""
-#: lib/feed.php:89
-msgid "Atom"
+#: lib/userprofile.php:116
+msgid "Edit Avatar"
msgstr ""
-#: lib/feed.php:91
-msgid "FOAF"
+#: lib/userprofile.php:236
+msgid "User actions"
msgstr ""
-#: lib/imagefile.php:75
-#, php-format
-msgid "That file is too big. The maximum file size is %d."
+#: lib/userprofile.php:248
+msgid "Edit profile settings"
msgstr ""
-#: lib/mail.php:175 lib/mail.php:174
-#, php-format
-msgid ""
-"Hey, %s.\n"
-"\n"
-"Someone just entered this email address on %s.\n"
-"\n"
-"If it was you, and you want to confirm your entry, use the URL below:\n"
-"\n"
-"\t%s\n"
-"\n"
-"If not, just ignore this message.\n"
-"\n"
-"Thanks for your time, \n"
-"%s\n"
+#: lib/userprofile.php:249
+msgid "Edit"
msgstr ""
-#: lib/mail.php:241 lib/mail.php:240
-#, php-format
-msgid ""
-"%1$s is now listening to your notices on %2$s.\n"
-"\n"
-"\t%3$s\n"
-"\n"
-"%4$s%5$s%6$s\n"
-"Faithfully yours,\n"
-"%7$s.\n"
-"\n"
-"----\n"
-"Change your email address or notification options at %8$s\n"
+#: lib/userprofile.php:272
+msgid "Send a direct message to this user"
msgstr ""
-#: lib/mail.php:466
-#, php-format
-msgid ""
-"%1$s (%2$s) is wondering what you are up to these days and is inviting you "
-"to post some news.\n"
-"\n"
-"So let's hear from you :)\n"
-"\n"
-"%3$s\n"
-"\n"
-"Don't reply to this email; it won't get to them.\n"
-"\n"
-"With kind regards,\n"
-"%4$s\n"
+#: lib/userprofile.php:273
+msgid "Message"
msgstr ""
-#: lib/mail.php:513
-#, php-format
-msgid ""
-"%1$s (%2$s) sent you a private message:\n"
-"\n"
-"------------------------------------------------------\n"
-"%3$s\n"
-"------------------------------------------------------\n"
-"\n"
-"You can reply to their message here:\n"
-"\n"
-"%4$s\n"
-"\n"
-"Don't reply to this email; it won't get to them.\n"
-"\n"
-"With kind regards,\n"
-"%5$s\n"
+#: lib/util.php:844
+msgid "a few seconds ago"
msgstr ""
-#: lib/mail.php:598 lib/mail.php:600
-#, php-format
-msgid "%s sent a notice to your attention"
+#: lib/util.php:846
+msgid "about a minute ago"
msgstr ""
-#: lib/mail.php:600 lib/mail.php:602
+#: lib/util.php:848
#, php-format
-msgid ""
-"%1$s just sent a notice to your attention (an '@-reply') on %2$s.\n"
-"\n"
-"The notice is here:\n"
-"\n"
-"\t%3$s\n"
-"\n"
-"It reads:\n"
-"\n"
-"\t%4$s\n"
-"\n"
-"You can reply back here:\n"
-"\n"
-"\t%5$s\n"
-"\n"
-"The list of all @-replies for you here:\n"
-"\n"
-"%6$s\n"
-"\n"
-"Faithfully yours,\n"
-"%2$s\n"
-"\n"
-"P.S. You can turn off these email notifications here: %7$s\n"
-msgstr ""
-
-#: lib/searchaction.php:122 lib/searchaction.php:120
-msgid "Search site"
-msgstr ""
-
-#: lib/section.php:106
-msgid "More..."
+msgid "about %d minutes ago"
msgstr ""
-#: actions/all.php:80 actions/all.php:127
-#, php-format
-msgid ""
-"This is the timeline for %s and friends but no one has posted anything yet."
+#: lib/util.php:850
+msgid "about an hour ago"
msgstr ""
-#: actions/all.php:85 actions/all.php:132
+#: lib/util.php:852
#, php-format
-msgid ""
-"Try subscribing to more people, [join a group](%%action.groups%%) or post "
-"something yourself."
+msgid "about %d hours ago"
msgstr ""
-#: actions/all.php:87 actions/all.php:134
-#, php-format
-msgid ""
-"You can try to [nudge %s](../%s) from his profile or [post something to his "
-"or her attention](%%%%action.newnotice%%%%?status_textarea=%s)."
+#: lib/util.php:854
+msgid "about a day ago"
msgstr ""
-#: actions/all.php:91 actions/replies.php:190 actions/showstream.php:361
-#: actions/all.php:137 actions/replies.php:209 actions/showstream.php:455
-#: actions/showstream.php:202
+#: lib/util.php:856
#, php-format
-msgid ""
-"Why not [register an account](%%%%action.register%%%%) and then nudge %s or "
-"post a notice to his or her attention."
+msgid "about %d days ago"
msgstr ""
-#: actions/attachment.php:73
-msgid "No such attachment."
+#: lib/util.php:858
+msgid "about a month ago"
msgstr ""
-#: actions/block.php:149
-msgid "Do not block this user from this group"
+#: lib/util.php:860
+#, php-format
+msgid "about %d months ago"
msgstr ""
-#: actions/block.php:150
-msgid "Block this user from this group"
+#: lib/util.php:862
+msgid "about a year ago"
msgstr ""
-#: actions/blockedfromgroup.php:90
+#: lib/webcolor.php:82
#, php-format
-msgid "%s blocked profiles"
+msgid "%s is not a valid color!"
msgstr ""
-#: actions/blockedfromgroup.php:93
+#: lib/webcolor.php:123
#, php-format
-msgid "%s blocked profiles, page %d"
-msgstr ""
-
-#: actions/blockedfromgroup.php:108
-msgid "A list of the users blocked from joining this group."
-msgstr ""
-
-#: actions/blockedfromgroup.php:281
-msgid "Unblock user from group"
-msgstr ""
-
-#: actions/conversation.php:99
-msgid "Conversation"
+msgid "%s is not a valid color! Use 3 or 6 hex chars."
msgstr ""
-#: actions/deletenotice.php:115 actions/deletenotice.php:145
-msgid "Do not delete this notice"
+#: scripts/maildaemon.php:48
+msgid "Could not parse message."
msgstr ""
-#: actions/editgroup.php:214 actions/newgroup.php:164
-#: actions/apigroupcreate.php:291 actions/editgroup.php:215
-#: actions/newgroup.php:159
-#, php-format
-msgid "Too many aliases! Maximum %d."
+#: scripts/maildaemon.php:53
+msgid "Not a registered user."
msgstr ""
-#: actions/editgroup.php:223 actions/newgroup.php:173
-#: actions/apigroupcreate.php:312 actions/editgroup.php:224
-#: actions/newgroup.php:168
-#, php-format
-msgid "Invalid alias: \"%s\""
+#: scripts/maildaemon.php:57
+msgid "Sorry, that is not your incoming email address."
msgstr ""
-#: actions/editgroup.php:227 actions/newgroup.php:177
-#: actions/apigroupcreate.php:321 actions/editgroup.php:228
-#: actions/newgroup.php:172
-#, php-format
-msgid "Alias \"%s\" already in use. Try another one."
-msgstr ""
-
-#: actions/editgroup.php:233 actions/newgroup.php:183
-#: actions/apigroupcreate.php:334 actions/editgroup.php:234
-#: actions/newgroup.php:178
-msgid "Alias can't be the same as nickname."
-msgstr ""
-
-#: actions/editgroup.php:259 actions/newgroup.php:215
-#: actions/apigroupcreate.php:147 actions/newgroup.php:210
-msgid "Could not create aliases."
-msgstr ""
-
-#: actions/favorited.php:150
-msgid "Favorite notices appear on this page but no one has favorited one yet."
-msgstr ""
-
-#: actions/favorited.php:153
-msgid ""
-"Be the first to add a notice to your favorites by clicking the fave button "
-"next to any notice you like."
-msgstr ""
-
-#: actions/favorited.php:156
-#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and be the first to add a "
-"notice to your favorites!"
-msgstr ""
-
-#: actions/file.php:34
-msgid "No notice id"
-msgstr ""
-
-#: actions/file.php:38
-msgid "No notice"
-msgstr ""
-
-#: actions/file.php:42
-msgid "No attachments"
-msgstr ""
-
-#: actions/file.php:51
-msgid "No uploaded attachments"
-msgstr ""
-
-#: actions/finishopenidlogin.php:211
-msgid "Not a valid invitation code."
-msgstr ""
-
-#: actions/groupblock.php:81 actions/groupunblock.php:81
-#: actions/makeadmin.php:81
-msgid "No group specified."
-msgstr ""
-
-#: actions/groupblock.php:91
-msgid "Only an admin can block group members."
-msgstr ""
-
-#: actions/groupblock.php:95
-msgid "User is already blocked from group."
-msgstr ""
-
-#: actions/groupblock.php:100
-msgid "User is not a member of group."
-msgstr ""
-
-#: actions/groupblock.php:136 actions/groupmembers.php:311
-#: actions/groupmembers.php:314
-msgid "Block user from group"
-msgstr ""
-
-#: actions/groupblock.php:155
-#, php-format
-msgid ""
-"Are you sure you want to block user \"%s\" from the group \"%s\"? They will "
-"be removed from the group, unable to post, and unable to subscribe to the "
-"group in the future."
-msgstr ""
-
-#: actions/groupblock.php:193
-msgid "Database error blocking user from group."
-msgstr ""
-
-#: actions/groupdesignsettings.php:73 actions/groupdesignsettings.php:68
-msgid "You must be logged in to edit a group."
-msgstr ""
-
-#: actions/groupdesignsettings.php:146 actions/groupdesignsettings.php:141
-msgid "Group design"
-msgstr ""
-
-#: actions/groupdesignsettings.php:157 actions/groupdesignsettings.php:152
-msgid ""
-"Customize the way your group looks with a background image and a colour "
-"palette of your choice."
-msgstr ""
-
-#: actions/groupdesignsettings.php:267 actions/userdesignsettings.php:186
-#: lib/designsettings.php:440 lib/designsettings.php:470
-#: actions/groupdesignsettings.php:262 lib/designsettings.php:431
-#: lib/designsettings.php:461 lib/designsettings.php:434
-#: lib/designsettings.php:464
-msgid "Couldn't update your design."
-msgstr ""
-
-#: actions/groupdesignsettings.php:291 actions/groupdesignsettings.php:301
-#: actions/userdesignsettings.php:210 actions/userdesignsettings.php:220
-#: actions/userdesignsettings.php:263 actions/userdesignsettings.php:273
-#: actions/groupdesignsettings.php:286 actions/groupdesignsettings.php:296
-msgid "Unable to save your design settings!"
-msgstr ""
-
-#: actions/groupdesignsettings.php:312 actions/userdesignsettings.php:231
-#: actions/groupdesignsettings.php:307
-msgid "Design preferences saved."
-msgstr ""
-
-#: actions/groupmembers.php:438 actions/groupmembers.php:441
-msgid "Make user an admin of the group"
-msgstr ""
-
-#: actions/groupmembers.php:470 actions/groupmembers.php:473
-msgid "Make Admin"
-msgstr ""
-
-#: actions/groupmembers.php:470 actions/groupmembers.php:473
-msgid "Make this user an admin"
-msgstr ""
-
-#: actions/groupsearch.php:79 actions/noticesearch.php:117
-#: actions/peoplesearch.php:83
-msgid "No results."
-msgstr ""
-
-#: actions/groupsearch.php:82
-#, php-format
-msgid ""
-"If you can't find the group you're looking for, you can [create it](%%action."
-"newgroup%%) yourself."
-msgstr ""
-
-#: actions/groupsearch.php:85
-#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and [create the group](%%"
-"action.newgroup%%) yourself!"
-msgstr ""
-
-#: actions/groupunblock.php:91
-msgid "Only an admin can unblock group members."
-msgstr ""
-
-#: actions/groupunblock.php:95
-msgid "User is not blocked from group."
-msgstr ""
-
-#: actions/invite.php:39
-msgid "Invites have been disabled."
-msgstr ""
-
-#: actions/joingroup.php:100 actions/apigroupjoin.php:119
-#: actions/joingroup.php:95 lib/command.php:221
-msgid "You have been blocked from that group by the admin."
-msgstr ""
-
-#: actions/makeadmin.php:91
-msgid "Only an admin can make another user an admin."
-msgstr ""
-
-#: actions/makeadmin.php:95
-#, php-format
-msgid "%s is already an admin for group \"%s\"."
-msgstr ""
-
-#: actions/makeadmin.php:132
-#, php-format
-msgid "Can't get membership record for %s in group %s"
-msgstr ""
-
-#: actions/makeadmin.php:145
-#, php-format
-msgid "Can't make %s an admin for group %s"
-msgstr ""
-
-#: actions/newmessage.php:178 actions/newmessage.php:181
-msgid "Message sent"
-msgstr ""
-
-#: actions/newnotice.php:93 lib/designsettings.php:281
-#: actions/newnotice.php:94 actions/apiaccountupdateprofileimage.php:97
-#: actions/apistatusesupdate.php:122 actions/avatarsettings.php:254
-#: lib/designsettings.php:283
-#, php-format
-msgid ""
-"The server was unable to handle that much POST data (%s bytes) due to its "
-"current configuration."
-msgstr ""
-
-#: actions/newnotice.php:128 scripts/maildaemon.php:185 lib/mediafile.php:270
-#, php-format
-msgid " Try using another %s format."
-msgstr ""
-
-#: actions/newnotice.php:133 scripts/maildaemon.php:190 lib/mediafile.php:275
-#, php-format
-msgid "%s is not a supported filetype on this server."
-msgstr ""
-
-#: actions/newnotice.php:205 lib/mediafile.php:142
-msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini."
-msgstr ""
-
-#: actions/newnotice.php:208 lib/mediafile.php:147
-msgid ""
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
-"the HTML form."
-msgstr ""
-
-#: actions/newnotice.php:211 lib/mediafile.php:152
-msgid "The uploaded file was only partially uploaded."
-msgstr ""
-
-#: actions/newnotice.php:214 lib/mediafile.php:159
-msgid "Missing a temporary folder."
-msgstr ""
-
-#: actions/newnotice.php:217 lib/mediafile.php:162
-msgid "Failed to write file to disk."
-msgstr ""
-
-#: actions/newnotice.php:220 lib/mediafile.php:165
-msgid "File upload stopped by extension."
-msgstr ""
-
-#: actions/newnotice.php:230 scripts/maildaemon.php:85
-msgid "Couldn't save file."
-msgstr ""
-
-#: actions/newnotice.php:246 scripts/maildaemon.php:101
-msgid "Max notice size is 140 chars, including attachment URL."
-msgstr ""
-
-#: actions/newnotice.php:297
-msgid "Somehow lost the login in saveFile"
-msgstr ""
-
-#: actions/newnotice.php:309 scripts/maildaemon.php:127 lib/mediafile.php:196
-#: lib/mediafile.php:233
-msgid "File could not be moved to destination directory."
-msgstr ""
-
-#: actions/newnotice.php:336 actions/newnotice.php:360
-#: scripts/maildaemon.php:148 scripts/maildaemon.php:167 lib/mediafile.php:98
-#: lib/mediafile.php:123
-msgid "There was a database error while saving your file. Please try again."
-msgstr ""
-
-#: actions/noticesearch.php:121
-#, php-format
-msgid ""
-"Be the first to [post on this topic](%%%%action.newnotice%%%%?"
-"status_textarea=%s)!"
-msgstr ""
-
-#: actions/noticesearch.php:124
-#, php-format
-msgid ""
-"Why not [register an account](%%%%action.register%%%%) and be the first to "
-"[post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!"
-msgstr ""
-
-#: actions/openidsettings.php:70
-#, php-format
-msgid ""
-"[OpenID](%%doc.openid%%) lets you log into many sites with the same user "
-"account. Manage your associated OpenIDs from here."
-msgstr ""
-
-#: actions/othersettings.php:110 actions/othersettings.php:117
-msgid "Shorten URLs with"
-msgstr ""
-
-#: actions/othersettings.php:115 actions/othersettings.php:122
-msgid "View profile designs"
-msgstr ""
-
-#: actions/othersettings.php:116 actions/othersettings.php:123
-msgid "Show or hide profile designs."
-msgstr ""
-
-#: actions/public.php:82 actions/public.php:83
-#, php-format
-msgid "Beyond the page limit (%s)"
-msgstr ""
-
-#: actions/public.php:179
-#, php-format
-msgid ""
-"This is the public timeline for %%site.name%% but no one has posted anything "
-"yet."
-msgstr ""
-
-#: actions/public.php:182
-msgid "Be the first to post!"
-msgstr ""
-
-#: actions/public.php:186
-#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and be the first to post!"
-msgstr ""
-
-#: actions/public.php:245 actions/public.php:238
-#, php-format
-msgid ""
-"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
-"blogging) service based on the Free Software [StatusNet](http://status.net/) "
-"tool."
-msgstr ""
-
-#: actions/publictagcloud.php:69
-#, php-format
-msgid "No one has posted a notice with a [hashtag](%%doc.tags%%) yet."
-msgstr ""
-
-#: actions/publictagcloud.php:72
-msgid "Be the first to post one!"
-msgstr ""
-
-#: actions/publictagcloud.php:75
-#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and be the first to post "
-"one!"
-msgstr ""
-
-#: actions/recoverpassword.php:152
-msgid ""
-"If you've forgotten or lost your password, you can get a new one sent to the "
-"email address you have stored in your account."
-msgstr ""
-
-#: actions/recoverpassword.php:158
-msgid "You've been identified. Enter a new password below. "
-msgstr ""
-
-#: actions/recoverpassword.php:188
-msgid "Password recover"
-msgstr ""
-
-#: actions/register.php:86 actions/register.php:92
-msgid "Sorry, invalid invitation code."
-msgstr ""
-
-#: actions/remotesubscribe.php:100 actions/remotesubscribe.php:124
-msgid "Subscribe to a remote user"
-msgstr ""
-
-#: actions/replies.php:179 actions/replies.php:198
-#, php-format
-msgid ""
-"This is the timeline showing replies to %s but %s hasn't received a notice "
-"to his attention yet."
-msgstr ""
-
-#: actions/replies.php:184 actions/replies.php:203
-#, php-format
-msgid ""
-"You can engage other users in a conversation, subscribe to more people or "
-"[join groups](%%action.groups%%)."
-msgstr ""
-
-#: actions/replies.php:186 actions/replies.php:205
-#, php-format
-msgid ""
-"You can try to [nudge %s](../%s) or [post something to his or her attention]"
-"(%%%%action.newnotice%%%%?status_textarea=%s)."
-msgstr ""
-
-#: actions/showfavorites.php:79
-#, php-format
-msgid "%s's favorite notices, page %d"
-msgstr ""
-
-#: actions/showfavorites.php:170 actions/showfavorites.php:205
-msgid ""
-"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."
-msgstr ""
-
-#: actions/showfavorites.php:172 actions/showfavorites.php:207
-#, php-format
-msgid ""
-"%s hasn't added any notices to his favorites yet. Post something interesting "
-"they would add to their favorites :)"
-msgstr ""
-
-#: actions/showfavorites.php:176
-#, php-format
-msgid ""
-"%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 thier favorites :)"
-msgstr ""
-
-#: actions/showfavorites.php:226 actions/showfavorites.php:242
-msgid "This is a way to share what you like."
-msgstr ""
-
-#: actions/showgroup.php:279 lib/groupeditform.php:178
-#: actions/showgroup.php:284 lib/groupeditform.php:184
-msgid "Aliases"
-msgstr ""
-
-#: actions/showgroup.php:323 actions/showgroup.php:328
-#, php-format
-msgid "Notice feed for %s group (RSS 1.0)"
-msgstr ""
-
-#: actions/showgroup.php:330 actions/tag.php:84 actions/showgroup.php:334
-#, php-format
-msgid "Notice feed for %s group (RSS 2.0)"
-msgstr ""
-
-#: actions/showgroup.php:337 actions/showgroup.php:340
-#, php-format
-msgid "Notice feed for %s group (Atom)"
-msgstr ""
-
-#: actions/showgroup.php:446 actions/showgroup.php:454
-#, php-format
-msgid ""
-"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. Its members share short messages about "
-"their life and interests. "
-msgstr ""
-
-#: actions/showgroup.php:474 actions/showgroup.php:482
-msgid "Admins"
-msgstr ""
-
-#: actions/shownotice.php:101
-msgid "Not a local notice"
-msgstr ""
-
-#: actions/showstream.php:72 actions/showstream.php:73
-#, php-format
-msgid " tagged %s"
-msgstr ""
-
-#: actions/showstream.php:121 actions/showstream.php:122
-#, php-format
-msgid "Notice feed for %s tagged %s (RSS 1.0)"
-msgstr ""
-
-#: actions/showstream.php:350 actions/showstream.php:444
-#: actions/showstream.php:191
-#, php-format
-msgid "This is the timeline for %s but %s hasn't posted anything yet."
-msgstr ""
-
-#: actions/showstream.php:355 actions/showstream.php:449
-#: actions/showstream.php:196
-msgid ""
-"Seen anything interesting recently? You haven't posted any notices yet, now "
-"would be a good time to start :)"
-msgstr ""
-
-#: actions/showstream.php:357 actions/showstream.php:451
-#: actions/showstream.php:198
-#, php-format
-msgid ""
-"You can try to nudge %s or [post something to his or her attention](%%%%"
-"action.newnotice%%%%?status_textarea=%s)."
-msgstr ""
-
-#: actions/showstream.php:393 actions/showstream.php:492
-#: actions/showstream.php:239
-#, php-format
-msgid ""
-"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. "
-msgstr ""
-
-#: actions/subscribers.php:108
-msgid ""
-"You have no subscribers. Try subscribing to people you know and they might "
-"return the favor"
-msgstr ""
-
-#: actions/subscribers.php:110
-#, php-format
-msgid "%s has no subscribers. Want to be the first?"
-msgstr ""
-
-#: actions/subscribers.php:114
-#, php-format
-msgid ""
-"%s has no subscribers. Why not [register an account](%%%%action.register%%%"
-"%) and be the first?"
-msgstr ""
-
-#: actions/subscriptions.php:115 actions/subscriptions.php:121
-#, php-format
-msgid ""
-"You're not listening to anyone's notices right now, try subscribing to "
-"people you know. Try [people search](%%action.peoplesearch%%), look for "
-"members in groups you're interested in and in our [featured users](%%action."
-"featured%%). If you're a [Twitter user](%%action.twittersettings%%), you can "
-"automatically subscribe to people you already follow there."
-msgstr ""
-
-#: actions/subscriptions.php:117 actions/subscriptions.php:121
-#: actions/subscriptions.php:123 actions/subscriptions.php:127
-#, php-format
-msgid "%s is not listening to anyone."
-msgstr ""
-
-#: actions/tag.php:77 actions/tag.php:86
-#, php-format
-msgid "Notice feed for tag %s (RSS 1.0)"
-msgstr ""
-
-#: actions/tag.php:91 actions/tag.php:98
-#, php-format
-msgid "Notice feed for tag %s (Atom)"
-msgstr ""
-
-#: actions/twitapifavorites.php:125 actions/apifavoritecreate.php:119
-msgid "This status is already a favorite!"
-msgstr ""
-
-#: actions/twitapifavorites.php:179 actions/apifavoritedestroy.php:122
-msgid "That status is not a favorite!"
-msgstr ""
-
-#: actions/twitapifriendships.php:180 actions/twitapifriendships.php:200
-#: actions/apifriendshipsshow.php:135
-msgid "Could not determine source user."
-msgstr ""
-
-#: actions/twitapifriendships.php:215
-msgid "Target user not specified."
-msgstr ""
-
-#: actions/twitapifriendships.php:221 actions/apifriendshipsshow.php:143
-msgid "Could not find target user."
-msgstr ""
-
-#: actions/twitapistatuses.php:322 actions/apitimelinementions.php:116
-#, php-format
-msgid "%1$s / Updates mentioning %2$s"
-msgstr ""
-
-#: actions/twitapitags.php:74 actions/apitimelinetag.php:107
-#: actions/tagrss.php:64
-#, php-format
-msgid "Updates tagged with %1$s on %2$s!"
-msgstr ""
-
-#: actions/twittersettings.php:165
-msgid "Import my Friends Timeline."
-msgstr ""
-
-#: actions/userauthorization.php:158 actions/userauthorization.php:188
-msgid "License"
-msgstr ""
-
-#: actions/userauthorization.php:179 actions/userauthorization.php:212
-msgid "Reject this subscription"
-msgstr ""
-
-#: actions/userdesignsettings.php:76 lib/designsettings.php:65
-msgid "Profile design"
-msgstr ""
-
-#: actions/userdesignsettings.php:87 lib/designsettings.php:76
-msgid ""
-"Customize the way your profile looks with a background image and a colour "
-"palette of your choice."
-msgstr ""
-
-#: actions/userdesignsettings.php:282
-msgid "Enjoy your hotdog!"
-msgstr ""
-
-#: actions/usergroups.php:153
-#, php-format
-msgid "%s is not a member of any group."
-msgstr ""
-
-#: actions/usergroups.php:158
-#, php-format
-msgid "Try [searching for groups](%%action.groupsearch%%) and joining them."
-msgstr ""
-
-#: classes/File.php:127 classes/File.php:137
-#, php-format
-msgid ""
-"No file may be larger than %d bytes and the file you sent was %d bytes. Try "
-"to upload a smaller version."
-msgstr ""
-
-#: classes/File.php:137 classes/File.php:147
-#, php-format
-msgid "A file this large would exceed your user quota of %d bytes."
-msgstr ""
-
-#: classes/File.php:145 classes/File.php:154
-#, php-format
-msgid "A file this large would exceed your monthly quota of %d bytes."
-msgstr ""
-
-#: classes/Notice.php:139 classes/Notice.php:179
-msgid "Problem saving notice. Too long."
-msgstr ""
-
-#: classes/User.php:319 classes/User.php:327 classes/User.php:334
-#: classes/User.php:333
-#, php-format
-msgid "Welcome to %1$s, @%2$s!"
-msgstr ""
-
-#: lib/accountsettingsaction.php:119 lib/groupnav.php:118
-#: lib/accountsettingsaction.php:120
-msgid "Design"
-msgstr ""
-
-#: lib/accountsettingsaction.php:120 lib/accountsettingsaction.php:121
-msgid "Design your profile"
-msgstr ""
-
-#: lib/action.php:712 lib/action.php:727
-msgid "TOS"
-msgstr ""
-
-#: lib/attachmentlist.php:87
-msgid "Attachments"
-msgstr ""
-
-#: lib/attachmentlist.php:265
-msgid "Author"
-msgstr ""
-
-#: lib/attachmentlist.php:278
-msgid "Provider"
-msgstr ""
-
-#: lib/attachmentnoticesection.php:67
-msgid "Notices where this attachment appears"
-msgstr ""
-
-#: lib/attachmenttagcloudsection.php:48
-msgid "Tags for this attachment"
-msgstr ""
-
-#: lib/designsettings.php:101
-msgid "Change background image"
-msgstr ""
-
-#: lib/designsettings.php:105
-msgid "Upload file"
-msgstr ""
-
-#: lib/designsettings.php:109
-msgid ""
-"You can upload your personal background image. The maximum file size is 2Mb."
-msgstr ""
-
-#: lib/designsettings.php:139
-msgid "On"
-msgstr ""
-
-#: lib/designsettings.php:155
-msgid "Off"
-msgstr ""
-
-#: lib/designsettings.php:156
-msgid "Turn background image on or off."
-msgstr ""
-
-#: lib/designsettings.php:161
-msgid "Tile background image"
-msgstr ""
-
-#: lib/designsettings.php:170
-msgid "Change colours"
-msgstr ""
-
-#: lib/designsettings.php:178
-msgid "Background"
-msgstr ""
-
-#: lib/designsettings.php:191
-msgid "Content"
-msgstr ""
-
-#: lib/designsettings.php:204
-msgid "Sidebar"
-msgstr ""
-
-#: lib/designsettings.php:230
-msgid "Links"
-msgstr ""
-
-#: lib/designsettings.php:247
-msgid "Use defaults"
-msgstr ""
-
-#: lib/designsettings.php:248
-msgid "Restore default designs"
-msgstr ""
-
-#: lib/designsettings.php:254
-msgid "Reset back to default"
-msgstr ""
-
-#: lib/designsettings.php:257
-msgid "Save design"
-msgstr ""
-
-#: lib/designsettings.php:378 lib/designsettings.php:369
-#: lib/designsettings.php:372
-msgid "Bad default color settings: "
-msgstr ""
-
-#: lib/designsettings.php:474 lib/designsettings.php:465
-#: lib/designsettings.php:468
-msgid "Design defaults restored."
-msgstr ""
-
-#: lib/groupeditform.php:181 lib/groupeditform.php:187
-#, php-format
-msgid "Extra nicknames for the group, comma- or space- separated, max %d"
-msgstr ""
-
-#: lib/groupnav.php:100
-msgid "Blocked"
-msgstr ""
-
-#: lib/groupnav.php:101
-#, php-format
-msgid "%s blocked users"
-msgstr ""
-
-#: lib/groupnav.php:119
-#, php-format
-msgid "Add or edit %s design"
-msgstr ""
-
-#: lib/mail.php:556
-#, php-format
-msgid ""
-"%1$s just added your notice from %2$s as one of their favorites.\n"
-"\n"
-"The URL of your notice is:\n"
-"\n"
-"%3$s\n"
-"\n"
-"The text of your notice is:\n"
-"\n"
-"%4$s\n"
-"\n"
-"You can see the list of %1$s's favorites here:\n"
-"\n"
-"%5$s\n"
-"\n"
-"Faithfully yours,\n"
-"%6$s\n"
-msgstr ""
-
-#: lib/mail.php:646
-#, php-format
-msgid "Your Twitter bridge has been disabled."
-msgstr ""
-
-#: lib/mail.php:648
-#, php-format
-msgid ""
-"Hi, %1$s. We're sorry to inform you that your link to Twitter has been "
-"disabled. Your Twitter credentials have either changed (did you recently "
-"change your Twitter password?) or you have otherwise revoked our access to "
-"your Twitter account.\n"
-"\n"
-"You can re-enable your Twitter bridge by visiting your Twitter settings "
-"page:\n"
-"\n"
-"\t%2$s\n"
-"\n"
-"Regards,\n"
-"%3$s\n"
-msgstr ""
-
-#: lib/mail.php:682
-#, php-format
-msgid "Your %s Facebook application access has been disabled."
-msgstr ""
-
-#: lib/mail.php:685
-#, php-format
-msgid ""
-"Hi, %1$s. We're sorry to inform you that we are unable to update your "
-"Facebook status from %s, and have disabled the Facebook application for your "
-"account. This may be because you have removed the Facebook application's "
-"authorization, or have deleted your Facebook account. You can re-enable the "
-"Facebook application and automatic status updating by re-installing the %1$s "
-"Facebook application.\n"
-"\n"
-"Regards,\n"
-"\n"
-"%1$s"
-msgstr ""
-
-#: lib/mailbox.php:139
-msgid ""
-"You have no private messages. You can send private message to engage other "
-"users in conversation. People can send you messages for your eyes only."
-msgstr ""
-
-#: lib/noticeform.php:154 lib/noticeform.php:180
-msgid "Attach"
-msgstr ""
-
-#: lib/noticeform.php:158 lib/noticeform.php:184
-msgid "Attach a file"
-msgstr ""
-
-#: lib/noticelist.php:436 lib/noticelist.php:478
-msgid "in context"
-msgstr ""
-
-#: lib/profileaction.php:177
-msgid "User ID"
-msgstr ""
-
-#: lib/searchaction.php:156 lib/searchaction.php:162
-msgid "Search help"
-msgstr ""
-
-#: lib/subscriberspeopleselftagcloudsection.php:48
-#: lib/subscriptionspeopleselftagcloudsection.php:48
-msgid "People Tagcloud as self-tagged"
-msgstr ""
-
-#: lib/subscriberspeopletagcloudsection.php:48
-#: lib/subscriptionspeopletagcloudsection.php:48
-msgid "People Tagcloud as tagged"
-msgstr ""
-
-#: lib/webcolor.php:82
-#, php-format
-msgid "%s is not a valid color!"
-msgstr ""
-
-#: lib/webcolor.php:123
-#, php-format
-msgid "%s is not a valid color! Use 3 or 6 hex chars."
-msgstr ""
-
-#: actions/all.php:63 actions/public.php:97 actions/replies.php:92
-#: actions/showfavorites.php:137 actions/tag.php:51
-msgid "No such page"
-msgstr ""
-
-#: actions/apidirectmessage.php:89
-#, php-format
-msgid "Direct messages from %s"
-msgstr ""
-
-#: actions/apidirectmessagenew.php:135 actions/newmessage.php:150
-#, php-format
-msgid "That's too long. Max message size is %d chars."
-msgstr ""
-
-#: actions/apifriendshipsdestroy.php:109
-msgid "Could not unfollow user: User not found."
-msgstr ""
-
-#: actions/apifriendshipsdestroy.php:120
-msgid "You cannot unfollow yourself!"
-msgstr ""
-
-#: actions/apigroupcreate.php:261
-#, php-format
-msgid "Description is too long (max %d chars)."
-msgstr ""
-
-#: actions/apigroupjoin.php:110
-msgid "You are already a member of that group."
-msgstr ""
-
-#: actions/apigroupjoin.php:138
-#, php-format
-msgid "Could not join user %s to group %s."
-msgstr ""
-
-#: actions/apigroupleave.php:114
-msgid "You are not a member of this group."
-msgstr ""
-
-#: actions/apigroupleave.php:124
-#, php-format
-msgid "Could not remove user %s to group %s."
-msgstr ""
-
-#: actions/apigrouplist.php:95
-#, php-format
-msgid "%s's groups"
-msgstr ""
-
-#: actions/apigrouplist.php:103
-#, php-format
-msgid "Groups %s is a member of on %s."
-msgstr ""
-
-#: actions/apigrouplistall.php:94
-#, php-format
-msgid "groups on %s"
-msgstr ""
-
-#: actions/apistatusesshow.php:138
-msgid "Status deleted."
-msgstr ""
-
-#: actions/apistatusesupdate.php:132
-#: actions/apiaccountupdateprofileimage.php:99
-msgid "Unable to handle that much POST data!"
-msgstr ""
-
-#: actions/apistatusesupdate.php:145 actions/newnotice.php:155
-#: scripts/maildaemon.php:71 actions/apistatusesupdate.php:152
-#, php-format
-msgid "That's too long. Max notice size is %d chars."
-msgstr ""
-
-#: actions/apistatusesupdate.php:209 actions/newnotice.php:178
-#: actions/apistatusesupdate.php:216
-#, php-format
-msgid "Max notice size is %d chars, including attachment URL."
-msgstr ""
-
-#: actions/apisubscriptions.php:231 actions/apisubscriptions.php:261
-msgid "Unsupported format."
-msgstr ""
-
-#: actions/bookmarklet.php:50
-msgid "Post to "
-msgstr ""
-
-#: actions/editgroup.php:201 actions/newgroup.php:145
-#, php-format
-msgid "description is too long (max %d chars)."
-msgstr ""
-
-#: actions/favoritesrss.php:115
-#, php-format
-msgid "Updates favored by %1$s on %2$s!"
-msgstr ""
-
-#: actions/finishremotesubscribe.php:80
-msgid "User being listened to does not exist."
-msgstr ""
-
-#: actions/finishremotesubscribe.php:106
-msgid "You are not authorized."
-msgstr ""
-
-#: actions/finishremotesubscribe.php:109
-msgid "Could not convert request token to access token."
-msgstr ""
-
-#: actions/finishremotesubscribe.php:114
-msgid "Remote service uses unknown version of OMB protocol."
-msgstr ""
-
-#: actions/getfile.php:75
-msgid "No such file."
-msgstr ""
-
-#: actions/getfile.php:79
-msgid "Cannot read file."
-msgstr ""
-
-#: actions/grouprss.php:133
-#, php-format
-msgid "Updates from members of %1$s on %2$s!"
-msgstr ""
-
-#: actions/imsettings.php:89
-msgid "IM is not available."
-msgstr ""
-
-#: actions/login.php:259 actions/login.php:286
-#, php-format
-msgid ""
-"Login with your username and password. Don't have a username yet? [Register]"
-"(%%action.register%%) a new account."
-msgstr ""
-
-#: actions/noticesearchrss.php:89
-#, php-format
-msgid "Updates with \"%s\""
-msgstr ""
-
-#: actions/noticesearchrss.php:91
-#, php-format
-msgid "Updates matching search term \"%1$s\" on %2$s!"
-msgstr ""
-
-#: actions/oembed.php:157
-msgid "content type "
-msgstr ""
-
-#: actions/oembed.php:160
-msgid "Only "
-msgstr ""
-
-#: actions/postnotice.php:90
-#, php-format
-msgid "Notice license ‘%s’ is not compatible with site license ‘%s’."
-msgstr ""
-
-#: actions/profilesettings.php:122 actions/register.php:454
-#: actions/register.php:460
-#, php-format
-msgid "Describe yourself and your interests in %d chars"
-msgstr ""
-
-#: actions/profilesettings.php:125 actions/register.php:457
-#: actions/register.php:463
-msgid "Describe yourself and your interests"
-msgstr ""
-
-#: actions/profilesettings.php:221 actions/register.php:217
-#: actions/register.php:223
-#, php-format
-msgid "Bio is too long (max %d chars)."
-msgstr ""
-
-#: actions/register.php:336 actions/register.php:342
-msgid ""
-"With this form you can create a new account. You can then post notices and "
-"link up to friends and colleagues. "
-msgstr ""
-
-#: actions/remotesubscribe.php:168
-msgid ""
-"Not a valid profile URL (no YADIS document or no or invalid XRDS defined)."
-msgstr ""
-
-#: actions/remotesubscribe.php:176
-msgid "That’s a local profile! Login to subscribe."
-msgstr ""
-
-#: actions/remotesubscribe.php:183
-msgid "Couldn’t get a request token."
-msgstr ""
-
-#: actions/replies.php:144
-#, php-format
-msgid "Replies feed for %s (RSS 1.0)"
-msgstr ""
-
-#: actions/replies.php:151
-#, php-format
-msgid "Replies feed for %s (RSS 2.0)"
-msgstr ""
-
-#: actions/replies.php:158
-#, php-format
-msgid "Replies feed for %s (Atom)"
-msgstr ""
-
-#: actions/repliesrss.php:72
-#, php-format
-msgid "Replies to %1$s on %2$s!"
-msgstr ""
-
-#: actions/showfavorites.php:170
-#, php-format
-msgid "Feed for favorites of %s (RSS 1.0)"
-msgstr ""
-
-#: actions/showfavorites.php:177
-#, php-format
-msgid "Feed for favorites of %s (RSS 2.0)"
-msgstr ""
-
-#: actions/showfavorites.php:184
-#, php-format
-msgid "Feed for favorites of %s (Atom)"
-msgstr ""
-
-#: actions/showfavorites.php:211
-#, php-format
-msgid ""
-"%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 :)"
-msgstr ""
-
-#: actions/showgroup.php:345
-#, php-format
-msgid "FOAF for %s group"
-msgstr ""
-
-#: actions/shownotice.php:90
-msgid "Notice deleted."
-msgstr ""
-
-#: actions/smssettings.php:91
-msgid "SMS is not available."
-msgstr ""
-
-#: actions/tag.php:92
-#, php-format
-msgid "Notice feed for tag %s (RSS 2.0)"
-msgstr ""
-
-#: actions/updateprofile.php:62 actions/userauthorization.php:330
-#, php-format
-msgid "Listenee stream license ‘%s’ is not compatible with site license ‘%s’."
-msgstr ""
-
-#: actions/userauthorization.php:110
-msgid ""
-"Please check these details to make sure that you want to subscribe to this "
-"user’s notices. If you didn’t just ask to subscribe to someone’s notices, "
-"click “Reject”."
-msgstr ""
-
-#: actions/userauthorization.php:249
-msgid ""
-"The subscription has been authorized, but no callback URL was passed. Check "
-"with the site’s instructions for details on how to authorize the "
-"subscription. Your subscription token is:"
-msgstr ""
-
-#: actions/userauthorization.php:261
-msgid ""
-"The subscription has been rejected, but no callback URL was passed. Check "
-"with the site’s instructions for details on how to fully reject the "
-"subscription."
-msgstr ""
-
-#: actions/userauthorization.php:296
-#, php-format
-msgid "Listener URI ‘%s’ not found here"
-msgstr ""
-
-#: actions/userauthorization.php:301
-#, php-format
-msgid "Listenee URI ‘%s’ is too long."
-msgstr ""
-
-#: actions/userauthorization.php:307
-#, php-format
-msgid "Listenee URI ‘%s’ is a local user."
-msgstr ""
-
-#: actions/userauthorization.php:322
-#, php-format
-msgid "Profile URL ‘%s’ is for a local user."
-msgstr ""
-
-#: actions/userauthorization.php:338
-#, php-format
-msgid "Avatar URL ‘%s’ is not valid."
-msgstr ""
-
-#: actions/userauthorization.php:343
-#, php-format
-msgid "Can’t read avatar URL ‘%s’."
-msgstr ""
-
-#: actions/userauthorization.php:348
-#, php-format
-msgid "Wrong image type for avatar URL ‘%s’."
-msgstr ""
-
-#: lib/action.php:435
-msgid "Connect to services"
-msgstr ""
-
-#: lib/action.php:785
-msgid "Site content license"
-msgstr ""
-
-#: lib/command.php:88
-#, php-format
-msgid "Could not find a user with nickname %s"
-msgstr ""
-
-#: lib/command.php:92
-msgid "It does not make a lot of sense to nudge yourself!"
-msgstr ""
-
-#: lib/command.php:99
-#, php-format
-msgid "Nudge sent to %s"
-msgstr ""
-
-#: lib/command.php:152 lib/command.php:400
-msgid "Notice with that id does not exist"
-msgstr ""
-
-#: lib/command.php:358 scripts/xmppdaemon.php:321
-#, php-format
-msgid "Message too long - maximum is %d characters, you sent %d"
-msgstr ""
-
-#: lib/command.php:431
-#, php-format
-msgid "Notice too long - maximum is %d characters, you sent %d"
-msgstr ""
-
-#: lib/command.php:439
-#, php-format
-msgid "Reply to %s sent"
-msgstr ""
-
-#: lib/command.php:441
-msgid "Error saving notice."
-msgstr ""
-
-#: lib/common.php:191
-msgid "No configuration file found. "
-msgstr ""
-
-#: lib/common.php:192
-msgid "I looked for configuration files in the following places: "
-msgstr ""
-
-#: lib/common.php:193
-msgid "You may wish to run the installer to fix this."
-msgstr ""
-
-#: lib/common.php:194
-msgid "Go to the installer."
-msgstr ""
-
-#: lib/galleryaction.php:139
-msgid "Select tag to filter"
-msgstr ""
-
-#: lib/groupeditform.php:168
-msgid "Describe the group or topic"
-msgstr ""
-
-#: lib/groupeditform.php:170
-#, php-format
-msgid "Describe the group or topic in %d characters"
-msgstr ""
-
-#: lib/jabber.php:192
-#, php-format
-msgid "notice id: %s"
-msgstr ""
-
-#: lib/mail.php:554
-#, php-format
-msgid "%s (@%s) added your notice as a favorite"
-msgstr ""
-
-#: lib/mail.php:556
-#, php-format
-msgid ""
-"%1$s (@%7$s) just added your notice from %2$s as one of their favorites.\n"
-"\n"
-"The URL of your notice is:\n"
-"\n"
-"%3$s\n"
-"\n"
-"The text of your notice is:\n"
-"\n"
-"%4$s\n"
-"\n"
-"You can see the list of %1$s's favorites here:\n"
-"\n"
-"%5$s\n"
-"\n"
-"Faithfully yours,\n"
-"%6$s\n"
-msgstr ""
-
-#: lib/mail.php:611
-#, php-format
-msgid "%s (@%s) sent a notice to your attention"
-msgstr ""
-
-#: lib/mail.php:613
-#, php-format
-msgid ""
-"%1$s (@%9$s) just sent a notice to your attention (an '@-reply') on %2$s.\n"
-"\n"
-"The notice is here:\n"
-"\n"
-"\t%3$s\n"
-"\n"
-"It reads:\n"
-"\n"
-"\t%4$s\n"
-"\n"
-msgstr ""
-
-#: lib/mailbox.php:227 lib/noticelist.php:424
-msgid "from"
-msgstr ""
-
-#: lib/mediafile.php:179 lib/mediafile.php:216
-msgid "File exceeds user's quota!"
-msgstr ""
-
-#: lib/mediafile.php:201 lib/mediafile.php:237
-msgid "Could not determine file's mime-type!"
-msgstr ""
-
-#: lib/oauthstore.php:345
-msgid "Duplicate notice"
-msgstr ""
-
-#: actions/login.php:110 actions/login.php:120
-msgid "Invalid or expired token."
-msgstr ""
-
-#: lib/command.php:597
-#, php-format
-msgid "Could not create login token for %s"
-msgstr ""
-
-#: lib/command.php:602
-#, php-format
-msgid "This link is useable only once, and is good for only 2 minutes: %s"
-msgstr ""
-
-#: lib/imagefile.php:75
-#, php-format
-msgid "That file is too big. The maximum file size is %s."
-msgstr ""
-
-#: lib/command.php:613
-msgid ""
-"Commands:\n"
-"on - turn on notifications\n"
-"off - turn off notifications\n"
-"help - show this help\n"
-"follow - subscribe to user\n"
-"leave - unsubscribe from user\n"
-"d - direct message to user\n"
-"get - get last notice from user\n"
-"whois - get profile info on user\n"
-"fav - add user's last notice as a 'fave'\n"
-"fav # - add notice with the given id as a 'fave'\n"
-"reply # - reply to notice with a given id\n"
-"reply - reply to the last notice from user\n"
-"join - join group\n"
-"login - Get a link to login to the web interface\n"
-"drop - leave group\n"
-"stats - get your stats\n"
-"stop - same as 'off'\n"
-"quit - same as 'off'\n"
-"sub - same as 'follow'\n"
-"unsub - same as 'leave'\n"
-"last - same as 'get'\n"
-"on - not yet implemented.\n"
-"off - not yet implemented.\n"
-"nudge - remind a user to update.\n"
-"invite - not yet implemented.\n"
-"track - not yet implemented.\n"
-"untrack - not yet implemented.\n"
-"track off - not yet implemented.\n"
-"untrack all - not yet implemented.\n"
-"tracks - not yet implemented.\n"
-"tracking - not yet implemented.\n"
+#: scripts/maildaemon.php:61
+msgid "Sorry, no incoming email allowed."
msgstr ""
diff --git a/plugins/Facebook/facebook/facebookapi_php5_restlib.php b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
index 55cb7fb86..e2a6fe88b 100755
--- a/plugins/Facebook/facebook/facebookapi_php5_restlib.php
+++ b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
@@ -2951,7 +2951,7 @@ function toggleDisplay(id, type) {
/**
- * Bans a list of users from the app. Banned users can't
+ * Bans a list of users from the app. Banned users cannot
* access the app's canvas page and forums.
*
* @param array $uids an array of user ids
diff --git a/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php b/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php
index 0cddbddb4..92542b47d 100644
--- a/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php
+++ b/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php
@@ -124,7 +124,7 @@ class Services_JSON
* "{...}" syntax creates associative arrays
* instead of objects in decode().
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
- * Values which can't be encoded (e.g. resources)
+ * Values which cannot be encoded (e.g. resources)
* appear as NULL instead of throwing errors.
* By default, a deeply-nested resource will
* bubble up with an error, so all return values
diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php
index a10fdf90d..1d8b5217b 100644
--- a/plugins/Facebook/facebookaction.php
+++ b/plugins/Facebook/facebookaction.php
@@ -513,7 +513,7 @@ class FacebookNoticeList extends NoticeList
/**
* show the list of notices
*
- * "Uses up" the stream by looping through it. So, probably can't
+ * "Uses up" the stream by looping through it. So, probably cannot
* be called twice on the same list.
*
* @return int count of notices listed.
diff --git a/plugins/Facebook/facebookhome.php b/plugins/Facebook/facebookhome.php
index 91c0cc6b8..ee6e6620b 100644
--- a/plugins/Facebook/facebookhome.php
+++ b/plugins/Facebook/facebookhome.php
@@ -108,7 +108,7 @@ class FacebookhomeAction extends FacebookAction
$user = User::staticGet('nickname', $nickname);
if (!$user) {
- $this->showLoginForm(_("Server error - couldn't get user!"));
+ $this->showLoginForm(_("Server error. Could not get user."));
}
$flink = DB_DataObject::factory('foreign_link');
diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php
index 915d15c07..bc433b896 100644
--- a/plugins/LinkbackPlugin.php
+++ b/plugins/LinkbackPlugin.php
@@ -125,7 +125,7 @@ class LinkbackPlugin extends Plugin
if (!extension_loaded('xmlrpc')) {
if (!dl('xmlrpc.so')) {
- common_log(LOG_ERR, "Can't pingback; xmlrpc extension not available.");
+ common_log(LOG_ERR, "Cannot pingback; xmlrpc extension not available.");
}
}
diff --git a/plugins/Meteor/MeteorPlugin.php b/plugins/Meteor/MeteorPlugin.php
index 5b345d7c2..f3cbc3eea 100644
--- a/plugins/Meteor/MeteorPlugin.php
+++ b/plugins/Meteor/MeteorPlugin.php
@@ -85,7 +85,7 @@ class MeteorPlugin extends RealtimePlugin
// May throw an exception.
$this->_socket = stream_socket_client("tcp://{$controlserver}:{$this->controlport}");
if (!$this->_socket) {
- throw new Exception("Couldn't connect to {$controlserver} on {$this->controlport}");
+ throw new Exception("Could not connect to {$controlserver} on {$this->controlport}");
}
}
diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php
index ff7a93899..cd042226b 100644
--- a/plugins/OpenID/openid.php
+++ b/plugins/OpenID/openid.php
@@ -36,7 +36,7 @@ function oid_store()
{
static $store = null;
if (!$store) {
- # Can't be called statically
+ # Cannot be called statically
$user = new User();
$conn = $user->getDatabaseConnection();
$store = new Auth_OpenID_MySQLStore($conn);
@@ -192,7 +192,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
$form_html = preg_replace('/&/', '&', $form_html);
- // Display an error if the form markup couldn't be generated;
+ // Display an error if the form markup could not be generated;
// otherwise, render the HTML.
if (Auth_OpenID::isFailure($form_html)) {
common_server_error(sprintf(_('Could not create OpenID form: %s'), $form_html->message));
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index 671e3c7af..6a155b301 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -126,7 +126,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
$conn->disconnect();
- // XXX: Couldn't find a less brutal way to blow
+ // XXX: Could not find a less brutal way to blow
// away a cached connection
global $_DB_DATAOBJECT;
@@ -188,7 +188,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
if (empty($more_friends)) {
common_log(LOG_WARNING, $this->name() .
- " - Couldn't retrieve page $i " .
+ " - Could not retrieve page $i " .
"of Twitter user $flink->foreign_id friends.");
continue;
} else {
@@ -222,11 +222,11 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
if (!save_twitter_user($friend_id, $friend_name)) {
common_log(LOG_WARNING, $this-name() .
- " - Couldn't save $screen_name's friend, $friend_name.");
+ " - Could not save $screen_name's friend, $friend_name.");
continue;
}
- // Check to see if there's a related local user
+ // Check to see if there is a related local user
$friend_flink = Foreign_link::getByForeignID($friend_id,
TWITTER_SERVICE);
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index b5428316b..ab610e553 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -147,7 +147,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$conn->disconnect();
- // XXX: Couldn't find a less brutal way to blow
+ // XXX: Could not find a less brutal way to blow
// away a cached connection
global $_DB_DATAOBJECT;
@@ -158,7 +158,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
{
if (empty($flink)) {
common_log(LOG_WARNING, $this->name() .
- " - Can't retrieve Foreign_link for foreign ID $fid");
+ " - Cannot retrieve Foreign_link for foreign ID $fid");
return;
}
@@ -458,7 +458,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$profile = Profile::staticGet($profile_id);
if (empty($profile)) {
- common_debug($this->name() . " - Couldn't get profile: $profile_id!");
+ common_debug($this->name() . " - Could not get profile: $profile_id!");
return;
}
@@ -537,7 +537,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$ok = file_put_contents($avatarfile, $response->getBody());
if (!$ok) {
common_log(LOG_WARNING, $this->name() .
- " - Couldn't open file $filename");
+ " - Could not open file $filename");
return false;
}
} else {
diff --git a/plugins/UserFlag/flagprofile.php b/plugins/UserFlag/flagprofile.php
index c72b74c6a..84c343c48 100644
--- a/plugins/UserFlag/flagprofile.php
+++ b/plugins/UserFlag/flagprofile.php
@@ -135,7 +135,7 @@ class FlagprofileAction extends Action
$ufp->created = common_sql_now();
if (!$ufp->insert()) {
- throw new ServerException(sprintf(_("Couldn't flag profile '%s' with flag '%s'."),
+ throw new ServerException(sprintf(_("Could not flag profile '%s' with flag '%s'."),
$this->profile->nickname, $this->flag));
}
diff --git a/scripts/console.php b/scripts/console.php
index 41dd43f28..2413f5079 100755
--- a/scripts/console.php
+++ b/scripts/console.php
@@ -90,7 +90,7 @@ function readline_emulation($prompt)
if ($retval == 0) {
return $line;
} elseif ($retval == 127) {
- // Couldn't execute bash even though we thought we saw it.
+ // Could not execute bash even though we thought we saw it.
// Shell probably spit out an error message, sorry :(
// Fall through to fgets()...
} else {
diff --git a/scripts/createsim.php b/scripts/createsim.php
index 1266a9700..592853f86 100644
--- a/scripts/createsim.php
+++ b/scripts/createsim.php
@@ -85,7 +85,7 @@ function newSub($i)
$from = User::staticGet('nickname', $fromnick);
if (empty($from)) {
- throw new Exception("Can't find user '$fromnick'.");
+ throw new Exception("Cannot find user '$fromnick'.");
}
$t = rand(0, $i - 1);
@@ -102,7 +102,7 @@ function newSub($i)
$to = User::staticGet('nickname', $tunic);
if (empty($to)) {
- throw new Exception("Can't find user '$tunic'.");
+ throw new Exception("Cannot find user '$tunic'.");
}
subs_subscribe_to($from, $to);
diff --git a/scripts/deleteuser.php b/scripts/deleteuser.php
index 52389123c..39331f1a8 100644
--- a/scripts/deleteuser.php
+++ b/scripts/deleteuser.php
@@ -39,14 +39,14 @@ if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
$user = User::staticGet('id', $id);
if (empty($user)) {
- print "Can't find user with ID $id\n";
+ print "Cannot find user with ID $id\n";
exit(1);
}
} else if (have_option('n', 'nickname')) {
$nickname = get_option_value('n', 'nickname');
$user = User::staticGet('nickname', $nickname);
if (empty($user)) {
- print "Can't find user with nickname '$nickname'\n";
+ print "Cannot find user with nickname '$nickname'\n";
exit(1);
}
} else {
diff --git a/scripts/fixup_utf8.php b/scripts/fixup_utf8.php
index 5a9fba7c3..5581633ec 100755
--- a/scripts/fixup_utf8.php
+++ b/scripts/fixup_utf8.php
@@ -76,7 +76,7 @@ class UTF8FixerUpper
$succ = mysqli_set_charset($conn, $charset);
if (!$succ) {
- echo "ERROR: couldn't set charset\n";
+ echo "ERROR: Could not set charset\n";
$db->disconnect();
return NULL;
}
diff --git a/scripts/makegroupadmin.php b/scripts/makegroupadmin.php
index a68798451..07f980d58 100644
--- a/scripts/makegroupadmin.php
+++ b/scripts/makegroupadmin.php
@@ -67,7 +67,7 @@ try {
$member->created = common_sql_now();
if (!$member->insert()) {
- throw new Exception("Can't add '$nickname' to '$groupname'.");
+ throw new Exception("Cannot add '$nickname' to '$groupname'.");
}
}
@@ -80,7 +80,7 @@ try {
$member->is_admin = 1;
if (!$member->update($orig)) {
- throw new Exception("Can't make '$nickname' admin of '$groupname'.");
+ throw new Exception("Cannot make '$nickname' admin of '$groupname'.");
}
} catch (Exception $e) {
diff --git a/scripts/registeruser.php b/scripts/registeruser.php
index 5d9c8862d..8aab325b7 100644
--- a/scripts/registeruser.php
+++ b/scripts/registeruser.php
@@ -60,7 +60,7 @@ try {
'fullname' => $fullname));
if (empty($user)) {
- throw new Exception("Can't register user '$nickname' with password '$password' and fullname '$fullname'.");
+ throw new Exception("Cannot register user '$nickname' with password '$password' and fullname '$fullname'.");
}
if (!empty($email)) {
@@ -71,7 +71,7 @@ try {
if (!$user->updateKeys($orig)) {
print "Failed!\n";
- throw new Exception("Can't update email address.");
+ throw new Exception("Cannot update email address.");
}
}
diff --git a/scripts/showcache.php b/scripts/showcache.php
index f17979572..6b00a8f7b 100644
--- a/scripts/showcache.php
+++ b/scripts/showcache.php
@@ -58,7 +58,7 @@ print "Checking key '$k'...\n";
$c = common_memcache();
if (empty($c)) {
- die("Can't initialize cache object!\n");
+ die("Cannot initialize cache object!\n");
}
$obj = $c->get($k);
diff --git a/scripts/sitemap.php b/scripts/sitemap.php
index f8c392146..ee5d33e1e 100755
--- a/scripts/sitemap.php
+++ b/scripts/sitemap.php
@@ -377,11 +377,11 @@ function write_file($path, $data)
}
if (($fh_out = fopen($path,'w')) === false) {
- error("couldn't open $path for writing.");
+ error("Could not open $path for writing.");
}
if (fwrite($fh_out, $data) === false) {
- error("couldn't write to $path.");
+ error("Could not write to $path.");
}
}
diff --git a/scripts/update_translations.php b/scripts/update_translations.php
index 580c472ee..8d4c9d3d2 100755
--- a/scripts/update_translations.php
+++ b/scripts/update_translations.php
@@ -98,7 +98,7 @@ foreach ($languages as $language) {
$new_file = curl_get_file($file_url);
if ($new_file === FALSE) {
- echo "Couldn't retrieve .po file for $code: $file_url\n";
+ echo "Could not retrieve .po file for $code: $file_url\n";
continue;
}
--
cgit v1.2.3-54-g00ecf
From fc5002015b2a9e16a3c6b9992d55b45c73a8d2fb Mon Sep 17 00:00:00 2001
From: Brion Vibber
Date: Sun, 8 Nov 2009 23:28:51 +0100
Subject: Revert "* [Cc]an't -> [Cc]annot"
This reverts commit 0ab17f382b9993ada3d12d4cdace72cca53fb545.
---
actions/emailsettings.php | 4 +-
actions/smssettings.php | 2 +-
classes/File.php | 2 +-
classes/Notice.php | 4 +-
extlib/Auth/OpenID/Consumer.php | 2 +-
extlib/Auth/OpenID/Discover.php | 4 +-
extlib/Auth/OpenID/FileStore.php | 2 +-
extlib/DB.php | 2 +-
extlib/DB/DataObject/Generator.php | 4 +-
extlib/DB/dbase.php | 6 +-
extlib/DB/fbsql.php | 8 +-
extlib/DB/ibase.php | 6 +-
extlib/DB/ifx.php | 12 +-
extlib/DB/msql.php | 8 +-
extlib/DB/mssql.php | 10 +-
extlib/DB/mysql.php | 14 +-
extlib/DB/mysqli.php | 14 +-
extlib/DB/oci8.php | 10 +-
extlib/DB/odbc.php | 8 +-
extlib/DB/pgsql.php | 10 +-
extlib/DB/sqlite.php | 8 +-
extlib/DB/sybase.php | 12 +-
extlib/HTTP/Request2/Adapter/Socket.php | 1940 ++---
extlib/MIME/Type.php | 4 +-
extlib/MIME/Type/Extension.php | 4 +-
extlib/Mail/mail.php | 2 +-
extlib/Mail/sendmail.php | 2 +-
extlib/Net/LDAP2/Entry.php | 2 +-
extlib/Net/LDAP2/Filter.php | 2 +-
extlib/System/Command.php | 2 +-
extlib/markdown.php | 2 +-
install.php | 16 +-
lib/attachmentlist.php | 2 +-
lib/noticelist.php | 2 +-
lib/profilelist.php | 2 +-
lib/serverexception.php | 2 +-
lib/settingsaction.php | 2 +-
lib/util.php | 2 +-
lib/xmppqueuehandler.php | 2 +-
locale/statusnet.po | 7824 +++++++++++++-------
.../Facebook/facebook/facebookapi_php5_restlib.php | 2 +-
.../Facebook/facebook/jsonwrapper/JSON/JSON.php | 2 +-
plugins/Facebook/facebookaction.php | 2 +-
plugins/Facebook/facebookhome.php | 2 +-
plugins/LinkbackPlugin.php | 2 +-
plugins/Meteor/MeteorPlugin.php | 2 +-
plugins/OpenID/openid.php | 4 +-
.../TwitterBridge/daemons/synctwitterfriends.php | 8 +-
.../TwitterBridge/daemons/twitterstatusfetcher.php | 8 +-
plugins/UserFlag/flagprofile.php | 2 +-
scripts/console.php | 2 +-
scripts/createsim.php | 4 +-
scripts/deleteuser.php | 4 +-
scripts/fixup_utf8.php | 2 +-
scripts/makegroupadmin.php | 4 +-
scripts/registeruser.php | 4 +-
scripts/showcache.php | 2 +-
scripts/sitemap.php | 4 +-
scripts/update_translations.php | 2 +-
59 files changed, 6448 insertions(+), 3580 deletions(-)
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/actions/emailsettings.php b/actions/emailsettings.php
index 715457eab..67b991cdc 100644
--- a/actions/emailsettings.php
+++ b/actions/emailsettings.php
@@ -452,7 +452,7 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
- $this->serverError(_("Could not update user record."));
+ $this->serverError(_("Couldn't update user record."));
}
$this->showForm(_('Incoming email address removed.'), true);
@@ -474,7 +474,7 @@ class EmailsettingsAction extends AccountSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
- $this->serverError(_("Could not update user record."));
+ $this->serverError(_("Couldn't update user record."));
}
$this->showForm(_('New incoming email address added.'), true);
diff --git a/actions/smssettings.php b/actions/smssettings.php
index 4debe1967..9fa7f62fb 100644
--- a/actions/smssettings.php
+++ b/actions/smssettings.php
@@ -525,7 +525,7 @@ class SmssettingsAction extends ConnectSettingsAction
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
- $this->serverError(_("Could not update user record."));
+ $this->serverError(_("Couldn't update user record."));
}
$this->showForm(_('Incoming email address removed.'), true);
diff --git a/classes/File.php b/classes/File.php
index dd0c3227e..e04a9d525 100644
--- a/classes/File.php
+++ b/classes/File.php
@@ -99,7 +99,7 @@ class File extends Memcached_DataObject
} elseif (is_string($redir_data)) {
$redir_url = $redir_data;
} else {
- throw new ServerException("Cannot process url '$given_url'");
+ throw new ServerException("Can't process url '$given_url'");
}
// TODO: max field length
if ($redir_url === $given_url || strlen($redir_url) > 255) {
diff --git a/classes/Notice.php b/classes/Notice.php
index 862d4c762..9886875cb 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -680,7 +680,7 @@ class Notice extends Memcached_DataObject
return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null);
}
- # Get the cache; if we cannot, just go to the DB
+ # Get the cache; if we can't, just go to the DB
$cache = common_memcache();
@@ -1364,7 +1364,7 @@ class Notice extends Memcached_DataObject
}
}
- // If it's not a "low bandwidth" source (one where you cannot set
+ // If it's not a "low bandwidth" source (one where you can't set
// a reply_to argument), we return. This is mostly web and API
// clients.
diff --git a/extlib/Auth/OpenID/Consumer.php b/extlib/Auth/OpenID/Consumer.php
index c75ef4c06..500890b65 100644
--- a/extlib/Auth/OpenID/Consumer.php
+++ b/extlib/Auth/OpenID/Consumer.php
@@ -1059,7 +1059,7 @@ class Auth_OpenID_GenericConsumer {
}
}
- // Fragments do not influence discovery, so we cannot compare a
+ // Fragments do not influence discovery, so we can't compare a
// claimed identifier with a fragment to discovered
// information.
list($defragged_claimed_id, $_) =
diff --git a/extlib/Auth/OpenID/Discover.php b/extlib/Auth/OpenID/Discover.php
index 9bb3ee357..62aeb1d2b 100644
--- a/extlib/Auth/OpenID/Discover.php
+++ b/extlib/Auth/OpenID/Discover.php
@@ -515,7 +515,7 @@ function Auth_OpenID_discoverXRI($iname, &$fetcher)
function Auth_OpenID_discover($uri, &$fetcher)
{
- // If the fetcher (i.e., PHP) doesn't support SSL, we cannot do
+ // If the fetcher (i.e., PHP) doesn't support SSL, we can't do
// discovery on an HTTPS URL.
if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) {
return array($uri, array());
@@ -527,7 +527,7 @@ function Auth_OpenID_discover($uri, &$fetcher)
$result = Auth_OpenID_discoverURI($uri, $fetcher);
}
- // If the fetcher doesn't support SSL, we cannot interact with
+ // If the fetcher doesn't support SSL, we can't interact with
// HTTPS server URLs; remove those endpoints from the list.
if (!$fetcher->supportsSSL()) {
$http_endpoints = array();
diff --git a/extlib/Auth/OpenID/FileStore.php b/extlib/Auth/OpenID/FileStore.php
index d9962e153..29d8d20e7 100644
--- a/extlib/Auth/OpenID/FileStore.php
+++ b/extlib/Auth/OpenID/FileStore.php
@@ -496,7 +496,7 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
return true;
} else {
- // Could not open directory.
+ // Couldn't open directory.
return false;
}
}
diff --git a/extlib/DB.php b/extlib/DB.php
index 4ef66f66f..a511979e6 100644
--- a/extlib/DB.php
+++ b/extlib/DB.php
@@ -1341,7 +1341,7 @@ class DB_result
* returning the total number of rows that would have been returned,
* rather than the real number. As a result, we'll just do the limit
* calculations for fbsql in the same way as a database with emulated
- * limits. Unfortunately, we cannot just do this in DB_fbsql::numRows()
+ * limits. Unfortunately, we can't just do this in DB_fbsql::numRows()
* because that only gets the result resource, rather than the full
* DB_Result object. */
if (($this->dbh->features['limit'] === 'emulate'
diff --git a/extlib/DB/DataObject/Generator.php b/extlib/DB/DataObject/Generator.php
index e14e3ef7f..ff6e42c7d 100644
--- a/extlib/DB/DataObject/Generator.php
+++ b/extlib/DB/DataObject/Generator.php
@@ -632,7 +632,7 @@ class DB_DataObject_Generator extends DB_DataObject
echo "*****************************************************************\n".
"** WARNING COLUMN NAME UNUSABLE **\n".
"** Found column '{$t->name}', of type '{$t->type}' **\n".
- "** Since this column name cannot be converted to a php variable **\n".
+ "** Since this column name can't be converted to a php variable **\n".
"** name, and the whole idea of mapping would result in a mess **\n".
"** This column has been ignored... **\n".
"*****************************************************************\n";
@@ -910,7 +910,7 @@ class DB_DataObject_Generator extends DB_DataObject
echo "*****************************************************************\n".
"** WARNING COLUMN NAME UNUSABLE **\n".
"** Found column '{$t->name}', of type '{$t->type}' **\n".
- "** Since this column name cannot be converted to a php variable **\n".
+ "** Since this column name can't be converted to a php variable **\n".
"** name, and the whole idea of mapping would result in a mess **\n".
"** This column has been ignored... **\n".
"*****************************************************************\n";
diff --git a/extlib/DB/dbase.php b/extlib/DB/dbase.php
index 15d259c4d..67afc897d 100644
--- a/extlib/DB/dbase.php
+++ b/extlib/DB/dbase.php
@@ -287,7 +287,7 @@ class DB_dbase extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -352,7 +352,7 @@ class DB_dbase extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -373,7 +373,7 @@ class DB_dbase extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/fbsql.php b/extlib/DB/fbsql.php
index 48ff705cf..4de4078f7 100644
--- a/extlib/DB/fbsql.php
+++ b/extlib/DB/fbsql.php
@@ -262,7 +262,7 @@ class DB_fbsql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -309,7 +309,7 @@ class DB_fbsql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -376,7 +376,7 @@ class DB_fbsql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -401,7 +401,7 @@ class DB_fbsql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/ibase.php b/extlib/DB/ibase.php
index 1e444d634..ee19c5589 100644
--- a/extlib/DB/ibase.php
+++ b/extlib/DB/ibase.php
@@ -353,7 +353,7 @@ class DB_ibase extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -402,7 +402,7 @@ class DB_ibase extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -449,7 +449,7 @@ class DB_ibase extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/ifx.php b/extlib/DB/ifx.php
index dcb3dbd3e..baa6f2867 100644
--- a/extlib/DB/ifx.php
+++ b/extlib/DB/ifx.php
@@ -147,7 +147,7 @@ class DB_ifx extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it cannot actually be designated
+ * {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -328,7 +328,7 @@ class DB_ifx extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -387,7 +387,7 @@ class DB_ifx extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -411,7 +411,7 @@ class DB_ifx extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -555,7 +555,7 @@ class DB_ifx extends DB_common
*
* If analyzing a query result and the result has duplicate field names,
* an error will be raised saying
- * cannot distinguish duplicate field names.
+ * can't distinguish duplicate field names.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
@@ -604,7 +604,7 @@ class DB_ifx extends DB_common
$count = @ifx_num_fields($id);
if (count($flds) != $count) {
- return $this->raiseError("cannot distinguish duplicate field names");
+ return $this->raiseError("can't distinguish duplicate field names");
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
diff --git a/extlib/DB/msql.php b/extlib/DB/msql.php
index ee64f932f..34854f472 100644
--- a/extlib/DB/msql.php
+++ b/extlib/DB/msql.php
@@ -288,7 +288,7 @@ class DB_msql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
@@ -339,7 +339,7 @@ class DB_msql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -360,7 +360,7 @@ class DB_msql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -385,7 +385,7 @@ class DB_msql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/mssql.php b/extlib/DB/mssql.php
index 1aad75671..511a2b686 100644
--- a/extlib/DB/mssql.php
+++ b/extlib/DB/mssql.php
@@ -156,7 +156,7 @@ class DB_mssql extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it cannot actually be designated
+ * {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -324,7 +324,7 @@ class DB_mssql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -371,7 +371,7 @@ class DB_mssql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -392,7 +392,7 @@ class DB_mssql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -417,7 +417,7 @@ class DB_mssql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/mysql.php b/extlib/DB/mysql.php
index bfe34dbe8..c67254520 100644
--- a/extlib/DB/mysql.php
+++ b/extlib/DB/mysql.php
@@ -139,7 +139,7 @@ class DB_mysql extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it cannot actually be designated
+ * {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -359,7 +359,7 @@ class DB_mysql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -411,7 +411,7 @@ class DB_mysql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -432,7 +432,7 @@ class DB_mysql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -457,7 +457,7 @@ class DB_mysql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -722,7 +722,7 @@ class DB_mysql extends DB_common
return $result;
}
if ($result == 0) {
- // Failed to get the lock, cannot do the conversion, bail
+ // Failed to get the lock, can't do the conversion, bail
// with a DB_ERROR_NOT_LOCKED error
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
}
@@ -757,7 +757,7 @@ class DB_mysql extends DB_common
* Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
- * WARNING: Older versions of MySQL cannot handle the backtick
+ * WARNING: Older versions of MySQL can't handle the backtick
* character (`) in table or column names.
*
* @param string $str identifier name to be quoted
diff --git a/extlib/DB/mysqli.php b/extlib/DB/mysqli.php
index b6196dfcc..c6941b170 100644
--- a/extlib/DB/mysqli.php
+++ b/extlib/DB/mysqli.php
@@ -142,7 +142,7 @@ class DB_mysqli extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it cannot actually be designated
+ * {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -434,7 +434,7 @@ class DB_mysqli extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -486,7 +486,7 @@ class DB_mysqli extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -507,7 +507,7 @@ class DB_mysqli extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -532,7 +532,7 @@ class DB_mysqli extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -796,7 +796,7 @@ class DB_mysqli extends DB_common
return $result;
}
if ($result == 0) {
- // Failed to get the lock, cannot do the conversion, bail
+ // Failed to get the lock, can't do the conversion, bail
// with a DB_ERROR_NOT_LOCKED error
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
}
@@ -832,7 +832,7 @@ class DB_mysqli extends DB_common
* Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
- * WARNING: Older versions of MySQL cannot handle the backtick
+ * WARNING: Older versions of MySQL can't handle the backtick
* character (`) in table or column names.
*
* @param string $str identifier name to be quoted
diff --git a/extlib/DB/oci8.php b/extlib/DB/oci8.php
index 6ad36643a..d30794871 100644
--- a/extlib/DB/oci8.php
+++ b/extlib/DB/oci8.php
@@ -251,7 +251,7 @@ class DB_oci8 extends DB_common
$char);
$error = OCIError();
if (!empty($error) && $error['code'] == 12541) {
- // Could not find TNS listener. Try direct connection.
+ // Couldn't find TNS listener. Try direct connection.
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
null,
@@ -368,7 +368,7 @@ class DB_oci8 extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -415,7 +415,7 @@ class DB_oci8 extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -468,7 +468,7 @@ class DB_oci8 extends DB_common
* is turned on.
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -511,7 +511,7 @@ class DB_oci8 extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/odbc.php b/extlib/DB/odbc.php
index b0dc83ab5..eba43659a 100644
--- a/extlib/DB/odbc.php
+++ b/extlib/DB/odbc.php
@@ -301,7 +301,7 @@ class DB_odbc extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -356,7 +356,7 @@ class DB_odbc extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -377,7 +377,7 @@ class DB_odbc extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -427,7 +427,7 @@ class DB_odbc extends DB_common
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/pgsql.php b/extlib/DB/pgsql.php
index 498ef8ade..6030bb4c1 100644
--- a/extlib/DB/pgsql.php
+++ b/extlib/DB/pgsql.php
@@ -115,7 +115,7 @@ class DB_pgsql extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it cannot actually be designated
+ * {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -397,7 +397,7 @@ class DB_pgsql extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -445,7 +445,7 @@ class DB_pgsql extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -535,7 +535,7 @@ class DB_pgsql extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -560,7 +560,7 @@ class DB_pgsql extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/sqlite.php b/extlib/DB/sqlite.php
index 96d5c934a..5c4b396e5 100644
--- a/extlib/DB/sqlite.php
+++ b/extlib/DB/sqlite.php
@@ -334,7 +334,7 @@ class DB_sqlite extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -396,7 +396,7 @@ class DB_sqlite extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -422,7 +422,7 @@ class DB_sqlite extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -447,7 +447,7 @@ class DB_sqlite extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
diff --git a/extlib/DB/sybase.php b/extlib/DB/sybase.php
index 97ab41a22..3befbf6ea 100644
--- a/extlib/DB/sybase.php
+++ b/extlib/DB/sybase.php
@@ -118,7 +118,7 @@ class DB_sybase extends DB_common
/**
* The quantity of transactions begun
*
- * {@internal While this is private, it cannot actually be designated
+ * {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
@@ -302,7 +302,7 @@ class DB_sybase extends DB_common
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
- * DB_result::fetchInto() instead. It cannot be declared "protected"
+ * DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
@@ -359,7 +359,7 @@ class DB_sybase extends DB_common
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
- * DB_result::free() instead. It cannot be declared "protected"
+ * DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -380,7 +380,7 @@ class DB_sybase extends DB_common
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numCols() instead. It cannot be declared "protected"
+ * DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -405,7 +405,7 @@ class DB_sybase extends DB_common
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
- * DB_result::numRows() instead. It cannot be declared "protected"
+ * DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
@@ -835,7 +835,7 @@ class DB_sybase extends DB_common
$tableName = $table;
/* We're running sp_helpindex directly because it doesn't exist in
- * older versions of ASE -- unfortunately, we cannot just use
+ * older versions of ASE -- unfortunately, we can't just use
* DB::isError() because the user may be using callback error
* handling. */
$res = @sybase_query("sp_helpindex $table", $this->connection);
diff --git a/extlib/HTTP/Request2/Adapter/Socket.php b/extlib/HTTP/Request2/Adapter/Socket.php
index 13cd6136f..ff44d4959 100644
--- a/extlib/HTTP/Request2/Adapter/Socket.php
+++ b/extlib/HTTP/Request2/Adapter/Socket.php
@@ -1,971 +1,971 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
- * @link http://pear.php.net/package/HTTP_Request2
- */
-
-/**
- * Base class for HTTP_Request2 adapters
- */
-require_once 'HTTP/Request2/Adapter.php';
-
-/**
- * Socket-based adapter for HTTP_Request2
- *
- * This adapter uses only PHP sockets and will work on almost any PHP
- * environment. Code is based on original HTTP_Request PEAR package.
- *
- * @category HTTP
- * @package HTTP_Request2
- * @author Alexey Borzov
- * @version Release: 0.4.1
- */
-class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
-{
- /**
- * Regular expression for 'token' rule from RFC 2616
- */
- const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
-
- /**
- * Regular expression for 'quoted-string' rule from RFC 2616
- */
- const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
-
- /**
- * Connected sockets, needed for Keep-Alive support
- * @var array
- * @see connect()
- */
- protected static $sockets = array();
-
- /**
- * Data for digest authentication scheme
- *
- * The keys for the array are URL prefixes.
- *
- * The values are associative arrays with data (realm, nonce, nonce-count,
- * opaque...) needed for digest authentication. Stored here to prevent making
- * duplicate requests to digest-protected resources after we have already
- * received the challenge.
- *
- * @var array
- */
- protected static $challenges = array();
-
- /**
- * Connected socket
- * @var resource
- * @see connect()
- */
- protected $socket;
-
- /**
- * Challenge used for server digest authentication
- * @var array
- */
- protected $serverChallenge;
-
- /**
- * Challenge used for proxy digest authentication
- * @var array
- */
- protected $proxyChallenge;
-
- /**
- * Global timeout, exception will be raised if request continues past this time
- * @var integer
- */
- protected $timeout = null;
-
- /**
- * Remaining length of the current chunk, when reading chunked response
- * @var integer
- * @see readChunked()
- */
- protected $chunkLength = 0;
-
- /**
- * Sends request to the remote server and returns its response
- *
- * @param HTTP_Request2
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- public function sendRequest(HTTP_Request2 $request)
- {
- $this->request = $request;
- $keepAlive = $this->connect();
- $headers = $this->prepareHeaders();
-
- // Use global request timeout if given, see feature requests #5735, #8964
- if ($timeout = $request->getConfig('timeout')) {
- $this->timeout = time() + $timeout;
- } else {
- $this->timeout = null;
- }
-
- try {
- if (false === @fwrite($this->socket, $headers, strlen($headers))) {
- throw new HTTP_Request2_Exception('Error writing request');
- }
- // provide request headers to the observer, see request #7633
- $this->request->setLastEvent('sentHeaders', $headers);
- $this->writeBody();
-
- if ($this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $request->getConfig('timeout') . ' second(s)'
- );
- }
-
- $response = $this->readResponse();
-
- if (!$this->canKeepAlive($keepAlive, $response)) {
- $this->disconnect();
- }
-
- if ($this->shouldUseProxyDigestAuth($response)) {
- return $this->sendRequest($request);
- }
- if ($this->shouldUseServerDigestAuth($response)) {
- return $this->sendRequest($request);
- }
- if ($authInfo = $response->getHeader('authentication-info')) {
- $this->updateChallenge($this->serverChallenge, $authInfo);
- }
- if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
- $this->updateChallenge($this->proxyChallenge, $proxyInfo);
- }
-
- } catch (Exception $e) {
- $this->disconnect();
- throw $e;
- }
-
- return $response;
- }
-
- /**
- * Connects to the remote server
- *
- * @return bool whether the connection can be persistent
- * @throws HTTP_Request2_Exception
- */
- protected function connect()
- {
- $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
- $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
- $headers = $this->request->getHeaders();
- $reqHost = $this->request->getUrl()->getHost();
- if (!($reqPort = $this->request->getUrl()->getPort())) {
- $reqPort = $secure? 443: 80;
- }
-
- if ($host = $this->request->getConfig('proxy_host')) {
- if (!($port = $this->request->getConfig('proxy_port'))) {
- throw new HTTP_Request2_Exception('Proxy port not provided');
- }
- $proxy = true;
- } else {
- $host = $reqHost;
- $port = $reqPort;
- $proxy = false;
- }
-
- if ($tunnel && !$proxy) {
- throw new HTTP_Request2_Exception(
- "Trying to perform CONNECT request without proxy"
- );
- }
- if ($secure && !in_array('ssl', stream_get_transports())) {
- throw new HTTP_Request2_Exception(
- 'Need OpenSSL support for https:// requests'
- );
- }
-
- // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
- // connection token to a proxy server...
- if ($proxy && !$secure &&
- !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
- ) {
- $this->request->setHeader('connection');
- }
-
- $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
- empty($headers['connection'])) ||
- (!empty($headers['connection']) &&
- 'Keep-Alive' == $headers['connection']);
- $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
-
- $options = array();
- if ($secure || $tunnel) {
- foreach ($this->request->getConfig() as $name => $value) {
- if ('ssl_' == substr($name, 0, 4) && null !== $value) {
- if ('ssl_verify_host' == $name) {
- if ($value) {
- $options['CN_match'] = $reqHost;
- }
- } else {
- $options[substr($name, 4)] = $value;
- }
- }
- }
- ksort($options);
- }
-
- // Changing SSL context options after connection is established does *not*
- // work, we need a new connection if options change
- $remote = $host . ':' . $port;
- $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
- (empty($options)? '': ':' . serialize($options));
- unset($this->socket);
-
- // We use persistent connections and have a connected socket?
- // Ensure that the socket is still connected, see bug #16149
- if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
- !feof(self::$sockets[$socketKey])
- ) {
- $this->socket =& self::$sockets[$socketKey];
-
- } elseif ($secure && $proxy && !$tunnel) {
- $this->establishTunnel();
- $this->request->setLastEvent(
- 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
- );
- self::$sockets[$socketKey] =& $this->socket;
-
- } else {
- // Set SSL context options if doing HTTPS request or creating a tunnel
- $context = stream_context_create();
- foreach ($options as $name => $value) {
- if (!stream_context_set_option($context, 'ssl', $name, $value)) {
- throw new HTTP_Request2_Exception(
- "Error setting SSL context option '{$name}'"
- );
- }
- }
- $this->socket = @stream_socket_client(
- $remote, $errno, $errstr,
- $this->request->getConfig('connect_timeout'),
- STREAM_CLIENT_CONNECT, $context
- );
- if (!$this->socket) {
- throw new HTTP_Request2_Exception(
- "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
- );
- }
- $this->request->setLastEvent('connect', $remote);
- self::$sockets[$socketKey] =& $this->socket;
- }
- return $keepAlive;
- }
-
- /**
- * Establishes a tunnel to a secure remote server via HTTP CONNECT request
- *
- * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
- * sees that we are connected to a proxy server (duh!) rather than the server
- * that presents its certificate.
- *
- * @link http://tools.ietf.org/html/rfc2817#section-5.2
- * @throws HTTP_Request2_Exception
- */
- protected function establishTunnel()
- {
- $donor = new self;
- $connect = new HTTP_Request2(
- $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
- array_merge($this->request->getConfig(),
- array('adapter' => $donor))
- );
- $response = $connect->send();
- // Need any successful (2XX) response
- if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
- throw new HTTP_Request2_Exception(
- 'Failed to connect via HTTPS proxy. Proxy response: ' .
- $response->getStatus() . ' ' . $response->getReasonPhrase()
- );
- }
- $this->socket = $donor->socket;
-
- $modes = array(
- STREAM_CRYPTO_METHOD_TLS_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
- STREAM_CRYPTO_METHOD_SSLv2_CLIENT
- );
-
- foreach ($modes as $mode) {
- if (stream_socket_enable_crypto($this->socket, true, $mode)) {
- return;
- }
- }
- throw new HTTP_Request2_Exception(
- 'Failed to enable secure connection when connecting through proxy'
- );
- }
-
- /**
- * Checks whether current connection may be reused or should be closed
- *
- * @param boolean whether connection could be persistent
- * in the first place
- * @param HTTP_Request2_Response response object to check
- * @return boolean
- */
- protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
- {
- // Do not close socket on successful CONNECT request
- if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
- 200 <= $response->getStatus() && 300 > $response->getStatus()
- ) {
- return true;
- }
-
- $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
- null !== $response->getHeader('content-length');
- $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
- (null === $response->getHeader('connection') &&
- '1.1' == $response->getVersion());
- return $requestKeepAlive && $lengthKnown && $persistent;
- }
-
- /**
- * Disconnects from the remote server
- */
- protected function disconnect()
- {
- if (is_resource($this->socket)) {
- fclose($this->socket);
- $this->socket = null;
- $this->request->setLastEvent('disconnect');
- }
- }
-
- /**
- * Checks whether another request should be performed with server digest auth
- *
- * Several conditions should be satisfied for it to return true:
- * - response status should be 401
- * - auth credentials should be set in the request object
- * - response should contain WWW-Authenticate header with digest challenge
- * - there is either no challenge stored for this URL or new challenge
- * contains stale=true parameter (in other case we probably just failed
- * due to invalid username / password)
- *
- * The method stores challenge values in $challenges static property
- *
- * @param HTTP_Request2_Response response to check
- * @return boolean whether another request should be performed
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
- {
- // no sense repeating a request if we don't have credentials
- if (401 != $response->getStatus() || !$this->request->getAuth()) {
- return false;
- }
- if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
- return false;
- }
-
- $url = $this->request->getUrl();
- $scheme = $url->getScheme();
- $host = $scheme . '://' . $url->getHost();
- if ($port = $url->getPort()) {
- if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
- (0 == strcasecmp($scheme, 'https') && 443 != $port)
- ) {
- $host .= ':' . $port;
- }
- }
-
- if (!empty($challenge['domain'])) {
- $prefixes = array();
- foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
- // don't bother with different servers
- if ('/' == substr($prefix, 0, 1)) {
- $prefixes[] = $host . $prefix;
- }
- }
- }
- if (empty($prefixes)) {
- $prefixes = array($host . '/');
- }
-
- $ret = true;
- foreach ($prefixes as $prefix) {
- if (!empty(self::$challenges[$prefix]) &&
- (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
- ) {
- // probably credentials are invalid
- $ret = false;
- }
- self::$challenges[$prefix] =& $challenge;
- }
- return $ret;
- }
-
- /**
- * Checks whether another request should be performed with proxy digest auth
- *
- * Several conditions should be satisfied for it to return true:
- * - response status should be 407
- * - proxy auth credentials should be set in the request object
- * - response should contain Proxy-Authenticate header with digest challenge
- * - there is either no challenge stored for this proxy or new challenge
- * contains stale=true parameter (in other case we probably just failed
- * due to invalid username / password)
- *
- * The method stores challenge values in $challenges static property
- *
- * @param HTTP_Request2_Response response to check
- * @return boolean whether another request should be performed
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
- {
- if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
- return false;
- }
- if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
- return false;
- }
-
- $key = 'proxy://' . $this->request->getConfig('proxy_host') .
- ':' . $this->request->getConfig('proxy_port');
-
- if (!empty(self::$challenges[$key]) &&
- (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
- ) {
- $ret = false;
- } else {
- $ret = true;
- }
- self::$challenges[$key] = $challenge;
- return $ret;
- }
-
- /**
- * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
- *
- * There is a problem with implementation of RFC 2617: several of the parameters
- * here are defined as quoted-string and thus may contain backslash escaped
- * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
- * just value of quoted-string X without surrounding quotes, it doesn't speak
- * about removing backslash escaping.
- *
- * Now realm parameter is user-defined and human-readable, strange things
- * happen when it contains quotes:
- * - Apache allows quotes in realm, but apparently uses realm value without
- * backslashes for digest computation
- * - Squid allows (manually escaped) quotes there, but it is impossible to
- * authorize with either escaped or unescaped quotes used in digest,
- * probably it cannot parse the response (?)
- * - Both IE and Firefox display realm value with backslashes in
- * the password popup and apparently use the same value for digest
- *
- * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
- * quoted-string handling, unfortunately that means failure to authorize
- * sometimes
- *
- * @param string value of WWW-Authenticate or Proxy-Authenticate header
- * @return mixed associative array with challenge parameters, false if
- * no challenge is present in header value
- * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
- */
- protected function parseDigestChallenge($headerValue)
- {
- $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
- self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
- $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
- if (!preg_match($challenge, $headerValue, $matches)) {
- return false;
- }
-
- preg_match_all('!' . $authParam . '!', $matches[0], $params);
- $paramsAry = array();
- $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
- 'algorithm', 'qop');
- for ($i = 0; $i < count($params[0]); $i++) {
- // section 3.2.1: Any unrecognized directive MUST be ignored.
- if (in_array($params[1][$i], $knownParams)) {
- if ('"' == substr($params[2][$i], 0, 1)) {
- $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
- } else {
- $paramsAry[$params[1][$i]] = $params[2][$i];
- }
- }
- }
- // we only support qop=auth
- if (!empty($paramsAry['qop']) &&
- !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
- ) {
- throw new HTTP_Request2_Exception(
- "Only 'auth' qop is currently supported in digest authentication, " .
- "server requested '{$paramsAry['qop']}'"
- );
- }
- // we only support algorithm=MD5
- if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
- throw new HTTP_Request2_Exception(
- "Only 'MD5' algorithm is currently supported in digest authentication, " .
- "server requested '{$paramsAry['algorithm']}'"
- );
- }
-
- return $paramsAry;
- }
-
- /**
- * Parses [Proxy-]Authentication-Info header value and updates challenge
- *
- * @param array challenge to update
- * @param string value of [Proxy-]Authentication-Info header
- * @todo validate server rspauth response
- */
- protected function updateChallenge(&$challenge, $headerValue)
- {
- $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
- self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
- $paramsAry = array();
-
- preg_match_all($authParam, $headerValue, $params);
- for ($i = 0; $i < count($params[0]); $i++) {
- if ('"' == substr($params[2][$i], 0, 1)) {
- $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
- } else {
- $paramsAry[$params[1][$i]] = $params[2][$i];
- }
- }
- // for now, just update the nonce value
- if (!empty($paramsAry['nextnonce'])) {
- $challenge['nonce'] = $paramsAry['nextnonce'];
- $challenge['nc'] = 1;
- }
- }
-
- /**
- * Creates a value for [Proxy-]Authorization header when using digest authentication
- *
- * @param string user name
- * @param string password
- * @param string request URL
- * @param array digest challenge parameters
- * @return string value of [Proxy-]Authorization request header
- * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
- */
- protected function createDigestResponse($user, $password, $url, &$challenge)
- {
- if (false !== ($q = strpos($url, '?')) &&
- $this->request->getConfig('digest_compat_ie')
- ) {
- $url = substr($url, 0, $q);
- }
-
- $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
- $a2 = md5($this->request->getMethod() . ':' . $url);
-
- if (empty($challenge['qop'])) {
- $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
- } else {
- $challenge['cnonce'] = 'Req2.' . rand();
- if (empty($challenge['nc'])) {
- $challenge['nc'] = 1;
- }
- $nc = sprintf('%08x', $challenge['nc']++);
- $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
- $challenge['cnonce'] . ':auth:' . $a2);
- }
- return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
- 'realm="' . $challenge['realm'] . '", ' .
- 'nonce="' . $challenge['nonce'] . '", ' .
- 'uri="' . $url . '", ' .
- 'response="' . $digest . '"' .
- (!empty($challenge['opaque'])?
- ', opaque="' . $challenge['opaque'] . '"':
- '') .
- (!empty($challenge['qop'])?
- ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
- '');
- }
-
- /**
- * Adds 'Authorization' header (if needed) to request headers array
- *
- * @param array request headers
- * @param string request host (needed for digest authentication)
- * @param string request URL (needed for digest authentication)
- * @throws HTTP_Request2_Exception
- */
- protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
- {
- if (!($auth = $this->request->getAuth())) {
- return;
- }
- switch ($auth['scheme']) {
- case HTTP_Request2::AUTH_BASIC:
- $headers['authorization'] =
- 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
- break;
-
- case HTTP_Request2::AUTH_DIGEST:
- unset($this->serverChallenge);
- $fullUrl = ('/' == $requestUrl[0])?
- $this->request->getUrl()->getScheme() . '://' .
- $requestHost . $requestUrl:
- $requestUrl;
- foreach (array_keys(self::$challenges) as $key) {
- if ($key == substr($fullUrl, 0, strlen($key))) {
- $headers['authorization'] = $this->createDigestResponse(
- $auth['user'], $auth['password'],
- $requestUrl, self::$challenges[$key]
- );
- $this->serverChallenge =& self::$challenges[$key];
- break;
- }
- }
- break;
-
- default:
- throw new HTTP_Request2_Exception(
- "Unknown HTTP authentication scheme '{$auth['scheme']}'"
- );
- }
- }
-
- /**
- * Adds 'Proxy-Authorization' header (if needed) to request headers array
- *
- * @param array request headers
- * @param string request URL (needed for digest authentication)
- * @throws HTTP_Request2_Exception
- */
- protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
- {
- if (!$this->request->getConfig('proxy_host') ||
- !($user = $this->request->getConfig('proxy_user')) ||
- (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
- HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
- ) {
- return;
- }
-
- $password = $this->request->getConfig('proxy_password');
- switch ($this->request->getConfig('proxy_auth_scheme')) {
- case HTTP_Request2::AUTH_BASIC:
- $headers['proxy-authorization'] =
- 'Basic ' . base64_encode($user . ':' . $password);
- break;
-
- case HTTP_Request2::AUTH_DIGEST:
- unset($this->proxyChallenge);
- $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
- ':' . $this->request->getConfig('proxy_port');
- if (!empty(self::$challenges[$proxyUrl])) {
- $headers['proxy-authorization'] = $this->createDigestResponse(
- $user, $password,
- $requestUrl, self::$challenges[$proxyUrl]
- );
- $this->proxyChallenge =& self::$challenges[$proxyUrl];
- }
- break;
-
- default:
- throw new HTTP_Request2_Exception(
- "Unknown HTTP authentication scheme '" .
- $this->request->getConfig('proxy_auth_scheme') . "'"
- );
- }
- }
-
-
- /**
- * Creates the string with the Request-Line and request headers
- *
- * @return string
- * @throws HTTP_Request2_Exception
- */
- protected function prepareHeaders()
- {
- $headers = $this->request->getHeaders();
- $url = $this->request->getUrl();
- $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
- $host = $url->getHost();
-
- $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
- if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
- $host .= ':' . (empty($port)? $defaultPort: $port);
- }
- // Do not overwrite explicitly set 'Host' header, see bug #16146
- if (!isset($headers['host'])) {
- $headers['host'] = $host;
- }
-
- if ($connect) {
- $requestUrl = $host;
-
- } else {
- if (!$this->request->getConfig('proxy_host') ||
- 0 == strcasecmp($url->getScheme(), 'https')
- ) {
- $requestUrl = '';
- } else {
- $requestUrl = $url->getScheme() . '://' . $host;
- }
- $path = $url->getPath();
- $query = $url->getQuery();
- $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
- }
-
- if ('1.1' == $this->request->getConfig('protocol_version') &&
- extension_loaded('zlib') && !isset($headers['accept-encoding'])
- ) {
- $headers['accept-encoding'] = 'gzip, deflate';
- }
-
- $this->addAuthorizationHeader($headers, $host, $requestUrl);
- $this->addProxyAuthorizationHeader($headers, $requestUrl);
- $this->calculateRequestLength($headers);
-
- $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
- $this->request->getConfig('protocol_version') . "\r\n";
- foreach ($headers as $name => $value) {
- $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
- $headersStr .= $canonicalName . ': ' . $value . "\r\n";
- }
- return $headersStr . "\r\n";
- }
-
- /**
- * Sends the request body
- *
- * @throws HTTP_Request2_Exception
- */
- protected function writeBody()
- {
- if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
- 0 == $this->contentLength
- ) {
- return;
- }
-
- $position = 0;
- $bufferSize = $this->request->getConfig('buffer_size');
- while ($position < $this->contentLength) {
- if (is_string($this->requestBody)) {
- $str = substr($this->requestBody, $position, $bufferSize);
- } elseif (is_resource($this->requestBody)) {
- $str = fread($this->requestBody, $bufferSize);
- } else {
- $str = $this->requestBody->read($bufferSize);
- }
- if (false === @fwrite($this->socket, $str, strlen($str))) {
- throw new HTTP_Request2_Exception('Error writing request');
- }
- // Provide the length of written string to the observer, request #7630
- $this->request->setLastEvent('sentBodyPart', strlen($str));
- $position += strlen($str);
- }
- }
-
- /**
- * Reads the remote server's response
- *
- * @return HTTP_Request2_Response
- * @throws HTTP_Request2_Exception
- */
- protected function readResponse()
- {
- $bufferSize = $this->request->getConfig('buffer_size');
-
- do {
- $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
- do {
- $headerLine = $this->readLine($bufferSize);
- $response->parseHeaderLine($headerLine);
- } while ('' != $headerLine);
- } while (in_array($response->getStatus(), array(100, 101)));
-
- $this->request->setLastEvent('receivedHeaders', $response);
-
- // No body possible in such responses
- if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
- (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
- 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
- in_array($response->getStatus(), array(204, 304))
- ) {
- return $response;
- }
-
- $chunked = 'chunked' == $response->getHeader('transfer-encoding');
- $length = $response->getHeader('content-length');
- $hasBody = false;
- if ($chunked || null === $length || 0 < intval($length)) {
- // RFC 2616, section 4.4:
- // 3. ... If a message is received with both a
- // Transfer-Encoding header field and a Content-Length header field,
- // the latter MUST be ignored.
- $toRead = ($chunked || null === $length)? null: $length;
- $this->chunkLength = 0;
-
- while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
- if ($chunked) {
- $data = $this->readChunked($bufferSize);
- } elseif (is_null($toRead)) {
- $data = $this->fread($bufferSize);
- } else {
- $data = $this->fread(min($toRead, $bufferSize));
- $toRead -= strlen($data);
- }
- if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
- break;
- }
-
- $hasBody = true;
- if ($this->request->getConfig('store_body')) {
- $response->appendBody($data);
- }
- if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
- $this->request->setLastEvent('receivedEncodedBodyPart', $data);
- } else {
- $this->request->setLastEvent('receivedBodyPart', $data);
- }
- }
- }
-
- if ($hasBody) {
- $this->request->setLastEvent('receivedBody', $response);
- }
- return $response;
- }
-
- /**
- * Reads until either the end of the socket or a newline, whichever comes first
- *
- * Strips the trailing newline from the returned data, handles global
- * request timeout. Method idea borrowed from Net_Socket PEAR package.
- *
- * @param int buffer size to use for reading
- * @return Available data up to the newline (not including newline)
- * @throws HTTP_Request2_Exception In case of timeout
- */
- protected function readLine($bufferSize)
- {
- $line = '';
- while (!feof($this->socket)) {
- if ($this->timeout) {
- stream_set_timeout($this->socket, max($this->timeout - time(), 1));
- }
- $line .= @fgets($this->socket, $bufferSize);
- $info = stream_get_meta_data($this->socket);
- if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $this->request->getConfig('timeout') . ' second(s)'
- );
- }
- if (substr($line, -1) == "\n") {
- return rtrim($line, "\r\n");
- }
- }
- return $line;
- }
-
- /**
- * Wrapper around fread(), handles global request timeout
- *
- * @param int Reads up to this number of bytes
- * @return Data read from socket
- * @throws HTTP_Request2_Exception In case of timeout
- */
- protected function fread($length)
- {
- if ($this->timeout) {
- stream_set_timeout($this->socket, max($this->timeout - time(), 1));
- }
- $data = fread($this->socket, $length);
- $info = stream_get_meta_data($this->socket);
- if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
- throw new HTTP_Request2_Exception(
- 'Request timed out after ' .
- $this->request->getConfig('timeout') . ' second(s)'
- );
- }
- return $data;
- }
-
- /**
- * Reads a part of response body encoded with chunked Transfer-Encoding
- *
- * @param int buffer size to use for reading
- * @return string
- * @throws HTTP_Request2_Exception
- */
- protected function readChunked($bufferSize)
- {
- // at start of the next chunk?
- if (0 == $this->chunkLength) {
- $line = $this->readLine($bufferSize);
- if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
- throw new HTTP_Request2_Exception(
- "Cannot decode chunked response, invalid chunk length '{$line}'"
- );
- } else {
- $this->chunkLength = hexdec($matches[1]);
- // Chunk with zero length indicates the end
- if (0 == $this->chunkLength) {
- $this->readLine($bufferSize);
- return '';
- }
- }
- }
- $data = $this->fread(min($this->chunkLength, $bufferSize));
- $this->chunkLength -= strlen($data);
- if (0 == $this->chunkLength) {
- $this->readLine($bufferSize); // Trailing CRLF
- }
- return $data;
- }
-}
-
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $
+ * @link http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * This adapter uses only PHP sockets and will work on almost any PHP
+ * environment. Code is based on original HTTP_Request PEAR package.
+ *
+ * @category HTTP
+ * @package HTTP_Request2
+ * @author Alexey Borzov
+ * @version Release: 0.4.1
+ */
+class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
+{
+ /**
+ * Regular expression for 'token' rule from RFC 2616
+ */
+ const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
+
+ /**
+ * Regular expression for 'quoted-string' rule from RFC 2616
+ */
+ const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
+
+ /**
+ * Connected sockets, needed for Keep-Alive support
+ * @var array
+ * @see connect()
+ */
+ protected static $sockets = array();
+
+ /**
+ * Data for digest authentication scheme
+ *
+ * The keys for the array are URL prefixes.
+ *
+ * The values are associative arrays with data (realm, nonce, nonce-count,
+ * opaque...) needed for digest authentication. Stored here to prevent making
+ * duplicate requests to digest-protected resources after we have already
+ * received the challenge.
+ *
+ * @var array
+ */
+ protected static $challenges = array();
+
+ /**
+ * Connected socket
+ * @var resource
+ * @see connect()
+ */
+ protected $socket;
+
+ /**
+ * Challenge used for server digest authentication
+ * @var array
+ */
+ protected $serverChallenge;
+
+ /**
+ * Challenge used for proxy digest authentication
+ * @var array
+ */
+ protected $proxyChallenge;
+
+ /**
+ * Global timeout, exception will be raised if request continues past this time
+ * @var integer
+ */
+ protected $timeout = null;
+
+ /**
+ * Remaining length of the current chunk, when reading chunked response
+ * @var integer
+ * @see readChunked()
+ */
+ protected $chunkLength = 0;
+
+ /**
+ * Sends request to the remote server and returns its response
+ *
+ * @param HTTP_Request2
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ public function sendRequest(HTTP_Request2 $request)
+ {
+ $this->request = $request;
+ $keepAlive = $this->connect();
+ $headers = $this->prepareHeaders();
+
+ // Use global request timeout if given, see feature requests #5735, #8964
+ if ($timeout = $request->getConfig('timeout')) {
+ $this->timeout = time() + $timeout;
+ } else {
+ $this->timeout = null;
+ }
+
+ try {
+ if (false === @fwrite($this->socket, $headers, strlen($headers))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // provide request headers to the observer, see request #7633
+ $this->request->setLastEvent('sentHeaders', $headers);
+ $this->writeBody();
+
+ if ($this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $request->getConfig('timeout') . ' second(s)'
+ );
+ }
+
+ $response = $this->readResponse();
+
+ if (!$this->canKeepAlive($keepAlive, $response)) {
+ $this->disconnect();
+ }
+
+ if ($this->shouldUseProxyDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($this->shouldUseServerDigestAuth($response)) {
+ return $this->sendRequest($request);
+ }
+ if ($authInfo = $response->getHeader('authentication-info')) {
+ $this->updateChallenge($this->serverChallenge, $authInfo);
+ }
+ if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
+ $this->updateChallenge($this->proxyChallenge, $proxyInfo);
+ }
+
+ } catch (Exception $e) {
+ $this->disconnect();
+ throw $e;
+ }
+
+ return $response;
+ }
+
+ /**
+ * Connects to the remote server
+ *
+ * @return bool whether the connection can be persistent
+ * @throws HTTP_Request2_Exception
+ */
+ protected function connect()
+ {
+ $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
+ $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $headers = $this->request->getHeaders();
+ $reqHost = $this->request->getUrl()->getHost();
+ if (!($reqPort = $this->request->getUrl()->getPort())) {
+ $reqPort = $secure? 443: 80;
+ }
+
+ if ($host = $this->request->getConfig('proxy_host')) {
+ if (!($port = $this->request->getConfig('proxy_port'))) {
+ throw new HTTP_Request2_Exception('Proxy port not provided');
+ }
+ $proxy = true;
+ } else {
+ $host = $reqHost;
+ $port = $reqPort;
+ $proxy = false;
+ }
+
+ if ($tunnel && !$proxy) {
+ throw new HTTP_Request2_Exception(
+ "Trying to perform CONNECT request without proxy"
+ );
+ }
+ if ($secure && !in_array('ssl', stream_get_transports())) {
+ throw new HTTP_Request2_Exception(
+ 'Need OpenSSL support for https:// requests'
+ );
+ }
+
+ // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+ // connection token to a proxy server...
+ if ($proxy && !$secure &&
+ !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
+ ) {
+ $this->request->setHeader('connection');
+ }
+
+ $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
+ empty($headers['connection'])) ||
+ (!empty($headers['connection']) &&
+ 'Keep-Alive' == $headers['connection']);
+ $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
+
+ $options = array();
+ if ($secure || $tunnel) {
+ foreach ($this->request->getConfig() as $name => $value) {
+ if ('ssl_' == substr($name, 0, 4) && null !== $value) {
+ if ('ssl_verify_host' == $name) {
+ if ($value) {
+ $options['CN_match'] = $reqHost;
+ }
+ } else {
+ $options[substr($name, 4)] = $value;
+ }
+ }
+ }
+ ksort($options);
+ }
+
+ // Changing SSL context options after connection is established does *not*
+ // work, we need a new connection if options change
+ $remote = $host . ':' . $port;
+ $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
+ (empty($options)? '': ':' . serialize($options));
+ unset($this->socket);
+
+ // We use persistent connections and have a connected socket?
+ // Ensure that the socket is still connected, see bug #16149
+ if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
+ !feof(self::$sockets[$socketKey])
+ ) {
+ $this->socket =& self::$sockets[$socketKey];
+
+ } elseif ($secure && $proxy && !$tunnel) {
+ $this->establishTunnel();
+ $this->request->setLastEvent(
+ 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
+ );
+ self::$sockets[$socketKey] =& $this->socket;
+
+ } else {
+ // Set SSL context options if doing HTTPS request or creating a tunnel
+ $context = stream_context_create();
+ foreach ($options as $name => $value) {
+ if (!stream_context_set_option($context, 'ssl', $name, $value)) {
+ throw new HTTP_Request2_Exception(
+ "Error setting SSL context option '{$name}'"
+ );
+ }
+ }
+ $this->socket = @stream_socket_client(
+ $remote, $errno, $errstr,
+ $this->request->getConfig('connect_timeout'),
+ STREAM_CLIENT_CONNECT, $context
+ );
+ if (!$this->socket) {
+ throw new HTTP_Request2_Exception(
+ "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
+ );
+ }
+ $this->request->setLastEvent('connect', $remote);
+ self::$sockets[$socketKey] =& $this->socket;
+ }
+ return $keepAlive;
+ }
+
+ /**
+ * Establishes a tunnel to a secure remote server via HTTP CONNECT request
+ *
+ * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
+ * sees that we are connected to a proxy server (duh!) rather than the server
+ * that presents its certificate.
+ *
+ * @link http://tools.ietf.org/html/rfc2817#section-5.2
+ * @throws HTTP_Request2_Exception
+ */
+ protected function establishTunnel()
+ {
+ $donor = new self;
+ $connect = new HTTP_Request2(
+ $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
+ array_merge($this->request->getConfig(),
+ array('adapter' => $donor))
+ );
+ $response = $connect->send();
+ // Need any successful (2XX) response
+ if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
+ throw new HTTP_Request2_Exception(
+ 'Failed to connect via HTTPS proxy. Proxy response: ' .
+ $response->getStatus() . ' ' . $response->getReasonPhrase()
+ );
+ }
+ $this->socket = $donor->socket;
+
+ $modes = array(
+ STREAM_CRYPTO_METHOD_TLS_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv2_CLIENT
+ );
+
+ foreach ($modes as $mode) {
+ if (stream_socket_enable_crypto($this->socket, true, $mode)) {
+ return;
+ }
+ }
+ throw new HTTP_Request2_Exception(
+ 'Failed to enable secure connection when connecting through proxy'
+ );
+ }
+
+ /**
+ * Checks whether current connection may be reused or should be closed
+ *
+ * @param boolean whether connection could be persistent
+ * in the first place
+ * @param HTTP_Request2_Response response object to check
+ * @return boolean
+ */
+ protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
+ {
+ // Do not close socket on successful CONNECT request
+ if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()
+ ) {
+ return true;
+ }
+
+ $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) ||
+ null !== $response->getHeader('content-length');
+ $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) ||
+ (null === $response->getHeader('connection') &&
+ '1.1' == $response->getVersion());
+ return $requestKeepAlive && $lengthKnown && $persistent;
+ }
+
+ /**
+ * Disconnects from the remote server
+ */
+ protected function disconnect()
+ {
+ if (is_resource($this->socket)) {
+ fclose($this->socket);
+ $this->socket = null;
+ $this->request->setLastEvent('disconnect');
+ }
+ }
+
+ /**
+ * Checks whether another request should be performed with server digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 401
+ * - auth credentials should be set in the request object
+ * - response should contain WWW-Authenticate header with digest challenge
+ * - there is either no challenge stored for this URL or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
+ {
+ // no sense repeating a request if we don't have credentials
+ if (401 != $response->getStatus() || !$this->request->getAuth()) {
+ return false;
+ }
+ if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
+ return false;
+ }
+
+ $url = $this->request->getUrl();
+ $scheme = $url->getScheme();
+ $host = $scheme . '://' . $url->getHost();
+ if ($port = $url->getPort()) {
+ if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
+ (0 == strcasecmp($scheme, 'https') && 443 != $port)
+ ) {
+ $host .= ':' . $port;
+ }
+ }
+
+ if (!empty($challenge['domain'])) {
+ $prefixes = array();
+ foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
+ // don't bother with different servers
+ if ('/' == substr($prefix, 0, 1)) {
+ $prefixes[] = $host . $prefix;
+ }
+ }
+ }
+ if (empty($prefixes)) {
+ $prefixes = array($host . '/');
+ }
+
+ $ret = true;
+ foreach ($prefixes as $prefix) {
+ if (!empty(self::$challenges[$prefix]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ // probably credentials are invalid
+ $ret = false;
+ }
+ self::$challenges[$prefix] =& $challenge;
+ }
+ return $ret;
+ }
+
+ /**
+ * Checks whether another request should be performed with proxy digest auth
+ *
+ * Several conditions should be satisfied for it to return true:
+ * - response status should be 407
+ * - proxy auth credentials should be set in the request object
+ * - response should contain Proxy-Authenticate header with digest challenge
+ * - there is either no challenge stored for this proxy or new challenge
+ * contains stale=true parameter (in other case we probably just failed
+ * due to invalid username / password)
+ *
+ * The method stores challenge values in $challenges static property
+ *
+ * @param HTTP_Request2_Response response to check
+ * @return boolean whether another request should be performed
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
+ {
+ if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
+ return false;
+ }
+ if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
+ return false;
+ }
+
+ $key = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+
+ if (!empty(self::$challenges[$key]) &&
+ (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+ ) {
+ $ret = false;
+ } else {
+ $ret = true;
+ }
+ self::$challenges[$key] = $challenge;
+ return $ret;
+ }
+
+ /**
+ * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
+ *
+ * There is a problem with implementation of RFC 2617: several of the parameters
+ * here are defined as quoted-string and thus may contain backslash escaped
+ * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
+ * just value of quoted-string X without surrounding quotes, it doesn't speak
+ * about removing backslash escaping.
+ *
+ * Now realm parameter is user-defined and human-readable, strange things
+ * happen when it contains quotes:
+ * - Apache allows quotes in realm, but apparently uses realm value without
+ * backslashes for digest computation
+ * - Squid allows (manually escaped) quotes there, but it is impossible to
+ * authorize with either escaped or unescaped quotes used in digest,
+ * probably it can't parse the response (?)
+ * - Both IE and Firefox display realm value with backslashes in
+ * the password popup and apparently use the same value for digest
+ *
+ * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
+ * quoted-string handling, unfortunately that means failure to authorize
+ * sometimes
+ *
+ * @param string value of WWW-Authenticate or Proxy-Authenticate header
+ * @return mixed associative array with challenge parameters, false if
+ * no challenge is present in header value
+ * @throws HTTP_Request2_Exception in case of unsupported challenge parameters
+ */
+ protected function parseDigestChallenge($headerValue)
+ {
+ $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
+ $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
+ if (!preg_match($challenge, $headerValue, $matches)) {
+ return false;
+ }
+
+ preg_match_all('!' . $authParam . '!', $matches[0], $params);
+ $paramsAry = array();
+ $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
+ 'algorithm', 'qop');
+ for ($i = 0; $i < count($params[0]); $i++) {
+ // section 3.2.1: Any unrecognized directive MUST be ignored.
+ if (in_array($params[1][$i], $knownParams)) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ }
+ // we only support qop=auth
+ if (!empty($paramsAry['qop']) &&
+ !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
+ ) {
+ throw new HTTP_Request2_Exception(
+ "Only 'auth' qop is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['qop']}'"
+ );
+ }
+ // we only support algorithm=MD5
+ if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
+ throw new HTTP_Request2_Exception(
+ "Only 'MD5' algorithm is currently supported in digest authentication, " .
+ "server requested '{$paramsAry['algorithm']}'"
+ );
+ }
+
+ return $paramsAry;
+ }
+
+ /**
+ * Parses [Proxy-]Authentication-Info header value and updates challenge
+ *
+ * @param array challenge to update
+ * @param string value of [Proxy-]Authentication-Info header
+ * @todo validate server rspauth response
+ */
+ protected function updateChallenge(&$challenge, $headerValue)
+ {
+ $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+ self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
+ $paramsAry = array();
+
+ preg_match_all($authParam, $headerValue, $params);
+ for ($i = 0; $i < count($params[0]); $i++) {
+ if ('"' == substr($params[2][$i], 0, 1)) {
+ $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+ } else {
+ $paramsAry[$params[1][$i]] = $params[2][$i];
+ }
+ }
+ // for now, just update the nonce value
+ if (!empty($paramsAry['nextnonce'])) {
+ $challenge['nonce'] = $paramsAry['nextnonce'];
+ $challenge['nc'] = 1;
+ }
+ }
+
+ /**
+ * Creates a value for [Proxy-]Authorization header when using digest authentication
+ *
+ * @param string user name
+ * @param string password
+ * @param string request URL
+ * @param array digest challenge parameters
+ * @return string value of [Proxy-]Authorization request header
+ * @link http://tools.ietf.org/html/rfc2617#section-3.2.2
+ */
+ protected function createDigestResponse($user, $password, $url, &$challenge)
+ {
+ if (false !== ($q = strpos($url, '?')) &&
+ $this->request->getConfig('digest_compat_ie')
+ ) {
+ $url = substr($url, 0, $q);
+ }
+
+ $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
+ $a2 = md5($this->request->getMethod() . ':' . $url);
+
+ if (empty($challenge['qop'])) {
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
+ } else {
+ $challenge['cnonce'] = 'Req2.' . rand();
+ if (empty($challenge['nc'])) {
+ $challenge['nc'] = 1;
+ }
+ $nc = sprintf('%08x', $challenge['nc']++);
+ $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
+ $challenge['cnonce'] . ':auth:' . $a2);
+ }
+ return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
+ 'realm="' . $challenge['realm'] . '", ' .
+ 'nonce="' . $challenge['nonce'] . '", ' .
+ 'uri="' . $url . '", ' .
+ 'response="' . $digest . '"' .
+ (!empty($challenge['opaque'])?
+ ', opaque="' . $challenge['opaque'] . '"':
+ '') .
+ (!empty($challenge['qop'])?
+ ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
+ '');
+ }
+
+ /**
+ * Adds 'Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request host (needed for digest authentication)
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
+ {
+ if (!($auth = $this->request->getAuth())) {
+ return;
+ }
+ switch ($auth['scheme']) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['authorization'] =
+ 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->serverChallenge);
+ $fullUrl = ('/' == $requestUrl[0])?
+ $this->request->getUrl()->getScheme() . '://' .
+ $requestHost . $requestUrl:
+ $requestUrl;
+ foreach (array_keys(self::$challenges) as $key) {
+ if ($key == substr($fullUrl, 0, strlen($key))) {
+ $headers['authorization'] = $this->createDigestResponse(
+ $auth['user'], $auth['password'],
+ $requestUrl, self::$challenges[$key]
+ );
+ $this->serverChallenge =& self::$challenges[$key];
+ break;
+ }
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '{$auth['scheme']}'"
+ );
+ }
+ }
+
+ /**
+ * Adds 'Proxy-Authorization' header (if needed) to request headers array
+ *
+ * @param array request headers
+ * @param string request URL (needed for digest authentication)
+ * @throws HTTP_Request2_Exception
+ */
+ protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
+ {
+ if (!$this->request->getConfig('proxy_host') ||
+ !($user = $this->request->getConfig('proxy_user')) ||
+ (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
+ HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
+ ) {
+ return;
+ }
+
+ $password = $this->request->getConfig('proxy_password');
+ switch ($this->request->getConfig('proxy_auth_scheme')) {
+ case HTTP_Request2::AUTH_BASIC:
+ $headers['proxy-authorization'] =
+ 'Basic ' . base64_encode($user . ':' . $password);
+ break;
+
+ case HTTP_Request2::AUTH_DIGEST:
+ unset($this->proxyChallenge);
+ $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
+ ':' . $this->request->getConfig('proxy_port');
+ if (!empty(self::$challenges[$proxyUrl])) {
+ $headers['proxy-authorization'] = $this->createDigestResponse(
+ $user, $password,
+ $requestUrl, self::$challenges[$proxyUrl]
+ );
+ $this->proxyChallenge =& self::$challenges[$proxyUrl];
+ }
+ break;
+
+ default:
+ throw new HTTP_Request2_Exception(
+ "Unknown HTTP authentication scheme '" .
+ $this->request->getConfig('proxy_auth_scheme') . "'"
+ );
+ }
+ }
+
+
+ /**
+ * Creates the string with the Request-Line and request headers
+ *
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function prepareHeaders()
+ {
+ $headers = $this->request->getHeaders();
+ $url = $this->request->getUrl();
+ $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+ $host = $url->getHost();
+
+ $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
+ if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
+ $host .= ':' . (empty($port)? $defaultPort: $port);
+ }
+ // Do not overwrite explicitly set 'Host' header, see bug #16146
+ if (!isset($headers['host'])) {
+ $headers['host'] = $host;
+ }
+
+ if ($connect) {
+ $requestUrl = $host;
+
+ } else {
+ if (!$this->request->getConfig('proxy_host') ||
+ 0 == strcasecmp($url->getScheme(), 'https')
+ ) {
+ $requestUrl = '';
+ } else {
+ $requestUrl = $url->getScheme() . '://' . $host;
+ }
+ $path = $url->getPath();
+ $query = $url->getQuery();
+ $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
+ }
+
+ if ('1.1' == $this->request->getConfig('protocol_version') &&
+ extension_loaded('zlib') && !isset($headers['accept-encoding'])
+ ) {
+ $headers['accept-encoding'] = 'gzip, deflate';
+ }
+
+ $this->addAuthorizationHeader($headers, $host, $requestUrl);
+ $this->addProxyAuthorizationHeader($headers, $requestUrl);
+ $this->calculateRequestLength($headers);
+
+ $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
+ $this->request->getConfig('protocol_version') . "\r\n";
+ foreach ($headers as $name => $value) {
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $headersStr .= $canonicalName . ': ' . $value . "\r\n";
+ }
+ return $headersStr . "\r\n";
+ }
+
+ /**
+ * Sends the request body
+ *
+ * @throws HTTP_Request2_Exception
+ */
+ protected function writeBody()
+ {
+ if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+ 0 == $this->contentLength
+ ) {
+ return;
+ }
+
+ $position = 0;
+ $bufferSize = $this->request->getConfig('buffer_size');
+ while ($position < $this->contentLength) {
+ if (is_string($this->requestBody)) {
+ $str = substr($this->requestBody, $position, $bufferSize);
+ } elseif (is_resource($this->requestBody)) {
+ $str = fread($this->requestBody, $bufferSize);
+ } else {
+ $str = $this->requestBody->read($bufferSize);
+ }
+ if (false === @fwrite($this->socket, $str, strlen($str))) {
+ throw new HTTP_Request2_Exception('Error writing request');
+ }
+ // Provide the length of written string to the observer, request #7630
+ $this->request->setLastEvent('sentBodyPart', strlen($str));
+ $position += strlen($str);
+ }
+ }
+
+ /**
+ * Reads the remote server's response
+ *
+ * @return HTTP_Request2_Response
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readResponse()
+ {
+ $bufferSize = $this->request->getConfig('buffer_size');
+
+ do {
+ $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
+ do {
+ $headerLine = $this->readLine($bufferSize);
+ $response->parseHeaderLine($headerLine);
+ } while ('' != $headerLine);
+ } while (in_array($response->getStatus(), array(100, 101)));
+
+ $this->request->setLastEvent('receivedHeaders', $response);
+
+ // No body possible in such responses
+ if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
+ (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+ 200 <= $response->getStatus() && 300 > $response->getStatus()) ||
+ in_array($response->getStatus(), array(204, 304))
+ ) {
+ return $response;
+ }
+
+ $chunked = 'chunked' == $response->getHeader('transfer-encoding');
+ $length = $response->getHeader('content-length');
+ $hasBody = false;
+ if ($chunked || null === $length || 0 < intval($length)) {
+ // RFC 2616, section 4.4:
+ // 3. ... If a message is received with both a
+ // Transfer-Encoding header field and a Content-Length header field,
+ // the latter MUST be ignored.
+ $toRead = ($chunked || null === $length)? null: $length;
+ $this->chunkLength = 0;
+
+ while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
+ if ($chunked) {
+ $data = $this->readChunked($bufferSize);
+ } elseif (is_null($toRead)) {
+ $data = $this->fread($bufferSize);
+ } else {
+ $data = $this->fread(min($toRead, $bufferSize));
+ $toRead -= strlen($data);
+ }
+ if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
+ break;
+ }
+
+ $hasBody = true;
+ if ($this->request->getConfig('store_body')) {
+ $response->appendBody($data);
+ }
+ if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
+ $this->request->setLastEvent('receivedEncodedBodyPart', $data);
+ } else {
+ $this->request->setLastEvent('receivedBodyPart', $data);
+ }
+ }
+ }
+
+ if ($hasBody) {
+ $this->request->setLastEvent('receivedBody', $response);
+ }
+ return $response;
+ }
+
+ /**
+ * Reads until either the end of the socket or a newline, whichever comes first
+ *
+ * Strips the trailing newline from the returned data, handles global
+ * request timeout. Method idea borrowed from Net_Socket PEAR package.
+ *
+ * @param int buffer size to use for reading
+ * @return Available data up to the newline (not including newline)
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function readLine($bufferSize)
+ {
+ $line = '';
+ while (!feof($this->socket)) {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $line .= @fgets($this->socket, $bufferSize);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ if (substr($line, -1) == "\n") {
+ return rtrim($line, "\r\n");
+ }
+ }
+ return $line;
+ }
+
+ /**
+ * Wrapper around fread(), handles global request timeout
+ *
+ * @param int Reads up to this number of bytes
+ * @return Data read from socket
+ * @throws HTTP_Request2_Exception In case of timeout
+ */
+ protected function fread($length)
+ {
+ if ($this->timeout) {
+ stream_set_timeout($this->socket, max($this->timeout - time(), 1));
+ }
+ $data = fread($this->socket, $length);
+ $info = stream_get_meta_data($this->socket);
+ if ($info['timed_out'] || $this->timeout && time() > $this->timeout) {
+ throw new HTTP_Request2_Exception(
+ 'Request timed out after ' .
+ $this->request->getConfig('timeout') . ' second(s)'
+ );
+ }
+ return $data;
+ }
+
+ /**
+ * Reads a part of response body encoded with chunked Transfer-Encoding
+ *
+ * @param int buffer size to use for reading
+ * @return string
+ * @throws HTTP_Request2_Exception
+ */
+ protected function readChunked($bufferSize)
+ {
+ // at start of the next chunk?
+ if (0 == $this->chunkLength) {
+ $line = $this->readLine($bufferSize);
+ if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
+ throw new HTTP_Request2_Exception(
+ "Cannot decode chunked response, invalid chunk length '{$line}'"
+ );
+ } else {
+ $this->chunkLength = hexdec($matches[1]);
+ // Chunk with zero length indicates the end
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize);
+ return '';
+ }
+ }
+ }
+ $data = $this->fread(min($this->chunkLength, $bufferSize));
+ $this->chunkLength -= strlen($data);
+ if (0 == $this->chunkLength) {
+ $this->readLine($bufferSize); // Trailing CRLF
+ }
+ return $data;
+ }
+}
+
?>
\ No newline at end of file
diff --git a/extlib/MIME/Type.php b/extlib/MIME/Type.php
index 8653362d3..c335f8d92 100644
--- a/extlib/MIME/Type.php
+++ b/extlib/MIME/Type.php
@@ -478,7 +478,7 @@ class MIME_Type
// Don't return an empty string
if (!$type || !strlen($type)) {
- return PEAR::raiseError("Sorry. Could not determine file type.");
+ return PEAR::raiseError("Sorry, couldn't determine file type.");
}
// Strip parameters if present & requested
@@ -510,7 +510,7 @@ class MIME_Type
$fileCmd = PEAR::getStaticProperty('MIME_Type', 'fileCmd');
if (!$cmd->which($fileCmd)) {
unset($cmd);
- return PEAR::raiseError("Cannot find file command \"{$fileCmd}\"");
+ return PEAR::raiseError("Can't find file command \"{$fileCmd}\"");
}
$cmd->pushCommand($fileCmd, "-bi " . escapeshellarg($file));
diff --git a/extlib/MIME/Type/Extension.php b/extlib/MIME/Type/Extension.php
index 2ffdee9a9..1987e2a10 100644
--- a/extlib/MIME/Type/Extension.php
+++ b/extlib/MIME/Type/Extension.php
@@ -265,7 +265,7 @@ class MIME_Type_Extension
}
if (!isset($this->extensionToType[$extension])) {
- return PEAR::raiseError("Sorry. Could not determine file type.");
+ return PEAR::raiseError("Sorry, couldn't determine file type.");
}
return $this->extensionToType[$extension];
@@ -288,7 +288,7 @@ class MIME_Type_Extension
$extension = array_search($type, $this->extensionToType);
if ($extension === false) {
- return PEAR::raiseError("Sorry. Could not determine extension.");
+ return PEAR::raiseError("Sorry, couldn't determine extension.");
}
return $extension;
}
diff --git a/extlib/Mail/mail.php b/extlib/Mail/mail.php
index 112ff940c..b13d69565 100644
--- a/extlib/Mail/mail.php
+++ b/extlib/Mail/mail.php
@@ -51,7 +51,7 @@ class Mail_mail extends Mail {
}
/* Because the mail() function may pass headers as command
- * line arguments, we cannot guarantee the use of the standard
+ * line arguments, we can't guarantee the use of the standard
* "\r\n" separator. Instead, we use the system's native line
* separator. */
if (defined('PHP_EOL')) {
diff --git a/extlib/Mail/sendmail.php b/extlib/Mail/sendmail.php
index aea52081a..cd248e61d 100644
--- a/extlib/Mail/sendmail.php
+++ b/extlib/Mail/sendmail.php
@@ -67,7 +67,7 @@ class Mail_sendmail extends Mail {
/*
* Because we need to pass message headers to the sendmail program on
- * the commandline, we cannot guarantee the use of the standard "\r\n"
+ * the commandline, we can't guarantee the use of the standard "\r\n"
* separator. Instead, we use the system's native line separator.
*/
if (defined('PHP_EOL')) {
diff --git a/extlib/Net/LDAP2/Entry.php b/extlib/Net/LDAP2/Entry.php
index 5531bfa13..66de96678 100644
--- a/extlib/Net/LDAP2/Entry.php
+++ b/extlib/Net/LDAP2/Entry.php
@@ -665,7 +665,7 @@ class Net_LDAP2_Entry extends PEAR
* To force replace mode instead of add, you can set $force to true.
*
* @param array $attr Attributes to replace
- * @param bool $force Force replacing mode in case we cannot read the attr value but are allowed to replace it
+ * @param bool $force Force replacing mode in case we can't read the attr value but are allowed to replace it
*
* @access public
* @return true|Net_LDAP2_Error
diff --git a/extlib/Net/LDAP2/Filter.php b/extlib/Net/LDAP2/Filter.php
index bd13d1ee4..0723edab2 100644
--- a/extlib/Net/LDAP2/Filter.php
+++ b/extlib/Net/LDAP2/Filter.php
@@ -439,7 +439,7 @@ class Net_LDAP2_Filter extends PEAR
*
* This method is only for compatibility to the perl interface.
* However, the original method was called "print" but due to PHP language restrictions,
- * we cannot have a print() method.
+ * we can't have a print() method.
*
* @param resource $FH (optional) A filehandle resource
*
diff --git a/extlib/System/Command.php b/extlib/System/Command.php
index d2001a975..f5c3ec6b9 100644
--- a/extlib/System/Command.php
+++ b/extlib/System/Command.php
@@ -376,7 +376,7 @@ class System_Command {
return $this->_initError;
}
- // if the command is empty or if the last element was a control operator, we cannot continue
+ // if the command is empty or if the last element was a control operator, we can't continue
if (is_null($this->previousElement) || $this->commandStatus == -1 || in_array($this->previousElement, $this->controlOperators)) {
return PEAR::raiseError(null, SYSTEM_COMMAND_INVALID_COMMAND, null, E_USER_WARNING, $this->systemCommand, 'System_Command_Error', true);
}
diff --git a/extlib/markdown.php b/extlib/markdown.php
index 1bb1b6ce4..8179b568b 100644
--- a/extlib/markdown.php
+++ b/extlib/markdown.php
@@ -1348,7 +1348,7 @@ class Markdown_Parser {
// {
// list(, $div_open, , $div_content, $div_close) = $matches;
//
-// # We cannot call Markdown(), because that resets the hash;
+// # We can't call Markdown(), because that resets the hash;
// # that initialization code should be pulled into its own sub, though.
// $div_content = $this->hashHTMLBlocks($div_content);
//
diff --git a/install.php b/install.php
index 78a4b8763..e7f7cf318 100644
--- a/install.php
+++ b/install.php
@@ -391,7 +391,7 @@ function showLibs()
libraries instead, as they tend to provide security updates faster, and may offer improved performance.
On Debian based distributions, such as Ubuntu, use a package manager (such as "aptitude", "apt-get", and "synaptic") to install the package listed.
On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as "yum", "apt-rpm", and "up2date") to install the package listed.
- On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP PEAR to install the library. Simply run "pear install <name>".
+ On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run "pear install <name>".
Absent Libraries
@@ -570,7 +570,7 @@ STR;
$res = writeConf($sitename, $server, $path, $fancy, $db);
if (!$res) {
- updateStatus("Cannot write config file.", true);
+ updateStatus("Can't write config file.", true);
showForm();
return;
}
@@ -616,7 +616,7 @@ function Pgsql_Db_installer($host, $database, $username, $password)
$res = runDbScript(INSTALLDIR.'/db/statusnet_pg.sql', $conn, 'pgsql');
if ($res === false) {
- updateStatus("Cannot run database script.", true);
+ updateStatus("Can't run database script.", true);
showForm();
return false;
}
@@ -627,7 +627,7 @@ function Pgsql_Db_installer($host, $database, $username, $password)
updateStatus(sprintf("Adding %s data to database...", $name));
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn, 'pgsql');
if ($res === false) {
- updateStatus(sprintf("Cannot run %d script.", $name), true);
+ updateStatus(sprintf("Can't run %d script.", $name), true);
showForm();
return false;
}
@@ -652,21 +652,21 @@ function Mysql_Db_installer($host, $database, $username, $password)
$conn = mysql_connect($host, $username, $password);
if (!$conn) {
- updateStatus("Cannot connect to server '$host' as '$username'.", true);
+ updateStatus("Can't connect to server '$host' as '$username'.", true);
showForm();
return false;
}
updateStatus("Changing to database...");
$res = mysql_select_db($database, $conn);
if (!$res) {
- updateStatus("Cannot change to database.", true);
+ updateStatus("Can't change to database.", true);
showForm();
return false;
}
updateStatus("Running database script...");
$res = runDbScript(INSTALLDIR.'/db/statusnet.sql', $conn);
if ($res === false) {
- updateStatus("Cannot run database script.", true);
+ updateStatus("Can't run database script.", true);
showForm();
return false;
}
@@ -677,7 +677,7 @@ function Mysql_Db_installer($host, $database, $username, $password)
updateStatus(sprintf("Adding %s data to database...", $name));
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
if ($res === false) {
- updateStatus(sprintf("Cannot run %d script.", $name), true);
+ updateStatus(sprintf("Can't run %d script.", $name), true);
showForm();
return false;
}
diff --git a/lib/attachmentlist.php b/lib/attachmentlist.php
index 60095dace..51ceca857 100644
--- a/lib/attachmentlist.php
+++ b/lib/attachmentlist.php
@@ -71,7 +71,7 @@ class AttachmentList extends Widget
/**
* show the list of notices
*
- * "Uses up" the stream by looping through it. So, probably cannot
+ * "Uses up" the stream by looping through it. So, probably can't
* be called twice on the same list.
*
* @return int count of notices listed.
diff --git a/lib/noticelist.php b/lib/noticelist.php
index 027db2b3e..bf12bb73c 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -75,7 +75,7 @@ class NoticeList extends Widget
/**
* show the list of notices
*
- * "Uses up" the stream by looping through it. So, probably cannot
+ * "Uses up" the stream by looping through it. So, probably can't
* be called twice on the same list.
*
* @return int count of notices listed.
diff --git a/lib/profilelist.php b/lib/profilelist.php
index f3eb66658..bbb722701 100644
--- a/lib/profilelist.php
+++ b/lib/profilelist.php
@@ -269,7 +269,7 @@ class ProfileListItem extends Widget
$usf = new UnsubscribeForm($this->out, $this->profile);
$usf->show();
} else {
- // Is it a local user? cannot remote sub from a list
+ // Is it a local user? can't remote sub from a list
// XXX: make that possible!
$other = User::staticGet('id', $this->profile->id);
if (!empty($other)) {
diff --git a/lib/serverexception.php b/lib/serverexception.php
index 6b2d55a0b..7dc9765ad 100644
--- a/lib/serverexception.php
+++ b/lib/serverexception.php
@@ -34,7 +34,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
/**
* Class for server exceptions
*
- * Subclass of PHP Exception for server errors. The user typically cannot fix these.
+ * Subclass of PHP Exception for server errors. The user typically can't fix these.
*
* @category Exception
* @package StatusNet
diff --git a/lib/settingsaction.php b/lib/settingsaction.php
index 4193ea521..c3669868d 100644
--- a/lib/settingsaction.php
+++ b/lib/settingsaction.php
@@ -72,7 +72,7 @@ class SettingsAction extends CurrentUserDesignAction
$this->clientError(_('Not logged in.'));
return;
} else if (!common_is_real_login()) {
- // Cookie theft means that automatic logins cannot
+ // Cookie theft means that automatic logins can't
// change important settings or see private info, and
// _all_ our settings are important
common_set_returnto($this->selfUrl());
diff --git a/lib/util.php b/lib/util.php
index dde3fb48f..a4865c46c 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -576,7 +576,7 @@ function common_linkify($url) {
} elseif (is_string($longurl_data)) {
$longurl = $longurl_data;
} else {
- throw new ServerException("Cannot linkify url '$url'");
+ throw new ServerException("Can't linkify url '$url'");
}
}
$attrs = array('href' => $canon, 'title' => $longurl, 'rel' => 'external');
diff --git a/lib/xmppqueuehandler.php b/lib/xmppqueuehandler.php
index 8acdcafe7..f28fc9088 100644
--- a/lib/xmppqueuehandler.php
+++ b/lib/xmppqueuehandler.php
@@ -43,7 +43,7 @@ class XmppQueueHandler extends QueueHandler
$this->conn = jabber_connect($this->_id.$this->transport());
if (empty($this->conn)) {
- $this->log(LOG_ERR, "Could not connect to server.");
+ $this->log(LOG_ERR, "Couldn't connect to server.");
return false;
}
diff --git a/locale/statusnet.po b/locale/statusnet.po
index 3ea314f34..4331b906e 100644
--- a/locale/statusnet.po
+++ b/locale/statusnet.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-11-08 22:12+0000\n"
+"POT-Creation-Date: 2009-11-08 11:53+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -16,4442 +16,7310 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: actions/all.php:63 actions/public.php:97 actions/replies.php:92
-#: actions/showfavorites.php:137 actions/tag.php:51
-msgid "No such page"
-msgstr ""
-
-#: actions/all.php:74 actions/allrss.php:68 actions/avatarbynickname.php:75
-#: actions/favoritesrss.php:74 actions/foaf.php:40 actions/foaf.php:58
-#: actions/remotesubscribe.php:145 actions/replies.php:73
-#: actions/repliesrss.php:38 actions/showfavorites.php:105
-#: actions/userbyid.php:74 actions/usergroups.php:91 actions/userrss.php:38
-#: actions/xrds.php:71 lib/command.php:163 lib/command.php:311
-#: lib/command.php:364 lib/command.php:411 lib/command.php:466
-#: lib/galleryaction.php:59 lib/mailbox.php:82 lib/profileaction.php:77
-#: lib/subs.php:34 lib/subs.php:112
-msgid "No such user."
-msgstr ""
-
-#: actions/all.php:84
+#: ../actions/noticesearchrss.php:64 actions/noticesearchrss.php:68
+#: actions/noticesearchrss.php:88 actions/noticesearchrss.php:89
#, php-format
-msgid "%s and friends, page %d"
+msgid " Search Stream for \"%s\""
msgstr ""
-#: actions/all.php:86 actions/all.php:167 actions/allrss.php:115
-#: actions/apitimelinefriends.php:114 lib/personalgroupnav.php:100
-#, php-format
-msgid "%s and friends"
+#: ../actions/finishopenidlogin.php:82 ../actions/register.php:191
+#: actions/finishopenidlogin.php:88 actions/register.php:205
+#: actions/finishopenidlogin.php:110 actions/finishopenidlogin.php:109
+msgid ""
+" except this private data: password, email address, IM address, phone number."
msgstr ""
-#: actions/all.php:99
-#, php-format
-msgid "Feed for friends of %s (RSS 1.0)"
+#: ../actions/showstream.php:400 ../lib/stream.php:109
+#: actions/showstream.php:418 lib/mailbox.php:164 lib/stream.php:76
+msgid " from "
msgstr ""
-#: actions/all.php:107
+#: ../actions/twitapistatuses.php:478 actions/twitapistatuses.php:412
+#: actions/twitapistatuses.php:347 actions/twitapistatuses.php:363
#, php-format
-msgid "Feed for friends of %s (RSS 2.0)"
+msgid "%1$s / Updates replying to %2$s"
msgstr ""
-#: actions/all.php:115
+#: ../actions/invite.php:168 actions/invite.php:176 actions/invite.php:211
+#: actions/invite.php:218 actions/invite.php:220 actions/invite.php:226
#, php-format
-msgid "Feed for friends of %s (Atom)"
+msgid "%1$s has invited you to join them on %2$s"
msgstr ""
-#: actions/all.php:127
+#: ../actions/invite.php:170 actions/invite.php:220 actions/invite.php:222
+#: actions/invite.php:228
#, php-format
msgid ""
-"This is the timeline for %s and friends but no one has posted anything yet."
+"%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. It's also great for meeting new people who "
+"share your interests.\n"
+"\n"
+"%1$s said:\n"
+"\n"
+"%4$s\n"
+"\n"
+"You can see %1$s's profile page on %2$s here:\n"
+"\n"
+"%5$s\n"
+"\n"
+"If you'd like to try the service, click on the link below to accept the "
+"invitation.\n"
+"\n"
+"%6$s\n"
+"\n"
+"If not, you can ignore this message. Thanks for your patience and your "
+"time.\n"
+"\n"
+"Sincerely, %2$s\n"
msgstr ""
-#: actions/all.php:132
+#: ../lib/mail.php:124 lib/mail.php:124 lib/mail.php:126 lib/mail.php:241
+#: lib/mail.php:236 lib/mail.php:235
#, php-format
-msgid ""
-"Try subscribing to more users, [join a group](%%action.groups%%) or post "
-"something yourself."
+msgid "%1$s is now listening to your notices on %2$s."
msgstr ""
-#: actions/all.php:134
+#: ../lib/mail.php:126
#, php-format
msgid ""
-"You can try to [nudge %s](../%s) from his profile or [post something to his "
-"or her attention](%%%%action.newnotice%%%%?status_textarea=%s)."
+"%1$s is now listening to your notices on %2$s.\n"
+"\n"
+"\t%3$s\n"
+"\n"
+"Faithfully yours,\n"
+"%4$s.\n"
msgstr ""
-#: actions/all.php:137 actions/replies.php:209 actions/showstream.php:202
+#: ../actions/twitapistatuses.php:482 actions/twitapistatuses.php:415
+#: actions/twitapistatuses.php:350 actions/twitapistatuses.php:367
+#: actions/twitapistatuses.php:328 actions/apitimelinementions.php:126
#, php-format
-msgid ""
-"Why not [register an account](%%%%action.register%%%%) and then nudge %s or "
-"post a notice to his or her attention."
+msgid "%1$s updates that reply to updates from %2$s / %3$s."
msgstr ""
-#: actions/all.php:165
-msgid "You and friends"
+#: ../actions/shownotice.php:45 actions/shownotice.php:45
+#: actions/shownotice.php:161 actions/shownotice.php:174 actions/oembed.php:86
+#: actions/shownotice.php:180
+#, php-format
+msgid "%1$s's status on %2$s"
msgstr ""
-#: actions/allrss.php:119 actions/apitimelinefriends.php:121
+#: ../actions/invite.php:84 ../actions/invite.php:92 actions/invite.php:91
+#: actions/invite.php:99 actions/invite.php:123 actions/invite.php:131
+#: actions/invite.php:125 actions/invite.php:133 actions/invite.php:139
#, php-format
-msgid "Updates from %1$s and friends on %2$s!"
+msgid "%s (%s)"
msgstr ""
-#: actions/apiaccountratelimitstatus.php:70 actions/apidirectmessage.php:156
-#: actions/apifavoritecreate.php:99 actions/apifavoritedestroy.php:100
-#: actions/apifriendshipscreate.php:100 actions/apifriendshipsdestroy.php:100
-#: actions/apifriendshipsshow.php:129 actions/apigroupcreate.php:184
-#: actions/apigroupismember.php:114 actions/apigroupjoin.php:155
-#: actions/apigroupleave.php:141 actions/apigrouplistall.php:120
-#: actions/apigrouplist.php:132 actions/apigroupmembership.php:101
-#: actions/apigroupshow.php:105 actions/apihelptest.php:88
-#: actions/apistatusesdestroy.php:102 actions/apistatusesshow.php:108
-#: actions/apistatusnetconfig.php:133 actions/apistatusnetversion.php:93
-#: actions/apisubscriptions.php:111 actions/apitimelinefavorites.php:144
-#: actions/apitimelinefriends.php:154 actions/apitimelinegroup.php:141
-#: actions/apitimelinementions.php:149 actions/apitimelinepublic.php:130
-#: actions/apitimelinetag.php:139 actions/apitimelineuser.php:163
-#: actions/apiusershow.php:101
-msgid "API method not found!"
+#: ../actions/publicrss.php:62 actions/publicrss.php:48
+#: actions/publicrss.php:90 actions/publicrss.php:89
+#, php-format
+msgid "%s Public Stream"
msgstr ""
-#: actions/apiaccountupdateprofileimage.php:84 actions/apiblockcreate.php:89
-#: actions/apiblockdestroy.php:88 actions/apidirectmessagenew.php:117
-#: actions/apifavoritecreate.php:90 actions/apifavoritedestroy.php:91
-#: actions/apifriendshipscreate.php:91 actions/apifriendshipsdestroy.php:91
-#: actions/apigroupcreate.php:104 actions/apigroupjoin.php:91
-#: actions/apigroupleave.php:91 actions/apistatusesupdate.php:109
-msgid "This method requires a POST."
+#: ../actions/all.php:47 ../actions/allrss.php:60
+#: ../actions/twitapistatuses.php:238 ../lib/stream.php:51 actions/all.php:47
+#: actions/allrss.php:60 actions/twitapistatuses.php:155 lib/personal.php:51
+#: actions/all.php:65 actions/allrss.php:103 actions/facebookhome.php:164
+#: actions/twitapistatuses.php:126 lib/personalgroupnav.php:99
+#: actions/all.php:68 actions/all.php:114 actions/allrss.php:106
+#: actions/facebookhome.php:163 actions/twitapistatuses.php:130
+#: actions/all.php:50 actions/all.php:127 actions/allrss.php:114
+#: actions/facebookhome.php:158 actions/twitapistatuses.php:89
+#: lib/personalgroupnav.php:100 actions/all.php:86 actions/all.php:167
+#: actions/allrss.php:115 actions/apitimelinefriends.php:114
+#, php-format
+msgid "%s and friends"
msgstr ""
-#: actions/apiaccountupdateprofileimage.php:97
-#: actions/apistatusesupdate.php:122 actions/avatarsettings.php:254
-#: actions/newnotice.php:94 lib/designsettings.php:283
+#: ../actions/twitapistatuses.php:49 actions/twitapistatuses.php:49
+#: actions/twitapistatuses.php:33 actions/twitapistatuses.php:32
+#: actions/twitapistatuses.php:37 actions/apitimelinepublic.php:106
+#: actions/publicrss.php:103
#, php-format
-msgid ""
-"The server was unable to handle that much POST data (%s bytes) due to its "
-"current configuration."
+msgid "%s public timeline"
msgstr ""
-#: actions/apiaccountupdateprofileimage.php:105 actions/apiblockcreate.php:97
-#: actions/apiblockdestroy.php:96 actions/apidirectmessagenew.php:75
-#: actions/apidirectmessage.php:77 actions/apigroupcreate.php:112
-#: actions/apigroupismember.php:90 actions/apigroupjoin.php:99
-#: actions/apigroupleave.php:99 actions/apigrouplist.php:90
-#: actions/apistatusesupdate.php:139 actions/apisubscriptions.php:87
-#: actions/apitimelinefavorites.php:70 actions/apitimelinefriends.php:79
-#: actions/apitimelinementions.php:79 actions/apitimelineuser.php:81
-msgid "No such user!"
+#: ../lib/mail.php:206 lib/mail.php:212 lib/mail.php:411 lib/mail.php:412
+#, php-format
+msgid "%s status"
msgstr ""
-#: actions/apiaccountupdateprofileimage.php:130 actions/apiusershow.php:108
-#: actions/avatarbynickname.php:80 actions/foaf.php:65 actions/replies.php:80
-#: actions/usergroups.php:98 lib/galleryaction.php:66 lib/profileaction.php:84
-msgid "User has no profile."
+#: ../actions/twitapistatuses.php:338 actions/twitapistatuses.php:265
+#: actions/twitapistatuses.php:199 actions/twitapistatuses.php:209
+#: actions/twitapigroups.php:69 actions/twitapistatuses.php:154
+#: actions/apitimelinegroup.php:102 actions/apitimelineuser.php:117
+#: actions/grouprss.php:131 actions/userrss.php:90
+#, php-format
+msgid "%s timeline"
msgstr ""
-#: actions/apiblockcreate.php:108
-msgid "Block user failed."
+#: ../actions/twitapistatuses.php:52 actions/twitapistatuses.php:52
+#: actions/twitapistatuses.php:36 actions/twitapistatuses.php:38
+#: actions/twitapistatuses.php:41 actions/apitimelinepublic.php:110
+#: actions/publicrss.php:105
+#, php-format
+msgid "%s updates from everyone!"
msgstr ""
-#: actions/apiblockdestroy.php:107
-msgid "Unblock user failed."
+#: ../actions/register.php:213 actions/register.php:497
+#: actions/register.php:545 actions/register.php:555 actions/register.php:561
+msgid ""
+"(You should receive a message by email momentarily, with instructions on how "
+"to confirm your email address.)"
msgstr ""
-#: actions/apidirectmessagenew.php:126
-msgid "No message text!"
+#: ../lib/util.php:257 lib/util.php:273 lib/action.php:605 lib/action.php:702
+#: lib/action.php:752 lib/action.php:767
+#, php-format
+msgid ""
+"**%%site.name%%** is a microblogging service brought to you by [%%site."
+"broughtby%%](%%site.broughtbyurl%%). "
msgstr ""
-#: actions/apidirectmessagenew.php:135 actions/newmessage.php:150
+#: ../lib/util.php:259 lib/util.php:275 lib/action.php:607 lib/action.php:704
+#: lib/action.php:754 lib/action.php:769
#, php-format
-msgid "That's too long. Max message size is %d chars."
+msgid "**%%site.name%%** is a microblogging service. "
msgstr ""
-#: actions/apidirectmessagenew.php:146
-msgid "Recipient user not found."
+#: ../actions/finishopenidlogin.php:73 ../actions/profilesettings.php:43
+#: actions/finishopenidlogin.php:79 actions/profilesettings.php:76
+#: actions/finishopenidlogin.php:101 actions/profilesettings.php:100
+#: lib/groupeditform.php:139 actions/finishopenidlogin.php:100
+#: lib/groupeditform.php:154 actions/profilesettings.php:108
+msgid "1-64 lowercase letters or numbers, no punctuation or spaces"
msgstr ""
-#: actions/apidirectmessagenew.php:150
-msgid "Can't send direct messages to users who aren't your friend."
+#: ../actions/register.php:152 actions/register.php:166
+#: actions/register.php:368 actions/register.php:414 actions/register.php:418
+#: actions/register.php:424
+msgid "1-64 lowercase letters or numbers, no punctuation or spaces. Required."
msgstr ""
-#: actions/apidirectmessage.php:89
-#, php-format
-msgid "Direct messages from %s"
+#: ../actions/password.php:42 actions/profilesettings.php:181
+#: actions/passwordsettings.php:102 actions/passwordsettings.php:108
+msgid "6 or more characters"
msgstr ""
-#: actions/apidirectmessage.php:93
-#, php-format
-msgid "All the direct messages sent from %s"
+#: ../actions/recoverpassword.php:180 actions/recoverpassword.php:186
+#: actions/recoverpassword.php:220 actions/recoverpassword.php:233
+#: actions/recoverpassword.php:236
+msgid "6 or more characters, and don't forget it!"
msgstr ""
-#: actions/apidirectmessage.php:101
-#, php-format
-msgid "Direct messages to %s"
+#: ../actions/register.php:154 actions/register.php:168
+#: actions/register.php:373 actions/register.php:419 actions/register.php:423
+#: actions/register.php:429
+msgid "6 or more characters. Required."
msgstr ""
-#: actions/apidirectmessage.php:105
+#: ../actions/imsettings.php:197 actions/imsettings.php:205
+#: actions/imsettings.php:321 actions/imsettings.php:327
#, php-format
-msgid "All the direct messages sent to %s"
+msgid ""
+"A confirmation code was sent to the IM address you added. You must approve %"
+"s for sending messages to you."
msgstr ""
-#: actions/apifavoritecreate.php:108 actions/apifavoritedestroy.php:109
-#: actions/apistatusesdestroy.php:113
-msgid "No status found with that ID."
+#: ../actions/emailsettings.php:213 actions/emailsettings.php:231
+#: actions/emailsettings.php:350 actions/emailsettings.php:358
+msgid ""
+"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."
msgstr ""
-#: actions/apifavoritecreate.php:119
-msgid "This status is already a favorite!"
+#: ../actions/smssettings.php:216 actions/smssettings.php:224
+msgid ""
+"A confirmation code was sent to the phone number you added. Check your inbox "
+"(and spam box!) for the code and instructions on how to use it."
+msgstr ""
+
+#: ../actions/twitapiaccount.php:49 ../actions/twitapihelp.php:45
+#: ../actions/twitapistatuses.php:88 ../actions/twitapistatuses.php:259
+#: ../actions/twitapistatuses.php:370 ../actions/twitapistatuses.php:532
+#: ../actions/twitapiusers.php:122 actions/twitapiaccount.php:49
+#: actions/twitapidirect_messages.php:104 actions/twitapifavorites.php:111
+#: actions/twitapifavorites.php:120 actions/twitapifriendships.php:156
+#: actions/twitapihelp.php:46 actions/twitapistatuses.php:93
+#: actions/twitapistatuses.php:176 actions/twitapistatuses.php:288
+#: actions/twitapistatuses.php:298 actions/twitapistatuses.php:454
+#: actions/twitapistatuses.php:463 actions/twitapistatuses.php:504
+#: actions/twitapiusers.php:55 actions/twitapiaccount.php:37
+#: actions/twitapidirect_messages.php:111 actions/twitapifavorites.php:85
+#: actions/twitapifavorites.php:102 actions/twitapifriendships.php:121
+#: actions/twitapihelp.php:44 actions/twitapistatusnet.php:82
+#: actions/twitapistatusnet.php:151 actions/twitapistatuses.php:79
+#: actions/twitapistatuses.php:147 actions/twitapistatuses.php:228
+#: actions/twitapistatuses.php:239 actions/twitapistatuses.php:392
+#: actions/twitapistatuses.php:402 actions/twitapistatuses.php:429
+#: actions/twitapiusers.php:32 actions/twitapidirect_messages.php:120
+#: actions/twitapifavorites.php:91 actions/twitapifavorites.php:108
+#: actions/twitapistatuses.php:82 actions/twitapistatuses.php:159
+#: actions/twitapistatuses.php:246 actions/twitapistatuses.php:257
+#: actions/twitapistatuses.php:416 actions/twitapistatuses.php:426
+#: actions/twitapistatuses.php:453 actions/twitapidirect_messages.php:113
+#: actions/twitapifavorites.php:92 actions/twitapifavorites.php:109
+#: actions/twitapifavorites.php:160 actions/twitapifriendships.php:128
+#: actions/twitapifriendships.php:168 actions/twitapigroups.php:110
+#: actions/twitapistatuses.php:68 actions/twitapistatuses.php:134
+#: actions/twitapistatuses.php:201 actions/twitapistatuses.php:211
+#: actions/twitapistatuses.php:357 actions/twitapistatuses.php:372
+#: actions/twitapistatuses.php:409 actions/twitapitags.php:110
+#: actions/twitapiusers.php:34 actions/apiaccountratelimitstatus.php:70
+#: actions/apidirectmessage.php:156 actions/apifavoritecreate.php:99
+#: actions/apifavoritedestroy.php:100 actions/apifriendshipscreate.php:100
+#: actions/apifriendshipsdestroy.php:100 actions/apifriendshipsshow.php:129
+#: actions/apigroupcreate.php:184 actions/apigroupismember.php:114
+#: actions/apigroupjoin.php:155 actions/apigroupleave.php:141
+#: actions/apigrouplist.php:132 actions/apigrouplistall.php:120
+#: actions/apigroupmembership.php:101 actions/apigroupshow.php:105
+#: actions/apihelptest.php:88 actions/apistatusesdestroy.php:102
+#: actions/apistatusesshow.php:108 actions/apistatusnetconfig.php:133
+#: actions/apistatusnetversion.php:93 actions/apisubscriptions.php:111
+#: actions/apitimelinefavorites.php:144 actions/apitimelinefriends.php:154
+#: actions/apitimelinegroup.php:141 actions/apitimelinementions.php:149
+#: actions/apitimelinepublic.php:130 actions/apitimelinetag.php:139
+#: actions/apitimelineuser.php:163 actions/apiusershow.php:101
+msgid "API method not found!"
msgstr ""
-#: actions/apifavoritecreate.php:130 actions/favor.php:84 lib/command.php:176
-msgid "Could not create favorite."
+#: ../actions/twitapiaccount.php:57 ../actions/twitapiaccount.php:113
+#: ../actions/twitapiaccount.php:119 ../actions/twitapiblocks.php:28
+#: ../actions/twitapiblocks.php:34 ../actions/twitapidirect_messages.php:43
+#: ../actions/twitapidirect_messages.php:49
+#: ../actions/twitapidirect_messages.php:56
+#: ../actions/twitapidirect_messages.php:62 ../actions/twitapifavorites.php:41
+#: ../actions/twitapifavorites.php:47 ../actions/twitapifavorites.php:53
+#: ../actions/twitapihelp.php:52 ../actions/twitapinotifications.php:29
+#: ../actions/twitapinotifications.php:35 ../actions/twitapistatuses.php:768
+#: actions/twitapiaccount.php:56 actions/twitapiaccount.php:109
+#: actions/twitapiaccount.php:114 actions/twitapiblocks.php:28
+#: actions/twitapiblocks.php:33 actions/twitapidirect_messages.php:170
+#: actions/twitapifavorites.php:168 actions/twitapihelp.php:53
+#: actions/twitapinotifications.php:29 actions/twitapinotifications.php:34
+#: actions/twitapistatuses.php:690 actions/twitapiaccount.php:45
+#: actions/twitapiaccount.php:97 actions/twitapiaccount.php:103
+#: actions/twitapidirect_messages.php:184 actions/twitapifavorites.php:143
+#: actions/twitapihelp.php:52 actions/twitapistatusnet.php:172
+#: actions/twitapinotifications.php:31 actions/twitapinotifications.php:37
+#: actions/twitapistatuses.php:562 actions/twitapiaccount.php:46
+#: actions/twitapiaccount.php:98 actions/twitapiaccount.php:104
+#: actions/twitapidirect_messages.php:193 actions/twitapifavorites.php:149
+#: actions/twitapistatuses.php:625 actions/twitapitrends.php:87
+#: actions/twitapiaccount.php:48 actions/twitapidirect_messages.php:189
+#: actions/twitapihelp.php:54 actions/twitapistatuses.php:582
+msgid "API method under construction."
msgstr ""
-#: actions/apifavoritedestroy.php:122
-msgid "That status is not a favorite!"
+#: ../lib/util.php:324 lib/util.php:340 lib/action.php:568 lib/action.php:661
+#: lib/action.php:706 lib/action.php:721
+msgid "About"
msgstr ""
-#: actions/apifavoritedestroy.php:134 actions/disfavor.php:87
-msgid "Could not delete favorite."
+#: ../actions/userauthorization.php:119 actions/userauthorization.php:126
+#: actions/userauthorization.php:143 actions/userauthorization.php:178
+#: actions/userauthorization.php:209
+msgid "Accept"
msgstr ""
-#: actions/apifriendshipscreate.php:109
-msgid "Could not follow user: User not found."
+#: ../actions/emailsettings.php:62 ../actions/imsettings.php:63
+#: ../actions/openidsettings.php:57 ../actions/smssettings.php:71
+#: actions/emailsettings.php:63 actions/imsettings.php:64
+#: actions/openidsettings.php:58 actions/smssettings.php:71
+#: actions/twittersettings.php:85 actions/emailsettings.php:120
+#: actions/imsettings.php:127 actions/openidsettings.php:111
+#: actions/smssettings.php:133 actions/twittersettings.php:163
+#: actions/twittersettings.php:166 actions/twittersettings.php:182
+#: actions/emailsettings.php:126 actions/imsettings.php:133
+#: actions/smssettings.php:145
+msgid "Add"
msgstr ""
-#: actions/apifriendshipscreate.php:118
-#, php-format
-msgid "Could not follow user: %s is already on your list."
+#: ../actions/openidsettings.php:43 actions/openidsettings.php:44
+#: actions/openidsettings.php:93
+msgid "Add OpenID"
msgstr ""
-#: actions/apifriendshipsdestroy.php:109
-msgid "Could not unfollow user: User not found."
+#: ../lib/settingsaction.php:97 lib/settingsaction.php:91
+#: lib/accountsettingsaction.php:117
+msgid "Add or remove OpenIDs"
msgstr ""
-#: actions/apifriendshipsdestroy.php:120
-msgid "You cannot unfollow yourself!"
+#: ../actions/emailsettings.php:38 ../actions/imsettings.php:39
+#: ../actions/smssettings.php:39 actions/emailsettings.php:39
+#: actions/imsettings.php:40 actions/smssettings.php:39
+#: actions/emailsettings.php:94 actions/imsettings.php:94
+#: actions/smssettings.php:92 actions/emailsettings.php:100
+#: actions/imsettings.php:100 actions/smssettings.php:104
+msgid "Address"
msgstr ""
-#: actions/apifriendshipsexists.php:94
-msgid "Two user ids or screen_names must be supplied."
+#: ../actions/invite.php:131 actions/invite.php:139 actions/invite.php:176
+#: actions/invite.php:181 actions/invite.php:183 actions/invite.php:189
+msgid "Addresses of friends to invite (one per line)"
msgstr ""
-#: actions/apifriendshipsshow.php:135
-msgid "Could not determine source user."
+#: ../actions/showstream.php:273 actions/showstream.php:288
+#: actions/showstream.php:422 lib/profileaction.php:126
+msgid "All subscriptions"
msgstr ""
-#: actions/apifriendshipsshow.php:143
-msgid "Could not find target user."
+#: ../actions/publicrss.php:64 actions/publicrss.php:50
+#: actions/publicrss.php:92 actions/publicrss.php:91
+#, php-format
+msgid "All updates for %s"
msgstr ""
-#: actions/apigroupcreate.php:136 actions/newgroup.php:204
-msgid "Could not create group."
+#: ../actions/noticesearchrss.php:66 actions/noticesearchrss.php:70
+#: actions/noticesearchrss.php:90 actions/noticesearchrss.php:91
+#, php-format
+msgid "All updates matching search term \"%s\""
msgstr ""
-#: actions/apigroupcreate.php:147 actions/editgroup.php:259
-#: actions/newgroup.php:210
-msgid "Could not create aliases."
+#: ../actions/finishopenidlogin.php:29 ../actions/login.php:31
+#: ../actions/openidlogin.php:29 ../actions/register.php:30
+#: actions/finishopenidlogin.php:29 actions/login.php:31
+#: actions/openidlogin.php:29 actions/register.php:30
+#: actions/finishopenidlogin.php:34 actions/login.php:77
+#: actions/openidlogin.php:30 actions/register.php:92 actions/register.php:131
+#: actions/login.php:79 actions/register.php:137
+msgid "Already logged in."
msgstr ""
-#: actions/apigroupcreate.php:166 actions/newgroup.php:224
-msgid "Could not set group membership."
+#: ../lib/subs.php:42 lib/subs.php:42 lib/subs.php:49 lib/subs.php:48
+msgid "Already subscribed!."
msgstr ""
-#: actions/apigroupcreate.php:212 actions/editgroup.php:182
-#: actions/newgroup.php:126 actions/profilesettings.php:208
-#: actions/register.php:205
-msgid "Nickname must have only lowercase letters and numbers and no spaces."
+#: ../actions/deletenotice.php:54 actions/deletenotice.php:55
+#: actions/deletenotice.php:113 actions/deletenotice.php:114
+#: actions/deletenotice.php:144
+msgid "Are you sure you want to delete this notice?"
msgstr ""
-#: actions/apigroupcreate.php:221 actions/editgroup.php:186
-#: actions/newgroup.php:130 actions/profilesettings.php:231
-#: actions/register.php:208
-msgid "Nickname already in use. Try another one."
+#: ../actions/userauthorization.php:77 actions/userauthorization.php:83
+#: actions/userauthorization.php:81 actions/userauthorization.php:76
+#: actions/userauthorization.php:105
+msgid "Authorize subscription"
msgstr ""
-#: actions/apigroupcreate.php:228 actions/editgroup.php:189
-#: actions/newgroup.php:133 actions/profilesettings.php:211
-#: actions/register.php:210
-msgid "Not a valid nickname."
+#: ../actions/login.php:104 ../actions/register.php:178
+#: actions/register.php:192 actions/login.php:218 actions/openidlogin.php:117
+#: actions/register.php:416 actions/register.php:463 actions/login.php:226
+#: actions/register.php:473 actions/login.php:253 actions/register.php:479
+msgid "Automatically login in the future; not for shared computers!"
msgstr ""
-#: actions/apigroupcreate.php:244 actions/editgroup.php:195
-#: actions/newgroup.php:139 actions/profilesettings.php:215
-#: actions/register.php:217
-msgid "Homepage is not a valid URL."
+#: ../actions/profilesettings.php:65 actions/profilesettings.php:98
+#: actions/profilesettings.php:144 actions/profilesettings.php:145
+#: actions/profilesettings.php:160
+msgid ""
+"Automatically subscribe to whoever subscribes to me (best for non-humans)"
msgstr ""
-#: actions/apigroupcreate.php:253 actions/editgroup.php:198
-#: actions/newgroup.php:142 actions/profilesettings.php:218
-#: actions/register.php:220
-msgid "Full name is too long (max 255 chars)."
+#: ../actions/avatar.php:32 ../lib/settingsaction.php:90
+#: actions/profilesettings.php:34 actions/avatarsettings.php:65
+#: actions/showgroup.php:209 lib/accountsettingsaction.php:107
+#: actions/avatarsettings.php:67 actions/showgroup.php:211
+#: actions/showgroup.php:216 actions/showgroup.php:221
+#: lib/accountsettingsaction.php:111
+msgid "Avatar"
msgstr ""
-#: actions/apigroupcreate.php:261
-#, php-format
-msgid "Description is too long (max %d chars)."
+#: ../actions/avatar.php:113 actions/profilesettings.php:350
+#: actions/avatarsettings.php:395 actions/avatarsettings.php:346
+#: actions/avatarsettings.php:360
+msgid "Avatar updated."
msgstr ""
-#: actions/apigroupcreate.php:272 actions/editgroup.php:204
-#: actions/newgroup.php:148 actions/profilesettings.php:225
-#: actions/register.php:227
-msgid "Location is too long (max 255 chars)."
+#: ../actions/imsettings.php:55 actions/imsettings.php:56
+#: actions/imsettings.php:108 actions/imsettings.php:114
+#, php-format
+msgid ""
+"Awaiting confirmation on this address. Check your Jabber/GTalk account for a "
+"message with further instructions. (Did you add %s to your buddy list?)"
msgstr ""
-#: actions/apigroupcreate.php:291 actions/editgroup.php:215
-#: actions/newgroup.php:159
-#, php-format
-msgid "Too many aliases! Maximum %d."
+#: ../actions/emailsettings.php:54 actions/emailsettings.php:55
+#: actions/emailsettings.php:107 actions/emailsettings.php:113
+msgid ""
+"Awaiting confirmation on this address. Check your inbox (and spam box!) for "
+"a message with further instructions."
msgstr ""
-#: actions/apigroupcreate.php:312 actions/editgroup.php:224
-#: actions/newgroup.php:168
-#, php-format
-msgid "Invalid alias: \"%s\""
+#: ../actions/smssettings.php:58 actions/smssettings.php:58
+#: actions/smssettings.php:111 actions/smssettings.php:123
+msgid "Awaiting confirmation on this phone number."
msgstr ""
-#: actions/apigroupcreate.php:321 actions/editgroup.php:228
-#: actions/newgroup.php:172
-#, php-format
-msgid "Alias \"%s\" already in use. Try another one."
+#: ../lib/util.php:1318 lib/util.php:1452
+msgid "Before »"
msgstr ""
-#: actions/apigroupcreate.php:334 actions/editgroup.php:234
-#: actions/newgroup.php:178
-msgid "Alias can't be the same as nickname."
+#: ../actions/profilesettings.php:49 ../actions/register.php:170
+#: actions/profilesettings.php:82 actions/register.php:184
+#: actions/profilesettings.php:112 actions/register.php:402
+#: actions/register.php:448 actions/profilesettings.php:127
+#: actions/register.php:459 actions/register.php:465
+msgid "Bio"
msgstr ""
-#: actions/apigroupjoin.php:110
-msgid "You are already a member of that group."
+#: ../actions/profilesettings.php:101 ../actions/register.php:82
+#: ../actions/updateprofile.php:103 actions/profilesettings.php:216
+#: actions/register.php:89 actions/updateprofile.php:104
+#: actions/profilesettings.php:205 actions/register.php:174
+#: actions/updateprofile.php:107 actions/updateprofile.php:109
+#: actions/profilesettings.php:206 actions/register.php:211
+msgid "Bio is too long (max 140 chars)."
msgstr ""
-#: actions/apigroupjoin.php:119 actions/joingroup.php:95 lib/command.php:221
-msgid "You have been blocked from that group by the admin."
+#: ../lib/deleteaction.php:41 lib/deleteaction.php:41 lib/deleteaction.php:69
+#: actions/deletenotice.php:71
+msgid "Can't delete this notice."
msgstr ""
-#: actions/apigroupjoin.php:138
+#: ../actions/updateprofile.php:119 actions/updateprofile.php:120
+#: actions/updateprofile.php:123 actions/updateprofile.php:125
#, php-format
-msgid "Could not join user %s to group %s."
+msgid "Can't read avatar URL '%s'"
msgstr ""
-#: actions/apigroupleave.php:114
-msgid "You are not a member of this group."
+#: ../actions/password.php:85 ../actions/recoverpassword.php:300
+#: actions/profilesettings.php:404 actions/recoverpassword.php:313
+#: actions/passwordsettings.php:169 actions/recoverpassword.php:347
+#: actions/passwordsettings.php:174 actions/recoverpassword.php:365
+#: actions/passwordsettings.php:180 actions/recoverpassword.php:368
+#: actions/passwordsettings.php:185
+msgid "Can't save new password."
msgstr ""
-#: actions/apigroupleave.php:124
-#, php-format
-msgid "Could not remove user %s to group %s."
+#: ../actions/emailsettings.php:57 ../actions/imsettings.php:58
+#: ../actions/smssettings.php:62 actions/emailsettings.php:58
+#: actions/imsettings.php:59 actions/smssettings.php:62
+#: actions/emailsettings.php:111 actions/imsettings.php:114
+#: actions/smssettings.php:114 actions/emailsettings.php:117
+#: actions/imsettings.php:120 actions/smssettings.php:126
+msgid "Cancel"
msgstr ""
-#: actions/apigrouplistall.php:90 actions/usergroups.php:62
-#, php-format
-msgid "%s groups"
+#: ../lib/openid.php:121 lib/openid.php:121 lib/openid.php:130
+#: lib/openid.php:133
+msgid "Cannot instantiate OpenID consumer object."
msgstr ""
-#: actions/apigrouplistall.php:94
-#, php-format
-msgid "groups on %s"
+#: ../actions/imsettings.php:163 actions/imsettings.php:171
+#: actions/imsettings.php:286 actions/imsettings.php:292
+msgid "Cannot normalize that Jabber ID"
msgstr ""
-#: actions/apigrouplist.php:95
-#, php-format
-msgid "%s's groups"
+#: ../actions/emailsettings.php:181 actions/emailsettings.php:199
+#: actions/emailsettings.php:311 actions/emailsettings.php:318
+#: actions/emailsettings.php:326
+msgid "Cannot normalize that email address"
msgstr ""
-#: actions/apigrouplist.php:103
-#, php-format
-msgid "Groups %s is a member of on %s."
+#: ../actions/password.php:45 actions/profilesettings.php:184
+#: actions/passwordsettings.php:110 actions/passwordsettings.php:116
+msgid "Change"
msgstr ""
-#: actions/apistatusesdestroy.php:107
-msgid "This method requires a POST or DELETE."
+#: ../lib/settingsaction.php:88 lib/settingsaction.php:88
+#: lib/accountsettingsaction.php:114 lib/accountsettingsaction.php:118
+msgid "Change email handling"
msgstr ""
-#: actions/apistatusesdestroy.php:130
-msgid "You may not delete another user's status."
-msgstr ""
-
-#: actions/apistatusesshow.php:138
-msgid "Status deleted."
+#: ../actions/password.php:32 actions/profilesettings.php:36
+#: actions/passwordsettings.php:58
+msgid "Change password"
msgstr ""
-#: actions/apistatusesshow.php:144
-msgid "No status with that ID found."
+#: ../lib/settingsaction.php:94 lib/accountsettingsaction.php:111
+#: lib/accountsettingsaction.php:115
+msgid "Change your password"
msgstr ""
-#: actions/apistatusesupdate.php:152 actions/newnotice.php:155
-#: scripts/maildaemon.php:71
-#, php-format
-msgid "That's too long. Max notice size is %d chars."
+#: ../lib/settingsaction.php:85 lib/settingsaction.php:85
+#: lib/accountsettingsaction.php:105 lib/accountsettingsaction.php:109
+msgid "Change your profile settings"
msgstr ""
-#: actions/apistatusesupdate.php:193
-msgid "Not found"
+#: ../actions/password.php:43 ../actions/recoverpassword.php:181
+#: ../actions/register.php:155 ../actions/smssettings.php:65
+#: actions/profilesettings.php:182 actions/recoverpassword.php:187
+#: actions/register.php:169 actions/smssettings.php:65
+#: actions/passwordsettings.php:105 actions/recoverpassword.php:221
+#: actions/register.php:376 actions/smssettings.php:122
+#: actions/recoverpassword.php:236 actions/register.php:422
+#: actions/passwordsettings.php:111 actions/recoverpassword.php:239
+#: actions/register.php:426 actions/smssettings.php:134
+#: actions/register.php:432
+msgid "Confirm"
msgstr ""
-#: actions/apistatusesupdate.php:216 actions/newnotice.php:178
-#, php-format
-msgid "Max notice size is %d chars, including attachment URL."
+#: ../actions/confirmaddress.php:90 actions/confirmaddress.php:90
+#: actions/confirmaddress.php:144
+msgid "Confirm Address"
msgstr ""
-#: actions/apisubscriptions.php:231 actions/apisubscriptions.php:261
-msgid "Unsupported format."
+#: ../actions/emailsettings.php:238 ../actions/imsettings.php:222
+#: ../actions/smssettings.php:245 actions/emailsettings.php:256
+#: actions/imsettings.php:230 actions/smssettings.php:253
+#: actions/emailsettings.php:379 actions/imsettings.php:361
+#: actions/smssettings.php:374 actions/emailsettings.php:386
+#: actions/emailsettings.php:394 actions/imsettings.php:367
+#: actions/smssettings.php:386
+msgid "Confirmation cancelled."
msgstr ""
-#: actions/apitimelinefavorites.php:107
-#, php-format
-msgid "%s / Favorites from %s"
+#: ../actions/smssettings.php:63 actions/smssettings.php:63
+#: actions/smssettings.php:118 actions/smssettings.php:130
+msgid "Confirmation code"
msgstr ""
-#: actions/apitimelinefavorites.php:119
-#, php-format
-msgid "%s updates favorited by %s / %s."
+#: ../actions/confirmaddress.php:38 actions/confirmaddress.php:38
+#: actions/confirmaddress.php:80
+msgid "Confirmation code not found."
msgstr ""
-#: actions/apitimelinegroup.php:102 actions/apitimelineuser.php:117
-#: actions/grouprss.php:131 actions/userrss.php:90
+#: ../actions/register.php:202 actions/register.php:473
+#: actions/register.php:521 actions/register.php:531 actions/register.php:537
#, php-format
-msgid "%s timeline"
+msgid ""
+"Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may "
+"want to...\n"
+"\n"
+"* Go to [your profile](%s) and post your first message.\n"
+"* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send "
+"notices through instant messages.\n"
+"* [Search for people](%%%%action.peoplesearch%%%%) that you may know or that "
+"share your interests. \n"
+"* Update your [profile settings](%%%%action.profilesettings%%%%) to tell "
+"others more about you. \n"
+"* Read over the [online docs](%%%%doc.help%%%%) for features you may have "
+"missed. \n"
+"\n"
+"Thanks for signing up and we hope you enjoy using this service."
msgstr ""
-#: actions/apitimelinegroup.php:110 actions/apitimelineuser.php:125
-#: actions/userrss.php:92
-#, php-format
-msgid "Updates from %1$s on %2$s!"
+#: ../actions/finishopenidlogin.php:91 actions/finishopenidlogin.php:97
+#: actions/finishopenidlogin.php:119 lib/action.php:330 lib/action.php:403
+#: lib/action.php:406 actions/finishopenidlogin.php:118 lib/action.php:422
+#: lib/action.php:425 lib/action.php:435
+msgid "Connect"
msgstr ""
-#: actions/apitimelinementions.php:116
-#, php-format
-msgid "%1$s / Updates mentioning %2$s"
+#: ../actions/finishopenidlogin.php:86 actions/finishopenidlogin.php:92
+#: actions/finishopenidlogin.php:114 actions/finishopenidlogin.php:113
+msgid "Connect existing account"
msgstr ""
-#: actions/apitimelinementions.php:126
-#, php-format
-msgid "%1$s updates that reply to updates from %2$s / %3$s."
+#: ../lib/util.php:332 lib/util.php:348 lib/action.php:576 lib/action.php:669
+#: lib/action.php:719 lib/action.php:734
+msgid "Contact"
msgstr ""
-#: actions/apitimelinepublic.php:106 actions/publicrss.php:103
+#: ../lib/openid.php:178 lib/openid.php:178 lib/openid.php:187
+#: lib/openid.php:190
#, php-format
-msgid "%s public timeline"
+msgid "Could not create OpenID form: %s"
msgstr ""
-#: actions/apitimelinepublic.php:110 actions/publicrss.php:105
+#: ../actions/twitapifriendships.php:60 ../actions/twitapifriendships.php:76
+#: actions/twitapifriendships.php:60 actions/twitapifriendships.php:76
+#: actions/twitapifriendships.php:48 actions/twitapifriendships.php:64
+#: actions/twitapifriendships.php:51 actions/twitapifriendships.php:68
+#: actions/apifriendshipscreate.php:118
#, php-format
-msgid "%s updates from everyone!"
+msgid "Could not follow user: %s is already on your list."
msgstr ""
-#: actions/apitimelinetag.php:101 actions/tag.php:66
-#, php-format
-msgid "Notices tagged with %s"
+#: ../actions/twitapifriendships.php:53 actions/twitapifriendships.php:53
+#: actions/twitapifriendships.php:41 actions/twitapifriendships.php:43
+#: actions/apifriendshipscreate.php:109
+msgid "Could not follow user: User not found."
msgstr ""
-#: actions/apitimelinetag.php:107 actions/tagrss.php:64
+#: ../lib/openid.php:160 lib/openid.php:160 lib/openid.php:169
+#: lib/openid.php:172
#, php-format
-msgid "Updates tagged with %1$s on %2$s!"
+msgid "Could not redirect to server: %s"
msgstr ""
-#: actions/apiusershow.php:96
-msgid "Not found."
+#: ../actions/updateprofile.php:162 actions/updateprofile.php:163
+#: actions/updateprofile.php:166 actions/updateprofile.php:176
+msgid "Could not save avatar info"
msgstr ""
-#: actions/attachment.php:73
-msgid "No such attachment."
+#: ../actions/updateprofile.php:155 actions/updateprofile.php:156
+#: actions/updateprofile.php:159 actions/updateprofile.php:163
+msgid "Could not save new profile info"
msgstr ""
-#: actions/avatarbynickname.php:59 actions/leavegroup.php:76
-msgid "No nickname."
+#: ../lib/subs.php:54 lib/subs.php:61 lib/subs.php:72 lib/subs.php:75
+msgid "Could not subscribe other to you."
msgstr ""
-#: actions/avatarbynickname.php:64
-msgid "No size."
+#: ../lib/subs.php:46 lib/subs.php:46 lib/subs.php:57 lib/subs.php:56
+msgid "Could not subscribe."
msgstr ""
-#: actions/avatarbynickname.php:69
-msgid "Invalid size."
+#: ../actions/recoverpassword.php:102 actions/recoverpassword.php:105
+#: actions/recoverpassword.php:111
+msgid "Could not update user with confirmed email address."
msgstr ""
-#: actions/avatarsettings.php:67 actions/showgroup.php:221
-#: lib/accountsettingsaction.php:111
-msgid "Avatar"
+#: ../actions/finishremotesubscribe.php:99
+#: actions/finishremotesubscribe.php:101 actions/finishremotesubscribe.php:114
+msgid "Couldn't convert request tokens to access tokens."
msgstr ""
-#: actions/avatarsettings.php:78
-#, php-format
-msgid "You can upload your personal avatar. The maximum file size is %s."
+#: ../actions/confirmaddress.php:84 ../actions/emailsettings.php:234
+#: ../actions/imsettings.php:218 ../actions/smssettings.php:241
+#: actions/confirmaddress.php:84 actions/emailsettings.php:252
+#: actions/imsettings.php:226 actions/smssettings.php:249
+#: actions/confirmaddress.php:126 actions/emailsettings.php:375
+#: actions/imsettings.php:357 actions/smssettings.php:370
+#: actions/emailsettings.php:382 actions/emailsettings.php:390
+#: actions/imsettings.php:363 actions/smssettings.php:382
+msgid "Couldn't delete email confirmation."
msgstr ""
-#: actions/avatarsettings.php:106 actions/avatarsettings.php:182
-#: actions/grouplogo.php:178 actions/remotesubscribe.php:191
-#: actions/userauthorization.php:72 actions/userrss.php:103
-msgid "User without matching profile"
+#: ../lib/subs.php:103 lib/subs.php:116 lib/subs.php:134 lib/subs.php:136
+msgid "Couldn't delete subscription."
msgstr ""
-#: actions/avatarsettings.php:119 actions/avatarsettings.php:194
-#: actions/grouplogo.php:251
-msgid "Avatar settings"
+#: ../actions/twitapistatuses.php:93 actions/twitapistatuses.php:98
+#: actions/twitapistatuses.php:84 actions/twitapistatuses.php:87
+msgid "Couldn't find any statuses."
msgstr ""
-#: actions/avatarsettings.php:126 actions/avatarsettings.php:202
-#: actions/grouplogo.php:199 actions/grouplogo.php:259
-msgid "Original"
+#: ../actions/remotesubscribe.php:127 actions/remotesubscribe.php:136
+#: actions/remotesubscribe.php:178
+msgid "Couldn't get a request token."
msgstr ""
-#: actions/avatarsettings.php:141 actions/avatarsettings.php:214
-#: actions/grouplogo.php:210 actions/grouplogo.php:271
-msgid "Preview"
+#: ../actions/emailsettings.php:205 ../actions/imsettings.php:187
+#: ../actions/smssettings.php:206 actions/emailsettings.php:223
+#: actions/imsettings.php:195 actions/smssettings.php:214
+#: actions/emailsettings.php:337 actions/imsettings.php:311
+#: actions/smssettings.php:325 actions/emailsettings.php:344
+#: actions/emailsettings.php:352 actions/imsettings.php:317
+#: actions/smssettings.php:337
+msgid "Couldn't insert confirmation code."
msgstr ""
-#: actions/avatarsettings.php:148 lib/noticelist.php:522
-msgid "Delete"
+#: ../actions/finishremotesubscribe.php:180
+#: actions/finishremotesubscribe.php:182 actions/finishremotesubscribe.php:218
+#: lib/oauthstore.php:487
+msgid "Couldn't insert new subscription."
msgstr ""
-#: actions/avatarsettings.php:165 actions/grouplogo.php:233
-msgid "Upload"
+#: ../actions/profilesettings.php:184 ../actions/twitapiaccount.php:96
+#: actions/profilesettings.php:299 actions/twitapiaccount.php:94
+#: actions/profilesettings.php:302 actions/twitapiaccount.php:81
+#: actions/twitapiaccount.php:82 actions/profilesettings.php:328
+msgid "Couldn't save profile."
msgstr ""
-#: actions/avatarsettings.php:228 actions/grouplogo.php:286
-msgid "Crop"
+#: ../actions/profilesettings.php:161 actions/profilesettings.php:276
+#: actions/profilesettings.php:279 actions/profilesettings.php:295
+msgid "Couldn't update user for autosubscribe."
msgstr ""
-#: actions/avatarsettings.php:265 actions/block.php:64 actions/disfavor.php:74
-#: actions/emailsettings.php:237 actions/favor.php:75
-#: actions/groupblock.php:66 actions/grouplogo.php:309
-#: actions/groupunblock.php:66 actions/imsettings.php:206
-#: actions/invite.php:56 actions/login.php:131 actions/makeadmin.php:66
-#: actions/newmessage.php:135 actions/newnotice.php:103 actions/nudge.php:80
-#: actions/othersettings.php:145 actions/passwordsettings.php:137
-#: actions/profilesettings.php:187 actions/recoverpassword.php:337
-#: actions/register.php:165 actions/remotesubscribe.php:77
-#: actions/smssettings.php:228 actions/subedit.php:38 actions/subscribe.php:46
-#: actions/tagother.php:166 actions/unblock.php:65 actions/unsubscribe.php:69
-#: actions/userauthorization.php:52 lib/designsettings.php:294
-msgid "There was a problem with your session token. Try again, please."
+#: ../actions/emailsettings.php:280 ../actions/emailsettings.php:294
+#: actions/emailsettings.php:298 actions/emailsettings.php:312
+#: actions/emailsettings.php:440 actions/emailsettings.php:462
+#: actions/emailsettings.php:447 actions/emailsettings.php:469
+#: actions/smssettings.php:515 actions/smssettings.php:539
+#: actions/smssettings.php:516 actions/smssettings.php:540
+#: actions/emailsettings.php:455 actions/emailsettings.php:477
+#: actions/smssettings.php:528 actions/smssettings.php:552
+msgid "Couldn't update user record."
msgstr ""
-#: actions/avatarsettings.php:277 actions/emailsettings.php:255
-#: actions/grouplogo.php:319 actions/imsettings.php:220
-#: actions/recoverpassword.php:44 actions/smssettings.php:248
-#: lib/designsettings.php:304
-msgid "Unexpected form submission."
+#: ../actions/confirmaddress.php:72 ../actions/emailsettings.php:156
+#: ../actions/emailsettings.php:259 ../actions/imsettings.php:138
+#: ../actions/imsettings.php:243 ../actions/profilesettings.php:141
+#: ../actions/smssettings.php:157 ../actions/smssettings.php:269
+#: actions/confirmaddress.php:72 actions/emailsettings.php:174
+#: actions/emailsettings.php:277 actions/imsettings.php:146
+#: actions/imsettings.php:251 actions/profilesettings.php:256
+#: actions/smssettings.php:165 actions/smssettings.php:277
+#: actions/confirmaddress.php:114 actions/emailsettings.php:280
+#: actions/emailsettings.php:411 actions/imsettings.php:252
+#: actions/imsettings.php:395 actions/othersettings.php:162
+#: actions/profilesettings.php:259 actions/smssettings.php:266
+#: actions/smssettings.php:408 actions/emailsettings.php:287
+#: actions/emailsettings.php:418 actions/othersettings.php:167
+#: actions/profilesettings.php:260 actions/emailsettings.php:295
+#: actions/emailsettings.php:426 actions/imsettings.php:258
+#: actions/imsettings.php:401 actions/othersettings.php:174
+#: actions/profilesettings.php:276 actions/smssettings.php:278
+#: actions/smssettings.php:420
+msgid "Couldn't update user."
msgstr ""
-#: actions/avatarsettings.php:322
-msgid "Pick a square area of the image to be your avatar"
+#: ../actions/finishopenidlogin.php:84 actions/finishopenidlogin.php:90
+#: actions/finishopenidlogin.php:112 actions/finishopenidlogin.php:111
+msgid "Create"
msgstr ""
-#: actions/avatarsettings.php:337 actions/grouplogo.php:377
-msgid "Lost our file data."
+#: ../actions/finishopenidlogin.php:70 actions/finishopenidlogin.php:76
+#: actions/finishopenidlogin.php:98 actions/finishopenidlogin.php:97
+msgid "Create a new user with this nickname."
msgstr ""
-#: actions/avatarsettings.php:360
-msgid "Avatar updated."
+#: ../actions/finishopenidlogin.php:68 actions/finishopenidlogin.php:74
+#: actions/finishopenidlogin.php:96 actions/finishopenidlogin.php:95
+msgid "Create new account"
msgstr ""
-#: actions/avatarsettings.php:363
-msgid "Failed updating avatar."
+#: ../actions/finishopenidlogin.php:191 actions/finishopenidlogin.php:197
+#: actions/finishopenidlogin.php:231 actions/finishopenidlogin.php:247
+msgid "Creating new account for OpenID that already has a user."
msgstr ""
-#: actions/avatarsettings.php:387
-msgid "Avatar deleted."
+#: ../actions/imsettings.php:45 actions/imsettings.php:46
+#: actions/imsettings.php:100 actions/imsettings.php:106
+msgid "Current confirmed Jabber/GTalk address."
msgstr ""
-#: actions/blockedfromgroup.php:73 actions/editgroup.php:84
-#: actions/groupdesignsettings.php:84 actions/grouplogo.php:86
-#: actions/groupmembers.php:76 actions/grouprss.php:91
-#: actions/joingroup.php:76 actions/showgroup.php:121
-msgid "No nickname"
+#: ../actions/smssettings.php:46 actions/smssettings.php:46
+#: actions/smssettings.php:100 actions/smssettings.php:112
+msgid "Current confirmed SMS-enabled phone number."
msgstr ""
-#: actions/blockedfromgroup.php:80 actions/editgroup.php:96
-#: actions/groupbyid.php:83 actions/groupdesignsettings.php:97
-#: actions/grouplogo.php:99 actions/groupmembers.php:83
-#: actions/grouprss.php:98 actions/joingroup.php:83 actions/showgroup.php:137
-msgid "No such group"
+#: ../actions/emailsettings.php:44 actions/emailsettings.php:45
+#: actions/emailsettings.php:99 actions/emailsettings.php:105
+msgid "Current confirmed email address."
msgstr ""
-#: actions/blockedfromgroup.php:90
+#: ../classes/Notice.php:72 classes/Notice.php:86 classes/Notice.php:91
+#: classes/Notice.php:114 classes/Notice.php:124 classes/Notice.php:164
#, php-format
-msgid "%s blocked profiles"
+msgid "DB error inserting hashtag: %s"
msgstr ""
-#: actions/blockedfromgroup.php:93
+#: ../lib/util.php:1061 lib/util.php:1110 classes/Notice.php:698
+#: classes/Notice.php:757 classes/Notice.php:1042 classes/Notice.php:1117
+#: classes/Notice.php:1120
#, php-format
-msgid "%s blocked profiles, page %d"
+msgid "DB error inserting reply: %s"
msgstr ""
-#: actions/blockedfromgroup.php:108
-msgid "A list of the users blocked from joining this group."
+#: ../actions/deletenotice.php:41 actions/deletenotice.php:41
+#: actions/deletenotice.php:79 actions/deletenotice.php:111
+#: actions/deletenotice.php:109 actions/deletenotice.php:141
+msgid "Delete notice"
msgstr ""
-#: actions/blockedfromgroup.php:281
-msgid "Unblock user from group"
+#: ../actions/profilesettings.php:51 ../actions/register.php:172
+#: actions/profilesettings.php:84 actions/register.php:186
+#: actions/profilesettings.php:114 actions/register.php:404
+#: actions/register.php:450
+msgid "Describe yourself and your interests in 140 chars"
msgstr ""
-#: actions/blockedfromgroup.php:313 lib/unblockform.php:150
-msgid "Unblock"
+#: ../actions/register.php:158 ../actions/register.php:161
+#: ../lib/settingsaction.php:87 actions/register.php:172
+#: actions/register.php:175 lib/settingsaction.php:87 actions/register.php:381
+#: actions/register.php:385 lib/accountsettingsaction.php:113
+#: actions/register.php:427 actions/register.php:431 actions/register.php:435
+#: lib/accountsettingsaction.php:117 actions/register.php:437
+#: actions/register.php:441
+msgid "Email"
msgstr ""
-#: actions/blockedfromgroup.php:313 lib/unblockform.php:120
-#: lib/unblockform.php:150
-msgid "Unblock this user"
+#: ../actions/emailsettings.php:59 actions/emailsettings.php:60
+#: actions/emailsettings.php:115 actions/emailsettings.php:121
+msgid "Email Address"
msgstr ""
-#: actions/block.php:59 actions/deletenotice.php:67 actions/disfavor.php:61
-#: actions/favor.php:62 actions/groupblock.php:61 actions/groupunblock.php:61
-#: actions/logout.php:69 actions/makeadmin.php:61 actions/newmessage.php:87
-#: actions/newnotice.php:89 actions/nudge.php:63 actions/subedit.php:31
-#: actions/subscribe.php:30 actions/unblock.php:60 actions/unsubscribe.php:52
-#: lib/settingsaction.php:72
-msgid "Not logged in."
+#: ../actions/emailsettings.php:32 actions/emailsettings.php:32
+#: actions/emailsettings.php:60
+msgid "Email Settings"
msgstr ""
-#: actions/block.php:69 actions/groupblock.php:71 actions/groupunblock.php:71
-#: actions/makeadmin.php:71 actions/subedit.php:46 actions/unblock.php:70
-msgid "No profile specified."
+#: ../actions/register.php:73 actions/register.php:80 actions/register.php:163
+#: actions/register.php:200 actions/register.php:206 actions/register.php:212
+msgid "Email address already exists."
msgstr ""
-#: actions/block.php:74 actions/groupblock.php:76 actions/groupunblock.php:76
-#: actions/makeadmin.php:76 actions/subedit.php:53 actions/tagother.php:46
-#: actions/unblock.php:75
-msgid "No profile with that ID."
+#: ../lib/mail.php:90 lib/mail.php:90 lib/mail.php:173 lib/mail.php:172
+msgid "Email address confirmation"
msgstr ""
-#: actions/block.php:111 actions/block.php:134
-msgid "Block user"
+#: ../actions/emailsettings.php:61 actions/emailsettings.php:62
+#: actions/emailsettings.php:117 actions/emailsettings.php:123
+msgid "Email address, like \"UserName@example.org\""
msgstr ""
-#: actions/block.php:136
-msgid ""
-"Are you sure you want to block this user? Afterwards, they will be "
-"unsubscribed from you, unable to subscribe to you in the future, and you "
-"will not be notified of any @-replies from them."
+#: ../actions/invite.php:129 actions/invite.php:137 actions/invite.php:174
+#: actions/invite.php:179 actions/invite.php:181 actions/invite.php:187
+msgid "Email addresses"
msgstr ""
-#: actions/block.php:149 actions/deletenotice.php:145
-#: actions/groupblock.php:176
-msgid "No"
+#: ../actions/recoverpassword.php:191 actions/recoverpassword.php:197
+#: actions/recoverpassword.php:231 actions/recoverpassword.php:249
+#: actions/recoverpassword.php:252
+msgid "Enter a nickname or email address."
msgstr ""
-#: actions/block.php:149
-msgid "Do not block this user from this group"
+#: ../actions/smssettings.php:64 actions/smssettings.php:64
+#: actions/smssettings.php:119 actions/smssettings.php:131
+msgid "Enter the code you received on your phone."
msgstr ""
-#: actions/block.php:150 actions/deletenotice.php:146
-#: actions/groupblock.php:177
-msgid "Yes"
+#: ../actions/userauthorization.php:137 actions/userauthorization.php:144
+#: actions/userauthorization.php:161 actions/userauthorization.php:200
+msgid "Error authorizing token"
msgstr ""
-#: actions/block.php:150
-msgid "Block this user from this group"
+#: ../actions/finishopenidlogin.php:253 actions/finishopenidlogin.php:259
+#: actions/finishopenidlogin.php:297 actions/finishopenidlogin.php:302
+#: actions/finishopenidlogin.php:325
+msgid "Error connecting user to OpenID."
msgstr ""
-#: actions/block.php:165
-msgid "You have already blocked this user."
+#: ../actions/finishaddopenid.php:78 actions/finishaddopenid.php:78
+#: actions/finishaddopenid.php:126
+msgid "Error connecting user."
msgstr ""
-#: actions/block.php:170
-msgid "Failed to save block information."
+#: ../actions/finishremotesubscribe.php:151
+#: actions/finishremotesubscribe.php:153 actions/finishremotesubscribe.php:166
+#: lib/oauthstore.php:291
+msgid "Error inserting avatar"
msgstr ""
-#: actions/bookmarklet.php:50
-msgid "Post to "
+#: ../actions/finishremotesubscribe.php:143
+#: actions/finishremotesubscribe.php:145 actions/finishremotesubscribe.php:158
+#: lib/oauthstore.php:283
+msgid "Error inserting new profile"
msgstr ""
-#: actions/confirmaddress.php:75
-msgid "No confirmation code."
+#: ../actions/finishremotesubscribe.php:167
+#: actions/finishremotesubscribe.php:169 actions/finishremotesubscribe.php:182
+#: lib/oauthstore.php:311
+msgid "Error inserting remote profile"
msgstr ""
-#: actions/confirmaddress.php:80
-msgid "Confirmation code not found."
+#: ../actions/recoverpassword.php:240 actions/recoverpassword.php:246
+#: actions/recoverpassword.php:280 actions/recoverpassword.php:298
+#: actions/recoverpassword.php:301
+msgid "Error saving address confirmation."
msgstr ""
-#: actions/confirmaddress.php:85
-msgid "That confirmation code is not for you!"
+#: ../actions/userauthorization.php:140 actions/userauthorization.php:147
+#: actions/userauthorization.php:164 actions/userauthorization.php:203
+msgid "Error saving remote profile"
msgstr ""
-#: actions/confirmaddress.php:90
-#, php-format
-msgid "Unrecognized address type %s"
+#: ../lib/openid.php:226 lib/openid.php:226 lib/openid.php:235
+#: lib/openid.php:238
+msgid "Error saving the profile."
msgstr ""
-#: actions/confirmaddress.php:94
-msgid "That address has already been confirmed."
+#: ../lib/openid.php:237 lib/openid.php:237 lib/openid.php:246
+#: lib/openid.php:249
+msgid "Error saving the user."
msgstr ""
-#: actions/confirmaddress.php:114 actions/emailsettings.php:295
-#: actions/emailsettings.php:426 actions/imsettings.php:258
-#: actions/imsettings.php:401 actions/othersettings.php:174
-#: actions/profilesettings.php:276 actions/smssettings.php:278
-#: actions/smssettings.php:420
-msgid "Couldn't update user."
+#: ../actions/password.php:80 actions/profilesettings.php:399
+#: actions/passwordsettings.php:164 actions/passwordsettings.php:169
+#: actions/passwordsettings.php:175 actions/passwordsettings.php:180
+msgid "Error saving user; invalid."
msgstr ""
-#: actions/confirmaddress.php:126 actions/emailsettings.php:390
-#: actions/imsettings.php:363 actions/smssettings.php:382
-msgid "Couldn't delete email confirmation."
+#: ../actions/login.php:47 ../actions/login.php:73
+#: ../actions/recoverpassword.php:307 ../actions/register.php:98
+#: actions/login.php:47 actions/login.php:73 actions/recoverpassword.php:320
+#: actions/register.php:108 actions/login.php:112 actions/login.php:138
+#: actions/recoverpassword.php:354 actions/register.php:198
+#: actions/login.php:120 actions/recoverpassword.php:372
+#: actions/register.php:235 actions/login.php:122
+#: actions/recoverpassword.php:375 actions/register.php:242
+#: actions/login.php:149 actions/register.php:248
+msgid "Error setting user."
msgstr ""
-#: actions/confirmaddress.php:144
-msgid "Confirm Address"
+#: ../actions/finishaddopenid.php:83 actions/finishaddopenid.php:83
+#: actions/finishaddopenid.php:131
+msgid "Error updating profile"
msgstr ""
-#: actions/confirmaddress.php:159
-#, php-format
-msgid "The address \"%s\" has been confirmed for your account."
+#: ../actions/finishremotesubscribe.php:161
+#: actions/finishremotesubscribe.php:163 actions/finishremotesubscribe.php:176
+#: actions/finishremotesubscribe.php:133 lib/oauthstore.php:306
+msgid "Error updating remote profile"
msgstr ""
-#: actions/conversation.php:99
-msgid "Conversation"
+#: ../actions/recoverpassword.php:80 actions/recoverpassword.php:80
+#: actions/recoverpassword.php:86
+msgid "Error with confirmation code."
msgstr ""
-#: actions/conversation.php:154 lib/mailbox.php:116 lib/noticelist.php:87
-#: lib/profileaction.php:206
-msgid "Notices"
+#: ../actions/finishopenidlogin.php:89 actions/finishopenidlogin.php:95
+#: actions/finishopenidlogin.php:117 actions/finishopenidlogin.php:116
+msgid "Existing nickname"
msgstr ""
-#: actions/deletenotice.php:52 actions/shownotice.php:92
-msgid "No such notice."
+#: ../lib/util.php:326 lib/util.php:342 lib/action.php:570 lib/action.php:663
+#: lib/action.php:708 lib/action.php:723
+msgid "FAQ"
msgstr ""
-#: actions/deletenotice.php:71
-msgid "Can't delete this notice."
+#: ../actions/avatar.php:115 actions/profilesettings.php:352
+#: actions/avatarsettings.php:397 actions/avatarsettings.php:349
+#: actions/avatarsettings.php:363
+msgid "Failed updating avatar."
msgstr ""
-#: actions/deletenotice.php:103
-msgid ""
-"You are about to permanently delete a notice. Once this is done, it cannot "
-"be undone."
+#: ../actions/all.php:61 ../actions/allrss.php:64 actions/all.php:61
+#: actions/allrss.php:64 actions/all.php:75 actions/allrss.php:107
+#: actions/allrss.php:110 actions/allrss.php:118
+#, php-format
+msgid "Feed for friends of %s"
msgstr ""
-#: actions/deletenotice.php:109 actions/deletenotice.php:141
-msgid "Delete notice"
+#: ../actions/replies.php:65 ../actions/repliesrss.php:80
+#: actions/replies.php:65 actions/repliesrss.php:66 actions/replies.php:134
+#: actions/repliesrss.php:71 actions/replies.php:136 actions/replies.php:135
+#, php-format
+msgid "Feed for replies to %s"
msgstr ""
-#: actions/deletenotice.php:144
-msgid "Are you sure you want to delete this notice?"
+#: ../actions/tag.php:55 actions/tag.php:55 actions/tag.php:61
+#: actions/tag.php:68
+#, php-format
+msgid "Feed for tag %s"
msgstr ""
-#: actions/deletenotice.php:145
-msgid "Do not delete this notice"
+#: ../lib/searchaction.php:105 lib/searchaction.php:105
+#: lib/searchgroupnav.php:83
+msgid "Find content of notices"
msgstr ""
-#: actions/deletenotice.php:146 lib/noticelist.php:522
-msgid "Delete this notice"
+#: ../lib/searchaction.php:101 lib/searchaction.php:101
+#: lib/searchgroupnav.php:81
+msgid "Find people on this site"
msgstr ""
-#: actions/deletenotice.php:157
-msgid "There was a problem with your session token. Try again, please."
+#: ../actions/login.php:122 actions/login.php:247 actions/login.php:255
+#: actions/login.php:282
+msgid ""
+"For security reasons, please re-enter your user name and password before "
+"changing your settings."
msgstr ""
-#: actions/disfavor.php:81
-msgid "This notice is not a favorite!"
+#: ../actions/profilesettings.php:44 ../actions/register.php:164
+#: actions/profilesettings.php:77 actions/register.php:178
+#: actions/profilesettings.php:103 actions/register.php:391
+#: actions/showgroup.php:235 actions/showstream.php:262
+#: actions/tagother.php:105 lib/groupeditform.php:142
+#: actions/showgroup.php:237 actions/showstream.php:255
+#: actions/tagother.php:104 actions/register.php:437 actions/showgroup.php:242
+#: actions/showstream.php:220 lib/groupeditform.php:157
+#: actions/profilesettings.php:111 actions/register.php:441
+#: actions/showgroup.php:247 actions/showstream.php:267
+#: actions/register.php:447 lib/userprofile.php:149
+msgid "Full name"
msgstr ""
-#: actions/disfavor.php:94
-msgid "Add to favorites"
+#: ../actions/profilesettings.php:98 ../actions/register.php:79
+#: ../actions/updateprofile.php:93 actions/profilesettings.php:213
+#: actions/register.php:86 actions/updateprofile.php:94
+#: actions/editgroup.php:195 actions/newgroup.php:146
+#: actions/profilesettings.php:202 actions/register.php:171
+#: actions/updateprofile.php:97 actions/updateprofile.php:99
+#: actions/editgroup.php:197 actions/newgroup.php:147
+#: actions/profilesettings.php:203 actions/register.php:208
+#: actions/apigroupcreate.php:253 actions/editgroup.php:198
+#: actions/newgroup.php:142 actions/profilesettings.php:218
+#: actions/register.php:214 actions/register.php:220
+msgid "Full name is too long (max 255 chars)."
msgstr ""
-#: actions/doc.php:69
-msgid "No such document."
+#: ../lib/util.php:322 lib/util.php:338 lib/action.php:344 lib/action.php:566
+#: lib/action.php:421 lib/action.php:659 lib/action.php:446 lib/action.php:704
+#: lib/action.php:456 lib/action.php:719
+msgid "Help"
msgstr ""
-#: actions/editgroup.php:56
-#, php-format
-msgid "Edit %s group"
+#: ../lib/util.php:298 lib/util.php:314 lib/action.php:322
+#: lib/facebookaction.php:200 lib/action.php:393 lib/facebookaction.php:213
+#: lib/action.php:417 lib/action.php:430
+msgid "Home"
msgstr ""
-#: actions/editgroup.php:68 actions/grouplogo.php:70 actions/newgroup.php:65
-msgid "You must be logged in to create a group."
+#: ../actions/profilesettings.php:46 ../actions/register.php:167
+#: actions/profilesettings.php:79 actions/register.php:181
+#: actions/profilesettings.php:107 actions/register.php:396
+#: lib/groupeditform.php:146 actions/register.php:442
+#: lib/groupeditform.php:161 actions/profilesettings.php:115
+#: actions/register.php:446 actions/register.php:452
+msgid "Homepage"
msgstr ""
-#: actions/editgroup.php:103 actions/editgroup.php:168
-#: actions/groupdesignsettings.php:104 actions/grouplogo.php:106
-msgid "You must be an admin to edit the group"
+#: ../actions/profilesettings.php:95 ../actions/register.php:76
+#: actions/profilesettings.php:210 actions/register.php:83
+#: actions/editgroup.php:192 actions/newgroup.php:143
+#: actions/profilesettings.php:199 actions/register.php:168
+#: actions/editgroup.php:194 actions/newgroup.php:144
+#: actions/profilesettings.php:200 actions/register.php:205
+#: actions/apigroupcreate.php:244 actions/editgroup.php:195
+#: actions/newgroup.php:139 actions/profilesettings.php:215
+#: actions/register.php:211 actions/register.php:217
+msgid "Homepage is not a valid URL."
msgstr ""
-#: actions/editgroup.php:154
-msgid "Use this form to edit the group."
+#: ../actions/emailsettings.php:91 actions/emailsettings.php:98
+#: actions/emailsettings.php:173 actions/emailsettings.php:178
+#: actions/emailsettings.php:185
+msgid "I want to post notices by email."
msgstr ""
-#: actions/editgroup.php:201 actions/newgroup.php:145
-#, php-format
-msgid "description is too long (max %d chars)."
+#: ../lib/settingsaction.php:102 lib/settingsaction.php:96
+#: lib/connectsettingsaction.php:104 lib/connectsettingsaction.php:110
+msgid "IM"
msgstr ""
-#: actions/editgroup.php:253
-msgid "Could not update group."
+#: ../actions/imsettings.php:60 actions/imsettings.php:61
+#: actions/imsettings.php:118 actions/imsettings.php:124
+msgid "IM Address"
msgstr ""
-#: actions/editgroup.php:269
-msgid "Options saved."
+#: ../actions/imsettings.php:33 actions/imsettings.php:33
+#: actions/imsettings.php:59
+msgid "IM Settings"
msgstr ""
-#: actions/emailsettings.php:60
-msgid "Email Settings"
+#: ../actions/finishopenidlogin.php:88 actions/finishopenidlogin.php:94
+#: actions/finishopenidlogin.php:116 actions/finishopenidlogin.php:115
+msgid ""
+"If you already have an account, login with your username and password to "
+"connect it to your OpenID."
msgstr ""
-#: actions/emailsettings.php:71
-#, php-format
-msgid "Manage how you get email from %%site.name%%."
+#: ../actions/openidsettings.php:45 actions/openidsettings.php:96
+msgid ""
+"If you want to add an OpenID to your account, enter it in the box below and "
+"click \"Add\"."
msgstr ""
-#: actions/emailsettings.php:100
-msgid "Address"
+#: ../actions/emailsettings.php:67 ../actions/smssettings.php:76
+#: actions/emailsettings.php:68 actions/smssettings.php:76
+#: actions/emailsettings.php:127 actions/smssettings.php:140
+#: actions/emailsettings.php:133 actions/smssettings.php:152
+msgid "Incoming email"
msgstr ""
-#: actions/emailsettings.php:105
-msgid "Current confirmed email address."
+#: ../actions/emailsettings.php:283 actions/emailsettings.php:301
+#: actions/emailsettings.php:443 actions/emailsettings.php:450
+#: actions/smssettings.php:518 actions/smssettings.php:519
+#: actions/emailsettings.php:458 actions/smssettings.php:531
+msgid "Incoming email address removed."
msgstr ""
-#: actions/emailsettings.php:107 actions/emailsettings.php:140
-#: actions/imsettings.php:108 actions/smssettings.php:115
-#: actions/smssettings.php:158
-msgid "Remove"
+#: ../actions/password.php:69 actions/profilesettings.php:388
+#: actions/passwordsettings.php:153 actions/passwordsettings.php:158
+#: actions/passwordsettings.php:164
+msgid "Incorrect old password"
+msgstr ""
+
+#: ../actions/login.php:67 actions/login.php:67 actions/facebookhome.php:131
+#: actions/login.php:132 actions/facebookhome.php:130 actions/login.php:114
+#: actions/facebookhome.php:129 actions/login.php:116 actions/login.php:143
+msgid "Incorrect username or password."
msgstr ""
-#: actions/emailsettings.php:113
+#: ../actions/recoverpassword.php:265 actions/recoverpassword.php:304
+#: actions/recoverpassword.php:322 actions/recoverpassword.php:325
msgid ""
-"Awaiting confirmation on this address. Check your inbox (and spam box!) for "
-"a message with further instructions."
+"Instructions for recovering your password have been sent to the email "
+"address registered to your account."
msgstr ""
-#: actions/emailsettings.php:117 actions/imsettings.php:120
-#: actions/smssettings.php:126
-msgid "Cancel"
+#: ../actions/updateprofile.php:114 actions/updateprofile.php:115
+#: actions/updateprofile.php:118 actions/updateprofile.php:120
+#, php-format
+msgid "Invalid avatar URL '%s'"
msgstr ""
-#: actions/emailsettings.php:121
-msgid "Email Address"
+#: ../actions/invite.php:55 actions/invite.php:62 actions/invite.php:70
+#: actions/invite.php:72
+#, php-format
+msgid "Invalid email address: %s"
msgstr ""
-#: actions/emailsettings.php:123
-msgid "Email address, like \"UserName@example.org\""
+#: ../actions/updateprofile.php:98 actions/updateprofile.php:99
+#: actions/updateprofile.php:102 actions/updateprofile.php:104
+#, php-format
+msgid "Invalid homepage '%s'"
msgstr ""
-#: actions/emailsettings.php:126 actions/imsettings.php:133
-#: actions/smssettings.php:145
-msgid "Add"
+#: ../actions/updateprofile.php:82 actions/updateprofile.php:83
+#: actions/updateprofile.php:86 actions/updateprofile.php:88
+#, php-format
+msgid "Invalid license URL '%s'"
msgstr ""
-#: actions/emailsettings.php:133 actions/smssettings.php:152
-msgid "Incoming email"
+#: ../actions/postnotice.php:61 actions/postnotice.php:62
+#: actions/postnotice.php:66 actions/postnotice.php:84
+msgid "Invalid notice content"
msgstr ""
-#: actions/emailsettings.php:138 actions/smssettings.php:157
-msgid "Send email to this address to post new notices."
+#: ../actions/postnotice.php:67 actions/postnotice.php:68
+#: actions/postnotice.php:72
+msgid "Invalid notice uri"
msgstr ""
-#: actions/emailsettings.php:145 actions/smssettings.php:162
-msgid "Make a new email address for posting to; cancels the old one."
+#: ../actions/postnotice.php:72 actions/postnotice.php:73
+#: actions/postnotice.php:77
+msgid "Invalid notice url"
msgstr ""
-#: actions/emailsettings.php:148 actions/smssettings.php:164
-msgid "New"
+#: ../actions/updateprofile.php:87 actions/updateprofile.php:88
+#: actions/updateprofile.php:91 actions/updateprofile.php:93
+#, php-format
+msgid "Invalid profile URL '%s'."
msgstr ""
-#: actions/emailsettings.php:153 actions/imsettings.php:139
-#: actions/smssettings.php:169
-msgid "Preferences"
+#: ../actions/remotesubscribe.php:96 actions/remotesubscribe.php:105
+#: actions/remotesubscribe.php:135 actions/remotesubscribe.php:159
+msgid "Invalid profile URL (bad format)"
msgstr ""
-#: actions/emailsettings.php:158
-msgid "Send me notices of new subscriptions through email."
+#: ../actions/finishremotesubscribe.php:77
+#: actions/finishremotesubscribe.php:79 actions/finishremotesubscribe.php:80
+msgid "Invalid profile URL returned by server."
msgstr ""
-#: actions/emailsettings.php:163
-msgid "Send me email when someone adds my notice as a favorite."
+#: ../actions/avatarbynickname.php:37 actions/avatarbynickname.php:37
+#: actions/avatarbynickname.php:69
+msgid "Invalid size."
msgstr ""
-#: actions/emailsettings.php:169
-msgid "Send me email when someone sends me a private message."
+#: ../actions/finishopenidlogin.php:235 ../actions/register.php:93
+#: ../actions/register.php:111 actions/finishopenidlogin.php:241
+#: actions/register.php:103 actions/register.php:121
+#: actions/finishopenidlogin.php:279 actions/register.php:193
+#: actions/register.php:211 actions/finishopenidlogin.php:284
+#: actions/finishopenidlogin.php:307 actions/register.php:230
+#: actions/register.php:251 actions/register.php:237 actions/register.php:258
+#: actions/register.php:243 actions/register.php:264
+msgid "Invalid username or password."
msgstr ""
-#: actions/emailsettings.php:174
-msgid "Send me email when someone sends me an \"@-reply\"."
+#: ../actions/invite.php:79 actions/invite.php:86 actions/invite.php:102
+#: actions/invite.php:104 actions/invite.php:110
+msgid "Invitation(s) sent"
msgstr ""
-#: actions/emailsettings.php:179
-msgid "Allow friends to nudge me and send me an email."
+#: ../actions/invite.php:97 actions/invite.php:104 actions/invite.php:136
+#: actions/invite.php:138 actions/invite.php:144
+msgid "Invitation(s) sent to the following people:"
msgstr ""
-#: actions/emailsettings.php:185
-msgid "I want to post notices by email."
+#: ../lib/util.php:306 lib/util.php:322 lib/facebookaction.php:207
+#: lib/subgroupnav.php:103 lib/facebookaction.php:220 lib/action.php:429
+#: lib/facebookaction.php:221 lib/subgroupnav.php:105 lib/action.php:439
+msgid "Invite"
msgstr ""
-#: actions/emailsettings.php:191
-msgid "Publish a MicroID for my email address."
+#: ../actions/invite.php:123 actions/invite.php:130 actions/invite.php:104
+#: actions/invite.php:106 actions/invite.php:112
+msgid "Invite new users"
msgstr ""
-#: actions/emailsettings.php:195 actions/imsettings.php:163
-#: actions/othersettings.php:126 actions/profilesettings.php:167
-#: actions/smssettings.php:181 actions/subscriptions.php:203
-#: actions/tagother.php:154 lib/designsettings.php:256
-#: lib/groupeditform.php:202
-msgid "Save"
+#: ../lib/util.php:261 lib/util.php:277 lib/action.php:609 lib/action.php:706
+#: lib/action.php:756 lib/action.php:771
+#, php-format
+msgid ""
+"It runs the [StatusNet](http://status.net/) microblogging software, version %"
+"s, available under the [GNU Affero General Public License](http://www.fsf."
+"org/licensing/licenses/agpl-3.0.html)."
msgstr ""
-#: actions/emailsettings.php:301 actions/imsettings.php:264
-#: actions/othersettings.php:180 actions/smssettings.php:284
-msgid "Preferences saved."
+#: ../actions/imsettings.php:173 actions/imsettings.php:181
+#: actions/imsettings.php:296 actions/imsettings.php:302
+msgid "Jabber ID already belongs to another user."
msgstr ""
-#: actions/emailsettings.php:319
-msgid "No email address."
+#: ../actions/imsettings.php:62 actions/imsettings.php:63
+#: actions/imsettings.php:120 actions/imsettings.php:126
+#, php-format
+msgid ""
+"Jabber or GTalk address, like \"UserName@example.org\". First, make sure to "
+"add %s to your buddy list in your IM client or on GTalk."
msgstr ""
-#: actions/emailsettings.php:326
-msgid "Cannot normalize that email address"
+#: ../actions/profilesettings.php:57 actions/profilesettings.php:90
+#: actions/profilesettings.php:128 actions/profilesettings.php:129
+#: actions/profilesettings.php:144
+msgid "Language"
msgstr ""
-#: actions/emailsettings.php:330
-msgid "Not a valid email address"
+#: ../actions/profilesettings.php:113 actions/profilesettings.php:228
+#: actions/profilesettings.php:217 actions/profilesettings.php:218
+#: actions/profilesettings.php:234
+msgid "Language is too long (max 50 chars)."
msgstr ""
-#: actions/emailsettings.php:333
-msgid "That is already your email address."
+#: ../actions/profilesettings.php:52 ../actions/register.php:173
+#: actions/profilesettings.php:85 actions/register.php:187
+#: actions/profilesettings.php:117 actions/register.php:408
+#: actions/showgroup.php:244 actions/showstream.php:271
+#: actions/tagother.php:113 lib/groupeditform.php:156 lib/grouplist.php:126
+#: lib/profilelist.php:125 actions/showgroup.php:246
+#: actions/showstream.php:264 actions/tagother.php:112 lib/profilelist.php:123
+#: actions/register.php:454 actions/showgroup.php:251
+#: actions/showstream.php:229 actions/userauthorization.php:128
+#: lib/groupeditform.php:171 lib/profilelist.php:185
+#: actions/profilesettings.php:132 actions/register.php:464
+#: actions/showgroup.php:256 actions/showstream.php:282
+#: actions/userauthorization.php:158 lib/groupeditform.php:177
+#: lib/profilelist.php:218 actions/register.php:470 lib/userprofile.php:164
+msgid "Location"
msgstr ""
-#: actions/emailsettings.php:336
-msgid "That email address already belongs to another user."
+#: ../actions/profilesettings.php:104 ../actions/register.php:85
+#: ../actions/updateprofile.php:108 actions/profilesettings.php:219
+#: actions/register.php:92 actions/updateprofile.php:109
+#: actions/editgroup.php:201 actions/newgroup.php:152
+#: actions/profilesettings.php:208 actions/register.php:177
+#: actions/updateprofile.php:112 actions/updateprofile.php:114
+#: actions/editgroup.php:203 actions/newgroup.php:153
+#: actions/profilesettings.php:209 actions/register.php:214
+#: actions/apigroupcreate.php:272 actions/editgroup.php:204
+#: actions/newgroup.php:148 actions/profilesettings.php:225
+#: actions/register.php:221 actions/register.php:227
+msgid "Location is too long (max 255 chars)."
msgstr ""
-#: actions/emailsettings.php:352 actions/imsettings.php:317
-#: actions/smssettings.php:337
-msgid "Couldn't insert confirmation code."
+#: ../actions/login.php:97 ../actions/login.php:106
+#: ../actions/openidlogin.php:68 ../lib/util.php:310 actions/login.php:97
+#: actions/login.php:106 actions/openidlogin.php:77 lib/util.php:326
+#: actions/facebooklogin.php:93 actions/login.php:186 actions/login.php:239
+#: actions/openidlogin.php:112 lib/action.php:335 lib/facebookaction.php:288
+#: lib/facebookaction.php:315 lib/logingroupnav.php:75 actions/login.php:169
+#: actions/login.php:222 actions/openidlogin.php:121 lib/action.php:412
+#: lib/facebookaction.php:293 lib/facebookaction.php:319 lib/action.php:443
+#: lib/facebookaction.php:295 lib/facebookaction.php:321 actions/login.php:177
+#: actions/login.php:230 lib/action.php:453 lib/logingroupnav.php:79
+#: actions/login.php:204 actions/login.php:257
+#, php-format
+msgid "Login"
+msgstr ""
+
+#: ../actions/openidlogin.php:44 actions/openidlogin.php:52
+#: actions/openidlogin.php:62 actions/openidlogin.php:70
+#, php-format
+msgid "Login with an [OpenID](%%doc.openid%%) account."
msgstr ""
-#: actions/emailsettings.php:358
+#: ../actions/login.php:126 actions/login.php:251
+#, php-format
msgid ""
-"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."
+"Login with your username and password. Don't have a username yet? [Register]"
+"(%%action.register%%) a new account, or try [OpenID](%%action.openidlogin%"
+"%). "
msgstr ""
-#: actions/emailsettings.php:378 actions/imsettings.php:351
-#: actions/smssettings.php:370
-msgid "No pending confirmation to cancel."
+#: ../lib/util.php:308 lib/util.php:324 lib/action.php:332 lib/action.php:409
+#: lib/action.php:435 lib/action.php:445
+msgid "Logout"
msgstr ""
-#: actions/emailsettings.php:382 actions/imsettings.php:355
-msgid "That is the wrong IM address."
+#: ../actions/register.php:166 actions/register.php:180
+#: actions/register.php:393 actions/register.php:439 actions/register.php:443
+#: actions/register.php:449
+msgid "Longer name, preferably your \"real\" name"
msgstr ""
-#: actions/emailsettings.php:394 actions/imsettings.php:367
-#: actions/smssettings.php:386
-msgid "Confirmation cancelled."
+#: ../actions/login.php:110 actions/login.php:110 actions/login.php:245
+#: lib/facebookaction.php:320 actions/login.php:228 lib/facebookaction.php:325
+#: lib/facebookaction.php:327 actions/login.php:236 actions/login.php:263
+msgid "Lost or forgotten password?"
msgstr ""
-#: actions/emailsettings.php:412
-msgid "That is not your email address."
+#: ../actions/emailsettings.php:80 ../actions/smssettings.php:89
+#: actions/emailsettings.php:81 actions/smssettings.php:89
+#: actions/emailsettings.php:139 actions/smssettings.php:150
+#: actions/emailsettings.php:145 actions/smssettings.php:162
+msgid "Make a new email address for posting to; cancels the old one."
msgstr ""
-#: actions/emailsettings.php:431 actions/imsettings.php:408
-#: actions/smssettings.php:425
-msgid "The address was removed."
+#: ../actions/emailsettings.php:27 actions/emailsettings.php:27
+#: actions/emailsettings.php:71
+#, php-format
+msgid "Manage how you get email from %%site.name%%."
msgstr ""
-#: actions/emailsettings.php:445 actions/smssettings.php:518
-msgid "No incoming email address."
+#: ../actions/showstream.php:300 actions/showstream.php:315
+#: actions/showstream.php:480 lib/profileaction.php:182
+msgid "Member since"
msgstr ""
-#: actions/emailsettings.php:455 actions/emailsettings.php:477
-#: actions/smssettings.php:528 actions/smssettings.php:552
-msgid "Couldn't update user record."
+#: ../actions/userrss.php:70 actions/userrss.php:67 actions/userrss.php:72
+#: actions/userrss.php:93
+#, php-format
+msgid "Microblog by %s"
msgstr ""
-#: actions/emailsettings.php:458 actions/smssettings.php:531
-msgid "Incoming email address removed."
+#: ../actions/smssettings.php:304 actions/smssettings.php:464
+#: actions/smssettings.php:476
+#, php-format
+msgid ""
+"Mobile carrier for your phone. If you know a carrier that accepts SMS over "
+"email but isn't listed here, send email to let us know at %s."
msgstr ""
-#: actions/emailsettings.php:480 actions/smssettings.php:555
-msgid "New incoming email address added."
+#: ../actions/finishopenidlogin.php:79 ../actions/register.php:188
+#: actions/finishopenidlogin.php:85 actions/register.php:202
+#: actions/finishopenidlogin.php:107 actions/register.php:429
+#: actions/register.php:430 actions/finishopenidlogin.php:106
+#: actions/register.php:477 actions/register.php:487 actions/register.php:493
+msgid "My text and files are available under "
msgstr ""
-#: actions/favorited.php:65 lib/popularnoticesection.php:87
-#: lib/publicgroupnav.php:93
-msgid "Popular notices"
+#: ../actions/emailsettings.php:82 ../actions/smssettings.php:91
+#: actions/emailsettings.php:83 actions/smssettings.php:91
+#: actions/emailsettings.php:142 actions/smssettings.php:152
+#: actions/emailsettings.php:148 actions/smssettings.php:164
+msgid "New"
msgstr ""
-#: actions/favorited.php:67
+#: ../lib/mail.php:144 lib/mail.php:144 lib/mail.php:286 lib/mail.php:285
#, php-format
-msgid "Popular notices, page %d"
+msgid "New email address for posting to %s"
msgstr ""
-#: actions/favorited.php:79
-msgid "The most popular notices on the site right now."
+#: ../actions/emailsettings.php:297 actions/emailsettings.php:315
+#: actions/emailsettings.php:465 actions/emailsettings.php:472
+#: actions/smssettings.php:542 actions/smssettings.php:543
+#: actions/emailsettings.php:480 actions/smssettings.php:555
+msgid "New incoming email address added."
msgstr ""
-#: actions/favorited.php:150
-msgid "Favorite notices appear on this page but no one has favorited one yet."
+#: ../actions/finishopenidlogin.php:71 actions/finishopenidlogin.php:77
+#: actions/finishopenidlogin.php:99 actions/finishopenidlogin.php:98
+msgid "New nickname"
msgstr ""
-#: actions/favorited.php:153
-msgid ""
-"Be the first to add a notice to your favorites by clicking the fave button "
-"next to any notice you like."
+#: ../actions/newnotice.php:87 actions/newnotice.php:96
+#: actions/newnotice.php:68 actions/newnotice.php:69
+msgid "New notice"
msgstr ""
-#: actions/favorited.php:156
-#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and be the first to add a "
-"notice to your favorites!"
+#: ../actions/password.php:41 ../actions/recoverpassword.php:179
+#: actions/profilesettings.php:180 actions/recoverpassword.php:185
+#: actions/passwordsettings.php:101 actions/recoverpassword.php:219
+#: actions/recoverpassword.php:232 actions/passwordsettings.php:107
+#: actions/recoverpassword.php:235
+msgid "New password"
msgstr ""
-#: actions/favoritesrss.php:111 actions/showfavorites.php:77
-#: lib/personalgroupnav.php:115
-#, php-format
-msgid "%s's favorite notices"
+#: ../actions/recoverpassword.php:314 actions/recoverpassword.php:361
+#: actions/recoverpassword.php:379 actions/recoverpassword.php:382
+msgid "New password successfully saved. You are now logged in."
msgstr ""
-#: actions/favoritesrss.php:115
-#, php-format
-msgid "Updates favored by %1$s on %2$s!"
+#: ../actions/login.php:101 ../actions/profilesettings.php:41
+#: ../actions/register.php:151 actions/login.php:101
+#: actions/profilesettings.php:74 actions/register.php:165
+#: actions/login.php:228 actions/profilesettings.php:98
+#: actions/register.php:367 actions/showgroup.php:224
+#: actions/showstream.php:251 actions/tagother.php:95
+#: lib/facebookaction.php:308 lib/groupeditform.php:137 actions/login.php:211
+#: actions/showgroup.php:226 actions/showstream.php:244
+#: actions/tagother.php:94 lib/facebookaction.php:312 actions/register.php:413
+#: actions/showgroup.php:231 actions/showstream.php:209
+#: lib/facebookaction.php:314 lib/groupeditform.php:152 actions/login.php:219
+#: actions/profilesettings.php:106 actions/register.php:417
+#: actions/showgroup.php:236 actions/showstream.php:249 actions/login.php:246
+#: actions/register.php:423 lib/userprofile.php:131
+msgid "Nickname"
msgstr ""
-#: actions/favor.php:79
-msgid "This notice is already a favorite!"
+#: ../actions/finishopenidlogin.php:175 ../actions/profilesettings.php:110
+#: ../actions/register.php:69 actions/finishopenidlogin.php:181
+#: actions/profilesettings.php:225 actions/register.php:76
+#: actions/editgroup.php:183 actions/finishopenidlogin.php:215
+#: actions/newgroup.php:134 actions/profilesettings.php:214
+#: actions/register.php:159 actions/editgroup.php:185
+#: actions/finishopenidlogin.php:231 actions/newgroup.php:135
+#: actions/profilesettings.php:215 actions/register.php:196
+#: actions/apigroupcreate.php:221 actions/editgroup.php:186
+#: actions/newgroup.php:130 actions/profilesettings.php:231
+#: actions/register.php:202 actions/register.php:208
+msgid "Nickname already in use. Try another one."
msgstr ""
-#: actions/favor.php:92 lib/disfavorform.php:140
-msgid "Disfavor favorite"
+#: ../actions/finishopenidlogin.php:165 ../actions/profilesettings.php:88
+#: ../actions/register.php:67 ../actions/updateprofile.php:77
+#: actions/finishopenidlogin.php:171 actions/profilesettings.php:203
+#: actions/register.php:74 actions/updateprofile.php:78
+#: actions/finishopenidlogin.php:205 actions/profilesettings.php:192
+#: actions/updateprofile.php:81 actions/editgroup.php:179
+#: actions/newgroup.php:130 actions/register.php:156
+#: actions/updateprofile.php:83 actions/editgroup.php:181
+#: actions/finishopenidlogin.php:221 actions/newgroup.php:131
+#: actions/profilesettings.php:193 actions/register.php:193
+#: actions/apigroupcreate.php:212 actions/editgroup.php:182
+#: actions/newgroup.php:126 actions/profilesettings.php:208
+#: actions/register.php:199 actions/register.php:205
+msgid "Nickname must have only lowercase letters and numbers and no spaces."
msgstr ""
-#: actions/featured.php:69 lib/featureduserssection.php:87
-#: lib/publicgroupnav.php:89
-msgid "Featured users"
+#: ../actions/finishopenidlogin.php:170 actions/finishopenidlogin.php:176
+#: actions/finishopenidlogin.php:210 actions/finishopenidlogin.php:226
+msgid "Nickname not allowed."
msgstr ""
-#: actions/featured.php:71
-#, php-format
-msgid "Featured users, page %d"
+#: ../actions/remotesubscribe.php:72 actions/remotesubscribe.php:81
+#: actions/remotesubscribe.php:106 actions/remotesubscribe.php:130
+msgid "Nickname of the user you want to follow"
msgstr ""
-#: actions/featured.php:99
-#, php-format
-msgid "A selection of some of the great users on %s"
+#: ../actions/recoverpassword.php:162 actions/recoverpassword.php:167
+#: actions/recoverpassword.php:186 actions/recoverpassword.php:191
+msgid "Nickname or email"
msgstr ""
-#: actions/file.php:34
-msgid "No notice id"
+#: ../actions/deletenotice.php:59 actions/deletenotice.php:60
+#: actions/block.php:147 actions/deletenotice.php:118
+#: actions/deletenotice.php:116 actions/block.php:149
+#: actions/deletenotice.php:115 actions/groupblock.php:176
+#: actions/deletenotice.php:145
+msgid "No"
msgstr ""
-#: actions/file.php:38
-msgid "No notice"
+#: ../actions/imsettings.php:156 actions/imsettings.php:164
+#: actions/imsettings.php:279 actions/imsettings.php:285
+msgid "No Jabber ID."
msgstr ""
-#: actions/file.php:42
-msgid "No attachments"
+#: ../actions/userauthorization.php:129 actions/userauthorization.php:136
+#: actions/userauthorization.php:153 actions/userauthorization.php:192
+#: actions/userauthorization.php:225
+msgid "No authorization request!"
msgstr ""
-#: actions/file.php:51
-msgid "No uploaded attachments"
+#: ../actions/smssettings.php:181 actions/smssettings.php:189
+#: actions/smssettings.php:299 actions/smssettings.php:311
+msgid "No carrier selected."
msgstr ""
-#: actions/finishremotesubscribe.php:69
-msgid "Not expecting this response!"
+#: ../actions/smssettings.php:316 actions/smssettings.php:324
+#: actions/smssettings.php:486 actions/smssettings.php:498
+msgid "No code entered"
msgstr ""
-#: actions/finishremotesubscribe.php:80
-msgid "User being listened to does not exist."
+#: ../actions/confirmaddress.php:33 actions/confirmaddress.php:33
+#: actions/confirmaddress.php:75
+msgid "No confirmation code."
msgstr ""
-#: actions/finishremotesubscribe.php:87 actions/remotesubscribe.php:59
-msgid "You can use the local subscription!"
+#: ../actions/newnotice.php:44 actions/newmessage.php:53
+#: actions/newnotice.php:44 classes/Command.php:197 actions/newmessage.php:109
+#: actions/newnotice.php:126 classes/Command.php:223
+#: actions/newmessage.php:142 actions/newnotice.php:131 lib/command.php:223
+#: actions/newnotice.php:162 lib/command.php:216 actions/newmessage.php:144
+#: actions/newnotice.php:136 lib/command.php:351 lib/command.php:424
+msgid "No content!"
msgstr ""
-#: actions/finishremotesubscribe.php:96
-msgid "That user has blocked you from subscribing."
+#: ../actions/emailsettings.php:174 actions/emailsettings.php:192
+#: actions/emailsettings.php:304 actions/emailsettings.php:311
+#: actions/emailsettings.php:319
+msgid "No email address."
msgstr ""
-#: actions/finishremotesubscribe.php:106
-msgid "You are not authorized."
+#: ../actions/userbyid.php:32 actions/userbyid.php:32 actions/userbyid.php:70
+msgid "No id."
msgstr ""
-#: actions/finishremotesubscribe.php:109
-msgid "Could not convert request token to access token."
-msgstr ""
-
-#: actions/finishremotesubscribe.php:114
-msgid "Remote service uses unknown version of OMB protocol."
+#: ../actions/emailsettings.php:271 actions/emailsettings.php:289
+#: actions/emailsettings.php:430 actions/emailsettings.php:437
+#: actions/smssettings.php:505 actions/smssettings.php:506
+#: actions/emailsettings.php:445 actions/smssettings.php:518
+msgid "No incoming email address."
msgstr ""
-#: actions/finishremotesubscribe.php:133 lib/oauthstore.php:306
-msgid "Error updating remote profile"
+#: ../actions/finishremotesubscribe.php:65
+#: actions/finishremotesubscribe.php:67 actions/finishremotesubscribe.php:68
+msgid "No nickname provided by remote server."
msgstr ""
-#: actions/foafgroup.php:44 actions/foafgroup.php:62 actions/groupblock.php:86
-#: actions/groupunblock.php:86 actions/leavegroup.php:83
-#: actions/makeadmin.php:86 lib/command.php:212 lib/command.php:263
-msgid "No such group."
+#: ../actions/avatarbynickname.php:27 actions/avatarbynickname.php:27
+#: actions/avatarbynickname.php:59 actions/leavegroup.php:81
+#: actions/leavegroup.php:76
+msgid "No nickname."
msgstr ""
-#: actions/getfile.php:75
-msgid "No such file."
+#: ../actions/emailsettings.php:222 ../actions/imsettings.php:206
+#: ../actions/smssettings.php:229 actions/emailsettings.php:240
+#: actions/imsettings.php:214 actions/smssettings.php:237
+#: actions/emailsettings.php:363 actions/imsettings.php:345
+#: actions/smssettings.php:358 actions/emailsettings.php:370
+#: actions/emailsettings.php:378 actions/imsettings.php:351
+#: actions/smssettings.php:370
+msgid "No pending confirmation to cancel."
msgstr ""
-#: actions/getfile.php:79
-msgid "Cannot read file."
+#: ../actions/smssettings.php:176 actions/smssettings.php:184
+#: actions/smssettings.php:294 actions/smssettings.php:306
+msgid "No phone number."
msgstr ""
-#: actions/groupblock.php:81 actions/groupunblock.php:81
-#: actions/makeadmin.php:81
-msgid "No group specified."
+#: ../actions/finishremotesubscribe.php:72
+#: actions/finishremotesubscribe.php:74 actions/finishremotesubscribe.php:75
+msgid "No profile URL returned by server."
msgstr ""
-#: actions/groupblock.php:91
-msgid "Only an admin can block group members."
+#: ../actions/recoverpassword.php:226 actions/recoverpassword.php:232
+#: actions/recoverpassword.php:266 actions/recoverpassword.php:284
+#: actions/recoverpassword.php:287
+msgid "No registered email address for that user."
msgstr ""
-#: actions/groupblock.php:95
-msgid "User is already blocked from group."
+#: ../actions/userauthorization.php:49 actions/userauthorization.php:55
+#: actions/userauthorization.php:57
+msgid "No request found!"
msgstr ""
-#: actions/groupblock.php:100
-msgid "User is not a member of group."
+#: ../actions/noticesearch.php:64 ../actions/peoplesearch.php:64
+#: actions/noticesearch.php:69 actions/peoplesearch.php:69
+#: actions/groupsearch.php:81 actions/noticesearch.php:104
+#: actions/peoplesearch.php:85 actions/noticesearch.php:117
+msgid "No results"
msgstr ""
-#: actions/groupblock.php:136 actions/groupmembers.php:314
-msgid "Block user from group"
+#: ../actions/avatarbynickname.php:32 actions/avatarbynickname.php:32
+#: actions/avatarbynickname.php:64
+msgid "No size."
msgstr ""
-#: actions/groupblock.php:155
-#, php-format
-msgid ""
-"Are you sure you want to block user \"%s\" from the group \"%s\"? They will "
-"be removed from the group, unable to post, and unable to subscribe to the "
-"group in the future."
+#: ../actions/twitapistatuses.php:595 actions/twitapifavorites.php:136
+#: actions/twitapistatuses.php:520 actions/twitapifavorites.php:112
+#: actions/twitapistatuses.php:446 actions/twitapifavorites.php:118
+#: actions/twitapistatuses.php:470 actions/twitapifavorites.php:169
+#: actions/twitapistatuses.php:426 actions/apifavoritecreate.php:108
+#: actions/apifavoritedestroy.php:109 actions/apistatusesdestroy.php:113
+msgid "No status found with that ID."
msgstr ""
-#: actions/groupblock.php:193
-msgid "Database error blocking user from group."
+#: ../actions/twitapistatuses.php:555 actions/twitapistatuses.php:478
+#: actions/twitapistatuses.php:418 actions/twitapistatuses.php:442
+#: actions/twitapistatuses.php:399 actions/apistatusesshow.php:144
+msgid "No status with that ID found."
msgstr ""
-#: actions/groupbyid.php:74
-msgid "No ID"
+#: ../actions/openidsettings.php:135 actions/openidsettings.php:144
+#: actions/openidsettings.php:222
+msgid "No such OpenID."
msgstr ""
-#: actions/groupdesignsettings.php:68
-msgid "You must be logged in to edit a group."
+#: ../actions/doc.php:29 actions/doc.php:29 actions/doc.php:64
+#: actions/doc.php:69
+msgid "No such document."
msgstr ""
-#: actions/groupdesignsettings.php:141
-msgid "Group design"
+#: ../actions/shownotice.php:32 ../actions/shownotice.php:83
+#: ../lib/deleteaction.php:30 actions/shownotice.php:32
+#: actions/shownotice.php:83 lib/deleteaction.php:30 actions/shownotice.php:87
+#: lib/deleteaction.php:51 actions/deletenotice.php:52
+#: actions/shownotice.php:92
+msgid "No such notice."
msgstr ""
-#: actions/groupdesignsettings.php:152
-msgid ""
-"Customize the way your group looks with a background image and a colour "
-"palette of your choice."
+#: ../actions/recoverpassword.php:56 actions/recoverpassword.php:56
+#: actions/recoverpassword.php:62
+msgid "No such recovery code."
msgstr ""
-#: actions/groupdesignsettings.php:262 actions/userdesignsettings.php:186
-#: lib/designsettings.php:434 lib/designsettings.php:464
-msgid "Couldn't update your design."
+#: ../actions/postnotice.php:56 actions/postnotice.php:57
+#: actions/postnotice.php:60
+msgid "No such subscription"
+msgstr ""
+
+#: ../actions/all.php:34 ../actions/allrss.php:35
+#: ../actions/avatarbynickname.php:43 ../actions/foaf.php:40
+#: ../actions/remotesubscribe.php:84 ../actions/remotesubscribe.php:91
+#: ../actions/replies.php:57 ../actions/repliesrss.php:35
+#: ../actions/showstream.php:110 ../actions/userbyid.php:36
+#: ../actions/userrss.php:35 ../actions/xrds.php:35 ../lib/gallery.php:57
+#: ../lib/subs.php:33 ../lib/subs.php:82 actions/all.php:34
+#: actions/allrss.php:35 actions/avatarbynickname.php:43
+#: actions/favoritesrss.php:35 actions/foaf.php:40 actions/ical.php:31
+#: actions/remotesubscribe.php:93 actions/remotesubscribe.php:100
+#: actions/replies.php:57 actions/repliesrss.php:35
+#: actions/showfavorites.php:34 actions/showstream.php:110
+#: actions/userbyid.php:36 actions/userrss.php:35 actions/xrds.php:35
+#: classes/Command.php:120 classes/Command.php:162 classes/Command.php:203
+#: classes/Command.php:237 lib/gallery.php:62 lib/mailbox.php:36
+#: lib/subs.php:33 lib/subs.php:95 actions/all.php:53 actions/allrss.php:66
+#: actions/avatarbynickname.php:75 actions/favoritesrss.php:64
+#: actions/foaf.php:41 actions/remotesubscribe.php:123
+#: actions/remotesubscribe.php:130 actions/replies.php:73
+#: actions/repliesrss.php:38 actions/showfavorites.php:105
+#: actions/showstream.php:100 actions/userbyid.php:74
+#: actions/usergroups.php:92 actions/userrss.php:38 actions/xrds.php:73
+#: classes/Command.php:140 classes/Command.php:185 classes/Command.php:234
+#: classes/Command.php:271 lib/galleryaction.php:60 lib/mailbox.php:82
+#: lib/subs.php:34 lib/subs.php:109 actions/all.php:56 actions/allrss.php:68
+#: actions/favoritesrss.php:74 lib/command.php:140 lib/command.php:185
+#: lib/command.php:234 lib/command.php:271 lib/mailbox.php:84
+#: actions/all.php:38 actions/foaf.php:58 actions/replies.php:72
+#: actions/usergroups.php:91 actions/userrss.php:39 lib/command.php:133
+#: lib/command.php:178 lib/command.php:227 lib/command.php:264
+#: lib/galleryaction.php:59 lib/profileaction.php:77 lib/subs.php:112
+#: actions/all.php:74 actions/remotesubscribe.php:145 actions/xrds.php:71
+#: lib/command.php:163 lib/command.php:311 lib/command.php:364
+#: lib/command.php:411 lib/command.php:466
+msgid "No such user."
msgstr ""
-#: actions/groupdesignsettings.php:286 actions/groupdesignsettings.php:296
-#: actions/userdesignsettings.php:210 actions/userdesignsettings.php:220
-#: actions/userdesignsettings.php:263 actions/userdesignsettings.php:273
-msgid "Unable to save your design settings!"
+#: ../actions/recoverpassword.php:211 actions/recoverpassword.php:217
+#: actions/recoverpassword.php:251 actions/recoverpassword.php:269
+#: actions/recoverpassword.php:272
+msgid "No user with that email address or username."
msgstr ""
-#: actions/groupdesignsettings.php:307 actions/userdesignsettings.php:231
-msgid "Design preferences saved."
+#: ../lib/gallery.php:80 lib/gallery.php:85
+msgid "Nobody to show!"
msgstr ""
-#: actions/grouplogo.php:139 actions/grouplogo.php:192
-msgid "Group logo"
+#: ../actions/recoverpassword.php:60 actions/recoverpassword.php:60
+#: actions/recoverpassword.php:66
+msgid "Not a recovery code."
msgstr ""
-#: actions/grouplogo.php:150
-#, php-format
-msgid ""
-"You can upload a logo image for your group. The maximum file size is %s."
+#: ../scripts/maildaemon.php:50 scripts/maildaemon.php:50
+#: scripts/maildaemon.php:53 scripts/maildaemon.php:52
+msgid "Not a registered user."
msgstr ""
-#: actions/grouplogo.php:362
-msgid "Pick a square area of the image to be the logo."
+#: ../lib/twitterapi.php:226 ../lib/twitterapi.php:247
+#: ../lib/twitterapi.php:332 lib/twitterapi.php:391 lib/twitterapi.php:418
+#: lib/twitterapi.php:502 lib/twitterapi.php:448 lib/twitterapi.php:476
+#: lib/twitterapi.php:566 lib/twitterapi.php:483 lib/twitterapi.php:511
+#: lib/twitterapi.php:601 lib/twitterapi.php:620 lib/twitterapi.php:648
+#: lib/twitterapi.php:741 actions/oembed.php:181 actions/oembed.php:200
+#: lib/api.php:954 lib/api.php:982 lib/api.php:1092 lib/api.php:963
+#: lib/api.php:991 lib/api.php:1101
+msgid "Not a supported data format."
msgstr ""
-#: actions/grouplogo.php:396
-msgid "Logo updated."
+#: ../actions/imsettings.php:167 actions/imsettings.php:175
+#: actions/imsettings.php:290 actions/imsettings.php:296
+msgid "Not a valid Jabber ID"
msgstr ""
-#: actions/grouplogo.php:398
-msgid "Failed updating logo."
+#: ../lib/openid.php:131 lib/openid.php:131 lib/openid.php:140
+#: lib/openid.php:143
+msgid "Not a valid OpenID."
msgstr ""
-#: actions/groupmembers.php:93 lib/groupnav.php:91
-#, php-format
-msgid "%s group members"
+#: ../actions/emailsettings.php:185 actions/emailsettings.php:203
+#: actions/emailsettings.php:315 actions/emailsettings.php:322
+#: actions/emailsettings.php:330
+msgid "Not a valid email address"
msgstr ""
-#: actions/groupmembers.php:96
-#, php-format
-msgid "%s group members, page %d"
+#: ../actions/register.php:63 actions/register.php:70 actions/register.php:152
+#: actions/register.php:189 actions/register.php:195 actions/register.php:201
+msgid "Not a valid email address."
msgstr ""
-#: actions/groupmembers.php:111
-msgid "A list of the users in this group."
+#: ../actions/profilesettings.php:91 ../actions/register.php:71
+#: actions/profilesettings.php:206 actions/register.php:78
+#: actions/editgroup.php:186 actions/newgroup.php:137
+#: actions/profilesettings.php:195 actions/register.php:161
+#: actions/editgroup.php:188 actions/newgroup.php:138
+#: actions/profilesettings.php:196 actions/register.php:198
+#: actions/apigroupcreate.php:228 actions/editgroup.php:189
+#: actions/newgroup.php:133 actions/profilesettings.php:211
+#: actions/register.php:204 actions/register.php:210
+msgid "Not a valid nickname."
msgstr ""
-#: actions/groupmembers.php:175 lib/groupnav.php:106
-msgid "Admin"
+#: ../actions/remotesubscribe.php:120 actions/remotesubscribe.php:129
+#: actions/remotesubscribe.php:159
+msgid "Not a valid profile URL (incorrect services)."
msgstr ""
-#: actions/groupmembers.php:346 lib/blockform.php:153
-msgid "Block"
+#: ../actions/remotesubscribe.php:113 actions/remotesubscribe.php:122
+#: actions/remotesubscribe.php:152
+msgid "Not a valid profile URL (no XRDS defined)."
msgstr ""
-#: actions/groupmembers.php:346 lib/blockform.php:123 lib/blockform.php:153
-msgid "Block this user"
+#: ../actions/remotesubscribe.php:104 actions/remotesubscribe.php:113
+#: actions/remotesubscribe.php:143
+msgid "Not a valid profile URL (no YADIS document)."
msgstr ""
-#: actions/groupmembers.php:441
-msgid "Make user an admin of the group"
+#: ../actions/avatar.php:95 actions/profilesettings.php:332
+#: lib/imagefile.php:87 lib/imagefile.php:90 lib/imagefile.php:91
+#: lib/imagefile.php:96
+msgid "Not an image or corrupt file."
msgstr ""
-#: actions/groupmembers.php:473
-msgid "Make Admin"
+#: ../actions/finishremotesubscribe.php:51
+#: actions/finishremotesubscribe.php:53 actions/finishremotesubscribe.php:54
+msgid "Not authorized."
msgstr ""
-#: actions/groupmembers.php:473
-msgid "Make this user an admin"
+#: ../actions/finishremotesubscribe.php:38
+#: actions/finishremotesubscribe.php:38 actions/finishremotesubscribe.php:40
+#: actions/finishremotesubscribe.php:69
+msgid "Not expecting this response!"
msgstr ""
-#: actions/grouprss.php:133
-#, php-format
-msgid "Updates from members of %1$s on %2$s!"
+#: ../actions/twitapistatuses.php:422 actions/twitapistatuses.php:361
+#: actions/twitapistatuses.php:309 actions/twitapistatuses.php:327
+#: actions/twitapistatuses.php:284 actions/apistatusesupdate.php:186
+#: actions/apistatusesupdate.php:193
+msgid "Not found"
msgstr ""
-#: actions/groupsearch.php:52
-#, php-format
-msgid ""
-"Search for groups on %%site.name%% by their name, location, or description. "
-"Separate the terms by spaces; they must be 3 characters or more."
+#: ../actions/finishaddopenid.php:29 ../actions/logout.php:33
+#: ../actions/newnotice.php:29 ../actions/subscribe.php:28
+#: ../actions/unsubscribe.php:25 ../lib/deleteaction.php:38
+#: ../lib/settingsaction.php:27 actions/disfavor.php:29 actions/favor.php:30
+#: actions/finishaddopenid.php:29 actions/logout.php:33
+#: actions/newmessage.php:28 actions/newnotice.php:29 actions/subscribe.php:28
+#: actions/unsubscribe.php:25 lib/deleteaction.php:38
+#: lib/settingsaction.php:27 actions/block.php:59 actions/disfavor.php:61
+#: actions/favor.php:64 actions/finishaddopenid.php:67 actions/logout.php:71
+#: actions/newmessage.php:83 actions/newnotice.php:90 actions/nudge.php:63
+#: actions/subedit.php:31 actions/subscribe.php:30 actions/unblock.php:60
+#: actions/unsubscribe.php:27 lib/deleteaction.php:66
+#: lib/settingsaction.php:72 actions/newmessage.php:87 actions/favor.php:62
+#: actions/groupblock.php:61 actions/groupunblock.php:61
+#: actions/makeadmin.php:61 actions/newnotice.php:88
+#: actions/deletenotice.php:67 actions/logout.php:69 actions/newnotice.php:89
+#: actions/unsubscribe.php:52
+msgid "Not logged in."
msgstr ""
-#: actions/groupsearch.php:58
-msgid "Group search"
+#: ../lib/subs.php:91 lib/subs.php:104 lib/subs.php:122 lib/subs.php:124
+msgid "Not subscribed!."
msgstr ""
-#: actions/groupsearch.php:79 actions/noticesearch.php:117
-#: actions/peoplesearch.php:83
-msgid "No results."
+#: ../actions/opensearch.php:35 actions/opensearch.php:35
+#: actions/opensearch.php:67
+msgid "Notice Search"
msgstr ""
-#: actions/groupsearch.php:82
+#: ../actions/showstream.php:82 actions/showstream.php:82
+#: actions/showstream.php:180 actions/showstream.php:187
+#: actions/showstream.php:192
#, php-format
-msgid ""
-"If you can't find the group you're looking for, you can [create it](%%action."
-"newgroup%%) yourself."
+msgid "Notice feed for %s"
msgstr ""
-#: actions/groupsearch.php:85
-#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and [create the group](%%"
-"action.newgroup%%) yourself!"
+#: ../actions/shownotice.php:39 actions/shownotice.php:39
+#: actions/shownotice.php:94 actions/oembed.php:79 actions/shownotice.php:100
+msgid "Notice has no profile"
msgstr ""
-#: actions/groups.php:62 lib/profileaction.php:220 lib/publicgroupnav.php:81
-#: lib/subgroupnav.php:98
-msgid "Groups"
+#: ../actions/showstream.php:316 actions/showstream.php:331
+#: actions/showstream.php:504 lib/facebookaction.php:477 lib/mailbox.php:116
+#: lib/noticelist.php:87 lib/facebookaction.php:581 lib/mailbox.php:118
+#: actions/conversation.php:149 lib/facebookaction.php:572
+#: lib/profileaction.php:206 actions/conversation.php:154
+msgid "Notices"
msgstr ""
-#: actions/groups.php:64
+#: ../actions/tag.php:35 ../actions/tag.php:81 actions/tag.php:35
+#: actions/tag.php:81 actions/tag.php:41 actions/tag.php:49 actions/tag.php:57
+#: actions/twitapitags.php:69 actions/apitimelinetag.php:101
+#: actions/tag.php:66
#, php-format
-msgid "Groups, page %d"
+msgid "Notices tagged with %s"
msgstr ""
-#: actions/groups.php:90
-#, php-format
-msgid ""
-"%%%%site.name%%%% groups let you find and talk with users of similar "
-"interests. After you join a group you can send messages to all other members "
-"using the syntax \"!groupname\". Are you not seeing any groups you like? Try "
-"[searching for one](%%%%action.groupsearch%%%%) or [start your own](%%%%"
-"action.newgroup%%%%)!"
+#: ../actions/password.php:39 actions/profilesettings.php:178
+#: actions/passwordsettings.php:97 actions/passwordsettings.php:103
+msgid "Old password"
msgstr ""
-#: actions/groups.php:108 actions/usergroups.php:124 lib/groupeditform.php:122
-msgid "Create a new group"
+#: ../lib/settingsaction.php:96 ../lib/util.php:314 lib/settingsaction.php:90
+#: lib/util.php:330 lib/accountsettingsaction.php:116 lib/action.php:341
+#: lib/logingroupnav.php:81 lib/action.php:418
+msgid "OpenID"
msgstr ""
-#: actions/groupunblock.php:91
-msgid "Only an admin can unblock group members."
+#: ../actions/finishopenidlogin.php:61 actions/finishopenidlogin.php:66
+#: actions/finishopenidlogin.php:73 actions/finishopenidlogin.php:72
+msgid "OpenID Account Setup"
msgstr ""
-#: actions/groupunblock.php:95
-msgid "User is not blocked from group."
+#: ../lib/openid.php:180 lib/openid.php:180 lib/openid.php:266
+#: lib/openid.php:269
+msgid "OpenID Auto-Submit"
msgstr ""
-#: actions/groupunblock.php:128 actions/unblock.php:108
-msgid "Error removing the block."
+#: ../actions/finishaddopenid.php:99 ../actions/finishopenidlogin.php:140
+#: ../actions/openidlogin.php:60 actions/finishaddopenid.php:99
+#: actions/finishopenidlogin.php:146 actions/openidlogin.php:68
+#: actions/finishaddopenid.php:170 actions/openidlogin.php:80
+#: actions/openidlogin.php:89
+msgid "OpenID Login"
msgstr ""
-#: actions/imsettings.php:59
-msgid "IM Settings"
+#: ../actions/openidlogin.php:65 ../actions/openidsettings.php:49
+#: actions/openidlogin.php:74 actions/openidsettings.php:50
+#: actions/openidlogin.php:102 actions/openidsettings.php:101
+#: actions/openidlogin.php:111
+msgid "OpenID URL"
msgstr ""
-#: actions/imsettings.php:70
+#: ../actions/finishaddopenid.php:42 ../actions/finishopenidlogin.php:103
+#: actions/finishaddopenid.php:42 actions/finishopenidlogin.php:109
+#: actions/finishaddopenid.php:88 actions/finishopenidlogin.php:130
+#: actions/finishopenidlogin.php:129
+msgid "OpenID authentication cancelled."
+msgstr ""
+
+#: ../actions/finishaddopenid.php:46 ../actions/finishopenidlogin.php:107
+#: actions/finishaddopenid.php:46 actions/finishopenidlogin.php:113
+#: actions/finishaddopenid.php:92 actions/finishopenidlogin.php:134
+#: actions/finishopenidlogin.php:133
#, php-format
-msgid ""
-"You can send and receive notices through Jabber/GTalk [instant messages](%%"
-"doc.im%%). Configure your instant messages address and settings below."
+msgid "OpenID authentication failed: %s"
msgstr ""
-#: actions/imsettings.php:89
-msgid "IM is not available."
+#: ../lib/openid.php:133 lib/openid.php:133 lib/openid.php:142
+#: lib/openid.php:145
+#, php-format
+msgid "OpenID failure: %s"
msgstr ""
-#: actions/imsettings.php:100
-msgid "IM address"
+#: ../actions/openidsettings.php:144 actions/openidsettings.php:153
+#: actions/openidsettings.php:231
+msgid "OpenID removed."
msgstr ""
-#: actions/imsettings.php:106
-msgid "Current confirmed Jabber/GTalk address."
+#: ../actions/openidsettings.php:37 actions/openidsettings.php:37
+#: actions/openidsettings.php:59
+msgid "OpenID settings"
msgstr ""
-#: actions/imsettings.php:114
-#, php-format
-msgid ""
-"Awaiting confirmation on this IM address. Check your Jabber/GTalk account "
-"for a message with further instructions. (Did you add %s to your buddy list?)"
+#: ../actions/invite.php:135 actions/invite.php:143 actions/invite.php:180
+#: actions/invite.php:186 actions/invite.php:188 actions/invite.php:194
+msgid "Optionally add a personal message to the invitation."
msgstr ""
-#: actions/imsettings.php:124
-msgid "IM Address"
+#: ../actions/avatar.php:84 actions/profilesettings.php:321
+#: lib/imagefile.php:75 lib/imagefile.php:79 lib/imagefile.php:80
+msgid "Partial upload."
msgstr ""
-#: actions/imsettings.php:126
-#, php-format
-msgid ""
-"Jabber or GTalk address, like \"UserName@example.org\". First, make sure to "
-"add %s to your buddy list in your IM client or on GTalk."
+#: ../actions/finishopenidlogin.php:90 ../actions/login.php:102
+#: ../actions/register.php:153 ../lib/settingsaction.php:93
+#: actions/finishopenidlogin.php:96 actions/login.php:102
+#: actions/register.php:167 actions/finishopenidlogin.php:118
+#: actions/login.php:231 actions/register.php:372
+#: lib/accountsettingsaction.php:110 lib/facebookaction.php:311
+#: actions/login.php:214 lib/facebookaction.php:315
+#: actions/finishopenidlogin.php:117 actions/register.php:418
+#: lib/facebookaction.php:317 actions/login.php:222 actions/register.php:422
+#: lib/accountsettingsaction.php:114 actions/login.php:249
+#: actions/register.php:428
+msgid "Password"
msgstr ""
-#: actions/imsettings.php:143
-msgid "Send me notices through Jabber/GTalk."
+#: ../actions/recoverpassword.php:288 actions/recoverpassword.php:301
+#: actions/recoverpassword.php:335 actions/recoverpassword.php:353
+#: actions/recoverpassword.php:356
+msgid "Password and confirmation do not match."
msgstr ""
-#: actions/imsettings.php:148
-msgid "Post a notice when my Jabber/GTalk status changes."
+#: ../actions/recoverpassword.php:284 actions/recoverpassword.php:297
+#: actions/recoverpassword.php:331 actions/recoverpassword.php:349
+#: actions/recoverpassword.php:352
+msgid "Password must be 6 chars or more."
msgstr ""
-#: actions/imsettings.php:153
-msgid "Send me replies through Jabber/GTalk from users I am not subscribed to."
+#: ../actions/recoverpassword.php:261 ../actions/recoverpassword.php:263
+#: actions/recoverpassword.php:267 actions/recoverpassword.php:269
+#: actions/recoverpassword.php:199 actions/recoverpassword.php:301
+#: actions/recoverpassword.php:207 actions/recoverpassword.php:319
+#: actions/recoverpassword.php:210 actions/recoverpassword.php:322
+msgid "Password recovery requested"
msgstr ""
-#: actions/imsettings.php:159
-msgid "Publish a MicroID for my Jabber/GTalk address."
+#: ../actions/password.php:89 ../actions/recoverpassword.php:313
+#: actions/profilesettings.php:408 actions/recoverpassword.php:326
+#: actions/passwordsettings.php:173 actions/recoverpassword.php:200
+#: actions/passwordsettings.php:178 actions/recoverpassword.php:208
+#: actions/passwordsettings.php:184 actions/recoverpassword.php:211
+#: actions/passwordsettings.php:191
+msgid "Password saved."
msgstr ""
-#: actions/imsettings.php:285
-msgid "No Jabber ID."
+#: ../actions/password.php:61 ../actions/register.php:88
+#: actions/profilesettings.php:380 actions/register.php:98
+#: actions/passwordsettings.php:145 actions/register.php:183
+#: actions/passwordsettings.php:150 actions/register.php:220
+#: actions/passwordsettings.php:156 actions/register.php:227
+#: actions/register.php:233
+msgid "Passwords don't match."
msgstr ""
-#: actions/imsettings.php:292
-msgid "Cannot normalize that Jabber ID"
+#: ../lib/searchaction.php:100 lib/searchaction.php:100
+#: lib/searchgroupnav.php:80
+msgid "People"
msgstr ""
-#: actions/imsettings.php:296
-msgid "Not a valid Jabber ID"
+#: ../actions/opensearch.php:33 actions/opensearch.php:33
+#: actions/opensearch.php:64
+msgid "People Search"
msgstr ""
-#: actions/imsettings.php:299
-msgid "That is already your Jabber ID."
+#: ../actions/peoplesearch.php:33 actions/peoplesearch.php:33
+#: actions/peoplesearch.php:58
+msgid "People search"
msgstr ""
-#: actions/imsettings.php:302
-msgid "Jabber ID already belongs to another user."
+#: ../lib/stream.php:50 lib/personal.php:50 lib/personalgroupnav.php:98
+#: lib/personalgroupnav.php:99
+msgid "Personal"
msgstr ""
-#: actions/imsettings.php:327
-#, php-format
-msgid ""
-"A confirmation code was sent to the IM address you added. You must approve %"
-"s for sending messages to you."
+#: ../actions/invite.php:133 actions/invite.php:141 actions/invite.php:178
+#: actions/invite.php:184 actions/invite.php:186 actions/invite.php:192
+msgid "Personal message"
msgstr ""
-#: actions/imsettings.php:387
-msgid "That is not your Jabber ID."
+#: ../actions/smssettings.php:69 actions/smssettings.php:69
+#: actions/smssettings.php:128 actions/smssettings.php:140
+msgid "Phone number, no punctuation or spaces, with area code"
msgstr ""
-#: actions/inbox.php:59
-#, php-format
-msgid "Inbox for %s - page %d"
+#: ../actions/userauthorization.php:78
+msgid ""
+"Please check these details to make sure that you want to subscribe to this "
+"user's notices. If you didn't just ask to subscribe to someone's notices, "
+"click \"Cancel\"."
msgstr ""
-#: actions/inbox.php:62
-#, php-format
-msgid "Inbox for %s"
+#: ../actions/imsettings.php:73 actions/imsettings.php:74
+#: actions/imsettings.php:142 actions/imsettings.php:148
+msgid "Post a notice when my Jabber/GTalk status changes."
msgstr ""
-#: actions/inbox.php:115
-msgid "This is your inbox, which lists your incoming private messages."
+#: ../actions/emailsettings.php:85 ../actions/imsettings.php:67
+#: ../actions/smssettings.php:94 actions/emailsettings.php:86
+#: actions/imsettings.php:68 actions/smssettings.php:94
+#: actions/twittersettings.php:70 actions/emailsettings.php:147
+#: actions/imsettings.php:133 actions/smssettings.php:157
+#: actions/twittersettings.php:134 actions/twittersettings.php:137
+#: actions/emailsettings.php:153 actions/imsettings.php:139
+#: actions/smssettings.php:169
+msgid "Preferences"
msgstr ""
-#: actions/invite.php:39
-msgid "Invites have been disabled."
+#: ../actions/emailsettings.php:162 ../actions/imsettings.php:144
+#: ../actions/smssettings.php:163 actions/emailsettings.php:180
+#: actions/imsettings.php:152 actions/smssettings.php:171
+#: actions/emailsettings.php:286 actions/imsettings.php:258
+#: actions/othersettings.php:168 actions/smssettings.php:272
+#: actions/emailsettings.php:293 actions/othersettings.php:173
+#: actions/emailsettings.php:301 actions/imsettings.php:264
+#: actions/othersettings.php:180 actions/smssettings.php:284
+msgid "Preferences saved."
msgstr ""
-#: actions/invite.php:41
-#, php-format
-msgid "You must be logged in to invite other users to use %s"
+#: ../actions/profilesettings.php:57 actions/profilesettings.php:90
+#: actions/profilesettings.php:129 actions/profilesettings.php:130
+#: actions/profilesettings.php:145
+msgid "Preferred language"
msgstr ""
-#: actions/invite.php:72
-#, php-format
-msgid "Invalid email address: %s"
+#: ../lib/util.php:328 lib/util.php:344 lib/action.php:572 lib/action.php:665
+#: lib/action.php:715 lib/action.php:730
+msgid "Privacy"
msgstr ""
-#: actions/invite.php:110
-msgid "Invitation(s) sent"
+#: ../classes/Notice.php:95 ../classes/Notice.php:106 classes/Notice.php:109
+#: classes/Notice.php:119 classes/Notice.php:145 classes/Notice.php:155
+#: classes/Notice.php:178 classes/Notice.php:188 classes/Notice.php:206
+#: classes/Notice.php:216 classes/Notice.php:232 classes/Notice.php:268
+#: classes/Notice.php:293
+msgid "Problem saving notice."
msgstr ""
-#: actions/invite.php:112
-msgid "Invite new users"
+#: ../lib/settingsaction.php:84 ../lib/stream.php:60 lib/personal.php:60
+#: lib/settingsaction.php:84 lib/accountsettingsaction.php:104
+#: lib/personalgroupnav.php:108 lib/personalgroupnav.php:109
+#: lib/accountsettingsaction.php:108
+msgid "Profile"
msgstr ""
-#: actions/invite.php:128
-msgid "You are already subscribed to these users:"
+#: ../actions/remotesubscribe.php:73 actions/remotesubscribe.php:82
+#: actions/remotesubscribe.php:109 actions/remotesubscribe.php:133
+msgid "Profile URL"
msgstr ""
-#: actions/invite.php:131 actions/invite.php:139
-#, php-format
-msgid "%s (%s)"
+#: ../actions/profilesettings.php:34 actions/profilesettings.php:32
+#: actions/profilesettings.php:58 actions/profilesettings.php:60
+msgid "Profile settings"
msgstr ""
-#: actions/invite.php:136
-msgid "These are already users and you were automatically subscribed to them:"
+#: ../actions/postnotice.php:51 ../actions/updateprofile.php:52
+#: actions/postnotice.php:52 actions/updateprofile.php:53
+#: actions/postnotice.php:55 actions/updateprofile.php:56
+#: actions/updateprofile.php:58
+msgid "Profile unknown"
msgstr ""
-#: actions/invite.php:144
-msgid "Invitation(s) sent to the following e-mail addresses:"
+#: ../actions/public.php:54 actions/public.php:54 actions/public.php:124
+msgid "Public Stream Feed"
msgstr ""
-#: actions/invite.php:150
-msgid ""
-"You will be notified when your invitees accept the invitation and register "
-"on the site. Thanks for growing the community!"
+#: ../actions/public.php:33 actions/public.php:33 actions/public.php:109
+#: lib/publicgroupnav.php:77 actions/public.php:112 lib/publicgroupnav.php:79
+#: actions/public.php:120 actions/public.php:131
+msgid "Public timeline"
msgstr ""
-#: actions/invite.php:162
-msgid ""
-"Use this form to invite your friends and colleagues to use this service."
+#: ../actions/imsettings.php:79 actions/imsettings.php:80
+#: actions/imsettings.php:153 actions/imsettings.php:159
+msgid "Publish a MicroID for my Jabber/GTalk address."
msgstr ""
-#: actions/invite.php:187
-msgid "Email addresses"
+#: ../actions/emailsettings.php:94 actions/emailsettings.php:101
+#: actions/emailsettings.php:178 actions/emailsettings.php:183
+#: actions/emailsettings.php:191
+msgid "Publish a MicroID for my email address."
msgstr ""
-#: actions/invite.php:189
-msgid "Addresses of friends to invite (one per line)"
+#: ../actions/tag.php:75 ../actions/tag.php:76 actions/tag.php:75
+#: actions/tag.php:76
+msgid "Recent Tags"
msgstr ""
-#: actions/invite.php:192
-msgid "Personal message"
+#: ../actions/recoverpassword.php:166 actions/recoverpassword.php:171
+#: actions/recoverpassword.php:190 actions/recoverpassword.php:197
+#: actions/recoverpassword.php:199 actions/recoverpassword.php:200
+msgid "Recover"
msgstr ""
-#: actions/invite.php:194
-msgid "Optionally add a personal message to the invitation."
+#: ../actions/recoverpassword.php:156 actions/recoverpassword.php:161
+#: actions/recoverpassword.php:198 actions/recoverpassword.php:206
+#: actions/recoverpassword.php:209
+msgid "Recover password"
msgstr ""
-#: actions/invite.php:197 lib/messageform.php:181 lib/noticeform.php:208
-msgid "Send"
+#: ../actions/recoverpassword.php:67 actions/recoverpassword.php:67
+#: actions/recoverpassword.php:73
+msgid "Recovery code for unknown user."
msgstr ""
-#: actions/invite.php:226
-#, php-format
-msgid "%1$s has invited you to join them on %2$s"
+#: ../actions/register.php:142 ../actions/register.php:193 ../lib/util.php:312
+#: actions/register.php:152 actions/register.php:207 lib/util.php:328
+#: actions/register.php:69 actions/register.php:436 lib/action.php:338
+#: lib/facebookaction.php:277 lib/logingroupnav.php:78
+#: actions/register.php:438 lib/action.php:415 lib/facebookaction.php:279
+#: actions/register.php:108 actions/register.php:486 lib/action.php:440
+#: lib/facebookaction.php:281 actions/register.php:496 lib/action.php:450
+#: lib/logingroupnav.php:85 actions/register.php:114 actions/register.php:502
+msgid "Register"
msgstr ""
-#: actions/invite.php:228
-#, php-format
-msgid ""
-"%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 those "
-"you know and those who interest you.\n"
-"\n"
-"You can also share news about yourself, your thoughts, or your life online "
-"with users who know about you. It is also great for meeting others who share "
-"your interests.\n"
-"\n"
-"%1$s said:\n"
-"\n"
-"%4$s\n"
-"\n"
-"You can see %1$s's profile page on %2$s here:\n"
-"\n"
-"%5$s\n"
-"\n"
-"If you'd like to try the service, click on the link below to accept the "
-"invitation.\n"
-"\n"
-"%6$s\n"
-"\n"
-"If not, you can ignore this message. Thanks for your patience and your "
-"time.\n"
-"\n"
-"Sincerely, %2$s\n"
+#: ../actions/register.php:28 actions/register.php:28
+#: actions/finishopenidlogin.php:196 actions/register.php:90
+#: actions/finishopenidlogin.php:195 actions/finishopenidlogin.php:204
+#: actions/register.php:129 actions/register.php:135
+msgid "Registration not allowed."
msgstr ""
-#: actions/joingroup.php:60
-msgid "You must be logged in to join a group."
+#: ../actions/register.php:200 actions/register.php:214
+#: actions/register.php:67 actions/register.php:106 actions/register.php:112
+msgid "Registration successful"
msgstr ""
-#: actions/joingroup.php:90 lib/command.php:217
-msgid "You are already a member of that group"
+#: ../actions/userauthorization.php:120 actions/userauthorization.php:127
+#: actions/userauthorization.php:144 actions/userauthorization.php:179
+#: actions/userauthorization.php:211
+msgid "Reject"
msgstr ""
-#: actions/joingroup.php:128 lib/command.php:234
-#, php-format
-msgid "Could not join user %s to group %s"
+#: ../actions/login.php:103 ../actions/register.php:176 actions/login.php:103
+#: actions/register.php:190 actions/login.php:234 actions/openidlogin.php:107
+#: actions/register.php:414 actions/login.php:217 actions/openidlogin.php:116
+#: actions/register.php:461 actions/login.php:225 actions/register.php:471
+#: actions/login.php:252 actions/register.php:477
+msgid "Remember me"
msgstr ""
-#: actions/joingroup.php:135 lib/command.php:239
-#, php-format
-msgid "%s joined group %s"
+#: ../actions/updateprofile.php:70 actions/updateprofile.php:71
+#: actions/updateprofile.php:74 actions/updateprofile.php:76
+msgid "Remote profile with no matching profile"
msgstr ""
-#: actions/leavegroup.php:60
-msgid "You must be logged in to leave a group."
+#: ../actions/remotesubscribe.php:65 actions/remotesubscribe.php:73
+#: actions/remotesubscribe.php:88 actions/remotesubscribe.php:112
+msgid "Remote subscribe"
msgstr ""
-#: actions/leavegroup.php:90 lib/command.php:268
-msgid "You are not a member of that group."
+#: ../actions/emailsettings.php:47 ../actions/emailsettings.php:75
+#: ../actions/imsettings.php:48 ../actions/openidsettings.php:106
+#: ../actions/smssettings.php:50 ../actions/smssettings.php:84
+#: actions/emailsettings.php:48 actions/emailsettings.php:76
+#: actions/imsettings.php:49 actions/openidsettings.php:108
+#: actions/smssettings.php:50 actions/smssettings.php:84
+#: actions/twittersettings.php:59 actions/emailsettings.php:101
+#: actions/emailsettings.php:134 actions/imsettings.php:102
+#: actions/openidsettings.php:166 actions/smssettings.php:103
+#: actions/smssettings.php:146 actions/twittersettings.php:115
+#: actions/twittersettings.php:118 actions/emailsettings.php:107
+#: actions/emailsettings.php:140 actions/imsettings.php:108
+#: actions/smssettings.php:115 actions/smssettings.php:158
+msgid "Remove"
msgstr ""
-#: actions/leavegroup.php:119 lib/command.php:278
-msgid "Could not find membership record."
+#: ../actions/openidsettings.php:68 actions/openidsettings.php:69
+#: actions/openidsettings.php:123
+msgid "Remove OpenID"
msgstr ""
-#: actions/leavegroup.php:127 lib/command.php:284
-#, php-format
-msgid "Could not remove user %s to group %s"
+#: ../actions/openidsettings.php:73 actions/openidsettings.php:128
+msgid ""
+"Removing your only OpenID would make it impossible to log in! If you need to "
+"remove it, add another OpenID first."
msgstr ""
-#: actions/leavegroup.php:134 lib/command.php:289
+#: ../lib/stream.php:55 lib/personal.php:55 lib/personalgroupnav.php:103
+#: lib/personalgroupnav.php:104
+msgid "Replies"
+msgstr ""
+
+#: ../actions/replies.php:47 ../actions/repliesrss.php:76 ../lib/stream.php:56
+#: actions/replies.php:47 actions/repliesrss.php:62 lib/personal.php:56
+#: actions/replies.php:116 actions/repliesrss.php:67
+#: lib/personalgroupnav.php:104 actions/replies.php:118
+#: actions/replies.php:117 lib/personalgroupnav.php:105
+#: actions/replies.php:125 actions/repliesrss.php:68
#, php-format
-msgid "%s left group %s"
+msgid "Replies to %s"
msgstr ""
-#: actions/login.php:79 actions/register.php:137
-msgid "Already logged in."
+#: ../actions/recoverpassword.php:183 actions/recoverpassword.php:189
+#: actions/recoverpassword.php:223 actions/recoverpassword.php:240
+#: actions/recoverpassword.php:243
+msgid "Reset"
msgstr ""
-#: actions/login.php:110 actions/login.php:120
-msgid "Invalid or expired token."
+#: ../actions/recoverpassword.php:173 actions/recoverpassword.php:178
+#: actions/recoverpassword.php:197 actions/recoverpassword.php:205
+#: actions/recoverpassword.php:208
+msgid "Reset password"
msgstr ""
-#: actions/login.php:143
-msgid "Incorrect username or password."
+#: ../lib/settingsaction.php:99 lib/settingsaction.php:93
+#: actions/subscriptions.php:123 lib/connectsettingsaction.php:107
+#: actions/subscriptions.php:125 actions/subscriptions.php:184
+#: actions/subscriptions.php:199 lib/connectsettingsaction.php:115
+msgid "SMS"
msgstr ""
-#: actions/login.php:149 actions/recoverpassword.php:375
-#: actions/register.php:248
-msgid "Error setting user."
+#: ../actions/smssettings.php:67 actions/smssettings.php:67
+#: actions/smssettings.php:126 actions/smssettings.php:138
+msgid "SMS Phone number"
msgstr ""
-#: actions/login.php:204 actions/login.php:257 lib/action.php:453
-#: lib/logingroupnav.php:79
-msgid "Login"
+#: ../actions/smssettings.php:33 actions/smssettings.php:33
+#: actions/smssettings.php:58
+msgid "SMS Settings"
msgstr ""
-#: actions/login.php:243
-msgid "Login to site"
+#: ../lib/mail.php:219 lib/mail.php:225 lib/mail.php:437 lib/mail.php:438
+msgid "SMS confirmation"
msgstr ""
-#: actions/login.php:246 actions/profilesettings.php:106
-#: actions/register.php:423 actions/showgroup.php:236 actions/tagother.php:94
-#: lib/groupeditform.php:152 lib/userprofile.php:131
-msgid "Nickname"
+#: ../actions/recoverpassword.php:182 actions/recoverpassword.php:188
+#: actions/recoverpassword.php:222 actions/recoverpassword.php:237
+#: actions/recoverpassword.php:240
+msgid "Same as password above"
msgstr ""
-#: actions/login.php:249 actions/register.php:428
-#: lib/accountsettingsaction.php:114
-msgid "Password"
+#: ../actions/register.php:156 actions/register.php:170
+#: actions/register.php:377 actions/register.php:423 actions/register.php:427
+#: actions/register.php:433
+msgid "Same as password above. Required."
msgstr ""
-#: actions/login.php:252 actions/register.php:477
-msgid "Remember me"
+#: ../actions/emailsettings.php:97 ../actions/imsettings.php:81
+#: ../actions/profilesettings.php:67 ../actions/smssettings.php:100
+#: actions/emailsettings.php:104 actions/imsettings.php:82
+#: actions/profilesettings.php:101 actions/smssettings.php:100
+#: actions/twittersettings.php:83 actions/emailsettings.php:182
+#: actions/facebooksettings.php:114 actions/imsettings.php:157
+#: actions/othersettings.php:117 actions/profilesettings.php:150
+#: actions/smssettings.php:169 actions/subscriptions.php:124
+#: actions/tagother.php:152 actions/twittersettings.php:161
+#: lib/groupeditform.php:171 actions/emailsettings.php:187
+#: actions/subscriptions.php:126 actions/tagother.php:154
+#: actions/twittersettings.php:164 actions/othersettings.php:119
+#: actions/profilesettings.php:152 actions/subscriptions.php:185
+#: actions/twittersettings.php:180 lib/designsettings.php:256
+#: lib/groupeditform.php:196 actions/emailsettings.php:195
+#: actions/imsettings.php:163 actions/othersettings.php:126
+#: actions/profilesettings.php:167 actions/smssettings.php:181
+#: actions/subscriptions.php:203 lib/groupeditform.php:202
+msgid "Save"
msgstr ""
-#: actions/login.php:253 actions/register.php:479
-msgid "Automatically login in the future; not for shared computers!"
+#: ../lib/searchaction.php:84 ../lib/util.php:300 lib/searchaction.php:84
+#: lib/util.php:316 lib/action.php:325 lib/action.php:396 lib/action.php:448
+#: lib/action.php:459
+msgid "Search"
msgstr ""
-#: actions/login.php:263
-msgid "Lost or forgotten password?"
+#: ../actions/noticesearch.php:80 actions/noticesearch.php:85
+#: actions/noticesearch.php:127
+msgid "Search Stream Feed"
msgstr ""
-#: actions/login.php:282
+#: ../actions/noticesearch.php:30 actions/noticesearch.php:30
+#: actions/noticesearch.php:57 actions/noticesearch.php:68
+#, php-format
msgid ""
-"For security reasons, please re-enter your user name and password before "
-"changing your settings."
+"Search for notices on %%site.name%% by their contents. Separate search terms "
+"by spaces; they must be 3 characters or more."
msgstr ""
-#: actions/login.php:286
+#: ../actions/peoplesearch.php:28 actions/peoplesearch.php:52
#, php-format
msgid ""
-"Login with your username and password. Don't have a username yet? [Register]"
-"(%%action.register%%) a new account."
+"Search for people on %%site.name%% by their name, location, or interests. "
+"Separate the terms by spaces; they must be 3 characters or more."
msgstr ""
-#: actions/makeadmin.php:91
-msgid "Only an admin can make another user an admin."
+#: ../actions/smssettings.php:296 actions/smssettings.php:304
+#: actions/smssettings.php:457 actions/smssettings.php:469
+msgid "Select a carrier"
msgstr ""
-#: actions/makeadmin.php:95
-#, php-format
-msgid "%s is already an admin for group \"%s\"."
+#: ../actions/invite.php:137 ../lib/util.php:1172 actions/invite.php:145
+#: lib/util.php:1306 lib/util.php:1731 actions/invite.php:182
+#: lib/messageform.php:167 lib/noticeform.php:177 actions/invite.php:189
+#: lib/messageform.php:165 actions/invite.php:191 lib/messageform.php:157
+#: lib/noticeform.php:179 actions/invite.php:197 lib/messageform.php:181
+#: lib/noticeform.php:208
+msgid "Send"
msgstr ""
-#: actions/makeadmin.php:132
-#, php-format
-msgid "Can't get membership record for %s in group %s"
+#: ../actions/emailsettings.php:73 ../actions/smssettings.php:82
+#: actions/emailsettings.php:74 actions/smssettings.php:82
+#: actions/emailsettings.php:132 actions/smssettings.php:145
+#: actions/emailsettings.php:138 actions/smssettings.php:157
+msgid "Send email to this address to post new notices."
msgstr ""
-#: actions/makeadmin.php:145
-#, php-format
-msgid "Can't make %s an admin for group %s"
+#: ../actions/emailsettings.php:88 actions/emailsettings.php:89
+#: actions/emailsettings.php:152 actions/emailsettings.php:158
+msgid "Send me notices of new subscriptions through email."
msgstr ""
-#: actions/microsummary.php:62 actions/newmessage.php:116
-#: actions/remotesubscribe.php:154
-msgid "No such user"
+#: ../actions/imsettings.php:70 actions/imsettings.php:71
+#: actions/imsettings.php:137 actions/imsettings.php:143
+msgid "Send me notices through Jabber/GTalk."
msgstr ""
-#: actions/microsummary.php:69
-msgid "No current status"
+#: ../actions/smssettings.php:97 actions/smssettings.php:97
+#: actions/smssettings.php:162 actions/smssettings.php:174
+msgid ""
+"Send me notices through SMS; I understand I may incur exorbitant charges "
+"from my carrier."
msgstr ""
-#: actions/newgroup.php:53
-msgid "New group"
+#: ../actions/imsettings.php:76 actions/imsettings.php:77
+#: actions/imsettings.php:147 actions/imsettings.php:153
+msgid "Send me replies through Jabber/GTalk from people I'm not subscribed to."
msgstr ""
-#: actions/newgroup.php:110
-msgid "Use this form to create a new group."
+#: ../lib/util.php:304 lib/util.php:320 lib/facebookaction.php:215
+#: lib/facebookaction.php:228 lib/facebookaction.php:230
+msgid "Settings"
msgstr ""
-#: actions/newmessage.php:71 actions/newmessage.php:231
-msgid "New message"
+#: ../actions/profilesettings.php:192 actions/profilesettings.php:307
+#: actions/profilesettings.php:319 actions/profilesettings.php:318
+#: actions/profilesettings.php:344
+msgid "Settings saved."
msgstr ""
-#: actions/newmessage.php:121 actions/newmessage.php:161 lib/command.php:367
-msgid "You can't send a message to this user."
+#: ../actions/tag.php:60 actions/tag.php:60
+msgid "Showing most popular tags from the last week"
msgstr ""
-#: actions/newmessage.php:144 actions/newnotice.php:136 lib/command.php:351
-#: lib/command.php:424
-msgid "No content!"
+#: ../actions/finishaddopenid.php:66 actions/finishaddopenid.php:66
+#: actions/finishaddopenid.php:114
+msgid "Someone else already has this OpenID."
msgstr ""
-#: actions/newmessage.php:158
-msgid "No recipient specified."
+#: ../actions/finishopenidlogin.php:42 ../actions/openidsettings.php:126
+#: actions/finishopenidlogin.php:47 actions/openidsettings.php:135
+#: actions/finishopenidlogin.php:52 actions/openidsettings.php:202
+msgid "Something weird happened."
msgstr ""
-#: actions/newmessage.php:164 lib/command.php:370
-msgid ""
-"Don't send a message to yourself; just say it to yourself quietly instead."
+#: ../scripts/maildaemon.php:58 scripts/maildaemon.php:58
+#: scripts/maildaemon.php:61 scripts/maildaemon.php:60
+msgid "Sorry, no incoming email allowed."
msgstr ""
-#: actions/newmessage.php:181
-msgid "Message sent"
+#: ../scripts/maildaemon.php:54 scripts/maildaemon.php:54
+#: scripts/maildaemon.php:57 scripts/maildaemon.php:56
+msgid "Sorry, that is not your incoming email address."
msgstr ""
-#: actions/newmessage.php:185 lib/command.php:375
-#, php-format
-msgid "Direct message to %s sent"
+#: ../lib/util.php:330 lib/util.php:346 lib/action.php:574 lib/action.php:667
+#: lib/action.php:717 lib/action.php:732
+msgid "Source"
msgstr ""
-#: actions/newmessage.php:210 actions/newnotice.php:233 lib/channel.php:170
-msgid "Ajax Error"
+#: ../actions/showstream.php:296 actions/showstream.php:311
+#: actions/showstream.php:476 actions/showgroup.php:375
+#: actions/showgroup.php:421 lib/profileaction.php:173
+#: actions/showgroup.php:429
+msgid "Statistics"
msgstr ""
-#: actions/newnotice.php:69
-msgid "New notice"
+#: ../actions/finishopenidlogin.php:182 ../actions/finishopenidlogin.php:246
+#: actions/finishopenidlogin.php:188 actions/finishopenidlogin.php:252
+#: actions/finishopenidlogin.php:222 actions/finishopenidlogin.php:290
+#: actions/finishopenidlogin.php:295 actions/finishopenidlogin.php:238
+#: actions/finishopenidlogin.php:318
+msgid "Stored OpenID not found."
msgstr ""
-#: actions/newnotice.php:199
-msgid "Notice posted"
+#: ../actions/remotesubscribe.php:75 ../actions/showstream.php:188
+#: ../actions/showstream.php:197 actions/remotesubscribe.php:84
+#: actions/showstream.php:197 actions/showstream.php:206
+#: actions/remotesubscribe.php:113 actions/showstream.php:376
+#: lib/subscribeform.php:139 actions/showstream.php:345
+#: actions/remotesubscribe.php:137 actions/showstream.php:439
+#: lib/userprofile.php:321
+msgid "Subscribe"
msgstr ""
-#: actions/noticesearch.php:68
-#, php-format
-msgid ""
-"Search for notices on %%site.name%% by their contents. Separate search terms "
-"by spaces; they must be 3 characters or more."
+#: ../actions/showstream.php:313 ../actions/subscribers.php:27
+#: actions/showstream.php:328 actions/subscribers.php:27
+#: actions/showstream.php:436 actions/showstream.php:498
+#: lib/subgroupnav.php:88 lib/profileaction.php:140 lib/profileaction.php:200
+#: lib/subgroupnav.php:90
+msgid "Subscribers"
msgstr ""
-#: actions/noticesearch.php:78
-msgid "Text search"
+#: ../actions/userauthorization.php:310 actions/userauthorization.php:322
+#: actions/userauthorization.php:338 actions/userauthorization.php:344
+#: actions/userauthorization.php:378 actions/userauthorization.php:247
+msgid "Subscription authorized"
msgstr ""
-#: actions/noticesearch.php:91
-#, php-format
-msgid "Search results for \"%s\" on %s"
+#: ../actions/userauthorization.php:320 actions/userauthorization.php:332
+#: actions/userauthorization.php:349 actions/userauthorization.php:355
+#: actions/userauthorization.php:389 actions/userauthorization.php:259
+msgid "Subscription rejected"
msgstr ""
-#: actions/noticesearch.php:121
-#, php-format
-msgid ""
-"Be the first to [post on this topic](%%%%action.newnotice%%%%?"
-"status_textarea=%s)!"
+#: ../actions/showstream.php:230 ../actions/showstream.php:307
+#: ../actions/subscriptions.php:27 actions/showstream.php:240
+#: actions/showstream.php:322 actions/subscriptions.php:27
+#: actions/showstream.php:407 actions/showstream.php:489
+#: lib/subgroupnav.php:80 lib/profileaction.php:109 lib/profileaction.php:191
+#: lib/subgroupnav.php:82
+msgid "Subscriptions"
msgstr ""
-#: actions/noticesearch.php:124
-#, php-format
-msgid ""
-"Why not [register an account](%%%%action.register%%%%) and be the first to "
-"[post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!"
+#: ../actions/avatar.php:87 actions/profilesettings.php:324
+#: lib/imagefile.php:78 lib/imagefile.php:82 lib/imagefile.php:83
+#: lib/imagefile.php:88 lib/mediafile.php:170
+msgid "System error uploading file."
msgstr ""
-#: actions/noticesearchrss.php:89
-#, php-format
-msgid "Updates with \"%s\""
+#: ../actions/tag.php:41 ../lib/util.php:301 actions/tag.php:41
+#: lib/util.php:317 actions/profilesettings.php:122 actions/showstream.php:297
+#: actions/tagother.php:147 actions/tagother.php:207 lib/profilelist.php:162
+#: lib/profilelist.php:164 actions/showstream.php:290 actions/tagother.php:149
+#: actions/tagother.php:209 lib/profilelist.php:160
+#: actions/profilesettings.php:123 actions/showstream.php:255
+#: lib/subscriptionlist.php:106 lib/subscriptionlist.php:108
+#: actions/profilesettings.php:138 actions/showstream.php:327
+#: lib/userprofile.php:209
+msgid "Tags"
msgstr ""
-#: actions/noticesearchrss.php:91
-#, php-format
-msgid "Updates matching search term \"%1$s\" on %2$s!"
+#: ../lib/searchaction.php:104 lib/searchaction.php:104
+#: lib/designsettings.php:217
+msgid "Text"
msgstr ""
-#: actions/nudge.php:85
-msgid ""
-"This user doesn't allow nudges or hasn't confirmed or set his email yet."
+#: ../actions/noticesearch.php:34 actions/noticesearch.php:34
+#: actions/noticesearch.php:67 actions/noticesearch.php:78
+msgid "Text search"
msgstr ""
-#: actions/nudge.php:94
-msgid "Nudge sent"
+#: ../actions/openidsettings.php:140 actions/openidsettings.php:149
+#: actions/openidsettings.php:227
+msgid "That OpenID does not belong to you."
msgstr ""
-#: actions/nudge.php:97
-msgid "Nudge sent!"
+#: ../actions/confirmaddress.php:52 actions/confirmaddress.php:52
+#: actions/confirmaddress.php:94
+msgid "That address has already been confirmed."
msgstr ""
-#: actions/oembed.php:79 actions/shownotice.php:100
-msgid "Notice has no profile"
+#: ../actions/confirmaddress.php:43 actions/confirmaddress.php:43
+#: actions/confirmaddress.php:85
+msgid "That confirmation code is not for you!"
msgstr ""
-#: actions/oembed.php:86 actions/shownotice.php:180
-#, php-format
-msgid "%1$s's status on %2$s"
+#: ../actions/emailsettings.php:191 actions/emailsettings.php:209
+#: actions/emailsettings.php:328 actions/emailsettings.php:336
+msgid "That email address already belongs to another user."
msgstr ""
-#: actions/oembed.php:157
-msgid "content type "
+#: ../actions/avatar.php:80 actions/profilesettings.php:317
+#: lib/imagefile.php:71
+msgid "That file is too big."
msgstr ""
-#: actions/oembed.php:160
-msgid "Only "
+#: ../actions/imsettings.php:170 actions/imsettings.php:178
+#: actions/imsettings.php:293 actions/imsettings.php:299
+msgid "That is already your Jabber ID."
msgstr ""
-#: actions/oembed.php:181 actions/oembed.php:200 lib/api.php:963
-#: lib/api.php:991 lib/api.php:1101
-msgid "Not a supported data format."
+#: ../actions/emailsettings.php:188 actions/emailsettings.php:206
+#: actions/emailsettings.php:318 actions/emailsettings.php:325
+#: actions/emailsettings.php:333
+msgid "That is already your email address."
msgstr ""
-#: actions/opensearch.php:64
-msgid "User Search"
+#: ../actions/smssettings.php:188 actions/smssettings.php:196
+#: actions/smssettings.php:306 actions/smssettings.php:318
+msgid "That is already your phone number."
msgstr ""
-#: actions/opensearch.php:67
-msgid "Notice Search"
+#: ../actions/imsettings.php:233 actions/imsettings.php:241
+#: actions/imsettings.php:381 actions/imsettings.php:387
+msgid "That is not your Jabber ID."
msgstr ""
-#: actions/othersettings.php:60
-msgid "Other Settings"
+#: ../actions/emailsettings.php:249 actions/emailsettings.php:267
+#: actions/emailsettings.php:397 actions/emailsettings.php:404
+#: actions/emailsettings.php:412
+msgid "That is not your email address."
msgstr ""
-#: actions/othersettings.php:71
-msgid "Manage various other options."
+#: ../actions/smssettings.php:257 actions/smssettings.php:265
+#: actions/smssettings.php:393 actions/smssettings.php:405
+msgid "That is not your phone number."
msgstr ""
-#: actions/othersettings.php:117
-msgid "Shorten URLs with"
+#: ../actions/emailsettings.php:226 ../actions/imsettings.php:210
+#: actions/emailsettings.php:244 actions/imsettings.php:218
+#: actions/emailsettings.php:367 actions/imsettings.php:349
+#: actions/emailsettings.php:374 actions/emailsettings.php:382
+#: actions/imsettings.php:355
+msgid "That is the wrong IM address."
msgstr ""
-#: actions/othersettings.php:118
-msgid "Automatic shortening service to use."
+#: ../actions/smssettings.php:233 actions/smssettings.php:241
+#: actions/smssettings.php:362 actions/smssettings.php:374
+msgid "That is the wrong confirmation number."
msgstr ""
-#: actions/othersettings.php:122
-msgid "View profile designs"
+#: ../actions/smssettings.php:191 actions/smssettings.php:199
+#: actions/smssettings.php:309 actions/smssettings.php:321
+msgid "That phone number already belongs to another user."
msgstr ""
-#: actions/othersettings.php:123
-msgid "Show or hide profile designs."
+#: ../actions/newnotice.php:49 ../actions/twitapistatuses.php:408
+#: actions/newnotice.php:49 actions/twitapistatuses.php:330
+#: actions/facebookhome.php:243 actions/twitapistatuses.php:276
+#: actions/newnotice.php:136 actions/twitapistatuses.php:294
+#: lib/facebookaction.php:485 actions/newnotice.php:166
+#: actions/twitapistatuses.php:251 lib/facebookaction.php:477
+#: scripts/maildaemon.php:70
+msgid "That's too long. Max notice size is 140 chars."
msgstr ""
-#: actions/othersettings.php:153
-msgid "URL shortening service is too long (max 50 chars)."
+#: ../actions/twitapiaccount.php:74 actions/twitapiaccount.php:72
+#: actions/twitapiaccount.php:62 actions/twitapiaccount.php:63
+#: actions/twitapiaccount.php:66
+msgid "That's too long. Max notice size is 255 chars."
msgstr ""
-#: actions/outbox.php:58
+#: ../actions/confirmaddress.php:92 actions/confirmaddress.php:92
+#: actions/confirmaddress.php:159
#, php-format
-msgid "Outbox for %s - page %d"
+msgid "The address \"%s\" has been confirmed for your account."
msgstr ""
-#: actions/outbox.php:61
-#, php-format
-msgid "Outbox for %s"
+#: ../actions/emailsettings.php:264 ../actions/imsettings.php:250
+#: ../actions/smssettings.php:274 actions/emailsettings.php:282
+#: actions/imsettings.php:258 actions/smssettings.php:282
+#: actions/emailsettings.php:416 actions/imsettings.php:402
+#: actions/smssettings.php:413 actions/emailsettings.php:423
+#: actions/emailsettings.php:431 actions/imsettings.php:408
+#: actions/smssettings.php:425
+msgid "The address was removed."
msgstr ""
-#: actions/outbox.php:116
-msgid "This is your outbox, which lists private messages you have sent."
+#: ../actions/userauthorization.php:312 actions/userauthorization.php:346
+#: actions/userauthorization.php:380
+msgid ""
+"The subscription has been authorized, but no callback URL was passed. Check "
+"with the site's instructions for details on how to authorize the "
+"subscription. Your subscription token is:"
msgstr ""
-#: actions/passwordsettings.php:58
-msgid "Change password"
+#: ../actions/userauthorization.php:322 actions/userauthorization.php:357
+#: actions/userauthorization.php:391
+msgid ""
+"The subscription has been rejected, but no callback URL was passed. Check "
+"with the site's instructions for details on how to fully reject the "
+"subscription."
msgstr ""
-#: actions/passwordsettings.php:69
-msgid "Change your password."
+#: ../actions/subscribers.php:35 actions/subscribers.php:35
+#: actions/subscribers.php:67
+#, php-format
+msgid "These are the people who listen to %s's notices."
msgstr ""
-#: actions/passwordsettings.php:95 actions/recoverpassword.php:231
-msgid "Password change"
+#: ../actions/subscribers.php:33 actions/subscribers.php:33
+#: actions/subscribers.php:63
+msgid "These are the people who listen to your notices."
msgstr ""
-#: actions/passwordsettings.php:103
-msgid "Old password"
+#: ../actions/subscriptions.php:35 actions/subscriptions.php:35
+#: actions/subscriptions.php:69
+#, php-format
+msgid "These are the people whose notices %s listens to."
msgstr ""
-#: actions/passwordsettings.php:107 actions/recoverpassword.php:235
-msgid "New password"
+#: ../actions/subscriptions.php:33 actions/subscriptions.php:33
+#: actions/subscriptions.php:65
+msgid "These are the people whose notices you listen to."
msgstr ""
-#: actions/passwordsettings.php:108
-msgid "6 or more characters"
+#: ../actions/invite.php:89 actions/invite.php:96 actions/invite.php:128
+#: actions/invite.php:130 actions/invite.php:136
+msgid ""
+"These people are already users and you were automatically subscribed to them:"
msgstr ""
-#: actions/passwordsettings.php:111 actions/recoverpassword.php:239
-#: actions/register.php:432 actions/smssettings.php:134
-msgid "Confirm"
+#: ../actions/recoverpassword.php:88 actions/recoverpassword.php:97
+msgid "This confirmation code is too old. Please start again."
msgstr ""
-#: actions/passwordsettings.php:112
-msgid "same as password above"
+#: ../lib/openid.php:195 lib/openid.php:206
+msgid ""
+"This form should automatically submit itself. If not, click the submit "
+"button to go to your OpenID provider."
msgstr ""
-#: actions/passwordsettings.php:116
-msgid "Change"
+#: ../actions/finishopenidlogin.php:56 actions/finishopenidlogin.php:61
+#: actions/finishopenidlogin.php:67 actions/finishopenidlogin.php:66
+#, php-format
+msgid ""
+"This is the first time you've logged into %s so we must connect your OpenID "
+"to a local account. You can either create a new account, or connect with "
+"your existing account, if you have one."
+msgstr ""
+
+#: ../actions/twitapifriendships.php:108 ../actions/twitapistatuses.php:586
+#: actions/twitapifavorites.php:127 actions/twitapifriendships.php:108
+#: actions/twitapistatuses.php:511 actions/twitapifavorites.php:97
+#: actions/twitapifriendships.php:85 actions/twitapistatuses.php:436
+#: actions/twitapifavorites.php:103 actions/twitapistatuses.php:460
+#: actions/twitapifavorites.php:154 actions/twitapifriendships.php:90
+#: actions/twitapistatuses.php:416 actions/apistatusesdestroy.php:107
+msgid "This method requires a POST or DELETE."
msgstr ""
-#: actions/passwordsettings.php:153 actions/register.php:230
-msgid "Password must be 6 or more characters."
+#: ../actions/twitapiaccount.php:65 ../actions/twitapifriendships.php:44
+#: ../actions/twitapistatuses.php:381 actions/twitapiaccount.php:63
+#: actions/twitapidirect_messages.php:114 actions/twitapifriendships.php:44
+#: actions/twitapistatuses.php:303 actions/twitapiaccount.php:53
+#: actions/twitapidirect_messages.php:122 actions/twitapifriendships.php:32
+#: actions/twitapistatuses.php:244 actions/twitapiaccount.php:54
+#: actions/twitapidirect_messages.php:131 actions/twitapistatuses.php:262
+#: actions/twitapiaccount.php:56 actions/twitapidirect_messages.php:124
+#: actions/twitapifriendships.php:34 actions/twitapistatuses.php:216
+#: actions/apiblockcreate.php:89 actions/apiblockdestroy.php:88
+#: actions/apidirectmessagenew.php:117 actions/apifavoritecreate.php:90
+#: actions/apifavoritedestroy.php:91 actions/apifriendshipscreate.php:91
+#: actions/apifriendshipsdestroy.php:91 actions/apigroupcreate.php:104
+#: actions/apigroupjoin.php:91 actions/apigroupleave.php:91
+#: actions/apistatusesupdate.php:109
+#: actions/apiaccountupdateprofileimage.php:84
+msgid "This method requires a POST."
msgstr ""
-#: actions/passwordsettings.php:156 actions/register.php:233
-msgid "Passwords don't match."
+#: ../lib/util.php:164 lib/util.php:246 lib/htmloutputter.php:104
+msgid "This page is not available in a media type you accept"
msgstr ""
-#: actions/passwordsettings.php:164
-msgid "Incorrect old password"
+#: ../actions/profilesettings.php:63 actions/profilesettings.php:96
+#: actions/profilesettings.php:138 actions/profilesettings.php:139
+#: actions/profilesettings.php:154
+msgid "Timezone"
msgstr ""
-#: actions/passwordsettings.php:180
-msgid "Error saving user; invalid."
+#: ../actions/profilesettings.php:107 actions/profilesettings.php:222
+#: actions/profilesettings.php:211 actions/profilesettings.php:212
+#: actions/profilesettings.php:228
+msgid "Timezone not selected."
msgstr ""
-#: actions/passwordsettings.php:185 actions/recoverpassword.php:368
-msgid "Can't save new password."
+#: ../actions/remotesubscribe.php:43 actions/remotesubscribe.php:74
+#: actions/remotesubscribe.php:98
+#, php-format
+msgid ""
+"To subscribe, you can [login](%%action.login%%), or [register](%%action."
+"register%%) a new account. If you already have an account on a [compatible "
+"microblogging site](%%doc.openmublog%%), enter your profile URL below."
msgstr ""
-#: actions/passwordsettings.php:191 actions/recoverpassword.php:211
-msgid "Password saved."
+#: ../actions/twitapifriendships.php:163 actions/twitapifriendships.php:167
+#: actions/twitapifriendships.php:132 actions/twitapifriendships.php:139
+#: actions/apifriendshipsexists.php:103 actions/apifriendshipsexists.php:94
+msgid "Two user ids or screen_names must be supplied."
msgstr ""
-#: actions/peoplesearch.php:52
-#, php-format
-msgid ""
-"Search for users on %%site.name%% by their name, location, or interests. "
-"Separate the terms by spaces; they must be 3 characters or more."
+#: ../actions/profilesettings.php:48 ../actions/register.php:169
+#: actions/profilesettings.php:81 actions/register.php:183
+#: actions/profilesettings.php:109 actions/register.php:398
+#: actions/register.php:444 actions/profilesettings.php:117
+#: actions/register.php:448 actions/register.php:454
+msgid "URL of your homepage, blog, or profile on another site"
msgstr ""
-#: actions/peoplesearch.php:58
-msgid "People search"
+#: ../actions/remotesubscribe.php:74 actions/remotesubscribe.php:83
+#: actions/remotesubscribe.php:110 actions/remotesubscribe.php:134
+msgid "URL of your profile on another compatible microblogging service"
msgstr ""
-#: actions/peopletag.php:70
-#, php-format
-msgid "Not a valid user tag: %s"
+#: ../actions/emailsettings.php:130 ../actions/imsettings.php:110
+#: ../actions/recoverpassword.php:39 ../actions/smssettings.php:135
+#: actions/emailsettings.php:144 actions/imsettings.php:118
+#: actions/recoverpassword.php:39 actions/smssettings.php:143
+#: actions/twittersettings.php:108 actions/avatarsettings.php:258
+#: actions/emailsettings.php:242 actions/grouplogo.php:317
+#: actions/imsettings.php:214 actions/recoverpassword.php:44
+#: actions/smssettings.php:236 actions/twittersettings.php:302
+#: actions/avatarsettings.php:263 actions/emailsettings.php:247
+#: actions/grouplogo.php:324 actions/twittersettings.php:306
+#: actions/twittersettings.php:322 lib/designsettings.php:301
+#: actions/emailsettings.php:255 actions/grouplogo.php:319
+#: actions/imsettings.php:220 actions/smssettings.php:248
+#: actions/avatarsettings.php:277 lib/designsettings.php:304
+msgid "Unexpected form submission."
msgstr ""
-#: actions/peopletag.php:144
-#, php-format
-msgid "Users self-tagged with %s - page %d"
+#: ../actions/recoverpassword.php:276 actions/recoverpassword.php:289
+#: actions/recoverpassword.php:323 actions/recoverpassword.php:341
+#: actions/recoverpassword.php:344
+msgid "Unexpected password reset."
msgstr ""
-#: actions/postnotice.php:84
-msgid "Invalid notice content"
+#: ../index.php:57 index.php:57 actions/recoverpassword.php:202
+#: actions/recoverpassword.php:210 actions/recoverpassword.php:213
+msgid "Unknown action"
msgstr ""
-#: actions/postnotice.php:90
-#, php-format
-msgid "Notice license ‘%s’ is not compatible with site license ‘%s’."
+#: ../actions/finishremotesubscribe.php:58
+#: actions/finishremotesubscribe.php:60 actions/finishremotesubscribe.php:61
+msgid "Unknown version of OMB protocol."
msgstr ""
-#: actions/profilesettings.php:60
-msgid "Profile settings"
+#: ../lib/util.php:269 lib/util.php:285
+msgid ""
+"Unless otherwise specified, contents of this site are copyright by the "
+"contributors and available under the "
msgstr ""
-#: actions/profilesettings.php:71
-msgid ""
-"You can update your personal profile info here so readers know more about "
-"you."
+#: ../actions/confirmaddress.php:48 actions/confirmaddress.php:48
+#: actions/confirmaddress.php:90
+#, php-format
+msgid "Unrecognized address type %s"
msgstr ""
-#: actions/profilesettings.php:99
-msgid "Profile information"
+#: ../actions/showstream.php:209 actions/showstream.php:219
+#: lib/unsubscribeform.php:137
+msgid "Unsubscribe"
msgstr ""
-#: actions/profilesettings.php:108 lib/groupeditform.php:154
-msgid "1-64 lowercase letters or numbers, no punctuation or spaces"
+#: ../actions/postnotice.php:44 ../actions/updateprofile.php:45
+#: actions/postnotice.php:45 actions/updateprofile.php:46
+#: actions/postnotice.php:48 actions/updateprofile.php:49
+#: actions/updateprofile.php:51
+msgid "Unsupported OMB version"
msgstr ""
-#: actions/profilesettings.php:111 actions/register.php:447
-#: actions/showgroup.php:247 actions/tagother.php:104
-#: lib/groupeditform.php:157 lib/userprofile.php:149
-msgid "Full name"
+#: ../actions/avatar.php:105 actions/profilesettings.php:342
+#: lib/imagefile.php:102 lib/imagefile.php:99 lib/imagefile.php:100
+#: lib/imagefile.php:105
+msgid "Unsupported image file format."
msgstr ""
-#: actions/profilesettings.php:115 actions/register.php:452
-#: lib/groupeditform.php:161
-msgid "Homepage"
+#: ../lib/settingsaction.php:100 lib/settingsaction.php:94
+#: lib/connectsettingsaction.php:108 lib/connectsettingsaction.php:116
+msgid "Updates by SMS"
msgstr ""
-#: actions/profilesettings.php:117 actions/register.php:454
-msgid "URL of your homepage, blog, or profile on another site"
+#: ../lib/settingsaction.php:103 lib/settingsaction.php:97
+#: lib/connectsettingsaction.php:105 lib/connectsettingsaction.php:111
+msgid "Updates by instant messenger (IM)"
msgstr ""
-#: actions/profilesettings.php:122 actions/register.php:460
+#: ../actions/twitapistatuses.php:241 actions/twitapistatuses.php:158
+#: actions/twitapistatuses.php:129 actions/twitapistatuses.php:134
+#: actions/twitapistatuses.php:94 actions/allrss.php:119
+#: actions/apitimelinefriends.php:121
#, php-format
-msgid "Describe yourself and your interests in %d chars"
+msgid "Updates from %1$s and friends on %2$s!"
msgstr ""
-#: actions/profilesettings.php:125 actions/register.php:463
-msgid "Describe yourself and your interests"
+#: ../actions/twitapistatuses.php:341 actions/twitapistatuses.php:268
+#: actions/twitapistatuses.php:202 actions/twitapistatuses.php:213
+#: actions/twitapigroups.php:74 actions/twitapistatuses.php:159
+#: actions/apitimelinegroup.php:110 actions/apitimelineuser.php:125
+#: actions/userrss.php:92
+#, php-format
+msgid "Updates from %1$s on %2$s!"
msgstr ""
-#: actions/profilesettings.php:127 actions/register.php:465
-msgid "Bio"
+#: ../actions/avatar.php:68 actions/profilesettings.php:161
+#: actions/avatarsettings.php:162 actions/grouplogo.php:232
+#: actions/avatarsettings.php:165 actions/grouplogo.php:238
+#: actions/grouplogo.php:233
+msgid "Upload"
msgstr ""
-#: actions/profilesettings.php:132 actions/register.php:470
-#: actions/showgroup.php:256 actions/tagother.php:112
-#: actions/userauthorization.php:158 lib/groupeditform.php:177
-#: lib/userprofile.php:164
-msgid "Location"
+#: ../actions/avatar.php:27
+msgid ""
+"Upload a new \"avatar\" (user image) here. You can't edit the picture after "
+"you upload it, so make sure it's more or less square. It must be under the "
+"site license, also. Use a picture that belongs to you and that you want to "
+"share."
msgstr ""
-#: actions/profilesettings.php:134 actions/register.php:472
-msgid "Where you are, like \"City, State (or Region), Country\""
+#: ../lib/settingsaction.php:91
+msgid "Upload a new profile image"
msgstr ""
-#: actions/profilesettings.php:138 actions/tagother.php:149
-#: actions/tagother.php:209 lib/subscriptionlist.php:106
-#: lib/subscriptionlist.php:108 lib/userprofile.php:209
-msgid "Tags"
+#: ../actions/invite.php:114 actions/invite.php:121 actions/invite.php:154
+#: actions/invite.php:156 actions/invite.php:162
+msgid ""
+"Use this form to invite your friends and colleagues to use this service."
msgstr ""
-#: actions/profilesettings.php:140
-msgid ""
-"Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated"
+#: ../actions/register.php:159 ../actions/register.php:162
+#: actions/register.php:173 actions/register.php:176 actions/register.php:382
+#: actions/register.php:386 actions/register.php:428 actions/register.php:432
+#: actions/register.php:436 actions/register.php:438 actions/register.php:442
+msgid "Used only for updates, announcements, and password recovery"
msgstr ""
-#: actions/profilesettings.php:144
-msgid "Language"
+#: ../actions/finishremotesubscribe.php:86
+#: actions/finishremotesubscribe.php:88 actions/finishremotesubscribe.php:94
+msgid "User being listened to doesn't exist."
+msgstr ""
+
+#: ../actions/all.php:41 ../actions/avatarbynickname.php:48
+#: ../actions/foaf.php:47 ../actions/replies.php:41
+#: ../actions/showstream.php:44 ../actions/twitapiaccount.php:82
+#: ../actions/twitapistatuses.php:319 ../actions/twitapistatuses.php:685
+#: ../actions/twitapiusers.php:82 actions/all.php:41
+#: actions/avatarbynickname.php:48 actions/foaf.php:47 actions/replies.php:41
+#: actions/showfavorites.php:41 actions/showstream.php:44
+#: actions/twitapiaccount.php:80 actions/twitapifavorites.php:68
+#: actions/twitapistatuses.php:235 actions/twitapistatuses.php:609
+#: actions/twitapiusers.php:87 lib/mailbox.php:50
+#: actions/avatarbynickname.php:80 actions/foaf.php:48 actions/replies.php:80
+#: actions/showstream.php:107 actions/twitapiaccount.php:70
+#: actions/twitapifavorites.php:42 actions/twitapistatuses.php:167
+#: actions/twitapistatuses.php:503 actions/twitapiusers.php:55
+#: actions/usergroups.php:99 lib/galleryaction.php:67 lib/twitterapi.php:626
+#: actions/twitapiaccount.php:71 actions/twitapistatuses.php:179
+#: actions/twitapistatuses.php:535 actions/twitapiusers.php:59
+#: actions/foaf.php:65 actions/replies.php:79 actions/twitapiusers.php:57
+#: actions/usergroups.php:98 lib/galleryaction.php:66 lib/profileaction.php:84
+#: actions/apiusershow.php:108 actions/apiaccountupdateprofileimage.php:124
+#: actions/apiaccountupdateprofileimage.php:130
+msgid "User has no profile."
msgstr ""
-#: actions/profilesettings.php:145
-msgid "Preferred language"
+#: ../actions/remotesubscribe.php:71 actions/remotesubscribe.php:80
+#: actions/remotesubscribe.php:105 actions/remotesubscribe.php:129
+msgid "User nickname"
msgstr ""
-#: actions/profilesettings.php:154
-msgid "Timezone"
+#: ../actions/twitapiusers.php:75 actions/twitapiusers.php:80
+msgid "User not found."
msgstr ""
+#: ../actions/profilesettings.php:63 actions/profilesettings.php:96
+#: actions/profilesettings.php:139 actions/profilesettings.php:140
#: actions/profilesettings.php:155
msgid "What timezone are you normally in?"
msgstr ""
-#: actions/profilesettings.php:160
-msgid ""
-"Automatically subscribe to whoever subscribes to me (best for non-humans)"
+#: ../lib/util.php:1159 lib/util.php:1293 lib/noticeform.php:141
+#: lib/noticeform.php:158
+#, php-format
+msgid "What's up, %s?"
+msgstr ""
+
+#: ../actions/profilesettings.php:54 ../actions/register.php:175
+#: actions/profilesettings.php:87 actions/register.php:189
+#: actions/profilesettings.php:119 actions/register.php:410
+#: actions/register.php:456 actions/profilesettings.php:134
+#: actions/register.php:466 actions/register.php:472
+msgid "Where you are, like \"City, State (or Region), Country\""
msgstr ""
-#: actions/profilesettings.php:221 actions/register.php:223
+#: ../actions/updateprofile.php:128 actions/updateprofile.php:129
+#: actions/updateprofile.php:132 actions/updateprofile.php:134
#, php-format
-msgid "Bio is too long (max %d chars)."
+msgid "Wrong image type for '%s'"
msgstr ""
-#: actions/profilesettings.php:228
-msgid "Timezone not selected."
+#: ../actions/updateprofile.php:123 actions/updateprofile.php:124
+#: actions/updateprofile.php:127 actions/updateprofile.php:129
+#, php-format
+msgid "Wrong size image at '%s'"
msgstr ""
-#: actions/profilesettings.php:234
-msgid "Language is too long (max 50 chars)."
+#: ../actions/deletenotice.php:63 ../actions/deletenotice.php:72
+#: actions/deletenotice.php:64 actions/deletenotice.php:79
+#: actions/block.php:148 actions/deletenotice.php:122
+#: actions/deletenotice.php:141 actions/deletenotice.php:115
+#: actions/block.php:150 actions/deletenotice.php:116
+#: actions/groupblock.php:177 actions/deletenotice.php:146
+msgid "Yes"
msgstr ""
-#: actions/profilesettings.php:246 actions/tagother.php:178
-#, php-format
-msgid "Invalid tag: \"%s\""
+#: ../actions/finishaddopenid.php:64 actions/finishaddopenid.php:64
+#: actions/finishaddopenid.php:112
+msgid "You already have this OpenID!"
msgstr ""
-#: actions/profilesettings.php:295
-msgid "Couldn't update user for autosubscribe."
+#: ../actions/deletenotice.php:37 actions/deletenotice.php:37
+msgid ""
+"You are about to permanently delete a notice. Once this is done, it cannot "
+"be undone."
msgstr ""
-#: actions/profilesettings.php:328
-msgid "Couldn't save profile."
+#: ../actions/recoverpassword.php:31 actions/recoverpassword.php:31
+#: actions/recoverpassword.php:36
+msgid "You are already logged in!"
msgstr ""
-#: actions/profilesettings.php:336
-msgid "Couldn't save tags."
+#: ../actions/invite.php:81 actions/invite.php:88 actions/invite.php:120
+#: actions/invite.php:122 actions/invite.php:128
+msgid "You are already subscribed to these users:"
msgstr ""
-#: actions/profilesettings.php:344
-msgid "Settings saved."
+#: ../actions/twitapifriendships.php:128 actions/twitapifriendships.php:128
+#: actions/twitapifriendships.php:105 actions/twitapifriendships.php:111
+msgid "You are not friends with the specified user."
+msgstr ""
+
+#: ../actions/password.php:27
+msgid "You can change your password here. Choose a good one!"
msgstr ""
-#: actions/public.php:83
+#: ../actions/register.php:135 actions/register.php:145
+msgid "You can create a new account to start posting notices."
+msgstr ""
+
+#: ../actions/smssettings.php:28 actions/smssettings.php:28
+#: actions/smssettings.php:69
#, php-format
-msgid "Beyond the page limit (%s)"
+msgid "You can receive SMS messages through email from %%site.name%%."
msgstr ""
-#: actions/public.php:92
-msgid "Could not retrieve public stream."
+#: ../actions/openidsettings.php:86 actions/openidsettings.php:143
+msgid ""
+"You can remove an OpenID from your account by clicking the button marked "
+"\"Remove\"."
msgstr ""
-#: actions/public.php:129
+#: ../actions/imsettings.php:28 actions/imsettings.php:28
+#: actions/imsettings.php:70
#, php-format
-msgid "Public timeline, page %d"
+msgid ""
+"You can send and receive notices through Jabber/GTalk [instant messages](%%"
+"doc.im%%). Configure your address and settings below."
msgstr ""
-#: actions/public.php:131 lib/publicgroupnav.php:79
-msgid "Public timeline"
+#: ../actions/profilesettings.php:27 actions/profilesettings.php:69
+#: actions/profilesettings.php:71
+msgid ""
+"You can update your personal profile info here so people know more about you."
msgstr ""
-#: actions/public.php:151
-msgid "Public Stream Feed (RSS 1.0)"
+#: ../actions/finishremotesubscribe.php:31 ../actions/remotesubscribe.php:31
+#: actions/finishremotesubscribe.php:31 actions/remotesubscribe.php:31
+#: actions/finishremotesubscribe.php:33 actions/finishremotesubscribe.php:85
+#: actions/finishremotesubscribe.php:101 actions/remotesubscribe.php:35
+#: actions/finishremotesubscribe.php:87 actions/remotesubscribe.php:59
+msgid "You can use the local subscription!"
msgstr ""
-#: actions/public.php:155
-msgid "Public Stream Feed (RSS 2.0)"
+#: ../actions/finishopenidlogin.php:33 ../actions/register.php:61
+#: actions/finishopenidlogin.php:38 actions/register.php:68
+#: actions/finishopenidlogin.php:43 actions/register.php:149
+#: actions/register.php:186 actions/register.php:192 actions/register.php:198
+msgid "You can't register if you don't agree to the license."
msgstr ""
-#: actions/public.php:159
-msgid "Public Stream Feed (Atom)"
+#: ../actions/updateprofile.php:63 actions/updateprofile.php:64
+#: actions/updateprofile.php:67 actions/updateprofile.php:69
+msgid "You did not send us that profile"
msgstr ""
-#: actions/public.php:179
+#: ../lib/mail.php:147 lib/mail.php:289 lib/mail.php:288
#, php-format
msgid ""
-"This is the public timeline for %%site.name%% but no one has posted anything "
-"yet."
+"You have a new posting address on %1$s.\n"
+"\n"
+"Send email to %2$s to post new messages.\n"
+"\n"
+"More email instructions at %3$s.\n"
+"\n"
+"Faithfully yours,\n"
+"%4$s"
msgstr ""
-#: actions/public.php:182
-msgid "Be the first to post!"
+#: ../actions/twitapistatuses.php:612 actions/twitapistatuses.php:537
+#: actions/twitapistatuses.php:463 actions/twitapistatuses.php:486
+#: actions/twitapistatuses.php:443 actions/apistatusesdestroy.php:130
+msgid "You may not delete another user's status."
msgstr ""
-#: actions/public.php:186
+#: ../actions/invite.php:31 actions/invite.php:31 actions/invite.php:39
+#: actions/invite.php:41
#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and be the first to post!"
+msgid "You must be logged in to invite other users to use %s"
msgstr ""
-#: actions/public.php:233
-#, php-format
+#: ../actions/invite.php:103 actions/invite.php:110 actions/invite.php:142
+#: actions/invite.php:144 actions/invite.php:150
msgid ""
-"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
-"blogging) service based on the Free Software [StatusNet](http://status.net/) "
-"tool. [Join now](%%action.register%%) to share notices about yourself with "
-"friends, family, and colleagues! ([Read more](%%doc.help%%))"
+"You will be notified when your invitees accept the invitation and register "
+"on the site. Thanks for growing the community!"
+msgstr ""
+
+#: ../actions/recoverpassword.php:149 actions/recoverpassword.php:158
+msgid "You've been identified. Enter a new password below. "
+msgstr ""
+
+#: ../actions/openidlogin.php:67 actions/openidlogin.php:76
+#: actions/openidlogin.php:104 actions/openidlogin.php:113
+msgid "Your OpenID URL"
msgstr ""
-#: actions/public.php:238
+#: ../actions/recoverpassword.php:164 actions/recoverpassword.php:188
+#: actions/recoverpassword.php:193
+msgid "Your nickname on this server, or your registered email address."
+msgstr ""
+
+#: ../actions/openidsettings.php:28 actions/openidsettings.php:70
#, php-format
msgid ""
-"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
-"blogging) service based on the Free Software [StatusNet](http://status.net/) "
-"tool."
+"[OpenID](%%doc.openid%%) lets you log into many sites with the same user "
+"account. Manage your associated OpenIDs from here."
msgstr ""
-#: actions/publictagcloud.php:57
-msgid "Public tag cloud"
+#: ../lib/util.php:943 lib/util.php:992 lib/util.php:945 lib/util.php:756
+#: lib/util.php:770 lib/util.php:816 lib/util.php:844
+msgid "a few seconds ago"
msgstr ""
-#: actions/publictagcloud.php:63
+#: ../lib/util.php:955 lib/util.php:1004 lib/util.php:957 lib/util.php:768
+#: lib/util.php:782 lib/util.php:828 lib/util.php:856
#, php-format
-msgid "These are most popular recent tags on %s "
+msgid "about %d days ago"
msgstr ""
-#: actions/publictagcloud.php:69
+#: ../lib/util.php:951 lib/util.php:1000 lib/util.php:953 lib/util.php:764
+#: lib/util.php:778 lib/util.php:824 lib/util.php:852
#, php-format
-msgid "No one has posted a notice with a [hashtag](%%doc.tags%%) yet."
+msgid "about %d hours ago"
msgstr ""
-#: actions/publictagcloud.php:72
-msgid "Be the first to post one!"
+#: ../lib/util.php:947 lib/util.php:996 lib/util.php:949 lib/util.php:760
+#: lib/util.php:774 lib/util.php:820 lib/util.php:848
+#, php-format
+msgid "about %d minutes ago"
msgstr ""
-#: actions/publictagcloud.php:75
+#: ../lib/util.php:959 lib/util.php:1008 lib/util.php:961 lib/util.php:772
+#: lib/util.php:786 lib/util.php:832 lib/util.php:860
#, php-format
-msgid ""
-"Why not [register an account](%%action.register%%) and be the first to post "
-"one!"
+msgid "about %d months ago"
msgstr ""
-#: actions/publictagcloud.php:135
-msgid "Tag cloud"
+#: ../lib/util.php:953 lib/util.php:1002 lib/util.php:955 lib/util.php:766
+#: lib/util.php:780 lib/util.php:826 lib/util.php:854
+msgid "about a day ago"
msgstr ""
-#: actions/recoverpassword.php:36
-msgid "You are already logged in!"
+#: ../lib/util.php:945 lib/util.php:994 lib/util.php:947 lib/util.php:758
+#: lib/util.php:772 lib/util.php:818 lib/util.php:846
+msgid "about a minute ago"
msgstr ""
-#: actions/recoverpassword.php:62
-msgid "No such recovery code."
+#: ../lib/util.php:957 lib/util.php:1006 lib/util.php:959 lib/util.php:770
+#: lib/util.php:784 lib/util.php:830 lib/util.php:858
+msgid "about a month ago"
msgstr ""
-#: actions/recoverpassword.php:66
-msgid "Not a recovery code."
+#: ../lib/util.php:961 lib/util.php:1010 lib/util.php:963 lib/util.php:774
+#: lib/util.php:788 lib/util.php:834 lib/util.php:862
+msgid "about a year ago"
msgstr ""
-#: actions/recoverpassword.php:73
-msgid "Recovery code for unknown user."
+#: ../lib/util.php:949 lib/util.php:998 lib/util.php:951 lib/util.php:762
+#: lib/util.php:776 lib/util.php:822 lib/util.php:850
+msgid "about an hour ago"
msgstr ""
-#: actions/recoverpassword.php:86
-msgid "Error with confirmation code."
+#: ../actions/showstream.php:423 ../lib/stream.php:132
+#: actions/showstream.php:441 lib/stream.php:99
+msgid "delete"
msgstr ""
-#: actions/recoverpassword.php:97
-msgid "This confirmation code is too old. Please start again."
+#: ../actions/noticesearch.php:130 ../actions/showstream.php:408
+#: ../lib/stream.php:117 actions/noticesearch.php:136
+#: actions/showstream.php:426 lib/stream.php:84 actions/noticesearch.php:187
+msgid "in reply to..."
msgstr ""
-#: actions/recoverpassword.php:111
-msgid "Could not update user with confirmed email address."
+#: ../actions/noticesearch.php:137 ../actions/showstream.php:415
+#: ../lib/stream.php:124 actions/noticesearch.php:143
+#: actions/showstream.php:433 lib/stream.php:91 actions/noticesearch.php:194
+msgid "reply"
msgstr ""
-#: actions/recoverpassword.php:152
-msgid ""
-"If you have forgotten or lost your password, you can get a new one sent to "
-"the email address you have stored in your account."
+#: ../actions/password.php:44 actions/profilesettings.php:183
+#: actions/passwordsettings.php:106 actions/passwordsettings.php:112
+msgid "same as password above"
msgstr ""
-#: actions/recoverpassword.php:158
-msgid "You have been identified. Enter a new password below. "
+#: ../actions/twitapistatuses.php:755 actions/twitapistatuses.php:678
+#: actions/twitapistatuses.php:555 actions/twitapistatuses.php:596
+#: actions/twitapistatuses.php:618 actions/twitapistatuses.php:553
+#: actions/twitapistatuses.php:575
+msgid "unsupported file type"
+msgstr ""
+
+#: ../lib/util.php:1309 lib/util.php:1443
+msgid "« After"
+msgstr ""
+
+#: actions/deletenotice.php:74 actions/disfavor.php:43
+#: actions/emailsettings.php:127 actions/favor.php:45
+#: actions/finishopenidlogin.php:33 actions/imsettings.php:105
+#: actions/invite.php:46 actions/newmessage.php:45 actions/openidlogin.php:36
+#: actions/openidsettings.php:123 actions/profilesettings.php:47
+#: actions/recoverpassword.php:282 actions/register.php:42
+#: actions/remotesubscribe.php:40 actions/smssettings.php:124
+#: actions/subscribe.php:44 actions/twittersettings.php:97
+#: actions/unsubscribe.php:41 actions/userauthorization.php:35
+#: actions/block.php:64 actions/disfavor.php:74 actions/favor.php:77
+#: actions/finishopenidlogin.php:38 actions/invite.php:54 actions/nudge.php:80
+#: actions/openidlogin.php:37 actions/recoverpassword.php:316
+#: actions/subscribe.php:46 actions/unblock.php:65 actions/unsubscribe.php:43
+#: actions/avatarsettings.php:251 actions/emailsettings.php:229
+#: actions/grouplogo.php:314 actions/imsettings.php:200 actions/login.php:103
+#: actions/newmessage.php:133 actions/newnotice.php:96
+#: actions/openidsettings.php:188 actions/othersettings.php:136
+#: actions/passwordsettings.php:131 actions/profilesettings.php:172
+#: actions/register.php:113 actions/remotesubscribe.php:53
+#: actions/smssettings.php:216 actions/subedit.php:38 actions/tagother.php:166
+#: actions/twittersettings.php:294 actions/userauthorization.php:39
+#: actions/favor.php:75 actions/groupblock.php:66 actions/groupunblock.php:66
+#: actions/invite.php:56 actions/makeadmin.php:66 actions/newnotice.php:102
+#: actions/othersettings.php:138 actions/recoverpassword.php:334
+#: actions/register.php:153 actions/twittersettings.php:310
+#: lib/designsettings.php:291 actions/emailsettings.php:237
+#: actions/grouplogo.php:309 actions/imsettings.php:206 actions/login.php:105
+#: actions/newmessage.php:135 actions/newnotice.php:103
+#: actions/othersettings.php:145 actions/passwordsettings.php:137
+#: actions/profilesettings.php:187 actions/recoverpassword.php:337
+#: actions/register.php:159 actions/remotesubscribe.php:77
+#: actions/smssettings.php:228 actions/unsubscribe.php:69
+#: actions/userauthorization.php:52 actions/login.php:131
+#: actions/register.php:165 actions/avatarsettings.php:265
+#: lib/designsettings.php:294
+msgid "There was a problem with your session token. Try again, please."
msgstr ""
-#: actions/recoverpassword.php:188
-msgid "Password recovery"
+#: actions/disfavor.php:55 actions/disfavor.php:81
+msgid "This notice is not a favorite!"
msgstr ""
-#: actions/recoverpassword.php:191
-msgid "Nickname or email address"
+#: actions/disfavor.php:63 actions/disfavor.php:87
+#: actions/twitapifavorites.php:188 actions/apifavoritedestroy.php:134
+msgid "Could not delete favorite."
msgstr ""
-#: actions/recoverpassword.php:193
-msgid "Your nickname on this server, or your registered email address."
+#: actions/disfavor.php:72 lib/favorform.php:140
+msgid "Favor"
msgstr ""
-#: actions/recoverpassword.php:199 actions/recoverpassword.php:200
-msgid "Recover"
+#: actions/emailsettings.php:92 actions/emailsettings.php:157
+#: actions/emailsettings.php:163
+msgid "Send me email when someone adds my notice as a favorite."
msgstr ""
-#: actions/recoverpassword.php:208
-msgid "Reset password"
+#: actions/emailsettings.php:95 actions/emailsettings.php:163
+#: actions/emailsettings.php:169
+msgid "Send me email when someone sends me a private message."
msgstr ""
-#: actions/recoverpassword.php:209
-msgid "Recover password"
+#: actions/favor.php:53 actions/twitapifavorites.php:142 actions/favor.php:81
+#: actions/twitapifavorites.php:118 actions/twitapifavorites.php:124
+#: actions/favor.php:79
+msgid "This notice is already a favorite!"
msgstr ""
-#: actions/recoverpassword.php:210 actions/recoverpassword.php:322
-msgid "Password recovery requested"
+#: actions/favor.php:60 actions/twitapifavorites.php:151
+#: classes/Command.php:132 actions/favor.php:86
+#: actions/twitapifavorites.php:125 classes/Command.php:152
+#: actions/twitapifavorites.php:131 lib/command.php:152 actions/favor.php:84
+#: actions/twitapifavorites.php:133 lib/command.php:145
+#: actions/apifavoritecreate.php:130 lib/command.php:176
+msgid "Could not create favorite."
msgstr ""
-#: actions/recoverpassword.php:213
-msgid "Unknown action"
+#: actions/favor.php:70
+msgid "Disfavor"
msgstr ""
-#: actions/recoverpassword.php:236
-msgid "6 or more characters, and don't forget it!"
+#: actions/favoritesrss.php:60 actions/showfavorites.php:47
+#: actions/favoritesrss.php:100 actions/showfavorites.php:77
+#: actions/favoritesrss.php:110
+#, php-format
+msgid "%s favorite notices"
msgstr ""
-#: actions/recoverpassword.php:240
-msgid "Same as password above"
+#: actions/favoritesrss.php:64 actions/favoritesrss.php:104
+#: actions/favoritesrss.php:114
+#, php-format
+msgid "Feed of favorite notices of %s"
msgstr ""
-#: actions/recoverpassword.php:243
-msgid "Reset"
+#: actions/inbox.php:28 actions/inbox.php:59
+#, php-format
+msgid "Inbox for %s - page %d"
msgstr ""
-#: actions/recoverpassword.php:252
-msgid "Enter a nickname or email address."
+#: actions/inbox.php:30 actions/inbox.php:62
+#, php-format
+msgid "Inbox for %s"
msgstr ""
-#: actions/recoverpassword.php:272
-msgid "No user with that email address or username."
+#: actions/inbox.php:53 actions/inbox.php:115
+msgid "This is your inbox, which lists your incoming private messages."
msgstr ""
-#: actions/recoverpassword.php:287
-msgid "No registered email address for that user."
+#: actions/invite.php:178 actions/invite.php:213
+#, php-format
+msgid ""
+"%1$s has invited you to join them on %2$s (%3$s).\n"
+"\n"
msgstr ""
-#: actions/recoverpassword.php:301
-msgid "Error saving address confirmation."
+#: actions/login.php:104 actions/login.php:235 actions/openidlogin.php:108
+#: actions/register.php:416
+msgid "Automatically login in the future; "
msgstr ""
-#: actions/recoverpassword.php:325
-msgid ""
-"Instructions for recovering your password have been sent to the email "
-"address registered to your account."
+#: actions/login.php:122 actions/login.php:264
+msgid "For security reasons, please re-enter your "
msgstr ""
-#: actions/recoverpassword.php:344
-msgid "Unexpected password reset."
+#: actions/login.php:126 actions/login.php:268
+msgid "Login with your username and password. "
msgstr ""
-#: actions/recoverpassword.php:352
-msgid "Password must be 6 chars or more."
+#: actions/newmessage.php:58 actions/twitapidirect_messages.php:130
+#: actions/twitapidirect_messages.php:141 actions/newmessage.php:148
+#: actions/twitapidirect_messages.php:150
+#: actions/twitapidirect_messages.php:145
+msgid "That's too long. Max message size is 140 chars."
msgstr ""
-#: actions/recoverpassword.php:356
-msgid "Password and confirmation do not match."
+#: actions/newmessage.php:65 actions/newmessage.php:128
+#: actions/newmessage.php:155 actions/newmessage.php:158
+msgid "No recipient specified."
msgstr ""
-#: actions/recoverpassword.php:382
-msgid "New password successfully saved. You are now logged in."
+#: actions/newmessage.php:68 actions/newmessage.php:113
+#: classes/Command.php:206 actions/newmessage.php:131
+#: actions/newmessage.php:168 classes/Command.php:237
+#: actions/newmessage.php:119 actions/newmessage.php:158 lib/command.php:237
+#: lib/command.php:230 actions/newmessage.php:121 actions/newmessage.php:161
+#: lib/command.php:367
+msgid "You can't send a message to this user."
+msgstr ""
+
+#: actions/newmessage.php:71 actions/twitapidirect_messages.php:146
+#: classes/Command.php:209 actions/twitapidirect_messages.php:158
+#: classes/Command.php:240 actions/newmessage.php:161
+#: actions/twitapidirect_messages.php:167 lib/command.php:240
+#: actions/twitapidirect_messages.php:163 lib/command.php:233
+#: actions/newmessage.php:164 lib/command.php:370
+msgid ""
+"Don't send a message to yourself; just say it to yourself quietly instead."
msgstr ""
-#: actions/register.php:85 actions/register.php:189 actions/register.php:404
-msgid "Sorry. Only those invited can register."
+#: actions/newmessage.php:108 actions/microsummary.php:62
+#: actions/newmessage.php:163 actions/newmessage.php:114
+#: actions/newmessage.php:116 actions/remotesubscribe.php:154
+msgid "No such user"
msgstr ""
-#: actions/register.php:92
-msgid "Sorry. This is an invalid invitation code."
+#: actions/newmessage.php:117 actions/newmessage.php:67
+#: actions/newmessage.php:71 actions/newmessage.php:231
+msgid "New message"
msgstr ""
-#: actions/register.php:112
-msgid "Registration successful"
+#: actions/noticesearch.php:95 actions/noticesearch.php:146
+msgid "Notice without matching profile"
msgstr ""
-#: actions/register.php:114 actions/register.php:502 lib/action.php:450
-#: lib/logingroupnav.php:85
-msgid "Register"
+#: actions/openidsettings.php:28 actions/openidsettings.php:70
+#, php-format
+msgid "[OpenID](%%doc.openid%%) lets you log into many sites "
msgstr ""
-#: actions/register.php:135
-msgid "Registration not allowed."
+#: actions/openidsettings.php:46 actions/openidsettings.php:96
+msgid "If you want to add an OpenID to your account, "
msgstr ""
-#: actions/register.php:198
-msgid "You can't register if you don't agree to the license."
+#: actions/openidsettings.php:74
+msgid "Removing your only OpenID would make it impossible to log in! "
msgstr ""
-#: actions/register.php:201
-msgid "Not a valid email address."
+#: actions/openidsettings.php:87 actions/openidsettings.php:143
+msgid "You can remove an OpenID from your account "
msgstr ""
-#: actions/register.php:212
-msgid "Email address already exists."
+#: actions/outbox.php:28 actions/outbox.php:58
+#, php-format
+msgid "Outbox for %s - page %d"
msgstr ""
-#: actions/register.php:243 actions/register.php:264
-msgid "Invalid username or password."
+#: actions/outbox.php:30 actions/outbox.php:61
+#, php-format
+msgid "Outbox for %s"
+msgstr ""
+
+#: actions/outbox.php:53 actions/outbox.php:116
+msgid "This is your outbox, which lists private messages you have sent."
msgstr ""
-#: actions/register.php:342
+#: actions/peoplesearch.php:28 actions/peoplesearch.php:52
+#, php-format
msgid ""
-"With this form you can create a new account. You can then post notices and "
-"link up to friends and colleagues. "
+"Search for people on %%site.name%% by their name, location, or interests. "
msgstr ""
-#: actions/register.php:424
-msgid "1-64 lowercase letters or numbers, no punctuation or spaces. Required."
+#: actions/profilesettings.php:27 actions/profilesettings.php:69
+msgid "You can update your personal profile info here "
msgstr ""
-#: actions/register.php:429
-msgid "6 or more characters. Required."
+#: actions/profilesettings.php:115 actions/remotesubscribe.php:320
+#: actions/userauthorization.php:159 actions/userrss.php:76
+#: actions/avatarsettings.php:104 actions/avatarsettings.php:179
+#: actions/grouplogo.php:177 actions/remotesubscribe.php:367
+#: actions/userauthorization.php:176 actions/userrss.php:82
+#: actions/avatarsettings.php:106 actions/avatarsettings.php:182
+#: actions/grouplogo.php:183 actions/remotesubscribe.php:366
+#: actions/remotesubscribe.php:364 actions/userauthorization.php:215
+#: actions/userrss.php:103 actions/grouplogo.php:178
+#: actions/remotesubscribe.php:191 actions/userauthorization.php:72
+msgid "User without matching profile"
msgstr ""
-#: actions/register.php:433
-msgid "Same as password above. Required."
+#: actions/recoverpassword.php:91 actions/recoverpassword.php:97
+msgid "This confirmation code is too old. "
msgstr ""
-#: actions/register.php:437 actions/register.php:441
-#: lib/accountsettingsaction.php:117
-msgid "Email"
+#: actions/recoverpassword.php:141 actions/recoverpassword.php:152
+msgid "If you've forgotten or lost your"
msgstr ""
-#: actions/register.php:438 actions/register.php:442
-msgid "Used only for updates, announcements, and password recovery"
+#: actions/recoverpassword.php:154 actions/recoverpassword.php:158
+msgid "You've been identified. Enter a "
msgstr ""
-#: actions/register.php:449
-msgid "Longer name, preferably your \"real\" name"
+#: actions/recoverpassword.php:169 actions/recoverpassword.php:188
+msgid "Your nickname on this server, "
msgstr ""
-#: actions/register.php:493
-msgid "My text and files are available under "
+#: actions/recoverpassword.php:271 actions/recoverpassword.php:304
+msgid "Instructions for recovering your password "
msgstr ""
-#: actions/register.php:495
-msgid "Creative Commons Attribution 3.0"
+#: actions/recoverpassword.php:327 actions/recoverpassword.php:361
+msgid "New password successfully saved. "
msgstr ""
-#: actions/register.php:496
-msgid ""
-" except this private data: password, email address, IM address, and phone "
-"number."
+#: actions/register.php:95 actions/register.php:180
+#: actions/passwordsettings.php:147 actions/register.php:217
+#: actions/passwordsettings.php:153 actions/register.php:224
+#: actions/register.php:230
+msgid "Password must be 6 or more characters."
msgstr ""
-#: actions/register.php:537
+#: actions/register.php:216
#, php-format
msgid ""
"Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may "
-"want to...\n"
-"\n"
-"* Go to [your profile](%s) and post your first message.\n"
-"* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send "
-"notices through instant messages.\n"
-"* [Search for users](%%%%action.peoplesearch%%%%) that you may know or that "
-"share your interests. \n"
-"* Update your [profile settings](%%%%action.profilesettings%%%%) to tell "
-"others more about you. \n"
-"* Read over the [online docs](%%%%doc.help%%%%) for features you may have "
-"missed. \n"
-"\n"
-"Thanks for signing up and we hope you enjoy using this service."
+"want to..."
msgstr ""
-#: actions/register.php:561
-msgid ""
-"(You should receive a message by email momentarily, with instructions on how "
-"to confirm your email address.)"
+#: actions/register.php:227
+msgid "(You should receive a message by email momentarily, with "
msgstr ""
-#: actions/remotesubscribe.php:98
+#: actions/remotesubscribe.php:51 actions/remotesubscribe.php:74
#, php-format
-msgid ""
-"To subscribe, you can [login](%%action.login%%), or [register](%%action."
-"register%%) a new account. If you already have an account on a [compatible "
-"microblogging site](%%doc.openmublog%%), enter your profile URL below."
+msgid "To subscribe, you can [login](%%action.login%%),"
msgstr ""
-#: actions/remotesubscribe.php:112
-msgid "Remote subscribe"
+#: actions/showfavorites.php:61 actions/showfavorites.php:145
+#: actions/showfavorites.php:147
+#, php-format
+msgid "Feed for favorites of %s"
msgstr ""
-#: actions/remotesubscribe.php:124
-msgid "Subscribe to a remote user"
+#: actions/showfavorites.php:84 actions/twitapifavorites.php:85
+#: actions/showfavorites.php:202 actions/twitapifavorites.php:59
+#: actions/showfavorites.php:179 actions/showfavorites.php:209
+#: actions/showfavorites.php:132
+msgid "Could not retrieve favorite notices."
msgstr ""
-#: actions/remotesubscribe.php:129
-msgid "User nickname"
+#: actions/showmessage.php:33 actions/showmessage.php:81
+msgid "No such message."
msgstr ""
-#: actions/remotesubscribe.php:130
-msgid "Nickname of the user you want to follow"
+#: actions/showmessage.php:42 actions/showmessage.php:98
+msgid "Only the sender and recipient may read this message."
msgstr ""
-#: actions/remotesubscribe.php:133
-msgid "Profile URL"
+#: actions/showmessage.php:61 actions/showmessage.php:108
+#, php-format
+msgid "Message to %1$s on %2$s"
msgstr ""
-#: actions/remotesubscribe.php:134
-msgid "URL of your profile on another compatible microblogging service"
+#: actions/showmessage.php:66 actions/showmessage.php:113
+#, php-format
+msgid "Message from %1$s on %2$s"
msgstr ""
-#: actions/remotesubscribe.php:137 lib/subscribeform.php:139
-#: lib/userprofile.php:321
-msgid "Subscribe"
+#: actions/showstream.php:154
+msgid "Send a message"
msgstr ""
-#: actions/remotesubscribe.php:159
-msgid "Invalid profile URL (bad format)"
+#: actions/smssettings.php:312 actions/smssettings.php:464
+#, php-format
+msgid "Mobile carrier for your phone. "
msgstr ""
-#: actions/remotesubscribe.php:168
-msgid ""
-"Not a valid profile URL (no YADIS document or no or invalid XRDS defined)."
+#: actions/twitapidirect_messages.php:76 actions/twitapidirect_messages.php:68
+#: actions/twitapidirect_messages.php:67 actions/twitapidirect_messages.php:53
+#: actions/apidirectmessage.php:101
+#, php-format
+msgid "Direct messages to %s"
msgstr ""
-#: actions/remotesubscribe.php:176
-msgid "That’s a local profile! Login to subscribe."
+#: actions/twitapidirect_messages.php:77 actions/twitapidirect_messages.php:69
+#: actions/twitapidirect_messages.php:68 actions/twitapidirect_messages.php:54
+#: actions/apidirectmessage.php:105
+#, php-format
+msgid "All the direct messages sent to %s"
msgstr ""
-#: actions/remotesubscribe.php:183
-msgid "Couldn’t get a request token."
+#: actions/twitapidirect_messages.php:81 actions/twitapidirect_messages.php:73
+#: actions/twitapidirect_messages.php:72 actions/twitapidirect_messages.php:59
+msgid "Direct Messages You've Sent"
msgstr ""
-#: actions/replies.php:125 actions/repliesrss.php:68
-#: lib/personalgroupnav.php:105
+#: actions/twitapidirect_messages.php:82 actions/twitapidirect_messages.php:74
+#: actions/twitapidirect_messages.php:73 actions/twitapidirect_messages.php:60
+#: actions/apidirectmessage.php:93
#, php-format
-msgid "Replies to %s"
+msgid "All the direct messages sent from %s"
msgstr ""
-#: actions/replies.php:127
-#, php-format
-msgid "Replies to %s, page %d"
+#: actions/twitapidirect_messages.php:128
+#: actions/twitapidirect_messages.php:137
+#: actions/twitapidirect_messages.php:146
+#: actions/twitapidirect_messages.php:140 actions/apidirectmessagenew.php:126
+msgid "No message text!"
msgstr ""
-#: actions/replies.php:144
-#, php-format
-msgid "Replies feed for %s (RSS 1.0)"
+#: actions/twitapidirect_messages.php:138
+#: actions/twitapidirect_messages.php:150
+#: actions/twitapidirect_messages.php:159
+#: actions/twitapidirect_messages.php:154 actions/apidirectmessagenew.php:146
+msgid "Recipient user not found."
msgstr ""
-#: actions/replies.php:151
+#: actions/twitapidirect_messages.php:141
+#: actions/twitapidirect_messages.php:153
+#: actions/twitapidirect_messages.php:162
+#: actions/twitapidirect_messages.php:158 actions/apidirectmessagenew.php:150
+msgid "Can't send direct messages to users who aren't your friend."
+msgstr ""
+
+#: actions/twitapifavorites.php:92 actions/twitapifavorites.php:66
+#: actions/twitapifavorites.php:64 actions/twitapifavorites.php:49
+#: actions/apitimelinefavorites.php:107
#, php-format
-msgid "Replies feed for %s (RSS 2.0)"
+msgid "%s / Favorites from %s"
msgstr ""
-#: actions/replies.php:158
+#: actions/twitapifavorites.php:95 actions/twitapifavorites.php:69
+#: actions/twitapifavorites.php:68 actions/twitapifavorites.php:55
+#: actions/apitimelinefavorites.php:119
#, php-format
-msgid "Replies feed for %s (Atom)"
+msgid "%s updates favorited by %s / %s."
msgstr ""
-#: actions/replies.php:198
+#: actions/twitapifavorites.php:187 lib/mail.php:275
+#: actions/twitapifavorites.php:164 lib/mail.php:553
+#: actions/twitapifavorites.php:170 lib/mail.php:554
+#: actions/twitapifavorites.php:221
#, php-format
-msgid ""
-"This is the timeline showing replies to %s but %s has not received a notice "
-"to his attention yet."
+msgid "%s added your notice as a favorite"
msgstr ""
-#: actions/replies.php:203
+#: actions/twitapifavorites.php:188 lib/mail.php:276
+#: actions/twitapifavorites.php:165
#, php-format
msgid ""
-"You can engage other users in a conversation, subscribe to more users or "
-"[join groups](%%action.groups%%)."
+"%1$s just added your notice from %2$s as one of their favorites.\n"
+"\n"
msgstr ""
-#: actions/replies.php:205
-#, php-format
+#: actions/twittersettings.php:27
msgid ""
-"You can try to [nudge %s](../%s) or [post something to his or her attention]"
-"(%%%%action.newnotice%%%%?status_textarea=%s)."
+"Add your Twitter account to automatically send your notices to Twitter, "
msgstr ""
-#: actions/repliesrss.php:72
-#, php-format
-msgid "Replies to %1$s on %2$s!"
+#: actions/twittersettings.php:41 actions/twittersettings.php:60
+#: actions/twittersettings.php:61
+msgid "Twitter settings"
msgstr ""
-#: actions/showfavorites.php:79
-#, php-format
-msgid "%s's favorite notices, page %d"
+#: actions/twittersettings.php:48 actions/twittersettings.php:105
+#: actions/twittersettings.php:106
+msgid "Twitter Account"
msgstr ""
-#: actions/showfavorites.php:132
-msgid "Could not retrieve favorite notices."
+#: actions/twittersettings.php:56 actions/twittersettings.php:113
+#: actions/twittersettings.php:114
+msgid "Current verified Twitter account."
msgstr ""
-#: actions/showfavorites.php:170
-#, php-format
-msgid "Feed for favorites of %s (RSS 1.0)"
+#: actions/twittersettings.php:63
+msgid "Twitter Username"
msgstr ""
-#: actions/showfavorites.php:177
-#, php-format
-msgid "Feed for favorites of %s (RSS 2.0)"
+#: actions/twittersettings.php:65 actions/twittersettings.php:123
+#: actions/twittersettings.php:126
+msgid "No spaces, please."
msgstr ""
-#: actions/showfavorites.php:184
-#, php-format
-msgid "Feed for favorites of %s (Atom)"
+#: actions/twittersettings.php:67
+msgid "Twitter Password"
msgstr ""
-#: actions/showfavorites.php:205
-msgid ""
-"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."
+#: actions/twittersettings.php:72 actions/twittersettings.php:139
+#: actions/twittersettings.php:142
+msgid "Automatically send my notices to Twitter."
msgstr ""
-#: actions/showfavorites.php:207
-#, php-format
-msgid ""
-"%s hasn't added any notices to his favorites yet. Post something interesting "
-"they would add to their favorites :)"
+#: actions/twittersettings.php:75 actions/twittersettings.php:146
+#: actions/twittersettings.php:149
+msgid "Send local \"@\" replies to Twitter."
msgstr ""
-#: actions/showfavorites.php:211
-#, php-format
-msgid ""
-"%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 :)"
+#: actions/twittersettings.php:78 actions/twittersettings.php:153
+#: actions/twittersettings.php:156
+msgid "Subscribe to my Twitter friends here."
msgstr ""
-#: actions/showfavorites.php:242
-msgid "This is a way to share what you like."
+#: actions/twittersettings.php:122 actions/twittersettings.php:331
+#: actions/twittersettings.php:348
+msgid ""
+"Username must have only numbers, upper- and lowercase letters, and "
+"underscore (_). 15 chars max."
msgstr ""
-#: actions/showgroup.php:82 lib/groupnav.php:85
-#, php-format
-msgid "%s group"
+#: actions/twittersettings.php:128 actions/twittersettings.php:334
+#: actions/twittersettings.php:338 actions/twittersettings.php:355
+msgid "Could not verify your Twitter credentials!"
msgstr ""
-#: actions/showgroup.php:84
+#: actions/twittersettings.php:137
#, php-format
-msgid "%s group, page %d"
+msgid "Unable to retrieve account information for \"%s\" from Twitter."
msgstr ""
-#: actions/showgroup.php:218
-msgid "Group profile"
+#: actions/twittersettings.php:151 actions/twittersettings.php:170
+#: actions/twittersettings.php:348 actions/twittersettings.php:368
+#: actions/twittersettings.php:352 actions/twittersettings.php:372
+#: actions/twittersettings.php:369 actions/twittersettings.php:389
+msgid "Unable to save your Twitter settings!"
msgstr ""
-#: actions/showgroup.php:263 actions/tagother.php:118
-#: actions/userauthorization.php:167 lib/userprofile.php:177
-msgid "URL"
+#: actions/twittersettings.php:174 actions/twittersettings.php:376
+#: actions/twittersettings.php:380 actions/twittersettings.php:399
+msgid "Twitter settings saved."
msgstr ""
-#: actions/showgroup.php:274 actions/tagother.php:128
-#: actions/userauthorization.php:179 lib/userprofile.php:194
-msgid "Note"
+#: actions/twittersettings.php:192 actions/twittersettings.php:395
+#: actions/twittersettings.php:399 actions/twittersettings.php:418
+msgid "That is not your Twitter account."
msgstr ""
-#: actions/showgroup.php:284 lib/groupeditform.php:184
-msgid "Aliases"
+#: actions/twittersettings.php:200 actions/twittersettings.php:208
+#: actions/twittersettings.php:403 actions/twittersettings.php:407
+#: actions/twittersettings.php:426
+msgid "Couldn't remove Twitter user."
msgstr ""
-#: actions/showgroup.php:293
-msgid "Group actions"
+#: actions/twittersettings.php:212 actions/twittersettings.php:407
+#: actions/twittersettings.php:411 actions/twittersettings.php:430
+msgid "Twitter account removed."
msgstr ""
-#: actions/showgroup.php:328
-#, php-format
-msgid "Notice feed for %s group (RSS 1.0)"
+#: actions/twittersettings.php:225 actions/twittersettings.php:239
+#: actions/twittersettings.php:428 actions/twittersettings.php:439
+#: actions/twittersettings.php:453 actions/twittersettings.php:432
+#: actions/twittersettings.php:443 actions/twittersettings.php:457
+#: actions/twittersettings.php:452 actions/twittersettings.php:463
+#: actions/twittersettings.php:477
+msgid "Couldn't save Twitter preferences."
msgstr ""
-#: actions/showgroup.php:334
-#, php-format
-msgid "Notice feed for %s group (RSS 2.0)"
+#: actions/twittersettings.php:245 actions/twittersettings.php:461
+#: actions/twittersettings.php:465 actions/twittersettings.php:485
+msgid "Twitter preferences saved."
msgstr ""
-#: actions/showgroup.php:340
-#, php-format
-msgid "Notice feed for %s group (Atom)"
+#: actions/userauthorization.php:84 actions/userauthorization.php:86
+msgid "Please check these details to make sure "
msgstr ""
-#: actions/showgroup.php:345
-#, php-format
-msgid "FOAF for %s group"
+#: actions/userauthorization.php:324 actions/userauthorization.php:340
+msgid "The subscription has been authorized, but no "
msgstr ""
-#: actions/showgroup.php:381 actions/showgroup.php:438 lib/groupnav.php:90
-msgid "Members"
+#: actions/userauthorization.php:334 actions/userauthorization.php:351
+msgid "The subscription has been rejected, but no "
msgstr ""
-#: actions/showgroup.php:386 lib/profileaction.php:117
-#: lib/profileaction.php:148 lib/profileaction.php:226 lib/section.php:95
-#: lib/tagcloudsection.php:71
-msgid "(None)"
+#: classes/Channel.php:113 classes/Channel.php:132 classes/Channel.php:151
+#: lib/channel.php:138 lib/channel.php:158
+msgid "Command results"
msgstr ""
-#: actions/showgroup.php:392
-msgid "All members"
+#: classes/Channel.php:148 classes/Channel.php:204 lib/channel.php:210
+msgid "Command complete"
msgstr ""
-#: actions/showgroup.php:429 lib/profileaction.php:173
-msgid "Statistics"
+#: classes/Channel.php:158 classes/Channel.php:215 lib/channel.php:221
+msgid "Command failed"
msgstr ""
-#: actions/showgroup.php:432
-msgid "Created"
+#: classes/Command.php:39 classes/Command.php:44 lib/command.php:44
+msgid "Sorry, this command is not yet implemented."
msgstr ""
-#: actions/showgroup.php:448
+#: classes/Command.php:96 classes/Command.php:113
#, php-format
-msgid ""
-"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. Its members share short messages about "
-"their life and interests. [Join now](%%%%action.register%%%%) to become part "
-"of this group and many more! ([Read more](%%%%doc.help%%%%))"
+msgid "Subscriptions: %1$s\n"
msgstr ""
-#: actions/showgroup.php:454
-#, php-format
-msgid ""
-"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. Its members share short messages about "
-"their life and interests. "
+#: classes/Command.php:125 classes/Command.php:242 classes/Command.php:145
+#: classes/Command.php:276 lib/command.php:145 lib/command.php:276
+#: lib/command.php:138 lib/command.php:269 lib/command.php:168
+#: lib/command.php:416 lib/command.php:471
+msgid "User has no last notice"
msgstr ""
-#: actions/showgroup.php:482
-msgid "Admins"
+#: classes/Command.php:146 classes/Command.php:166 lib/command.php:166
+#: lib/command.php:159 lib/command.php:190
+msgid "Notice marked as fave."
msgstr ""
-#: actions/showmessage.php:81
-msgid "No such message."
+#: classes/Command.php:166 classes/Command.php:189 lib/command.php:189
+#: lib/command.php:182 lib/command.php:315
+#, php-format
+msgid "%1$s (%2$s)"
msgstr ""
-#: actions/showmessage.php:98
-msgid "Only the sender and recipient may read this message."
+#: classes/Command.php:169 classes/Command.php:192 lib/command.php:192
+#: lib/command.php:185 lib/command.php:318
+#, php-format
+msgid "Fullname: %s"
msgstr ""
-#: actions/showmessage.php:108
+#: classes/Command.php:172 classes/Command.php:195 lib/command.php:195
+#: lib/command.php:188 lib/command.php:321
#, php-format
-msgid "Message to %1$s on %2$s"
+msgid "Location: %s"
msgstr ""
-#: actions/showmessage.php:113
+#: classes/Command.php:175 classes/Command.php:198 lib/command.php:198
+#: lib/command.php:191 lib/command.php:324
#, php-format
-msgid "Message from %1$s on %2$s"
+msgid "Homepage: %s"
msgstr ""
-#: actions/shownotice.php:90
-msgid "Notice deleted."
+#: classes/Command.php:178 classes/Command.php:201 lib/command.php:201
+#: lib/command.php:194 lib/command.php:327
+#, php-format
+msgid "About: %s"
msgstr ""
-#: actions/showstream.php:73
+#: classes/Command.php:200 classes/Command.php:228 lib/command.php:228
+#: lib/command.php:221
#, php-format
-msgid " tagged %s"
+msgid "Message too long - maximum is 140 characters, you sent %d"
msgstr ""
-#: actions/showstream.php:79
+#: classes/Command.php:214 classes/Command.php:245 lib/command.php:245
+#: actions/newmessage.php:182 lib/command.php:238 actions/newmessage.php:185
+#: lib/command.php:375
#, php-format
-msgid "%s, page %d"
+msgid "Direct message to %s sent"
msgstr ""
-#: actions/showstream.php:122
-#, php-format
-msgid "Notice feed for %s tagged %s (RSS 1.0)"
+#: classes/Command.php:216 classes/Command.php:247 lib/command.php:247
+#: lib/command.php:240 lib/command.php:377
+msgid "Error sending direct message."
msgstr ""
-#: actions/showstream.php:129
-#, php-format
-msgid "Notice feed for %s (RSS 1.0)"
+#: classes/Command.php:263 classes/Command.php:300 lib/command.php:300
+#: lib/command.php:293 lib/command.php:495
+msgid "Specify the name of the user to subscribe to"
msgstr ""
-#: actions/showstream.php:136
+#: classes/Command.php:270 classes/Command.php:307 lib/command.php:307
+#: lib/command.php:300 lib/command.php:502
#, php-format
-msgid "Notice feed for %s (RSS 2.0)"
+msgid "Subscribed to %s"
msgstr ""
-#: actions/showstream.php:143
-#, php-format
-msgid "Notice feed for %s (Atom)"
+#: classes/Command.php:288 classes/Command.php:328 lib/command.php:328
+#: lib/command.php:321 lib/command.php:523
+msgid "Specify the name of the user to unsubscribe from"
msgstr ""
-#: actions/showstream.php:148
+#: classes/Command.php:295 classes/Command.php:335 lib/command.php:335
+#: lib/command.php:328 lib/command.php:530
#, php-format
-msgid "FOAF for %s"
+msgid "Unsubscribed from %s"
msgstr ""
-#: actions/showstream.php:191
-#, php-format
-msgid "This is the timeline for %s but %s hasn't posted anything yet."
+#: classes/Command.php:310 classes/Command.php:330 classes/Command.php:353
+#: classes/Command.php:376 lib/command.php:353 lib/command.php:376
+#: lib/command.php:346 lib/command.php:369 lib/command.php:548
+#: lib/command.php:571
+msgid "Command not yet implemented."
msgstr ""
-#: actions/showstream.php:196
-msgid ""
-"Seen anything interesting recently? You haven't posted any notices yet, now "
-"would be a good time to start :)"
+#: classes/Command.php:313 classes/Command.php:356 lib/command.php:356
+#: lib/command.php:349 lib/command.php:551
+msgid "Notification off."
msgstr ""
-#: actions/showstream.php:198
+#: classes/Command.php:315 classes/Command.php:358 lib/command.php:358
+#: lib/command.php:351 lib/command.php:553
+msgid "Can't turn off notification."
+msgstr ""
+
+#: classes/Command.php:333 classes/Command.php:379 lib/command.php:379
+#: lib/command.php:372 lib/command.php:574
+msgid "Notification on."
+msgstr ""
+
+#: classes/Command.php:335 classes/Command.php:381 lib/command.php:381
+#: lib/command.php:374 lib/command.php:576
+msgid "Can't turn on notification."
+msgstr ""
+
+#: classes/Command.php:344 classes/Command.php:392
+msgid "Commands:\n"
+msgstr ""
+
+#: classes/Message.php:53 classes/Message.php:56 classes/Message.php:55
+msgid "Could not insert message."
+msgstr ""
+
+#: classes/Message.php:63 classes/Message.php:66 classes/Message.php:65
+msgid "Could not update message with new URI."
+msgstr ""
+
+#: lib/gallery.php:46
+msgid "User without matching profile in system."
+msgstr ""
+
+#: lib/mail.php:147 lib/mail.php:289
#, php-format
msgid ""
-"You can try to nudge %s or [post something to his or her attention](%%%%"
-"action.newnotice%%%%?status_textarea=%s)."
+"You have a new posting address on %1$s.\n"
+"\n"
msgstr ""
-#: actions/showstream.php:234
+#: lib/mail.php:249 lib/mail.php:508 lib/mail.php:509
#, php-format
-msgid ""
-"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. [Join now](%%%%action.register%%%%) to "
-"follow **%s**'s notices and many more! ([Read more](%%%%doc.help%%%%))"
+msgid "New private message from %s"
msgstr ""
-#: actions/showstream.php:239
+#: lib/mail.php:253 lib/mail.php:512
#, php-format
msgid ""
-"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
-"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
-"[StatusNet](http://status.net/) tool. "
+"%1$s (%2$s) sent you a private message:\n"
+"\n"
msgstr ""
-#: actions/smssettings.php:58
-msgid "SMS Settings"
+#: lib/mailbox.php:43 lib/mailbox.php:89 lib/mailbox.php:91
+msgid "Only the user can read their own mailboxes."
msgstr ""
-#: actions/smssettings.php:69
-#, php-format
-msgid "You can receive SMS messages through email from %%site.name%%."
+#: lib/openid.php:195 lib/openid.php:203
+msgid "This form should automatically submit itself. "
msgstr ""
-#: actions/smssettings.php:91
-msgid "SMS is not available."
+#: lib/personal.php:65 lib/personalgroupnav.php:113
+#: lib/personalgroupnav.php:114
+msgid "Favorites"
msgstr ""
-#: actions/smssettings.php:104
-msgid "SMS address"
+#: lib/personal.php:66 lib/personalgroupnav.php:114
+#: actions/favoritesrss.php:110 actions/showfavorites.php:77
+#: lib/personalgroupnav.php:115 actions/favoritesrss.php:111
+#, php-format
+msgid "%s's favorite notices"
msgstr ""
-#: actions/smssettings.php:112
-msgid "Current confirmed SMS-enabled phone number."
+#: lib/personal.php:66 lib/personalgroupnav.php:114
+#: lib/personalgroupnav.php:115
+msgid "User"
msgstr ""
-#: actions/smssettings.php:123
-msgid "Awaiting confirmation on this phone number."
+#: lib/personal.php:75 lib/personalgroupnav.php:123
+#: lib/personalgroupnav.php:124
+msgid "Inbox"
msgstr ""
-#: actions/smssettings.php:130
-msgid "Confirmation code"
+#: lib/personal.php:76 lib/personalgroupnav.php:124
+#: lib/personalgroupnav.php:125
+msgid "Your incoming messages"
msgstr ""
-#: actions/smssettings.php:131
-msgid "Enter the code you received on your phone."
+#: lib/personal.php:80 lib/personalgroupnav.php:128
+#: lib/personalgroupnav.php:129
+msgid "Outbox"
msgstr ""
-#: actions/smssettings.php:138
-msgid "SMS Phone number"
+#: lib/personal.php:81 lib/personalgroupnav.php:129
+#: lib/personalgroupnav.php:130
+msgid "Your sent messages"
msgstr ""
-#: actions/smssettings.php:140
-msgid "Phone number, no punctuation or spaces, with area code"
+#: lib/settingsaction.php:99 lib/connectsettingsaction.php:110
+msgid "Twitter"
msgstr ""
-#: actions/smssettings.php:174
-msgid ""
-"Send me notices through SMS; I understand I may incur exorbitant charges "
-"from my carrier."
+#: lib/settingsaction.php:100 lib/connectsettingsaction.php:111
+msgid "Twitter integration options"
msgstr ""
-#: actions/smssettings.php:306
-msgid "No phone number."
+#: lib/util.php:1718 lib/messageform.php:139 lib/noticelist.php:422
+#: lib/messageform.php:137 lib/noticelist.php:425 lib/messageform.php:135
+#: lib/noticelist.php:433 lib/messageform.php:146
+msgid "To"
msgstr ""
-#: actions/smssettings.php:311
-msgid "No carrier selected."
+#: scripts/maildaemon.php:45 scripts/maildaemon.php:48
+#: scripts/maildaemon.php:47
+msgid "Could not parse message."
msgstr ""
-#: actions/smssettings.php:318
-msgid "That is already your phone number."
+#: actions/all.php:63 actions/facebookhome.php:162 actions/all.php:66
+#: actions/facebookhome.php:161 actions/all.php:48
+#: actions/facebookhome.php:156 actions/all.php:84
+#, php-format
+msgid "%s and friends, page %d"
msgstr ""
-#: actions/smssettings.php:321
-msgid "That phone number already belongs to another user."
+#: actions/avatarsettings.php:76
+msgid "You can upload your personal avatar."
msgstr ""
-#: actions/smssettings.php:347
-msgid ""
-"A confirmation code was sent to the phone number you added. Check your phone "
-"for the code and instructions on how to use it."
+#: actions/avatarsettings.php:117 actions/avatarsettings.php:191
+#: actions/grouplogo.php:250 actions/avatarsettings.php:119
+#: actions/avatarsettings.php:194 actions/grouplogo.php:256
+#: actions/grouplogo.php:251
+msgid "Avatar settings"
msgstr ""
-#: actions/smssettings.php:374
-msgid "That is the wrong confirmation number."
+#: actions/avatarsettings.php:124 actions/avatarsettings.php:199
+#: actions/grouplogo.php:198 actions/grouplogo.php:258
+#: actions/avatarsettings.php:126 actions/avatarsettings.php:202
+#: actions/grouplogo.php:204 actions/grouplogo.php:264
+#: actions/grouplogo.php:199 actions/grouplogo.php:259
+msgid "Original"
msgstr ""
-#: actions/smssettings.php:405
-msgid "That is not your phone number."
+#: actions/avatarsettings.php:139 actions/avatarsettings.php:211
+#: actions/grouplogo.php:209 actions/grouplogo.php:270
+#: actions/avatarsettings.php:141 actions/avatarsettings.php:214
+#: actions/grouplogo.php:215 actions/grouplogo.php:276
+#: actions/grouplogo.php:210 actions/grouplogo.php:271
+msgid "Preview"
msgstr ""
-#: actions/smssettings.php:465
-msgid "Mobile carrier"
+#: actions/avatarsettings.php:225 actions/grouplogo.php:284
+#: actions/avatarsettings.php:228 actions/grouplogo.php:291
+#: actions/grouplogo.php:286
+msgid "Crop"
msgstr ""
-#: actions/smssettings.php:469
-msgid "Select a carrier"
+#: actions/avatarsettings.php:248 actions/deletenotice.php:133
+#: actions/emailsettings.php:224 actions/grouplogo.php:307
+#: actions/imsettings.php:200 actions/login.php:102 actions/newmessage.php:100
+#: actions/newnotice.php:96 actions/openidsettings.php:188
+#: actions/othersettings.php:136 actions/passwordsettings.php:131
+#: actions/profilesettings.php:172 actions/register.php:113
+#: actions/remotesubscribe.php:53 actions/smssettings.php:216
+#: actions/subedit.php:38 actions/twittersettings.php:290
+#: actions/userauthorization.php:39
+msgid "There was a problem with your session token. "
msgstr ""
-#: actions/smssettings.php:476
-#, php-format
-msgid ""
-"Mobile carrier for your phone. If you know a carrier that accepts SMS over "
-"email but isn't listed here, send email to let us know at %s."
+#: actions/avatarsettings.php:303 actions/grouplogo.php:360
+#: actions/avatarsettings.php:308 actions/avatarsettings.php:322
+msgid "Pick a square area of the image to be your avatar"
msgstr ""
-#: actions/smssettings.php:498
-msgid "No code entered"
+#: actions/avatarsettings.php:327 actions/grouplogo.php:384
+#: actions/avatarsettings.php:323 actions/grouplogo.php:382
+#: actions/grouplogo.php:377 actions/avatarsettings.php:337
+msgid "Lost our file data."
msgstr ""
-#: actions/subedit.php:70
-msgid "You are not subscribed to that profile."
+#: actions/avatarsettings.php:334 actions/grouplogo.php:391
+#: classes/User_group.php:112 lib/imagefile.php:112 lib/imagefile.php:113
+#: lib/imagefile.php:118
+msgid "Lost our file."
msgstr ""
-#: actions/subedit.php:83
-msgid "Could not save subscription."
+#: actions/avatarsettings.php:349 actions/avatarsettings.php:383
+#: actions/grouplogo.php:406 actions/grouplogo.php:440
+#: classes/User_group.php:129 classes/User_group.php:161 lib/imagefile.php:144
+#: lib/imagefile.php:191 lib/imagefile.php:145 lib/imagefile.php:192
+#: lib/imagefile.php:150 lib/imagefile.php:197
+msgid "Unknown file type"
msgstr ""
-#: actions/subscribe.php:55
-msgid "Not a local user."
+#: actions/block.php:69 actions/subedit.php:46 actions/unblock.php:70
+#: actions/groupblock.php:71 actions/groupunblock.php:71
+#: actions/makeadmin.php:71
+msgid "No profile specified."
msgstr ""
-#: actions/subscribe.php:69
-msgid "Subscribed"
+#: actions/block.php:74 actions/subedit.php:53 actions/tagother.php:46
+#: actions/unblock.php:75 actions/groupblock.php:76
+#: actions/groupunblock.php:76 actions/makeadmin.php:76
+msgid "No profile with that ID."
msgstr ""
-#: actions/subscribers.php:50
-#, php-format
-msgid "%s subscribers"
+#: actions/block.php:111 actions/block.php:134
+msgid "Block user"
msgstr ""
-#: actions/subscribers.php:52
-#, php-format
-msgid "%s subscribers, page %d"
+#: actions/block.php:129
+msgid "Are you sure you want to block this user? "
msgstr ""
-#: actions/subscribers.php:63
-msgid "These are the users who have subscribed to your notices."
+#: actions/block.php:162 actions/block.php:165
+msgid "You have already blocked this user."
msgstr ""
-#: actions/subscribers.php:67
+#: actions/block.php:167 actions/block.php:170
+msgid "Failed to save block information."
+msgstr ""
+
+#: actions/confirmaddress.php:159
#, php-format
-msgid "These are the users who have subscribed to %s's notices."
+msgid "The address \"%s\" has been "
msgstr ""
-#: actions/subscribers.php:108
-msgid ""
-"You have no subscribers. Try subscribing to users you know and they might "
-"return the favor"
+#: actions/deletenotice.php:73
+msgid "You are about to permanently delete a notice. "
msgstr ""
-#: actions/subscribers.php:110
-#, php-format
-msgid "%s has no subscribers. Want to be the first?"
+#: actions/disfavor.php:94
+msgid "Add to favorites"
msgstr ""
-#: actions/subscribers.php:114
+#: actions/editgroup.php:54 actions/editgroup.php:56
#, php-format
-msgid ""
-"%s has no subscribers. Why not [register an account](%%%%action.register%%%"
-"%) and be the first?"
+msgid "Edit %s group"
msgstr ""
-#: actions/subscriptions.php:52
-#, php-format
-msgid "%s subscriptions"
+#: actions/editgroup.php:66 actions/groupbyid.php:72 actions/grouplogo.php:66
+#: actions/joingroup.php:60 actions/newgroup.php:65 actions/showgroup.php:100
+#: actions/grouplogo.php:70 actions/grouprss.php:80 actions/editgroup.php:68
+#: actions/groupdesignsettings.php:68 actions/showgroup.php:105
+msgid "Inboxes must be enabled for groups to work"
msgstr ""
-#: actions/subscriptions.php:54
-#, php-format
-msgid "%s subscriptions, page %d"
+#: actions/editgroup.php:71 actions/grouplogo.php:71 actions/newgroup.php:70
+#: actions/grouplogo.php:75 actions/editgroup.php:73 actions/editgroup.php:68
+#: actions/grouplogo.php:70 actions/newgroup.php:65
+msgid "You must be logged in to create a group."
msgstr ""
-#: actions/subscriptions.php:65
-msgid "These are the users whose notices you have subscribed to."
+#: actions/editgroup.php:87 actions/grouplogo.php:87
+#: actions/groupmembers.php:76 actions/joingroup.php:81
+#: actions/showgroup.php:121 actions/grouplogo.php:91 actions/grouprss.php:96
+#: actions/blockedfromgroup.php:73 actions/editgroup.php:89
+#: actions/groupdesignsettings.php:89 actions/showgroup.php:126
+#: actions/editgroup.php:84 actions/groupdesignsettings.php:84
+#: actions/grouplogo.php:86 actions/grouprss.php:91 actions/joingroup.php:76
+msgid "No nickname"
msgstr ""
-#: actions/subscriptions.php:69
-#, php-format
-msgid "These are the users whose notices %s has subscribed to."
+#: actions/editgroup.php:99 actions/groupbyid.php:88 actions/grouplogo.php:100
+#: actions/groupmembers.php:83 actions/joingroup.php:88
+#: actions/showgroup.php:128 actions/grouplogo.php:104
+#: actions/grouprss.php:103 actions/blockedfromgroup.php:80
+#: actions/editgroup.php:101 actions/groupdesignsettings.php:102
+#: actions/showgroup.php:133 actions/editgroup.php:96 actions/groupbyid.php:83
+#: actions/groupdesignsettings.php:97 actions/grouplogo.php:99
+#: actions/grouprss.php:98 actions/joingroup.php:83 actions/showgroup.php:137
+msgid "No such group"
msgstr ""
-#: actions/subscriptions.php:121
-#, php-format
-msgid ""
-"You have not subscribed to anyone's notices right now. Try subscribing to "
-"users you know. Try [user search](%%action.peoplesearch%%), look for members "
-"in groups you're interested in and in our [featured users](%%action.featured%"
-"%). If you are a [Twitter user](%%action.twittersettings%%), you can "
-"automatically subscribe to users you already follow there."
+#: actions/editgroup.php:106 actions/editgroup.php:165
+#: actions/grouplogo.php:107 actions/grouplogo.php:111
+#: actions/editgroup.php:108 actions/editgroup.php:167
+#: actions/groupdesignsettings.php:109 actions/editgroup.php:103
+#: actions/editgroup.php:168 actions/groupdesignsettings.php:104
+#: actions/grouplogo.php:106
+msgid "You must be an admin to edit the group"
msgstr ""
-#: actions/subscriptions.php:123 actions/subscriptions.php:127
-#, php-format
-msgid "%s is not listening to anyone."
+#: actions/editgroup.php:157 actions/editgroup.php:159
+#: actions/editgroup.php:154
+msgid "Use this form to edit the group."
msgstr ""
-#: actions/subscriptions.php:194
-msgid "Jabber"
+#: actions/editgroup.php:179 actions/newgroup.php:130 actions/register.php:156
+msgid "Nickname must have only lowercase letters "
msgstr ""
-#: actions/subscriptions.php:199 lib/connectsettingsaction.php:115
-msgid "SMS"
+#: actions/editgroup.php:198 actions/newgroup.php:149
+#: actions/editgroup.php:200 actions/newgroup.php:150
+msgid "description is too long (max 140 chars)."
msgstr ""
-#: actions/tagother.php:33
-msgid "Not logged in"
+#: actions/editgroup.php:218 actions/editgroup.php:253
+msgid "Could not update group."
msgstr ""
-#: actions/tagother.php:39
-msgid "No id argument."
+#: actions/editgroup.php:226 actions/editgroup.php:269
+msgid "Options saved."
msgstr ""
-#: actions/tagother.php:65
+#: actions/emailsettings.php:107 actions/imsettings.php:108
#, php-format
-msgid "Tag %s"
+msgid "Awaiting confirmation on this address. "
msgstr ""
-#: actions/tagother.php:77 lib/userprofile.php:75
-msgid "User profile"
+#: actions/emailsettings.php:139 actions/smssettings.php:150
+msgid "Make a new email address for posting to; "
msgstr ""
-#: actions/tagother.php:81 lib/userprofile.php:102
-msgid "Photo"
+#: actions/emailsettings.php:157
+msgid "Send me email when someone "
msgstr ""
-#: actions/tagother.php:141
-msgid "Tag user"
+#: actions/emailsettings.php:168 actions/emailsettings.php:173
+#: actions/emailsettings.php:179
+msgid "Allow friends to nudge me and send me an email."
msgstr ""
-#: actions/tagother.php:151
-msgid ""
-"Tags for this user (letters, numbers, -, ., and _), comma- or space- "
-"separated"
+#: actions/emailsettings.php:321
+msgid "That email address already belongs "
msgstr ""
-#: actions/tagother.php:193
-msgid ""
-"You can only tag users you are subscribed to or who are subscribed to you."
+#: actions/emailsettings.php:343
+msgid "A confirmation code was sent to the email address you added. "
msgstr ""
-#: actions/tagother.php:200
-msgid "Could not save tags."
+#: actions/facebookhome.php:110 actions/facebookhome.php:109
+msgid "Server error - couldn't get user!"
msgstr ""
-#: actions/tagother.php:236
-msgid "Use this form to add tags to your subscribers or subscriptions."
+#: actions/facebookhome.php:196
+#, php-format
+msgid "If you would like the %s app to automatically update "
msgstr ""
-#: actions/tag.php:68
+#: actions/facebookhome.php:213 actions/facebooksettings.php:137
#, php-format
-msgid "Notices tagged with %s, page %d"
+msgid "Allow %s to update my Facebook status"
msgstr ""
-#: actions/tag.php:86
-#, php-format
-msgid "Notice feed for tag %s (RSS 1.0)"
+#: actions/facebookhome.php:218 actions/facebookhome.php:223
+#: actions/facebookhome.php:217
+msgid "Skip"
msgstr ""
-#: actions/tag.php:92
-#, php-format
-msgid "Notice feed for tag %s (RSS 2.0)"
+#: actions/facebookhome.php:235 lib/facebookaction.php:479
+#: lib/facebookaction.php:471
+msgid "No notice content!"
msgstr ""
-#: actions/tag.php:98
-#, php-format
-msgid "Notice feed for tag %s (Atom)"
+#: actions/facebookhome.php:295 lib/action.php:870 lib/facebookaction.php:399
+#: actions/facebookhome.php:253 lib/action.php:973 lib/facebookaction.php:433
+#: actions/facebookhome.php:247 lib/action.php:1037 lib/facebookaction.php:435
+#: lib/action.php:1053
+msgid "Pagination"
msgstr ""
-#: actions/tagrss.php:35
-msgid "No such tag."
+#: actions/facebookhome.php:304 lib/action.php:879 lib/facebookaction.php:408
+#: actions/facebookhome.php:262 lib/action.php:982 lib/facebookaction.php:442
+#: actions/facebookhome.php:256 lib/action.php:1046 lib/facebookaction.php:444
+#: lib/action.php:1062
+msgid "After"
msgstr ""
-#: actions/twitapitrends.php:87
-msgid "API method under construction."
+#: actions/facebookhome.php:312 lib/action.php:887 lib/facebookaction.php:416
+#: actions/facebookhome.php:270 lib/action.php:990 lib/facebookaction.php:450
+#: actions/facebookhome.php:264 lib/action.php:1054 lib/facebookaction.php:452
+#: lib/action.php:1070
+msgid "Before"
msgstr ""
-#: actions/unsubscribe.php:77
-msgid "No profile id in request."
+#: actions/facebookinvite.php:70 actions/facebookinvite.php:72
+#, php-format
+msgid "Thanks for inviting your friends to use %s"
msgstr ""
-#: actions/unsubscribe.php:84
-msgid "No profile with that id."
+#: actions/facebookinvite.php:72 actions/facebookinvite.php:74
+msgid "Invitations have been sent to the following users:"
msgstr ""
-#: actions/unsubscribe.php:98
-msgid "Unsubscribed"
+#: actions/facebookinvite.php:96 actions/facebookinvite.php:102
+#: actions/facebookinvite.php:94
+#, php-format
+msgid "You have been invited to %s"
msgstr ""
-#: actions/updateprofile.php:62 actions/userauthorization.php:330
+#: actions/facebookinvite.php:105 actions/facebookinvite.php:111
+#: actions/facebookinvite.php:103
#, php-format
-msgid "Listenee stream license ‘%s’ is not compatible with site license ‘%s’."
+msgid "Invite your friends to use %s"
msgstr ""
-#: actions/userauthorization.php:105
-msgid "Authorize subscription"
+#: actions/facebookinvite.php:113 actions/facebookinvite.php:126
+#: actions/facebookinvite.php:124
+#, php-format
+msgid "Friends already using %s:"
msgstr ""
-#: actions/userauthorization.php:110
-msgid ""
-"Please check these details to make sure that you want to subscribe to this "
-"user’s notices. If you didn’t just ask to subscribe to someone’s notices, "
-"click “Reject”."
+#: actions/facebookinvite.php:130 actions/facebookinvite.php:143
+#: actions/facebookinvite.php:142
+#, php-format
+msgid "Send invitations"
msgstr ""
-#: actions/userauthorization.php:188
-msgid "License"
+#: actions/facebookremove.php:56
+msgid "Couldn't remove Facebook user."
msgstr ""
-#: actions/userauthorization.php:209
-msgid "Accept"
+#: actions/facebooksettings.php:65
+msgid "There was a problem saving your sync preferences!"
msgstr ""
-#: actions/userauthorization.php:210 lib/subscribeform.php:115
-#: lib/subscribeform.php:139
-msgid "Subscribe to this user"
+#: actions/facebooksettings.php:67
+msgid "Sync preferences saved."
msgstr ""
-#: actions/userauthorization.php:211
-msgid "Reject"
+#: actions/facebooksettings.php:90
+msgid "Automatically update my Facebook status with my notices."
msgstr ""
-#: actions/userauthorization.php:212
-msgid "Reject this subscription"
+#: actions/facebooksettings.php:97
+msgid "Send \"@\" replies to Facebook."
msgstr ""
-#: actions/userauthorization.php:225
-msgid "No authorization request!"
+#: actions/facebooksettings.php:106
+msgid "Prefix"
msgstr ""
-#: actions/userauthorization.php:247
-msgid "Subscription authorized"
+#: actions/facebooksettings.php:108
+msgid "A string to prefix notices with."
msgstr ""
-#: actions/userauthorization.php:249
-msgid ""
-"The subscription has been authorized, but no callback URL was passed. Check "
-"with the site’s instructions for details on how to authorize the "
-"subscription. Your subscription token is:"
+#: actions/facebooksettings.php:124
+#, php-format
+msgid "If you would like %s to automatically update "
msgstr ""
-#: actions/userauthorization.php:259
-msgid "Subscription rejected"
+#: actions/facebooksettings.php:147
+msgid "Sync preferences"
msgstr ""
-#: actions/userauthorization.php:261
-msgid ""
-"The subscription has been rejected, but no callback URL was passed. Check "
-"with the site’s instructions for details on how to fully reject the "
-"subscription."
+#: actions/favor.php:94 lib/disfavorform.php:140 actions/favor.php:92
+msgid "Disfavor favorite"
msgstr ""
-#: actions/userauthorization.php:296
-#, php-format
-msgid "Listener URI ‘%s’ not found here"
+#: actions/favorited.php:65 lib/popularnoticesection.php:76
+#: lib/publicgroupnav.php:91 lib/popularnoticesection.php:82
+#: lib/publicgroupnav.php:93 lib/popularnoticesection.php:91
+#: lib/popularnoticesection.php:87
+msgid "Popular notices"
msgstr ""
-#: actions/userauthorization.php:301
+#: actions/favorited.php:67
#, php-format
-msgid "Listenee URI ‘%s’ is too long."
+msgid "Popular notices, page %d"
msgstr ""
-#: actions/userauthorization.php:307
-#, php-format
-msgid "Listenee URI ‘%s’ is a local user."
+#: actions/favorited.php:79
+msgid "The most popular notices on the site right now."
msgstr ""
-#: actions/userauthorization.php:322
-#, php-format
-msgid "Profile URL ‘%s’ is for a local user."
+#: actions/featured.php:69 lib/featureduserssection.php:82
+#: lib/publicgroupnav.php:87 lib/publicgroupnav.php:89
+#: lib/featureduserssection.php:87
+msgid "Featured users"
msgstr ""
-#: actions/userauthorization.php:338
+#: actions/featured.php:71
#, php-format
-msgid "Avatar URL ‘%s’ is not valid."
+msgid "Featured users, page %d"
msgstr ""
-#: actions/userauthorization.php:343
+#: actions/featured.php:99
#, php-format
-msgid "Can’t read avatar URL ‘%s’."
+msgid "A selection of some of the great users on %s"
msgstr ""
-#: actions/userauthorization.php:348
-#, php-format
-msgid "Wrong image type for avatar URL ‘%s’."
+#: actions/finishremotesubscribe.php:188 actions/finishremotesubscribe.php:96
+msgid "That user has blocked you from subscribing."
msgstr ""
-#: actions/userbyid.php:70
-msgid "No id."
+#: actions/groupbyid.php:79 actions/groupbyid.php:74
+msgid "No ID"
msgstr ""
-#: actions/userdesignsettings.php:76 lib/designsettings.php:65
-msgid "Profile design"
+#: actions/grouplogo.php:138 actions/grouplogo.php:191
+#: actions/grouplogo.php:144 actions/grouplogo.php:197
+#: actions/grouplogo.php:139 actions/grouplogo.php:192
+msgid "Group logo"
msgstr ""
-#: actions/userdesignsettings.php:87 lib/designsettings.php:76
-msgid ""
-"Customize the way your profile looks with a background image and a colour "
-"palette of your choice."
+#: actions/grouplogo.php:149
+msgid "You can upload a logo image for your group."
msgstr ""
-#: actions/userdesignsettings.php:282
-msgid "Enjoy your hotdog!"
+#: actions/grouplogo.php:448 actions/grouplogo.php:401
+#: actions/grouplogo.php:396
+msgid "Logo updated."
msgstr ""
-#: actions/usergroups.php:64
-#, php-format
-msgid "%s groups, page %d"
+#: actions/grouplogo.php:450 actions/grouplogo.php:403
+#: actions/grouplogo.php:398
+msgid "Failed updating logo."
msgstr ""
-#: actions/usergroups.php:130
-msgid "Search for more groups"
+#: actions/groupmembers.php:93 lib/groupnav.php:91
+#, php-format
+msgid "%s group members"
msgstr ""
-#: actions/usergroups.php:153
+#: actions/groupmembers.php:96
#, php-format
-msgid "%s is not a member of any group."
+msgid "%s group members, page %d"
msgstr ""
-#: actions/usergroups.php:158
-#, php-format
-msgid "Try [searching for groups](%%action.groupsearch%%) and joining them."
+#: actions/groupmembers.php:111
+msgid "A list of the users in this group."
msgstr ""
-#: classes/File.php:137
-#, php-format
-msgid ""
-"No file may be larger than %d bytes and the file you sent was %d bytes. Try "
-"to upload a smaller version."
+#: actions/groups.php:62 actions/showstream.php:518 lib/publicgroupnav.php:79
+#: lib/subgroupnav.php:96 lib/publicgroupnav.php:81 lib/profileaction.php:220
+#: lib/subgroupnav.php:98
+msgid "Groups"
msgstr ""
-#: classes/File.php:147
+#: actions/groups.php:64
#, php-format
-msgid "A file this large would exceed your user quota of %d bytes."
+msgid "Groups, page %d"
msgstr ""
-#: classes/File.php:154
+#: actions/groups.php:90
#, php-format
-msgid "A file this large would exceed your monthly quota of %d bytes."
+msgid "%%%%site.name%%%% groups let you find and talk with "
msgstr ""
-#: classes/Message.php:55
-msgid "Could not insert message."
+#: actions/groups.php:106 actions/usergroups.php:124 lib/groupeditform.php:123
+#: actions/usergroups.php:125 actions/groups.php:107 lib/groupeditform.php:122
+msgid "Create a new group"
msgstr ""
-#: classes/Message.php:65
-msgid "Could not update message with new URI."
+#: actions/groupsearch.php:57
+#, php-format
+msgid ""
+"Search for groups on %%site.name%% by their name, location, or description. "
msgstr ""
-#: classes/Notice.php:164
-#, php-format
-msgid "DB error inserting hashtag: %s"
+#: actions/groupsearch.php:63 actions/groupsearch.php:58
+msgid "Group search"
msgstr ""
-#: classes/Notice.php:179
-msgid "Problem saving notice. Too long."
+#: actions/imsettings.php:70
+msgid "You can send and receive notices through "
msgstr ""
-#: classes/Notice.php:183
-msgid "Problem saving notice. Unknown user."
+#: actions/imsettings.php:120
+#, php-format
+msgid "Jabber or GTalk address, "
msgstr ""
-#: classes/Notice.php:188
-msgid ""
-"Too many notices too fast; take a breather and post again in a few minutes."
+#: actions/imsettings.php:147
+msgid "Send me replies through Jabber/GTalk "
msgstr ""
-#: classes/Notice.php:194
-msgid ""
-"Too many duplicate messages too quickly; take a breather and post again in a "
-"few minutes."
+#: actions/imsettings.php:321
+#, php-format
+msgid "A confirmation code was sent "
msgstr ""
-#: classes/Notice.php:202
-msgid "You are banned from posting notices on this site."
+#: actions/joingroup.php:65 actions/joingroup.php:60
+msgid "You must be logged in to join a group."
msgstr ""
-#: classes/Notice.php:268 classes/Notice.php:293
-msgid "Problem saving notice."
+#: actions/joingroup.php:95 actions/joingroup.php:90 lib/command.php:217
+msgid "You are already a member of that group"
msgstr ""
-#: classes/Notice.php:1120
+#: actions/joingroup.php:128 actions/joingroup.php:133 lib/command.php:234
#, php-format
-msgid "DB error inserting reply: %s"
+msgid "Could not join user %s to group %s"
msgstr ""
-#: classes/User.php:333
+#: actions/joingroup.php:135 actions/joingroup.php:140 lib/command.php:239
#, php-format
-msgid "Welcome to %1$s, @%2$s!"
+msgid "%s joined group %s"
msgstr ""
-#: lib/accountsettingsaction.php:108 lib/personalgroupnav.php:109
-msgid "Profile"
+#: actions/leavegroup.php:60
+msgid "Inboxes must be enabled for groups to work."
msgstr ""
-#: lib/accountsettingsaction.php:109
-msgid "Change your profile settings"
+#: actions/leavegroup.php:65 actions/leavegroup.php:60
+msgid "You must be logged in to leave a group."
msgstr ""
-#: lib/accountsettingsaction.php:112
-msgid "Upload an avatar"
+#: actions/leavegroup.php:88 actions/groupblock.php:86
+#: actions/groupunblock.php:86 actions/makeadmin.php:86
+#: actions/foafgroup.php:44 actions/foafgroup.php:62 actions/leavegroup.php:83
+#: lib/command.php:212 lib/command.php:263
+msgid "No such group."
msgstr ""
-#: lib/accountsettingsaction.php:115
-msgid "Change your password"
+#: actions/leavegroup.php:95 actions/leavegroup.php:90 lib/command.php:268
+msgid "You are not a member of that group."
msgstr ""
-#: lib/accountsettingsaction.php:118
-msgid "Change email handling"
+#: actions/leavegroup.php:100
+msgid "You may not leave a group while you are its administrator."
msgstr ""
-#: lib/accountsettingsaction.php:120 lib/groupnav.php:118
-msgid "Design"
+#: actions/leavegroup.php:130 actions/leavegroup.php:124
+#: actions/leavegroup.php:119 lib/command.php:278
+msgid "Could not find membership record."
msgstr ""
-#: lib/accountsettingsaction.php:121
-msgid "Design your profile"
+#: actions/leavegroup.php:138 actions/leavegroup.php:132
+#: actions/leavegroup.php:127 lib/command.php:284
+#, php-format
+msgid "Could not remove user %s to group %s"
msgstr ""
-#: lib/accountsettingsaction.php:123
-msgid "Other"
+#: actions/leavegroup.php:145 actions/leavegroup.php:139
+#: actions/leavegroup.php:134 lib/command.php:289
+#, php-format
+msgid "%s left group %s"
msgstr ""
-#: lib/accountsettingsaction.php:124
-msgid "Other options"
+#: actions/login.php:225 lib/facebookaction.php:304 actions/login.php:208
+#: actions/login.php:216 actions/login.php:243
+msgid "Login to site"
msgstr ""
-#: lib/action.php:144
-#, php-format
-msgid "%s - %s"
+#: actions/microsummary.php:69
+msgid "No current status"
msgstr ""
-#: lib/action.php:159
-msgid "Untitled page"
+#: actions/newgroup.php:53
+msgid "New group"
msgstr ""
-#: lib/action.php:424
-msgid "Primary site navigation"
+#: actions/newgroup.php:115 actions/newgroup.php:110
+msgid "Use this form to create a new group."
msgstr ""
-#: lib/action.php:430
-msgid "Home"
+#: actions/newgroup.php:177 actions/newgroup.php:209
+#: actions/apigroupcreate.php:136 actions/newgroup.php:204
+msgid "Could not create group."
msgstr ""
-#: lib/action.php:430
-msgid "Personal profile and friends timeline"
+#: actions/newgroup.php:191 actions/newgroup.php:229
+#: actions/apigroupcreate.php:166 actions/newgroup.php:224
+msgid "Could not set group membership."
msgstr ""
-#: lib/action.php:432
-msgid "Account"
+#: actions/newmessage.php:119 actions/newnotice.php:132
+msgid "That's too long. "
msgstr ""
-#: lib/action.php:432
-msgid "Change your email, avatar, password, profile"
+#: actions/newmessage.php:134
+msgid "Don't send a message to yourself; "
msgstr ""
-#: lib/action.php:435
-msgid "Connect"
+#: actions/newnotice.php:166 actions/newnotice.php:174
+#: actions/newnotice.php:272 actions/newnotice.php:199
+msgid "Notice posted"
msgstr ""
-#: lib/action.php:435
-msgid "Connect to services"
+#: actions/newnotice.php:200 classes/Channel.php:163 actions/newnotice.php:208
+#: lib/channel.php:170 actions/newmessage.php:207 actions/newnotice.php:387
+#: actions/newmessage.php:210 actions/newnotice.php:233
+msgid "Ajax Error"
msgstr ""
-#: lib/action.php:439 lib/subgroupnav.php:105
-msgid "Invite"
+#: actions/nudge.php:85
+msgid ""
+"This user doesn't allow nudges or hasn't confirmed or set his email yet."
msgstr ""
-#: lib/action.php:440 lib/subgroupnav.php:106
-#, php-format
-msgid "Invite friends and colleagues to join you on %s"
+#: actions/nudge.php:94
+msgid "Nudge sent"
msgstr ""
-#: lib/action.php:445
-msgid "Logout"
+#: actions/nudge.php:97
+msgid "Nudge sent!"
msgstr ""
-#: lib/action.php:445
-msgid "Logout from the site"
+#: actions/openidlogin.php:97 actions/openidlogin.php:106
+msgid "OpenID login"
msgstr ""
-#: lib/action.php:450
-msgid "Create an account"
+#: actions/openidsettings.php:128
+msgid "Removing your only OpenID "
msgstr ""
-#: lib/action.php:453
-msgid "Login to the site"
+#: actions/othersettings.php:60
+msgid "Other Settings"
msgstr ""
-#: lib/action.php:456 lib/action.php:719
-msgid "Help"
+#: actions/othersettings.php:71
+msgid "Manage various other options."
msgstr ""
-#: lib/action.php:456
-msgid "Help me!"
+#: actions/othersettings.php:93
+msgid "URL Auto-shortening"
msgstr ""
-#: lib/action.php:459
-msgid "Search"
+#: actions/othersettings.php:112
+msgid "Service"
msgstr ""
-#: lib/action.php:459
-msgid "Search for users or text"
+#: actions/othersettings.php:113 actions/othersettings.php:111
+#: actions/othersettings.php:118
+msgid "Automatic shortening service to use."
msgstr ""
-#: lib/action.php:480
-msgid "Site notice"
+#: actions/othersettings.php:144 actions/othersettings.php:146
+#: actions/othersettings.php:153
+msgid "URL shortening service is too long (max 50 chars)."
msgstr ""
-#: lib/action.php:546
-msgid "Local views"
+#: actions/passwordsettings.php:69
+msgid "Change your password."
msgstr ""
-#: lib/action.php:612
-msgid "Page notice"
+#: actions/passwordsettings.php:89 actions/recoverpassword.php:228
+#: actions/passwordsettings.php:95 actions/recoverpassword.php:231
+msgid "Password change"
msgstr ""
-#: lib/action.php:714
-msgid "Secondary site navigation"
+#: actions/peopletag.php:35 actions/peopletag.php:70
+#, php-format
+msgid "Not a valid people tag: %s"
msgstr ""
-#: lib/action.php:721
-msgid "About"
+#: actions/peopletag.php:47 actions/peopletag.php:144
+#, php-format
+msgid "Users self-tagged with %s - page %d"
msgstr ""
-#: lib/action.php:723
-msgid "FAQ"
+#: actions/peopletag.php:91
+#, php-format
+msgid "These are users who have tagged themselves \"%s\" "
msgstr ""
-#: lib/action.php:727
-msgid "TOS"
+#: actions/profilesettings.php:91 actions/profilesettings.php:99
+msgid "Profile information"
msgstr ""
-#: lib/action.php:730
-msgid "Privacy"
+#: actions/profilesettings.php:124 actions/profilesettings.php:125
+#: actions/profilesettings.php:140
+msgid ""
+"Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated"
msgstr ""
-#: lib/action.php:732
-msgid "Source"
+#: actions/profilesettings.php:144
+msgid "Automatically subscribe to whoever "
msgstr ""
-#: lib/action.php:734
-msgid "Contact"
+#: actions/profilesettings.php:229 actions/tagother.php:176
+#: actions/tagother.php:178 actions/profilesettings.php:230
+#: actions/profilesettings.php:246
+#, php-format
+msgid "Invalid tag: \"%s\""
msgstr ""
-#: lib/action.php:736
-msgid "Badge"
+#: actions/profilesettings.php:311 actions/profilesettings.php:310
+#: actions/profilesettings.php:336
+msgid "Couldn't save tags."
msgstr ""
-#: lib/action.php:764
-msgid "StatusNet software license"
+#: actions/public.php:107 actions/public.php:110 actions/public.php:118
+#: actions/public.php:129
+#, php-format
+msgid "Public timeline, page %d"
+msgstr ""
+
+#: actions/public.php:173 actions/public.php:184 actions/public.php:210
+#: actions/public.php:92
+msgid "Could not retrieve public stream."
msgstr ""
-#: lib/action.php:767
+#: actions/public.php:220
#, php-format
msgid ""
-"**%%site.name%%** is a microblogging service brought to you by [%%site."
-"broughtby%%](%%site.broughtbyurl%%). "
+"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
+"blogging) service "
msgstr ""
-#: lib/action.php:769
-#, php-format
-msgid "**%%site.name%%** is a microblogging service. "
+#: actions/publictagcloud.php:57
+msgid "Public tag cloud"
msgstr ""
-#: lib/action.php:771
+#: actions/publictagcloud.php:63
#, php-format
-msgid ""
-"It runs the [StatusNet](http://status.net/) microblogging software, version %"
-"s, available under the [GNU Affero General Public License](http://www.fsf."
-"org/licensing/licenses/agpl-3.0.html)."
+msgid "These are most popular recent tags on %s "
msgstr ""
-#: lib/action.php:785
-msgid "Site content license"
+#: actions/publictagcloud.php:119 actions/publictagcloud.php:135
+msgid "Tag cloud"
msgstr ""
-#: lib/action.php:794
-msgid "All "
+#: actions/register.php:139 actions/register.php:349 actions/register.php:79
+#: actions/register.php:177 actions/register.php:394 actions/register.php:183
+#: actions/register.php:398 actions/register.php:85 actions/register.php:189
+#: actions/register.php:404
+msgid "Sorry, only invited people can register."
msgstr ""
-#: lib/action.php:799
-msgid "license."
+#: actions/register.php:149
+msgid "You can't register if you don't "
msgstr ""
-#: lib/action.php:1053
-msgid "Pagination"
+#: actions/register.php:286
+msgid "With this form you can create "
msgstr ""
-#: lib/action.php:1062
-msgid "After"
+#: actions/register.php:368
+msgid "1-64 lowercase letters or numbers, "
msgstr ""
-#: lib/action.php:1070
-msgid "Before"
+#: actions/register.php:382 actions/register.php:386
+msgid "Used only for updates, announcements, "
msgstr ""
-#: lib/attachmentlist.php:87
-msgid "Attachments"
+#: actions/register.php:398
+msgid "URL of your homepage, blog, "
msgstr ""
-#: lib/attachmentlist.php:265
-msgid "Author"
-msgstr ""
-
-#: lib/attachmentlist.php:278
-msgid "Provider"
-msgstr ""
-
-#: lib/attachmentnoticesection.php:67
-msgid "Notices where this attachment appears"
+#: actions/register.php:404
+msgid "Describe yourself and your "
msgstr ""
-#: lib/attachmenttagcloudsection.php:48
-msgid "Tags for this attachment"
+#: actions/register.php:410
+msgid "Where you are, like \"City, "
msgstr ""
-#: lib/channel.php:138 lib/channel.php:158
-msgid "Command results"
+#: actions/register.php:432
+msgid " except this private data: password, "
msgstr ""
-#: lib/channel.php:210
-msgid "Command complete"
+#: actions/register.php:471
+#, php-format
+msgid "Congratulations, %s! And welcome to %%%%site.name%%%%. "
msgstr ""
-#: lib/channel.php:221
-msgid "Command failed"
+#: actions/register.php:495
+msgid "(You should receive a message by email "
msgstr ""
-#: lib/command.php:44
-msgid "Sorry, this command is not yet implemented."
+#: actions/remotesubscribe.php:166 actions/remotesubscribe.php:171
+msgid "That's a local profile! Login to subscribe."
msgstr ""
-#: lib/command.php:88
+#: actions/replies.php:118 actions/replies.php:120 actions/replies.php:119
+#: actions/replies.php:127
#, php-format
-msgid "Could not find a user with nickname %s"
+msgid "Replies to %s, page %d"
msgstr ""
-#: lib/command.php:92
-msgid "It does not make a lot of sense to nudge yourself!"
+#: actions/showfavorites.php:79
+#, php-format
+msgid "%s favorite notices, page %d"
msgstr ""
-#: lib/command.php:99
+#: actions/showgroup.php:77 lib/groupnav.php:85 actions/showgroup.php:82
#, php-format
-msgid "Nudge sent to %s"
+msgid "%s group"
msgstr ""
-#: lib/command.php:126
+#: actions/showgroup.php:79 actions/showgroup.php:84
#, php-format
-msgid ""
-"Subscriptions: %1$s\n"
-"Subscribers: %2$s\n"
-"Notices: %3$s"
+msgid "%s group, page %d"
msgstr ""
-#: lib/command.php:152 lib/command.php:400
-msgid "Notice with that id does not exist"
+#: actions/showgroup.php:206 actions/showgroup.php:208
+#: actions/showgroup.php:213 actions/showgroup.php:218
+msgid "Group profile"
msgstr ""
-#: lib/command.php:168 lib/command.php:416 lib/command.php:471
-msgid "User has no last notice"
+#: actions/showgroup.php:251 actions/showstream.php:278
+#: actions/tagother.php:119 lib/grouplist.php:134 lib/profilelist.php:133
+#: actions/showgroup.php:253 actions/showstream.php:271
+#: actions/tagother.php:118 lib/profilelist.php:131 actions/showgroup.php:258
+#: actions/showstream.php:236 actions/userauthorization.php:137
+#: lib/profilelist.php:197 actions/showgroup.php:263
+#: actions/showstream.php:295 actions/userauthorization.php:167
+#: lib/profilelist.php:230 lib/userprofile.php:177
+msgid "URL"
msgstr ""
-#: lib/command.php:190
-msgid "Notice marked as fave."
+#: actions/showgroup.php:262 actions/showstream.php:289
+#: actions/tagother.php:129 lib/grouplist.php:145 lib/profilelist.php:144
+#: actions/showgroup.php:264 actions/showstream.php:282
+#: actions/tagother.php:128 lib/profilelist.php:142 actions/showgroup.php:269
+#: actions/showstream.php:247 actions/userauthorization.php:149
+#: lib/profilelist.php:212 actions/showgroup.php:274
+#: actions/showstream.php:312 actions/userauthorization.php:179
+#: lib/profilelist.php:245 lib/userprofile.php:194
+msgid "Note"
msgstr ""
-#: lib/command.php:315
-#, php-format
-msgid "%1$s (%2$s)"
+#: actions/showgroup.php:270 actions/showgroup.php:272
+#: actions/showgroup.php:288 actions/showgroup.php:293
+msgid "Group actions"
msgstr ""
-#: lib/command.php:318
+#: actions/showgroup.php:323 actions/showgroup.php:304
#, php-format
-msgid "Fullname: %s"
+msgid "Notice feed for %s group"
msgstr ""
-#: lib/command.php:321
-#, php-format
-msgid "Location: %s"
+#: actions/showgroup.php:357 lib/groupnav.php:90 actions/showgroup.php:339
+#: actions/showgroup.php:384 actions/showgroup.php:373
+#: actions/showgroup.php:430 actions/showgroup.php:381
+#: actions/showgroup.php:438
+msgid "Members"
msgstr ""
-#: lib/command.php:324
-#, php-format
-msgid "Homepage: %s"
+#: actions/showgroup.php:363 actions/showstream.php:413
+#: actions/showstream.php:442 actions/showstream.php:524 lib/section.php:95
+#: lib/tagcloudsection.php:71 actions/showgroup.php:344
+#: actions/showgroup.php:378 lib/profileaction.php:117
+#: lib/profileaction.php:148 lib/profileaction.php:226
+#: actions/showgroup.php:386
+msgid "(None)"
msgstr ""
-#: lib/command.php:327
-#, php-format
-msgid "About: %s"
+#: actions/showgroup.php:370 actions/showgroup.php:350
+#: actions/showgroup.php:384 actions/showgroup.php:392
+msgid "All members"
msgstr ""
-#: lib/command.php:358 scripts/xmppdaemon.php:321
+#: actions/showgroup.php:378
#, php-format
-msgid "Message too long - maximum is %d characters, you sent %d"
+msgid ""
+"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service "
msgstr ""
-#: lib/command.php:377
-msgid "Error sending direct message."
+#: actions/showmessage.php:98
+msgid "Only the sender and recipient "
msgstr ""
-#: lib/command.php:431
+#: actions/showstream.php:73 actions/showstream.php:78
+#: actions/showstream.php:79
#, php-format
-msgid "Notice too long - maximum is %d characters, you sent %d"
+msgid "%s, page %d"
msgstr ""
-#: lib/command.php:439
-#, php-format
-msgid "Reply to %s sent"
+#: actions/showstream.php:143
+msgid "'s profile"
msgstr ""
-#: lib/command.php:441
-msgid "Error saving notice."
+#: actions/showstream.php:236 actions/tagother.php:77
+#: actions/showstream.php:220 actions/showstream.php:185
+#: actions/showstream.php:193 lib/userprofile.php:75
+msgid "User profile"
msgstr ""
-#: lib/command.php:495
-msgid "Specify the name of the user to subscribe to"
+#: actions/showstream.php:240 actions/tagother.php:81
+#: actions/showstream.php:224 actions/showstream.php:189
+#: actions/showstream.php:220 lib/userprofile.php:102
+msgid "Photo"
msgstr ""
-#: lib/command.php:502
-#, php-format
-msgid "Subscribed to %s"
+#: actions/showstream.php:317 actions/showstream.php:309
+#: actions/showstream.php:274 actions/showstream.php:354
+#: lib/userprofile.php:236
+msgid "User actions"
msgstr ""
-#: lib/command.php:523
-msgid "Specify the name of the user to unsubscribe from"
+#: actions/showstream.php:342 actions/showstream.php:307
+#: actions/showstream.php:390 lib/userprofile.php:272
+msgid "Send a direct message to this user"
msgstr ""
-#: lib/command.php:530
-#, php-format
-msgid "Unsubscribed from %s"
+#: actions/showstream.php:343 actions/showstream.php:308
+#: actions/showstream.php:391 lib/userprofile.php:273
+msgid "Message"
msgstr ""
-#: lib/command.php:548 lib/command.php:571
-msgid "Command not yet implemented."
+#: actions/showstream.php:451 lib/profileaction.php:157
+msgid "All subscribers"
msgstr ""
-#: lib/command.php:551
-msgid "Notification off."
+#: actions/showstream.php:533 lib/profileaction.php:235
+msgid "All groups"
msgstr ""
-#: lib/command.php:553
-msgid "Can't turn off notification."
+#: actions/showstream.php:542
+#, php-format
+msgid ""
+"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service "
msgstr ""
-#: lib/command.php:574
-msgid "Notification on."
+#: actions/smssettings.php:128
+msgid "Phone number, no punctuation or spaces, "
msgstr ""
-#: lib/command.php:576
-msgid "Can't turn on notification."
+#: actions/smssettings.php:162
+msgid "Send me notices through SMS; "
msgstr ""
-#: lib/command.php:597
-#, php-format
-msgid "Could not create login token for %s"
+#: actions/smssettings.php:335
+msgid "A confirmation code was sent to the phone number you added. "
msgstr ""
-#: lib/command.php:602
-#, php-format
-msgid "This link is useable only once, and is good for only 2 minutes: %s"
+#: actions/smssettings.php:453 actions/smssettings.php:465
+msgid "Mobile carrier"
msgstr ""
-#: lib/command.php:613
-msgid ""
-"Commands:\n"
-"on - turn on notifications\n"
-"off - turn off notifications\n"
-"help - show this help\n"
-"follow - subscribe to user\n"
-"leave - unsubscribe from user\n"
-"d - direct message to user\n"
-"get - get last notice from user\n"
-"whois - get profile info on user\n"
-"fav - add user's last notice as a 'fave'\n"
-"fav # - add notice with the given id as a 'fave'\n"
-"reply # - reply to notice with a given id\n"
-"reply - reply to the last notice from user\n"
-"join - join group\n"
-"login - Get a link to login to the web interface\n"
-"drop - leave group\n"
-"stats - get your stats\n"
-"stop - same as 'off'\n"
-"quit - same as 'off'\n"
-"sub - same as 'follow'\n"
-"unsub - same as 'leave'\n"
-"last - same as 'get'\n"
-"on - not yet implemented.\n"
-"off - not yet implemented.\n"
-"nudge - remind a user to update.\n"
-"invite - not yet implemented.\n"
-"track - not yet implemented.\n"
-"untrack - not yet implemented.\n"
-"track off - not yet implemented.\n"
-"untrack all - not yet implemented.\n"
-"tracks - not yet implemented.\n"
-"tracking - not yet implemented.\n"
+#: actions/subedit.php:70
+msgid "You are not subscribed to that profile."
msgstr ""
-#: lib/common.php:191
-msgid "No configuration file found. "
+#: actions/subedit.php:83
+msgid "Could not save subscription."
msgstr ""
-#: lib/common.php:192
-msgid "I looked for configuration files in the following places: "
+#: actions/subscribe.php:55
+msgid "Not a local user."
msgstr ""
-#: lib/common.php:193
-msgid "You may wish to run the installer to fix this."
+#: actions/subscribe.php:69
+msgid "Subscribed"
msgstr ""
-#: lib/common.php:194
-msgid "Go to the installer."
+#: actions/subscribers.php:50
+#, php-format
+msgid "%s subscribers"
msgstr ""
-#: lib/connectsettingsaction.php:110
-msgid "IM"
+#: actions/subscribers.php:52
+#, php-format
+msgid "%s subscribers, page %d"
msgstr ""
-#: lib/connectsettingsaction.php:111
-msgid "Updates by instant messenger (IM)"
+#: actions/subscribers.php:63
+msgid "These are the people who listen to "
msgstr ""
-#: lib/connectsettingsaction.php:116
-msgid "Updates by SMS"
+#: actions/subscribers.php:67
+#, php-format
+msgid "These are the people who "
msgstr ""
-#: lib/dberroraction.php:60
-msgid "Database error"
+#: actions/subscriptions.php:52
+#, php-format
+msgid "%s subscriptions"
msgstr ""
-#: lib/designsettings.php:101
-msgid "Change background image"
+#: actions/subscriptions.php:54
+#, php-format
+msgid "%s subscriptions, page %d"
msgstr ""
-#: lib/designsettings.php:105
-msgid "Upload file"
+#: actions/subscriptions.php:65
+msgid "These are the people whose notices "
msgstr ""
-#: lib/designsettings.php:109
-msgid ""
-"You can upload your personal background image. The maximum file size is 2Mb."
+#: actions/subscriptions.php:69
+#, php-format
+msgid "These are the people whose "
msgstr ""
-#: lib/designsettings.php:139
-msgid "On"
+#: actions/subscriptions.php:122 actions/subscriptions.php:124
+#: actions/subscriptions.php:183 actions/subscriptions.php:194
+msgid "Jabber"
msgstr ""
-#: lib/designsettings.php:155
-msgid "Off"
+#: actions/tag.php:43 actions/tag.php:51 actions/tag.php:59 actions/tag.php:68
+#, php-format
+msgid "Notices tagged with %s, page %d"
msgstr ""
-#: lib/designsettings.php:156
-msgid "Turn background image on or off."
+#: actions/tag.php:66 actions/tag.php:73
+#, php-format
+msgid "Messages tagged \"%s\", most recent first"
msgstr ""
-#: lib/designsettings.php:161
-msgid "Tile background image"
+#: actions/tagother.php:33
+msgid "Not logged in"
msgstr ""
-#: lib/designsettings.php:170
-msgid "Change colours"
+#: actions/tagother.php:39
+msgid "No id argument."
msgstr ""
-#: lib/designsettings.php:178
-msgid "Background"
+#: actions/tagother.php:65
+#, php-format
+msgid "Tag %s"
msgstr ""
-#: lib/designsettings.php:191
-msgid "Content"
+#: actions/tagother.php:141
+msgid "Tag user"
msgstr ""
-#: lib/designsettings.php:204
-msgid "Sidebar"
+#: actions/tagother.php:149 actions/tagother.php:151
+msgid ""
+"Tags for this user (letters, numbers, -, ., and _), comma- or space- "
+"separated"
msgstr ""
-#: lib/designsettings.php:217
-msgid "Text"
+#: actions/tagother.php:164
+msgid "There was a problem with your session token."
msgstr ""
-#: lib/designsettings.php:230
-msgid "Links"
+#: actions/tagother.php:191 actions/tagother.php:193
+msgid ""
+"You can only tag people you are subscribed to or who are subscribed to you."
msgstr ""
-#: lib/designsettings.php:247
-msgid "Use defaults"
+#: actions/tagother.php:198 actions/tagother.php:200
+msgid "Could not save tags."
msgstr ""
-#: lib/designsettings.php:248
-msgid "Restore default designs"
+#: actions/tagother.php:233 actions/tagother.php:235 actions/tagother.php:236
+msgid "Use this form to add tags to your subscribers or subscriptions."
msgstr ""
-#: lib/designsettings.php:254
-msgid "Reset back to default"
+#: actions/tagrss.php:35
+msgid "No such tag."
msgstr ""
-#: lib/designsettings.php:257
-msgid "Save design"
+#: actions/tagrss.php:66 actions/tagrss.php:64
+#, php-format
+msgid "Microblog tagged with %s"
msgstr ""
-#: lib/designsettings.php:372
-msgid "Bad default color settings: "
+#: actions/twitapiblocks.php:47 actions/twitapiblocks.php:49
+#: actions/apiblockcreate.php:108
+msgid "Block user failed."
msgstr ""
-#: lib/designsettings.php:468
-msgid "Design defaults restored."
+#: actions/twitapiblocks.php:69 actions/twitapiblocks.php:71
+#: actions/apiblockdestroy.php:107
+msgid "Unblock user failed."
msgstr ""
-#: lib/disfavorform.php:114 lib/disfavorform.php:140
-msgid "Disfavor this notice"
+#: actions/twitapiusers.php:48 actions/twitapiusers.php:52
+#: actions/twitapiusers.php:50 actions/apiusershow.php:96
+msgid "Not found."
msgstr ""
-#: lib/favorform.php:114 lib/favorform.php:140
-msgid "Favor this notice"
+#: actions/twittersettings.php:71
+msgid "Add your Twitter account to automatically send "
msgstr ""
-#: lib/favorform.php:140
-msgid "Favor"
+#: actions/twittersettings.php:119 actions/twittersettings.php:122
+msgid "Twitter user name"
msgstr ""
-#: lib/feedlist.php:64
-msgid "Export data"
+#: actions/twittersettings.php:126 actions/twittersettings.php:129
+msgid "Twitter password"
msgstr ""
-#: lib/feed.php:85
-msgid "RSS 1.0"
+#: actions/twittersettings.php:228 actions/twittersettings.php:232
+#: actions/twittersettings.php:248
+msgid "Twitter Friends"
msgstr ""
-#: lib/feed.php:87
-msgid "RSS 2.0"
+#: actions/twittersettings.php:327
+msgid "Username must have only numbers, "
msgstr ""
-#: lib/feed.php:89
-msgid "Atom"
+#: actions/twittersettings.php:341
+#, php-format
+msgid "Unable to retrieve account information "
msgstr ""
-#: lib/feed.php:91
-msgid "FOAF"
+#: actions/unblock.php:108 actions/groupunblock.php:128
+msgid "Error removing the block."
msgstr ""
-#: lib/galleryaction.php:121
-msgid "Filter tags"
+#: actions/unsubscribe.php:50 actions/unsubscribe.php:77
+msgid "No profile id in request."
msgstr ""
-#: lib/galleryaction.php:131
-msgid "All"
+#: actions/unsubscribe.php:57 actions/unsubscribe.php:84
+msgid "No profile with that id."
msgstr ""
-#: lib/galleryaction.php:139
-msgid "Select tag to filter"
+#: actions/unsubscribe.php:71 actions/unsubscribe.php:98
+msgid "Unsubscribed"
msgstr ""
-#: lib/galleryaction.php:140
-msgid "Tag"
+#: actions/usergroups.php:63 actions/usergroups.php:62
+#: actions/apigrouplistall.php:90
+#, php-format
+msgid "%s groups"
msgstr ""
-#: lib/galleryaction.php:141
-msgid "Choose a tag to narrow list"
+#: actions/usergroups.php:65 actions/usergroups.php:64
+#, php-format
+msgid "%s groups, page %d"
msgstr ""
-#: lib/galleryaction.php:143
-msgid "Go"
+#: classes/Notice.php:104 classes/Notice.php:128 classes/Notice.php:144
+#: classes/Notice.php:183
+msgid "Problem saving notice. Unknown user."
msgstr ""
-#: lib/groupeditform.php:163
-msgid "URL of the homepage or blog of the group or topic"
+#: classes/Notice.php:109 classes/Notice.php:133 classes/Notice.php:149
+#: classes/Notice.php:188
+msgid ""
+"Too many notices too fast; take a breather and post again in a few minutes."
msgstr ""
-#: lib/groupeditform.php:168
-msgid "Describe the group or topic"
+#: classes/Notice.php:116 classes/Notice.php:145 classes/Notice.php:161
+#: classes/Notice.php:202
+msgid "You are banned from posting notices on this site."
msgstr ""
-#: lib/groupeditform.php:170
-#, php-format
-msgid "Describe the group or topic in %d characters"
+#: lib/accountsettingsaction.php:108 lib/accountsettingsaction.php:112
+msgid "Upload an avatar"
msgstr ""
-#: lib/groupeditform.php:172
-msgid "Description"
+#: lib/accountsettingsaction.php:119 lib/accountsettingsaction.php:122
+#: lib/accountsettingsaction.php:123
+msgid "Other"
msgstr ""
-#: lib/groupeditform.php:179
-msgid ""
-"Location for the group, if any, like \"City, State (or Region), Country\""
+#: lib/accountsettingsaction.php:120 lib/accountsettingsaction.php:123
+#: lib/accountsettingsaction.php:124
+msgid "Other options"
msgstr ""
-#: lib/groupeditform.php:187
+#: lib/action.php:130 lib/action.php:132 lib/action.php:142 lib/action.php:144
#, php-format
-msgid "Extra nicknames for the group, comma- or space- separated, max %d"
+msgid "%s - %s"
msgstr ""
-#: lib/groupnav.php:84 lib/searchgroupnav.php:84
-msgid "Group"
+#: lib/action.php:145 lib/action.php:147 lib/action.php:157 lib/action.php:159
+msgid "Untitled page"
msgstr ""
-#: lib/groupnav.php:100
-msgid "Blocked"
+#: lib/action.php:316 lib/action.php:387 lib/action.php:411 lib/action.php:424
+msgid "Primary site navigation"
msgstr ""
-#: lib/groupnav.php:101
-#, php-format
-msgid "%s blocked users"
+#: lib/action.php:322 lib/action.php:393 lib/action.php:417 lib/action.php:430
+msgid "Personal profile and friends timeline"
msgstr ""
-#: lib/groupnav.php:107
-#, php-format
-msgid "Edit %s group properties"
+#: lib/action.php:325 lib/action.php:396 lib/action.php:448 lib/action.php:459
+msgid "Search for people or text"
msgstr ""
-#: lib/groupnav.php:112
-msgid "Logo"
+#: lib/action.php:328 lib/action.php:399 lib/action.php:419 lib/action.php:432
+msgid "Account"
msgstr ""
-#: lib/groupnav.php:113
-#, php-format
-msgid "Add or edit %s logo"
+#: lib/action.php:328 lib/action.php:399 lib/action.php:419 lib/action.php:432
+msgid "Change your email, avatar, password, profile"
msgstr ""
-#: lib/groupnav.php:119
-#, php-format
-msgid "Add or edit %s design"
+#: lib/action.php:330 lib/action.php:403 lib/action.php:422
+msgid "Connect to IM, SMS, Twitter"
msgstr ""
-#: lib/groupsbymemberssection.php:71
-msgid "Groups with most members"
+#: lib/action.php:332 lib/action.php:409 lib/action.php:435 lib/action.php:445
+msgid "Logout from the site"
msgstr ""
-#: lib/groupsbypostssection.php:71
-msgid "Groups with most posts"
+#: lib/action.php:335 lib/action.php:412 lib/action.php:443 lib/action.php:453
+msgid "Login to the site"
msgstr ""
-#: lib/grouptagcloudsection.php:56
-#, php-format
-msgid "Tags in %s group's notices"
+#: lib/action.php:338 lib/action.php:415 lib/action.php:440 lib/action.php:450
+msgid "Create an account"
msgstr ""
-#: lib/htmloutputter.php:104
-msgid "This page is not available in a media type you accept"
+#: lib/action.php:341 lib/action.php:418
+msgid "Login with OpenID"
msgstr ""
-#: lib/imagefile.php:75
-#, php-format
-msgid "That file is too big. The maximum file size is %s."
+#: lib/action.php:344 lib/action.php:421 lib/action.php:446 lib/action.php:456
+msgid "Help me!"
msgstr ""
-#: lib/imagefile.php:80
-msgid "Partial upload."
+#: lib/action.php:362 lib/action.php:441 lib/action.php:468 lib/action.php:480
+msgid "Site notice"
msgstr ""
-#: lib/imagefile.php:88 lib/mediafile.php:170
-msgid "System error uploading file."
+#: lib/action.php:417 lib/action.php:504 lib/action.php:531 lib/action.php:546
+msgid "Local views"
msgstr ""
-#: lib/imagefile.php:96
-msgid "Not an image or corrupt file."
+#: lib/action.php:472 lib/action.php:559 lib/action.php:597 lib/action.php:612
+msgid "Page notice"
msgstr ""
-#: lib/imagefile.php:105
-msgid "Unsupported image file format."
+#: lib/action.php:562 lib/action.php:654 lib/action.php:699 lib/action.php:714
+msgid "Secondary site navigation"
msgstr ""
-#: lib/imagefile.php:118
-msgid "Lost our file."
+#: lib/action.php:602 lib/action.php:623 lib/action.php:699 lib/action.php:720
+#: lib/action.php:749 lib/action.php:770 lib/action.php:764
+msgid "StatusNet software license"
msgstr ""
-#: lib/imagefile.php:150 lib/imagefile.php:197
-msgid "Unknown file type"
+#: lib/action.php:630 lib/action.php:727 lib/action.php:779 lib/action.php:794
+msgid "All "
msgstr ""
-#: lib/jabber.php:192
+#: lib/action.php:635 lib/action.php:732 lib/action.php:784 lib/action.php:799
+msgid "license."
+msgstr ""
+
+#: lib/blockform.php:123 lib/blockform.php:153 actions/groupmembers.php:343
+#: actions/groupmembers.php:346
+msgid "Block this user"
+msgstr ""
+
+#: lib/blockform.php:153 actions/groupmembers.php:343
+#: actions/groupmembers.php:346
+msgid "Block"
+msgstr ""
+
+#: lib/disfavorform.php:114 lib/disfavorform.php:140
+msgid "Disfavor this notice"
+msgstr ""
+
+#: lib/facebookaction.php:268
#, php-format
-msgid "notice id: %s"
+msgid "To use the %s Facebook Application you need to login "
msgstr ""
-#: lib/joinform.php:114
-msgid "Join"
+#: lib/facebookaction.php:271 lib/facebookaction.php:273
+#: lib/facebookaction.php:275
+msgid " a new account."
msgstr ""
-#: lib/leaveform.php:114
-msgid "Leave"
+#: lib/facebookaction.php:557 lib/mailbox.php:214 lib/noticelist.php:354
+#: lib/facebookaction.php:675 lib/mailbox.php:216 lib/noticelist.php:357
+#: lib/mailbox.php:217 lib/noticelist.php:361
+msgid "Published"
msgstr ""
-#: lib/logingroupnav.php:80
-msgid "Login with a username and password"
+#: lib/favorform.php:114 lib/favorform.php:140
+msgid "Favor this notice"
msgstr ""
-#: lib/logingroupnav.php:86
-msgid "Sign up for a new account"
+#: lib/feedlist.php:64
+msgid "Export data"
msgstr ""
-#: lib/mailbox.php:89
-msgid "Only the user can read their own mailboxes."
+#: lib/galleryaction.php:121
+msgid "Filter tags"
msgstr ""
-#: lib/mailbox.php:139
+#: lib/galleryaction.php:131
+msgid "All"
+msgstr ""
+
+#: lib/galleryaction.php:137 lib/galleryaction.php:138
+#: lib/galleryaction.php:140
+msgid "Tag"
+msgstr ""
+
+#: lib/galleryaction.php:138 lib/galleryaction.php:139
+#: lib/galleryaction.php:141
+msgid "Choose a tag to narrow list"
+msgstr ""
+
+#: lib/galleryaction.php:139 lib/galleryaction.php:141
+#: lib/galleryaction.php:143
+msgid "Go"
+msgstr ""
+
+#: lib/groupeditform.php:148 lib/groupeditform.php:163
+msgid "URL of the homepage or blog of the group or topic"
+msgstr ""
+
+#: lib/groupeditform.php:151 lib/groupeditform.php:166
+#: lib/groupeditform.php:172
+msgid "Description"
+msgstr ""
+
+#: lib/groupeditform.php:153 lib/groupeditform.php:168
+msgid "Describe the group or topic in 140 chars"
+msgstr ""
+
+#: lib/groupeditform.php:158 lib/groupeditform.php:173
+#: lib/groupeditform.php:179
msgid ""
-"You have no private messages. You can send private message to engage other "
-"users in conversation. People can send you messages for your eyes only."
+"Location for the group, if any, like \"City, State (or Region), Country\""
msgstr ""
-#: lib/mailbox.php:227 lib/noticelist.php:424
-msgid "from"
+#: lib/groupnav.php:84 lib/searchgroupnav.php:84
+msgid "Group"
msgstr ""
-#: lib/mail.php:172
-msgid "Email address confirmation"
+#: lib/groupnav.php:100 actions/groupmembers.php:175 lib/groupnav.php:106
+msgid "Admin"
msgstr ""
-#: lib/mail.php:174
+#: lib/groupnav.php:101 lib/groupnav.php:107
#, php-format
-msgid ""
-"Hey, %s.\n"
-"\n"
-"Someone just entered this email address on %s.\n"
-"\n"
-"If it was you, and you want to confirm your entry, use the URL below:\n"
-"\n"
-"\t%s\n"
-"\n"
-"If not, just ignore this message.\n"
-"\n"
-"Thanks for your time, \n"
-"%s\n"
+msgid "Edit %s group properties"
+msgstr ""
+
+#: lib/groupnav.php:106 lib/groupnav.php:112
+msgid "Logo"
msgstr ""
-#: lib/mail.php:235
+#: lib/groupnav.php:107 lib/groupnav.php:113
#, php-format
-msgid "%1$s is now listening to your notices on %2$s."
+msgid "Add or edit %s logo"
+msgstr ""
+
+#: lib/groupsbymemberssection.php:71
+msgid "Groups with most members"
+msgstr ""
+
+#: lib/groupsbypostssection.php:71
+msgid "Groups with most posts"
+msgstr ""
+
+#: lib/grouptagcloudsection.php:56
+#, php-format
+msgid "Tags in %s group's notices"
+msgstr ""
+
+#: lib/htmloutputter.php:104
+msgid "This page is not available in a "
+msgstr ""
+
+#: lib/joinform.php:114
+msgid "Join"
+msgstr ""
+
+#: lib/leaveform.php:114
+msgid "Leave"
+msgstr ""
+
+#: lib/logingroupnav.php:76 lib/logingroupnav.php:80
+msgid "Login with a username and password"
+msgstr ""
+
+#: lib/logingroupnav.php:79 lib/logingroupnav.php:86
+msgid "Sign up for a new account"
+msgstr ""
+
+#: lib/logingroupnav.php:82
+msgid "Login or register with OpenID"
msgstr ""
-#: lib/mail.php:240
+#: lib/mail.php:175
#, php-format
msgid ""
-"%1$s is now listening to your notices on %2$s.\n"
-"\n"
-"\t%3$s\n"
-"\n"
-"%4$s%5$s%6$s\n"
-"Faithfully yours,\n"
-"%7$s.\n"
+"Hey, %s.\n"
"\n"
-"----\n"
-"Change your email address or notification options at %8$s\n"
msgstr ""
-#: lib/mail.php:253
+#: lib/mail.php:236
+#, php-format
+msgid "%1$s is now listening to "
+msgstr ""
+
+#: lib/mail.php:254 lib/mail.php:253
#, php-format
msgid "Location: %s\n"
msgstr ""
-#: lib/mail.php:255
+#: lib/mail.php:256 lib/mail.php:255
#, php-format
msgid "Homepage: %s\n"
msgstr ""
-#: lib/mail.php:257
+#: lib/mail.php:258 lib/mail.php:257
#, php-format
msgid ""
"Bio: %s\n"
"\n"
msgstr ""
-#: lib/mail.php:285
+#: lib/mail.php:461 lib/mail.php:462
#, php-format
-msgid "New email address for posting to %s"
+msgid "You've been nudged by %s"
msgstr ""
-#: lib/mail.php:288
+#: lib/mail.php:465
#, php-format
-msgid ""
-"You have a new posting address on %1$s.\n"
-"\n"
-"Send email to %2$s to post new messages.\n"
-"\n"
-"More email instructions at %3$s.\n"
-"\n"
-"Faithfully yours,\n"
-"%4$s"
+msgid "%1$s (%2$s) is wondering what you are up to "
msgstr ""
-#: lib/mail.php:412
+#: lib/mail.php:555
#, php-format
-msgid "%s status"
+msgid "%1$s just added your notice from %2$s"
msgstr ""
-#: lib/mail.php:438
-msgid "SMS confirmation"
+#: lib/mailbox.php:229 lib/noticelist.php:380 lib/mailbox.php:231
+#: lib/noticelist.php:383 lib/mailbox.php:232 lib/noticelist.php:388
+msgid "From"
msgstr ""
-#: lib/mail.php:462
-#, php-format
-msgid "You've been nudged by %s"
+#: lib/messageform.php:110 lib/messageform.php:109 lib/messageform.php:120
+msgid "Send a direct notice"
msgstr ""
-#: lib/mail.php:466
-#, php-format
-msgid ""
-"%1$s (%2$s) is wondering what you are up to these days and is inviting you "
-"to post some news.\n"
-"\n"
-"So let's hear from you :)\n"
-"\n"
-"%3$s\n"
-"\n"
-"Don't reply to this email; it won't get to them.\n"
-"\n"
-"With kind regards,\n"
-"%4$s\n"
+#: lib/noticeform.php:125 lib/noticeform.php:128 lib/noticeform.php:145
+msgid "Send a notice"
msgstr ""
-#: lib/mail.php:509
-#, php-format
-msgid "New private message from %s"
-msgstr ""
-
-#: lib/mail.php:513
-#, php-format
-msgid ""
-"%1$s (%2$s) sent you a private message:\n"
-"\n"
-"------------------------------------------------------\n"
-"%3$s\n"
-"------------------------------------------------------\n"
-"\n"
-"You can reply to their message here:\n"
-"\n"
-"%4$s\n"
-"\n"
-"Don't reply to this email; it won't get to them.\n"
-"\n"
-"With kind regards,\n"
-"%5$s\n"
-msgstr ""
-
-#: lib/mail.php:554
-#, php-format
-msgid "%s (@%s) added your notice as a favorite"
+#: lib/noticeform.php:152 lib/noticeform.php:149 lib/messageform.php:162
+#: lib/noticeform.php:173
+msgid "Available characters"
msgstr ""
-#: lib/mail.php:556
-#, php-format
-msgid ""
-"%1$s (@%7$s) just added your notice from %2$s as one of their favorites.\n"
-"\n"
-"The URL of your notice is:\n"
-"\n"
-"%3$s\n"
-"\n"
-"The text of your notice is:\n"
-"\n"
-"%4$s\n"
-"\n"
-"You can see the list of %1$s's favorites here:\n"
-"\n"
-"%5$s\n"
-"\n"
-"Faithfully yours,\n"
-"%6$s\n"
+#: lib/noticelist.php:426 lib/noticelist.php:429
+msgid "in reply to"
msgstr ""
-#: lib/mail.php:611
-#, php-format
-msgid "%s (@%s) sent a notice to your attention"
+#: lib/noticelist.php:447 lib/noticelist.php:450 lib/noticelist.php:451
+#: lib/noticelist.php:454 lib/noticelist.php:458 lib/noticelist.php:461
+#: lib/noticelist.php:498
+msgid "Reply to this notice"
msgstr ""
-#: lib/mail.php:613
-#, php-format
-msgid ""
-"%1$s (@%9$s) just sent a notice to your attention (an '@-reply') on %2$s.\n"
-"\n"
-"The notice is here:\n"
-"\n"
-"\t%3$s\n"
-"\n"
-"It reads:\n"
-"\n"
-"\t%4$s\n"
-"\n"
+#: lib/noticelist.php:451 lib/noticelist.php:455 lib/noticelist.php:462
+#: lib/noticelist.php:499
+msgid "Reply"
msgstr ""
-#: lib/mediafile.php:98 lib/mediafile.php:123
-msgid "There was a database error while saving your file. Please try again."
+#: lib/noticelist.php:471 lib/noticelist.php:474 lib/noticelist.php:476
+#: lib/noticelist.php:479 actions/deletenotice.php:116 lib/noticelist.php:483
+#: lib/noticelist.php:486 actions/deletenotice.php:146 lib/noticelist.php:522
+msgid "Delete this notice"
msgstr ""
-#: lib/mediafile.php:142
-msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini."
+#: lib/noticelist.php:474 actions/avatarsettings.php:148
+#: lib/noticelist.php:479 lib/noticelist.php:486 lib/noticelist.php:522
+msgid "Delete"
msgstr ""
-#: lib/mediafile.php:147
-msgid ""
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
-"the HTML form."
+#: lib/nudgeform.php:116
+msgid "Nudge this user"
msgstr ""
-#: lib/mediafile.php:152
-msgid "The uploaded file was only partially uploaded."
+#: lib/nudgeform.php:128
+msgid "Nudge"
msgstr ""
-#: lib/mediafile.php:159
-msgid "Missing a temporary folder."
+#: lib/nudgeform.php:128
+msgid "Send a nudge to this user"
msgstr ""
-#: lib/mediafile.php:162
-msgid "Failed to write file to disk."
+#: lib/personaltagcloudsection.php:56
+#, php-format
+msgid "Tags in %s's notices"
msgstr ""
-#: lib/mediafile.php:165
-msgid "File upload stopped by extension."
+#: lib/profilelist.php:182 lib/profilelist.php:180
+#: lib/subscriptionlist.php:126
+msgid "(none)"
msgstr ""
-#: lib/mediafile.php:179 lib/mediafile.php:216
-msgid "File exceeds user's quota!"
+#: lib/publicgroupnav.php:76 lib/publicgroupnav.php:78
+msgid "Public"
msgstr ""
-#: lib/mediafile.php:196 lib/mediafile.php:233
-msgid "File could not be moved to destination directory."
+#: lib/publicgroupnav.php:80 lib/publicgroupnav.php:82
+msgid "User groups"
msgstr ""
-#: lib/mediafile.php:201 lib/mediafile.php:237
-msgid "Could not determine file's mime-type!"
+#: lib/publicgroupnav.php:82 lib/publicgroupnav.php:83
+#: lib/publicgroupnav.php:84 lib/publicgroupnav.php:85
+msgid "Recent tags"
msgstr ""
-#: lib/mediafile.php:270
-#, php-format
-msgid " Try using another %s format."
+#: lib/publicgroupnav.php:86 lib/publicgroupnav.php:88
+msgid "Featured"
msgstr ""
-#: lib/mediafile.php:275
-#, php-format
-msgid "%s is not a supported filetype on this server."
+#: lib/publicgroupnav.php:90 lib/publicgroupnav.php:92
+msgid "Popular"
msgstr ""
-#: lib/messageform.php:120
-msgid "Send a direct notice"
+#: lib/searchgroupnav.php:82
+msgid "Notice"
msgstr ""
-#: lib/messageform.php:146
-msgid "To"
+#: lib/searchgroupnav.php:85
+msgid "Find groups on this site"
msgstr ""
-#: lib/messageform.php:162 lib/noticeform.php:173
-msgid "Available characters"
+#: lib/section.php:89
+msgid "Untitled section"
msgstr ""
-#: lib/noticeform.php:145
-msgid "Send a notice"
+#: lib/subgroupnav.php:81 lib/subgroupnav.php:83
+#, php-format
+msgid "People %s subscribes to"
msgstr ""
-#: lib/noticeform.php:158
+#: lib/subgroupnav.php:89 lib/subgroupnav.php:91
#, php-format
-msgid "What's up, %s?"
+msgid "People subscribed to %s"
msgstr ""
-#: lib/noticeform.php:180
-msgid "Attach"
+#: lib/subgroupnav.php:97 lib/subgroupnav.php:99
+#, php-format
+msgid "Groups %s is a member of"
msgstr ""
-#: lib/noticeform.php:184
-msgid "Attach a file"
+#: lib/subgroupnav.php:104 lib/action.php:430 lib/subgroupnav.php:106
+#: lib/action.php:440
+#, php-format
+msgid "Invite friends and colleagues to join you on %s"
msgstr ""
-#: lib/noticelist.php:478
-msgid "in context"
+#: lib/subs.php:53 lib/subs.php:52
+msgid "User has blocked you."
msgstr ""
-#: lib/noticelist.php:498
-msgid "Reply to this notice"
+#: lib/subscribeform.php:115 lib/subscribeform.php:139
+#: actions/userauthorization.php:178 actions/userauthorization.php:210
+msgid "Subscribe to this user"
msgstr ""
-#: lib/noticelist.php:499
-msgid "Reply"
+#: lib/tagcloudsection.php:56
+msgid "None"
msgstr ""
-#: lib/nudgeform.php:116
-msgid "Nudge this user"
+#: lib/topposterssection.php:74
+msgid "Top posters"
msgstr ""
-#: lib/nudgeform.php:128
-msgid "Nudge"
+#: lib/unblockform.php:120 lib/unblockform.php:150
+#: actions/blockedfromgroup.php:313
+msgid "Unblock this user"
msgstr ""
-#: lib/nudgeform.php:128
-msgid "Send a nudge to this user"
+#: lib/unblockform.php:150 actions/blockedfromgroup.php:313
+msgid "Unblock"
msgstr ""
-#: lib/oauthstore.php:283
-msgid "Error inserting new profile"
+#: lib/unsubscribeform.php:113 lib/unsubscribeform.php:137
+msgid "Unsubscribe from this user"
msgstr ""
-#: lib/oauthstore.php:291
-msgid "Error inserting avatar"
+#: actions/all.php:77 actions/all.php:59 actions/all.php:99
+#, php-format
+msgid "Feed for friends of %s (RSS 1.0)"
msgstr ""
-#: lib/oauthstore.php:311
-msgid "Error inserting remote profile"
+#: actions/all.php:82 actions/all.php:64 actions/all.php:107
+#, php-format
+msgid "Feed for friends of %s (RSS 2.0)"
msgstr ""
-#: lib/oauthstore.php:345
-msgid "Duplicate notice"
+#: actions/all.php:87 actions/all.php:69 actions/all.php:115
+#, php-format
+msgid "Feed for friends of %s (Atom)"
msgstr ""
-#: lib/oauthstore.php:487
-msgid "Couldn't insert new subscription."
+#: actions/all.php:112 actions/all.php:125 actions/all.php:165
+msgid "You and friends"
msgstr ""
-#: lib/personalgroupnav.php:99
-msgid "Personal"
+#: actions/avatarsettings.php:78
+#, php-format
+msgid "You can upload your personal avatar. The maximum file size is %s."
msgstr ""
-#: lib/personalgroupnav.php:104
-msgid "Replies"
+#: actions/avatarsettings.php:373 actions/avatarsettings.php:387
+msgid "Avatar deleted."
msgstr ""
-#: lib/personalgroupnav.php:114
-msgid "Favorites"
+#: actions/block.php:129 actions/block.php:136
+msgid ""
+"Are you sure you want to block this user? Afterwards, they will be "
+"unsubscribed from you, unable to subscribe to you in the future, and you "
+"will not be notified of any @-replies from them."
msgstr ""
-#: lib/personalgroupnav.php:115
-msgid "User"
+#: actions/deletenotice.php:73 actions/deletenotice.php:103
+msgid ""
+"You are about to permanently delete a notice. Once this is done, it cannot "
+"be undone."
msgstr ""
-#: lib/personalgroupnav.php:124
-msgid "Inbox"
+#: actions/deletenotice.php:127 actions/deletenotice.php:157
+msgid "There was a problem with your session token. Try again, please."
msgstr ""
-#: lib/personalgroupnav.php:125
-msgid "Your incoming messages"
+#: actions/emailsettings.php:168 actions/emailsettings.php:174
+msgid "Send me email when someone sends me an \"@-reply\"."
msgstr ""
-#: lib/personalgroupnav.php:129
-msgid "Outbox"
+#: actions/facebookhome.php:193 actions/facebookhome.php:187
+#, php-format
+msgid ""
+"If you would like the %s app to automatically update your Facebook status "
+"with your latest notice, you need to give it permission."
msgstr ""
-#: lib/personalgroupnav.php:130
-msgid "Your sent messages"
+#: actions/facebookhome.php:217 actions/facebookhome.php:211
+#, php-format
+msgid "Okay, do it!"
msgstr ""
-#: lib/personaltagcloudsection.php:56
+#: actions/facebooksettings.php:124
#, php-format
-msgid "Tags in %s's notices"
+msgid ""
+"If you would like %s to automatically update your Facebook status with your "
+"latest notice, you need to give it permission."
msgstr ""
-#: lib/profileaction.php:109 lib/profileaction.php:191 lib/subgroupnav.php:82
-msgid "Subscriptions"
+#: actions/grouplogo.php:155 actions/grouplogo.php:150
+#, php-format
+msgid ""
+"You can upload a logo image for your group. The maximum file size is %s."
msgstr ""
-#: lib/profileaction.php:126
-msgid "All subscriptions"
+#: actions/grouplogo.php:367 actions/grouplogo.php:362
+msgid "Pick a square area of the image to be the logo."
msgstr ""
-#: lib/profileaction.php:140 lib/profileaction.php:200 lib/subgroupnav.php:90
-msgid "Subscribers"
+#: actions/grouprss.php:136 actions/grouprss.php:137
+#, php-format
+msgid "Microblog by %s group"
msgstr ""
-#: lib/profileaction.php:157
-msgid "All subscribers"
+#: actions/groupsearch.php:57 actions/groupsearch.php:52
+#, php-format
+msgid ""
+"Search for groups on %%site.name%% by their name, location, or description. "
+"Separate the terms by spaces; they must be 3 characters or more."
msgstr ""
-#: lib/profileaction.php:177
-msgid "User ID"
+#: actions/groups.php:90
+#, php-format
+msgid ""
+"%%%%site.name%%%% groups let you find and talk with people of similar "
+"interests. After you join a group you can send messages to all other members "
+"using the syntax \"!groupname\". Don't see a group you like? Try [searching "
+"for one](%%%%action.groupsearch%%%%) or [start your own!](%%%%action.newgroup"
+"%%%%)"
msgstr ""
-#: lib/profileaction.php:182
-msgid "Member since"
+#: actions/newmessage.php:102
+msgid "Only logged-in users can send direct messages."
msgstr ""
-#: lib/profileaction.php:235
-msgid "All groups"
+#: actions/noticesearch.php:91
+#, php-format
+msgid "Search results for \"%s\" on %s"
msgstr ""
-#: lib/publicgroupnav.php:78
-msgid "Public"
+#: actions/openidlogin.php:66
+#, php-format
+msgid ""
+"For security reasons, please re-login with your [OpenID](%%doc.openid%%) "
+"before changing your settings."
msgstr ""
-#: lib/publicgroupnav.php:82
-msgid "User groups"
+#: actions/public.php:125 actions/public.php:133 actions/public.php:151
+msgid "Public Stream Feed (RSS 1.0)"
msgstr ""
-#: lib/publicgroupnav.php:84 lib/publicgroupnav.php:85
-msgid "Recent tags"
+#: actions/public.php:130 actions/public.php:138 actions/public.php:155
+msgid "Public Stream Feed (RSS 2.0)"
msgstr ""
-#: lib/publicgroupnav.php:88
-msgid "Featured"
+#: actions/public.php:135 actions/public.php:143 actions/public.php:159
+msgid "Public Stream Feed (Atom)"
msgstr ""
-#: lib/publicgroupnav.php:92
-msgid "Popular"
+#: actions/public.php:210 actions/public.php:241 actions/public.php:233
+#, php-format
+msgid ""
+"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
+"blogging) service based on the Free Software [StatusNet](http://status.net/) "
+"tool. [Join now](%%action.register%%) to share notices about yourself with "
+"friends, family, and colleagues! ([Read more](%%doc.help%%))"
msgstr ""
-#: lib/searchaction.php:120
-msgid "Search site"
+#: actions/register.php:286 actions/register.php:329
+#, php-format
+msgid ""
+"With this form you can create a new account. You can then post notices and "
+"link up to friends and colleagues. (Have an [OpenID](http://openid.net/)? "
+"Try our [OpenID registration](%%action.openidlogin%%)!)"
msgstr ""
-#: lib/searchaction.php:162
-msgid "Search help"
+#: actions/register.php:432 actions/register.php:479 actions/register.php:489
+#: actions/register.php:495
+msgid "Creative Commons Attribution 3.0"
msgstr ""
-#: lib/searchgroupnav.php:80
-msgid "People"
+#: actions/register.php:433 actions/register.php:480 actions/register.php:490
+#: actions/register.php:496
+msgid ""
+" except this private data: password, email address, IM address, and phone "
+"number."
msgstr ""
-#: lib/searchgroupnav.php:81
-msgid "Find people on this site"
+#: actions/showgroup.php:378 actions/showgroup.php:424
+#: actions/showgroup.php:432
+msgid "Created"
msgstr ""
-#: lib/searchgroupnav.php:82
-msgid "Notice"
+#: actions/showgroup.php:393 actions/showgroup.php:440
+#: actions/showgroup.php:448
+#, php-format
+msgid ""
+"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. Its members share short messages about "
+"their life and interests. [Join now](%%%%action.register%%%%) to become part "
+"of this group and many more! ([Read more](%%%%doc.help%%%%))"
msgstr ""
-#: lib/searchgroupnav.php:83
-msgid "Find content of notices"
+#: actions/showstream.php:147
+msgid "Your profile"
msgstr ""
-#: lib/searchgroupnav.php:85
-msgid "Find groups on this site"
+#: actions/showstream.php:149
+#, php-format
+msgid "%s's profile"
msgstr ""
-#: lib/section.php:89
-msgid "Untitled section"
+#: actions/showstream.php:163 actions/showstream.php:128
+#: actions/showstream.php:129
+#, php-format
+msgid "Notice feed for %s (RSS 1.0)"
msgstr ""
-#: lib/section.php:106
-msgid "More..."
+#: actions/showstream.php:170 actions/showstream.php:135
+#: actions/showstream.php:136
+#, php-format
+msgid "Notice feed for %s (RSS 2.0)"
msgstr ""
-#: lib/subgroupnav.php:83
+#: actions/showstream.php:177 actions/showstream.php:142
+#: actions/showstream.php:143
#, php-format
-msgid "People %s subscribes to"
+msgid "Notice feed for %s (Atom)"
msgstr ""
-#: lib/subgroupnav.php:91
+#: actions/showstream.php:182 actions/showstream.php:147
+#: actions/showstream.php:148
#, php-format
-msgid "People subscribed to %s"
+msgid "FOAF for %s"
+msgstr ""
+
+#: actions/showstream.php:237 actions/showstream.php:202
+#: actions/showstream.php:234 lib/userprofile.php:116
+msgid "Edit Avatar"
+msgstr ""
+
+#: actions/showstream.php:316 actions/showstream.php:281
+#: actions/showstream.php:366 lib/userprofile.php:248
+msgid "Edit profile settings"
msgstr ""
-#: lib/subgroupnav.php:99
+#: actions/showstream.php:317 actions/showstream.php:282
+#: actions/showstream.php:367 lib/userprofile.php:249
+msgid "Edit"
+msgstr ""
+
+#: actions/showstream.php:542 actions/showstream.php:388
+#: actions/showstream.php:487 actions/showstream.php:234
#, php-format
-msgid "Groups %s is a member of"
+msgid ""
+"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. [Join now](%%%%action.register%%%%) to "
+"follow **%s**'s notices and many more! ([Read more](%%%%doc.help%%%%))"
msgstr ""
-#: lib/subscriberspeopleselftagcloudsection.php:48
-#: lib/subscriptionspeopleselftagcloudsection.php:48
-msgid "People Tagcloud as self-tagged"
+#: actions/smssettings.php:335 actions/smssettings.php:347
+msgid ""
+"A confirmation code was sent to the phone number you added. Check your phone "
+"for the code and instructions on how to use it."
msgstr ""
-#: lib/subscriberspeopletagcloudsection.php:48
-#: lib/subscriptionspeopletagcloudsection.php:48
-msgid "People Tagcloud as tagged"
+#: actions/twitapifavorites.php:171 lib/mail.php:556
+#: actions/twitapifavorites.php:222
+#, php-format
+msgid ""
+"%1$s just added your notice from %2$s as one of their favorites.\n"
+"\n"
+"In case you forgot, you can see the text of your notice here:\n"
+"\n"
+"%3$s\n"
+"\n"
+"You can see the list of %1$s's favorites here:\n"
+"\n"
+"%4$s\n"
+"\n"
+"Faithfully yours,\n"
+"%5$s\n"
msgstr ""
-#: lib/subscriptionlist.php:126
-msgid "(none)"
+#: actions/twitapistatuses.php:124 actions/twitapistatuses.php:82
+#: actions/twitapistatuses.php:314 actions/apiblockcreate.php:97
+#: actions/apiblockdestroy.php:96 actions/apidirectmessage.php:77
+#: actions/apidirectmessagenew.php:75 actions/apigroupcreate.php:112
+#: actions/apigroupismember.php:90 actions/apigroupjoin.php:99
+#: actions/apigroupleave.php:99 actions/apigrouplist.php:90
+#: actions/apistatusesupdate.php:125 actions/apisubscriptions.php:87
+#: actions/apitimelinefavorites.php:70 actions/apitimelinefriends.php:79
+#: actions/apitimelinementions.php:79 actions/apitimelineuser.php:81
+#: actions/apiaccountupdateprofileimage.php:91
+#: actions/apiaccountupdateprofileimage.php:105
+#: actions/apistatusesupdate.php:139
+msgid "No such user!"
msgstr ""
-#: lib/subs.php:48
-msgid "Already subscribed!"
+#: actions/twittersettings.php:72
+msgid ""
+"Add your Twitter account to automatically send your notices to Twitter, and "
+"subscribe to Twitter friends already here."
msgstr ""
-#: lib/subs.php:52
-msgid "User has blocked you."
+#: actions/twittersettings.php:345 actions/twittersettings.php:362
+#, php-format
+msgid "Unable to retrieve account information For \"%s\" from Twitter."
msgstr ""
-#: lib/subs.php:56
-msgid "Could not subscribe."
+#: actions/userauthorization.php:86 actions/userauthorization.php:81
+msgid ""
+"Please check these details to make sure that you want to subscribe to this "
+"user's notices. If you didn't just ask to subscribe to someone's notices, "
+"click \"Reject\"."
msgstr ""
-#: lib/subs.php:75
-msgid "Could not subscribe other to you."
+#: actions/usergroups.php:131 actions/usergroups.php:130
+msgid "Search for more groups"
msgstr ""
-#: lib/subs.php:124
-msgid "Not subscribed!."
+#: classes/Notice.php:138 classes/Notice.php:154 classes/Notice.php:194
+msgid ""
+"Too many duplicate messages too quickly; take a breather and post again in a "
+"few minutes."
msgstr ""
-#: lib/subs.php:136
-msgid "Couldn't delete subscription."
+#: lib/action.php:406 lib/action.php:425
+msgid "Connect to SMS, Twitter"
msgstr ""
-#: lib/tagcloudsection.php:56
-msgid "None"
+#: lib/action.php:671 lib/action.php:721 lib/action.php:736
+msgid "Badge"
msgstr ""
-#: lib/topposterssection.php:74
-msgid "Top posters"
+#: lib/command.php:113 lib/command.php:106 lib/command.php:126
+#, php-format
+msgid ""
+"Subscriptions: %1$s\n"
+"Subscribers: %2$s\n"
+"Notices: %3$s"
msgstr ""
-#: lib/unsubscribeform.php:113 lib/unsubscribeform.php:137
-msgid "Unsubscribe from this user"
+#: lib/dberroraction.php:60
+msgid "Database error"
msgstr ""
-#: lib/unsubscribeform.php:137
-msgid "Unsubscribe"
+#: lib/facebookaction.php:271 lib/facebookaction.php:273
+#, php-format
+msgid ""
+"To use the %s Facebook Application you need to login with your username and "
+"password. Don't have a username yet? "
msgstr ""
-#: lib/userprofile.php:116
-msgid "Edit Avatar"
+#: lib/feed.php:85
+msgid "RSS 1.0"
msgstr ""
-#: lib/userprofile.php:236
-msgid "User actions"
+#: lib/feed.php:87
+msgid "RSS 2.0"
msgstr ""
-#: lib/userprofile.php:248
-msgid "Edit profile settings"
+#: lib/feed.php:89
+msgid "Atom"
msgstr ""
-#: lib/userprofile.php:249
-msgid "Edit"
+#: lib/feed.php:91
+msgid "FOAF"
msgstr ""
-#: lib/userprofile.php:272
-msgid "Send a direct message to this user"
+#: lib/imagefile.php:75
+#, php-format
+msgid "That file is too big. The maximum file size is %d."
msgstr ""
-#: lib/userprofile.php:273
-msgid "Message"
+#: lib/mail.php:175 lib/mail.php:174
+#, php-format
+msgid ""
+"Hey, %s.\n"
+"\n"
+"Someone just entered this email address on %s.\n"
+"\n"
+"If it was you, and you want to confirm your entry, use the URL below:\n"
+"\n"
+"\t%s\n"
+"\n"
+"If not, just ignore this message.\n"
+"\n"
+"Thanks for your time, \n"
+"%s\n"
msgstr ""
-#: lib/util.php:844
-msgid "a few seconds ago"
+#: lib/mail.php:241 lib/mail.php:240
+#, php-format
+msgid ""
+"%1$s is now listening to your notices on %2$s.\n"
+"\n"
+"\t%3$s\n"
+"\n"
+"%4$s%5$s%6$s\n"
+"Faithfully yours,\n"
+"%7$s.\n"
+"\n"
+"----\n"
+"Change your email address or notification options at %8$s\n"
msgstr ""
-#: lib/util.php:846
-msgid "about a minute ago"
+#: lib/mail.php:466
+#, php-format
+msgid ""
+"%1$s (%2$s) is wondering what you are up to these days and is inviting you "
+"to post some news.\n"
+"\n"
+"So let's hear from you :)\n"
+"\n"
+"%3$s\n"
+"\n"
+"Don't reply to this email; it won't get to them.\n"
+"\n"
+"With kind regards,\n"
+"%4$s\n"
msgstr ""
-#: lib/util.php:848
+#: lib/mail.php:513
#, php-format
-msgid "about %d minutes ago"
+msgid ""
+"%1$s (%2$s) sent you a private message:\n"
+"\n"
+"------------------------------------------------------\n"
+"%3$s\n"
+"------------------------------------------------------\n"
+"\n"
+"You can reply to their message here:\n"
+"\n"
+"%4$s\n"
+"\n"
+"Don't reply to this email; it won't get to them.\n"
+"\n"
+"With kind regards,\n"
+"%5$s\n"
msgstr ""
-#: lib/util.php:850
-msgid "about an hour ago"
+#: lib/mail.php:598 lib/mail.php:600
+#, php-format
+msgid "%s sent a notice to your attention"
msgstr ""
-#: lib/util.php:852
+#: lib/mail.php:600 lib/mail.php:602
#, php-format
-msgid "about %d hours ago"
+msgid ""
+"%1$s just sent a notice to your attention (an '@-reply') on %2$s.\n"
+"\n"
+"The notice is here:\n"
+"\n"
+"\t%3$s\n"
+"\n"
+"It reads:\n"
+"\n"
+"\t%4$s\n"
+"\n"
+"You can reply back here:\n"
+"\n"
+"\t%5$s\n"
+"\n"
+"The list of all @-replies for you here:\n"
+"\n"
+"%6$s\n"
+"\n"
+"Faithfully yours,\n"
+"%2$s\n"
+"\n"
+"P.S. You can turn off these email notifications here: %7$s\n"
msgstr ""
-#: lib/util.php:854
-msgid "about a day ago"
+#: lib/searchaction.php:122 lib/searchaction.php:120
+msgid "Search site"
+msgstr ""
+
+#: lib/section.php:106
+msgid "More..."
msgstr ""
-#: lib/util.php:856
+#: actions/all.php:80 actions/all.php:127
#, php-format
-msgid "about %d days ago"
+msgid ""
+"This is the timeline for %s and friends but no one has posted anything yet."
msgstr ""
-#: lib/util.php:858
-msgid "about a month ago"
+#: actions/all.php:85 actions/all.php:132
+#, php-format
+msgid ""
+"Try subscribing to more people, [join a group](%%action.groups%%) or post "
+"something yourself."
msgstr ""
-#: lib/util.php:860
+#: actions/all.php:87 actions/all.php:134
#, php-format
-msgid "about %d months ago"
+msgid ""
+"You can try to [nudge %s](../%s) from his profile or [post something to his "
+"or her attention](%%%%action.newnotice%%%%?status_textarea=%s)."
msgstr ""
-#: lib/util.php:862
-msgid "about a year ago"
+#: actions/all.php:91 actions/replies.php:190 actions/showstream.php:361
+#: actions/all.php:137 actions/replies.php:209 actions/showstream.php:455
+#: actions/showstream.php:202
+#, php-format
+msgid ""
+"Why not [register an account](%%%%action.register%%%%) and then nudge %s or "
+"post a notice to his or her attention."
msgstr ""
-#: lib/webcolor.php:82
+#: actions/attachment.php:73
+msgid "No such attachment."
+msgstr ""
+
+#: actions/block.php:149
+msgid "Do not block this user from this group"
+msgstr ""
+
+#: actions/block.php:150
+msgid "Block this user from this group"
+msgstr ""
+
+#: actions/blockedfromgroup.php:90
#, php-format
-msgid "%s is not a valid color!"
+msgid "%s blocked profiles"
msgstr ""
-#: lib/webcolor.php:123
+#: actions/blockedfromgroup.php:93
#, php-format
-msgid "%s is not a valid color! Use 3 or 6 hex chars."
+msgid "%s blocked profiles, page %d"
msgstr ""
-#: scripts/maildaemon.php:48
-msgid "Could not parse message."
+#: actions/blockedfromgroup.php:108
+msgid "A list of the users blocked from joining this group."
msgstr ""
-#: scripts/maildaemon.php:53
-msgid "Not a registered user."
+#: actions/blockedfromgroup.php:281
+msgid "Unblock user from group"
msgstr ""
-#: scripts/maildaemon.php:57
-msgid "Sorry, that is not your incoming email address."
+#: actions/conversation.php:99
+msgid "Conversation"
msgstr ""
-#: scripts/maildaemon.php:61
-msgid "Sorry, no incoming email allowed."
+#: actions/deletenotice.php:115 actions/deletenotice.php:145
+msgid "Do not delete this notice"
+msgstr ""
+
+#: actions/editgroup.php:214 actions/newgroup.php:164
+#: actions/apigroupcreate.php:291 actions/editgroup.php:215
+#: actions/newgroup.php:159
+#, php-format
+msgid "Too many aliases! Maximum %d."
+msgstr ""
+
+#: actions/editgroup.php:223 actions/newgroup.php:173
+#: actions/apigroupcreate.php:312 actions/editgroup.php:224
+#: actions/newgroup.php:168
+#, php-format
+msgid "Invalid alias: \"%s\""
+msgstr ""
+
+#: actions/editgroup.php:227 actions/newgroup.php:177
+#: actions/apigroupcreate.php:321 actions/editgroup.php:228
+#: actions/newgroup.php:172
+#, php-format
+msgid "Alias \"%s\" already in use. Try another one."
+msgstr ""
+
+#: actions/editgroup.php:233 actions/newgroup.php:183
+#: actions/apigroupcreate.php:334 actions/editgroup.php:234
+#: actions/newgroup.php:178
+msgid "Alias can't be the same as nickname."
+msgstr ""
+
+#: actions/editgroup.php:259 actions/newgroup.php:215
+#: actions/apigroupcreate.php:147 actions/newgroup.php:210
+msgid "Could not create aliases."
+msgstr ""
+
+#: actions/favorited.php:150
+msgid "Favorite notices appear on this page but no one has favorited one yet."
+msgstr ""
+
+#: actions/favorited.php:153
+msgid ""
+"Be the first to add a notice to your favorites by clicking the fave button "
+"next to any notice you like."
+msgstr ""
+
+#: actions/favorited.php:156
+#, php-format
+msgid ""
+"Why not [register an account](%%action.register%%) and be the first to add a "
+"notice to your favorites!"
+msgstr ""
+
+#: actions/file.php:34
+msgid "No notice id"
+msgstr ""
+
+#: actions/file.php:38
+msgid "No notice"
+msgstr ""
+
+#: actions/file.php:42
+msgid "No attachments"
+msgstr ""
+
+#: actions/file.php:51
+msgid "No uploaded attachments"
+msgstr ""
+
+#: actions/finishopenidlogin.php:211
+msgid "Not a valid invitation code."
+msgstr ""
+
+#: actions/groupblock.php:81 actions/groupunblock.php:81
+#: actions/makeadmin.php:81
+msgid "No group specified."
+msgstr ""
+
+#: actions/groupblock.php:91
+msgid "Only an admin can block group members."
+msgstr ""
+
+#: actions/groupblock.php:95
+msgid "User is already blocked from group."
+msgstr ""
+
+#: actions/groupblock.php:100
+msgid "User is not a member of group."
+msgstr ""
+
+#: actions/groupblock.php:136 actions/groupmembers.php:311
+#: actions/groupmembers.php:314
+msgid "Block user from group"
+msgstr ""
+
+#: actions/groupblock.php:155
+#, php-format
+msgid ""
+"Are you sure you want to block user \"%s\" from the group \"%s\"? They will "
+"be removed from the group, unable to post, and unable to subscribe to the "
+"group in the future."
+msgstr ""
+
+#: actions/groupblock.php:193
+msgid "Database error blocking user from group."
+msgstr ""
+
+#: actions/groupdesignsettings.php:73 actions/groupdesignsettings.php:68
+msgid "You must be logged in to edit a group."
+msgstr ""
+
+#: actions/groupdesignsettings.php:146 actions/groupdesignsettings.php:141
+msgid "Group design"
+msgstr ""
+
+#: actions/groupdesignsettings.php:157 actions/groupdesignsettings.php:152
+msgid ""
+"Customize the way your group looks with a background image and a colour "
+"palette of your choice."
+msgstr ""
+
+#: actions/groupdesignsettings.php:267 actions/userdesignsettings.php:186
+#: lib/designsettings.php:440 lib/designsettings.php:470
+#: actions/groupdesignsettings.php:262 lib/designsettings.php:431
+#: lib/designsettings.php:461 lib/designsettings.php:434
+#: lib/designsettings.php:464
+msgid "Couldn't update your design."
+msgstr ""
+
+#: actions/groupdesignsettings.php:291 actions/groupdesignsettings.php:301
+#: actions/userdesignsettings.php:210 actions/userdesignsettings.php:220
+#: actions/userdesignsettings.php:263 actions/userdesignsettings.php:273
+#: actions/groupdesignsettings.php:286 actions/groupdesignsettings.php:296
+msgid "Unable to save your design settings!"
+msgstr ""
+
+#: actions/groupdesignsettings.php:312 actions/userdesignsettings.php:231
+#: actions/groupdesignsettings.php:307
+msgid "Design preferences saved."
+msgstr ""
+
+#: actions/groupmembers.php:438 actions/groupmembers.php:441
+msgid "Make user an admin of the group"
+msgstr ""
+
+#: actions/groupmembers.php:470 actions/groupmembers.php:473
+msgid "Make Admin"
+msgstr ""
+
+#: actions/groupmembers.php:470 actions/groupmembers.php:473
+msgid "Make this user an admin"
+msgstr ""
+
+#: actions/groupsearch.php:79 actions/noticesearch.php:117
+#: actions/peoplesearch.php:83
+msgid "No results."
+msgstr ""
+
+#: actions/groupsearch.php:82
+#, php-format
+msgid ""
+"If you can't find the group you're looking for, you can [create it](%%action."
+"newgroup%%) yourself."
+msgstr ""
+
+#: actions/groupsearch.php:85
+#, php-format
+msgid ""
+"Why not [register an account](%%action.register%%) and [create the group](%%"
+"action.newgroup%%) yourself!"
+msgstr ""
+
+#: actions/groupunblock.php:91
+msgid "Only an admin can unblock group members."
+msgstr ""
+
+#: actions/groupunblock.php:95
+msgid "User is not blocked from group."
+msgstr ""
+
+#: actions/invite.php:39
+msgid "Invites have been disabled."
+msgstr ""
+
+#: actions/joingroup.php:100 actions/apigroupjoin.php:119
+#: actions/joingroup.php:95 lib/command.php:221
+msgid "You have been blocked from that group by the admin."
+msgstr ""
+
+#: actions/makeadmin.php:91
+msgid "Only an admin can make another user an admin."
+msgstr ""
+
+#: actions/makeadmin.php:95
+#, php-format
+msgid "%s is already an admin for group \"%s\"."
+msgstr ""
+
+#: actions/makeadmin.php:132
+#, php-format
+msgid "Can't get membership record for %s in group %s"
+msgstr ""
+
+#: actions/makeadmin.php:145
+#, php-format
+msgid "Can't make %s an admin for group %s"
+msgstr ""
+
+#: actions/newmessage.php:178 actions/newmessage.php:181
+msgid "Message sent"
+msgstr ""
+
+#: actions/newnotice.php:93 lib/designsettings.php:281
+#: actions/newnotice.php:94 actions/apiaccountupdateprofileimage.php:97
+#: actions/apistatusesupdate.php:122 actions/avatarsettings.php:254
+#: lib/designsettings.php:283
+#, php-format
+msgid ""
+"The server was unable to handle that much POST data (%s bytes) due to its "
+"current configuration."
+msgstr ""
+
+#: actions/newnotice.php:128 scripts/maildaemon.php:185 lib/mediafile.php:270
+#, php-format
+msgid " Try using another %s format."
+msgstr ""
+
+#: actions/newnotice.php:133 scripts/maildaemon.php:190 lib/mediafile.php:275
+#, php-format
+msgid "%s is not a supported filetype on this server."
+msgstr ""
+
+#: actions/newnotice.php:205 lib/mediafile.php:142
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini."
+msgstr ""
+
+#: actions/newnotice.php:208 lib/mediafile.php:147
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form."
+msgstr ""
+
+#: actions/newnotice.php:211 lib/mediafile.php:152
+msgid "The uploaded file was only partially uploaded."
+msgstr ""
+
+#: actions/newnotice.php:214 lib/mediafile.php:159
+msgid "Missing a temporary folder."
+msgstr ""
+
+#: actions/newnotice.php:217 lib/mediafile.php:162
+msgid "Failed to write file to disk."
+msgstr ""
+
+#: actions/newnotice.php:220 lib/mediafile.php:165
+msgid "File upload stopped by extension."
+msgstr ""
+
+#: actions/newnotice.php:230 scripts/maildaemon.php:85
+msgid "Couldn't save file."
+msgstr ""
+
+#: actions/newnotice.php:246 scripts/maildaemon.php:101
+msgid "Max notice size is 140 chars, including attachment URL."
+msgstr ""
+
+#: actions/newnotice.php:297
+msgid "Somehow lost the login in saveFile"
+msgstr ""
+
+#: actions/newnotice.php:309 scripts/maildaemon.php:127 lib/mediafile.php:196
+#: lib/mediafile.php:233
+msgid "File could not be moved to destination directory."
+msgstr ""
+
+#: actions/newnotice.php:336 actions/newnotice.php:360
+#: scripts/maildaemon.php:148 scripts/maildaemon.php:167 lib/mediafile.php:98
+#: lib/mediafile.php:123
+msgid "There was a database error while saving your file. Please try again."
+msgstr ""
+
+#: actions/noticesearch.php:121
+#, php-format
+msgid ""
+"Be the first to [post on this topic](%%%%action.newnotice%%%%?"
+"status_textarea=%s)!"
+msgstr ""
+
+#: actions/noticesearch.php:124
+#, php-format
+msgid ""
+"Why not [register an account](%%%%action.register%%%%) and be the first to "
+"[post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!"
+msgstr ""
+
+#: actions/openidsettings.php:70
+#, php-format
+msgid ""
+"[OpenID](%%doc.openid%%) lets you log into many sites with the same user "
+"account. Manage your associated OpenIDs from here."
+msgstr ""
+
+#: actions/othersettings.php:110 actions/othersettings.php:117
+msgid "Shorten URLs with"
+msgstr ""
+
+#: actions/othersettings.php:115 actions/othersettings.php:122
+msgid "View profile designs"
+msgstr ""
+
+#: actions/othersettings.php:116 actions/othersettings.php:123
+msgid "Show or hide profile designs."
+msgstr ""
+
+#: actions/public.php:82 actions/public.php:83
+#, php-format
+msgid "Beyond the page limit (%s)"
+msgstr ""
+
+#: actions/public.php:179
+#, php-format
+msgid ""
+"This is the public timeline for %%site.name%% but no one has posted anything "
+"yet."
+msgstr ""
+
+#: actions/public.php:182
+msgid "Be the first to post!"
+msgstr ""
+
+#: actions/public.php:186
+#, php-format
+msgid ""
+"Why not [register an account](%%action.register%%) and be the first to post!"
+msgstr ""
+
+#: actions/public.php:245 actions/public.php:238
+#, php-format
+msgid ""
+"This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-"
+"blogging) service based on the Free Software [StatusNet](http://status.net/) "
+"tool."
+msgstr ""
+
+#: actions/publictagcloud.php:69
+#, php-format
+msgid "No one has posted a notice with a [hashtag](%%doc.tags%%) yet."
+msgstr ""
+
+#: actions/publictagcloud.php:72
+msgid "Be the first to post one!"
+msgstr ""
+
+#: actions/publictagcloud.php:75
+#, php-format
+msgid ""
+"Why not [register an account](%%action.register%%) and be the first to post "
+"one!"
+msgstr ""
+
+#: actions/recoverpassword.php:152
+msgid ""
+"If you've forgotten or lost your password, you can get a new one sent to the "
+"email address you have stored in your account."
+msgstr ""
+
+#: actions/recoverpassword.php:158
+msgid "You've been identified. Enter a new password below. "
+msgstr ""
+
+#: actions/recoverpassword.php:188
+msgid "Password recover"
+msgstr ""
+
+#: actions/register.php:86 actions/register.php:92
+msgid "Sorry, invalid invitation code."
+msgstr ""
+
+#: actions/remotesubscribe.php:100 actions/remotesubscribe.php:124
+msgid "Subscribe to a remote user"
+msgstr ""
+
+#: actions/replies.php:179 actions/replies.php:198
+#, php-format
+msgid ""
+"This is the timeline showing replies to %s but %s hasn't received a notice "
+"to his attention yet."
+msgstr ""
+
+#: actions/replies.php:184 actions/replies.php:203
+#, php-format
+msgid ""
+"You can engage other users in a conversation, subscribe to more people or "
+"[join groups](%%action.groups%%)."
+msgstr ""
+
+#: actions/replies.php:186 actions/replies.php:205
+#, php-format
+msgid ""
+"You can try to [nudge %s](../%s) or [post something to his or her attention]"
+"(%%%%action.newnotice%%%%?status_textarea=%s)."
+msgstr ""
+
+#: actions/showfavorites.php:79
+#, php-format
+msgid "%s's favorite notices, page %d"
+msgstr ""
+
+#: actions/showfavorites.php:170 actions/showfavorites.php:205
+msgid ""
+"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."
+msgstr ""
+
+#: actions/showfavorites.php:172 actions/showfavorites.php:207
+#, php-format
+msgid ""
+"%s hasn't added any notices to his favorites yet. Post something interesting "
+"they would add to their favorites :)"
+msgstr ""
+
+#: actions/showfavorites.php:176
+#, php-format
+msgid ""
+"%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 thier favorites :)"
+msgstr ""
+
+#: actions/showfavorites.php:226 actions/showfavorites.php:242
+msgid "This is a way to share what you like."
+msgstr ""
+
+#: actions/showgroup.php:279 lib/groupeditform.php:178
+#: actions/showgroup.php:284 lib/groupeditform.php:184
+msgid "Aliases"
+msgstr ""
+
+#: actions/showgroup.php:323 actions/showgroup.php:328
+#, php-format
+msgid "Notice feed for %s group (RSS 1.0)"
+msgstr ""
+
+#: actions/showgroup.php:330 actions/tag.php:84 actions/showgroup.php:334
+#, php-format
+msgid "Notice feed for %s group (RSS 2.0)"
+msgstr ""
+
+#: actions/showgroup.php:337 actions/showgroup.php:340
+#, php-format
+msgid "Notice feed for %s group (Atom)"
+msgstr ""
+
+#: actions/showgroup.php:446 actions/showgroup.php:454
+#, php-format
+msgid ""
+"**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. Its members share short messages about "
+"their life and interests. "
+msgstr ""
+
+#: actions/showgroup.php:474 actions/showgroup.php:482
+msgid "Admins"
+msgstr ""
+
+#: actions/shownotice.php:101
+msgid "Not a local notice"
+msgstr ""
+
+#: actions/showstream.php:72 actions/showstream.php:73
+#, php-format
+msgid " tagged %s"
+msgstr ""
+
+#: actions/showstream.php:121 actions/showstream.php:122
+#, php-format
+msgid "Notice feed for %s tagged %s (RSS 1.0)"
+msgstr ""
+
+#: actions/showstream.php:350 actions/showstream.php:444
+#: actions/showstream.php:191
+#, php-format
+msgid "This is the timeline for %s but %s hasn't posted anything yet."
+msgstr ""
+
+#: actions/showstream.php:355 actions/showstream.php:449
+#: actions/showstream.php:196
+msgid ""
+"Seen anything interesting recently? You haven't posted any notices yet, now "
+"would be a good time to start :)"
+msgstr ""
+
+#: actions/showstream.php:357 actions/showstream.php:451
+#: actions/showstream.php:198
+#, php-format
+msgid ""
+"You can try to nudge %s or [post something to his or her attention](%%%%"
+"action.newnotice%%%%?status_textarea=%s)."
+msgstr ""
+
+#: actions/showstream.php:393 actions/showstream.php:492
+#: actions/showstream.php:239
+#, php-format
+msgid ""
+"**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en."
+"wikipedia.org/wiki/Micro-blogging) service based on the Free Software "
+"[StatusNet](http://status.net/) tool. "
+msgstr ""
+
+#: actions/subscribers.php:108
+msgid ""
+"You have no subscribers. Try subscribing to people you know and they might "
+"return the favor"
+msgstr ""
+
+#: actions/subscribers.php:110
+#, php-format
+msgid "%s has no subscribers. Want to be the first?"
+msgstr ""
+
+#: actions/subscribers.php:114
+#, php-format
+msgid ""
+"%s has no subscribers. Why not [register an account](%%%%action.register%%%"
+"%) and be the first?"
+msgstr ""
+
+#: actions/subscriptions.php:115 actions/subscriptions.php:121
+#, php-format
+msgid ""
+"You're not listening to anyone's notices right now, try subscribing to "
+"people you know. Try [people search](%%action.peoplesearch%%), look for "
+"members in groups you're interested in and in our [featured users](%%action."
+"featured%%). If you're a [Twitter user](%%action.twittersettings%%), you can "
+"automatically subscribe to people you already follow there."
+msgstr ""
+
+#: actions/subscriptions.php:117 actions/subscriptions.php:121
+#: actions/subscriptions.php:123 actions/subscriptions.php:127
+#, php-format
+msgid "%s is not listening to anyone."
+msgstr ""
+
+#: actions/tag.php:77 actions/tag.php:86
+#, php-format
+msgid "Notice feed for tag %s (RSS 1.0)"
+msgstr ""
+
+#: actions/tag.php:91 actions/tag.php:98
+#, php-format
+msgid "Notice feed for tag %s (Atom)"
+msgstr ""
+
+#: actions/twitapifavorites.php:125 actions/apifavoritecreate.php:119
+msgid "This status is already a favorite!"
+msgstr ""
+
+#: actions/twitapifavorites.php:179 actions/apifavoritedestroy.php:122
+msgid "That status is not a favorite!"
+msgstr ""
+
+#: actions/twitapifriendships.php:180 actions/twitapifriendships.php:200
+#: actions/apifriendshipsshow.php:135
+msgid "Could not determine source user."
+msgstr ""
+
+#: actions/twitapifriendships.php:215
+msgid "Target user not specified."
+msgstr ""
+
+#: actions/twitapifriendships.php:221 actions/apifriendshipsshow.php:143
+msgid "Could not find target user."
+msgstr ""
+
+#: actions/twitapistatuses.php:322 actions/apitimelinementions.php:116
+#, php-format
+msgid "%1$s / Updates mentioning %2$s"
+msgstr ""
+
+#: actions/twitapitags.php:74 actions/apitimelinetag.php:107
+#: actions/tagrss.php:64
+#, php-format
+msgid "Updates tagged with %1$s on %2$s!"
+msgstr ""
+
+#: actions/twittersettings.php:165
+msgid "Import my Friends Timeline."
+msgstr ""
+
+#: actions/userauthorization.php:158 actions/userauthorization.php:188
+msgid "License"
+msgstr ""
+
+#: actions/userauthorization.php:179 actions/userauthorization.php:212
+msgid "Reject this subscription"
+msgstr ""
+
+#: actions/userdesignsettings.php:76 lib/designsettings.php:65
+msgid "Profile design"
+msgstr ""
+
+#: actions/userdesignsettings.php:87 lib/designsettings.php:76
+msgid ""
+"Customize the way your profile looks with a background image and a colour "
+"palette of your choice."
+msgstr ""
+
+#: actions/userdesignsettings.php:282
+msgid "Enjoy your hotdog!"
+msgstr ""
+
+#: actions/usergroups.php:153
+#, php-format
+msgid "%s is not a member of any group."
+msgstr ""
+
+#: actions/usergroups.php:158
+#, php-format
+msgid "Try [searching for groups](%%action.groupsearch%%) and joining them."
+msgstr ""
+
+#: classes/File.php:127 classes/File.php:137
+#, php-format
+msgid ""
+"No file may be larger than %d bytes and the file you sent was %d bytes. Try "
+"to upload a smaller version."
+msgstr ""
+
+#: classes/File.php:137 classes/File.php:147
+#, php-format
+msgid "A file this large would exceed your user quota of %d bytes."
+msgstr ""
+
+#: classes/File.php:145 classes/File.php:154
+#, php-format
+msgid "A file this large would exceed your monthly quota of %d bytes."
+msgstr ""
+
+#: classes/Notice.php:139 classes/Notice.php:179
+msgid "Problem saving notice. Too long."
+msgstr ""
+
+#: classes/User.php:319 classes/User.php:327 classes/User.php:334
+#: classes/User.php:333
+#, php-format
+msgid "Welcome to %1$s, @%2$s!"
+msgstr ""
+
+#: lib/accountsettingsaction.php:119 lib/groupnav.php:118
+#: lib/accountsettingsaction.php:120
+msgid "Design"
+msgstr ""
+
+#: lib/accountsettingsaction.php:120 lib/accountsettingsaction.php:121
+msgid "Design your profile"
+msgstr ""
+
+#: lib/action.php:712 lib/action.php:727
+msgid "TOS"
+msgstr ""
+
+#: lib/attachmentlist.php:87
+msgid "Attachments"
+msgstr ""
+
+#: lib/attachmentlist.php:265
+msgid "Author"
+msgstr ""
+
+#: lib/attachmentlist.php:278
+msgid "Provider"
+msgstr ""
+
+#: lib/attachmentnoticesection.php:67
+msgid "Notices where this attachment appears"
+msgstr ""
+
+#: lib/attachmenttagcloudsection.php:48
+msgid "Tags for this attachment"
+msgstr ""
+
+#: lib/designsettings.php:101
+msgid "Change background image"
+msgstr ""
+
+#: lib/designsettings.php:105
+msgid "Upload file"
+msgstr ""
+
+#: lib/designsettings.php:109
+msgid ""
+"You can upload your personal background image. The maximum file size is 2Mb."
+msgstr ""
+
+#: lib/designsettings.php:139
+msgid "On"
+msgstr ""
+
+#: lib/designsettings.php:155
+msgid "Off"
+msgstr ""
+
+#: lib/designsettings.php:156
+msgid "Turn background image on or off."
+msgstr ""
+
+#: lib/designsettings.php:161
+msgid "Tile background image"
+msgstr ""
+
+#: lib/designsettings.php:170
+msgid "Change colours"
+msgstr ""
+
+#: lib/designsettings.php:178
+msgid "Background"
+msgstr ""
+
+#: lib/designsettings.php:191
+msgid "Content"
+msgstr ""
+
+#: lib/designsettings.php:204
+msgid "Sidebar"
+msgstr ""
+
+#: lib/designsettings.php:230
+msgid "Links"
+msgstr ""
+
+#: lib/designsettings.php:247
+msgid "Use defaults"
+msgstr ""
+
+#: lib/designsettings.php:248
+msgid "Restore default designs"
+msgstr ""
+
+#: lib/designsettings.php:254
+msgid "Reset back to default"
+msgstr ""
+
+#: lib/designsettings.php:257
+msgid "Save design"
+msgstr ""
+
+#: lib/designsettings.php:378 lib/designsettings.php:369
+#: lib/designsettings.php:372
+msgid "Bad default color settings: "
+msgstr ""
+
+#: lib/designsettings.php:474 lib/designsettings.php:465
+#: lib/designsettings.php:468
+msgid "Design defaults restored."
+msgstr ""
+
+#: lib/groupeditform.php:181 lib/groupeditform.php:187
+#, php-format
+msgid "Extra nicknames for the group, comma- or space- separated, max %d"
+msgstr ""
+
+#: lib/groupnav.php:100
+msgid "Blocked"
+msgstr ""
+
+#: lib/groupnav.php:101
+#, php-format
+msgid "%s blocked users"
+msgstr ""
+
+#: lib/groupnav.php:119
+#, php-format
+msgid "Add or edit %s design"
+msgstr ""
+
+#: lib/mail.php:556
+#, php-format
+msgid ""
+"%1$s just added your notice from %2$s as one of their favorites.\n"
+"\n"
+"The URL of your notice is:\n"
+"\n"
+"%3$s\n"
+"\n"
+"The text of your notice is:\n"
+"\n"
+"%4$s\n"
+"\n"
+"You can see the list of %1$s's favorites here:\n"
+"\n"
+"%5$s\n"
+"\n"
+"Faithfully yours,\n"
+"%6$s\n"
+msgstr ""
+
+#: lib/mail.php:646
+#, php-format
+msgid "Your Twitter bridge has been disabled."
+msgstr ""
+
+#: lib/mail.php:648
+#, php-format
+msgid ""
+"Hi, %1$s. We're sorry to inform you that your link to Twitter has been "
+"disabled. Your Twitter credentials have either changed (did you recently "
+"change your Twitter password?) or you have otherwise revoked our access to "
+"your Twitter account.\n"
+"\n"
+"You can re-enable your Twitter bridge by visiting your Twitter settings "
+"page:\n"
+"\n"
+"\t%2$s\n"
+"\n"
+"Regards,\n"
+"%3$s\n"
+msgstr ""
+
+#: lib/mail.php:682
+#, php-format
+msgid "Your %s Facebook application access has been disabled."
+msgstr ""
+
+#: lib/mail.php:685
+#, php-format
+msgid ""
+"Hi, %1$s. We're sorry to inform you that we are unable to update your "
+"Facebook status from %s, and have disabled the Facebook application for your "
+"account. This may be because you have removed the Facebook application's "
+"authorization, or have deleted your Facebook account. You can re-enable the "
+"Facebook application and automatic status updating by re-installing the %1$s "
+"Facebook application.\n"
+"\n"
+"Regards,\n"
+"\n"
+"%1$s"
+msgstr ""
+
+#: lib/mailbox.php:139
+msgid ""
+"You have no private messages. You can send private message to engage other "
+"users in conversation. People can send you messages for your eyes only."
+msgstr ""
+
+#: lib/noticeform.php:154 lib/noticeform.php:180
+msgid "Attach"
+msgstr ""
+
+#: lib/noticeform.php:158 lib/noticeform.php:184
+msgid "Attach a file"
+msgstr ""
+
+#: lib/noticelist.php:436 lib/noticelist.php:478
+msgid "in context"
+msgstr ""
+
+#: lib/profileaction.php:177
+msgid "User ID"
+msgstr ""
+
+#: lib/searchaction.php:156 lib/searchaction.php:162
+msgid "Search help"
+msgstr ""
+
+#: lib/subscriberspeopleselftagcloudsection.php:48
+#: lib/subscriptionspeopleselftagcloudsection.php:48
+msgid "People Tagcloud as self-tagged"
+msgstr ""
+
+#: lib/subscriberspeopletagcloudsection.php:48
+#: lib/subscriptionspeopletagcloudsection.php:48
+msgid "People Tagcloud as tagged"
+msgstr ""
+
+#: lib/webcolor.php:82
+#, php-format
+msgid "%s is not a valid color!"
+msgstr ""
+
+#: lib/webcolor.php:123
+#, php-format
+msgid "%s is not a valid color! Use 3 or 6 hex chars."
+msgstr ""
+
+#: actions/all.php:63 actions/public.php:97 actions/replies.php:92
+#: actions/showfavorites.php:137 actions/tag.php:51
+msgid "No such page"
+msgstr ""
+
+#: actions/apidirectmessage.php:89
+#, php-format
+msgid "Direct messages from %s"
+msgstr ""
+
+#: actions/apidirectmessagenew.php:135 actions/newmessage.php:150
+#, php-format
+msgid "That's too long. Max message size is %d chars."
+msgstr ""
+
+#: actions/apifriendshipsdestroy.php:109
+msgid "Could not unfollow user: User not found."
+msgstr ""
+
+#: actions/apifriendshipsdestroy.php:120
+msgid "You cannot unfollow yourself!"
+msgstr ""
+
+#: actions/apigroupcreate.php:261
+#, php-format
+msgid "Description is too long (max %d chars)."
+msgstr ""
+
+#: actions/apigroupjoin.php:110
+msgid "You are already a member of that group."
+msgstr ""
+
+#: actions/apigroupjoin.php:138
+#, php-format
+msgid "Could not join user %s to group %s."
+msgstr ""
+
+#: actions/apigroupleave.php:114
+msgid "You are not a member of this group."
+msgstr ""
+
+#: actions/apigroupleave.php:124
+#, php-format
+msgid "Could not remove user %s to group %s."
+msgstr ""
+
+#: actions/apigrouplist.php:95
+#, php-format
+msgid "%s's groups"
+msgstr ""
+
+#: actions/apigrouplist.php:103
+#, php-format
+msgid "Groups %s is a member of on %s."
+msgstr ""
+
+#: actions/apigrouplistall.php:94
+#, php-format
+msgid "groups on %s"
+msgstr ""
+
+#: actions/apistatusesshow.php:138
+msgid "Status deleted."
+msgstr ""
+
+#: actions/apistatusesupdate.php:132
+#: actions/apiaccountupdateprofileimage.php:99
+msgid "Unable to handle that much POST data!"
+msgstr ""
+
+#: actions/apistatusesupdate.php:145 actions/newnotice.php:155
+#: scripts/maildaemon.php:71 actions/apistatusesupdate.php:152
+#, php-format
+msgid "That's too long. Max notice size is %d chars."
+msgstr ""
+
+#: actions/apistatusesupdate.php:209 actions/newnotice.php:178
+#: actions/apistatusesupdate.php:216
+#, php-format
+msgid "Max notice size is %d chars, including attachment URL."
+msgstr ""
+
+#: actions/apisubscriptions.php:231 actions/apisubscriptions.php:261
+msgid "Unsupported format."
+msgstr ""
+
+#: actions/bookmarklet.php:50
+msgid "Post to "
+msgstr ""
+
+#: actions/editgroup.php:201 actions/newgroup.php:145
+#, php-format
+msgid "description is too long (max %d chars)."
+msgstr ""
+
+#: actions/favoritesrss.php:115
+#, php-format
+msgid "Updates favored by %1$s on %2$s!"
+msgstr ""
+
+#: actions/finishremotesubscribe.php:80
+msgid "User being listened to does not exist."
+msgstr ""
+
+#: actions/finishremotesubscribe.php:106
+msgid "You are not authorized."
+msgstr ""
+
+#: actions/finishremotesubscribe.php:109
+msgid "Could not convert request token to access token."
+msgstr ""
+
+#: actions/finishremotesubscribe.php:114
+msgid "Remote service uses unknown version of OMB protocol."
+msgstr ""
+
+#: actions/getfile.php:75
+msgid "No such file."
+msgstr ""
+
+#: actions/getfile.php:79
+msgid "Cannot read file."
+msgstr ""
+
+#: actions/grouprss.php:133
+#, php-format
+msgid "Updates from members of %1$s on %2$s!"
+msgstr ""
+
+#: actions/imsettings.php:89
+msgid "IM is not available."
+msgstr ""
+
+#: actions/login.php:259 actions/login.php:286
+#, php-format
+msgid ""
+"Login with your username and password. Don't have a username yet? [Register]"
+"(%%action.register%%) a new account."
+msgstr ""
+
+#: actions/noticesearchrss.php:89
+#, php-format
+msgid "Updates with \"%s\""
+msgstr ""
+
+#: actions/noticesearchrss.php:91
+#, php-format
+msgid "Updates matching search term \"%1$s\" on %2$s!"
+msgstr ""
+
+#: actions/oembed.php:157
+msgid "content type "
+msgstr ""
+
+#: actions/oembed.php:160
+msgid "Only "
+msgstr ""
+
+#: actions/postnotice.php:90
+#, php-format
+msgid "Notice license ‘%s’ is not compatible with site license ‘%s’."
+msgstr ""
+
+#: actions/profilesettings.php:122 actions/register.php:454
+#: actions/register.php:460
+#, php-format
+msgid "Describe yourself and your interests in %d chars"
+msgstr ""
+
+#: actions/profilesettings.php:125 actions/register.php:457
+#: actions/register.php:463
+msgid "Describe yourself and your interests"
+msgstr ""
+
+#: actions/profilesettings.php:221 actions/register.php:217
+#: actions/register.php:223
+#, php-format
+msgid "Bio is too long (max %d chars)."
+msgstr ""
+
+#: actions/register.php:336 actions/register.php:342
+msgid ""
+"With this form you can create a new account. You can then post notices and "
+"link up to friends and colleagues. "
+msgstr ""
+
+#: actions/remotesubscribe.php:168
+msgid ""
+"Not a valid profile URL (no YADIS document or no or invalid XRDS defined)."
+msgstr ""
+
+#: actions/remotesubscribe.php:176
+msgid "That’s a local profile! Login to subscribe."
+msgstr ""
+
+#: actions/remotesubscribe.php:183
+msgid "Couldn’t get a request token."
+msgstr ""
+
+#: actions/replies.php:144
+#, php-format
+msgid "Replies feed for %s (RSS 1.0)"
+msgstr ""
+
+#: actions/replies.php:151
+#, php-format
+msgid "Replies feed for %s (RSS 2.0)"
+msgstr ""
+
+#: actions/replies.php:158
+#, php-format
+msgid "Replies feed for %s (Atom)"
+msgstr ""
+
+#: actions/repliesrss.php:72
+#, php-format
+msgid "Replies to %1$s on %2$s!"
+msgstr ""
+
+#: actions/showfavorites.php:170
+#, php-format
+msgid "Feed for favorites of %s (RSS 1.0)"
+msgstr ""
+
+#: actions/showfavorites.php:177
+#, php-format
+msgid "Feed for favorites of %s (RSS 2.0)"
+msgstr ""
+
+#: actions/showfavorites.php:184
+#, php-format
+msgid "Feed for favorites of %s (Atom)"
+msgstr ""
+
+#: actions/showfavorites.php:211
+#, php-format
+msgid ""
+"%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 :)"
+msgstr ""
+
+#: actions/showgroup.php:345
+#, php-format
+msgid "FOAF for %s group"
+msgstr ""
+
+#: actions/shownotice.php:90
+msgid "Notice deleted."
+msgstr ""
+
+#: actions/smssettings.php:91
+msgid "SMS is not available."
+msgstr ""
+
+#: actions/tag.php:92
+#, php-format
+msgid "Notice feed for tag %s (RSS 2.0)"
+msgstr ""
+
+#: actions/updateprofile.php:62 actions/userauthorization.php:330
+#, php-format
+msgid "Listenee stream license ‘%s’ is not compatible with site license ‘%s’."
+msgstr ""
+
+#: actions/userauthorization.php:110
+msgid ""
+"Please check these details to make sure that you want to subscribe to this "
+"user’s notices. If you didn’t just ask to subscribe to someone’s notices, "
+"click “Reject”."
+msgstr ""
+
+#: actions/userauthorization.php:249
+msgid ""
+"The subscription has been authorized, but no callback URL was passed. Check "
+"with the site’s instructions for details on how to authorize the "
+"subscription. Your subscription token is:"
+msgstr ""
+
+#: actions/userauthorization.php:261
+msgid ""
+"The subscription has been rejected, but no callback URL was passed. Check "
+"with the site’s instructions for details on how to fully reject the "
+"subscription."
+msgstr ""
+
+#: actions/userauthorization.php:296
+#, php-format
+msgid "Listener URI ‘%s’ not found here"
+msgstr ""
+
+#: actions/userauthorization.php:301
+#, php-format
+msgid "Listenee URI ‘%s’ is too long."
+msgstr ""
+
+#: actions/userauthorization.php:307
+#, php-format
+msgid "Listenee URI ‘%s’ is a local user."
+msgstr ""
+
+#: actions/userauthorization.php:322
+#, php-format
+msgid "Profile URL ‘%s’ is for a local user."
+msgstr ""
+
+#: actions/userauthorization.php:338
+#, php-format
+msgid "Avatar URL ‘%s’ is not valid."
+msgstr ""
+
+#: actions/userauthorization.php:343
+#, php-format
+msgid "Can’t read avatar URL ‘%s’."
+msgstr ""
+
+#: actions/userauthorization.php:348
+#, php-format
+msgid "Wrong image type for avatar URL ‘%s’."
+msgstr ""
+
+#: lib/action.php:435
+msgid "Connect to services"
+msgstr ""
+
+#: lib/action.php:785
+msgid "Site content license"
+msgstr ""
+
+#: lib/command.php:88
+#, php-format
+msgid "Could not find a user with nickname %s"
+msgstr ""
+
+#: lib/command.php:92
+msgid "It does not make a lot of sense to nudge yourself!"
+msgstr ""
+
+#: lib/command.php:99
+#, php-format
+msgid "Nudge sent to %s"
+msgstr ""
+
+#: lib/command.php:152 lib/command.php:400
+msgid "Notice with that id does not exist"
+msgstr ""
+
+#: lib/command.php:358 scripts/xmppdaemon.php:321
+#, php-format
+msgid "Message too long - maximum is %d characters, you sent %d"
+msgstr ""
+
+#: lib/command.php:431
+#, php-format
+msgid "Notice too long - maximum is %d characters, you sent %d"
+msgstr ""
+
+#: lib/command.php:439
+#, php-format
+msgid "Reply to %s sent"
+msgstr ""
+
+#: lib/command.php:441
+msgid "Error saving notice."
+msgstr ""
+
+#: lib/common.php:191
+msgid "No configuration file found. "
+msgstr ""
+
+#: lib/common.php:192
+msgid "I looked for configuration files in the following places: "
+msgstr ""
+
+#: lib/common.php:193
+msgid "You may wish to run the installer to fix this."
+msgstr ""
+
+#: lib/common.php:194
+msgid "Go to the installer."
+msgstr ""
+
+#: lib/galleryaction.php:139
+msgid "Select tag to filter"
+msgstr ""
+
+#: lib/groupeditform.php:168
+msgid "Describe the group or topic"
+msgstr ""
+
+#: lib/groupeditform.php:170
+#, php-format
+msgid "Describe the group or topic in %d characters"
+msgstr ""
+
+#: lib/jabber.php:192
+#, php-format
+msgid "notice id: %s"
+msgstr ""
+
+#: lib/mail.php:554
+#, php-format
+msgid "%s (@%s) added your notice as a favorite"
+msgstr ""
+
+#: lib/mail.php:556
+#, php-format
+msgid ""
+"%1$s (@%7$s) just added your notice from %2$s as one of their favorites.\n"
+"\n"
+"The URL of your notice is:\n"
+"\n"
+"%3$s\n"
+"\n"
+"The text of your notice is:\n"
+"\n"
+"%4$s\n"
+"\n"
+"You can see the list of %1$s's favorites here:\n"
+"\n"
+"%5$s\n"
+"\n"
+"Faithfully yours,\n"
+"%6$s\n"
+msgstr ""
+
+#: lib/mail.php:611
+#, php-format
+msgid "%s (@%s) sent a notice to your attention"
+msgstr ""
+
+#: lib/mail.php:613
+#, php-format
+msgid ""
+"%1$s (@%9$s) just sent a notice to your attention (an '@-reply') on %2$s.\n"
+"\n"
+"The notice is here:\n"
+"\n"
+"\t%3$s\n"
+"\n"
+"It reads:\n"
+"\n"
+"\t%4$s\n"
+"\n"
+msgstr ""
+
+#: lib/mailbox.php:227 lib/noticelist.php:424
+msgid "from"
+msgstr ""
+
+#: lib/mediafile.php:179 lib/mediafile.php:216
+msgid "File exceeds user's quota!"
+msgstr ""
+
+#: lib/mediafile.php:201 lib/mediafile.php:237
+msgid "Could not determine file's mime-type!"
+msgstr ""
+
+#: lib/oauthstore.php:345
+msgid "Duplicate notice"
+msgstr ""
+
+#: actions/login.php:110 actions/login.php:120
+msgid "Invalid or expired token."
+msgstr ""
+
+#: lib/command.php:597
+#, php-format
+msgid "Could not create login token for %s"
+msgstr ""
+
+#: lib/command.php:602
+#, php-format
+msgid "This link is useable only once, and is good for only 2 minutes: %s"
+msgstr ""
+
+#: lib/imagefile.php:75
+#, php-format
+msgid "That file is too big. The maximum file size is %s."
+msgstr ""
+
+#: lib/command.php:613
+msgid ""
+"Commands:\n"
+"on - turn on notifications\n"
+"off - turn off notifications\n"
+"help - show this help\n"
+"follow - subscribe to user\n"
+"leave - unsubscribe from user\n"
+"d - direct message to user\n"
+"get - get last notice from user\n"
+"whois - get profile info on user\n"
+"fav - add user's last notice as a 'fave'\n"
+"fav # - add notice with the given id as a 'fave'\n"
+"reply # - reply to notice with a given id\n"
+"reply - reply to the last notice from user\n"
+"join - join group\n"
+"login - Get a link to login to the web interface\n"
+"drop - leave group\n"
+"stats - get your stats\n"
+"stop - same as 'off'\n"
+"quit - same as 'off'\n"
+"sub - same as 'follow'\n"
+"unsub - same as 'leave'\n"
+"last - same as 'get'\n"
+"on - not yet implemented.\n"
+"off - not yet implemented.\n"
+"nudge - remind a user to update.\n"
+"invite - not yet implemented.\n"
+"track - not yet implemented.\n"
+"untrack - not yet implemented.\n"
+"track off - not yet implemented.\n"
+"untrack all - not yet implemented.\n"
+"tracks - not yet implemented.\n"
+"tracking - not yet implemented.\n"
msgstr ""
diff --git a/plugins/Facebook/facebook/facebookapi_php5_restlib.php b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
index e2a6fe88b..55cb7fb86 100755
--- a/plugins/Facebook/facebook/facebookapi_php5_restlib.php
+++ b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
@@ -2951,7 +2951,7 @@ function toggleDisplay(id, type) {
/**
- * Bans a list of users from the app. Banned users cannot
+ * Bans a list of users from the app. Banned users can't
* access the app's canvas page and forums.
*
* @param array $uids an array of user ids
diff --git a/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php b/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php
index 92542b47d..0cddbddb4 100644
--- a/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php
+++ b/plugins/Facebook/facebook/jsonwrapper/JSON/JSON.php
@@ -124,7 +124,7 @@ class Services_JSON
* "{...}" syntax creates associative arrays
* instead of objects in decode().
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
- * Values which cannot be encoded (e.g. resources)
+ * Values which can't be encoded (e.g. resources)
* appear as NULL instead of throwing errors.
* By default, a deeply-nested resource will
* bubble up with an error, so all return values
diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php
index 1d8b5217b..a10fdf90d 100644
--- a/plugins/Facebook/facebookaction.php
+++ b/plugins/Facebook/facebookaction.php
@@ -513,7 +513,7 @@ class FacebookNoticeList extends NoticeList
/**
* show the list of notices
*
- * "Uses up" the stream by looping through it. So, probably cannot
+ * "Uses up" the stream by looping through it. So, probably can't
* be called twice on the same list.
*
* @return int count of notices listed.
diff --git a/plugins/Facebook/facebookhome.php b/plugins/Facebook/facebookhome.php
index ee6e6620b..91c0cc6b8 100644
--- a/plugins/Facebook/facebookhome.php
+++ b/plugins/Facebook/facebookhome.php
@@ -108,7 +108,7 @@ class FacebookhomeAction extends FacebookAction
$user = User::staticGet('nickname', $nickname);
if (!$user) {
- $this->showLoginForm(_("Server error. Could not get user."));
+ $this->showLoginForm(_("Server error - couldn't get user!"));
}
$flink = DB_DataObject::factory('foreign_link');
diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php
index bc433b896..915d15c07 100644
--- a/plugins/LinkbackPlugin.php
+++ b/plugins/LinkbackPlugin.php
@@ -125,7 +125,7 @@ class LinkbackPlugin extends Plugin
if (!extension_loaded('xmlrpc')) {
if (!dl('xmlrpc.so')) {
- common_log(LOG_ERR, "Cannot pingback; xmlrpc extension not available.");
+ common_log(LOG_ERR, "Can't pingback; xmlrpc extension not available.");
}
}
diff --git a/plugins/Meteor/MeteorPlugin.php b/plugins/Meteor/MeteorPlugin.php
index f3cbc3eea..5b345d7c2 100644
--- a/plugins/Meteor/MeteorPlugin.php
+++ b/plugins/Meteor/MeteorPlugin.php
@@ -85,7 +85,7 @@ class MeteorPlugin extends RealtimePlugin
// May throw an exception.
$this->_socket = stream_socket_client("tcp://{$controlserver}:{$this->controlport}");
if (!$this->_socket) {
- throw new Exception("Could not connect to {$controlserver} on {$this->controlport}");
+ throw new Exception("Couldn't connect to {$controlserver} on {$this->controlport}");
}
}
diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php
index cd042226b..ff7a93899 100644
--- a/plugins/OpenID/openid.php
+++ b/plugins/OpenID/openid.php
@@ -36,7 +36,7 @@ function oid_store()
{
static $store = null;
if (!$store) {
- # Cannot be called statically
+ # Can't be called statically
$user = new User();
$conn = $user->getDatabaseConnection();
$store = new Auth_OpenID_MySQLStore($conn);
@@ -192,7 +192,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
$form_html = preg_replace('/&/', '&', $form_html);
- // Display an error if the form markup could not be generated;
+ // Display an error if the form markup couldn't be generated;
// otherwise, render the HTML.
if (Auth_OpenID::isFailure($form_html)) {
common_server_error(sprintf(_('Could not create OpenID form: %s'), $form_html->message));
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index 6a155b301..671e3c7af 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -126,7 +126,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
$conn->disconnect();
- // XXX: Could not find a less brutal way to blow
+ // XXX: Couldn't find a less brutal way to blow
// away a cached connection
global $_DB_DATAOBJECT;
@@ -188,7 +188,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
if (empty($more_friends)) {
common_log(LOG_WARNING, $this->name() .
- " - Could not retrieve page $i " .
+ " - Couldn't retrieve page $i " .
"of Twitter user $flink->foreign_id friends.");
continue;
} else {
@@ -222,11 +222,11 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
if (!save_twitter_user($friend_id, $friend_name)) {
common_log(LOG_WARNING, $this-name() .
- " - Could not save $screen_name's friend, $friend_name.");
+ " - Couldn't save $screen_name's friend, $friend_name.");
continue;
}
- // Check to see if there is a related local user
+ // Check to see if there's a related local user
$friend_flink = Foreign_link::getByForeignID($friend_id,
TWITTER_SERVICE);
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index ab610e553..b5428316b 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -147,7 +147,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$conn->disconnect();
- // XXX: Could not find a less brutal way to blow
+ // XXX: Couldn't find a less brutal way to blow
// away a cached connection
global $_DB_DATAOBJECT;
@@ -158,7 +158,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
{
if (empty($flink)) {
common_log(LOG_WARNING, $this->name() .
- " - Cannot retrieve Foreign_link for foreign ID $fid");
+ " - Can't retrieve Foreign_link for foreign ID $fid");
return;
}
@@ -458,7 +458,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$profile = Profile::staticGet($profile_id);
if (empty($profile)) {
- common_debug($this->name() . " - Could not get profile: $profile_id!");
+ common_debug($this->name() . " - Couldn't get profile: $profile_id!");
return;
}
@@ -537,7 +537,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$ok = file_put_contents($avatarfile, $response->getBody());
if (!$ok) {
common_log(LOG_WARNING, $this->name() .
- " - Could not open file $filename");
+ " - Couldn't open file $filename");
return false;
}
} else {
diff --git a/plugins/UserFlag/flagprofile.php b/plugins/UserFlag/flagprofile.php
index 84c343c48..c72b74c6a 100644
--- a/plugins/UserFlag/flagprofile.php
+++ b/plugins/UserFlag/flagprofile.php
@@ -135,7 +135,7 @@ class FlagprofileAction extends Action
$ufp->created = common_sql_now();
if (!$ufp->insert()) {
- throw new ServerException(sprintf(_("Could not flag profile '%s' with flag '%s'."),
+ throw new ServerException(sprintf(_("Couldn't flag profile '%s' with flag '%s'."),
$this->profile->nickname, $this->flag));
}
diff --git a/scripts/console.php b/scripts/console.php
index 2413f5079..41dd43f28 100755
--- a/scripts/console.php
+++ b/scripts/console.php
@@ -90,7 +90,7 @@ function readline_emulation($prompt)
if ($retval == 0) {
return $line;
} elseif ($retval == 127) {
- // Could not execute bash even though we thought we saw it.
+ // Couldn't execute bash even though we thought we saw it.
// Shell probably spit out an error message, sorry :(
// Fall through to fgets()...
} else {
diff --git a/scripts/createsim.php b/scripts/createsim.php
index 592853f86..1266a9700 100644
--- a/scripts/createsim.php
+++ b/scripts/createsim.php
@@ -85,7 +85,7 @@ function newSub($i)
$from = User::staticGet('nickname', $fromnick);
if (empty($from)) {
- throw new Exception("Cannot find user '$fromnick'.");
+ throw new Exception("Can't find user '$fromnick'.");
}
$t = rand(0, $i - 1);
@@ -102,7 +102,7 @@ function newSub($i)
$to = User::staticGet('nickname', $tunic);
if (empty($to)) {
- throw new Exception("Cannot find user '$tunic'.");
+ throw new Exception("Can't find user '$tunic'.");
}
subs_subscribe_to($from, $to);
diff --git a/scripts/deleteuser.php b/scripts/deleteuser.php
index 39331f1a8..52389123c 100644
--- a/scripts/deleteuser.php
+++ b/scripts/deleteuser.php
@@ -39,14 +39,14 @@ if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
$user = User::staticGet('id', $id);
if (empty($user)) {
- print "Cannot find user with ID $id\n";
+ print "Can't find user with ID $id\n";
exit(1);
}
} else if (have_option('n', 'nickname')) {
$nickname = get_option_value('n', 'nickname');
$user = User::staticGet('nickname', $nickname);
if (empty($user)) {
- print "Cannot find user with nickname '$nickname'\n";
+ print "Can't find user with nickname '$nickname'\n";
exit(1);
}
} else {
diff --git a/scripts/fixup_utf8.php b/scripts/fixup_utf8.php
index 5581633ec..5a9fba7c3 100755
--- a/scripts/fixup_utf8.php
+++ b/scripts/fixup_utf8.php
@@ -76,7 +76,7 @@ class UTF8FixerUpper
$succ = mysqli_set_charset($conn, $charset);
if (!$succ) {
- echo "ERROR: Could not set charset\n";
+ echo "ERROR: couldn't set charset\n";
$db->disconnect();
return NULL;
}
diff --git a/scripts/makegroupadmin.php b/scripts/makegroupadmin.php
index 07f980d58..a68798451 100644
--- a/scripts/makegroupadmin.php
+++ b/scripts/makegroupadmin.php
@@ -67,7 +67,7 @@ try {
$member->created = common_sql_now();
if (!$member->insert()) {
- throw new Exception("Cannot add '$nickname' to '$groupname'.");
+ throw new Exception("Can't add '$nickname' to '$groupname'.");
}
}
@@ -80,7 +80,7 @@ try {
$member->is_admin = 1;
if (!$member->update($orig)) {
- throw new Exception("Cannot make '$nickname' admin of '$groupname'.");
+ throw new Exception("Can't make '$nickname' admin of '$groupname'.");
}
} catch (Exception $e) {
diff --git a/scripts/registeruser.php b/scripts/registeruser.php
index 8aab325b7..5d9c8862d 100644
--- a/scripts/registeruser.php
+++ b/scripts/registeruser.php
@@ -60,7 +60,7 @@ try {
'fullname' => $fullname));
if (empty($user)) {
- throw new Exception("Cannot register user '$nickname' with password '$password' and fullname '$fullname'.");
+ throw new Exception("Can't register user '$nickname' with password '$password' and fullname '$fullname'.");
}
if (!empty($email)) {
@@ -71,7 +71,7 @@ try {
if (!$user->updateKeys($orig)) {
print "Failed!\n";
- throw new Exception("Cannot update email address.");
+ throw new Exception("Can't update email address.");
}
}
diff --git a/scripts/showcache.php b/scripts/showcache.php
index 6b00a8f7b..f17979572 100644
--- a/scripts/showcache.php
+++ b/scripts/showcache.php
@@ -58,7 +58,7 @@ print "Checking key '$k'...\n";
$c = common_memcache();
if (empty($c)) {
- die("Cannot initialize cache object!\n");
+ die("Can't initialize cache object!\n");
}
$obj = $c->get($k);
diff --git a/scripts/sitemap.php b/scripts/sitemap.php
index ee5d33e1e..f8c392146 100755
--- a/scripts/sitemap.php
+++ b/scripts/sitemap.php
@@ -377,11 +377,11 @@ function write_file($path, $data)
}
if (($fh_out = fopen($path,'w')) === false) {
- error("Could not open $path for writing.");
+ error("couldn't open $path for writing.");
}
if (fwrite($fh_out, $data) === false) {
- error("Could not write to $path.");
+ error("couldn't write to $path.");
}
}
diff --git a/scripts/update_translations.php b/scripts/update_translations.php
index 8d4c9d3d2..580c472ee 100755
--- a/scripts/update_translations.php
+++ b/scripts/update_translations.php
@@ -98,7 +98,7 @@ foreach ($languages as $language) {
$new_file = curl_get_file($file_url);
if ($new_file === FALSE) {
- echo "Could not retrieve .po file for $code: $file_url\n";
+ echo "Couldn't retrieve .po file for $code: $file_url\n";
continue;
}
--
cgit v1.2.3-54-g00ecf
From 5ab709b73977131813884558bf56d97172a7aa26 Mon Sep 17 00:00:00 2001
From: Siebrand Mazeland
Date: Sun, 8 Nov 2009 23:32:15 +0100
Subject: Remove more contractions * doesn't * won't * isn't * don't
---
actions/allrss.php | 2 +-
actions/apiaccountratelimitstatus.php | 2 +-
actions/apifriendshipsdestroy.php | 2 +-
actions/attachment.php | 4 ++--
actions/avatarbynickname.php | 2 +-
actions/groupblock.php | 2 +-
actions/login.php | 2 +-
actions/logout.php | 2 +-
actions/newmessage.php | 2 +-
actions/newnotice.php | 2 +-
actions/opensearch.php | 2 +-
actions/passwordsettings.php | 2 +-
actions/register.php | 2 +-
actions/showgroup.php | 2 +-
actions/showmessage.php | 8 ++++----
actions/shownotice.php | 6 +++---
actions/showstream.php | 2 +-
actions/sup.php | 2 +-
actions/twitapisearchatom.php | 2 +-
actions/twitapitrends.php | 2 +-
classes/File_redirection.php | 8 ++++----
classes/Notice.php | 6 +++---
classes/Profile.php | 4 ++--
classes/User.php | 6 +++---
lib/api.php | 14 +++++++-------
lib/apiauth.php | 2 +-
lib/dberroraction.php | 6 +++---
lib/error.php | 4 ++--
lib/htmloutputter.php | 2 +-
lib/imagefile.php | 2 +-
lib/jabber.php | 2 +-
lib/mail.php | 6 +++---
lib/noticelist.php | 4 ++--
lib/queuehandler.php | 12 ++++++------
lib/rssaction.php | 2 +-
lib/search_engines.php | 2 +-
lib/util.php | 12 ++++++------
lib/xmloutputter.php | 2 +-
lib/xmppqueuehandler.php | 2 +-
plugins/Autocomplete/autocomplete.php | 2 +-
plugins/BlogspamNetPlugin.php | 2 +-
plugins/Facebook/FBConnectAuth.php | 4 ++--
plugins/Facebook/FacebookPlugin.php | 4 ++--
plugins/Facebook/facebook/facebook.php | 8 ++++----
plugins/Facebook/facebook/facebook_desktop.php | 2 +-
plugins/Facebook/facebook/facebookapi_php5_restlib.php | 6 +++---
plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php | 2 +-
plugins/Facebook/facebookaction.php | 6 +++---
plugins/GeonamesPlugin.php | 8 ++++----
plugins/OpenID/finishopenidlogin.php | 4 ++--
plugins/OpenID/openid.php | 2 +-
plugins/PiwikAnalyticsPlugin.php | 2 +-
plugins/Realtime/RealtimePlugin.php | 2 +-
plugins/TwitterBridge/daemons/synctwitterfriends.php | 2 +-
plugins/TwitterBridge/daemons/twitterstatusfetcher.php | 4 ++--
plugins/TwitterBridge/twitter.php | 2 +-
scripts/console.php | 4 ++--
scripts/maildaemon.php | 2 +-
scripts/xmppconfirmhandler.php | 2 +-
59 files changed, 110 insertions(+), 110 deletions(-)
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/actions/allrss.php b/actions/allrss.php
index 28b1be27d..4a5d15c7b 100644
--- a/actions/allrss.php
+++ b/actions/allrss.php
@@ -56,7 +56,7 @@ class AllrssAction extends Rss10Action
*
* @param array $args Web and URL arguments
*
- * @return boolean false if user doesn't exist
+ * @return boolean false if user does not exist
*/
function prepare($args)
{
diff --git a/actions/apiaccountratelimitstatus.php b/actions/apiaccountratelimitstatus.php
index 96179f175..c7c0e7c00 100644
--- a/actions/apiaccountratelimitstatus.php
+++ b/actions/apiaccountratelimitstatus.php
@@ -36,7 +36,7 @@ if (!defined('STATUSNET')) {
require_once INSTALLDIR . '/lib/apibareauth.php';
/**
- * We don't have a rate limit, but some clients check this method.
+ * We do not have a rate limit, but some clients check this method.
* It always returns the same thing: 150 hits left.
*
* @category API
diff --git a/actions/apifriendshipsdestroy.php b/actions/apifriendshipsdestroy.php
index 3d9b7e001..fb73624c9 100644
--- a/actions/apifriendshipsdestroy.php
+++ b/actions/apifriendshipsdestroy.php
@@ -113,7 +113,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
return;
}
- // Don't allow unsubscribing from yourself!
+ // Do not allow unsubscribing from yourself!
if ($this->user->id == $this->other->id) {
$this->clientError(
diff --git a/actions/attachment.php b/actions/attachment.php
index 6981354d1..ca9e57845 100644
--- a/actions/attachment.php
+++ b/actions/attachment.php
@@ -146,7 +146,7 @@ class AttachmentAction extends Action
}
/**
- * Don't show local navigation
+ * Do not show local navigation
*
* @return void
*/
@@ -170,7 +170,7 @@ class AttachmentAction extends Action
}
/**
- * Don't show page notice
+ * Do not show page notice
*
* @return void
*/
diff --git a/actions/avatarbynickname.php b/actions/avatarbynickname.php
index 537950792..1a6925e11 100644
--- a/actions/avatarbynickname.php
+++ b/actions/avatarbynickname.php
@@ -49,7 +49,7 @@ class AvatarbynicknameAction extends Action
*
* @param array $args query arguments
*
- * @return boolean false if nickname or user isn't found
+ * @return boolean false if nickname or user is not found
*/
function handle($args)
{
diff --git a/actions/groupblock.php b/actions/groupblock.php
index 979a56a81..133101eb7 100644
--- a/actions/groupblock.php
+++ b/actions/groupblock.php
@@ -95,7 +95,7 @@ class GroupblockAction extends Action
$this->clientError(_('User is already blocked from group.'));
return false;
}
- // XXX: could have proactive blocks, but we don't have UI for it.
+ // XXX: could have proactive blocks, but we do not have UI for it.
if (!$this->profile->isMember($this->group)) {
$this->clientError(_('User is not a member of group.'));
return false;
diff --git a/actions/login.php b/actions/login.php
index ad57dd667..679817520 100644
--- a/actions/login.php
+++ b/actions/login.php
@@ -159,7 +159,7 @@ class LoginAction extends Action
$url = common_get_returnto();
if ($url) {
- // We don't have to return to it again
+ // We do not have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
diff --git a/actions/logout.php b/actions/logout.php
index 1e0adae57..7e768fca6 100644
--- a/actions/logout.php
+++ b/actions/logout.php
@@ -81,7 +81,7 @@ class LogoutAction extends Action
{
common_set_user(null);
common_real_login(false); // not logged in
- common_forgetme(); // don't log back in!
+ common_forgetme(); // do not log back in!
}
}
diff --git a/actions/newmessage.php b/actions/newmessage.php
index 0db2e7181..73307fdfc 100644
--- a/actions/newmessage.php
+++ b/actions/newmessage.php
@@ -61,7 +61,7 @@ class NewmessageAction extends Action
/**
* Title of the page
*
- * Note that this usually doesn't get called unless something went wrong
+ * Note that this usually does not get called unless something went wrong
*
* @return string page title
*/
diff --git a/actions/newnotice.php b/actions/newnotice.php
index fbd7ab6bc..fc06e5c98 100644
--- a/actions/newnotice.php
+++ b/actions/newnotice.php
@@ -59,7 +59,7 @@ class NewnoticeAction extends Action
/**
* Title of the page
*
- * Note that this usually doesn't get called unless something went wrong
+ * Note that this usually does not get called unless something went wrong
*
* @return string page title
*/
diff --git a/actions/opensearch.php b/actions/opensearch.php
index 8ebb5fc82..3136380b0 100644
--- a/actions/opensearch.php
+++ b/actions/opensearch.php
@@ -52,7 +52,7 @@ class OpensearchAction extends Action
*
* @param array $args query arguments
*
- * @return boolean false if user doesn't exist
+ * @return boolean false if user does not exist
*/
function handle($args)
{
diff --git a/actions/passwordsettings.php b/actions/passwordsettings.php
index 87eb45a7d..6658d279f 100644
--- a/actions/passwordsettings.php
+++ b/actions/passwordsettings.php
@@ -97,7 +97,7 @@ class PasswordsettingsAction extends AccountSettingsAction
$this->elementStart('ul', 'form_data');
- // Users who logged in with OpenID won't have a pwd
+ // Users who logged in with OpenID will not have a pwd
if ($user->password) {
$this->elementStart('li');
$this->password('oldpassword', _('Old password'));
diff --git a/actions/register.php b/actions/register.php
index 584ad3ead..69c50faca 100644
--- a/actions/register.php
+++ b/actions/register.php
@@ -174,7 +174,7 @@ class RegisterAction extends Action
$bio = $this->trimmed('bio');
$location = $this->trimmed('location');
- // We don't trim these... whitespace is OK in a password!
+ // We do not trim these... whitespace is OK in a password!
$password = $this->arg('password');
$confirm = $this->arg('confirm');
diff --git a/actions/showgroup.php b/actions/showgroup.php
index a4af29391..ae956befa 100644
--- a/actions/showgroup.php
+++ b/actions/showgroup.php
@@ -418,7 +418,7 @@ class ShowgroupAction extends GroupDesignAction
// XXX: WORM cache this
$members = $this->group->getMembers();
$members_count = 0;
- /** $member->count() doesn't work. */
+ /** $member->count() does not work. */
while ($members->fetch()) {
$members_count++;
}
diff --git a/actions/showmessage.php b/actions/showmessage.php
index db757948b..cf3a819c1 100644
--- a/actions/showmessage.php
+++ b/actions/showmessage.php
@@ -137,7 +137,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Don't show local navigation
+ * Do not show local navigation
*
* @return void
*/
@@ -147,7 +147,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Don't show page notice
+ * Do not show page notice
*
* @return void
*/
@@ -157,7 +157,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Don't show aside
+ * Do not show aside
*
* @return void
*/
@@ -167,7 +167,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Don't show any instructions
+ * Do not show any instructions
*
* @return string
*/
diff --git a/actions/shownotice.php b/actions/shownotice.php
index 5d16fdad9..688089f02 100644
--- a/actions/shownotice.php
+++ b/actions/shownotice.php
@@ -208,7 +208,7 @@ class ShownoticeAction extends OwnerDesignAction
}
/**
- * Don't show local navigation
+ * Do not show local navigation
*
* @return void
*/
@@ -234,7 +234,7 @@ class ShownoticeAction extends OwnerDesignAction
}
/**
- * Don't show page notice
+ * Do not show page notice
*
* @return void
*/
@@ -244,7 +244,7 @@ class ShownoticeAction extends OwnerDesignAction
}
/**
- * Don't show aside
+ * Do not show aside
*
* @return void
*/
diff --git a/actions/showstream.php b/actions/showstream.php
index 663638c18..4952ebdb7 100644
--- a/actions/showstream.php
+++ b/actions/showstream.php
@@ -253,7 +253,7 @@ class ShowstreamAction extends ProfileAction
}
}
-// We don't show the author for a profile, since we already know who it is!
+// We do not show the author for a profile, since we already know who it is!
class ProfileNoticeList extends NoticeList
{
diff --git a/actions/sup.php b/actions/sup.php
index 5daf0a1c1..a199f247e 100644
--- a/actions/sup.php
+++ b/actions/sup.php
@@ -61,7 +61,7 @@ class SupAction extends Action
$notice = new Notice();
# XXX: cache this. Depends on how big this protocol becomes;
- # Re-doing this query every 15 seconds isn't the end of the world.
+ # Re-doing this query every 15 seconds is not the end of the world.
$divider = common_sql_date(time() - $seconds);
diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php
index 7d618c471..511d7cdc6 100644
--- a/actions/twitapisearchatom.php
+++ b/actions/twitapisearchatom.php
@@ -250,7 +250,7 @@ class TwitapisearchatomAction extends ApiAction
}
// FIXME: this alternate link is not quite right because our
- // web-based notice search doesn't support a rpp (responses per
+ // web-based notice search does not support a rpp (responses per
// page) param yet
$this->element('link', array('type' => 'text/html',
diff --git a/actions/twitapitrends.php b/actions/twitapitrends.php
index 779405e6d..2d17e77cc 100644
--- a/actions/twitapitrends.php
+++ b/actions/twitapitrends.php
@@ -55,7 +55,7 @@ class TwitapitrendsAction extends ApiAction
*
* @param array $args Web and URL arguments
*
- * @return boolean false if user doesn't exist
+ * @return boolean false if user does not exist
*/
function prepare($args)
{
diff --git a/classes/File_redirection.php b/classes/File_redirection.php
index 08a6e8d8b..c951c1ee7 100644
--- a/classes/File_redirection.php
+++ b/classes/File_redirection.php
@@ -53,7 +53,7 @@ class File_redirection extends Memcached_DataObject
'connect_timeout' => 10, // # seconds to wait
'max_redirs' => $redirs, // # max number of http redirections to follow
'follow_redirects' => true, // Follow redirects
- 'store_body' => false, // We won't need body content here.
+ 'store_body' => false, // We will not need body content here.
));
return $request;
}
@@ -81,12 +81,12 @@ class File_redirection extends Memcached_DataObject
}
try {
$request = self::_commonHttp($short_url, $redirs);
- // Don't include body in output
+ // Do not include body in output
$request->setMethod(HTTP_Request2::METHOD_HEAD);
$response = $request->send();
if (405 == $response->getStatus()) {
- // Server doesn't support HEAD method? Can this really happen?
+ // Server does not support HEAD method? Can this really happen?
// We'll try again as a GET and ignore the response data.
$request = self::_commonHttp($short_url, $redirs);
$response = $request->send();
@@ -178,7 +178,7 @@ class File_redirection extends Memcached_DataObject
case 'aim':
case 'jabber':
case 'xmpp':
- // don't touch anything
+ // do not touch anything
break;
default:
diff --git a/classes/Notice.php b/classes/Notice.php
index 862d4c762..0c54b6b67 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -146,7 +146,7 @@ class Notice extends Memcached_DataObject
/* Add them to the database */
foreach(array_unique($hashtags) as $hashtag) {
- /* elide characters we don't want in the tag */
+ /* elide characters we do not want in the tag */
$this->saveTag($hashtag);
}
return true;
@@ -1105,7 +1105,7 @@ class Notice extends Memcached_DataObject
if (empty($recipient)) {
continue;
}
- // Don't save replies from blocked profile to local user
+ // Do not save replies from blocked profile to local user
$recipient_user = User::staticGet('id', $recipient->id);
if (!empty($recipient_user) && $recipient_user->hasBlocked($sender)) {
continue;
@@ -1131,7 +1131,7 @@ class Notice extends Memcached_DataObject
$tagged = Profile_tag::getTagged($sender->id, $tag);
foreach ($tagged as $t) {
if (!$replied[$t->id]) {
- // Don't save replies from blocked profile to local user
+ // Do not save replies from blocked profile to local user
$t_user = User::staticGet('id', $t->id);
if ($t_user && $t_user->hasBlocked($sender)) {
continue;
diff --git a/classes/Profile.php b/classes/Profile.php
index 7c1e9db33..a50f4951d 100644
--- a/classes/Profile.php
+++ b/classes/Profile.php
@@ -101,7 +101,7 @@ class Profile extends Memcached_DataObject
}
foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
- # We don't do a scaled one if original is our scaled size
+ # We do not do a scaled one if original is our scaled size
if (!($avatar->width == $size && $avatar->height == $size)) {
$scaled_filename = $imagefile->resize($size);
@@ -174,7 +174,7 @@ class Profile extends Memcached_DataObject
function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
{
- // XXX: I'm not sure this is going to be any faster. It probably isn't.
+ // XXX: I'm not sure this is going to be any faster. It probably is not.
$ids = Notice::stream(array($this, '_streamDirect'),
array(),
'profile:notice_ids:' . $this->id,
diff --git a/classes/User.php b/classes/User.php
index 9b90ce61b..c529b82e0 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -87,7 +87,7 @@ class User extends Memcached_DataObject
return (is_null($sub)) ? false : true;
}
- // 'update' won't write key columns, so we have to do it ourselves.
+ // 'update' will not write key columns, so we have to do it ourselves.
function updateKeys(&$orig)
{
@@ -384,7 +384,7 @@ class User extends Memcached_DataObject
return false;
}
- // Otherwise, cache doesn't have all faves;
+ // Otherwise, cache does not have all faves;
// fall through to the default
}
@@ -463,7 +463,7 @@ class User extends Memcached_DataObject
{
$cache = common_memcache();
if ($cache) {
- // Faves don't happen chronologically, so we need to blow
+ // Faves do not happen chronologically, so we need to blow
// ;last cache, too
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id));
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id.';last'));
diff --git a/lib/api.php b/lib/api.php
index a1236ab7e..fb4c4289b 100644
--- a/lib/api.php
+++ b/lib/api.php
@@ -66,7 +66,7 @@ class ApiAction extends Action
*
* @param array $args Web and URL arguments
*
- * @return boolean false if user doesn't exist
+ * @return boolean false if user does not exist
*/
function prepare($args)
@@ -138,7 +138,7 @@ class ApiAction extends Action
$design = null;
$user = $profile->getUser();
- // Note: some profiles don't have an associated user
+ // Note: some profiles do not have an associated user
if (!empty($user)) {
$design = $user->getDesign();
@@ -203,7 +203,7 @@ class ApiAction extends Action
if ($get_notice) {
$notice = $profile->getCurrentNotice();
if ($notice) {
- # don't get user!
+ # do not get user!
$twitter_user['status'] = $this->twitterStatusArray($notice, false);
}
}
@@ -263,7 +263,7 @@ class ApiAction extends Action
}
if ($include_user) {
- # Don't get notice (recursive!)
+ # Do not get notice (recursive!)
$twitter_user = $this->twitterUserArray($profile, false);
$twitter_status['user'] = $twitter_user;
}
@@ -1074,7 +1074,7 @@ class ApiAction extends Action
function initTwitterAtom()
{
$this->startXML();
- // FIXME: don't hardcode the language here!
+ // FIXME: do not hardcode the language here!
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom',
'xml:lang' => 'en-US',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'));
@@ -1116,7 +1116,7 @@ class ApiAction extends Action
return User::staticGet('nickname', $nickname);
} else if ($this->arg('user_id')) {
// This is to ensure that a non-numeric user_id still
- // overrides screen_name even if it doesn't get used
+ // overrides screen_name even if it does not get used
if (is_numeric($this->arg('user_id'))) {
return User::staticGet('id', $this->arg('user_id'));
}
@@ -1146,7 +1146,7 @@ class ApiAction extends Action
return User_group::staticGet('nickname', $nickname);
} else if ($this->arg('group_id')) {
// This is to ensure that a non-numeric user_id still
- // overrides screen_name even if it doesn't get used
+ // overrides screen_name even if it does not get used
if (is_numeric($this->arg('group_id'))) {
return User_group::staticGet('id', $this->arg('group_id'));
}
diff --git a/lib/apiauth.php b/lib/apiauth.php
index 2f2e44a26..b8189f15d 100644
--- a/lib/apiauth.php
+++ b/lib/apiauth.php
@@ -87,7 +87,7 @@ class ApiAuthAction extends ApiAction
}
/**
- * Check for a user specified via HTTP basic auth. If there isn't
+ * Check for a user specified via HTTP basic auth. If there is not
* one, try to get one by outputting the basic auth header.
*
* @return boolean true or false
diff --git a/lib/dberroraction.php b/lib/dberroraction.php
index 2cb66a022..893797b70 100644
--- a/lib/dberroraction.php
+++ b/lib/dberroraction.php
@@ -39,7 +39,7 @@ require_once INSTALLDIR.'/lib/servererroraction.php';
*
* This only occurs if there's been a DB_DataObject_Error that's
* reported through PEAR, so we try to avoid doing anything that connects
- * to the DB, so we don't trigger it again.
+ * to the DB, so we do not trigger it again.
*
* @category Action
* @package StatusNet
@@ -62,12 +62,12 @@ class DBErrorAction extends ServerErrorAction
function getLanguage()
{
- // Don't try to figure out user's language; just show the page
+ // Do not try to figure out user's language; just show the page
return common_config('site', 'language');
}
function showPrimaryNav()
{
- // don't show primary nav
+ // do not show primary nav
}
}
diff --git a/lib/error.php b/lib/error.php
index 3162cfe65..5ed5dec1b 100644
--- a/lib/error.php
+++ b/lib/error.php
@@ -104,11 +104,11 @@ class ErrorAction extends Action
{
parent::showPage();
- // We don't want to have any more output after this
+ // We do not want to have any more output after this
exit();
}
- // Overload a bunch of stuff so the page isn't too bloated
+ // Overload a bunch of stuff so the page is not too bloated
function showBody()
{
diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php
index c2ec83c28..73bd9ce81 100644
--- a/lib/htmloutputter.php
+++ b/lib/htmloutputter.php
@@ -76,7 +76,7 @@ class HTMLOutputter extends XMLOutputter
/**
* Start an HTML document
*
- * If $type isn't specified, will attempt to do content negotiation.
+ * If $type is not specified, will attempt to do content negotiation.
*
* Attempts to do content negotiation for language, also.
*
diff --git a/lib/imagefile.php b/lib/imagefile.php
index cf1668f20..edc7218d0 100644
--- a/lib/imagefile.php
+++ b/lib/imagefile.php
@@ -119,7 +119,7 @@ class ImageFile
return;
}
- // Don't crop/scale if it isn't necessary
+ // Do not crop/scale if it is not necessary
if ($size === $this->width
&& $size === $this->height
&& $x === 0
diff --git a/lib/jabber.php b/lib/jabber.php
index 73f2ec660..d666fcbb3 100644
--- a/lib/jabber.php
+++ b/lib/jabber.php
@@ -437,7 +437,7 @@ function jabber_public_notice($notice)
$public = common_config('xmpp', 'public');
- // FIXME PRIV don't send out private messages here
+ // FIXME PRIV do not send out private messages here
// XXX: should we send out non-local messages if public,localonly
// = false? I think not
diff --git a/lib/mail.php b/lib/mail.php
index 5218059e9..79630b721 100644
--- a/lib/mail.php
+++ b/lib/mail.php
@@ -467,7 +467,7 @@ function mail_notify_nudge($from, $to)
"these days and is inviting you to post some news.\n\n".
"So let's hear from you :)\n\n".
"%3\$s\n\n".
- "Don't reply to this email; it won't get to them.\n\n".
+ "Do not reply to this email. It will not get to them.\n\n".
"With kind regards,\n".
"%4\$s\n"),
$from_profile->getBestName(),
@@ -516,7 +516,7 @@ function mail_notify_message($message, $from=null, $to=null)
"------------------------------------------------------\n\n".
"You can reply to their message here:\n\n".
"%4\$s\n\n".
- "Don't reply to this email; it won't get to them.\n\n".
+ "Do not reply to this email. It will not get to them.\n\n".
"With kind regards,\n".
"%5\$s\n"),
$from_profile->getBestName(),
@@ -532,7 +532,7 @@ function mail_notify_message($message, $from=null, $to=null)
/**
* notify a user that one of their notices has been chosen as a 'fave'
*
- * Doesn't check that the user has an email address nor if they
+ * Does not check that the user has an email address nor if they
* want to receive notification of faves. Maybe this happens higher
* up the stack...?
*
diff --git a/lib/noticelist.php b/lib/noticelist.php
index 027db2b3e..206724676 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -347,7 +347,7 @@ class NoticeListItem extends Widget
* show the link to the main page for the notice
*
* Displays a link to the page for a notice, with "relative" time. Tries to
- * get remote notice URLs correct, but doesn't always succeed.
+ * get remote notice URLs correct, but does not always succeed.
*
* @return void
*/
@@ -483,7 +483,7 @@ class NoticeListItem extends Widget
* show a link to reply to the current notice
*
* Should either do the reply in the current notice form (if available), or
- * link out to the notice-posting form. A little flakey, doesn't always work.
+ * link out to the notice-posting form. A little flakey, does not always work.
*
* @return void
*/
diff --git a/lib/queuehandler.php b/lib/queuehandler.php
index cd43b1e09..7c07ca4f9 100644
--- a/lib/queuehandler.php
+++ b/lib/queuehandler.php
@@ -96,8 +96,8 @@ class QueueHandler extends Daemon
* Initialization, run when the queue handler starts.
* If this function indicates failure, the handler run will be aborted.
*
- * @fixme run() will abort if this doesn't return true,
- * but some subclasses don't bother.
+ * @fixme run() will abort if this does not return true,
+ * but some subclasses do not bother.
* @return boolean true on success, false on failure
*/
function start()
@@ -108,8 +108,8 @@ class QueueHandler extends Daemon
* Cleanup, run when the queue handler ends.
* If this function indicates failure, a warning will be logged.
*
- * @fixme run() will throw warnings if this doesn't return true,
- * but many subclasses don't bother.
+ * @fixme run() will throw warnings if this does not return true,
+ * but many subclasses do not bother.
* @return boolean true on success, false on failure
*/
function finish()
@@ -137,7 +137,7 @@ class QueueHandler extends Daemon
* method, which passes control back to our handle_notice() method for
* each notice that comes in on the queue.
*
- * Most of the time this won't need to be overridden in a subclass.
+ * Most of the time this will not need to be overridden in a subclass.
*
* @return boolean true on success, false on failure
*/
@@ -173,7 +173,7 @@ class QueueHandler extends Daemon
* Called by QueueHandler after each handled item or empty polling cycle.
* This is a good time to e.g. service your XMPP connection.
*
- * Doesn't need to be overridden if there's no maintenance to do.
+ * Does not need to be overridden if there's no maintenance to do.
*
* @param int $timeout seconds to sleep if there's nothing to do
*/
diff --git a/lib/rssaction.php b/lib/rssaction.php
index faf6bec7d..0e84a65e9 100644
--- a/lib/rssaction.php
+++ b/lib/rssaction.php
@@ -386,7 +386,7 @@ class Rss10Action extends Action
return null;
}
- // FIXME: doesn't handle modified profiles, avatars, deleted notices
+ // FIXME: does not handle modified profiles, avatars, deleted notices
return strtotime($this->notices[0]->created);
}
diff --git a/lib/search_engines.php b/lib/search_engines.php
index 69f6ff468..82713235c 100644
--- a/lib/search_engines.php
+++ b/lib/search_engines.php
@@ -119,7 +119,7 @@ class MySQLSearch extends SearchEngine
return true;
} else if ('identica_notices' === $this->table) {
- // Don't show imported notices
+ // Do not show imported notices
$this->target->whereAdd('notice.is_local != ' . Notice::GATEWAY);
if (strtolower($q) != $q) {
diff --git a/lib/util.php b/lib/util.php
index dde3fb48f..8f7521e59 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -62,7 +62,7 @@ function common_init_language()
$locale_set = common_init_locale($language);
setlocale(LC_CTYPE, 'C');
- // So we don't have to make people install the gettext locales
+ // So we do not have to make people install the gettext locales
$path = common_config('site','locale_path');
bindtextdomain("statusnet", $path);
bind_textdomain_codeset("statusnet", "UTF-8");
@@ -139,7 +139,7 @@ function common_check_user($nickname, $password)
}
}
}else{
- //no handler indicated the credentials were valid, and we know their not valid because the user isn't in the database
+ //no handler indicated the credentials were valid, and we know their not valid because the user is not in the database
return false;
}
} else {
@@ -396,7 +396,7 @@ function common_current_user()
}
// Logins that are 'remembered' aren't 'real' -- they're subject to
-// cookie-stealing. So, we don't let them do certain things. New reg,
+// cookie-stealing. So, we do not let them do certain things. New reg,
// OpenID, and password logins _are_ real.
function common_real_login($real=true)
@@ -1147,7 +1147,7 @@ function common_accept_to_prefs($accept, $def = '*/*')
$parts = explode(',', $accept);
foreach($parts as $part) {
- // FIXME: doesn't deal with params like 'text/html; level=1'
+ // FIXME: does not deal with params like 'text/html; level=1'
@list($value, $qpart) = explode(';', trim($part));
$match = array();
if(!isset($qpart)) {
@@ -1346,7 +1346,7 @@ function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
}
// FIXME: show error page if we're on the Web
- /* Don't execute PHP internal error handler */
+ /* Do not execute PHP internal error handler */
return true;
}
@@ -1448,7 +1448,7 @@ function common_shorten_url($long_url)
}
global $_shorteners;
if (!isset($_shorteners[$svc])) {
- //the user selected service doesn't exist, so default to ur1.ca
+ //the user selected service does not exist, so default to ur1.ca
$svc = 'ur1.ca';
}
if (!isset($_shorteners[$svc])) {
diff --git a/lib/xmloutputter.php b/lib/xmloutputter.php
index 5f06e491d..9d862b2d0 100644
--- a/lib/xmloutputter.php
+++ b/lib/xmloutputter.php
@@ -112,7 +112,7 @@ class XMLOutputter
*
* Utility for outputting an XML element. A convenient wrapper
* for a bunch of longer XMLWriter calls. This is best for
- * when an element doesn't have any sub-elements; if that's the
+ * when an element does not have any sub-elements; if that's the
* case, use elementStart() and elementEnd() instead.
*
* The $content element will be escaped for XML. If you need
diff --git a/lib/xmppqueuehandler.php b/lib/xmppqueuehandler.php
index 8acdcafe7..29008da64 100644
--- a/lib/xmppqueuehandler.php
+++ b/lib/xmppqueuehandler.php
@@ -37,7 +37,7 @@ class XmppQueueHandler extends QueueHandler
function start()
{
- # Low priority; we don't want to receive messages
+ # Low priority; we do not want to receive messages
$this->log(LOG_INFO, "INITIALIZE");
$this->conn = jabber_connect($this->_id.$this->transport());
diff --git a/plugins/Autocomplete/autocomplete.php b/plugins/Autocomplete/autocomplete.php
index 379390ffd..aeb100cfa 100644
--- a/plugins/Autocomplete/autocomplete.php
+++ b/plugins/Autocomplete/autocomplete.php
@@ -79,7 +79,7 @@ class AutocompleteAction extends Action
function etag()
{
return '"' . implode(':', array($this->arg('action'),
- crc32($this->arg('q')), //the actual string can have funny characters in we don't want showing up in the etag
+ crc32($this->arg('q')), //the actual string can have funny characters in we do not want showing up in the etag
$this->arg('limit'),
$this->lastModified())) . '"';
}
diff --git a/plugins/BlogspamNetPlugin.php b/plugins/BlogspamNetPlugin.php
index 51236001a..bf60fdcaf 100644
--- a/plugins/BlogspamNetPlugin.php
+++ b/plugins/BlogspamNetPlugin.php
@@ -85,7 +85,7 @@ class BlogspamNetPlugin extends Plugin
} else if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400);
} else if (preg_match('/^OK$/', $response)) {
- // don't do anything
+ // do not do anything
} else {
throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500);
}
diff --git a/plugins/Facebook/FBConnectAuth.php b/plugins/Facebook/FBConnectAuth.php
index b909a4977..165477419 100644
--- a/plugins/Facebook/FBConnectAuth.php
+++ b/plugins/Facebook/FBConnectAuth.php
@@ -71,7 +71,7 @@ class FBConnectauthAction extends Action
'There is already a local user (' . $flink->user_id .
') linked with this Facebook (' . $this->fbuid . ').');
- // We don't want these cookies
+ // We do not want these cookies
getFacebook()->clear_cookie_state();
$this->clientError(_('There is already a local user linked with this Facebook.'));
@@ -364,7 +364,7 @@ class FBConnectauthAction extends Action
{
$url = common_get_returnto();
if ($url) {
- // We don't have to return to it again
+ // We do not have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
diff --git a/plugins/Facebook/FacebookPlugin.php b/plugins/Facebook/FacebookPlugin.php
index b68534b24..cd1ad7b45 100644
--- a/plugins/Facebook/FacebookPlugin.php
+++ b/plugins/Facebook/FacebookPlugin.php
@@ -182,7 +182,7 @@ class FacebookPlugin extends Plugin
$login_url = common_local_url('FBConnectAuth');
$logout_url = common_local_url('logout');
- // XXX: Facebook says we don't need this FB_RequireFeatures(),
+ // XXX: Facebook says we do not need this FB_RequireFeatures(),
// but we actually do, for IE and Safari. Gar.
$js = '";
} else {
diff --git a/plugins/Facebook/facebook/facebook_desktop.php b/plugins/Facebook/facebook/facebook_desktop.php
index e79a2ca34..425bb5c7b 100644
--- a/plugins/Facebook/facebook/facebook_desktop.php
+++ b/plugins/Facebook/facebook/facebook_desktop.php
@@ -93,7 +93,7 @@ class FacebookDesktop extends Facebook {
}
public function verify_signature($fb_params, $expected_sig) {
- // we don't want to verify the signature until we have a valid
+ // we do not want to verify the signature until we have a valid
// session secret
if ($this->verify_sig) {
return parent::verify_signature($fb_params, $expected_sig);
diff --git a/plugins/Facebook/facebook/facebookapi_php5_restlib.php b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
index e2a6fe88b..781390002 100755
--- a/plugins/Facebook/facebook/facebookapi_php5_restlib.php
+++ b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
@@ -46,7 +46,7 @@ class FacebookRestClient {
// on canvas pages
public $added;
public $is_user;
- // we don't pass friends list to iframes, but we want to make
+ // we do not pass friends list to iframes, but we want to make
// friends_get really simple in the canvas_user (non-logged in) case.
// So we use the canvas_user as default arg to friends_get
public $canvas_user;
@@ -657,7 +657,7 @@ function toggleDisplay(id, type) {
* deleted.
*
* IMPORTANT: If your application has registered public tags
- * that other applications may be using, don't delete those tags!
+ * that other applications may be using, do not delete those tags!
* Doing so can break the FBML ofapplications that are using them.
*
* @param array $tag_names the names of the tags to delete (optinal)
@@ -820,7 +820,7 @@ function toggleDisplay(id, type) {
if (is_array($target_ids)) {
$target_ids = json_encode($target_ids);
- $target_ids = trim($target_ids, "[]"); // we don't want square brackets
+ $target_ids = trim($target_ids, "[]"); // we do not want square brackets
}
return $this->call_method('facebook.feed.publishUserAction',
diff --git a/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php b/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php
index 29509deba..9c6c62663 100644
--- a/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php
+++ b/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php
@@ -1,5 +1,5 @@
location_id = $n->geonameId;
$location->location_ns = self::NAMESPACE;
- // handled, don't continue processing!
+ // handled, do not continue processing!
return false;
}
}
- // Continue processing; we don't have the answer
+ // Continue processing; we do not have the answer
return true;
}
@@ -217,7 +217,7 @@ class GeonamesPlugin extends Plugin
}
}
- // For some reason we don't know, so pass.
+ // For some reason we do not know, so pass.
return true;
}
@@ -299,7 +299,7 @@ class GeonamesPlugin extends Plugin
$url = 'http://www.geonames.org/' . $location->location_id;
- // it's been filled, so don't process further.
+ // it's been filled, so do not process further.
return false;
}
}
diff --git a/plugins/OpenID/finishopenidlogin.php b/plugins/OpenID/finishopenidlogin.php
index ff0b451d3..b5d978294 100644
--- a/plugins/OpenID/finishopenidlogin.php
+++ b/plugins/OpenID/finishopenidlogin.php
@@ -341,7 +341,7 @@ class FinishopenidloginAction extends Action
{
$url = common_get_returnto();
if ($url) {
- # We don't have to return to it again
+ # We do not have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
@@ -421,7 +421,7 @@ class FinishopenidloginAction extends Action
$parts = parse_url($openid);
- # If any of these parts exist, this won't work
+ # If any of these parts exist, this will not work
foreach ($bad as $badpart) {
if (array_key_exists($badpart, $parts)) {
diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php
index cd042226b..4a76a8791 100644
--- a/plugins/OpenID/openid.php
+++ b/plugins/OpenID/openid.php
@@ -187,7 +187,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
$form_html = $auth_request->formMarkup($trust_root, $process_url,
$immediate, array('id' => $form_id));
- # XXX: This is cheap, but things choke if we don't escape ampersands
+ # XXX: This is cheap, but things choke if we do not escape ampersands
# in the HTML attributes
$form_html = preg_replace('/&/', '&', $form_html);
diff --git a/plugins/PiwikAnalyticsPlugin.php b/plugins/PiwikAnalyticsPlugin.php
index 54faa0bdb..81ef7c683 100644
--- a/plugins/PiwikAnalyticsPlugin.php
+++ b/plugins/PiwikAnalyticsPlugin.php
@@ -44,7 +44,7 @@ if (!defined('STATUSNET')) {
* 'piwikId' => 'id'));
*
* Replace 'example.com/piwik/' with the URL to your Piwik installation and
- * make sure you don't forget the final /.
+ * make sure you do not forget the final /.
* Replace 'id' with the ID your statusnet installation has in your Piwik
* analytics setup - for example '8'.
*
diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php
index 0c7c1240c..88a87dcf9 100644
--- a/plugins/Realtime/RealtimePlugin.php
+++ b/plugins/Realtime/RealtimePlugin.php
@@ -240,7 +240,7 @@ class RealtimePlugin extends Plugin
// FIXME: this code should be abstracted to a neutral third
// party, like Notice::asJson(). I'm not sure of the ethics
// of refactoring from within a plugin, so I'm just abusing
- // the ApiAction method. Don't do this unless you're me!
+ // the ApiAction method. Do not do this unless you're me!
require_once(INSTALLDIR.'/lib/api.php');
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index 6a155b301..76410c7cb 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -115,7 +115,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
// Each child ps needs its own DB connection
// Note: DataObject::getDatabaseConnection() creates
- // a new connection if there isn't one already
+ // a new connection if there is not one already
$conn = &$flink->getDatabaseConnection();
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index ab610e553..5d0d83be3 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -136,7 +136,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
// Each child ps needs its own DB connection
// Note: DataObject::getDatabaseConnection() creates
- // a new connection if there isn't one already
+ // a new connection if there is not one already
$conn = &$flink->getDatabaseConnection();
@@ -499,7 +499,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$avatar->height = 73;
}
- $avatar->original = 0; // we don't have the original
+ $avatar->original = 0; // we do not have the original
$avatar->mediatype = $mediatype;
$avatar->filename = $filename;
$avatar->url = Avatar::url($filename);
diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php
index 3c6803e49..d48089caa 100644
--- a/plugins/TwitterBridge/twitter.php
+++ b/plugins/TwitterBridge/twitter.php
@@ -33,7 +33,7 @@ function updateTwitter_user($twitter_id, $screen_name)
$fuser->query('BEGIN');
- // Dropping down to SQL because regular DB_DataObject udpate stuff doesn't seem
+ // Dropping down to SQL because regular DB_DataObject udpate stuff does not seem
// to work so good with tables that have multiple column primary keys
// Any time we update the uri for a forein user we have to make sure there
diff --git a/scripts/console.php b/scripts/console.php
index 2413f5079..fecb75b4a 100755
--- a/scripts/console.php
+++ b/scripts/console.php
@@ -60,9 +60,9 @@ function read_input_line($prompt)
}
/**
- * On Unix-like systems where PHP readline extension isn't present,
+ * On Unix-like systems where PHP readline extension is not present,
* -cough- Mac OS X -cough- we can shell out to bash to do it for us.
- * This lets us at least handle things like arrow keys, but we don't
+ * This lets us at least handle things like arrow keys, but we do not
* get any entry history. :(
*
* Shamelessly ripped from when I wrote the same code for MediaWiki. :)
diff --git a/scripts/maildaemon.php b/scripts/maildaemon.php
index b4e4d9f08..4ec4526ef 100755
--- a/scripts/maildaemon.php
+++ b/scripts/maildaemon.php
@@ -231,7 +231,7 @@ class MailerDaemon
foreach ($parsed->parts as $part) {
$this->extract_part($part,$msg,$attachments);
}
- //we don't want any attachments that are a result of this parsing
+ //we do not want any attachments that are a result of this parsing
return $msg;
}
diff --git a/scripts/xmppconfirmhandler.php b/scripts/xmppconfirmhandler.php
index c7ed15e49..f5f824dee 100755
--- a/scripts/xmppconfirmhandler.php
+++ b/scripts/xmppconfirmhandler.php
@@ -69,7 +69,7 @@ class XmppConfirmHandler extends XmppQueueHandler
continue;
} else {
$this->log(LOG_INFO, 'Confirmation sent for ' . $confirm->address);
- # Mark confirmation sent; need a dupe so we don't have the WHERE clause
+ # Mark confirmation sent; need a dupe so we do not have the WHERE clause
$dupe = Confirm_address::staticGet('code', $confirm->code);
if (!$dupe) {
common_log(LOG_WARNING, 'Could not refetch confirm', __FILE__);
--
cgit v1.2.3-54-g00ecf
From 088081675fb7d5250a9b9dfe5015de0822cb5ac2 Mon Sep 17 00:00:00 2001
From: Brion Vibber
Date: Mon, 9 Nov 2009 20:01:46 +0100
Subject: Revert "Remove more contractions"
This reverts commit 5ab709b73977131813884558bf56d97172a7aa26.
Missed this one yesterday...
---
actions/allrss.php | 2 +-
actions/apiaccountratelimitstatus.php | 2 +-
actions/apifriendshipsdestroy.php | 2 +-
actions/attachment.php | 4 ++--
actions/avatarbynickname.php | 2 +-
actions/groupblock.php | 2 +-
actions/login.php | 2 +-
actions/logout.php | 2 +-
actions/newmessage.php | 2 +-
actions/newnotice.php | 2 +-
actions/opensearch.php | 2 +-
actions/passwordsettings.php | 2 +-
actions/register.php | 2 +-
actions/showgroup.php | 2 +-
actions/showmessage.php | 8 ++++----
actions/shownotice.php | 6 +++---
actions/showstream.php | 2 +-
actions/sup.php | 2 +-
actions/twitapisearchatom.php | 2 +-
actions/twitapitrends.php | 2 +-
classes/File_redirection.php | 8 ++++----
classes/Notice.php | 6 +++---
classes/Profile.php | 4 ++--
classes/User.php | 6 +++---
lib/api.php | 14 +++++++-------
lib/apiauth.php | 2 +-
lib/dberroraction.php | 6 +++---
lib/error.php | 4 ++--
lib/htmloutputter.php | 2 +-
lib/imagefile.php | 2 +-
lib/jabber.php | 2 +-
lib/mail.php | 6 +++---
lib/noticelist.php | 4 ++--
lib/queuehandler.php | 12 ++++++------
lib/rssaction.php | 2 +-
lib/search_engines.php | 2 +-
lib/util.php | 12 ++++++------
lib/xmloutputter.php | 2 +-
lib/xmppqueuehandler.php | 2 +-
plugins/Autocomplete/autocomplete.php | 2 +-
plugins/BlogspamNetPlugin.php | 2 +-
plugins/Facebook/FBConnectAuth.php | 4 ++--
plugins/Facebook/FacebookPlugin.php | 4 ++--
plugins/Facebook/facebook/facebook.php | 8 ++++----
plugins/Facebook/facebook/facebook_desktop.php | 2 +-
plugins/Facebook/facebook/facebookapi_php5_restlib.php | 6 +++---
plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php | 2 +-
plugins/Facebook/facebookaction.php | 6 +++---
plugins/GeonamesPlugin.php | 8 ++++----
plugins/OpenID/finishopenidlogin.php | 4 ++--
plugins/OpenID/openid.php | 2 +-
plugins/PiwikAnalyticsPlugin.php | 2 +-
plugins/Realtime/RealtimePlugin.php | 2 +-
plugins/TwitterBridge/daemons/synctwitterfriends.php | 2 +-
plugins/TwitterBridge/daemons/twitterstatusfetcher.php | 4 ++--
plugins/TwitterBridge/twitter.php | 2 +-
scripts/console.php | 4 ++--
scripts/maildaemon.php | 2 +-
scripts/xmppconfirmhandler.php | 2 +-
59 files changed, 110 insertions(+), 110 deletions(-)
(limited to 'plugins/TwitterBridge/daemons')
diff --git a/actions/allrss.php b/actions/allrss.php
index 4a5d15c7b..28b1be27d 100644
--- a/actions/allrss.php
+++ b/actions/allrss.php
@@ -56,7 +56,7 @@ class AllrssAction extends Rss10Action
*
* @param array $args Web and URL arguments
*
- * @return boolean false if user does not exist
+ * @return boolean false if user doesn't exist
*/
function prepare($args)
{
diff --git a/actions/apiaccountratelimitstatus.php b/actions/apiaccountratelimitstatus.php
index c7c0e7c00..96179f175 100644
--- a/actions/apiaccountratelimitstatus.php
+++ b/actions/apiaccountratelimitstatus.php
@@ -36,7 +36,7 @@ if (!defined('STATUSNET')) {
require_once INSTALLDIR . '/lib/apibareauth.php';
/**
- * We do not have a rate limit, but some clients check this method.
+ * We don't have a rate limit, but some clients check this method.
* It always returns the same thing: 150 hits left.
*
* @category API
diff --git a/actions/apifriendshipsdestroy.php b/actions/apifriendshipsdestroy.php
index fb73624c9..3d9b7e001 100644
--- a/actions/apifriendshipsdestroy.php
+++ b/actions/apifriendshipsdestroy.php
@@ -113,7 +113,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
return;
}
- // Do not allow unsubscribing from yourself!
+ // Don't allow unsubscribing from yourself!
if ($this->user->id == $this->other->id) {
$this->clientError(
diff --git a/actions/attachment.php b/actions/attachment.php
index ca9e57845..6981354d1 100644
--- a/actions/attachment.php
+++ b/actions/attachment.php
@@ -146,7 +146,7 @@ class AttachmentAction extends Action
}
/**
- * Do not show local navigation
+ * Don't show local navigation
*
* @return void
*/
@@ -170,7 +170,7 @@ class AttachmentAction extends Action
}
/**
- * Do not show page notice
+ * Don't show page notice
*
* @return void
*/
diff --git a/actions/avatarbynickname.php b/actions/avatarbynickname.php
index 1a6925e11..537950792 100644
--- a/actions/avatarbynickname.php
+++ b/actions/avatarbynickname.php
@@ -49,7 +49,7 @@ class AvatarbynicknameAction extends Action
*
* @param array $args query arguments
*
- * @return boolean false if nickname or user is not found
+ * @return boolean false if nickname or user isn't found
*/
function handle($args)
{
diff --git a/actions/groupblock.php b/actions/groupblock.php
index 133101eb7..979a56a81 100644
--- a/actions/groupblock.php
+++ b/actions/groupblock.php
@@ -95,7 +95,7 @@ class GroupblockAction extends Action
$this->clientError(_('User is already blocked from group.'));
return false;
}
- // XXX: could have proactive blocks, but we do not have UI for it.
+ // XXX: could have proactive blocks, but we don't have UI for it.
if (!$this->profile->isMember($this->group)) {
$this->clientError(_('User is not a member of group.'));
return false;
diff --git a/actions/login.php b/actions/login.php
index 679817520..ad57dd667 100644
--- a/actions/login.php
+++ b/actions/login.php
@@ -159,7 +159,7 @@ class LoginAction extends Action
$url = common_get_returnto();
if ($url) {
- // We do not have to return to it again
+ // We don't have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
diff --git a/actions/logout.php b/actions/logout.php
index 7e768fca6..1e0adae57 100644
--- a/actions/logout.php
+++ b/actions/logout.php
@@ -81,7 +81,7 @@ class LogoutAction extends Action
{
common_set_user(null);
common_real_login(false); // not logged in
- common_forgetme(); // do not log back in!
+ common_forgetme(); // don't log back in!
}
}
diff --git a/actions/newmessage.php b/actions/newmessage.php
index 73307fdfc..0db2e7181 100644
--- a/actions/newmessage.php
+++ b/actions/newmessage.php
@@ -61,7 +61,7 @@ class NewmessageAction extends Action
/**
* Title of the page
*
- * Note that this usually does not get called unless something went wrong
+ * Note that this usually doesn't get called unless something went wrong
*
* @return string page title
*/
diff --git a/actions/newnotice.php b/actions/newnotice.php
index fc06e5c98..fbd7ab6bc 100644
--- a/actions/newnotice.php
+++ b/actions/newnotice.php
@@ -59,7 +59,7 @@ class NewnoticeAction extends Action
/**
* Title of the page
*
- * Note that this usually does not get called unless something went wrong
+ * Note that this usually doesn't get called unless something went wrong
*
* @return string page title
*/
diff --git a/actions/opensearch.php b/actions/opensearch.php
index b205d2fe2..861b53d7d 100644
--- a/actions/opensearch.php
+++ b/actions/opensearch.php
@@ -52,7 +52,7 @@ class OpensearchAction extends Action
*
* @param array $args query arguments
*
- * @return boolean false if user does not exist
+ * @return boolean false if user doesn't exist
*/
function handle($args)
{
diff --git a/actions/passwordsettings.php b/actions/passwordsettings.php
index 6658d279f..87eb45a7d 100644
--- a/actions/passwordsettings.php
+++ b/actions/passwordsettings.php
@@ -97,7 +97,7 @@ class PasswordsettingsAction extends AccountSettingsAction
$this->elementStart('ul', 'form_data');
- // Users who logged in with OpenID will not have a pwd
+ // Users who logged in with OpenID won't have a pwd
if ($user->password) {
$this->elementStart('li');
$this->password('oldpassword', _('Old password'));
diff --git a/actions/register.php b/actions/register.php
index c4f6760aa..57f8e7bdf 100644
--- a/actions/register.php
+++ b/actions/register.php
@@ -174,7 +174,7 @@ class RegisterAction extends Action
$bio = $this->trimmed('bio');
$location = $this->trimmed('location');
- // We do not trim these... whitespace is OK in a password!
+ // We don't trim these... whitespace is OK in a password!
$password = $this->arg('password');
$confirm = $this->arg('confirm');
diff --git a/actions/showgroup.php b/actions/showgroup.php
index ae956befa..a4af29391 100644
--- a/actions/showgroup.php
+++ b/actions/showgroup.php
@@ -418,7 +418,7 @@ class ShowgroupAction extends GroupDesignAction
// XXX: WORM cache this
$members = $this->group->getMembers();
$members_count = 0;
- /** $member->count() does not work. */
+ /** $member->count() doesn't work. */
while ($members->fetch()) {
$members_count++;
}
diff --git a/actions/showmessage.php b/actions/showmessage.php
index cf3a819c1..db757948b 100644
--- a/actions/showmessage.php
+++ b/actions/showmessage.php
@@ -137,7 +137,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Do not show local navigation
+ * Don't show local navigation
*
* @return void
*/
@@ -147,7 +147,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Do not show page notice
+ * Don't show page notice
*
* @return void
*/
@@ -157,7 +157,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Do not show aside
+ * Don't show aside
*
* @return void
*/
@@ -167,7 +167,7 @@ class ShowmessageAction extends MailboxAction
}
/**
- * Do not show any instructions
+ * Don't show any instructions
*
* @return string
*/
diff --git a/actions/shownotice.php b/actions/shownotice.php
index 688089f02..5d16fdad9 100644
--- a/actions/shownotice.php
+++ b/actions/shownotice.php
@@ -208,7 +208,7 @@ class ShownoticeAction extends OwnerDesignAction
}
/**
- * Do not show local navigation
+ * Don't show local navigation
*
* @return void
*/
@@ -234,7 +234,7 @@ class ShownoticeAction extends OwnerDesignAction
}
/**
- * Do not show page notice
+ * Don't show page notice
*
* @return void
*/
@@ -244,7 +244,7 @@ class ShownoticeAction extends OwnerDesignAction
}
/**
- * Do not show aside
+ * Don't show aside
*
* @return void
*/
diff --git a/actions/showstream.php b/actions/showstream.php
index 4952ebdb7..663638c18 100644
--- a/actions/showstream.php
+++ b/actions/showstream.php
@@ -253,7 +253,7 @@ class ShowstreamAction extends ProfileAction
}
}
-// We do not show the author for a profile, since we already know who it is!
+// We don't show the author for a profile, since we already know who it is!
class ProfileNoticeList extends NoticeList
{
diff --git a/actions/sup.php b/actions/sup.php
index a199f247e..5daf0a1c1 100644
--- a/actions/sup.php
+++ b/actions/sup.php
@@ -61,7 +61,7 @@ class SupAction extends Action
$notice = new Notice();
# XXX: cache this. Depends on how big this protocol becomes;
- # Re-doing this query every 15 seconds is not the end of the world.
+ # Re-doing this query every 15 seconds isn't the end of the world.
$divider = common_sql_date(time() - $seconds);
diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php
index 511d7cdc6..7d618c471 100644
--- a/actions/twitapisearchatom.php
+++ b/actions/twitapisearchatom.php
@@ -250,7 +250,7 @@ class TwitapisearchatomAction extends ApiAction
}
// FIXME: this alternate link is not quite right because our
- // web-based notice search does not support a rpp (responses per
+ // web-based notice search doesn't support a rpp (responses per
// page) param yet
$this->element('link', array('type' => 'text/html',
diff --git a/actions/twitapitrends.php b/actions/twitapitrends.php
index 2d17e77cc..779405e6d 100644
--- a/actions/twitapitrends.php
+++ b/actions/twitapitrends.php
@@ -55,7 +55,7 @@ class TwitapitrendsAction extends ApiAction
*
* @param array $args Web and URL arguments
*
- * @return boolean false if user does not exist
+ * @return boolean false if user doesn't exist
*/
function prepare($args)
{
diff --git a/classes/File_redirection.php b/classes/File_redirection.php
index c951c1ee7..08a6e8d8b 100644
--- a/classes/File_redirection.php
+++ b/classes/File_redirection.php
@@ -53,7 +53,7 @@ class File_redirection extends Memcached_DataObject
'connect_timeout' => 10, // # seconds to wait
'max_redirs' => $redirs, // # max number of http redirections to follow
'follow_redirects' => true, // Follow redirects
- 'store_body' => false, // We will not need body content here.
+ 'store_body' => false, // We won't need body content here.
));
return $request;
}
@@ -81,12 +81,12 @@ class File_redirection extends Memcached_DataObject
}
try {
$request = self::_commonHttp($short_url, $redirs);
- // Do not include body in output
+ // Don't include body in output
$request->setMethod(HTTP_Request2::METHOD_HEAD);
$response = $request->send();
if (405 == $response->getStatus()) {
- // Server does not support HEAD method? Can this really happen?
+ // Server doesn't support HEAD method? Can this really happen?
// We'll try again as a GET and ignore the response data.
$request = self::_commonHttp($short_url, $redirs);
$response = $request->send();
@@ -178,7 +178,7 @@ class File_redirection extends Memcached_DataObject
case 'aim':
case 'jabber':
case 'xmpp':
- // do not touch anything
+ // don't touch anything
break;
default:
diff --git a/classes/Notice.php b/classes/Notice.php
index 32a8b693c..9886875cb 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -146,7 +146,7 @@ class Notice extends Memcached_DataObject
/* Add them to the database */
foreach(array_unique($hashtags) as $hashtag) {
- /* elide characters we do not want in the tag */
+ /* elide characters we don't want in the tag */
$this->saveTag($hashtag);
}
return true;
@@ -1105,7 +1105,7 @@ class Notice extends Memcached_DataObject
if (empty($recipient)) {
continue;
}
- // Do not save replies from blocked profile to local user
+ // Don't save replies from blocked profile to local user
$recipient_user = User::staticGet('id', $recipient->id);
if (!empty($recipient_user) && $recipient_user->hasBlocked($sender)) {
continue;
@@ -1131,7 +1131,7 @@ class Notice extends Memcached_DataObject
$tagged = Profile_tag::getTagged($sender->id, $tag);
foreach ($tagged as $t) {
if (!$replied[$t->id]) {
- // Do not save replies from blocked profile to local user
+ // Don't save replies from blocked profile to local user
$t_user = User::staticGet('id', $t->id);
if ($t_user && $t_user->hasBlocked($sender)) {
continue;
diff --git a/classes/Profile.php b/classes/Profile.php
index a50f4951d..7c1e9db33 100644
--- a/classes/Profile.php
+++ b/classes/Profile.php
@@ -101,7 +101,7 @@ class Profile extends Memcached_DataObject
}
foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
- # We do not do a scaled one if original is our scaled size
+ # We don't do a scaled one if original is our scaled size
if (!($avatar->width == $size && $avatar->height == $size)) {
$scaled_filename = $imagefile->resize($size);
@@ -174,7 +174,7 @@ class Profile extends Memcached_DataObject
function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
{
- // XXX: I'm not sure this is going to be any faster. It probably is not.
+ // XXX: I'm not sure this is going to be any faster. It probably isn't.
$ids = Notice::stream(array($this, '_streamDirect'),
array(),
'profile:notice_ids:' . $this->id,
diff --git a/classes/User.php b/classes/User.php
index c529b82e0..9b90ce61b 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -87,7 +87,7 @@ class User extends Memcached_DataObject
return (is_null($sub)) ? false : true;
}
- // 'update' will not write key columns, so we have to do it ourselves.
+ // 'update' won't write key columns, so we have to do it ourselves.
function updateKeys(&$orig)
{
@@ -384,7 +384,7 @@ class User extends Memcached_DataObject
return false;
}
- // Otherwise, cache does not have all faves;
+ // Otherwise, cache doesn't have all faves;
// fall through to the default
}
@@ -463,7 +463,7 @@ class User extends Memcached_DataObject
{
$cache = common_memcache();
if ($cache) {
- // Faves do not happen chronologically, so we need to blow
+ // Faves don't happen chronologically, so we need to blow
// ;last cache, too
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id));
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id.';last'));
diff --git a/lib/api.php b/lib/api.php
index fb4c4289b..a1236ab7e 100644
--- a/lib/api.php
+++ b/lib/api.php
@@ -66,7 +66,7 @@ class ApiAction extends Action
*
* @param array $args Web and URL arguments
*
- * @return boolean false if user does not exist
+ * @return boolean false if user doesn't exist
*/
function prepare($args)
@@ -138,7 +138,7 @@ class ApiAction extends Action
$design = null;
$user = $profile->getUser();
- // Note: some profiles do not have an associated user
+ // Note: some profiles don't have an associated user
if (!empty($user)) {
$design = $user->getDesign();
@@ -203,7 +203,7 @@ class ApiAction extends Action
if ($get_notice) {
$notice = $profile->getCurrentNotice();
if ($notice) {
- # do not get user!
+ # don't get user!
$twitter_user['status'] = $this->twitterStatusArray($notice, false);
}
}
@@ -263,7 +263,7 @@ class ApiAction extends Action
}
if ($include_user) {
- # Do not get notice (recursive!)
+ # Don't get notice (recursive!)
$twitter_user = $this->twitterUserArray($profile, false);
$twitter_status['user'] = $twitter_user;
}
@@ -1074,7 +1074,7 @@ class ApiAction extends Action
function initTwitterAtom()
{
$this->startXML();
- // FIXME: do not hardcode the language here!
+ // FIXME: don't hardcode the language here!
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom',
'xml:lang' => 'en-US',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'));
@@ -1116,7 +1116,7 @@ class ApiAction extends Action
return User::staticGet('nickname', $nickname);
} else if ($this->arg('user_id')) {
// This is to ensure that a non-numeric user_id still
- // overrides screen_name even if it does not get used
+ // overrides screen_name even if it doesn't get used
if (is_numeric($this->arg('user_id'))) {
return User::staticGet('id', $this->arg('user_id'));
}
@@ -1146,7 +1146,7 @@ class ApiAction extends Action
return User_group::staticGet('nickname', $nickname);
} else if ($this->arg('group_id')) {
// This is to ensure that a non-numeric user_id still
- // overrides screen_name even if it does not get used
+ // overrides screen_name even if it doesn't get used
if (is_numeric($this->arg('group_id'))) {
return User_group::staticGet('id', $this->arg('group_id'));
}
diff --git a/lib/apiauth.php b/lib/apiauth.php
index b8189f15d..2f2e44a26 100644
--- a/lib/apiauth.php
+++ b/lib/apiauth.php
@@ -87,7 +87,7 @@ class ApiAuthAction extends ApiAction
}
/**
- * Check for a user specified via HTTP basic auth. If there is not
+ * Check for a user specified via HTTP basic auth. If there isn't
* one, try to get one by outputting the basic auth header.
*
* @return boolean true or false
diff --git a/lib/dberroraction.php b/lib/dberroraction.php
index 893797b70..2cb66a022 100644
--- a/lib/dberroraction.php
+++ b/lib/dberroraction.php
@@ -39,7 +39,7 @@ require_once INSTALLDIR.'/lib/servererroraction.php';
*
* This only occurs if there's been a DB_DataObject_Error that's
* reported through PEAR, so we try to avoid doing anything that connects
- * to the DB, so we do not trigger it again.
+ * to the DB, so we don't trigger it again.
*
* @category Action
* @package StatusNet
@@ -62,12 +62,12 @@ class DBErrorAction extends ServerErrorAction
function getLanguage()
{
- // Do not try to figure out user's language; just show the page
+ // Don't try to figure out user's language; just show the page
return common_config('site', 'language');
}
function showPrimaryNav()
{
- // do not show primary nav
+ // don't show primary nav
}
}
diff --git a/lib/error.php b/lib/error.php
index 5ed5dec1b..3162cfe65 100644
--- a/lib/error.php
+++ b/lib/error.php
@@ -104,11 +104,11 @@ class ErrorAction extends Action
{
parent::showPage();
- // We do not want to have any more output after this
+ // We don't want to have any more output after this
exit();
}
- // Overload a bunch of stuff so the page is not too bloated
+ // Overload a bunch of stuff so the page isn't too bloated
function showBody()
{
diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php
index 73bd9ce81..c2ec83c28 100644
--- a/lib/htmloutputter.php
+++ b/lib/htmloutputter.php
@@ -76,7 +76,7 @@ class HTMLOutputter extends XMLOutputter
/**
* Start an HTML document
*
- * If $type is not specified, will attempt to do content negotiation.
+ * If $type isn't specified, will attempt to do content negotiation.
*
* Attempts to do content negotiation for language, also.
*
diff --git a/lib/imagefile.php b/lib/imagefile.php
index edc7218d0..cf1668f20 100644
--- a/lib/imagefile.php
+++ b/lib/imagefile.php
@@ -119,7 +119,7 @@ class ImageFile
return;
}
- // Do not crop/scale if it is not necessary
+ // Don't crop/scale if it isn't necessary
if ($size === $this->width
&& $size === $this->height
&& $x === 0
diff --git a/lib/jabber.php b/lib/jabber.php
index d666fcbb3..73f2ec660 100644
--- a/lib/jabber.php
+++ b/lib/jabber.php
@@ -437,7 +437,7 @@ function jabber_public_notice($notice)
$public = common_config('xmpp', 'public');
- // FIXME PRIV do not send out private messages here
+ // FIXME PRIV don't send out private messages here
// XXX: should we send out non-local messages if public,localonly
// = false? I think not
diff --git a/lib/mail.php b/lib/mail.php
index 79630b721..5218059e9 100644
--- a/lib/mail.php
+++ b/lib/mail.php
@@ -467,7 +467,7 @@ function mail_notify_nudge($from, $to)
"these days and is inviting you to post some news.\n\n".
"So let's hear from you :)\n\n".
"%3\$s\n\n".
- "Do not reply to this email. It will not get to them.\n\n".
+ "Don't reply to this email; it won't get to them.\n\n".
"With kind regards,\n".
"%4\$s\n"),
$from_profile->getBestName(),
@@ -516,7 +516,7 @@ function mail_notify_message($message, $from=null, $to=null)
"------------------------------------------------------\n\n".
"You can reply to their message here:\n\n".
"%4\$s\n\n".
- "Do not reply to this email. It will not get to them.\n\n".
+ "Don't reply to this email; it won't get to them.\n\n".
"With kind regards,\n".
"%5\$s\n"),
$from_profile->getBestName(),
@@ -532,7 +532,7 @@ function mail_notify_message($message, $from=null, $to=null)
/**
* notify a user that one of their notices has been chosen as a 'fave'
*
- * Does not check that the user has an email address nor if they
+ * Doesn't check that the user has an email address nor if they
* want to receive notification of faves. Maybe this happens higher
* up the stack...?
*
diff --git a/lib/noticelist.php b/lib/noticelist.php
index 4e5623ded..bf12bb73c 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -347,7 +347,7 @@ class NoticeListItem extends Widget
* show the link to the main page for the notice
*
* Displays a link to the page for a notice, with "relative" time. Tries to
- * get remote notice URLs correct, but does not always succeed.
+ * get remote notice URLs correct, but doesn't always succeed.
*
* @return void
*/
@@ -483,7 +483,7 @@ class NoticeListItem extends Widget
* show a link to reply to the current notice
*
* Should either do the reply in the current notice form (if available), or
- * link out to the notice-posting form. A little flakey, does not always work.
+ * link out to the notice-posting form. A little flakey, doesn't always work.
*
* @return void
*/
diff --git a/lib/queuehandler.php b/lib/queuehandler.php
index 7c07ca4f9..cd43b1e09 100644
--- a/lib/queuehandler.php
+++ b/lib/queuehandler.php
@@ -96,8 +96,8 @@ class QueueHandler extends Daemon
* Initialization, run when the queue handler starts.
* If this function indicates failure, the handler run will be aborted.
*
- * @fixme run() will abort if this does not return true,
- * but some subclasses do not bother.
+ * @fixme run() will abort if this doesn't return true,
+ * but some subclasses don't bother.
* @return boolean true on success, false on failure
*/
function start()
@@ -108,8 +108,8 @@ class QueueHandler extends Daemon
* Cleanup, run when the queue handler ends.
* If this function indicates failure, a warning will be logged.
*
- * @fixme run() will throw warnings if this does not return true,
- * but many subclasses do not bother.
+ * @fixme run() will throw warnings if this doesn't return true,
+ * but many subclasses don't bother.
* @return boolean true on success, false on failure
*/
function finish()
@@ -137,7 +137,7 @@ class QueueHandler extends Daemon
* method, which passes control back to our handle_notice() method for
* each notice that comes in on the queue.
*
- * Most of the time this will not need to be overridden in a subclass.
+ * Most of the time this won't need to be overridden in a subclass.
*
* @return boolean true on success, false on failure
*/
@@ -173,7 +173,7 @@ class QueueHandler extends Daemon
* Called by QueueHandler after each handled item or empty polling cycle.
* This is a good time to e.g. service your XMPP connection.
*
- * Does not need to be overridden if there's no maintenance to do.
+ * Doesn't need to be overridden if there's no maintenance to do.
*
* @param int $timeout seconds to sleep if there's nothing to do
*/
diff --git a/lib/rssaction.php b/lib/rssaction.php
index 0e84a65e9..faf6bec7d 100644
--- a/lib/rssaction.php
+++ b/lib/rssaction.php
@@ -386,7 +386,7 @@ class Rss10Action extends Action
return null;
}
- // FIXME: does not handle modified profiles, avatars, deleted notices
+ // FIXME: doesn't handle modified profiles, avatars, deleted notices
return strtotime($this->notices[0]->created);
}
diff --git a/lib/search_engines.php b/lib/search_engines.php
index 82713235c..69f6ff468 100644
--- a/lib/search_engines.php
+++ b/lib/search_engines.php
@@ -119,7 +119,7 @@ class MySQLSearch extends SearchEngine
return true;
} else if ('identica_notices' === $this->table) {
- // Do not show imported notices
+ // Don't show imported notices
$this->target->whereAdd('notice.is_local != ' . Notice::GATEWAY);
if (strtolower($q) != $q) {
diff --git a/lib/util.php b/lib/util.php
index b4f5af1af..a4865c46c 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -62,7 +62,7 @@ function common_init_language()
$locale_set = common_init_locale($language);
setlocale(LC_CTYPE, 'C');
- // So we do not have to make people install the gettext locales
+ // So we don't have to make people install the gettext locales
$path = common_config('site','locale_path');
bindtextdomain("statusnet", $path);
bind_textdomain_codeset("statusnet", "UTF-8");
@@ -139,7 +139,7 @@ function common_check_user($nickname, $password)
}
}
}else{
- //no handler indicated the credentials were valid, and we know their not valid because the user is not in the database
+ //no handler indicated the credentials were valid, and we know their not valid because the user isn't in the database
return false;
}
} else {
@@ -396,7 +396,7 @@ function common_current_user()
}
// Logins that are 'remembered' aren't 'real' -- they're subject to
-// cookie-stealing. So, we do not let them do certain things. New reg,
+// cookie-stealing. So, we don't let them do certain things. New reg,
// OpenID, and password logins _are_ real.
function common_real_login($real=true)
@@ -1147,7 +1147,7 @@ function common_accept_to_prefs($accept, $def = '*/*')
$parts = explode(',', $accept);
foreach($parts as $part) {
- // FIXME: does not deal with params like 'text/html; level=1'
+ // FIXME: doesn't deal with params like 'text/html; level=1'
@list($value, $qpart) = explode(';', trim($part));
$match = array();
if(!isset($qpart)) {
@@ -1346,7 +1346,7 @@ function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
}
// FIXME: show error page if we're on the Web
- /* Do not execute PHP internal error handler */
+ /* Don't execute PHP internal error handler */
return true;
}
@@ -1448,7 +1448,7 @@ function common_shorten_url($long_url)
}
global $_shorteners;
if (!isset($_shorteners[$svc])) {
- //the user selected service does not exist, so default to ur1.ca
+ //the user selected service doesn't exist, so default to ur1.ca
$svc = 'ur1.ca';
}
if (!isset($_shorteners[$svc])) {
diff --git a/lib/xmloutputter.php b/lib/xmloutputter.php
index 9d862b2d0..5f06e491d 100644
--- a/lib/xmloutputter.php
+++ b/lib/xmloutputter.php
@@ -112,7 +112,7 @@ class XMLOutputter
*
* Utility for outputting an XML element. A convenient wrapper
* for a bunch of longer XMLWriter calls. This is best for
- * when an element does not have any sub-elements; if that's the
+ * when an element doesn't have any sub-elements; if that's the
* case, use elementStart() and elementEnd() instead.
*
* The $content element will be escaped for XML. If you need
diff --git a/lib/xmppqueuehandler.php b/lib/xmppqueuehandler.php
index 7caa078ae..f28fc9088 100644
--- a/lib/xmppqueuehandler.php
+++ b/lib/xmppqueuehandler.php
@@ -37,7 +37,7 @@ class XmppQueueHandler extends QueueHandler
function start()
{
- # Low priority; we do not want to receive messages
+ # Low priority; we don't want to receive messages
$this->log(LOG_INFO, "INITIALIZE");
$this->conn = jabber_connect($this->_id.$this->transport());
diff --git a/plugins/Autocomplete/autocomplete.php b/plugins/Autocomplete/autocomplete.php
index aeb100cfa..379390ffd 100644
--- a/plugins/Autocomplete/autocomplete.php
+++ b/plugins/Autocomplete/autocomplete.php
@@ -79,7 +79,7 @@ class AutocompleteAction extends Action
function etag()
{
return '"' . implode(':', array($this->arg('action'),
- crc32($this->arg('q')), //the actual string can have funny characters in we do not want showing up in the etag
+ crc32($this->arg('q')), //the actual string can have funny characters in we don't want showing up in the etag
$this->arg('limit'),
$this->lastModified())) . '"';
}
diff --git a/plugins/BlogspamNetPlugin.php b/plugins/BlogspamNetPlugin.php
index bf60fdcaf..51236001a 100644
--- a/plugins/BlogspamNetPlugin.php
+++ b/plugins/BlogspamNetPlugin.php
@@ -85,7 +85,7 @@ class BlogspamNetPlugin extends Plugin
} else if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400);
} else if (preg_match('/^OK$/', $response)) {
- // do not do anything
+ // don't do anything
} else {
throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500);
}
diff --git a/plugins/Facebook/FBConnectAuth.php b/plugins/Facebook/FBConnectAuth.php
index 165477419..b909a4977 100644
--- a/plugins/Facebook/FBConnectAuth.php
+++ b/plugins/Facebook/FBConnectAuth.php
@@ -71,7 +71,7 @@ class FBConnectauthAction extends Action
'There is already a local user (' . $flink->user_id .
') linked with this Facebook (' . $this->fbuid . ').');
- // We do not want these cookies
+ // We don't want these cookies
getFacebook()->clear_cookie_state();
$this->clientError(_('There is already a local user linked with this Facebook.'));
@@ -364,7 +364,7 @@ class FBConnectauthAction extends Action
{
$url = common_get_returnto();
if ($url) {
- // We do not have to return to it again
+ // We don't have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
diff --git a/plugins/Facebook/FacebookPlugin.php b/plugins/Facebook/FacebookPlugin.php
index cd1ad7b45..b68534b24 100644
--- a/plugins/Facebook/FacebookPlugin.php
+++ b/plugins/Facebook/FacebookPlugin.php
@@ -182,7 +182,7 @@ class FacebookPlugin extends Plugin
$login_url = common_local_url('FBConnectAuth');
$logout_url = common_local_url('logout');
- // XXX: Facebook says we do not need this FB_RequireFeatures(),
+ // XXX: Facebook says we don't need this FB_RequireFeatures(),
// but we actually do, for IE and Safari. Gar.
$js = '";
} else {
diff --git a/plugins/Facebook/facebook/facebook_desktop.php b/plugins/Facebook/facebook/facebook_desktop.php
index 425bb5c7b..e79a2ca34 100644
--- a/plugins/Facebook/facebook/facebook_desktop.php
+++ b/plugins/Facebook/facebook/facebook_desktop.php
@@ -93,7 +93,7 @@ class FacebookDesktop extends Facebook {
}
public function verify_signature($fb_params, $expected_sig) {
- // we do not want to verify the signature until we have a valid
+ // we don't want to verify the signature until we have a valid
// session secret
if ($this->verify_sig) {
return parent::verify_signature($fb_params, $expected_sig);
diff --git a/plugins/Facebook/facebook/facebookapi_php5_restlib.php b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
index c742df748..55cb7fb86 100755
--- a/plugins/Facebook/facebook/facebookapi_php5_restlib.php
+++ b/plugins/Facebook/facebook/facebookapi_php5_restlib.php
@@ -46,7 +46,7 @@ class FacebookRestClient {
// on canvas pages
public $added;
public $is_user;
- // we do not pass friends list to iframes, but we want to make
+ // we don't pass friends list to iframes, but we want to make
// friends_get really simple in the canvas_user (non-logged in) case.
// So we use the canvas_user as default arg to friends_get
public $canvas_user;
@@ -657,7 +657,7 @@ function toggleDisplay(id, type) {
* deleted.
*
* IMPORTANT: If your application has registered public tags
- * that other applications may be using, do not delete those tags!
+ * that other applications may be using, don't delete those tags!
* Doing so can break the FBML ofapplications that are using them.
*
* @param array $tag_names the names of the tags to delete (optinal)
@@ -820,7 +820,7 @@ function toggleDisplay(id, type) {
if (is_array($target_ids)) {
$target_ids = json_encode($target_ids);
- $target_ids = trim($target_ids, "[]"); // we do not want square brackets
+ $target_ids = trim($target_ids, "[]"); // we don't want square brackets
}
return $this->call_method('facebook.feed.publishUserAction',
diff --git a/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php b/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php
index 9c6c62663..29509deba 100644
--- a/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php
+++ b/plugins/Facebook/facebook/jsonwrapper/jsonwrapper.php
@@ -1,5 +1,5 @@
location_id = $n->geonameId;
$location->location_ns = self::NAMESPACE;
- // handled, do not continue processing!
+ // handled, don't continue processing!
return false;
}
}
- // Continue processing; we do not have the answer
+ // Continue processing; we don't have the answer
return true;
}
@@ -217,7 +217,7 @@ class GeonamesPlugin extends Plugin
}
}
- // For some reason we do not know, so pass.
+ // For some reason we don't know, so pass.
return true;
}
@@ -299,7 +299,7 @@ class GeonamesPlugin extends Plugin
$url = 'http://www.geonames.org/' . $location->location_id;
- // it's been filled, so do not process further.
+ // it's been filled, so don't process further.
return false;
}
}
diff --git a/plugins/OpenID/finishopenidlogin.php b/plugins/OpenID/finishopenidlogin.php
index b5d978294..ff0b451d3 100644
--- a/plugins/OpenID/finishopenidlogin.php
+++ b/plugins/OpenID/finishopenidlogin.php
@@ -341,7 +341,7 @@ class FinishopenidloginAction extends Action
{
$url = common_get_returnto();
if ($url) {
- # We do not have to return to it again
+ # We don't have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
@@ -421,7 +421,7 @@ class FinishopenidloginAction extends Action
$parts = parse_url($openid);
- # If any of these parts exist, this will not work
+ # If any of these parts exist, this won't work
foreach ($bad as $badpart) {
if (array_key_exists($badpart, $parts)) {
diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php
index c5f6d1713..ff7a93899 100644
--- a/plugins/OpenID/openid.php
+++ b/plugins/OpenID/openid.php
@@ -187,7 +187,7 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
$form_html = $auth_request->formMarkup($trust_root, $process_url,
$immediate, array('id' => $form_id));
- # XXX: This is cheap, but things choke if we do not escape ampersands
+ # XXX: This is cheap, but things choke if we don't escape ampersands
# in the HTML attributes
$form_html = preg_replace('/&/', '&', $form_html);
diff --git a/plugins/PiwikAnalyticsPlugin.php b/plugins/PiwikAnalyticsPlugin.php
index 81ef7c683..54faa0bdb 100644
--- a/plugins/PiwikAnalyticsPlugin.php
+++ b/plugins/PiwikAnalyticsPlugin.php
@@ -44,7 +44,7 @@ if (!defined('STATUSNET')) {
* 'piwikId' => 'id'));
*
* Replace 'example.com/piwik/' with the URL to your Piwik installation and
- * make sure you do not forget the final /.
+ * make sure you don't forget the final /.
* Replace 'id' with the ID your statusnet installation has in your Piwik
* analytics setup - for example '8'.
*
diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php
index 88a87dcf9..0c7c1240c 100644
--- a/plugins/Realtime/RealtimePlugin.php
+++ b/plugins/Realtime/RealtimePlugin.php
@@ -240,7 +240,7 @@ class RealtimePlugin extends Plugin
// FIXME: this code should be abstracted to a neutral third
// party, like Notice::asJson(). I'm not sure of the ethics
// of refactoring from within a plugin, so I'm just abusing
- // the ApiAction method. Do not do this unless you're me!
+ // the ApiAction method. Don't do this unless you're me!
require_once(INSTALLDIR.'/lib/api.php');
diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php
index c89c02eed..671e3c7af 100755
--- a/plugins/TwitterBridge/daemons/synctwitterfriends.php
+++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php
@@ -115,7 +115,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
// Each child ps needs its own DB connection
// Note: DataObject::getDatabaseConnection() creates
- // a new connection if there is not one already
+ // a new connection if there isn't one already
$conn = &$flink->getDatabaseConnection();
diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
index 25df0d839..b5428316b 100755
--- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
+++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php
@@ -136,7 +136,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
// Each child ps needs its own DB connection
// Note: DataObject::getDatabaseConnection() creates
- // a new connection if there is not one already
+ // a new connection if there isn't one already
$conn = &$flink->getDatabaseConnection();
@@ -499,7 +499,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$avatar->height = 73;
}
- $avatar->original = 0; // we do not have the original
+ $avatar->original = 0; // we don't have the original
$avatar->mediatype = $mediatype;
$avatar->filename = $filename;
$avatar->url = Avatar::url($filename);
diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php
index d48089caa..3c6803e49 100644
--- a/plugins/TwitterBridge/twitter.php
+++ b/plugins/TwitterBridge/twitter.php
@@ -33,7 +33,7 @@ function updateTwitter_user($twitter_id, $screen_name)
$fuser->query('BEGIN');
- // Dropping down to SQL because regular DB_DataObject udpate stuff does not seem
+ // Dropping down to SQL because regular DB_DataObject udpate stuff doesn't seem
// to work so good with tables that have multiple column primary keys
// Any time we update the uri for a forein user we have to make sure there
diff --git a/scripts/console.php b/scripts/console.php
index 2a000d39b..41dd43f28 100755
--- a/scripts/console.php
+++ b/scripts/console.php
@@ -60,9 +60,9 @@ function read_input_line($prompt)
}
/**
- * On Unix-like systems where PHP readline extension is not present,
+ * On Unix-like systems where PHP readline extension isn't present,
* -cough- Mac OS X -cough- we can shell out to bash to do it for us.
- * This lets us at least handle things like arrow keys, but we do not
+ * This lets us at least handle things like arrow keys, but we don't
* get any entry history. :(
*
* Shamelessly ripped from when I wrote the same code for MediaWiki. :)
diff --git a/scripts/maildaemon.php b/scripts/maildaemon.php
index 4ec4526ef..b4e4d9f08 100755
--- a/scripts/maildaemon.php
+++ b/scripts/maildaemon.php
@@ -231,7 +231,7 @@ class MailerDaemon
foreach ($parsed->parts as $part) {
$this->extract_part($part,$msg,$attachments);
}
- //we do not want any attachments that are a result of this parsing
+ //we don't want any attachments that are a result of this parsing
return $msg;
}
diff --git a/scripts/xmppconfirmhandler.php b/scripts/xmppconfirmhandler.php
index f5f824dee..c7ed15e49 100755
--- a/scripts/xmppconfirmhandler.php
+++ b/scripts/xmppconfirmhandler.php
@@ -69,7 +69,7 @@ class XmppConfirmHandler extends XmppQueueHandler
continue;
} else {
$this->log(LOG_INFO, 'Confirmation sent for ' . $confirm->address);
- # Mark confirmation sent; need a dupe so we do not have the WHERE clause
+ # Mark confirmation sent; need a dupe so we don't have the WHERE clause
$dupe = Confirm_address::staticGet('code', $confirm->code);
if (!$dupe) {
common_log(LOG_WARNING, 'Could not refetch confirm', __FILE__);
--
cgit v1.2.3-54-g00ecf