Merge branch '1.0.x' of gitorious.org:statusnet/mainline into 1.0.x

This commit is contained in:
Evan Prodromou 2011-05-31 17:01:11 -04:00
commit 506958f2c8
32 changed files with 385 additions and 246 deletions

View File

@ -193,10 +193,18 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
{
$notices = array();
$notice = $this->user->getReplies(
($this->page - 1) * $this->count, $this->count,
$this->since_id, $this->max_id
);
if (empty($this->auth_user)) {
$profile = null;
} else {
$profile = $this->auth_user->getProfile();
}
$stream = new ReplyNoticeStream($this->user->id, $profile);
$notice = $stream->getNotices(($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
while ($notice->fetch()) {
$notices[] = clone($notice);

View File

@ -60,7 +60,6 @@ class InviteAction extends CurrentUserDesignAction
function sendInvitations()
{
if (Event::handle('StartSendInvitations', array(&$this))) {
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
@ -162,7 +161,6 @@ class InviteAction extends CurrentUserDesignAction
function showInvitationSuccess()
{
if (Event::handle('StartShowInvitationSuccess', array($this))) {
if ($this->already) {
// TRANS: Message displayed inviting users to use a StatusNet site while the inviting user
// TRANS: is already subscribed to one or more users with the given e-mail address(es).

View File

@ -85,7 +85,10 @@ class RepliesAction extends OwnerDesignAction
common_set_returnto($this->selfUrl());
$this->notice = $this->user->getReplies(($this->page-1) * NOTICES_PER_PAGE,
$stream = new ReplyNoticeStream($this->user->id,
Profile::current());
$this->notice = $stream->getNotices(($this->page-1) * NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
if($this->page > 1 && $this->notice->N == 0){

View File

@ -14,6 +14,7 @@ class Invitation extends Memcached_DataObject
public $user_id; // int(4) not_null
public $address; // varchar(255) multiple_key not_null
public $address_type; // varchar(8) multiple_key not_null
public $registered_user_id; // int(4) not_null
public $created; // datetime() not_null
/* Static get */
@ -22,4 +23,11 @@ class Invitation extends Memcached_DataObject
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
function convert($user)
{
$orig = clone($this);
$this->registered_user_id = $user->id;
return $this->update($orig);
}
}

View File

@ -263,6 +263,8 @@ class User extends Memcached_DataObject
$user->nickname = $nickname;
$invite = null;
// Users who respond to invite email have proven their ownership of that address
if (!empty($code)) {
@ -353,6 +355,12 @@ class User extends Memcached_DataObject
return false;
}
// Mark that this invite was converted
if (!empty($invite)) {
$invite->convert($user);
}
if (!empty($email) && !$user->email) {
$confirm = new Confirm_address();

View File

@ -258,6 +258,7 @@ user_id = 129
address = 130
address_type = 130
created = 142
registered_user_id = 1
[invitation__keys]
code = K

View File

@ -542,14 +542,17 @@ $schema['invitation'] = array(
'address' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'invitation sent to'),
'address_type' => array('type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'),
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
'registered_user_id' => array('type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'),
),
'primary key' => array('code'),
'foreign keys' => array(
'invitation_user_id_fkey' => array('user', array('user_id' => 'id')),
'invitation_registered_user_id_fkey' => array('user', array('registered_user_id' => 'id')),
),
'indexes' => array(
'invitation_address_idx' => array('address', 'address_type'),
'invitation_user_id_idx' => array('user_id'),
'invitation_registered_user_id_idx' => array('registered_user_id'),
),
);

View File

@ -63,9 +63,9 @@ class ActivityImporter extends QueueHandler
$done = null;
try {
if (Event::handle('StartImportActivity',
array($user, $author, $activity, $trusted, &$done))) {
try {
switch ($activity->verb) {
case ActivityVerb::FOLLOW:
$this->subscribeProfile($user, $author, $activity);
@ -83,11 +83,11 @@ class ActivityImporter extends QueueHandler
Event::handle('EndImportActivity',
array($user, $author, $activity, $trusted));
$done = true;
}
} catch (Exception $e) {
common_log(LOG_ERR, $e->getMessage());
$done = true;
}
}
return $done;
}

View File

@ -105,7 +105,8 @@ class ActivityUtils
$els = $element->childNodes;
$out = array();
foreach ($els as $link) {
for ($i = 0; $i < $els->length; $i++) {
$link = $els->item($i);
if ($link->localName == self::LINK && $link->namespaceURI == self::ATOM) {
$linkRel = $link->getAttribute(self::REL);
$linkType = $link->getAttribute(self::TYPE);

View File

@ -41,7 +41,6 @@ require_once INSTALLDIR . '/lib/form.php';
* @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 InviteForm extends Form
{
@ -95,21 +94,21 @@ class InviteForm extends Form
{
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li');
// TRANS: Field label for a list of e-mail addresses.
$this->out->textarea(
'addresses',
// TRANS: Field label for a list of e-mail addresses.
_('Email addresses'),
$this->out->trimmed('addresses'),
// TRANS: Tooltip for field label for a list of e-mail addresses.
// TRANS: Field title for a list of e-mail addresses.
_('Addresses of friends to invite (one per line).')
);
$this->out->elementEnd('li');
$this->out->elementStart('li');
// TRANS: Field label for a personal message to send to invitees.
$this->out->textarea(
// TRANS: Field label for a personal message to send to invitees.
'personal', _('Personal message'),
$this->out->trimmed('personal'),
// TRANS: Tooltip for field label for a personal message to send to invitees.
// TRANS: Field title for a personal message to send to invitees.
_('Optionally add a personal message to the invitation.')
);
$this->out->elementEnd('li');
@ -123,13 +122,13 @@ class InviteForm extends Form
*/
function formActions()
{
// TRANS: Send button for inviting friends
$this->out->submit(
'send',
// TRANS: Send button for inviting friends
_m('BUTTON','Send'), 'submit form_action-primary',
// TRANS: Submit button title.
'send',
_('Send')
// TRANS: Submit button title.
_('Send invitations.')
);
}
}

View File

@ -229,43 +229,15 @@ class NoticeListItem extends Widget
function showAddressees()
{
$ga = $this->getGroupAddressees();
$pa = $this->getProfileAddressees();
$a = array_merge($ga, $pa);
if (!empty($a)) {
$this->out->elementStart('span', 'addressees');
$cnt = $this->showGroupAddressees(true);
$cnt = $this->showProfileAddressees($cnt == 0);
$this->out->elementEnd('span', 'addressees');
}
function showGroupAddressees($first)
{
$groups = $this->getGroups();
foreach ($groups as $group) {
if (!$first) {
$this->out->text( _m('SEPARATOR',', '));
} else {
$first = false;
}
$this->out->element('a', array('href' => $group->homeUrl(),
'title' => $group->nickname,
'class' => 'addressee group'),
$group->getBestName());
}
return count($groups);
}
function getGroups()
{
return $this->notice->getGroups();
}
function showProfileAddressees($first)
{
$replies = $this->getReplyProfiles();
foreach ($replies as $reply) {
$first = true;
foreach ($a as $addr) {
if (!$first) {
// TRANS: Separator in profile addressees list.
$this->out->text(_m('SEPARATOR',', '));
@ -273,13 +245,49 @@ class NoticeListItem extends Widget
// TRANS: Start of profile addressees list.
$first = false;
}
$this->out->element('a', array('href' => $reply->profileurl,
'title' => $reply->nickname,
'class' => 'addressee account'),
$reply->getBestName());
$text = $addr['text'];
unset($addr['text']);
$this->out->element('a', $addr, $text);
}
$this->out->elementEnd('span', 'addressees');
}
}
return count($replies);
function getGroupAddressees()
{
$ga = array();
$groups = $this->getGroups();
foreach ($groups as $group) {
$ga[] = array('href' => $group->homeUrl(),
'title' => $group->nickname,
'class' => 'addressee group',
'text' => $group->getBestName());
}
return $ga;
}
function getGroups()
{
return $this->notice->getGroups();
}
function getProfileAddressees()
{
$pa = array();
$replies = $this->getReplyProfiles();
foreach ($replies as $reply) {
$pa[] = array('href' => $reply->profileurl,
'title' => $reply->nickname,
'class' => 'addressee account',
'text' => $reply->getBestName());
}
return $pa;
}
function getReplyProfiles()

View File

@ -77,6 +77,7 @@ class DomainStatusNetworkPlugin extends Plugin
$sn = Status_network::staticGet('nickname', $nickname);
} catch (Exception $e) {
$this->log(LOG_ERR, $e->getMessage());
return;
}
$tags = $sn->getTags();

View File

@ -118,7 +118,7 @@ class DomainWhitelistPlugin extends Plugin
} else {
// TRANS: Client exception thrown when a given e-mailaddress is not in the domain whitelist.
// TRANS: %s are whitelisted e-mail domains separated by comma's (localisable).
$message = sprintf(_('Email address must be in one of these domains: %s.'),
$message = sprintf(_m('Email address must be in one of these domains: %s.'),
// TRANS: Separator for whitelisted domains.
implode(_m('SEPARATOR',', '), $whitelist));
}
@ -132,7 +132,7 @@ class DomainWhitelistPlugin extends Plugin
{
if (!$this->matchesWhitelist($email)) {
// TRANS: Exception thrown when an e-mail address does not match the site's domain whitelist.
throw new Exception(_('That email address is not allowed on this site.'));
throw new Exception(_m('That email address is not allowed on this site.'));
}
return true;

View File

@ -86,7 +86,7 @@ class WhitelistInviteForm extends Form
function formLegend()
{
// TRANS: Form legend.
$this->out->element('legend', null, _('Invite collegues'));
$this->out->element('legend', null, _m('Invite collegues'));
}
/**
@ -101,12 +101,12 @@ class WhitelistInviteForm extends Form
$this->showEmailLI();
}
$this->out->elementStart('li');
// TRANS: Field label for a personal message to send to invitees.
$this->out->textarea(
'personal', _('Personal message'),
// TRANS: Field label for a personal message to send to invitees.
'personal', _m('Personal message'),
$this->out->trimmed('personal'),
// TRANS: Tooltip for field label for a personal message to send to invitees.
_('Optionally add a personal message to the invitation.')
// TRANS: Field title for a personal message to send to invitees.
_m('Optionally add a personal message to the invitation.')
);
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
@ -154,6 +154,7 @@ class WhitelistInviteForm extends Form
'href' => 'javascript://',
'style' => 'display: none;'
),
// TRANS: Link description to action to add another item to a list.
_m('Add another item')
);
}
@ -165,13 +166,13 @@ class WhitelistInviteForm extends Form
*/
function formActions()
{
// TRANS: Send button for inviting friends
$this->out->submit(
'send',
// TRANS: Send button for inviting friends.
_m('BUTTON','Send'), 'submit form_action-primary',
// TRANS: Submit button title.
'send',
_('Send')
// TRANS: Submit button title.
_m('Send invitations.')
);
}
}

View File

@ -107,7 +107,11 @@ class EmailregisterAction extends Action
$this->invitation = Invitation::staticGet('code', $this->code);
if (empty($this->invitation)) {
if (!empty($this->invitation)) {
if (!empty($this->invitation->registered_user_id)) {
throw new ClientException(_m('Invitation already used.'), 403);
}
} else {
$this->confirmation = Confirm_address::staticGet('code', $this->code);
@ -133,6 +137,9 @@ class EmailregisterAction extends Action
} else {
$this->invitation = Invitation::staticGet('code', $this->code);
if (!empty($this->invitation)) {
if (!empty($this->invitation->registered_user_id)) {
throw new ClientException(_m('Invitation already used.'), 403);
}
$this->state = self::CONFIRMINVITE;
} else {
$this->state = self::CONFIRMREGISTER;
@ -283,10 +290,15 @@ class EmailregisterAction extends Action
$nickname = $this->nicknameFromEmail($email);
try {
$this->user = User::register(array('nickname' => $nickname,
$fields = array('nickname' => $nickname,
'email' => $email,
'password' => $this->password1,
'email_confirmed' => true));
'email_confirmed' => true);
if (!empty($this->invitation)) {
$fields['code'] = $this->invitation->code;
}
$this->user = User::register($fields);
} catch (ClientException $e) {
$this->error = $e->getMessage();
$nickname = $this->nicknameFromEmail($email);
@ -306,18 +318,8 @@ class EmailregisterAction extends Action
// Re-init language env in case it changed (not yet, but soon)
common_init_language();
if (!empty($this->invitation)) {
$inviter = User::staticGet('id', $this->invitation->user_id);
if (!empty($inviter)) {
Subscription::start($inviter->getProfile(),
$this->user->getProfile());
}
$this->invitation->delete();
} else if (!empty($this->confirmation)) {
if (!empty($this->confirmation)) {
$this->confirmation->delete();
} else {
throw new Exception('No confirmation thing.');
}
Event::handle('EndRegistrationTry', array($this));

View File

@ -27,7 +27,7 @@ $helptext = <<<END_OF_REGISTEREMAILUSER_HELP
cancelemailregistration.php [options] <email address>
Options:
-d --dryrun Don't actually delete the email registration and confirmation code
-d --dryrun Do not actually delete the email registration and confirmation code
Cancel an email registration code

View File

@ -328,7 +328,7 @@ class ExtendedProfileWidget extends Form
if (!empty($field['company'])) {
$this->out->element('div', 'field', $field['company']);
// TRANS: Field label in experience area of extended profile (when did one start a position).
// TRANS: Field label in extended profile (when did one start a position or education).
$this->out->element('div', 'label', _m('Start'));
$this->out->element(
'div',
@ -336,7 +336,7 @@ class ExtendedProfileWidget extends Form
date('j M Y', strtotime($field['start'])
)
);
// TRANS: Field label in experience area of extended profile (when did one end a position).
// TRANS: Field label in extended profile (when did one end a position or education).
$this->out->element('div', 'label', _m('End'));
$this->out->element(
'div',
@ -376,7 +376,7 @@ class ExtendedProfileWidget extends Form
isset($field['company']) ? $field['company'] : null
);
// TRANS: Field label in experience edit area of extended profile (when did one start at a company).
// TRANS: Field label in extended profile (when did one start a position or education).
$this->out->element('div', 'label', _m('Start'));
$this->out->input(
$id . '-start',
@ -384,7 +384,7 @@ class ExtendedProfileWidget extends Form
isset($field['start']) ? date('j M Y', strtotime($field['start'])) : null
);
// TRANS: Field label in experience edit area of extended profile (when did one terminate at a company).
// TRANS: Field label in extended profile (when did one end a position or education).
$this->out->element('div', 'label', _m('End'));
$this->out->input(
@ -416,13 +416,13 @@ class ExtendedProfileWidget extends Form
$this->out->element('div', 'label', _m('Institution'));
if (!empty($field['school'])) {
$this->out->element('div', 'field', $field['school']);
// TRANS: Field label in education area of extended profile.
// TRANS: Field label in extended profile for specifying an academic degree.
$this->out->element('div', 'label', _m('Degree'));
$this->out->element('div', 'field', $field['degree']);
// TRANS: Field label in education area of extended profile.
$this->out->element('div', 'label', _m('Description'));
$this->out->element('div', 'field', $field['description']);
// TRANS: Field label in education area of extended profile (when did one start an education).
// TRANS: Field label in extended profile (when did one start a position or education).
$this->out->element('div', 'label', _m('Start'));
$this->out->element(
'div',
@ -430,7 +430,7 @@ class ExtendedProfileWidget extends Form
date('j M Y', strtotime($field['start'])
)
);
// TRANS: Field label in education area of extended profile (when did one end a education).
// TRANS: Field label in extended profile (when did one end a position or education).
$this->out->element('div', 'label', _m('End'));
$this->out->element(
'div',
@ -460,7 +460,7 @@ class ExtendedProfileWidget extends Form
isset($field['school']) ? $field['school'] : null
);
// TRANS: Field label in education edit area of extended profile.
// TRANS: Field label in extended profile for specifying an academic degree.
$this->out->element('div', 'label', _m('Degree'));
$this->out->input(
$id . '-degree',
@ -477,7 +477,7 @@ class ExtendedProfileWidget extends Form
isset($field['description']) ? $field['description'] : null
);
// TRANS: Field label in education edit area of extended profile (when did one start an education).
// TRANS: Field label in extended profile (when did one start a position or education).
$this->out->element('div', 'label', _m('Start'));
$this->out->input(
$id . '-start',
@ -486,7 +486,7 @@ class ExtendedProfileWidget extends Form
isset($field['start']) ? date('j M Y', strtotime($field['start'])) : null
);
// TRANS: Field label in education edit area of extended profile (when did one end an education).
// TRANS: Field label in extended profile (when did one end a position or education).
$this->out->element('div', 'label', _m('End'));
$this->out->input(
$id . '-end',

View File

@ -49,6 +49,7 @@ class MobileProfilePlugin extends WAP20Plugin
{
public $DTD = null;
public $serveMobile = false;
public $reallyMobile = false;
public $mobileFeatures = array();
function __construct($DTD='http://www.wapforum.org/DTD/xhtml-mobile10.dtd')
@ -160,6 +161,7 @@ class MobileProfilePlugin extends WAP20Plugin
$this->setMobileFeatures($httpuseragent);
$this->serveMobile = true;
$this->reallyMobile = true;
break;
}
}
@ -201,6 +203,8 @@ class MobileProfilePlugin extends WAP20Plugin
header('Content-Type: '.$type);
if ($this->reallyMobile) {
$action->extraHeaders();
if (preg_match("/.*\/.*xml/", $type)) {
// Required for XML documents
@ -216,6 +220,11 @@ class MobileProfilePlugin extends WAP20Plugin
'xml:lang' => $language));
return false;
} else {
return true;
}
}
function setMobileFeatures($useragent)
@ -312,6 +321,7 @@ class MobileProfilePlugin extends WAP20Plugin
function onStartShowLocalNavBlock($action)
{
if ($this->serveMobile) {
// @todo FIXME: "Show Navigation" / "Hide Navigation" needs i18n
$action->element('a', array('href' => '#', 'id' => 'navtoggle'), 'Show Navigation');
return true;
}
@ -319,6 +329,7 @@ class MobileProfilePlugin extends WAP20Plugin
function onEndShowScripts($action)
{
// @todo FIXME: "Show Navigation" / "Hide Navigation" needs i18n
$action->inlineScript('
$(function() {
$("#mobile-toggle-disable").click(function() {
@ -337,6 +348,7 @@ class MobileProfilePlugin extends WAP20Plugin
$("#navtoggle").text(
text == "Show Navigation" ? "Hide Navigation" : "Show Navigation");
});
$(".checkbox-wrapper").unbind("click");
});'
);
}

View File

@ -2973,7 +2973,7 @@ X-OIM-Sequence-Num: 1
// <wsse:BinarySecurityToken Id="Compact1">t=tick&p=</wsse:BinarySecurityToken>
// <wst:BinarySecret>binary secret</wst:BinarySecret>
// RST2: messenger.msn.com
// <wsse:BinarySecurityToken Id="PPToken2">t=tick</wsse:BinarySecurityToken>
// <wsse:BinarySecurityToken Id="Compact2">t=tick</wsse:BinarySecurityToken>
// RST3: contacts.msn.com
// <wsse:BinarySecurityToken Id="Compact3">t=tick&p=</wsse:BinarySecurityToken>
// RST4: messengersecure.live.com
@ -2985,7 +2985,7 @@ X-OIM-Sequence-Num: 1
preg_match("#".
"<wsse\:BinarySecurityToken Id=\"Compact1\">(.*)</wsse\:BinarySecurityToken>(.*)".
"<wst\:BinarySecret>(.*)</wst\:BinarySecret>(.*)".
"<wsse\:BinarySecurityToken Id=\"PPToken2\">(.*)</wsse\:BinarySecurityToken>(.*)".
"<wsse\:BinarySecurityToken Id=\"Compact2\">(.*)</wsse\:BinarySecurityToken>(.*)".
"<wsse\:BinarySecurityToken Id=\"Compact3\">(.*)</wsse\:BinarySecurityToken>(.*)".
"<wsse\:BinarySecurityToken Id=\"Compact4\">(.*)</wsse\:BinarySecurityToken>(.*)".
"<wsse\:BinarySecurityToken Id=\"Compact5\">(.*)</wsse\:BinarySecurityToken>(.*)".

View File

@ -327,7 +327,8 @@ class OStatusPlugin extends Plugin
return false;
} catch (Exception $e) {
// TRANS: Error message in OStatus plugin.
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
// TRANS: and example.net, as these are official standard domain names for use in examples.
$err = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname.");
}
@ -360,7 +361,8 @@ class OStatusPlugin extends Plugin
return $this->filter(array($oprofile->localProfile()));
} catch (Exception $e) {
// TRANS: Error message in OStatus plugin.
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
// TRANS: and example.net, as these are official standard domain names for use in examples.
$this->msg = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname.");
return array();
}

View File

@ -77,7 +77,8 @@ class OStatusGroupAction extends OStatusSubAction
// TRANS: Field label.
_m('Join group'),
$this->profile_uri,
// TRANS: Tooltip for field label "Join group".
// TRANS: Tooltip for field label "Join group". Do not translate the "example.net"
// TRANS: domain name in the URL, as it is an official standard domain name for examples.
_m("OStatus group's address, like http://example.net/group/nickname."));
$this->elementEnd('li');
$this->elementEnd('ul');

View File

@ -228,14 +228,16 @@ class OStatusSubAction extends Action
} else if (Validate::uri($this->profile_uri)) {
$this->oprofile = Ostatus_profile::ensureProfileURL($this->profile_uri);
} else {
// TRANS: Error text.
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
// TRANS: and example.net, as these are official standard domain names for use in examples.
$this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname.");
common_debug('Invalid address format.', __FILE__);
return false;
}
return true;
} catch (FeedSubBadURLException $e) {
// TRANS: Error text.
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
// TRANS: and example.net, as these are official standard domain names for use in examples.
$this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname.");
common_debug('Invalid URL or could not reach server.', __FILE__);
} catch (FeedSubBadResponseException $e) {
@ -260,7 +262,8 @@ class OStatusSubAction extends Action
common_debug('Not a recognized feed type.', __FILE__);
} catch (Exception $e) {
// Any new ones we forgot about
// TRANS: Error text.
// TRANS: Error message in OStatus plugin. Do not translate the domain names example.com
// TRANS: and example.net, as these are official standard domain names for use in examples.
$this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname.");
common_debug(sprintf('Bad feed URL: %s %s', get_class($e), $e->getMessage()), __FILE__);
}

View File

@ -74,7 +74,7 @@ class OStatusTagAction extends OStatusInitAction
// TRANS: Field label.
$this->input('profile', _m('Profile Account'), $this->profile,
// TRANS: Field title.
_m('Your account id (i.e. user@identi.ca).'));
_m('Your account id (for example user@identi.ca).'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('submit', $submit);

View File

@ -219,7 +219,7 @@ class QnA_Answer extends Managed_DataObject
$out->elementStart('p', array('class' => implode(' ', $cls)));
$out->elementStart('span', 'answer-content');
$out->raw(QnAPlugin::shorten($answer->content, $notice));
$out->raw(common_render_text($answer->content));
$out->elementEnd('span');
if (!empty($answer->revisions)) {

View File

@ -227,7 +227,7 @@ class QnA_Question extends Managed_DataObject
if (!empty($question->description)) {
$out->elementStart('span', 'question-description');
$out->raw(QnAPlugin::shorten($question->description, $notice));
$out->raw(common_render_text($question->description));
$out->elementEnd('span');
}

View File

@ -405,6 +405,28 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase
$act = new Activity($entry, $feed);
$this->assertEquals($act->actor->id, $expected);
}
public function testBookmarkRelated()
{
global $_example11;
$dom = new DOMDocument();
$dom->loadXML($_example11);
$feed = $dom->documentElement;
$entry = $dom->getElementsByTagName('entry')->item(0);
$expected = 'http://blog.teambox.com/open-source-companies';
$links = ActivityUtils::getLinks($entry, 'related');
$this->assertFalse(empty($links));
$this->assertTrue(is_array($links));
$this->assertEquals(count($links), 1);
$url = $links[0]->getAttribute('href');
$this->assertEquals($url, $expected);
}
}
$_example1 = <<<EXAMPLE1
@ -905,3 +927,90 @@ $_example10 = <<<EXAMPLE10
</entry>
</feed>
EXAMPLE10;
$_example11 = <<<EXAMPLE11
<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
<generator uri="http://status.net" version="0.9.7">StatusNet</generator>
<id>http://freelish.us/api/statuses/user_timeline/1.atom</id>
<title>demon timeline</title>
<subtitle>Updates from demon on freelish.us!</subtitle>
<logo>http://avatar.status.net/f/freelishus/1-96-20110331163048.jpeg</logo>
<updated>2011-05-30T09:36:03-04:00</updated>
<author>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<uri>http://freelishus.status.net/user/1</uri>
<name>demon</name>
<link rel="alternate" type="text/html" href="http://freelish.us/demon"/>
<link rel="avatar" type="image/jpeg" media:width="192" media:height="192" href="http://avatar.status.net/f/freelishus/1-192-20110331163048.jpeg"/>
<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="http://avatar.status.net/f/freelishus/1-96-20110331163048.jpeg"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="http://avatar.status.net/f/freelishus/1-48-20110331163048.jpeg"/>
<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="http://avatar.status.net/f/freelishus/1-24-20110331163049.jpeg"/>
<georss:point>45.50884 -73.58781</georss:point>
<poco:preferredUsername>demon</poco:preferredUsername>
<poco:displayName>Evan Prodromou</poco:displayName>
<poco:note>Montreal hacker and entrepreneur.</poco:note>
<poco:address>
<poco:formatted>Montreal, Quebec</poco:formatted>
</poco:address>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>http://evan.status.net/</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
<statusnet:profile_info local_id="1"></statusnet:profile_info>
</author>
<!--Deprecation warning: activity:subject is present only for backward compatibility. It will be removed in the next version of StatusNet.-->
<activity:subject>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<id>http://freelishus.status.net/user/1</id>
<title>Evan Prodromou</title>
<link rel="alternate" type="text/html" href="http://freelish.us/demon"/>
<link rel="avatar" type="image/jpeg" media:width="192" media:height="192" href="http://avatar.status.net/f/freelishus/1-192-20110331163048.jpeg"/>
<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="http://avatar.status.net/f/freelishus/1-96-20110331163048.jpeg"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="http://avatar.status.net/f/freelishus/1-48-20110331163048.jpeg"/>
<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="http://avatar.status.net/f/freelishus/1-24-20110331163049.jpeg"/>
<georss:point>45.50884 -73.58781</georss:point>
<poco:preferredUsername>demon</poco:preferredUsername>
<poco:displayName>Evan Prodromou</poco:displayName>
<poco:note>Montreal hacker and entrepreneur.</poco:note>
<poco:address>
<poco:formatted>Montreal, Quebec</poco:formatted>
</poco:address>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>http://evan.status.net/</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
<statusnet:profile_info local_id="1"></statusnet:profile_info>
</activity:subject>
<link href="http://freelish.us/demon" rel="alternate" type="text/html"/>
<link href="http://freelish.us/main/sup#1" rel="http://api.friendfeed.com/2008/03#sup" type="application/json"/>
<link href="http://freelish.us/api/statuses/user_timeline/1.atom?max_id=13210408" rel="next" type="application/atom+xml"/>
<link href="http://freelish.us/main/push/hub" rel="hub"/>
<link href="http://freelish.us/main/salmon/user/1" rel="salmon"/>
<link href="http://freelish.us/main/salmon/user/1" rel="http://salmon-protocol.org/ns/salmon-replies"/>
<link href="http://freelish.us/main/salmon/user/1" rel="http://salmon-protocol.org/ns/salmon-mention"/>
<link href="http://freelish.us/api/statuses/user_timeline/1.atom" rel="self" type="application/atom+xml"/>
<entry>
<activity:object-type>http://activitystrea.ms/schema/1.0/bookmark</activity:object-type>
<id>http://freelish.us/bookmark/9e930c3e-7ed9-47de-aba5-df6c60cec542</id>
<title>Why you should build an open-source startup | Teambox Blog</title>
<link rel="alternate" type="text/html" href="http://freelish.us/bookmark/9e930c3e-7ed9-47de-aba5-df6c60cec542"/>
<link rel="related" href="http://blog.teambox.com/open-source-companies"/>
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
<published>2011-05-26T20:36:25+00:00</published>
<updated>2011-05-26T20:36:25+00:00</updated>
<link rel="ostatus:conversation" href="http://freelish.us/conversation/13835232"/>
<category term="opensource"></category>
<category term="startup"></category>
<link rel="self" type="application/atom+xml" href="http://freelish.us/api/statuses/show/13836862.atom"/>
<link rel="edit" type="application/atom+xml" href="http://freelish.us/api/statuses/show/13836862.atom"/>
<statusnet:notice_info local_id="13836862" source="web" favorite="false" repeated="false"></statusnet:notice_info>
</entry>
</feed>
EXAMPLE11;

View File

@ -418,10 +418,6 @@ address .poweredby {
content: '\25B8';
}
.notice .addressees:empty:before {
content: none;
}
.fn {
overflow: hidden;
}

View File

@ -1,13 +1,19 @@
/* Temporary copy of base styles for overriding */
/* IE specific styles */
input.checkbox,
input.radio {
top:0;
}
.form_notice textarea {
width: 485px;
width: 473px;
}
.form_notice .count + label {
.threaded-replies .form_notice textarea {
width: 385px;
}
.form_notice .form_note + label {
position:absolute;
top:25px;
left:83%;
@ -15,25 +21,47 @@ text-indent:-9999px;
height:16px;
width:16px;
display:block;
top: 30px;
left: 390px;
top: 27px;
}
.form_notice .submit {
.form_notice #notice_action-submit {
width: 106px;
max-width: 106px;
}
.form_notice .attach-status,
.form_notice #notice_data-geo_selected {
width:78.75%;
.form_notice .count {
right: 52px;
}
.form_notice .attach-status button,
.form_notice #notice_data-geo_selected button {
padding:0 4px;
#form_notice-direct.form_notice .count {
right: 18px;
}
#form_notice-direct label {
float: left;
}
#form_notice-direct select {
margin-top: 0px;
float: left;
}
.form_notice .error,
.form_notice .success,
.form_notice .notice-status {
width: 468px;
}
.threaded-replies .form_notice textarea {
width: 395px;
}
.notice-options input.submit {
font-size:0;
text-align:right;
text-indent:0;
}
.notice div.entry-content .timestamp a {
margin-right:4px;
}
@ -54,8 +82,14 @@ z-index:9999;
line-height:auto;
}
#site_nav_global_primary ul {
margin-right: 0px;
}
/* IE specific styles */
#site_nav_local_views ul {
list-style-type: none;
list-style-position: outside;
}
.notice-options input.submit {
color:#FFFFFF;
@ -65,16 +99,31 @@ line-height:auto;
filter: alpha(opacity=0);
}
.form_notice .count + label {
background:transparent url(../images/icons/icons-01.gif) no-repeat 0 -328px;
.notice .addressees:before {
content: '\003E';
}
.form_notice .notice_data-geo_wrap label {
background:transparent url(../images/icons/icons-01.gif) no-repeat 0 -1780px;
/* IE7 */
*+html .input_forms {
margin-bottom: -20px;
}
.form_notice .notice_data-geo_wrap label.checked {
background:transparent url(../images/icons/icons-01.gif) no-repeat 0 -1846px;
*+html .notice .addressees {
background: url(../images/icons/arrow_right.png) no-repeat top left;
padding-left: 16px;
}
/* IE6 */
#content {
_width: 520px;
}
#aside_primary {
_width: 190px;
}
#content h1 {
_clear: left;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

View File

@ -383,7 +383,7 @@ address {
}
#form_notice-direct.form_notice .count {
top: 80px;
top: 78px;
right: 7px;
}
@ -450,6 +450,7 @@ address {
text-align: left;
color: #888;
cursor: text;
background: #fff;
}
.input_form .form_settings li input {
@ -786,6 +787,10 @@ div.entry-content a.response:after {
font-size: 1em;
}
.threaded-replies:empty {
display: none;
}
.user_in .threaded-replies {
margin-top: 0px;
}

View File

@ -1,100 +0,0 @@
/* Temporary copy of base styles for overriding */
input.checkbox,
input.radio {
top:0;
}
.form_notice textarea {
width: 473px;
}
.threaded-replies .form_notice textarea {
width: 385px;
}
.form_notice .form_note + label {
position:absolute;
top:25px;
left:83%;
text-indent:-9999px;
height:16px;
width:16px;
display:block;
left: 390px;
top: 27px;
}
.form_notice #notice_action-submit {
width: 106px;
max-width: 106px;
}
.form_notice input.notice_data-attach_selected,
.form_notice #notice_data-geo_selected {
width:78.75%;
}
.form_notice input.notice_data-attach_selected button,
.form_notice #notice_data-geo_selected button {
padding:0 4px;
}
.notice-options input.submit {
font-size:0;
text-align:right;
text-indent:0;
}
.notice div.entry-content .timestamp a {
margin-right:4px;
}
.entity_profile {
width:64%;
}
.notice {
z-index:1;
}
.notice:hover {
z-index:9999;
}
.notice .thumbnail img {
z-index:9999;
}
.form_settings fieldset fieldset legend {
line-height:auto;
}
/* IE specific styles */
#site_nav_global_primary ul {
margin-right: 0px;
}
#site_nav_local_views ul {
list-style-type: none;
list-style-position: outside;
}
.notice-options input.submit {
color:#FFFFFF;
}
.form_notice input.notice_data-attach {
filter: alpha(opacity=0);
}
.form_notice .form_note + label {
background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -328px;
}
.form_notice #notice_data-geo_wrap label {
background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1780px;
}
.form_notice #notice_data-geo_wrap label.checked {
background:transparent url(../../rebase/images/icons/icons-01.gif) no-repeat 0 -1846px;
}
/* IE6 sucks */
#content {
_width: 520px;
}
#aside_primary {
_width: 190px;
}

View File

@ -120,6 +120,10 @@ address img + .fn {
color: #333;
font-size: 1em;
margin-bottom: 0px;
background: none;
text-transform: none;
letter-spacing: 0;
padding-bottom: 0;
}
#site_nav_local_views li {
@ -240,6 +244,12 @@ address img + .fn {
left: 270px;
}
.form_notice .error,
.form_notice .success,
.form_notice .notice-status {
width: 285px;
}
/*input type=file no good in
iPhone/iPod Touch, Android, Opera Mini Simulator
@ -254,6 +264,7 @@ iPhone/iPod Touch, Android, Opera Mini Simulator
clear: left;
float: left;
width: 200px;
z-index: 2;
}
.form_notice .checkbox-wrapper {
@ -262,7 +273,7 @@ iPhone/iPod Touch, Android, Opera Mini Simulator
}
.checkbox-wrapper label.checkbox {
display: none;
display: none !important;
}
.checkbox-wrapper #notice_private {
@ -283,6 +294,10 @@ iPhone/iPod Touch, Android, Opera Mini Simulator
width: 300px;
}
.input_form .form_settings label {
display: inline;
}
.input_form .form_settings li input {
width: 292px;
}
@ -295,6 +310,11 @@ iPhone/iPod Touch, Android, Opera Mini Simulator
display: none;
}
#event-startdate, #event-starttime, #event-enddate, #event-endtime {
width: 120px;
margin-right: 12px;
}
.input_form .form_settings .submit {
font-size: 1em;
margin: 10px 0;
@ -305,7 +325,8 @@ iPhone/iPod Touch, Android, Opera Mini Simulator
.form_notice #notice_action-submit {
text-align: center;
left: 0px;
top: 192px;
top: 100%;
margin-top: -45px;
width: 80px;
font-size: 1em;
}
@ -406,10 +427,6 @@ margin-left:0 !important;
content: '\003E';
}
.notice .addressees:empty:before {
content: none;
}
.user_in .notice div.entry-content {
max-width: 150px;
}
@ -426,6 +443,10 @@ ul.qna-dummy {
width: 220px;
}
.threaded-replies #answer-form fieldset {
width: 220px;
}
.threaded-replies #qna-answer-submit {
float: left;
clear: left;