Commit 506958f2 authored by Evan Prodromou's avatar Evan Prodromou

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

parents 60a1b0a1 712ba64f
......@@ -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);
......
......@@ -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).
......
......@@ -85,8 +85,11 @@ class RepliesAction extends OwnerDesignAction
common_set_returnto($this->selfUrl());
$this->notice = $this->user->getReplies(($this->page-1) * NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
$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){
// TRANS: Server error when page not found (404)
......
......@@ -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);
}
}
......@@ -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();
......
......@@ -258,6 +258,7 @@ user_id = 129
address = 130
address_type = 130
created = 142
registered_user_id = 1
[invitation__keys]
code = K
......
......@@ -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'),
),
);
......
......@@ -63,9 +63,9 @@ class ActivityImporter extends QueueHandler
$done = null;
if (Event::handle('StartImportActivity',
array($user, $author, $activity, $trusted, &$done))) {
try {
try {
if (Event::handle('StartImportActivity',
array($user, $author, $activity, $trusted, &$done))) {
switch ($activity->verb) {
case ActivityVerb::FOLLOW:
$this->subscribeProfile($user, $author, $activity);
......@@ -83,10 +83,10 @@ 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;
}
} catch (Exception $e) {
common_log(LOG_ERR, $e->getMessage());
$done = true;
}
return $done;
}
......
......@@ -104,8 +104,9 @@ 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);
......
......@@ -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.')
);
}
}
......@@ -229,31 +229,44 @@ class NoticeListItem extends Widget
function showAddressees()
{
$this->out->elementStart('span', 'addressees');
$cnt = $this->showGroupAddressees(true);
$cnt = $this->showProfileAddressees($cnt == 0);
$this->out->elementEnd('span', 'addressees');
$ga = $this->getGroupAddressees();
$pa = $this->getProfileAddressees();
$a = array_merge($ga, $pa);
if (!empty($a)) {
$this->out->elementStart('span', 'addressees');
$first = true;
foreach ($a as $addr) {
if (!$first) {
// TRANS: Separator in profile addressees list.
$this->out->text(_m('SEPARATOR',', '));
} else {
// TRANS: Start of profile addressees list.
$first = false;
}
$text = $addr['text'];
unset($addr['text']);
$this->out->element('a', $addr, $text);
}
$this->out->elementEnd('span', 'addressees');
}
}
function showGroupAddressees($first)
function getGroupAddressees()
{
$ga = array();
$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());
$ga[] = array('href' => $group->homeUrl(),
'title' => $group->nickname,
'class' => 'addressee group',
'text' => $group->getBestName());
}
return count($groups);
return $ga;
}
function getGroups()
......@@ -261,25 +274,20 @@ class NoticeListItem extends Widget
return $this->notice->getGroups();
}
function showProfileAddressees($first)
function getProfileAddressees()
{
$pa = array();
$replies = $this->getReplyProfiles();
foreach ($replies as $reply) {
if (!$first) {
// TRANS: Separator in profile addressees list.
$this->out->text(_m('SEPARATOR',', '));
} else {
// TRANS: Start of profile addressees list.
$first = false;
}
$this->out->element('a', array('href' => $reply->profileurl,
'title' => $reply->nickname,
'class' => 'addressee account'),
$reply->getBestName());
$pa[] = array('href' => $reply->profileurl,
'title' => $reply->nickname,
'class' => 'addressee account',
'text' => $reply->getBestName());
}
return count($replies);
return $pa;
}
function getReplyProfiles()
......
......@@ -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();
......
......@@ -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;
......
......@@ -46,7 +46,7 @@ require_once INSTALLDIR . '/lib/form.php';
class WhitelistInviteForm extends Form
{
private $whitelist = null;
/**
* Constructor
*
......@@ -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,17 +101,17 @@ 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');
}
function showEmailLI()
{
$this->out->elementStart('li');
......@@ -119,8 +119,8 @@ class WhitelistInviteForm extends Form
$this->out->text('@');
if (count($this->whitelist) == 1) {
$this->out->element(
'span',
array('class' => 'email_invite'),
'span',
array('class' => 'email_invite'),
$this->whitelist[0]
);
$this->out->hidden('domain[]', $this->whitelist[0]);
......@@ -154,10 +154,11 @@ 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')
);
}
/**
* Action elements
*
......@@ -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.')
);
}
}
......@@ -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,
'email' => $email,
'password' => $this->password1,
'email_confirmed' => true));
$fields = array('nickname' => $nickname,
'email' => $email,
'password' => $this->password1,
'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));
......
......@@ -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
......
......@@ -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',
......
......@@ -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,21 +203,28 @@ class MobileProfilePlugin extends WAP20Plugin
header('Content-Type: '.$type);
$action->extraHeaders();
if (preg_match("/.*\/.*xml/", $type)) {
// Required for XML documents
$action->xw->startDocument('1.0', 'UTF-8');
}
$action->xw->writeDTD('html',
'-//WAPFORUM//DTD XHTML Mobile 1.0//EN',
$this->DTD);
if ($this->reallyMobile) {
$action->extraHeaders();
if (preg_match("/.*\/.*xml/", $type)) {
// Required for XML documents
$action->xw->startDocument('1.0', 'UTF-8');
}
$action->xw->writeDTD('html',
'-//WAPFORUM//DTD XHTML Mobile 1.0//EN',
$this->DTD);
$language = $action->getLanguage();
$language = $action->getLanguage();
$action->elementStart('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
$action->elementStart('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
'xml:lang' => $language));
return false;
return false;
} else {
return true;
}
}
function setMobileFeatures($useragent)
......@@ -312,13 +321,15 @@ class MobileProfilePlugin extends WAP20Plugin
function onStartShowLocalNavBlock($action)
{
if ($this->serveMobile) {
$action->element('a', array('href' => '#', 'id' => 'navtoggle'), 'Show Navigation');
// @todo FIXME: "Show Navigation" / "Hide Navigation" needs i18n
$action->element('a', array('href' => '#', 'id' => 'navtoggle'), 'Show Navigation');
return true;
}
}
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");
});'
);
}
......
......@@ -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>(.*)".