Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x

This commit is contained in:
Evan Prodromou 2009-10-31 14:47:21 -04:00
commit 44ce8e2fcd
42 changed files with 1190 additions and 582 deletions

View File

@ -458,3 +458,19 @@ StartProfileListItemActionElements: Showing the profile list actions (prepend a
EndProfileListItemActionElements: Showing profile list actions (append a button here) EndProfileListItemActionElements: Showing profile list actions (append a button here)
- $item: ProfileListItem widget - $item: ProfileListItem widget
StartUserXRDS: Start XRDS output (right after the opening XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to
EndUserXRDS: End XRDS output (right before the closing XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to
StartPublicXRDS: Start XRDS output (right after the opening XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to
EndPublicXRDS: End XRDS output (right before the closing XRDS tag)
- $action: the current action
- &$xrdsoutputter - XRDSOutputter object to write to

View File

@ -99,19 +99,17 @@ class AllAction extends ProfileAction
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)), sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
new Feed(Feed::RSS2, new Feed(Feed::RSS2,
common_local_url( common_local_url(
'api', array( 'ApiTimelineFriends', array(
'apiaction' => 'statuses', 'format' => 'rss',
'method' => 'friends_timeline', 'id' => $this->user->nickname
'argument' => $this->user->nickname.'.rss'
) )
), ),
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)), sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
new Feed(Feed::ATOM, new Feed(Feed::ATOM,
common_local_url( common_local_url(
'api', array( 'ApiTimelineFriends', array(
'apiaction' => 'statuses', 'format' => 'atom',
'method' => 'friends_timeline', 'id' => $this->user->nickname
'argument' => $this->user->nickname.'.atom'
) )
), ),
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname)) sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname))

View File

@ -99,7 +99,9 @@ class NewmessageAction extends Action
$user = common_current_user(); $user = common_current_user();
if (!$user) { if (!$user) {
$this->clientError(_('Only logged-in users can send direct messages.'), 403); /* Go log in, and then come back. */
common_set_returnto($_SERVER['REQUEST_URI']);
common_redirect(common_local_url('login'));
return false; return false;
} }
@ -221,7 +223,22 @@ class NewmessageAction extends Action
} }
$this->msg = $msg; $this->msg = $msg;
$this->showPage(); if ($this->trimmed('ajax')) {
$this->startHTML('text/xml;charset=UTF-8');
$this->elementStart('head');
$this->element('title', null, _('New message'));
$this->elementEnd('head');
$this->elementStart('body');
if (common_logged_in()) {
$this->showNoticeForm();
}
$this->elementEnd('div');
$this->elementEnd('body');
$this->endHTML();
}
else {
$this->showPage();
}
} }
function showPageNotice() function showPageNotice()

View File

@ -131,6 +131,13 @@ class PublicAction extends Action
return _('Public timeline'); return _('Public timeline');
} }
} }
function extraHead()
{
parent::extraHead();
$this->element('meta', array('http-equiv' => 'X-XRDS-Location',
'content' => common_local_url('publicxrds')));
}
/** /**
* Output <head> elements for RSS and Atom feeds * Output <head> elements for RSS and Atom feeds
@ -143,14 +150,12 @@ class PublicAction extends Action
return array(new Feed(Feed::RSS1, common_local_url('publicrss'), return array(new Feed(Feed::RSS1, common_local_url('publicrss'),
_('Public Stream Feed (RSS 1.0)')), _('Public Stream Feed (RSS 1.0)')),
new Feed(Feed::RSS2, new Feed(Feed::RSS2,
common_local_url('api', common_local_url('ApiTimelinePublic',
array('apiaction' => 'statuses', array('format' => 'rss')),
'method' => 'public_timeline.rss')),
_('Public Stream Feed (RSS 2.0)')), _('Public Stream Feed (RSS 2.0)')),
new Feed(Feed::ATOM, new Feed(Feed::ATOM,
common_local_url('api', common_local_url('ApiTimelinePublic',
array('apiaction' => 'statuses', array('format' => 'atom')),
'method' => 'public_timeline.atom')),
_('Public Stream Feed (Atom)'))); _('Public Stream Feed (Atom)')));
} }

81
actions/publicxrds.php Normal file
View File

@ -0,0 +1,81 @@
<?php
/**
* Public XRDS for OpenID
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once INSTALLDIR.'/lib/xrdsoutputter.php';
/**
* Public XRDS
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @author Craig Andrews <candrews@integralblue.com>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* @todo factor out similarities with XrdsAction
*/
class PublicxrdsAction extends Action
{
/**
* Is read only?
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* Class handler.
*
* @param array $args array of arguments
*
* @return nothing
*/
function handle($args)
{
parent::handle($args);
$xrdsOutputter = new XRDSOutputter();
$xrdsOutputter->startXRDS();
Event::handle('StartPublicXRDS', array($this,&$xrdsOutputter));
Event::handle('EndPublicXRDS', array($this,&$xrdsOutputter));
$xrdsOutputter->endXRDS();
}
}

View File

@ -138,11 +138,25 @@ class RepliesAction extends OwnerDesignAction
function getFeeds() function getFeeds()
{ {
$rssurl = common_local_url('repliesrss', return array(new Feed(Feed::RSS1,
array('nickname' => $this->user->nickname)); common_local_url('repliesrss',
$rsstitle = sprintf(_('Feed for replies to %s'), $this->user->nickname); array('nickname' => $this->user->nickname)),
sprintf(_('Replies feed for %s (RSS 1.0)'),
return array(new Feed(Feed::RSS1, $rssurl, $rsstitle)); $this->user->nickname)),
new Feed(Feed::RSS2,
common_local_url('ApiTimelineMentions',
array(
'id' => $this->user->nickname,
'format' => 'rss')),
sprintf(_('Replies feed for %s (RSS 2.0)'),
$this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('ApiTimelineMentions',
array(
'id' => $this->user->nickname,
'format' => 'atom')),
sprintf(_('Replies feed for %s (Atom)'),
$this->user->nickname)));
} }
/** /**

View File

@ -164,13 +164,25 @@ class ShowfavoritesAction extends OwnerDesignAction
function getFeeds() function getFeeds()
{ {
$feedurl = common_local_url('favoritesrss', return array(new Feed(Feed::RSS1,
array('nickname' => common_local_url('favoritesrss',
$this->user->nickname)); array('nickname' => $this->user->nickname)),
$feedtitle = sprintf(_('Feed for favorites of %s'), sprintf(_('Feed for favorites of %s (RSS 1.0)'),
$this->user->nickname); $this->user->nickname)),
new Feed(Feed::RSS2,
return array(new Feed(Feed::RSS1, $feedurl, $feedtitle)); common_local_url('ApiTimelineFavorites',
array(
'id' => $this->user->nickname,
'format' => 'rss')),
sprintf(_('Feed for favorites of %s (RSS 2.0)'),
$this->user->nickname)),
new Feed(Feed::ATOM,
common_local_url('ApiTimelineFavorites',
array(
'id' => $this->user->nickname,
'format' => 'atom')),
sprintf(_('Feed for favorites of %s (Atom)'),
$this->user->nickname)));
} }
/** /**

View File

@ -328,17 +328,15 @@ class ShowgroupAction extends GroupDesignAction
sprintf(_('Notice feed for %s group (RSS 1.0)'), sprintf(_('Notice feed for %s group (RSS 1.0)'),
$this->group->nickname)), $this->group->nickname)),
new Feed(Feed::RSS2, new Feed(Feed::RSS2,
common_local_url('api', common_local_url('ApiTimelineGroup',
array('apiaction' => 'groups', array('format' => 'rss',
'method' => 'timeline', 'id' => $this->group->nickname)),
'argument' => $this->group->nickname.'.rss')),
sprintf(_('Notice feed for %s group (RSS 2.0)'), sprintf(_('Notice feed for %s group (RSS 2.0)'),
$this->group->nickname)), $this->group->nickname)),
new Feed(Feed::ATOM, new Feed(Feed::ATOM,
common_local_url('api', common_local_url('ApiTimelineGroup',
array('apiaction' => 'groups', array('format' => 'atom',
'method' => 'timeline', 'id' => $this->group->nickname)),
'argument' => $this->group->nickname.'.atom')),
sprintf(_('Notice feed for %s group (Atom)'), sprintf(_('Notice feed for %s group (Atom)'),
$this->group->nickname)), $this->group->nickname)),
new Feed(Feed::FOAF, new Feed(Feed::FOAF,

View File

@ -172,9 +172,9 @@ class ShownoticeAction extends OwnerDesignAction
function title() function title()
{ {
if (!empty($this->profile->fullname)) { if (!empty($this->profile->fullname)) {
$base = $this->profile->fullname . ' (' . $this->user->nickname . ') '; $base = $this->profile->fullname . ' (' . $this->profile->nickname . ') ';
} else { } else {
$base = $this->user->nickname; $base = $this->profile->nickname;
} }
return sprintf(_('%1$s\'s status on %2$s'), return sprintf(_('%1$s\'s status on %2$s'),

View File

@ -128,17 +128,17 @@ class ShowstreamAction extends ProfileAction
sprintf(_('Notice feed for %s (RSS 1.0)'), sprintf(_('Notice feed for %s (RSS 1.0)'),
$this->user->nickname)), $this->user->nickname)),
new Feed(Feed::RSS2, new Feed(Feed::RSS2,
common_local_url('api', common_local_url('ApiTimelineUser',
array('apiaction' => 'statuses', array(
'method' => 'user_timeline', 'id' => $this->user->nickname,
'argument' => $this->user->nickname.'.rss')), 'format' => 'rss')),
sprintf(_('Notice feed for %s (RSS 2.0)'), sprintf(_('Notice feed for %s (RSS 2.0)'),
$this->user->nickname)), $this->user->nickname)),
new Feed(Feed::ATOM, new Feed(Feed::ATOM,
common_local_url('api', common_local_url('ApiTimelineUser',
array('apiaction' => 'statuses', array(
'method' => 'user_timeline', 'id' => $this->user->nickname,
'argument' => $this->user->nickname.'.atom')), 'format' => 'atom')),
sprintf(_('Notice feed for %s (Atom)'), sprintf(_('Notice feed for %s (Atom)'),
$this->user->nickname)), $this->user->nickname)),
new Feed(Feed::FOAF, new Feed(Feed::FOAF,

View File

@ -86,17 +86,15 @@ class TagAction extends Action
sprintf(_('Notice feed for tag %s (RSS 1.0)'), sprintf(_('Notice feed for tag %s (RSS 1.0)'),
$this->tag)), $this->tag)),
new Feed(Feed::RSS2, new Feed(Feed::RSS2,
common_local_url('api', common_local_url('ApiTimelineTag',
array('apiaction' => 'tags', array('format' => 'rss',
'method' => 'timeline', 'tag' => $this->tag)),
'argument' => $this->tag.'.rss')), sprintf(_('Notice feed for tag %s (RSS 2.0)'),
sprintf(_('Notice feed for %s group (RSS 2.0)'),
$this->tag)), $this->tag)),
new Feed(Feed::ATOM, new Feed(Feed::ATOM,
common_local_url('api', common_local_url('ApiTimelineTag',
array('apiaction' => 'tags', array('format' => 'atom',
'method' => 'timeline', 'tag' => $this->tag)),
'argument' => $this->tag.'.atom')),
sprintf(_('Notice feed for tag %s (Atom)'), sprintf(_('Notice feed for tag %s (Atom)'),
$this->tag))); $this->tag)));
} }

View File

@ -36,6 +36,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
require_once INSTALLDIR.'/lib/omb.php'; require_once INSTALLDIR.'/lib/omb.php';
require_once INSTALLDIR.'/extlib/libomb/service_provider.php'; require_once INSTALLDIR.'/extlib/libomb/service_provider.php';
require_once INSTALLDIR.'/extlib/libomb/xrds_mapper.php'; require_once INSTALLDIR.'/extlib/libomb/xrds_mapper.php';
require_once INSTALLDIR.'/lib/xrdsoutputter.php';
/** /**
* XRDS for OpenMicroBlogging * XRDS for OpenMicroBlogging
@ -49,6 +50,8 @@ require_once INSTALLDIR.'/extlib/libomb/xrds_mapper.php';
*/ */
class XrdsAction extends Action class XrdsAction extends Action
{ {
var $user;
/** /**
* Is read only? * Is read only?
* *
@ -58,6 +61,18 @@ class XrdsAction extends Action
{ {
return true; return true;
} }
function prepare($args)
{
parent::prepare($args);
$nickname = $this->trimmed('nickname');
$this->user = User::staticGet('nickname', $nickname);
if (!$this->user) {
$this->clientError(_('No such user.'));
return;
}
return true;
}
/** /**
* Class handler. * Class handler.
@ -69,49 +84,64 @@ class XrdsAction extends Action
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
$nickname = $this->trimmed('nickname'); $xrdsOutputter = new XRDSOutputter();
$user = User::staticGet('nickname', $nickname); $xrdsOutputter->startXRDS();
if (!$user) {
$this->clientError(_('No such user.'));
return;
}
$this->showXrds($user);
}
/** Event::handle('StartUserXRDS', array($this,&$xrdsOutputter));
* Show XRDS for a user.
*
* @param class $user XRDS for this user.
*
* @return void
*/
function showXrds($user)
{
$srv = new OMB_Service_Provider(profile_to_omb_profile($user->uri,
$user->getProfile()));
/* Use libombs default XRDS Writer. */
$xrds_writer = null;
$srv->writeXRDS(new Laconica_XRDS_Mapper(), $xrds_writer);
}
}
class Laconica_XRDS_Mapper implements OMB_XRDS_Mapper //oauth
{ $xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
protected $urls; 'xml:id' => 'oauth',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
$xrdsOutputter->showXrdsService(OAUTH_ENDPOINT_REQUEST,
common_local_url('requesttoken'),
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1));
$xrdsOutputter->showXrdsService( OAUTH_ENDPOINT_AUTHORIZE,
common_local_url('userauthorization'),
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1),
null,
$this->user->getIdentifierURI());
$xrdsOutputter->showXrdsService(OAUTH_ENDPOINT_ACCESS,
common_local_url('accesstoken'),
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1),
null,
$this->user->getIdentifierURI());
$xrdsOutputter->showXrdsService(OAUTH_ENDPOINT_RESOURCE,
null,
array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY, OAUTH_HMAC_SHA1),
null,
$this->user->getIdentifierURI());
$xrdsOutputter->elementEnd('XRD');
//omb
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'oauth',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
$xrdsOutputter->showXrdsService(OMB_ENDPOINT_POSTNOTICE,
common_local_url('postnotice'));
$xrdsOutputter->showXrdsService(OMB_ENDPOINT_UPDATEPROFILE,
common_local_url('updateprofile'));
$xrdsOutputter->elementEnd('XRD');
//misc
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'oauth',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->showXrdsService(OAUTH_DISCOVERY,
'#oauth');
$xrdsOutputter->showXrdsService(OMB_VERSION,
'#omb');
$xrdsOutputter->elementEnd('XRD');
public function __construct() Event::handle('EndUserXRDS', array($this,&$xrdsOutputter));
{
$this->urls = array(
OAUTH_ENDPOINT_REQUEST => 'requesttoken',
OAUTH_ENDPOINT_AUTHORIZE => 'userauthorization',
OAUTH_ENDPOINT_ACCESS => 'accesstoken',
OMB_ENDPOINT_POSTNOTICE => 'postnotice',
OMB_ENDPOINT_UPDATEPROFILE => 'updateprofile');
}
public function getURL($action) $xrdsOutputter->endXRDS();
{
return common_local_url($this->urls[$action]);
} }
} }
?> ?>

View File

@ -1181,10 +1181,9 @@ class Notice extends Memcached_DataObject
$xs->element('link', array('href' => $profile->profileurl)); $xs->element('link', array('href' => $profile->profileurl));
$user = User::staticGet('id', $profile->id); $user = User::staticGet('id', $profile->id);
if (!empty($user)) { if (!empty($user)) {
$atom_feed = common_local_url('api', $atom_feed = common_local_url('ApiTimelineUser',
array('apiaction' => 'statuses', array('format' => 'atom',
'method' => 'user_timeline', 'id' => $profile->nickname));
'argument' => $profile->nickname.'.atom'));
$xs->element('link', array('rel' => 'self', $xs->element('link', array('rel' => 'self',
'type' => 'application/atom+xml', 'type' => 'application/atom+xml',
'href' => $profile->profileurl)); 'href' => $profile->profileurl));

View File

@ -537,6 +537,16 @@ modified = 384
canonical = K canonical = K
display = U display = U
[user_openid_trustroot]
trustroot = 130
user_id = 129
created = 142
modified = 384
[user_openid__keys]
trustroot = K
user_id = K
[user_role] [user_role]
user_id = 129 user_id = 129
role = 130 role = 130

View File

@ -20,7 +20,7 @@
/** /**
* The library version string * The library version string
*/ */
define('Auth_OpenID_VERSION', '2.1.2'); define('Auth_OpenID_VERSION', '2.1.3');
/** /**
* Require the fetcher code. * Require the fetcher code.

View File

@ -376,7 +376,7 @@ function Auth_OpenID_detectMathLibrary($exts)
// Try to load dynamic modules. // Try to load dynamic modules.
if (!$loaded) { if (!$loaded) {
foreach ($extension['modules'] as $module) { foreach ($extension['modules'] as $module) {
if (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode') && @dl($module . "." . PHP_SHLIB_SUFFIX)) { if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
$loaded = true; $loaded = true;
break; break;
} }

View File

@ -1295,7 +1295,8 @@ class Auth_OpenID_GenericConsumer {
Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields, Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields,
array('response_nonce', array('response_nonce',
'claimed_id', 'claimed_id',
'assoc_handle')), 'assoc_handle',
'op_endpoint')),
Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields, Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields,
array('nonce')) array('nonce'))
); );

View File

@ -887,6 +887,11 @@ class Auth_OpenID_Message {
function getAliasedArg($aliased_key, $default = null) function getAliasedArg($aliased_key, $default = null)
{ {
if ($aliased_key == 'ns') {
// Return the namespace URI for the OpenID namespace
return $this->getOpenIDNamespace();
}
$parts = explode('.', $aliased_key, 2); $parts = explode('.', $aliased_key, 2);
if (count($parts) != 2) { if (count($parts) != 2) {

View File

@ -138,7 +138,7 @@ class Auth_Yadis_HTTPFetcher {
* pass the URLHasAllowedScheme check or if the server's response * pass the URLHasAllowedScheme check or if the server's response
* is malformed. * is malformed.
*/ */
function get($url, $headers) function get($url, $headers = null)
{ {
trigger_error("not implemented", E_USER_ERROR); trigger_error("not implemented", E_USER_ERROR);
} }

View File

@ -127,8 +127,6 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
Auth_OpenID_USER_AGENT.' '.$curl_user_agent); Auth_OpenID_USER_AGENT.' '.$curl_user_agent);
curl_setopt($c, CURLOPT_TIMEOUT, $off); curl_setopt($c, CURLOPT_TIMEOUT, $off);
curl_setopt($c, CURLOPT_URL, $url); curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RANGE,
"0-".(1024 * Auth_OpenID_FETCHER_MAX_RESPONSE_KB));
curl_exec($c); curl_exec($c);

View File

@ -83,8 +83,6 @@ class Auth_Yadis_PlainHTTPFetcher extends Auth_Yadis_HTTPFetcher {
"User-Agent: $user_agent", "User-Agent: $user_agent",
"Host: ".$parts['host']. "Host: ".$parts['host'].
($specify_port ? ":".$parts['port'] : ""), ($specify_port ? ":".$parts['port'] : ""),
"Range: 0-".
(1024*Auth_OpenID_FETCHER_MAX_RESPONSE_KB),
"Port: ".$parts['port']); "Port: ".$parts['port']);
$errno = 0; $errno = 0;

View File

@ -91,7 +91,7 @@ class Auth_Yadis_XMLParser {
* @return array $node_list An array of matching opaque node * @return array $node_list An array of matching opaque node
* objects to be used with other methods of this parser class. * objects to be used with other methods of this parser class.
*/ */
function evalXPath($xpath, $node = null) function &evalXPath($xpath, $node = null)
{ {
// Not implemented. // Not implemented.
} }
@ -349,7 +349,7 @@ function &Auth_Yadis_getXMLParser()
foreach ($extensions as $name => $params) { foreach ($extensions as $name => $params) {
if (!extension_loaded($name)) { if (!extension_loaded($name)) {
foreach ($params['libname'] as $libname) { foreach ($params['libname'] as $libname) {
if (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode') && @dl($libname)) { if (@dl($libname)) {
$classname = $params['classname']; $classname = $params['classname'];
} }
} }

View File

@ -143,7 +143,7 @@ function checkMirror($action_obj, $args)
function isLoginAction($action) function isLoginAction($action)
{ {
static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register'); static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds');
$login = null; $login = null;

View File

@ -692,9 +692,7 @@ function writeConf($sitename, $server, $path, $fancy, $db)
// database // database
"\$config['db']['database'] = '{$db['database']}';\n\n". "\$config['db']['database'] = '{$db['database']}';\n\n".
($db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":''). ($db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
"\$config['db']['type'] = '{$db['type']}';\n\n". "\$config['db']['type'] = '{$db['type']}';\n\n";
"?>";
// write configuration file out to install directory // write configuration file out to install directory
$res = file_put_contents(INSTALLDIR.'/config.php', $cfg); $res = file_put_contents(INSTALLDIR.'/config.php', $cfg);

View File

@ -14,373 +14,377 @@
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category UI interaction
* @package StatusNet
* @author Sarven Capadisli <csarven@status.net>
* @author Evan Prodromou <evan@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/ */
$(document).ready(function(){ $(document).ready(function(){
var counterBlackout = false; if ($('body.user_in').length > 0) {
$('.'+SN.C.S.FormNotice).each(function() { SN.U.FormNoticeEnhancements($(this)); });
// count character on keyup
function counter(event){
if (maxLength <= 0) {
return;
}
var currentLength = $("#notice_data-text").val().length;
var remaining = maxLength - currentLength;
var counter = $("#notice_text-count");
if (remaining.toString() != counter.text()) {
if (!counterBlackout || remaining == 0) {
if (counter.text() != String(remaining)) {
counter.text(remaining);
}
if (remaining < 0) { $('.form_user_subscribe').each(function() { SN.U.FormXHR($(this)); });
$("#form_notice").addClass("warning"); $('.form_user_unsubscribe').each(function() { SN.U.FormXHR($(this)); });
} else { $('.form_favor').each(function() { SN.U.FormXHR($(this)); });
$("#form_notice").removeClass("warning"); $('.form_disfavor').each(function() { SN.U.FormXHR($(this)); });
} $('.form_group_join').each(function() { SN.U.FormXHR($(this)); });
// Skip updates for the next 500ms. $('.form_group_leave').each(function() { SN.U.FormXHR($(this)); });
// On slower hardware, updating on every keypress is unpleasant. $('.form_user_nudge').each(function() { SN.U.FormXHR($(this)); });
if (!counterBlackout) {
counterBlackout = true;
window.setTimeout(clearCounterBlackout, 500);
}
}
}
}
function clearCounterBlackout() {
// Allow keyup events to poke the counter again
counterBlackout = false;
// Check if the string changed since we last looked
counter(null);
}
function submitonreturn(event) { SN.U.NoticeReply();
if (event.keyCode == 13 || event.keyCode == 10) {
// iPhone sends \n not \r for 'return'
$("#form_notice").submit();
event.preventDefault();
event.stopPropagation();
$("#notice_data-text").blur();
$("body").focus();
return false;
}
return true;
}
// define maxLength if it wasn't defined already SN.U.NoticeDataAttach();
if (typeof(maxLength) == "undefined") { SN.U.NewDirectMessage();
maxLength = 140;
} }
if ($("#notice_data-text").length) { SN.U.NoticeAttachments();
if (maxLength > 0) {
$("#notice_data-text").bind("keyup", counter);
// run once in case there's something in there
counter();
}
$("#notice_data-text").bind("keydown", submitonreturn);
if($('body')[0].id != 'conversation') {
$("#notice_data-text").focus();
}
}
// XXX: refactor this code
var favoptions = { dataType: 'xml',
beforeSubmit: function(data, target, options) {
$(target).addClass('processing');
return true;
},
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var dis = new_form.id;
var fav = dis.replace('disfavor', 'favor');
$('form#'+fav).replaceWith(new_form);
$('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden);
}
};
var disoptions = { dataType: 'xml',
beforeSubmit: function(data, target, options) {
$(target).addClass('processing');
return true;
},
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var fav = new_form.id;
var dis = fav.replace('favor', 'disfavor');
$('form#'+dis).replaceWith(new_form);
$('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden);
}
};
var joinoptions = { dataType: 'xml',
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var leave = new_form.id;
var join = leave.replace('leave', 'join');
$('form#'+join).replaceWith(new_form);
$('form#'+leave).ajaxForm(leaveoptions).each(addAjaxHidden);
}
};
var leaveoptions = { dataType: 'xml',
success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
var join = new_form.id;
var leave = join.replace('join', 'leave');
$('form#'+leave).replaceWith(new_form);
$('form#'+join).ajaxForm(joinoptions).each(addAjaxHidden);
}
};
function addAjaxHidden() {
var ajax = document.createElement('input');
ajax.setAttribute('type', 'hidden');
ajax.setAttribute('name', 'ajax');
ajax.setAttribute('value', 1);
this.appendChild(ajax);
}
$("form.form_favor").ajaxForm(favoptions);
$("form.form_disfavor").ajaxForm(disoptions);
$("form.form_group_join").ajaxForm(joinoptions);
$("form.form_group_leave").ajaxForm(leaveoptions);
$("form.form_favor").each(addAjaxHidden);
$("form.form_disfavor").each(addAjaxHidden);
$("form.form_group_join").each(addAjaxHidden);
$("form.form_group_leave").each(addAjaxHidden);
$("#form_user_nudge").ajaxForm ({ dataType: 'xml',
beforeSubmit: function(xml) { $("#form_user_nudge input[type=submit]").attr("disabled", "disabled");
$("#form_user_nudge input[type=submit]").addClass("disabled");
},
success: function(xml) { $("#form_user_nudge").replaceWith(document._importNode($("#nudge_response", xml).get(0),true));
$("#form_user_nudge input[type=submit]").removeAttr("disabled");
$("#form_user_nudge input[type=submit]").removeClass("disabled");
}
});
$("#form_user_nudge").each(addAjaxHidden);
var Subscribe = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { $(".form_user_subscribe input[type=submit]").attr("disabled", "disabled");
$(".form_user_subscribe input[type=submit]").addClass("disabled");
},
success: function(xml) { var form_unsubscribe = document._importNode($('form', xml).get(0), true);
var form_unsubscribe_id = form_unsubscribe.id;
var form_subscribe_id = form_unsubscribe_id.replace('unsubscribe', 'subscribe');
$("form#"+form_subscribe_id).replaceWith(form_unsubscribe);
$("form#"+form_unsubscribe_id).ajaxForm(UnSubscribe).each(addAjaxHidden);
$("dd.subscribers").text(parseInt($("dd.subscribers").text())+1);
$(".form_user_subscribe input[type=submit]").removeAttr("disabled");
$(".form_user_subscribe input[type=submit]").removeClass("disabled");
}
};
var UnSubscribe = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { $(".form_user_unsubscribe input[type=submit]").attr("disabled", "disabled");
$(".form_user_unsubscribe input[type=submit]").addClass("disabled");
},
success: function(xml) { var form_subscribe = document._importNode($('form', xml).get(0), true);
var form_subscribe_id = form_subscribe.id;
var form_unsubscribe_id = form_subscribe_id.replace('subscribe', 'unsubscribe');
$("form#"+form_unsubscribe_id).replaceWith(form_subscribe);
$("form#"+form_subscribe_id).ajaxForm(Subscribe).each(addAjaxHidden);
$("#profile_send_a_new_message").remove();
$("#profile_nudge").remove();
$("dd.subscribers").text(parseInt($("dd.subscribers").text())-1);
$(".form_user_unsubscribe input[type=submit]").removeAttr("disabled");
$(".form_user_unsubscribe input[type=submit]").removeClass("disabled");
}
};
$(".form_user_subscribe").ajaxForm(Subscribe);
$(".form_user_unsubscribe").ajaxForm(UnSubscribe);
$(".form_user_subscribe").each(addAjaxHidden);
$(".form_user_unsubscribe").each(addAjaxHidden);
var PostNotice = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { if ($("#notice_data-text").get(0).value.length == 0) {
$("#form_notice").addClass("warning");
return false;
}
$("#form_notice").addClass("processing");
$("#notice_action-submit").attr("disabled", "disabled");
$("#notice_action-submit").addClass("disabled");
return true;
},
timeout: '60000',
error: function (xhr, textStatus, errorThrown) { $("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
if (textStatus == "timeout") {
alert ("Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists");
}
else {
if ($(".error", xhr.responseXML).length > 0) {
$('#form_notice').append(document._importNode($(".error", xhr.responseXML).get(0), true));
}
else {
var HTTP20x30x = [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307];
if(jQuery.inArray(parseInt(xhr.status), HTTP20x30x) < 0) {
alert("Sorry! We had trouble sending your notice ("+xhr.status+" "+xhr.statusText+"). Please report the problem to the site administrator if this happens again.");
}
else {
$("#notice_data-text").val("");
if (maxLength > 0) {
counter();
}
}
}
}
},
success: function(xml) { if ($("#error", xml).length > 0) {
var result = document._importNode($("p", xml).get(0), true);
result = result.textContent || result.innerHTML;
alert(result);
}
else {
if($('body')[0].id == 'bookmarklet') {
self.close();
}
if ($("#command_result", xml).length > 0) {
var result = document._importNode($("p", xml).get(0), true);
result = result.textContent || result.innerHTML;
alert(result);
}
else {
li = $("li", xml).get(0);
if ($("#"+li.id).length == 0) {
var notice_irt_value = $('#notice_in-reply-to').val();
var notice_irt = '#notices_primary #notice-'+notice_irt_value;
if($('body')[0].id == 'conversation') {
if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) {
$(notice_irt).append('<ul class="notices"></ul>');
}
$($(notice_irt+' .notices')[0]).append(document._importNode(li, true));
}
else {
$("#notices_primary .notices").prepend(document._importNode(li, true));
}
$('#'+li.id).css({display:'none'});
$('#'+li.id).fadeIn(2500);
NoticeReply();
NoticeAttachments();
}
}
$("#notice_data-text").val("");
$("#notice_data-attach").val("");
$("#notice_in-reply-to").val("");
$('#notice_data-attach_selected').remove();
if (maxLength > 0) {
counter();
}
}
$("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
}
};
$("#form_notice").ajaxForm(PostNotice);
$("#form_notice").each(addAjaxHidden);
NoticeReply();
NoticeAttachments();
NoticeDataAttach();
}); });
function NoticeReply() {
if ($('#notice_data-text').length > 0 && $('#content .notice_reply').length > 0) { var SN = { // StatusNet
$('#content .notice').each(function() { C: { // Config
var notice = $(this)[0]; I: { // Init
$($('.notice_reply', notice)[0]).click(function() { CounterBlackout: false,
var nickname = ($('.author .nickname', notice).length > 0) ? $($('.author .nickname', notice)[0]) : $('.author .nickname.uid'); MaxLength: 140,
NoticeReplySet(nickname.text(), $($('.notice_id', notice)[0]).text()); PatternUsername: /^[0-9a-zA-Z\-_.]*$/,
HTTP20x30x: [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307]
},
S: { // Selector
Disabled: 'disabled',
Warning: 'warning',
Error: 'error',
Success: 'success',
Processing: 'processing',
CommandResult: 'command_result',
FormNotice: 'form_notice',
NoticeDataText: 'notice_data-text',
NoticeTextCount: 'notice_text-count',
NoticeInReplyTo: 'notice_in-reply-to',
NoticeDataAttach: 'notice_data-attach',
NoticeDataAttachSelected: 'notice_data-attach_selected',
NoticeActionSubmit: 'notice_action-submit'
}
},
U: { // Utils
FormNoticeEnhancements: function(form) {
form_id = form.attr('id');
if (maxLength > 0) {
$('#'+form_id+' #'+SN.C.S.NoticeDataText).bind('keyup', function(e) {
SN.U.Counter(form);
});
// run once in case there's something in there
SN.U.Counter(form);
}
$('#'+form_id+' #'+SN.C.S.NoticeDataText).bind('keydown', function(e) {
SN.U.SubmitOnReturn(e, form);
});
if($('body')[0].id != 'conversation') {
$('#'+form_id+' textarea').focus();
}
SN.U.FormNoticeXHR(form);
},
SubmitOnReturn: function(event, el) {
if (event.keyCode == 13 || event.keyCode == 10) {
el.submit();
event.preventDefault();
event.stopPropagation();
$('#'+el[0].id+' #'+SN.U.NoticeDataText).blur();
$('body').focus();
return false;
}
return true;
},
Counter: function(form) {
SN.C.I.FormNoticeCurrent = form;
form_id = form.attr('id');
if (typeof(maxLength) == "undefined") {
maxLength = SN.C.I.MaxLength;
}
if (maxLength <= 0) {
return;
}
var remaining = maxLength - $('#'+form_id+' #'+SN.C.S.NoticeDataText).val().length;
var counter = $('#'+form_id+' #'+SN.C.S.NoticeTextCount);
if (remaining.toString() != counter.text()) {
if (!SN.C.I.CounterBlackout || remaining == 0) {
if (counter.text() != String(remaining)) {
counter.text(remaining);
}
if (remaining < 0) {
form.addClass(SN.C.S.Warning);
} else {
form.removeClass(SN.C.S.Warning);
}
// Skip updates for the next 500ms.
// On slower hardware, updating on every keypress is unpleasant.
if (!SN.C.I.CounterBlackout) {
SN.C.I.CounterBlackout = true;
SN.C.I.FormNoticeCurrent = form;
window.setTimeout("SN.U.ClearCounterBlackout(SN.C.I.FormNoticeCurrent);", 500);
}
}
}
},
ClearCounterBlackout: function(form) {
// Allow keyup events to poke the counter again
SN.C.I.CounterBlackout = false;
// Check if the string changed since we last looked
SN.U.Counter(form);
},
FormXHR: function(f) {
f.bind('submit', function(e) {
form_id = $(this)[0].id;
$.ajax({
type: 'POST',
dataType: 'xml',
url: $(this)[0].action,
data: $(this).serialize() + '&ajax=1',
beforeSend: function(xhr) {
$('#'+form_id).addClass(SN.C.S.Processing);
$('#'+form_id+' .submit').addClass(SN.C.S.Disabled);
$('#'+form_id+' .submit').attr(SN.C.S.Disabled, SN.C.S.Disabled);
},
error: function (xhr, textStatus, errorThrown) {
alert(errorThrown || textStatus);
},
success: function(data, textStatus) {
if (typeof($('form', data)[0]) != 'undefined') {
form_new = document._importNode($('form', data)[0], true);
$('#'+form_id).replaceWith(form_new);
$('#'+form_new.id).each(function() { SN.U.FormXHR($(this)); });
}
else {
$('#'+form_id).replaceWith(document._importNode($('p', data)[0], true));
}
}
});
return false; return false;
}); });
}); },
FormNoticeXHR: function(form) {
form_id = form.attr('id');
form.append('<input type="hidden" name="ajax" value="1"/>');
form.ajaxForm({
dataType: 'xml',
timeout: '60000',
beforeSend: function(xhr) {
if ($('#'+form_id+' #'+SN.C.S.NoticeDataText)[0].value.length === 0) {
form.addClass(SN.C.S.Warning);
return false;
}
form.addClass(SN.C.S.Processing);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).addClass(SN.C.S.Disabled);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).attr(SN.C.S.Disabled, SN.C.S.Disabled);
return true;
},
error: function (xhr, textStatus, errorThrown) {
form.removeClass(SN.C.S.Processing);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeClass(SN.C.S.Disabled);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeAttr(SN.C.S.Disabled, SN.C.S.Disabled);
if (textStatus == 'timeout') {
alert ('Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists');
}
else {
if ($('.'+SN.C.S.Error, xhr.responseXML).length > 0) {
form.append(document._importNode($('.'+SN.C.S.Error, xhr.responseXML)[0], true));
}
else {
if(jQuery.inArray(parseInt(xhr.status), SN.C.I.HTTP20x30x) < 0) {
alert('Sorry! We had trouble sending your notice ('+xhr.status+' '+xhr.statusText+'). Please report the problem to the site administrator if this happens again.');
}
else {
$('#'+form_id+' #'+SN.C.S.NoticeDataText).val('');
SN.U.Counter($('#'+SN.C.S.FormNotice));
}
}
}
},
success: function(data, textStatus) {
if ($('#'+SN.C.S.Error, data).length > 0) {
var result = document._importNode($('p', data)[0], true);
alert(result.textContent || result.innerHTML);
}
else {
if($('body')[0].id == 'bookmarklet') {
self.close();
}
if ($('#'+SN.C.S.CommandResult, data).length > 0) {
var result = document._importNode($('p', data)[0], true);
alert(result.textContent || result.innerHTML);
}
else {
notice = document._importNode($('li', data)[0], true);
if ($('#'+notice.id).length == 0) {
var notice_irt_value = $('#'+SN.C.S.NoticeInReplyTo).val();
var notice_irt = '#notices_primary #notice-'+notice_irt_value;
if($('body')[0].id == 'conversation') {
if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) {
$(notice_irt).append('<ul class="notices"></ul>');
}
$($(notice_irt+' .notices')[0]).append(notice);
}
else {
$("#notices_primary .notices").prepend(notice);
}
$('#'+notice.id).css({display:'none'});
$('#'+notice.id).fadeIn(2500);
SN.U.NoticeAttachments();
SN.U.NoticeReply();
}
}
$('#'+form_id+' #'+SN.C.S.NoticeDataText).val('');
$('#'+form_id+' #'+SN.C.S.NoticeDataAttach).val('');
$('#'+form_id+' #'+SN.C.S.NoticeInReplyTo).val('');
$('#'+form_id+' #'+SN.C.S.NoticeDataAttachSelected).remove();
SN.U.Counter($('#'+SN.C.S.FormNotice));
}
},
complete: function(xhr, textStatus) {
form.removeClass(SN.C.S.Processing);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeAttr(SN.C.S.Disabled);
$('#'+form_id+' #'+SN.C.S.NoticeActionSubmit).removeClass(SN.C.S.Disabled);
}
});
},
NoticeReply: function() {
if ($('#'+SN.C.S.NoticeDataText).length > 0 && $('#content .notice_reply').length > 0) {
$('#content .notice').each(function() {
var notice = $(this)[0];
$($('.notice_reply', notice)[0]).click(function() {
var nickname = ($('.author .nickname', notice).length > 0) ? $($('.author .nickname', notice)[0]) : $('.author .nickname.uid');
SN.U.NoticeReplySet(nickname.text(), $($('.notice_id', notice)[0]).text());
return false;
});
});
}
},
NoticeReplySet: function(nick,id) {
if (nick.match(SN.C.I.PatternUsername)) {
var text = $('#'+SN.C.S.NoticeDataText);
if (text.length) {
replyto = '@' + nick + ' ';
text.val(replyto + text.val().replace(RegExp(replyto, 'i'), ''));
$('#'+SN.C.S.FormNotice+' input#'+SN.C.S.NoticeInReplyTo).val(id);
if (text.get(0).setSelectionRange) {
var len = text.val().length;
text.get(0).setSelectionRange(len,len);
text.get(0).focus();
}
return false;
}
}
return true;
},
NoticeAttachments: function() {
$.fn.jOverlay.options = {
method : 'GET',
data : '',
url : '',
color : '#000',
opacity : '0.6',
zIndex : 99,
center : false,
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
bgClickToClose : true,
success : function() {
$('#jOverlayContent').append('<button>&#215;</button>');
$('#jOverlayContent button').click($.closeOverlay);
},
timeout : 0,
autoHide : true,
css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'}
};
$('#content .notice a.attachment').click(function() {
$().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
return false;
});
var t;
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
function() {
var anchor = $(this);
$("a.thumbnail").children('img').hide();
anchor.closest(".entry-title").addClass('ov');
if (anchor.children('img').length == 0) {
t = setTimeout(function() {
$.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
anchor.append(data);
});
}, 500);
}
else {
anchor.children('img').show();
}
},
function() {
clearTimeout(t);
$("a.thumbnail").children('img').hide();
$(this).closest(".entry-title").removeClass('ov');
}
);
},
NoticeDataAttach: function() {
NDA = $('#'+SN.C.S.NoticeDataAttach);
NDA.change(function() {
S = '<div id="'+SN.C.S.NoticeDataAttachSelected+'" class="'+SN.C.S.Success+'"><code>'+$(this).val()+'</code> <button>&#215;</button></div>';
NDAS = $('#'+SN.C.S.NoticeDataAttachSelected);
(NDAS.length > 0) ? NDAS.replaceWith(S) : $('#'+SN.C.S.FormNotice).append(S);
$('#'+SN.C.S.NoticeDataAttachSelected+' button').click(function(){
$('#'+SN.C.S.NoticeDataAttachSelected).remove();
NDA.val('');
});
});
},
NewDirectMessage: function() {
NDM = $('.entity_send-a-message a');
NDM.attr({'href':NDM.attr('href')+'&ajax=1'});
NDM.click(function() {
var NDMF = $('.entity_send-a-message form');
if (NDMF.length == 0) {
$.get(NDM.attr('href'), null, function(data) {
$('.entity_send-a-message').append(document._importNode($('form', data).get(0), true));
NDMF = $('.entity_send-a-message .form_notice');
SN.U.FormNoticeEnhancements(NDMF);
NDMF.append('<button>&#215;</button>');
$('.entity_send-a-message button').click(function(){
NDMF.hide();
return false;
});
});
}
else {
NDMF.show();
$('.entity_send-a-message textarea').focus();
}
return false;
});
}
} }
} }
function NoticeReplySet(nick,id) {
rgx_username = /^[0-9a-zA-Z\-_.]*$/;
if (nick.match(rgx_username)) {
var text = $("#notice_data-text");
if (text.length) {
replyto = "@" + nick + " ";
text.val(replyto + text.val().replace(RegExp(replyto, 'i'), ''));
$("#form_notice input#notice_in-reply-to").val(id);
if (text.get(0).setSelectionRange) {
var len = text.val().length;
text.get(0).setSelectionRange(len,len);
text.get(0).focus();
}
return false;
}
}
return true;
}
function NoticeAttachments() {
$.fn.jOverlay.options = {
method : 'GET',
data : '',
url : '',
color : '#000',
opacity : '0.6',
zIndex : 99,
center : false,
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
bgClickToClose : true,
success : function() {
$('#jOverlayContent').append('<button>&#215;</button>');
$('#jOverlayContent button').click($.closeOverlay);
},
timeout : 0,
autoHide : true,
css : {'max-width':'542px', 'top':'5%', 'left':'32.5%'}
};
$('#content .notice a.attachment').click(function() {
$().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
return false;
});
var t;
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
function() {
var anchor = $(this);
$("a.thumbnail").children('img').hide();
anchor.closest(".entry-title").addClass('ov');
if (anchor.children('img').length == 0) {
t = setTimeout(function() {
$.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
anchor.append(data);
});
}, 500);
}
else {
anchor.children('img').show();
}
},
function() {
clearTimeout(t);
$("a.thumbnail").children('img').hide();
$(this).closest(".entry-title").removeClass('ov');
}
);
}
function NoticeDataAttach() {
NDA = $('#notice_data-attach');
NDA.change(function() {
S = '<div id="notice_data-attach_selected" class="success"><code>'+$(this).val()+'</code> <button>&#215;</button></div>';
NDAS = $('#notice_data-attach_selected');
(NDAS.length > 0) ? NDAS.replaceWith(S) : $('#form_notice').append(S);
$('#notice_data-attach_selected button').click(function(){
$('#notice_data-attach_selected').remove();
NDA.val('');
});
});
}

View File

@ -185,7 +185,14 @@ function _have_config()
} }
// XXX: Throw a conniption if database not installed // XXX: Throw a conniption if database not installed
// XXX: Find a way to use htmlwriter for this instead of handcoded markup
if (!_have_config()) {
echo '<p>'. _('No configuation file found. ') .'</p>';
echo '<p>'. _('I looked for configuration files in the following places: ') .'<br/> '. implode($_config_files, '<br/>');
echo '<p>'. _('You may wish to run the installer to fix this.') .'</p>';
echo '<a href="install.php">'. _('Go to the installer.') .'</a>';
exit;
}
// Fixup for statusnet.ini // Fixup for statusnet.ini
$_db_name = substr($config['db']['database'], strrpos($config['db']['database'], '/') + 1); $_db_name = substr($config['db']['database'], strrpos($config['db']['database'], '/') + 1);

View File

@ -80,10 +80,21 @@ class MessageForm extends Form
/** /**
* ID of the form * ID of the form
* *
* @return int ID of the form * @return string ID of the form
*/ */
function id() function id()
{
return 'form_notice-direct';
}
/**
* Class of the form
*
* @return string class of the form
*/
function formClass()
{ {
return 'form_notice'; return 'form_notice';
} }

View File

@ -105,7 +105,7 @@ class NoticeForm extends Form
/** /**
* ID of the form * ID of the form
* *
* @return int ID of the form * @return string ID of the form
*/ */
function id() function id()
@ -113,6 +113,17 @@ class NoticeForm extends Form
return 'form_notice'; return 'form_notice';
} }
/**
* Class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_notice';
}
/** /**
* Action of the form * Action of the form
* *

View File

@ -108,6 +108,9 @@ class Router
$m->connect('main/oembed', $m->connect('main/oembed',
array('action' => 'oembed')); array('action' => 'oembed'));
$m->connect('main/xrds',
array('action' => 'publicxrds'));
// these take a code // these take a code
foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) { foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) {

View File

@ -1,21 +1,12 @@
<?php <?php
/** /**
* Public XRDS for OpenID * StatusNet, the distributed open-source microblogging tool
*
* Low-level generator for HTML
* *
* PHP version 5 * PHP version 5
* *
* @category Action * LICENCE: This program is free software: you can redistribute it and/or modify
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by * it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -27,60 +18,44 @@
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Output
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2008 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') && !defined('LACONICA')) { if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1); exit(1);
} }
require_once INSTALLDIR.'/plugins/OpenID/openid.php'; require_once INSTALLDIR.'/lib/xmloutputter.php';
/** /**
* Public XRDS for OpenID * Low-level generator for XRDS XML
* *
* @category Action * @category Output
* @package StatusNet * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Craig Andrews <candrews@integralblue.com>
* @author Robin Millette <millette@status.net> * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/ * @link http://status.net/
* *
* @todo factor out similarities with XrdsAction * @see Action
* @see XMLOutputter
*/ */
class PublicxrdsAction extends Action class XRDSOutputter extends XMLOutputter
{ {
/** public function startXRDS()
* Is read only?
*
* @return boolean true
*/
function isReadOnly($args)
{ {
return true;
}
/**
* Class handler.
*
* @param array $args array of arguments
*
* @return nothing
*/
function handle($args)
{
parent::handle($args);
header('Content-Type: application/xrds+xml'); header('Content-Type: application/xrds+xml');
$this->startXML(); $this->startXML();
$this->elementStart('XRDS', array('xmlns' => 'xri://$xrds')); $this->elementStart('XRDS', array('xmlns' => 'xri://$xrds'));
$this->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', }
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0')); public function endXRDS()
$this->element('Type', null, 'xri://$xrds*simple'); {
foreach (array('finishopenidlogin', 'finishaddopenid') as $finish) {
$this->showService(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
common_local_url($finish));
}
$this->elementEnd('XRD');
$this->elementEnd('XRDS'); $this->elementEnd('XRDS');
$this->endXML(); $this->endXML();
} }
@ -96,7 +71,7 @@ class PublicxrdsAction extends Action
* *
* @return void * @return void
*/ */
function showService($type, $uri, $params=null, $sigs=null, $localId=null) function showXrdsService($type, $uri, $params=null, $sigs=null, $localId=null)
{ {
$this->elementStart('Service'); $this->elementStart('Service');
if ($uri) { if ($uri) {
@ -119,4 +94,3 @@ class PublicxrdsAction extends Action
$this->elementEnd('Service'); $this->elementEnd('Service');
} }
} }

View File

@ -62,17 +62,59 @@ class OpenIDPlugin extends Plugin
* @return boolean hook return * @return boolean hook return
*/ */
function onRouterInitialized($m) function onStartInitializeRouter($m)
{ {
$m->connect('main/openid', array('action' => 'openidlogin')); $m->connect('main/openid', array('action' => 'openidlogin'));
$m->connect('main/openidtrust', array('action' => 'openidtrust'));
$m->connect('settings/openid', array('action' => 'openidsettings')); $m->connect('settings/openid', array('action' => 'openidsettings'));
$m->connect('xrds', array('action' => 'publicxrds'));
$m->connect('index.php?action=finishopenidlogin', array('action' => 'finishopenidlogin')); $m->connect('index.php?action=finishopenidlogin', array('action' => 'finishopenidlogin'));
$m->connect('index.php?action=finishaddopenid', array('action' => 'finishaddopenid')); $m->connect('index.php?action=finishaddopenid', array('action' => 'finishaddopenid'));
$m->connect('main/openidserver', array('action' => 'openidserver'));
return true; return true;
} }
function onEndPublicXRDS($action, &$xrdsOutputter)
{
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
//consumer
foreach (array('finishopenidlogin', 'finishaddopenid') as $finish) {
$xrdsOutputter->showXrdsService(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
common_local_url($finish));
}
//provider
$xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/server',
common_local_url('openidserver'),
null,
null,
'http://specs.openid.net/auth/2.0/identifier_select');
$xrdsOutputter->elementEnd('XRD');
}
function onEndUserXRDS($action, &$xrdsOutputter)
{
$xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
'xml:id' => 'openid',
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
'version' => '2.0'));
$xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
//consumer
$xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/return_to',
common_local_url('finishopenidlogin'));
//provider
$xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/signon',
common_local_url('openidserver'),
null,
null,
common_profile_url($action->user->nickname));
$xrdsOutputter->elementEnd('XRD');
}
function onEndLoginGroupNav(&$action) function onEndLoginGroupNav(&$action)
{ {
$action_name = $action->trimmed('action'); $action_name = $action->trimmed('action');
@ -107,6 +149,8 @@ class OpenIDPlugin extends Plugin
case 'XrdsAction': case 'XrdsAction':
case 'PublicxrdsAction': case 'PublicxrdsAction':
case 'OpenidsettingsAction': case 'OpenidsettingsAction':
case 'OpenidserverAction':
case 'OpenidtrustAction':
require_once(INSTALLDIR.'/plugins/OpenID/' . strtolower(mb_substr($cls, 0, -6)) . '.php'); require_once(INSTALLDIR.'/plugins/OpenID/' . strtolower(mb_substr($cls, 0, -6)) . '.php');
return false; return false;
case 'User_openid': case 'User_openid':
@ -136,6 +180,7 @@ class OpenIDPlugin extends Plugin
{ {
case 'openidlogin': case 'openidlogin':
case 'finishopenidlogin': case 'finishopenidlogin':
case 'openidserver':
$login = true; $login = true;
return false; return false;
default: default:
@ -152,12 +197,16 @@ class OpenIDPlugin extends Plugin
function onEndShowHeadElements($action) function onEndShowHeadElements($action)
{ {
if ($action->trimmed('action') == 'public') { if($action instanceof ShowstreamAction){
// for client side of OpenID authentication $action->element('link', array('rel' => 'openid2.provider',
$action->element('meta', array('http-equiv' => 'X-XRDS-Location', 'href' => common_local_url('openidserver')));
'content' => common_local_url('publicxrds'))); $action->element('link', array('rel' => 'openid2.local_id',
'href' => $action->profile->profileurl));
$action->element('link', array('rel' => 'openid.server',
'href' => common_local_url('openidserver')));
$action->element('link', array('rel' => 'openid.delegate',
'href' => $action->profile->profileurl));
} }
return true; return true;
} }
@ -239,6 +288,14 @@ class OpenIDPlugin extends Plugin
new ColumnDef('created', 'datetime', new ColumnDef('created', 'datetime',
null, false), null, false),
new ColumnDef('modified', 'timestamp'))); new ColumnDef('modified', 'timestamp')));
$schema->ensureTable('user_openid_trustroot',
array(new ColumnDef('trustroot', 'varchar',
'255', false, 'PRI'),
new ColumnDef('user_id', 'integer',
null, false, 'PRI'),
new ColumnDef('created', 'datetime',
null, false),
new ColumnDef('modified', 'timestamp')));
return true; return true;
} }
} }

View File

@ -0,0 +1,29 @@
<?php
/**
* Table Definition for user_openid_trustroot
*/
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class User_openid_trustroot extends Memcached_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'user_openid_trustroot'; // table name
public $trustroot; // varchar(255) primary_key not_null
public $user_id; // int(4) primary_key not_null
public $created; // datetime() not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=null)
{ return Memcached_DataObject::staticGet('User_openid_trustroot',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
function &pkeyGet($kv)
{
return Memcached_DataObject::pkeyGet('User_openid_trustroot', $kv);
}
}

View File

@ -23,6 +23,7 @@ require_once(INSTALLDIR.'/plugins/OpenID/User_openid.php');
require_once('Auth/OpenID.php'); require_once('Auth/OpenID.php');
require_once('Auth/OpenID/Consumer.php'); require_once('Auth/OpenID/Consumer.php');
require_once('Auth/OpenID/Server.php');
require_once('Auth/OpenID/SReg.php'); require_once('Auth/OpenID/SReg.php');
require_once('Auth/OpenID/MySQLStore.php'); require_once('Auth/OpenID/MySQLStore.php');
@ -50,6 +51,13 @@ function oid_consumer()
return $consumer; return $consumer;
} }
function oid_server()
{
$store = oid_store();
$server = new Auth_OpenID_Server($store, common_local_url('openidserver'));
return $server;
}
function oid_clear_last() function oid_clear_last()
{ {
oid_set_last(''); oid_set_last('');

View File

@ -0,0 +1,151 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Settings for OpenID
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2008-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') && !defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/action.php';
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php');
/**
* Settings for OpenID
*
* Lets users add, edit and delete OpenIDs from their account
*
* @category Settings
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class OpenidserverAction extends Action
{
var $oserver;
function prepare($args)
{
parent::prepare($args);
$this->oserver = oid_server();
return true;
}
function handle($args)
{
parent::handle($args);
$request = $this->oserver->decodeRequest();
if (in_array($request->mode, array('checkid_immediate',
'checkid_setup'))) {
$user = common_current_user();
if(!$user){
if($request->immediate){
//cannot prompt the user to login in immediate mode, so answer false
$response = $this->generateDenyResponse($request);
}else{
/* Go log in, and then come back. */
common_set_returnto($_SERVER['REQUEST_URI']);
common_redirect(common_local_url('login'));
return;
}
}else if(common_profile_url($user->nickname) == $request->identity || $request->idSelect()){
$user_openid_trustroot = User_openid_trustroot::pkeyGet(
array('user_id'=>$user->id, 'trustroot'=>$request->trust_root));
if(empty($user_openid_trustroot)){
if($request->immediate){
//cannot prompt the user to trust this trust root in immediate mode, so answer false
$response = $this->generateDenyResponse($request);
}else{
common_ensure_session();
$_SESSION['openid_trust_root'] = $request->trust_root;
$allowResponse = $this->generateAllowResponse($request, $user);
$this->oserver->encodeResponse($allowResponse); //sign the response
$denyResponse = $this->generateDenyResponse($request);
$this->oserver->encodeResponse($denyResponse); //sign the response
$_SESSION['openid_allow_url'] = $allowResponse->encodeToUrl();
$_SESSION['openid_deny_url'] = $denyResponse->encodeToUrl();
//ask the user to trust this trust root
common_redirect(common_local_url('openidtrust'));
return;
}
}else{
//user has previously authorized this trust root
$response = $this->generateAllowResponse($request, $user);
//$response = $request->answer(true, null, common_profile_url($user->nickname));
}
} else if ($request->immediate) {
$response = $this->generateDenyResponse($request);
} else {
//invalid
$this->clientError(sprintf(_('You are not authorized to use the identity %s'),$request->identity),$code=403);
}
} else {
$response = $this->oserver->handleRequest($request);
}
if($response){
$response = $this->oserver->encodeResponse($response);
if ($response->code != AUTH_OPENID_HTTP_OK) {
header(sprintf("HTTP/1.1 %d ", $response->code),
true, $response->code);
}
if($response->headers){
foreach ($response->headers as $k => $v) {
header("$k: $v");
}
}
$this->raw($response->body);
}else{
$this->clientError(_('Just an OpenID provider. Nothing to see here, move along...'),$code=500);
}
}
function generateAllowResponse($request, $user){
$response = $request->answer(true, null, common_profile_url($user->nickname));
$profile = $user->getProfile();
$sreg_data = array(
'fullname' => $profile->fullname,
'nickname' => $user->nickname,
'email' => $user->email,
'language' => $user->language,
'timezone' => $user->timezone);
$sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request);
$sreg_response = Auth_OpenID_SRegResponse::extractResponse(
$sreg_request, $sreg_data);
$sreg_response->toMessage($response->fields);
return $response;
}
function generateDenyResponse($request){
$response = $request->answer(false);
return $response;
}
}

View File

@ -0,0 +1,142 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php');
class OpenidtrustAction extends Action
{
var $trust_root;
var $allowUrl;
var $denyUrl;
var $user;
/**
* Is this a read-only action?
*
* @return boolean false
*/
function isReadOnly($args)
{
return false;
}
/**
* Title of the page
*
* @return string title of the page
*/
function title()
{
return _('OpenID Identity Verification');
}
function prepare($args)
{
parent::prepare($args);
common_ensure_session();
$this->user = common_current_user();
if(empty($this->user)){
/* Go log in, and then come back. */
common_set_returnto($_SERVER['REQUEST_URI']);
common_redirect(common_local_url('login'));
return;
}
$this->trust_root = $_SESSION['openid_trust_root'];
$this->allowUrl = $_SESSION['openid_allow_url'];
$this->denyUrl = $_SESSION['openid_deny_url'];
if(empty($this->trust_root) || empty($this->allowUrl) || empty($this->denyUrl)){
$this->clientError(_('This page should only be reached during OpenID processing, not directly.'));
return;
}
return true;
}
function handle($args)
{
parent::handle($args);
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$this->handleSubmit();
}else{
$this->showPage();
}
}
function handleSubmit()
{
unset($_SESSION['openid_trust_root']);
unset($_SESSION['openid_allow_url']);
unset($_SESSION['openid_deny_url']);
if($this->arg('allow'))
{
//save to database
$user_openid_trustroot = new User_openid_trustroot();
$user_openid_trustroot->user_id = $this->user->id;
$user_openid_trustroot->trustroot = $this->trust_root;
$user_openid_trustroot->created = DB_DataObject_Cast::dateTime();
if (!$user_openid_trustroot->insert()) {
$err = PEAR::getStaticProperty('DB_DataObject','lastError');
common_debug('DB error ' . $err->code . ': ' . $err->message, __FILE__);
}
common_redirect($this->allowUrl, $code=302);
}else{
common_redirect($this->denyUrl, $code=302);
}
}
/**
* Show page notice
*
* Display a notice for how to use the page, or the
* error if it exists.
*
* @return void
*/
function showPageNotice()
{
$this->element('p',null,sprintf(_('%s has asked to verify your identity. Click Continue to verify your identity and login without creating a new password.'),$this->trust_root));
}
/**
* Core of the display code
*
* Shows the login form.
*
* @return void
*/
function showContent()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'form_openidtrust',
'class' => 'form_settings',
'action' => common_local_url('openidtrust')));
$this->elementStart('fieldset');
$this->submit('allow', _('Continue'));
$this->submit('deny', _('Cancel'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
}

View File

@ -65,21 +65,21 @@ class PubSubHubBubPlugin extends Plugin
$feeds = array(); $feeds = array();
//public timeline feeds //public timeline feeds
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'public_timeline.rss')); $feeds[]=common_local_url('ApiTimelinePublic',array('format' => 'rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'public_timeline.atom')); $feeds[]=common_local_url('ApiTimelinePublic',array('format' => 'atom'));
//author's own feeds //author's own feeds
$user = User::staticGet('id',$notice->profile_id); $user = User::staticGet('id',$notice->profile_id);
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.rss')); $feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.atom')); $feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'atom'));
//tag feeds //tag feeds
$tag = new Notice_tag(); $tag = new Notice_tag();
$tag->notice_id = $notice->id; $tag->notice_id = $notice->id;
if ($tag->find()) { if ($tag->find()) {
while ($tag->fetch()) { while ($tag->fetch()) {
$feeds[]=common_local_url('api',array('apiaction' => 'tags','method' => 'timeline', 'argument'=>$tag->tag.'.atom')); $feeds[]=common_local_url('ApiTimelineTag',array('tag'=>$tag->tag, 'format'=>'rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'tags','method' => 'timeline', 'argument'=>$tag->tag.'.rss')); $feeds[]=common_local_url('ApiTimelineTag',array('tag'=>$tag->tag, 'format'=>'atom'));
} }
} }
@ -89,8 +89,8 @@ class PubSubHubBubPlugin extends Plugin
if ($group_inbox->find()) { if ($group_inbox->find()) {
while ($group_inbox->fetch()) { while ($group_inbox->fetch()) {
$group = User_group::staticGet('id',$group_inbox->group_id); $group = User_group::staticGet('id',$group_inbox->group_id);
$feeds[]=common_local_url('api',array('apiaction' => 'groups','method' => 'timeline','argument' => $group->nickname.'.rss')); $feeds[]=common_local_url('ApiTimelineGroup',array('id' => $group->nickname,'format'=>'rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'groups','method' => 'timeline','argument' => $group->nickname.'.atom')); $feeds[]=common_local_url('ApiTimelineGroup',array('id' => $group->nickname,'format'=>'atom'));
} }
} }
@ -100,18 +100,17 @@ class PubSubHubBubPlugin extends Plugin
if ($notice_inbox->find()) { if ($notice_inbox->find()) {
while ($notice_inbox->fetch()) { while ($notice_inbox->fetch()) {
$user = User::staticGet('id',$notice_inbox->user_id); $user = User::staticGet('id',$notice_inbox->user_id);
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.rss')); $feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.atom')); $feeds[]=common_local_url('ApiTimelineUser',array('id' => $user->nickname, 'format'=>'atom'));
} }
} }
/* TODO: when the reply page gets RSS and ATOM feeds, implement this
//feed of user replied to //feed of user replied to
if($notice->reply_to){ if($notice->reply_to){
$user = User::staticGet('id',$notice->reply_to); $user = User::staticGet('id',$notice->reply_to);
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.rss')); $feeds[]=common_local_url('ApiTimelineMentions',array('id' => $user->nickname,'format'=>'rss'));
$feeds[]=common_local_url('api',array('apiaction' => 'statuses','method' => 'user_timeline','argument' => $user->nickname.'.atom')); $feeds[]=common_local_url('ApiTimelineMentions',array('id' => $user->nickname,'format'=>'atom'));
}*/ }
foreach(array_unique($feeds) as $feed){ foreach(array_unique($feeds) as $feed){
if(! $publisher->publish_update($feed)){ if(! $publisher->publish_update($feed)){

View File

@ -432,21 +432,21 @@ border-width:1px;
border-style:solid; border-style:solid;
} }
#form_notice { .form_notice {
width:45%; width:45%;
float:left; float:left;
position:relative; position:relative;
line-height:1; line-height:1;
} }
#form_notice fieldset { .form_notice fieldset {
border:0; border:0;
padding:0; padding:0;
position:relative; position:relative;
} }
#form_notice legend { .form_notice legend {
display:none; display:none;
} }
#form_notice textarea { .form_notice textarea {
float:left; float:left;
border-radius:7px; border-radius:7px;
-moz-border-radius:7px; -moz-border-radius:7px;
@ -458,44 +458,44 @@ padding:7px 7px 16px 7px;
position:relative; position:relative;
z-index:2; z-index:2;
} }
#form_notice label { .form_notice label {
display:block; display:block;
float:left; float:left;
font-size:1.3em; font-size:1.3em;
margin-bottom:7px; margin-bottom:7px;
} }
#form_notice label[for=notice_data-attach], .form_notice label[for=notice_data-attach],
#form_notice #notice_data-attach { .form_notice #notice_data-attach {
position:absolute; position:absolute;
top:25px; top:25px;
right:10.5%; right:10.5%;
cursor:pointer; cursor:pointer;
} }
#form_notice label[for=notice_data-attach] { .form_notice label[for=notice_data-attach] {
text-indent:-9999px; text-indent:-9999px;
width:16px; width:16px;
height:16px; height:16px;
} }
#form_notice #notice_data-attach { .form_notice #notice_data-attach {
padding:0; padding:0;
height:16px; height:16px;
} }
#form_notice .form_note { .form_notice .form_note {
position:absolute; position:absolute;
bottom:2px; bottom:2px;
right:21.715%; right:21.715%;
z-index:9; z-index:9;
} }
#form_notice .form_note dt { .form_notice .form_note dt {
font-weight:bold; font-weight:bold;
display:none; display:none;
} }
#notice_text-count { .form_notice #notice_text-count {
font-weight:bold; font-weight:bold;
line-height:1.15; line-height:1.15;
padding:1px 2px; padding:1px 2px;
} }
#form_notice #notice_action-submit { .form_notice #notice_action-submit {
width:14%; width:14%;
height:47px; height:47px;
padding:0; padding:0;
@ -503,24 +503,24 @@ position:absolute;
bottom:0; bottom:0;
right:0; right:0;
} }
#form_notice label[for=to] { .form_notice label[for=to] {
margin-top:7px; margin-top:7px;
} }
#form_notice select[id=to] { .form_notice select[id=to] {
margin-bottom:7px; margin-bottom:7px;
margin-left:18px; margin-left:18px;
float:left; float:left;
max-width:322px; max-width:322px;
} }
#form_notice .error, .form_notice .error,
#form_notice .success { .form_notice .success {
float:left; float:left;
clear:both; clear:both;
width:81.5%; width:81.5%;
margin-bottom:0; margin-bottom:0;
line-height:1.618; line-height:1.618;
} }
#form_notice #notice_data-attach_selected code { .form_notice #notice_data-attach_selected code {
float:left; float:left;
width:90%; width:90%;
display:block; display:block;
@ -528,7 +528,7 @@ font-size:1.1em;
line-height:1.8; line-height:1.8;
overflow:auto; overflow:auto;
} }
#form_notice #notice_data-attach_selected button { .form_notice #notice_data-attach_selected button {
float:right; float:right;
font-size:0.8em; font-size:0.8em;
} }
@ -670,6 +670,40 @@ border-radius:4px;
margin-bottom:18px; margin-bottom:18px;
} }
.entity_send-a-message button {
position:absolute;
top:0;
right:0;
}
.entity_send-a-message .form_notice {
position:absolute;
top:34px;
right:-1px;
padding:1.795%;
width:65%;
z-index:1;
background-color:#FFFFFF;
border:1px solid #CCCCCC;
-moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.7);
-moz-border-radius:7px;
}
.entity_send-a-message .form_notice legend {
display:block;
margin-bottom:11px;
}
.entity_send-a-message .form_notice label,
.entity_send-a-message .form_notice select {
display:none;
}
.entity_send-a-message .form_notice input.submit {
text-align:center;
}
.entity_tags ul { .entity_tags ul {
list-style-type:none; list-style-type:none;
display:inline; display:inline;
@ -1299,7 +1333,7 @@ clear:both;
#bookmarklet address { #bookmarklet address {
display:none; display:none;
} }
#bookmarklet #form_notice { #bookmarklet .form_notice {
width:auto; width:auto;
} }
#bookmarklet #wrap { #bookmarklet #wrap {

View File

@ -3,10 +3,10 @@ input.checkbox,
input.radio { input.radio {
top:0; top:0;
} }
#form_notice textarea { .form_notice textarea {
width:78%; width:78%;
} }
#form_notice .form_note + label { .form_notice .form_note + label {
position:absolute; position:absolute;
top:25px; top:25px;
left:83%; left:83%;
@ -15,14 +15,14 @@ height:16px;
width:16px; width:16px;
display:block; display:block;
} }
#form_notice #notice_action-submit { .form_notice #notice_action-submit {
width:17%; width:17%;
max-width:17%; max-width:17%;
} }
#form_notice #notice_data-attach_selected { .form_notice #notice_data-attach_selected {
width:78.5%; width:78.5%;
} }
#form_notice #notice_data-attach_selected button { .form_notice #notice_data-attach_selected button {
padding:0 4px; padding:0 4px;
} }
.notice-options input.submit { .notice-options input.submit {

View File

@ -37,14 +37,14 @@ background:none;
} }
input.submit, input.submit,
#form_notice.warning #notice_text-count, .form_notice.warning #notice_text-count,
.form_settings .form_note, .form_settings .form_note,
.entity_remote_subscribe { .entity_remote_subscribe {
background-color:#9BB43E; background-color:#9BB43E;
} }
input:focus, textarea:focus, select:focus, input:focus, textarea:focus, select:focus,
#form_notice.warning #notice_data-text { .form_notice.warning #notice_data-text {
border-color:#9BB43E; border-color:#9BB43E;
box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); -moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
@ -84,13 +84,13 @@ background-color:#C8D1D5;
#notice_text-count { #notice_text-count {
color:#333333; color:#333333;
} }
#form_notice.warning #notice_text-count { .form_notice.warning #notice_text-count {
color:#000000; color:#000000;
} }
#form_notice label[for=notice_data-attach] { .form_notice label[for=notice_data-attach] {
background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px; background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
} }
#form_notice #notice_data-attach { .form_notice #notice_data-attach {
opacity:0; opacity:0;
} }

View File

@ -6,9 +6,9 @@ color:#FFFFFF;
#site_nav_local_views a { #site_nav_local_views a {
background-color:#C8D1D5; background-color:#C8D1D5;
} }
#form_notice .form_note + label { .form_notice .form_note + label {
background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%; background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
} }
#form_notice #notice_data-attach { .form_notice #notice_data-attach {
filter: alpha(opacity=0); filter: alpha(opacity=0);
} }

View File

@ -37,14 +37,14 @@ background:none;
} }
input.submit, input.submit,
#form_notice.warning #notice_text-count, .form_notice.warning #notice_text-count,
.form_settings .form_note, .form_settings .form_note,
.entity_remote_subscribe { .entity_remote_subscribe {
background-color:#9BB43E; background-color:#9BB43E;
} }
input:focus, textarea:focus, select:focus, input:focus, textarea:focus, select:focus,
#form_notice.warning #notice_data-text { .form_notice.warning #notice_data-text {
border-color:#9BB43E; border-color:#9BB43E;
box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3); -moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
@ -84,13 +84,13 @@ background-color:#CEE1E9;
#notice_text-count { #notice_text-count {
color:#333333; color:#333333;
} }
#form_notice.warning #notice_text-count { .form_notice.warning #notice_text-count {
color:#000000; color:#000000;
} }
#form_notice label[for=notice_data-attach] { .form_notice label[for=notice_data-attach] {
background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px; background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
} }
#form_notice #notice_data-attach { .form_notice #notice_data-attach {
opacity:0; opacity:0;
} }

View File

@ -6,10 +6,10 @@ color:#FFFFFF;
#site_nav_local_views a { #site_nav_local_views a {
background-color:#D9DADB; background-color:#D9DADB;
} }
#form_notice .form_note + label { .form_notice .form_note + label {
background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px; background:transparent url(../../base/images/icons/icons-01.png) no-repeat 0 -328px;
} }
#form_notice #notice_data-attach { .form_notice #notice_data-attach {
filter: alpha(opacity=0); filter: alpha(opacity=0);
} }
.notice-options form.form_favor input.submit { .notice-options form.form_favor input.submit {