diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/action.php | 13 | ||||
-rw-r--r-- | lib/apiaction.php | 10 | ||||
-rw-r--r-- | lib/apiauth.php | 9 | ||||
-rw-r--r-- | lib/apioauthstore.php | 215 | ||||
-rw-r--r-- | lib/applicationlist.php | 247 | ||||
-rw-r--r-- | lib/common.php | 4 | ||||
-rw-r--r-- | lib/dberroraction.php | 1 | ||||
-rw-r--r-- | lib/feed.php | 1 | ||||
-rw-r--r-- | lib/feedlist.php | 1 | ||||
-rw-r--r-- | lib/groupsbymemberssection.php | 2 | ||||
-rw-r--r-- | lib/groupsbypostssection.php | 2 | ||||
-rw-r--r-- | lib/groupsection.php | 1 | ||||
-rw-r--r-- | lib/grouptagcloudsection.php | 3 | ||||
-rw-r--r-- | lib/mail.php | 109 | ||||
-rw-r--r-- | lib/router.php | 37 | ||||
-rw-r--r-- | lib/util.php | 15 | ||||
-rw-r--r-- | lib/webcolor.php | 15 |
17 files changed, 474 insertions, 211 deletions
diff --git a/lib/action.php b/lib/action.php index 55ee83bde..01bb0f7e9 100644 --- a/lib/action.php +++ b/lib/action.php @@ -362,9 +362,9 @@ class Action extends HTMLOutputter // lawsuit */ function showBody() { - $this->elementStart('body', (common_current_user()) ? array('id' => $this->trimmed('action'), + $this->elementStart('body', (common_current_user()) ? array('id' => strtolower($this->trimmed('action')), 'class' => 'user_in') - : array('id' => $this->trimmed('action'))); + : array('id' => strtolower($this->trimmed('action')))); $this->elementStart('div', array('id' => 'wrap')); if (Event::handle('StartShowHeader', array($this))) { $this->showHeader(); @@ -419,8 +419,9 @@ class Action extends HTMLOutputter // lawsuit 'class' => 'vcard')); if (Event::handle('StartAddressData', array($this))) { if (common_config('singleuser', 'enabled')) { + $user = User::singleUser(); $url = common_local_url('showstream', - array('nickname' => common_config('singleuser', 'nickname'))); + array('nickname' => $user->nickname)); } else { $url = common_local_url('public'); } @@ -526,20 +527,20 @@ class Action extends HTMLOutputter // lawsuit } // TRANS: Tooltip for main menu option "Login" $tooltip = _m('TOOLTIP', 'Login to the site'); - // TRANS: Main menu option when not logged in to log in $this->menuItem(common_local_url('login'), + // TRANS: Main menu option when not logged in to log in _m('MENU', 'Login'), $tooltip, false, 'nav_login'); } // TRANS: Tooltip for main menu option "Help" $tooltip = _m('TOOLTIP', 'Help me!'); - // TRANS: Main menu option for help on the StatusNet site $this->menuItem(common_local_url('doc', array('title' => 'help')), + // TRANS: Main menu option for help on the StatusNet site _m('MENU', 'Help'), $tooltip, false, 'nav_help'); if ($user || !common_config('site', 'private')) { // TRANS: Tooltip for main menu option "Search" $tooltip = _m('TOOLTIP', 'Search for people or text'); - // TRANS: Main menu option when logged in or when the StatusNet instance is not private $this->menuItem(common_local_url('peoplesearch'), + // TRANS: Main menu option when logged in or when the StatusNet instance is not private _m('MENU', 'Search'), $tooltip, false, 'nav_search'); } Event::handle('EndPrimaryNav', array($this)); diff --git a/lib/apiaction.php b/lib/apiaction.php index fbc3a1451..82685e62e 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -1400,8 +1400,10 @@ class ApiAction extends Action if (is_numeric($this->arg('id'))) { return Profile::staticGet($this->arg('id')); } else if ($this->arg('id')) { + // Screen names currently can only uniquely identify a local user. $nickname = common_canonical_nickname($this->arg('id')); - return Profile::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', $nickname); + return $user ? $user->getProfile() : null; } 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 @@ -1410,13 +1412,15 @@ class ApiAction extends Action } } else if ($this->arg('screen_name')) { $nickname = common_canonical_nickname($this->arg('screen_name')); - return Profile::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', $nickname); + return $user ? $user->getProfile() : null; } } else if (is_numeric($id)) { return Profile::staticGet($id); } else { $nickname = common_canonical_nickname($id); - return Profile::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', $nickname); + return $user ? $user->getProfile() : null; } } diff --git a/lib/apiauth.php b/lib/apiauth.php index a1c698bba..1dacf1409 100644 --- a/lib/apiauth.php +++ b/lib/apiauth.php @@ -178,8 +178,10 @@ class ApiAuthAction extends ApiAction } // set the source attr + if ($app->name != 'anonymous') { + $this->source = $app->name; + } - $this->source = $app->name; $appUser = Oauth_application_user::staticGet('token', $access_token); @@ -261,7 +263,7 @@ class ApiAuthAction extends ApiAction // show error if the user clicks 'cancel' // TRANS: Client error thrown when authentication fails becaus a user clicked "Cancel". - $this->clientError(_("Could not authenticate you."), 401, $this->format); + $this->clientError(_('Could not authenticate you.'), 401, $this->format); exit; } else { @@ -288,7 +290,7 @@ class ApiAuthAction extends ApiAction ); $this->logAuthFailure($msg); // TRANS: Client error thrown when authentication fails. - $this->clientError(_("Could not authenticate you."), 401, $this->format); + $this->clientError(_('Could not authenticate you.'), 401, $this->format); exit; } } @@ -340,7 +342,6 @@ class ApiAuthAction extends ApiAction * * @param string $logMsg additional log message */ - function logAuthFailure($logMsg) { list($proxy, $ip) = common_client_ip(); diff --git a/lib/apioauthstore.php b/lib/apioauthstore.php index 6e0039bdd..2a65fffc4 100644 --- a/lib/apioauthstore.php +++ b/lib/apioauthstore.php @@ -23,24 +23,71 @@ require_once INSTALLDIR . '/lib/oauthstore.php'; class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore { - function lookup_consumer($consumer_key) + function lookup_consumer($consumerKey) { - $con = Consumer::staticGet('consumer_key', $consumer_key); + $con = Consumer::staticGet('consumer_key', $consumerKey); if (!$con) { - return null; + + // Create an anon consumer and anon application if one + // doesn't exist already + if ($consumerKey == 'anonymous') { + + common_debug("API OAuth - creating anonymous consumer"); + $con = new Consumer(); + $con->consumer_key = $consumerKey; + $con->consumer_secret = $consumerKey; + $con->created = common_sql_now(); + + $result = $con->insert(); + if (!$result) { + // TRANS: Server error displayed when trying to create an anynymous OAuth consumer. + $this->serverError(_('Could not create anonymous consumer.')); + } + + $app = Oauth_application::getByConsumerKey('anonymous'); + + if (!$app) { + common_debug("API OAuth - creating anonymous application"); + $app = new OAuth_application(); + $app->owner = 1; // XXX: What to do here? + $app->consumer_key = $con->consumer_key; + $app->name = 'anonymous'; + $app->icon = 'default-avatar-stream.png'; // XXX: Fix this! + $app->description = "An anonymous application"; + // XXX: allow the user to set the access type when + // authorizing? Currently we default to r+w for anonymous + // OAuth client applications + $app->access_type = 3; // read + write + $app->type = 2; // desktop + $app->created = common_sql_now(); + + $id = $app->insert(); + + if (!$id) { + // TRANS: Server error displayed when trying to create an anynymous OAuth application. + $this->serverError(_("Could not create anonymous OAuth application.")); + } + } + } else { + return null; + } } - return new OAuthConsumer($con->consumer_key, - $con->consumer_secret); + return new OAuthConsumer( + $con->consumer_key, + $con->consumer_secret + ); } function getAppByRequestToken($token_key) { - // Look up the full req tokenx - $req_token = $this->lookup_token(null, - 'request', - $token_key); + // Look up the full req token + $req_token = $this->lookup_token( + null, + 'request', + $token_key + ); if (empty($req_token)) { common_debug("couldn't get request token from oauth datastore"); @@ -58,7 +105,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore } // Look up the app - $app = new Oauth_application(); $app->consumer_key = $token->consumer_key; $result = $app->find(true); @@ -75,12 +121,12 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore { common_debug( sprintf( - "%s - New access token from request token %s, consumer %s and verifier %s ", - __FILE__, + "New access token from request token %s, consumer %s and verifier %s ", $token, $consumer, $verifier - ) + ), + __FILE__ ); $rt = new Token(); @@ -94,73 +140,123 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized - common_debug('request token found.', __FILE__); + common_debug('Request token found.', __FILE__); - // find the associated user of the app + // find the app and profile associated with this token + $tokenAssoc = Oauth_token_association::staticGet('token', $rt->tok); + + if (!$tokenAssoc) { + throw new Exception( + // TRANS: Exception thrown when no token association could be found. + _('Could not find a profile and application associated with the request token.') + ); + } + + // check to see if we have previously issued an access token for this application + // and profile $appUser = new Oauth_application_user(); $appUser->application_id = $app->id; - $appUser->token = $rt->tok; + $appUser->profile_id = $tokenAssoc->profile_id; $result = $appUser->find(true); if (!empty($result)) { - common_debug("Ouath app user found."); - } else { - common_debug("Oauth app user not found. app id $app->id token $rt->tok"); - return null; - } - // go ahead and make the access token + common_log(LOG_INFO, + sprintf( + "Existing access token found for application %s, profile %s.", + $app->id, + $tokenAssoc->profile_id + ) + ); - $at = new Token(); - $at->consumer_key = $consumer->key; - $at->tok = common_good_rand(16); - $at->secret = common_good_rand(16); - $at->type = 1; // access - $at->verifier = $verifier; - $at->verified_callback = $rt->verified_callback; // 1.0a - $at->created = DB_DataObject_Cast::dateTime(); + $at = new Token(); - if (!$at->insert()) { - $e = $at->_lastError; - common_debug('access token "'.$at->tok.'" not inserted: "'.$e->message.'"', __FILE__); - return null; - } else { - common_debug('access token "'.$at->tok.'" inserted', __FILE__); - // burn the old one - $orig_rt = clone($rt); - $rt->state = 2; // used - if (!$rt->update($orig_rt)) { - return null; + // fetch the full access token + $at->consumer_key = $consumer->key; + $at->tok = $appUser->token; + + $result = $at->find(true); + + if (!$result) { + throw new Exception( + // TRANS: Exception thrown when no access token can be issued. + _('Could not issue access token.') + ); } - common_debug('request token "'.$rt->tok.'" updated', __FILE__); - // update the token from req to access for the user + // Yay, we can re-issue the access token + return new OAuthToken($at->tok, $at->secret); + + } else { - $orig = clone($appUser); - $appUser->token = $at->tok; + common_log(LOG_INFO, + sprintf( + "Creating new access token for application %s, profile %s.", + $app->id, + $tokenAssoc->profile_id + ) + ); + + // make a brand new access token + $at = new Token(); + + $at->consumer_key = $consumer->key; + $at->tok = common_good_rand(16); + $at->secret = common_good_rand(16); + $at->type = 1; // access + $at->verifier = $verifier; + $at->verified_callback = $rt->verified_callback; // 1.0a + $at->created = common_sql_now(); + + if (!$at->insert()) { + $e = $at->_lastError; + common_debug('access token "' . $at->tok . '" not inserted: "' . $e->message . '"', __FILE__); + return null; + } else { + common_debug('access token "' . $at->tok . '" inserted', __FILE__); + // burn the old one + $orig_rt = clone($rt); + $rt->state = 2; // used + if (!$rt->update($orig_rt)) { + return null; + } + common_debug('request token "' . $rt->tok . '" updated', __FILE__); + } - // It's at this point that we change the access type - // to whatever the application's access is. Request - // tokens should always have an access type of 0, and - // therefore be unuseable for making requests for - // protected resources. + // insert a new Oauth_application_user record w/access token + $appUser = new Oauth_application_user(); - $appUser->access_type = $app->access_type; + $appUser->profile_id = $tokenAssoc->profile_id;; + $appUser->application_id = $app->id; + $appUser->access_type = $app->access_type; + $appUser->token = $at->tok; + $appUser->created = common_sql_now(); - $result = $appUser->update($orig); + $result = $appUser->insert(); - if (empty($result)) { - common_debug('couldn\'t update OAuth app user.'); - return null; + if (!$result) { + common_log_db_error($appUser, 'INSERT', __FILE__); + // TRANS: Server error displayed when a database error occurs. + $this->serverError(_('Database error inserting OAuth application user.')); } // Okay, good return new OAuthToken($at->tok, $at->secret); } + } else { + + // the token was not authorized or not verfied + common_log( + LOG_INFO, + sprintf( + "API OAuth - Attempt to exchange unauthorized or unverified request token %s for an access token.", + $rt->tok + ) + ); return null; } } @@ -179,9 +275,9 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore * @return void */ public function revoke_token($token_key, $type = 0) { - $rt = new Token(); - $rt->tok = $token_key; - $rt->type = $type; + $rt = new Token(); + $rt->tok = $token_key; + $rt->type = $type; $rt->state = 0; if (!$rt->find(true)) { @@ -203,7 +299,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore * * @return OAuthToken $token a new unauthorized OAuth request token */ - function new_request_token($consumer, $callback) { $t = new Token(); @@ -228,6 +323,4 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore return new OAuthToken($t->tok, $t->secret); } } - - } diff --git a/lib/applicationlist.php b/lib/applicationlist.php index 8b6e3a8ad..3f50f110b 100644 --- a/lib/applicationlist.php +++ b/lib/applicationlist.php @@ -22,7 +22,7 @@ * @category Application * @package StatusNet * @author Zach Copley <zach@status.net> - * @copyright 2008-2009 StatusNet, Inc. + * @copyright 2008-2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ @@ -55,14 +55,13 @@ class ApplicationList extends Widget /** Action object using us. */ var $action = null; - function __construct($application, $owner=null, $action=null, $connections = false) + function __construct($application, $owner=null, $action=null) { parent::__construct($action); $this->application = $application; $this->owner = $owner; $this->action = $action; - $this->connections = $connections; } function show() @@ -88,24 +87,34 @@ class ApplicationList extends Widget { $user = common_current_user(); - $this->out->elementStart('li', array('class' => 'application', - 'id' => 'oauthclient-' . $this->application->id)); + $this->out->elementStart( + 'li', + array( + 'class' => 'application', + 'id' => 'oauthclient-' . $this->application->id + ) + ); $this->out->elementStart('span', 'vcard author'); - if (!$this->connections) { - $this->out->elementStart('a', - array('href' => common_local_url('showapplication', - array('id' => $this->application->id)), - 'class' => 'url')); - - } else { - $this->out->elementStart('a', array('href' => $this->application->source_url, - 'class' => 'url')); - } + + $this->out->elementStart( + 'a', + array( + 'href' => common_local_url( + 'showapplication', + array('id' => $this->application->id)), + 'class' => 'url' + ) + ); if (!empty($this->application->icon)) { - $this->out->element('img', array('src' => $this->application->icon, - 'class' => 'photo avatar')); + $this->out->element( + 'img', + array( + 'src' => $this->application->icon, + 'class' => 'photo avatar' + ) + ); } $this->out->element('span', 'fn', $this->application->name); @@ -114,51 +123,56 @@ class ApplicationList extends Widget $this->out->raw(' by '); - $this->out->element('a', array('href' => $this->application->homepage, - 'class' => 'url'), - $this->application->organization); + $this->out->element( + 'a', + array( + 'href' => $this->application->homepage, + 'class' => 'url' + ), + $this->application->organization + ); $this->out->element('p', 'note', $this->application->description); $this->out->elementEnd('li'); - if ($this->connections) { - $appUser = Oauth_application_user::getByKeys($this->owner, $this->application); + } - if (empty($appUser)) { - common_debug("empty appUser!"); - } + /* Override this in subclasses. */ + function showOwnerControls() + { + return; + } +} - $this->out->elementStart('li'); - - // TRANS: Application access type - $readWriteText = _('read-write'); - // TRANS: Application access type - $readOnlyText = _('read-only'); - - $access = ($this->application->access_type & Oauth_application::$writeAccess) - ? $readWriteText : $readOnlyText; - $modifiedDate = common_date_string($appUser->modified); - // TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only") - $txt = sprintf(_('Approved %1$s - "%2$s" access.'),$modifiedDate,$access); - - $this->out->raw($txt); - $this->out->elementEnd('li'); - - $this->out->elementStart('li', 'entity_revoke'); - $this->out->elementStart('form', array('id' => 'form_revoke_app', - 'class' => 'form_revoke_app', - 'method' => 'POST', - 'action' => - common_local_url('oauthconnectionssettings'))); - $this->out->elementStart('fieldset'); - $this->out->hidden('id', $this->application->id); - $this->out->hidden('token', common_session_token()); - // TRANS: Button label - $this->out->submit('revoke', _m('BUTTON','Revoke')); - $this->out->elementEnd('fieldset'); - $this->out->elementEnd('form'); - $this->out->elementEnd('li'); - } +/** + * Widget to show a list of connected OAuth clients + * + * @category Application + * @package StatusNet + * @author Zach Copley <zach@status.net> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ +class ConnectedAppsList extends Widget +{ + /** Current connected application query */ + var $connection = null; + + /** Owner of this list */ + var $owner = null; + + /** Action object using us. */ + var $action = null; + + function __construct($connection, $owner=null, $action=null) + { + parent::__construct($action); + + common_debug("ConnectedAppsList constructor"); + + $this->connection = $connection; + $this->owner = $owner; + $this->action = $action; } /* Override this in subclasses. */ @@ -166,4 +180,125 @@ class ApplicationList extends Widget { return; } + + function show() + { + $this->out->elementStart('ul', 'applications'); + + $cnt = 0; + + while ($this->connection->fetch()) { + $cnt++; + if($cnt > APPS_PER_PAGE) { + break; + } + $this->showConnection(); + } + + $this->out->elementEnd('ul'); + + return $cnt; + } + + function showConnection() + { + $app = Oauth_application::staticGet('id', $this->connection->application_id); + + $this->out->elementStart( + 'li', + array( + 'class' => 'application', + 'id' => 'oauthclient-' . $app->id + ) + ); + + $this->out->elementStart('span', 'vcard author'); + + $this->out->elementStart( + 'a', + array( + 'href' => $app->source_url, + 'class' => 'url' + ) + ); + + if (!empty($app->icon)) { + $this->out->element( + 'img', + array( + 'src' => $app->icon, + 'class' => 'photo avatar' + ) + ); + } + if ($app->name != 'anonymous') { + $this->out->element('span', 'fn', $app->name); + } + $this->out->elementEnd('a'); + + if ($app->name == 'anonymous') { + $this->out->element('span', 'fn', "Unknown application"); + } + + $this->out->elementEnd('span'); + + if ($app->name != 'anonymous') { + // @todo FIXME: i18n trouble. + $this->out->raw(_(' by ')); + + $this->out->element( + 'a', + array( + 'href' => $app->homepage, + 'class' => 'url' + ), + $app->organization + ); + } + + // TRANS: Application access type + $readWriteText = _('read-write'); + // TRANS: Application access type + $readOnlyText = _('read-only'); + + $access = ($this->connection->access_type & Oauth_application::$writeAccess) + ? $readWriteText : $readOnlyText; + $modifiedDate = common_date_string($this->connection->modified); + // TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only") + $txt = sprintf(_('Approved %1$s - "%2$s" access.'), $modifiedDate, $access); + + $this->out->raw(" - $txt"); + if (!empty($app->description)) { + $this->out->element( + 'p', array('class' => 'application_description'), + $app->description + ); + } + $this->out->element( + 'p', array( + 'class' => 'access_token'), + // TRANS: Access token in the application list. + // TRANS: %s are the first 7 characters of the access token. + sprintf(_('Access token starting with: %s'), substr($this->connection->token, 0, 7)) + ); + + $this->out->elementStart( + 'form', + array( + 'id' => 'form_revoke_app', + 'class' => 'form_revoke_app', + 'method' => 'POST', + 'action' => common_local_url('oauthconnectionssettings') + ) + ); + $this->out->elementStart('fieldset'); + $this->out->hidden('oauth_token', $this->connection->token); + $this->out->hidden('token', common_session_token()); + // TRANS: Button label + $this->out->submit('revoke', _m('BUTTON','Revoke')); + $this->out->elementEnd('fieldset'); + $this->out->elementEnd('form'); + + $this->out->elementEnd('li'); + } } diff --git a/lib/common.php b/lib/common.php index 0d60657a3..ca02a3e7f 100644 --- a/lib/common.php +++ b/lib/common.php @@ -33,10 +33,10 @@ try { // XXX: Throw a conniption if database not installed // XXX: Find a way to use htmlwriter for this instead of handcoded markup // TRANS: Error message displayed when no configuration file was found for a StatusNet installation. - echo '<p>'. _('No configuration file found. ') .'</p>'; + echo '<p>'. _('No configuration file found.') .'</p>'; // TRANS: Error message displayed when no configuration file was found for a StatusNet installation. // TRANS: Is followed by a list of directories (separated by HTML breaks). - echo '<p>'. _('I looked for configuration files in the following places: ') .'<br /> '; + echo '<p>'. _('I looked for configuration files in the following places:') .'<br /> '; echo implode($e->configFiles, '<br />'); // TRANS: Error message displayed when no configuration file was found for a StatusNet installation. echo '<p>'. _('You may wish to run the installer to fix this.') .'</p>'; diff --git a/lib/dberroraction.php b/lib/dberroraction.php index 2cb66a022..0a6fce100 100644 --- a/lib/dberroraction.php +++ b/lib/dberroraction.php @@ -47,7 +47,6 @@ require_once INSTALLDIR.'/lib/servererroraction.php'; * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class DBErrorAction extends ServerErrorAction { function __construct($message='Error', $code=500) diff --git a/lib/feed.php b/lib/feed.php index e9fb6fdff..590265367 100644 --- a/lib/feed.php +++ b/lib/feed.php @@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class Feed { const RSS1 = 1; diff --git a/lib/feedlist.php b/lib/feedlist.php index 4aacf0b3d..076576028 100644 --- a/lib/feedlist.php +++ b/lib/feedlist.php @@ -46,7 +46,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * * @see Action::showExportList() */ - class FeedList extends Widget { var $action = null; diff --git a/lib/groupsbymemberssection.php b/lib/groupsbymemberssection.php index 19b35eddb..5cf1a563c 100644 --- a/lib/groupsbymemberssection.php +++ b/lib/groupsbymemberssection.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupsByMembersSection extends GroupSection { function getGroups() @@ -68,6 +67,7 @@ class GroupsByMembersSection extends GroupSection function title() { + // TRANS: Title for groups with the most members section. return _('Groups with most members'); } diff --git a/lib/groupsbypostssection.php b/lib/groupsbypostssection.php index 45d49aba6..50d60e87c 100644 --- a/lib/groupsbypostssection.php +++ b/lib/groupsbypostssection.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupsByPostsSection extends GroupSection { function getGroups() @@ -68,6 +67,7 @@ class GroupsByPostsSection extends GroupSection function title() { + // TRANS: Title for groups with the most posts section. return _('Groups with most posts'); } diff --git a/lib/groupsection.php b/lib/groupsection.php index 3b0b3029d..019b13135 100644 --- a/lib/groupsection.php +++ b/lib/groupsection.php @@ -45,7 +45,6 @@ define('GROUPS_PER_SECTION', 6); * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupSection extends Section { function showContent() diff --git a/lib/grouptagcloudsection.php b/lib/grouptagcloudsection.php index f1106cc7b..5b914c007 100644 --- a/lib/grouptagcloudsection.php +++ b/lib/grouptagcloudsection.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupTagCloudSection extends TagCloudSection { var $group = null; @@ -53,6 +52,8 @@ class GroupTagCloudSection extends TagCloudSection function title() { + // TRANS: Title for group tag cloud section. + // TRANS: %s is a group name. return sprintf(_('Tags in %s group\'s notices'), $this->group->nickname); } diff --git a/lib/mail.php b/lib/mail.php index ab5742e33..30d743848 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -170,19 +170,21 @@ function mail_to_user(&$user, $subject, $body, $headers=array(), $address=null) function mail_confirm_address($user, $code, $nickname, $address) { - // TRANS: Subject for address confirmation email + // TRANS: Subject for address confirmation email. $subject = _('Email address confirmation'); // TRANS: Body for address confirmation email. - $body = sprintf(_("Hey, %s.\n\n". - "Someone just entered this email address on %s.\n\n" . + // TRANS: %1$s is the addressed user's nickname, %2$s is the StatusNet sitename, + // TRANS: %3$s is the URL to confirm at. + $body = sprintf(_("Hey, %1\$s.\n\n". + "Someone just entered this email address on %2\$s.\n\n" . "If it was you, and you want to confirm your entry, ". - "use the URL below:\n\n\t%s\n\n" . + "use the URL below:\n\n\t%3\$s\n\n" . "If not, just ignore this message.\n\n". - "Thanks for your time, \n%s\n"), - $nickname, common_config('site', 'name'), - common_local_url('confirmaddress', array('code' => $code)), - common_config('site', 'name')); + "Thanks for your time, \n%2\$s\n"), + $nickname, + common_config('site', 'name'), + common_local_url('confirmaddress', array('code' => $code))); $headers = array(); return mail_to_user($user, $subject, $body, $headers, $address); @@ -239,41 +241,50 @@ function mail_subscribe_notify_profile($listenee, $other) $headers = _mail_prepare_headers('subscribe', $listenee->nickname, $other->nickname); $headers['From'] = mail_notify_from(); $headers['To'] = $name . ' <' . $listenee->email . '>'; - // TRANS: Subject of new-subscriber notification e-mail + // TRANS: Subject of new-subscriber notification e-mail. + // TRANS: %1$s is the subscribing user's nickname, %2$s is the StatusNet sitename. $headers['Subject'] = sprintf(_('%1$s is now listening to '. 'your notices on %2$s.'), $other->getBestName(), common_config('site', 'name')); + // TRANS: This is a paragraph in a new-subscriber e-mail. + // TRANS: %s is a URL where the subscriber can be reported as abusive. $blocklink = sprintf(_("If you believe this account is being used abusively, " . "you can block them from your subscribers list and " . "report as spam to site administrators at %s"), common_local_url('block', array('profileid' => $other->id))); - // TRANS: Main body of new-subscriber notification e-mail + // TRANS: Main body of new-subscriber notification e-mail. + // TRANS: %1$s is the subscriber's long name, %2$s is the StatusNet sitename, + // TRANS: %3$s is the subscriber's profile URL, %4$s is the subscriber's location (or empty) + // TRANS: %5$s is the subscriber's homepage URL (or empty), %6%s is the subscriber's bio (or empty) + // TRANS: %7$s is a link to the addressed user's e-mail settings. $body = sprintf(_('%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".'Faithfully yours,'."\n".'%2$s.'."\n\n". "----\n". "Change your email address or ". - "notification options at ".'%8$s' ."\n"), + "notification options at ".'%7$s' ."\n"), $long_name, common_config('site', 'name'), $other->profileurl, ($other->location) ? - // TRANS: Profile info line in new-subscriber notification e-mail + // TRANS: Profile info line in new-subscriber notification e-mail. + // TRANS: %s is a location. sprintf(_("Location: %s"), $other->location) . "\n" : '', ($other->homepage) ? - // TRANS: Profile info line in new-subscriber notification e-mail + // TRANS: Profile info line in new-subscriber notification e-mail. + // TRANS: %s is a homepage. sprintf(_("Homepage: %s"), $other->homepage) . "\n" : '', (($other->bio) ? - // TRANS: Profile info line in new-subscriber notification e-mail + // TRANS: Profile info line in new-subscriber notification e-mail. + // TRANS: %s is biographical information. sprintf(_("Bio: %s"), $other->bio) . "\n" : '') . "\n\n" . $blocklink . "\n", - common_config('site', 'name'), common_local_url('emailsettings')); // reset localization @@ -291,7 +302,6 @@ function mail_subscribe_notify_profile($listenee, $other) * * @return void */ - function mail_new_incoming_notify($user) { $profile = $user->getProfile(); @@ -300,19 +310,21 @@ function mail_new_incoming_notify($user) $headers['From'] = $user->incomingemail; $headers['To'] = $name . ' <' . $user->email . '>'; - // TRANS: Subject of notification mail for new posting email address + // TRANS: Subject of notification mail for new posting email address. + // TRANS: %s is the StatusNet sitename. $headers['Subject'] = sprintf(_('New email address for posting to %s'), common_config('site', 'name')); - // TRANS: Body of notification mail for new posting email address + // TRANS: Body of notification mail for new posting email address. + // TRANS: %1$s is the StatusNet sitename, %2$s is the e-mail address to send + // TRANS: to to post by e-mail, %3$s is a URL to more instructions. $body = sprintf(_("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"), + "Faithfully yours,\n%1\$s"), common_config('site', 'name'), $user->incomingemail, - common_local_url('doc', array('title' => 'email')), - common_config('site', 'name')); + common_local_url('doc', array('title' => 'email'))); mail_send($user->email, $headers, $body); } @@ -324,7 +336,6 @@ function mail_new_incoming_notify($user) * * @return string new email address for incoming messages */ - function mail_new_incoming_address() { $prefix = common_confirmation_code(64); @@ -343,7 +354,6 @@ function mail_new_incoming_address() * * @return success flag */ - function mail_broadcast_notice_sms($notice) { // Now, get users subscribed to this profile @@ -395,7 +405,6 @@ function mail_broadcast_notice_sms($notice) * * @return boolean success flag */ - function mail_send_sms_notice($notice, $user) { return mail_send_sms_notice_address($notice, @@ -415,7 +424,6 @@ function mail_send_sms_notice($notice, $user) * * @return boolean success flag */ - function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) { $to = $nickname . ' <' . $smsemail . '>'; @@ -429,7 +437,8 @@ function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) $headers['From'] = ($incomingemail) ? $incomingemail : mail_notify_from(); $headers['To'] = $to; - // TRANS: Subject line for SMS-by-email notification messages + // TRANS: Subject line for SMS-by-email notification messages. + // TRANS: %s is the posting user's nickname. $headers['Subject'] = sprintf(_('%s status'), $other->getBestName()); @@ -449,17 +458,17 @@ function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) * * @return void */ - function mail_confirm_sms($code, $nickname, $address) { $recipients = $address; $headers['From'] = mail_notify_from(); $headers['To'] = $nickname . ' <' . $address . '>'; - // TRANS: Subject line for SMS-by-email address confirmation message + // TRANS: Subject line for SMS-by-email address confirmation message. $headers['Subject'] = _('SMS confirmation'); - // TRANS: Main body heading for SMS-by-email address confirmation message + // TRANS: Main body heading for SMS-by-email address confirmation message. + // TRANS: %s is the addressed user's nickname. $body = sprintf(_("%s: confirm you own this phone number with this code:"), $nickname); $body .= "\n\n"; $body .= $code; @@ -476,16 +485,18 @@ function mail_confirm_sms($code, $nickname, $address) * * @return boolean success flag */ - function mail_notify_nudge($from, $to) { common_switch_locale($to->language); - // TRANS: Subject for 'nudge' notification email + // TRANS: Subject for 'nudge' notification email. + // TRANS: %s is the nudging user. $subject = sprintf(_('You\'ve been nudged by %s'), $from->nickname); $from_profile = $from->getProfile(); - // TRANS: Body for 'nudge' notification email + // TRANS: Body for 'nudge' notification email. + // TRANS: %1$s is the nuding user's long name, $2$s is the nudging user's nickname, + // TRANS: %3$s is a URL to post notices at, %4$s is the StatusNet sitename. $body = sprintf(_("%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". @@ -516,7 +527,6 @@ function mail_notify_nudge($from, $to) * * @return boolean success code */ - function mail_notify_message($message, $from=null, $to=null) { if (is_null($from)) { @@ -532,12 +542,16 @@ function mail_notify_message($message, $from=null, $to=null) } common_switch_locale($to->language); - // TRANS: Subject for direct-message notification email + // TRANS: Subject for direct-message notification email. + // TRANS: %s is the sending user's nickname. $subject = sprintf(_('New private message from %s'), $from->nickname); $from_profile = $from->getProfile(); - // TRANS: Body for direct-message notification email + // TRANS: Body for direct-message notification email. + // TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname, + // TRANS: %3$s is the message content, %4$s a URL to the message, + // TRANS: %5$s is the StatusNet sitename. $body = sprintf(_("%1\$s (%2\$s) sent you a private message:\n\n". "------------------------------------------------------\n". "%3\$s\n". @@ -572,7 +586,6 @@ function mail_notify_message($message, $from=null, $to=null) * * @return void */ - function mail_notify_fave($other, $user, $notice) { if (!$user->hasRight(Right::EMAILONFAVE)) { @@ -585,10 +598,15 @@ function mail_notify_fave($other, $user, $notice) common_switch_locale($other->language); - // TRANS: Subject for favorite notification email - $subject = sprintf(_('%s (@%s) added your notice as a favorite'), $bestname, $user->nickname); + // TRANS: Subject for favorite notification e-mail. + // TRANS: %1$s is the adding user's long name, %2$s is the adding user's nickname. + $subject = sprintf(_('%1$s (@%2$s) added your notice as a favorite'), $bestname, $user->nickname); - // TRANS: Body for favorite notification email + // TRANS: Body for favorite notification e-mail. + // TRANS: %1$s is the adding user's long name, $2$s is the date the notice was created, + // TRANS: %3$s is a URL to the faved notice, %4$s is the faved notice text, + // TRANS: %5$s is a URL to all faves of the adding user, %6$s is the StatusNet sitename, + // TRANS: %7$s is the adding user's nickname. $body = sprintf(_("%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" . @@ -623,7 +641,6 @@ function mail_notify_fave($other, $user, $notice) * * @return void */ - function mail_notify_attn($user, $notice) { if (!$user->email || !$user->emailnotifyattn) { @@ -654,9 +671,16 @@ function mail_notify_attn($user, $notice) $conversationEmailText = ''; } - $subject = sprintf(_('%s (@%s) sent a notice to your attention'), $bestname, $sender->nickname); + // TRANS: E-mail subject for notice notification. + // TRANS: %1$s is the sending user's long name, %2$s is the adding user's nickname. + $subject = sprintf(_('%1$s (@%2$s) sent a notice to your attention'), $bestname, $sender->nickname); // TRANS: Body of @-reply notification e-mail. + // TRANS: %1$s is the sending user's long name, $2$s is the StatusNet sitename, + // TRANS: %3$s is a URL to the notice, %4$s is the notice text, + // TRANS: %5$s is a URL to the full conversion if it exists (otherwise empty), + // TRANS: %6$s is a URL to reply to the notice, %7$s is a URL to all @-replied for the addressed user, + // TRANS: %8$s is a URL to the addressed user's e-mail settings, %9$s is the sender's nickname. $body = sprintf(_("%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" . @@ -709,4 +733,3 @@ function _mail_prepare_headers($msg_type, $to, $from) return $headers; } - diff --git a/lib/router.php b/lib/router.php index 54d3d0f68..32292397e 100644 --- a/lib/router.php +++ b/lib/router.php @@ -34,7 +34,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { require_once 'Net/URL/Mapper.php'; class StatusNet_URL_Mapper extends Net_URL_Mapper { - private static $_singleton = null; private function __construct() @@ -71,7 +70,6 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class Router { var $m = null; @@ -560,11 +558,19 @@ class Router 'format' => '(xml|json)')); // blocks + $m->connect('api/blocks/create.:format', + array('action' => 'ApiBlockCreate', + 'format' => '(xml|json)')); + $m->connect('api/blocks/create/:id.:format', array('action' => 'ApiBlockCreate', 'id' => '[a-zA-Z0-9]+', 'format' => '(xml|json)')); + $m->connect('api/blocks/destroy.:format', + array('action' => 'ApiBlockDestroy', + 'format' => '(xml|json)')); + $m->connect('api/blocks/destroy/:id.:format', array('action' => 'ApiBlockDestroy', 'id' => '[a-zA-Z0-9]+', @@ -704,6 +710,7 @@ class Router $m->connect('admin/sitenotice', array('action' => 'sitenoticeadminpanel')); $m->connect('admin/snapshot', array('action' => 'snapshotadminpanel')); $m->connect('admin/license', array('action' => 'licenseadminpanel')); + $m->connect('admin/plugins', array('action' => 'pluginsadminpanel')); $m->connect('admin/plugins/enable/:plugin', array('action' => 'pluginenable'), @@ -720,16 +727,8 @@ class Router if (common_config('singleuser', 'enabled')) { - $user = User::siteOwner(); - - if (!empty($user)) { - $nickname = $user->nickname; - } else { - $nickname = common_config('singleuser', 'nickname'); - if (empty($nickname)) { - throw new ServerException(_("No single user defined for single-user mode.")); - } - } + $user = User::singleUser(); + $nickname = $user->nickname; foreach (array('subscriptions', 'subscribers', 'all', 'foaf', 'xrds', @@ -784,9 +783,7 @@ class Router $m->connect('', array('action' => 'showstream', 'nickname' => $nickname)); - } else { - $m->connect('', array('action' => 'public')); $m->connect('rss', array('action' => 'publicrss')); $m->connect('featuredrss', array('action' => 'featuredrss')); @@ -867,7 +864,8 @@ class Router } catch (Net_URL_Mapper_InvalidException $e) { common_log(LOG_ERR, "Problem getting route for $path - " . $e->getMessage()); - $cac = new ClientErrorAction("Page not found.", 404); + // TRANS: Client error on action trying to visit a non-existing page. + $cac = new ClientErrorAction(_('Page not found.'), 404); $cac->showPage(); } @@ -894,7 +892,16 @@ class Router if ($qpos !== false) { $url = substr($url, 0, $qpos+1) . str_replace('?', '&', substr($url, $qpos+1)); + + // @fixme this is a hacky workaround for http_build_query in the + // lower-level code and bad configs that set the default separator + // to & instead of &. Encoded &s in parameters will not be + // affected. + $url = substr($url, 0, $qpos+1) . + str_replace('&', '&', substr($url, $qpos+1)); + } + return $url; } } diff --git a/lib/util.php b/lib/util.php index 1d7cffe41..f5077f601 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1002,8 +1002,9 @@ function common_tag_link($tag) $canonical = common_canonical_tag($tag); if (common_config('singleuser', 'enabled')) { // regular TagAction isn't set up in 1user mode + $user = User::singleUser(); $url = common_local_url('showstream', - array('nickname' => common_config('singleuser', 'nickname'), + array('nickname' => $user->nickname, 'tag' => $canonical)); } else { $url = common_local_url('tag', array('tag' => $canonical)); @@ -1107,7 +1108,17 @@ function common_local_url($action, $args=null, $params=null, $fragment=null, $ad function common_is_sensitive($action) { - static $sensitive = array('login', 'register', 'passwordsettings', 'api'); + static $sensitive = array( + 'login', + 'register', + 'passwordsettings', + 'api', + 'ApiOauthRequestToken', + 'ApiOauthAccessToken', + 'ApiOauthAuthorize', + 'ApiOauthPin', + 'showapplication' + ); $ssl = null; if (Event::handle('SensitiveAction', array($action, &$ssl))) { diff --git a/lib/webcolor.php b/lib/webcolor.php index 6fa603fa2..7f264c674 100644 --- a/lib/webcolor.php +++ b/lib/webcolor.php @@ -32,7 +32,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { } class WebColor { - // XXX: Maybe make getters and setters for r,g,b values and tuples, // e.g.: to support this kinda CSS representation: rgb(255,0,0) // http://www.w3.org/TR/CSS21/syndata.html#color-units @@ -65,7 +64,6 @@ class WebColor { * * @return nothing */ - function parseColor($color) { if (is_numeric($color)) { @@ -90,13 +88,11 @@ class WebColor { * * @return nothing */ - function setNamedColor($name) { // XXX Implement this } - /** * Sets the RGB color values from a a hex tuple * @@ -104,7 +100,6 @@ class WebColor { * * @return nothing */ - function setHexColor($hexcolor) { if ($hexcolor[0] == '#') { @@ -120,7 +115,9 @@ class WebColor { $hexcolor[1].$hexcolor[1], $hexcolor[2].$hexcolor[2]); } else { - $errmsg = _('%s is not a valid color! Use 3 or 6 hex chars.'); + // TRANS: Validation error for a web colour. + // TRANS: %s is the provided (invalid) text for colour. + $errmsg = _('%s is not a valid color! Use 3 or 6 hex characters.'); throw new WebColorException(sprintf($errmsg, $hexcolor)); } @@ -137,7 +134,6 @@ class WebColor { * * @return nothing */ - function setIntColor($intcolor) { // We could do 32 bit and have an alpha channel because @@ -154,7 +150,6 @@ class WebColor { * * @return string */ - function hexValue() { $hexcolor = (strlen(dechex($this->red)) < 2 ? '0' : '' ) . @@ -165,7 +160,6 @@ class WebColor { dechex($this->blue); return strtoupper($hexcolor); - } /** @@ -176,7 +170,6 @@ class WebColor { * * @return int */ - function intValue() { $intcolor = 256 * 256 * $this->red + 256 * $this->green + $this->blue; @@ -188,5 +181,3 @@ class WebColor { class WebColorException extends Exception { } - -?>
\ No newline at end of file |